Lines 904-910
Link Here
|
904 |
* Remove the item from the tree; it should be there, |
904 |
* Remove the item from the tree; it should be there, |
905 |
* but when callers invoke us blindly it may not (sigh). |
905 |
* but when callers invoke us blindly it may not (sigh). |
906 |
*/ |
906 |
*/ |
907 |
rn = rnh->rnh_deladdr(rt_key(rt), rt_mask(rt), rnh); |
907 |
rn = rnh->rnh_deladdr(rt_key(rt), rt_mask(rt), rnh, NULL); |
908 |
if (rn == NULL) { |
908 |
if (rn == NULL) { |
909 |
error = ESRCH; |
909 |
error = ESRCH; |
910 |
goto bad; |
910 |
goto bad; |
Lines 942-1053
Link Here
|
942 |
return (error); |
942 |
return (error); |
943 |
} |
943 |
} |
944 |
|
944 |
|
945 |
#ifdef RADIX_MPATH |
|
|
946 |
static int |
947 |
rn_mpath_update(int req, struct rt_addrinfo *info, |
948 |
struct radix_node_head *rnh, struct rtentry **ret_nrt) |
949 |
{ |
950 |
/* |
951 |
* if we got multipath routes, we require users to specify |
952 |
* a matching RTAX_GATEWAY. |
953 |
*/ |
954 |
struct rtentry *rt, *rto = NULL; |
955 |
register struct radix_node *rn; |
956 |
int error = 0; |
957 |
|
958 |
rn = rnh->rnh_matchaddr(dst, rnh); |
959 |
if (rn == NULL) |
960 |
return (ESRCH); |
961 |
rto = rt = RNTORT(rn); |
962 |
rt = rt_mpath_matchgate(rt, gateway); |
963 |
if (rt == NULL) |
964 |
return (ESRCH); |
965 |
/* |
966 |
* this is the first entry in the chain |
967 |
*/ |
968 |
if (rto == rt) { |
969 |
rn = rn_mpath_next((struct radix_node *)rt); |
970 |
/* |
971 |
* there is another entry, now it's active |
972 |
*/ |
973 |
if (rn) { |
974 |
rto = RNTORT(rn); |
975 |
RT_LOCK(rto); |
976 |
rto->rt_flags |= RTF_UP; |
977 |
RT_UNLOCK(rto); |
978 |
} else if (rt->rt_flags & RTF_GATEWAY) { |
979 |
/* |
980 |
* For gateway routes, we need to |
981 |
* make sure that we we are deleting |
982 |
* the correct gateway. |
983 |
* rt_mpath_matchgate() does not |
984 |
* check the case when there is only |
985 |
* one route in the chain. |
986 |
*/ |
987 |
if (gateway && |
988 |
(rt->rt_gateway->sa_len != gateway->sa_len || |
989 |
memcmp(rt->rt_gateway, gateway, gateway->sa_len))) |
990 |
error = ESRCH; |
991 |
else { |
992 |
/* |
993 |
* remove from tree before returning it |
994 |
* to the caller |
995 |
*/ |
996 |
rn = rnh->rnh_deladdr(dst, netmask, rnh); |
997 |
KASSERT(rt == RNTORT(rn), ("radix node disappeared")); |
998 |
goto gwdelete; |
999 |
} |
1000 |
|
1001 |
} |
1002 |
/* |
1003 |
* use the normal delete code to remove |
1004 |
* the first entry |
1005 |
*/ |
1006 |
if (req != RTM_DELETE) |
1007 |
goto nondelete; |
1008 |
|
1009 |
error = ENOENT; |
1010 |
goto done; |
1011 |
} |
1012 |
|
1013 |
/* |
1014 |
* if the entry is 2nd and on up |
1015 |
*/ |
1016 |
if ((req == RTM_DELETE) && !rt_mpath_deldup(rto, rt)) |
1017 |
panic ("rtrequest1: rt_mpath_deldup"); |
1018 |
gwdelete: |
1019 |
RT_LOCK(rt); |
1020 |
RT_ADDREF(rt); |
1021 |
if (req == RTM_DELETE) { |
1022 |
rt->rt_flags &= ~RTF_UP; |
1023 |
/* |
1024 |
* One more rtentry floating around that is not |
1025 |
* linked to the routing table. rttrash will be decremented |
1026 |
* when RTFREE(rt) is eventually called. |
1027 |
*/ |
1028 |
V_rttrash++; |
1029 |
} |
1030 |
|
1031 |
nondelete: |
1032 |
if (req != RTM_DELETE) |
1033 |
panic("unrecognized request %d", req); |
1034 |
|
1035 |
|
1036 |
/* |
1037 |
* If the caller wants it, then it can have it, |
1038 |
* but it's up to it to free the rtentry as we won't be |
1039 |
* doing it. |
1040 |
*/ |
1041 |
if (ret_nrt) { |
1042 |
*ret_nrt = rt; |
1043 |
RT_UNLOCK(rt); |
1044 |
} else |
1045 |
RTFREE_LOCKED(rt); |
1046 |
done: |
1047 |
return (error); |
1048 |
} |
1049 |
#endif |
1050 |
|
1051 |
int |
945 |
int |
1052 |
rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt, |
946 |
rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt, |
1053 |
u_int fibnum) |
947 |
u_int fibnum) |
Lines 1100-1122
Link Here
|
1100 |
rt_maskedcopy(dst, (struct sockaddr *)&mdst, netmask); |
994 |
rt_maskedcopy(dst, (struct sockaddr *)&mdst, netmask); |
1101 |
dst = (struct sockaddr *)&mdst; |
995 |
dst = (struct sockaddr *)&mdst; |
1102 |
} |
996 |
} |
|
|
997 |
if ((rn = rnh->rnh_lookup(dst, netmask, rnh)) == NULL) |
998 |
senderr(ESRCH); |
999 |
rt = RNTORT(rn); |
1103 |
#ifdef RADIX_MPATH |
1000 |
#ifdef RADIX_MPATH |
|
|
1001 |
/* |
1002 |
* if we got multipath routes, we require users to specify |
1003 |
* a matching RTAX_GATEWAY. |
1004 |
*/ |
1104 |
if (rn_mpath_capable(rnh)) { |
1005 |
if (rn_mpath_capable(rnh)) { |
1105 |
error = rn_mpath_update(req, info, rnh, ret_nrt); |
1006 |
rt = rt_mpath_matchgate( rt, gateway); |
1106 |
/* |
1007 |
rn = (struct radix_node *)rt; |
1107 |
* "bad" holds true for the success case |
1008 |
if (!rt) |
1108 |
* as well |
1009 |
senderr(ESRCH); |
1109 |
*/ |
|
|
1110 |
if (error != ENOENT) |
1111 |
goto bad; |
1112 |
error = 0; |
1113 |
} |
1010 |
} |
1114 |
#endif |
1011 |
#endif |
1115 |
/* |
1012 |
/* |
1116 |
* Remove the item from the tree and return it. |
1013 |
* Remove the item from the tree and return it. |
1117 |
* Complain if it is not there and do no more processing. |
1014 |
* Complain if it is not there and do no more processing. |
1118 |
*/ |
1015 |
*/ |
1119 |
rn = rnh->rnh_deladdr(dst, netmask, rnh); |
1016 |
rn = rnh->rnh_deladdr(dst, netmask, rnh, rn); |
1120 |
if (rn == NULL) |
1017 |
if (rn == NULL) |
1121 |
senderr(ESRCH); |
1018 |
senderr(ESRCH); |
1122 |
if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) |
1019 |
if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) |
Lines 1212-1218
Link Here
|
1212 |
rt->rt_ifa = ifa; |
1109 |
rt->rt_ifa = ifa; |
1213 |
rt->rt_ifp = ifa->ifa_ifp; |
1110 |
rt->rt_ifp = ifa->ifa_ifp; |
1214 |
rt->rt_rmx.rmx_weight = 1; |
1111 |
rt->rt_rmx.rmx_weight = 1; |
1215 |
|
1112 |
|
1216 |
#ifdef RADIX_MPATH |
1113 |
#ifdef RADIX_MPATH |
1217 |
/* do not permit exactly the same dst/mask/gw pair */ |
1114 |
/* do not permit exactly the same dst/mask/gw pair */ |
1218 |
if (rn_mpath_capable(rnh) && |
1115 |
if (rn_mpath_capable(rnh) && |
Lines 1373-1379
Link Here
|
1373 |
*/ |
1270 |
*/ |
1374 |
if (rt->rt_gateway == NULL || glen > SA_SIZE(rt->rt_gateway)) { |
1271 |
if (rt->rt_gateway == NULL || glen > SA_SIZE(rt->rt_gateway)) { |
1375 |
caddr_t new; |
1272 |
caddr_t new; |
1376 |
|
1273 |
|
1377 |
R_Malloc(new, caddr_t, dlen + glen); |
1274 |
R_Malloc(new, caddr_t, dlen + glen); |
1378 |
if (new == NULL) |
1275 |
if (new == NULL) |
1379 |
return ENOBUFS; |
1276 |
return ENOBUFS; |
Lines 1506-1514
Link Here
|
1506 |
RADIX_NODE_HEAD_LOCK(rnh); |
1403 |
RADIX_NODE_HEAD_LOCK(rnh); |
1507 |
#ifdef RADIX_MPATH |
1404 |
#ifdef RADIX_MPATH |
1508 |
if (rn_mpath_capable(rnh)) { |
1405 |
if (rn_mpath_capable(rnh)) { |
1509 |
|
1406 |
rn = rnh->rnh_lookup(dst, netmask, rnh); |
1510 |
rn = rnh->rnh_matchaddr(dst, rnh); |
1407 |
if (rn == NULL) |
1511 |
if (rn == NULL) |
|
|
1512 |
error = ESRCH; |
1408 |
error = ESRCH; |
1513 |
else { |
1409 |
else { |
1514 |
rt = RNTORT(rn); |
1410 |
rt = RNTORT(rn); |
Lines 1523-1528
Link Here
|
1523 |
ifa->ifa_addr); |
1419 |
ifa->ifa_addr); |
1524 |
if (!rt) |
1420 |
if (!rt) |
1525 |
error = ESRCH; |
1421 |
error = ESRCH; |
|
|
1422 |
rn = (struct radix_node *)rt; |
1526 |
} |
1423 |
} |
1527 |
} |
1424 |
} |
1528 |
else |
1425 |
else |