Deleted Added
full compact
route.c (191734) route.c (193232)
1/*-
2 * Copyright (c) 1980, 1986, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * @(#)route.c 8.3.1.1 (Berkeley) 2/23/95
1/*-
2 * Copyright (c) 1980, 1986, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * @(#)route.c 8.3.1.1 (Berkeley) 2/23/95
30 * $FreeBSD: head/sys/net/route.c 191734 2009-05-02 05:02:28Z zec $
30 * $FreeBSD: head/sys/net/route.c 193232 2009-06-01 15:49:42Z bz $
31 */
32/************************************************************************
33 * Note: In this file a 'fib' is a "forwarding information base" *
34 * Which is the new name for an in kernel routing (next hop) table. *
35 ***********************************************************************/
36
37#include "opt_inet.h"
38#include "opt_route.h"

--- 47 unchanged lines hidden (view full) ---

86 */
87u_int rt_add_addr_allfibs = 1;
88SYSCTL_INT(_net, OID_AUTO, add_addr_allfibs, CTLFLAG_RW,
89 &rt_add_addr_allfibs, 0, "");
90TUNABLE_INT("net.add_addr_allfibs", &rt_add_addr_allfibs);
91
92#ifdef VIMAGE_GLOBALS
93static struct rtstat rtstat;
31 */
32/************************************************************************
33 * Note: In this file a 'fib' is a "forwarding information base" *
34 * Which is the new name for an in kernel routing (next hop) table. *
35 ***********************************************************************/
36
37#include "opt_inet.h"
38#include "opt_route.h"

--- 47 unchanged lines hidden (view full) ---

86 */
87u_int rt_add_addr_allfibs = 1;
88SYSCTL_INT(_net, OID_AUTO, add_addr_allfibs, CTLFLAG_RW,
89 &rt_add_addr_allfibs, 0, "");
90TUNABLE_INT("net.add_addr_allfibs", &rt_add_addr_allfibs);
91
92#ifdef VIMAGE_GLOBALS
93static struct rtstat rtstat;
94struct radix_node_head *rt_tables;
94
95
95/* by default only the first 'row' of tables will be accessed. */
96/*
97 * XXXMRT When we fix netstat, and do this differnetly,
98 * we can allocate this dynamically. As long as we are keeping
99 * things backwards compaitble we need to allocate this
100 * statically.
101 */
102struct radix_node_head *rt_tables[RT_MAXFIBS][AF_MAX+1];
103
104static int rttrash; /* routes not in table but not freed */
105#endif
106
107static void rt_maskedcopy(struct sockaddr *,
108 struct sockaddr *, struct sockaddr *);
109static int vnet_route_iattach(const void *);
110
111#ifndef VIMAGE_GLOBALS

--- 41 unchanged lines hidden (view full) ---

153 fibnum = curthread->td_proc->p_fibnum;
154 error = sysctl_handle_int(oidp, &fibnum, 0, req);
155 return (error);
156}
157
158SYSCTL_PROC(_net, OID_AUTO, my_fibnum, CTLTYPE_INT|CTLFLAG_RD,
159 NULL, 0, &sysctl_my_fibnum, "I", "default FIB of caller");
160
96static int rttrash; /* routes not in table but not freed */
97#endif
98
99static void rt_maskedcopy(struct sockaddr *,
100 struct sockaddr *, struct sockaddr *);
101static int vnet_route_iattach(const void *);
102
103#ifndef VIMAGE_GLOBALS

--- 41 unchanged lines hidden (view full) ---

145 fibnum = curthread->td_proc->p_fibnum;
146 error = sysctl_handle_int(oidp, &fibnum, 0, req);
147 return (error);
148}
149
150SYSCTL_PROC(_net, OID_AUTO, my_fibnum, CTLTYPE_INT|CTLFLAG_RD,
151 NULL, 0, &sysctl_my_fibnum, "I", "default FIB of caller");
152
153static __inline struct radix_node_head **
154rt_tables_get_rnh_ptr(int table, int fam)
155{
156 INIT_VNET_NET(curvnet);
157 struct radix_node_head **rnh;
158
159 KASSERT(table >= 0 && table < rt_numfibs, ("%s: table out of bounds.",
160 __func__));
161 KASSERT(fam >= 0 && fam < (AF_MAX+1), ("%s: fam out of bounds.",
162 __func__));
163
164 /* rnh is [fib=0][af=0]. */
165 rnh = (struct radix_node_head **)V_rt_tables;
166 /* Get the offset to the requested table and fam. */
167 rnh += table * (AF_MAX+1) + fam;
168
169 return (rnh);
170}
171
172struct radix_node_head *
173rt_tables_get_rnh(int table, int fam)
174{
175
176 return (*rt_tables_get_rnh_ptr(table, fam));
177}
178
161static void
162route_init(void)
163{
164
165 /* whack the tunable ints into line. */
166 if (rt_numfibs > RT_MAXFIBS)
167 rt_numfibs = RT_MAXFIBS;
168 if (rt_numfibs == 0)

--- 5 unchanged lines hidden (view full) ---

174#else
175 vnet_route_iattach(NULL);
176#endif
177}
178
179static int vnet_route_iattach(const void *unused __unused)
180{
181 INIT_VNET_NET(curvnet);
179static void
180route_init(void)
181{
182
183 /* whack the tunable ints into line. */
184 if (rt_numfibs > RT_MAXFIBS)
185 rt_numfibs = RT_MAXFIBS;
186 if (rt_numfibs == 0)

--- 5 unchanged lines hidden (view full) ---

192#else
193 vnet_route_iattach(NULL);
194#endif
195}
196
197static int vnet_route_iattach(const void *unused __unused)
198{
199 INIT_VNET_NET(curvnet);
182 int table;
183 struct domain *dom;
200 struct domain *dom;
201 struct radix_node_head **rnh;
202 int table;
184 int fam;
185
203 int fam;
204
205 V_rt_tables = malloc(rt_numfibs * (AF_MAX+1) *
206 sizeof(struct radix_node_head *), M_RTABLE, M_WAITOK|M_ZERO);
207
186 V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry), NULL, NULL,
187 NULL, NULL, UMA_ALIGN_PTR, 0);
188 for (dom = domains; dom; dom = dom->dom_next) {
189 if (dom->dom_rtattach) {
190 for (table = 0; table < rt_numfibs; table++) {
191 if ( (fam = dom->dom_family) == AF_INET ||
192 table == 0) {
193 /* for now only AF_INET has > 1 table */
194 /* XXX MRT
195 * rtattach will be also called
196 * from vfs_export.c but the
197 * offset will be 0
198 * (only for AF_INET and AF_INET6
199 * which don't need it anyhow)
200 */
208 V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry), NULL, NULL,
209 NULL, NULL, UMA_ALIGN_PTR, 0);
210 for (dom = domains; dom; dom = dom->dom_next) {
211 if (dom->dom_rtattach) {
212 for (table = 0; table < rt_numfibs; table++) {
213 if ( (fam = dom->dom_family) == AF_INET ||
214 table == 0) {
215 /* for now only AF_INET has > 1 table */
216 /* XXX MRT
217 * rtattach will be also called
218 * from vfs_export.c but the
219 * offset will be 0
220 * (only for AF_INET and AF_INET6
221 * which don't need it anyhow)
222 */
201 dom->dom_rtattach(
202 (void **)&V_rt_tables[table][fam],
223 rnh = rt_tables_get_rnh_ptr(table, fam);
224 if (rnh == NULL)
225 panic("%s: rnh NULL", __func__);
226 dom->dom_rtattach((void **)rnh,
203 dom->dom_rtoffset);
204 } else {
205 break;
206 }
207 }
208 }
209 }
210

--- 84 unchanged lines hidden (view full) ---

295 struct rtentry *newrt;
296 struct rt_addrinfo info;
297 int err = 0, msgtype = RTM_MISS;
298 int needlock;
299
300 KASSERT((fibnum < rt_numfibs), ("rtalloc1_fib: bad fibnum"));
301 if (dst->sa_family != AF_INET) /* Only INET supports > 1 fib now */
302 fibnum = 0;
227 dom->dom_rtoffset);
228 } else {
229 break;
230 }
231 }
232 }
233 }
234

--- 84 unchanged lines hidden (view full) ---

319 struct rtentry *newrt;
320 struct rt_addrinfo info;
321 int err = 0, msgtype = RTM_MISS;
322 int needlock;
323
324 KASSERT((fibnum < rt_numfibs), ("rtalloc1_fib: bad fibnum"));
325 if (dst->sa_family != AF_INET) /* Only INET supports > 1 fib now */
326 fibnum = 0;
303 rnh = V_rt_tables[fibnum][dst->sa_family];
327 rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
304 newrt = NULL;
305 /*
306 * Look up the address in the table for that Address Family
307 */
308 if (rnh == NULL) {
309 V_rtstat.rts_unreach++;
310 goto miss;
311 }

--- 45 unchanged lines hidden (view full) ---

357 */
358void
359rtfree(struct rtentry *rt)
360{
361 INIT_VNET_NET(curvnet);
362 struct radix_node_head *rnh;
363
364 KASSERT(rt != NULL,("%s: NULL rt", __func__));
328 newrt = NULL;
329 /*
330 * Look up the address in the table for that Address Family
331 */
332 if (rnh == NULL) {
333 V_rtstat.rts_unreach++;
334 goto miss;
335 }

--- 45 unchanged lines hidden (view full) ---

381 */
382void
383rtfree(struct rtentry *rt)
384{
385 INIT_VNET_NET(curvnet);
386 struct radix_node_head *rnh;
387
388 KASSERT(rt != NULL,("%s: NULL rt", __func__));
365 rnh = V_rt_tables[rt->rt_fibnum][rt_key(rt)->sa_family];
389 rnh = rt_tables_get_rnh(rt->rt_fibnum, rt_key(rt)->sa_family);
366 KASSERT(rnh != NULL,("%s: NULL rnh", __func__));
367
368 RT_LOCK_ASSERT(rt);
369
370 /*
371 * The callers should use RTFREE_LOCKED() or RTFREE(), so
372 * we should come here exactly with the last reference.
373 */

--- 84 unchanged lines hidden (view full) ---

458 u_int fibnum)
459{
460 INIT_VNET_NET(curvnet);
461 struct rtentry *rt, *rt0 = NULL;
462 int error = 0;
463 short *stat = NULL;
464 struct rt_addrinfo info;
465 struct ifaddr *ifa;
390 KASSERT(rnh != NULL,("%s: NULL rnh", __func__));
391
392 RT_LOCK_ASSERT(rt);
393
394 /*
395 * The callers should use RTFREE_LOCKED() or RTFREE(), so
396 * we should come here exactly with the last reference.
397 */

--- 84 unchanged lines hidden (view full) ---

482 u_int fibnum)
483{
484 INIT_VNET_NET(curvnet);
485 struct rtentry *rt, *rt0 = NULL;
486 int error = 0;
487 short *stat = NULL;
488 struct rt_addrinfo info;
489 struct ifaddr *ifa;
466 struct radix_node_head *rnh =
467 V_rt_tables[fibnum][dst->sa_family];
490 struct radix_node_head *rnh;
468
491
492 rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
493 if (rnh == NULL) {
494 error = EAFNOSUPPORT;
495 goto out;
496 }
497
469 /* verify the gateway is directly reachable */
470 if ((ifa = ifa_ifwithnet(gateway)) == NULL) {
471 error = ENETUNREACH;
472 goto out;
473 }
474 rt = rtalloc1_fib(dst, 0, 0UL, fibnum); /* NB: rt is locked */
475 /*
476 * If the redirect isn't from our current router for this dst,

--- 292 unchanged lines hidden (view full) ---

769 struct radix_node *rn;
770 struct radix_node_head *rnh;
771 struct ifaddr *ifa;
772 int error = 0;
773
774 /*
775 * Find the correct routing tree to use for this Address Family
776 */
498 /* verify the gateway is directly reachable */
499 if ((ifa = ifa_ifwithnet(gateway)) == NULL) {
500 error = ENETUNREACH;
501 goto out;
502 }
503 rt = rtalloc1_fib(dst, 0, 0UL, fibnum); /* NB: rt is locked */
504 /*
505 * If the redirect isn't from our current router for this dst,

--- 292 unchanged lines hidden (view full) ---

798 struct radix_node *rn;
799 struct radix_node_head *rnh;
800 struct ifaddr *ifa;
801 int error = 0;
802
803 /*
804 * Find the correct routing tree to use for this Address Family
805 */
777 rnh = V_rt_tables[rt->rt_fibnum][rt_key(rt)->sa_family];
806 rnh = rt_tables_get_rnh(rt->rt_fibnum, rt_key(rt)->sa_family);
778 RT_LOCK_ASSERT(rt);
779 if (rnh == NULL)
780 return (EAFNOSUPPORT);
781 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
782#if 0
783 /*
784 * We cannot assume anything about the reference count
785 * because protocols call us in many situations; often

--- 151 unchanged lines hidden (view full) ---

937#define senderr(x) { error = x ; goto bad; }
938
939 KASSERT((fibnum < rt_numfibs), ("rtrequest1_fib: bad fibnum"));
940 if (dst->sa_family != AF_INET) /* Only INET supports > 1 fib now */
941 fibnum = 0;
942 /*
943 * Find the correct routing tree to use for this Address Family
944 */
807 RT_LOCK_ASSERT(rt);
808 if (rnh == NULL)
809 return (EAFNOSUPPORT);
810 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
811#if 0
812 /*
813 * We cannot assume anything about the reference count
814 * because protocols call us in many situations; often

--- 151 unchanged lines hidden (view full) ---

966#define senderr(x) { error = x ; goto bad; }
967
968 KASSERT((fibnum < rt_numfibs), ("rtrequest1_fib: bad fibnum"));
969 if (dst->sa_family != AF_INET) /* Only INET supports > 1 fib now */
970 fibnum = 0;
971 /*
972 * Find the correct routing tree to use for this Address Family
973 */
945 rnh = V_rt_tables[fibnum][dst->sa_family];
974 rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
946 if (rnh == NULL)
947 return (EAFNOSUPPORT);
948 needlock = ((flags & RTF_RNH_LOCKED) == 0);
949 flags &= ~RTF_RNH_LOCKED;
950 if (needlock)
951 RADIX_NODE_HEAD_LOCK(rnh);
952 else
953 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);

--- 175 unchanged lines hidden (view full) ---

1129#undef flags
1130
1131int
1132rt_setgate(struct rtentry *rt, struct sockaddr *dst, struct sockaddr *gate)
1133{
1134 /* XXX dst may be overwritten, can we move this to below */
1135 int dlen = SA_SIZE(dst), glen = SA_SIZE(gate);
1136#ifdef INVARIANTS
975 if (rnh == NULL)
976 return (EAFNOSUPPORT);
977 needlock = ((flags & RTF_RNH_LOCKED) == 0);
978 flags &= ~RTF_RNH_LOCKED;
979 if (needlock)
980 RADIX_NODE_HEAD_LOCK(rnh);
981 else
982 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);

--- 175 unchanged lines hidden (view full) ---

1158#undef flags
1159
1160int
1161rt_setgate(struct rtentry *rt, struct sockaddr *dst, struct sockaddr *gate)
1162{
1163 /* XXX dst may be overwritten, can we move this to below */
1164 int dlen = SA_SIZE(dst), glen = SA_SIZE(gate);
1165#ifdef INVARIANTS
1137 INIT_VNET_NET(curvnet);
1138 struct radix_node_head *rnh =
1139 V_rt_tables[rt->rt_fibnum][dst->sa_family];
1166 struct radix_node_head *rnh;
1167
1168 rnh = rt_tables_get_rnh(rt->rt_fibnum, dst->sa_family);
1140#endif
1141
1142 RT_LOCK_ASSERT(rt);
1143 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
1144
1145 /*
1146 * Prepare to store the gateway in rt->rt_gateway.
1147 * Both dst and gateway are stored one after the other in the same

--- 50 unchanged lines hidden (view full) ---

1198/*
1199 * Set up a routing table entry, normally
1200 * for an interface.
1201 */
1202#define _SOCKADDR_TMPSIZE 128 /* Not too big.. kernel stack size is limited */
1203static inline int
1204rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
1205{
1169#endif
1170
1171 RT_LOCK_ASSERT(rt);
1172 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
1173
1174 /*
1175 * Prepare to store the gateway in rt->rt_gateway.
1176 * Both dst and gateway are stored one after the other in the same

--- 50 unchanged lines hidden (view full) ---

1227/*
1228 * Set up a routing table entry, normally
1229 * for an interface.
1230 */
1231#define _SOCKADDR_TMPSIZE 128 /* Not too big.. kernel stack size is limited */
1232static inline int
1233rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
1234{
1206 INIT_VNET_NET(curvnet);
1207 struct sockaddr *dst;
1208 struct sockaddr *netmask;
1209 struct rtentry *rt = NULL;
1210 struct rt_addrinfo info;
1211 int error = 0;
1212 int startfib, endfib;
1213 char tempbuf[_SOCKADDR_TMPSIZE];
1214 int didwork = 0;

--- 53 unchanged lines hidden (view full) ---

1268 for ( fibnum = startfib; fibnum <= endfib; fibnum++) {
1269 if (cmd == RTM_DELETE) {
1270 struct radix_node_head *rnh;
1271 struct radix_node *rn;
1272 /*
1273 * Look up an rtentry that is in the routing tree and
1274 * contains the correct info.
1275 */
1235 struct sockaddr *dst;
1236 struct sockaddr *netmask;
1237 struct rtentry *rt = NULL;
1238 struct rt_addrinfo info;
1239 int error = 0;
1240 int startfib, endfib;
1241 char tempbuf[_SOCKADDR_TMPSIZE];
1242 int didwork = 0;

--- 53 unchanged lines hidden (view full) ---

1296 for ( fibnum = startfib; fibnum <= endfib; fibnum++) {
1297 if (cmd == RTM_DELETE) {
1298 struct radix_node_head *rnh;
1299 struct radix_node *rn;
1300 /*
1301 * Look up an rtentry that is in the routing tree and
1302 * contains the correct info.
1303 */
1276 if ((rnh = V_rt_tables[fibnum][dst->sa_family]) == NULL)
1304 rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
1305 if (rnh == NULL)
1277 /* this table doesn't exist but others might */
1278 continue;
1279 RADIX_NODE_HEAD_LOCK(rnh);
1280#ifdef RADIX_MPATH
1281 if (rn_mpath_capable(rnh)) {
1282
1283 rn = rnh->rnh_matchaddr(dst, rnh);
1284 if (rn == NULL)

--- 146 unchanged lines hidden ---
1306 /* this table doesn't exist but others might */
1307 continue;
1308 RADIX_NODE_HEAD_LOCK(rnh);
1309#ifdef RADIX_MPATH
1310 if (rn_mpath_capable(rnh)) {
1311
1312 rn = rnh->rnh_matchaddr(dst, rnh);
1313 if (rn == NULL)

--- 146 unchanged lines hidden ---