nd6.c (edbb8b460058c7f076c8d11d247c254f963e6e17) nd6.c (1272577e22d8f1c1c5b5e88f2624836e93aecb17)
1/* $FreeBSD$ */
2/* $KAME: nd6.c,v 1.144 2001/05/24 07:44:00 itojun Exp $ */
3
4/*-
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

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

115static void nd6_llinfo_timer __P((void *));
116static void clear_llinfo_pqueue __P((struct llinfo_nd6 *));
117
118struct callout nd6_slowtimo_ch;
119struct callout nd6_timer_ch;
120extern struct callout in6_tmpaddrtimer_ch;
121
122void
1/* $FreeBSD$ */
2/* $KAME: nd6.c,v 1.144 2001/05/24 07:44:00 itojun Exp $ */
3
4/*-
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

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

115static void nd6_llinfo_timer __P((void *));
116static void clear_llinfo_pqueue __P((struct llinfo_nd6 *));
117
118struct callout nd6_slowtimo_ch;
119struct callout nd6_timer_ch;
120extern struct callout in6_tmpaddrtimer_ch;
121
122void
123nd6_init()
123nd6_init(void)
124{
125 static int nd6_init_done = 0;
126 int i;
127
128 if (nd6_init_done) {
129 log(LOG_NOTICE, "nd6_init called more than once(ignored)\n");
130 return;
131 }

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

142
143 /* start timer */
144 callout_init(&nd6_slowtimo_ch, 0);
145 callout_reset(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz,
146 nd6_slowtimo, NULL);
147}
148
149struct nd_ifinfo *
124{
125 static int nd6_init_done = 0;
126 int i;
127
128 if (nd6_init_done) {
129 log(LOG_NOTICE, "nd6_init called more than once(ignored)\n");
130 return;
131 }

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

142
143 /* start timer */
144 callout_init(&nd6_slowtimo_ch, 0);
145 callout_reset(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz,
146 nd6_slowtimo, NULL);
147}
148
149struct nd_ifinfo *
150nd6_ifattach(ifp)
151 struct ifnet *ifp;
150nd6_ifattach(struct ifnet *ifp)
152{
153 struct nd_ifinfo *nd;
154
155 nd = (struct nd_ifinfo *)malloc(sizeof(*nd), M_IP6NDP, M_WAITOK);
156 bzero(nd, sizeof(*nd));
157
158 nd->initialized = 1;
159

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

170
171 /* XXX: we cannot call nd6_setmtu since ifp is not fully initialized */
172 nd6_setmtu0(ifp, nd);
173
174 return nd;
175}
176
177void
151{
152 struct nd_ifinfo *nd;
153
154 nd = (struct nd_ifinfo *)malloc(sizeof(*nd), M_IP6NDP, M_WAITOK);
155 bzero(nd, sizeof(*nd));
156
157 nd->initialized = 1;
158

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

169
170 /* XXX: we cannot call nd6_setmtu since ifp is not fully initialized */
171 nd6_setmtu0(ifp, nd);
172
173 return nd;
174}
175
176void
178nd6_ifdetach(nd)
179 struct nd_ifinfo *nd;
177nd6_ifdetach(struct nd_ifinfo *nd)
180{
181
182 free(nd, M_IP6NDP);
183}
184
185/*
186 * Reset ND level link MTU. This function is called when the physical MTU
187 * changes, which means we might have to adjust the ND level MTU.
188 */
189void
178{
179
180 free(nd, M_IP6NDP);
181}
182
183/*
184 * Reset ND level link MTU. This function is called when the physical MTU
185 * changes, which means we might have to adjust the ND level MTU.
186 */
187void
190nd6_setmtu(ifp)
191 struct ifnet *ifp;
188nd6_setmtu(struct ifnet *ifp)
192{
193
194 nd6_setmtu0(ifp, ND_IFINFO(ifp));
195}
196
197/* XXX todo: do not maintain copy of ifp->if_mtu in ndi->maxmtu */
198void
189{
190
191 nd6_setmtu0(ifp, ND_IFINFO(ifp));
192}
193
194/* XXX todo: do not maintain copy of ifp->if_mtu in ndi->maxmtu */
195void
199nd6_setmtu0(ifp, ndi)
200 struct ifnet *ifp;
201 struct nd_ifinfo *ndi;
196nd6_setmtu0(struct ifnet *ifp, struct nd_ifinfo *ndi)
202{
203 u_int32_t omaxmtu;
204
205 omaxmtu = ndi->maxmtu;
206
207 switch (ifp->if_type) {
208 case IFT_ARCNET:
209 ndi->maxmtu = MIN(ARC_PHDS_MAXMTU, ifp->if_mtu); /* RFC2497 */

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

233
234 if (ndi->maxmtu > in6_maxmtu)
235 in6_setmaxmtu(); /* check all interfaces just in case */
236
237#undef MIN
238}
239
240void
197{
198 u_int32_t omaxmtu;
199
200 omaxmtu = ndi->maxmtu;
201
202 switch (ifp->if_type) {
203 case IFT_ARCNET:
204 ndi->maxmtu = MIN(ARC_PHDS_MAXMTU, ifp->if_mtu); /* RFC2497 */

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

228
229 if (ndi->maxmtu > in6_maxmtu)
230 in6_setmaxmtu(); /* check all interfaces just in case */
231
232#undef MIN
233}
234
235void
241nd6_option_init(opt, icmp6len, ndopts)
242 void *opt;
243 int icmp6len;
244 union nd_opts *ndopts;
236nd6_option_init(void *opt, int icmp6len, union nd_opts *ndopts)
245{
246
247 bzero(ndopts, sizeof(*ndopts));
248 ndopts->nd_opts_search = (struct nd_opt_hdr *)opt;
249 ndopts->nd_opts_last
250 = (struct nd_opt_hdr *)(((u_char *)opt) + icmp6len);
251
252 if (icmp6len == 0) {
253 ndopts->nd_opts_done = 1;
254 ndopts->nd_opts_search = NULL;
255 }
256}
257
258/*
259 * Take one ND option.
260 */
261struct nd_opt_hdr *
237{
238
239 bzero(ndopts, sizeof(*ndopts));
240 ndopts->nd_opts_search = (struct nd_opt_hdr *)opt;
241 ndopts->nd_opts_last
242 = (struct nd_opt_hdr *)(((u_char *)opt) + icmp6len);
243
244 if (icmp6len == 0) {
245 ndopts->nd_opts_done = 1;
246 ndopts->nd_opts_search = NULL;
247 }
248}
249
250/*
251 * Take one ND option.
252 */
253struct nd_opt_hdr *
262nd6_option(ndopts)
263 union nd_opts *ndopts;
254nd6_option(union nd_opts *ndopts)
264{
265 struct nd_opt_hdr *nd_opt;
266 int olen;
267
268 if (ndopts == NULL)
269 panic("ndopts == NULL in nd6_option");
270 if (ndopts->nd_opts_last == NULL)
271 panic("uninitialized ndopts in nd6_option");

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

306}
307
308/*
309 * Parse multiple ND options.
310 * This function is much easier to use, for ND routines that do not need
311 * multiple options of the same type.
312 */
313int
255{
256 struct nd_opt_hdr *nd_opt;
257 int olen;
258
259 if (ndopts == NULL)
260 panic("ndopts == NULL in nd6_option");
261 if (ndopts->nd_opts_last == NULL)
262 panic("uninitialized ndopts in nd6_option");

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

297}
298
299/*
300 * Parse multiple ND options.
301 * This function is much easier to use, for ND routines that do not need
302 * multiple options of the same type.
303 */
304int
314nd6_options(ndopts)
315 union nd_opts *ndopts;
305nd6_options(union nd_opts *ndopts)
316{
317 struct nd_opt_hdr *nd_opt;
318 int i = 0;
319
320 if (ndopts == NULL)
321 panic("ndopts == NULL in nd6_options");
322 if (ndopts->nd_opts_last == NULL)
323 panic("uninitialized ndopts in nd6_options");

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

386
387 return 0;
388}
389
390/*
391 * ND6 timer routine to handle ND6 entries
392 */
393void
306{
307 struct nd_opt_hdr *nd_opt;
308 int i = 0;
309
310 if (ndopts == NULL)
311 panic("ndopts == NULL in nd6_options");
312 if (ndopts->nd_opts_last == NULL)
313 panic("uninitialized ndopts in nd6_options");

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

376
377 return 0;
378}
379
380/*
381 * ND6 timer routine to handle ND6 entries
382 */
383void
394nd6_llinfo_settimer(ln, tick)
395 struct llinfo_nd6 *ln;
396 long tick;
384nd6_llinfo_settimer(struct llinfo_nd6 *ln, long tick)
397{
398 if (tick < 0) {
399 ln->ln_expire = 0;
400 ln->ln_ntick = 0;
401 callout_stop(&ln->ln_timer_ch);
402 } else {
403 ln->ln_expire = time_second + tick / hz;
404 if (tick > INT_MAX) {

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

409 ln->ln_ntick = 0;
410 callout_reset(&ln->ln_timer_ch, tick,
411 nd6_llinfo_timer, ln);
412 }
413 }
414}
415
416static void
385{
386 if (tick < 0) {
387 ln->ln_expire = 0;
388 ln->ln_ntick = 0;
389 callout_stop(&ln->ln_timer_ch);
390 } else {
391 ln->ln_expire = time_second + tick / hz;
392 if (tick > INT_MAX) {

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

397 ln->ln_ntick = 0;
398 callout_reset(&ln->ln_timer_ch, tick,
399 nd6_llinfo_timer, ln);
400 }
401 }
402}
403
404static void
417nd6_llinfo_timer(arg)
418 void *arg;
405nd6_llinfo_timer(void *arg)
419{
420 struct llinfo_nd6 *ln;
421 struct rtentry *rt;
422 struct in6_addr *dst;
423 struct ifnet *ifp;
424 struct nd_ifinfo *ndi = NULL;
425
426 ln = (struct llinfo_nd6 *)arg;

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

534 }
535}
536
537
538/*
539 * ND6 timer routine to expire default route list and prefix list
540 */
541void
406{
407 struct llinfo_nd6 *ln;
408 struct rtentry *rt;
409 struct in6_addr *dst;
410 struct ifnet *ifp;
411 struct nd_ifinfo *ndi = NULL;
412
413 ln = (struct llinfo_nd6 *)arg;

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

521 }
522}
523
524
525/*
526 * ND6 timer routine to expire default route list and prefix list
527 */
528void
542nd6_timer(ignored_arg)
543 void *ignored_arg;
529nd6_timer(void *ignored_arg)
544{
545 int s;
546 struct nd_defrouter *dr;
547 struct nd_prefix *pr;
548 struct in6_ifaddr *ia6, *nia6;
549 struct in6_addrlifetime *lt6;
550
551 callout_reset(&nd6_timer_ch, nd6_prune * hz,

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

658 prelist_remove(pr);
659 pr = t;
660 } else
661 pr = pr->ndpr_next;
662 }
663 splx(s);
664}
665
530{
531 int s;
532 struct nd_defrouter *dr;
533 struct nd_prefix *pr;
534 struct in6_ifaddr *ia6, *nia6;
535 struct in6_addrlifetime *lt6;
536
537 callout_reset(&nd6_timer_ch, nd6_prune * hz,

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

644 prelist_remove(pr);
645 pr = t;
646 } else
647 pr = pr->ndpr_next;
648 }
649 splx(s);
650}
651
652/*
653 * ia6 - deprecated/invalidated temporary address
654 */
666static int
655static int
667regen_tmpaddr(ia6)
668 struct in6_ifaddr *ia6; /* deprecated/invalidated temporary address */
656regen_tmpaddr(struct in6_ifaddr *ia6)
669{
670 struct ifaddr *ifa;
671 struct ifnet *ifp;
672 struct in6_ifaddr *public_ifa6 = NULL;
673
674 ifp = ia6->ia_ifa.ifa_ifp;
675 for (ifa = ifp->if_addrlist.tqh_first; ifa;
676 ifa = ifa->ifa_list.tqe_next) {

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

726 return (-1);
727}
728
729/*
730 * Nuke neighbor cache/prefix/default router management table, right before
731 * ifp goes away.
732 */
733void
657{
658 struct ifaddr *ifa;
659 struct ifnet *ifp;
660 struct in6_ifaddr *public_ifa6 = NULL;
661
662 ifp = ia6->ia_ifa.ifa_ifp;
663 for (ifa = ifp->if_addrlist.tqh_first; ifa;
664 ifa = ifa->ifa_list.tqe_next) {

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

714 return (-1);
715}
716
717/*
718 * Nuke neighbor cache/prefix/default router management table, right before
719 * ifp goes away.
720 */
721void
734nd6_purge(ifp)
735 struct ifnet *ifp;
722nd6_purge(struct ifnet *ifp)
736{
737 struct llinfo_nd6 *ln, *nln;
738 struct nd_defrouter *dr, *ndr;
739 struct nd_prefix *pr, *npr;
740
741 /*
742 * Nuke default router list entries toward ifp.
743 * We defer removal of default router list entries that is installed

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

814 if (sdl->sdl_index == ifp->if_index)
815 nln = nd6_free(rt, 0);
816 }
817 ln = nln;
818 }
819}
820
821struct rtentry *
723{
724 struct llinfo_nd6 *ln, *nln;
725 struct nd_defrouter *dr, *ndr;
726 struct nd_prefix *pr, *npr;
727
728 /*
729 * Nuke default router list entries toward ifp.
730 * We defer removal of default router list entries that is installed

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

801 if (sdl->sdl_index == ifp->if_index)
802 nln = nd6_free(rt, 0);
803 }
804 ln = nln;
805 }
806}
807
808struct rtentry *
822nd6_lookup(addr6, create, ifp)
823 struct in6_addr *addr6;
824 int create;
825 struct ifnet *ifp;
809nd6_lookup(struct in6_addr *addr6, int create, struct ifnet *ifp)
826{
827 struct rtentry *rt;
828 struct sockaddr_in6 sin6;
829 char ip6buf[INET6_ADDRSTRLEN];
830
831 bzero(&sin6, sizeof(sin6));
832 sin6.sin6_len = sizeof(struct sockaddr_in6);
833 sin6.sin6_family = AF_INET6;

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

922}
923
924/*
925 * Test whether a given IPv6 address is a neighbor or not, ignoring
926 * the actual neighbor cache. The neighbor cache is ignored in order
927 * to not reenter the routing code from within itself.
928 */
929static int
810{
811 struct rtentry *rt;
812 struct sockaddr_in6 sin6;
813 char ip6buf[INET6_ADDRSTRLEN];
814
815 bzero(&sin6, sizeof(sin6));
816 sin6.sin6_len = sizeof(struct sockaddr_in6);
817 sin6.sin6_family = AF_INET6;

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

906}
907
908/*
909 * Test whether a given IPv6 address is a neighbor or not, ignoring
910 * the actual neighbor cache. The neighbor cache is ignored in order
911 * to not reenter the routing code from within itself.
912 */
913static int
930nd6_is_new_addr_neighbor(addr, ifp)
931 struct sockaddr_in6 *addr;
932 struct ifnet *ifp;
914nd6_is_new_addr_neighbor(struct sockaddr_in6 *addr, struct ifnet *ifp)
933{
934 struct nd_prefix *pr;
935 struct ifaddr *dstaddr;
936
937 /*
938 * A link-local address is always a neighbor.
939 * XXX: a link does not necessarily specify a single interface.
940 */

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

998}
999
1000
1001/*
1002 * Detect if a given IPv6 address identifies a neighbor on a given link.
1003 * XXX: should take care of the destination of a p2p link?
1004 */
1005int
915{
916 struct nd_prefix *pr;
917 struct ifaddr *dstaddr;
918
919 /*
920 * A link-local address is always a neighbor.
921 * XXX: a link does not necessarily specify a single interface.
922 */

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

980}
981
982
983/*
984 * Detect if a given IPv6 address identifies a neighbor on a given link.
985 * XXX: should take care of the destination of a p2p link?
986 */
987int
1006nd6_is_addr_neighbor(addr, ifp)
1007 struct sockaddr_in6 *addr;
1008 struct ifnet *ifp;
988nd6_is_addr_neighbor(struct sockaddr_in6 *addr, struct ifnet *ifp)
1009{
1010
1011 if (nd6_is_new_addr_neighbor(addr, ifp))
1012 return (1);
1013
1014 /*
1015 * Even if the address matches none of our addresses, it might be
1016 * in the neighbor cache.

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

1023
1024/*
1025 * Free an nd6 llinfo entry.
1026 * Since the function would cause significant changes in the kernel, DO NOT
1027 * make it global, unless you have a strong reason for the change, and are sure
1028 * that the change is safe.
1029 */
1030static struct llinfo_nd6 *
989{
990
991 if (nd6_is_new_addr_neighbor(addr, ifp))
992 return (1);
993
994 /*
995 * Even if the address matches none of our addresses, it might be
996 * in the neighbor cache.

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

1003
1004/*
1005 * Free an nd6 llinfo entry.
1006 * Since the function would cause significant changes in the kernel, DO NOT
1007 * make it global, unless you have a strong reason for the change, and are sure
1008 * that the change is safe.
1009 */
1010static struct llinfo_nd6 *
1031nd6_free(rt, gc)
1032 struct rtentry *rt;
1033 int gc;
1011nd6_free(struct rtentry *rt, int gc)
1034{
1035 struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo, *next;
1036 struct in6_addr in6 = ((struct sockaddr_in6 *)rt_key(rt))->sin6_addr;
1037 struct nd_defrouter *dr;
1038
1039 /*
1040 * we used to have pfctlinput(PRC_HOSTDEAD) here.
1041 * even though it is not harmful, it was not really necessary.

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

1134}
1135
1136/*
1137 * Upper-layer reachability hint for Neighbor Unreachability Detection.
1138 *
1139 * XXX cost-effective methods?
1140 */
1141void
1012{
1013 struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo, *next;
1014 struct in6_addr in6 = ((struct sockaddr_in6 *)rt_key(rt))->sin6_addr;
1015 struct nd_defrouter *dr;
1016
1017 /*
1018 * we used to have pfctlinput(PRC_HOSTDEAD) here.
1019 * even though it is not harmful, it was not really necessary.

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

1112}
1113
1114/*
1115 * Upper-layer reachability hint for Neighbor Unreachability Detection.
1116 *
1117 * XXX cost-effective methods?
1118 */
1119void
1142nd6_nud_hint(rt, dst6, force)
1143 struct rtentry *rt;
1144 struct in6_addr *dst6;
1145 int force;
1120nd6_nud_hint(struct rtentry *rt, struct in6_addr *dst6, int force)
1146{
1147 struct llinfo_nd6 *ln;
1148
1149 /*
1150 * If the caller specified "rt", use that. Otherwise, resolve the
1151 * routing table by supplied "dst6".
1152 */
1153 if (rt == NULL) {

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

1181
1182 ln->ln_state = ND6_LLINFO_REACHABLE;
1183 if (!ND6_LLINFO_PERMANENT(ln)) {
1184 nd6_llinfo_settimer(ln,
1185 (long)ND_IFINFO(rt->rt_ifp)->reachable * hz);
1186 }
1187}
1188
1121{
1122 struct llinfo_nd6 *ln;
1123
1124 /*
1125 * If the caller specified "rt", use that. Otherwise, resolve the
1126 * routing table by supplied "dst6".
1127 */
1128 if (rt == NULL) {

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

1156
1157 ln->ln_state = ND6_LLINFO_REACHABLE;
1158 if (!ND6_LLINFO_PERMANENT(ln)) {
1159 nd6_llinfo_settimer(ln,
1160 (long)ND_IFINFO(rt->rt_ifp)->reachable * hz);
1161 }
1162}
1163
1164/*
1165 * info - XXX unused
1166 */
1189void
1167void
1190nd6_rtrequest(req, rt, info)
1191 int req;
1192 struct rtentry *rt;
1193 struct rt_addrinfo *info; /* xxx unused */
1168nd6_rtrequest(int req, struct rtentry *rt, struct rt_addrinfo *info)
1194{
1195 struct sockaddr *gate = rt->rt_gateway;
1196 struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo;
1197 static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
1198 struct ifnet *ifp = rt->rt_ifp;
1199 struct ifaddr *ifa;
1200
1201 RT_LOCK_ASSERT(rt);

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

1430 rt->rt_llinfo = 0;
1431 rt->rt_flags &= ~RTF_LLINFO;
1432 clear_llinfo_pqueue(ln);
1433 Free((caddr_t)ln);
1434 }
1435}
1436
1437int
1169{
1170 struct sockaddr *gate = rt->rt_gateway;
1171 struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo;
1172 static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
1173 struct ifnet *ifp = rt->rt_ifp;
1174 struct ifaddr *ifa;
1175
1176 RT_LOCK_ASSERT(rt);

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

1405 rt->rt_llinfo = 0;
1406 rt->rt_flags &= ~RTF_LLINFO;
1407 clear_llinfo_pqueue(ln);
1408 Free((caddr_t)ln);
1409 }
1410}
1411
1412int
1438nd6_ioctl(cmd, data, ifp)
1439 u_long cmd;
1440 caddr_t data;
1441 struct ifnet *ifp;
1413nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
1442{
1443 struct in6_drlist *drl = (struct in6_drlist *)data;
1444 struct in6_oprlist *oprl = (struct in6_oprlist *)data;
1445 struct in6_ndireq *ndi = (struct in6_ndireq *)data;
1446 struct in6_nbrinfo *nbi = (struct in6_nbrinfo *)data;
1447 struct in6_ndifreq *ndif = (struct in6_ndifreq *)data;
1448 struct nd_defrouter *dr;
1449 struct nd_prefix *pr;

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

1665 return (nd6_setdefaultiface(ndif->ifindex));
1666 }
1667 return (error);
1668}
1669
1670/*
1671 * Create neighbor cache entry and cache link-layer address,
1672 * on reception of inbound ND6 packets. (RS/RA/NS/redirect)
1414{
1415 struct in6_drlist *drl = (struct in6_drlist *)data;
1416 struct in6_oprlist *oprl = (struct in6_oprlist *)data;
1417 struct in6_ndireq *ndi = (struct in6_ndireq *)data;
1418 struct in6_nbrinfo *nbi = (struct in6_nbrinfo *)data;
1419 struct in6_ndifreq *ndif = (struct in6_ndifreq *)data;
1420 struct nd_defrouter *dr;
1421 struct nd_prefix *pr;

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

1637 return (nd6_setdefaultiface(ndif->ifindex));
1638 }
1639 return (error);
1640}
1641
1642/*
1643 * Create neighbor cache entry and cache link-layer address,
1644 * on reception of inbound ND6 packets. (RS/RA/NS/redirect)
1645 *
1646 * type - ICMP6 type
1647 * code - type dependent information
1673 */
1674struct rtentry *
1648 */
1649struct rtentry *
1675nd6_cache_lladdr(ifp, from, lladdr, lladdrlen, type, code)
1676 struct ifnet *ifp;
1677 struct in6_addr *from;
1678 char *lladdr;
1679 int lladdrlen;
1680 int type; /* ICMP6 type */
1681 int code; /* type dependent information */
1650nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
1651 int lladdrlen, int type, int code)
1682{
1683 struct rtentry *rt = NULL;
1684 struct llinfo_nd6 *ln = NULL;
1685 int is_newentry;
1686 struct sockaddr_dl *sdl = NULL;
1687 int do_update;
1688 int olladdr;
1689 int llchange;

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

1905 */
1906 if (do_update && ln->ln_router && !ip6_forwarding && ip6_accept_rtadv)
1907 defrouter_select();
1908
1909 return rt;
1910}
1911
1912static void
1652{
1653 struct rtentry *rt = NULL;
1654 struct llinfo_nd6 *ln = NULL;
1655 int is_newentry;
1656 struct sockaddr_dl *sdl = NULL;
1657 int do_update;
1658 int olladdr;
1659 int llchange;

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

1875 */
1876 if (do_update && ln->ln_router && !ip6_forwarding && ip6_accept_rtadv)
1877 defrouter_select();
1878
1879 return rt;
1880}
1881
1882static void
1913nd6_slowtimo(ignored_arg)
1914 void *ignored_arg;
1883nd6_slowtimo(void *ignored_arg)
1915{
1916 struct nd_ifinfo *nd6if;
1917 struct ifnet *ifp;
1918
1919 callout_reset(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz,
1920 nd6_slowtimo, NULL);
1921 IFNET_RLOCK();
1922 for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) {

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

1933 nd6if->reachable = ND_COMPUTE_RTIME(nd6if->basereachable);
1934 }
1935 }
1936 IFNET_RUNLOCK();
1937}
1938
1939#define senderr(e) { error = (e); goto bad;}
1940int
1884{
1885 struct nd_ifinfo *nd6if;
1886 struct ifnet *ifp;
1887
1888 callout_reset(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz,
1889 nd6_slowtimo, NULL);
1890 IFNET_RLOCK();
1891 for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) {

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

1902 nd6if->reachable = ND_COMPUTE_RTIME(nd6if->basereachable);
1903 }
1904 }
1905 IFNET_RUNLOCK();
1906}
1907
1908#define senderr(e) { error = (e); goto bad;}
1909int
1941nd6_output(ifp, origifp, m0, dst, rt0)
1942 struct ifnet *ifp;
1943 struct ifnet *origifp;
1944 struct mbuf *m0;
1945 struct sockaddr_in6 *dst;
1946 struct rtentry *rt0;
1910nd6_output(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0,
1911 struct sockaddr_in6 *dst, struct rtentry *rt0)
1947{
1948 struct mbuf *m = m0;
1949 struct rtentry *rt = rt0;
1950 struct sockaddr_in6 *gw6 = NULL;
1951 struct llinfo_nd6 *ln = NULL;
1952 int error = 0;
1953
1954 if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr))

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

2158 bad:
2159 if (m)
2160 m_freem(m);
2161 return (error);
2162}
2163#undef senderr
2164
2165int
1912{
1913 struct mbuf *m = m0;
1914 struct rtentry *rt = rt0;
1915 struct sockaddr_in6 *gw6 = NULL;
1916 struct llinfo_nd6 *ln = NULL;
1917 int error = 0;
1918
1919 if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr))

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

2123 bad:
2124 if (m)
2125 m_freem(m);
2126 return (error);
2127}
2128#undef senderr
2129
2130int
2166nd6_need_cache(ifp)
2167 struct ifnet *ifp;
2131nd6_need_cache(struct ifnet *ifp)
2168{
2169 /*
2170 * XXX: we currently do not make neighbor cache on any interface
2171 * other than ARCnet, Ethernet, FDDI and GIF.
2172 *
2173 * RFC2893 says:
2174 * - unidirectional tunnels needs no ND
2175 */

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

2194 case IFT_PROPVIRTUAL:
2195 return (1);
2196 default:
2197 return (0);
2198 }
2199}
2200
2201int
2132{
2133 /*
2134 * XXX: we currently do not make neighbor cache on any interface
2135 * other than ARCnet, Ethernet, FDDI and GIF.
2136 *
2137 * RFC2893 says:
2138 * - unidirectional tunnels needs no ND
2139 */

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

2158 case IFT_PROPVIRTUAL:
2159 return (1);
2160 default:
2161 return (0);
2162 }
2163}
2164
2165int
2202nd6_storelladdr(ifp, rt0, m, dst, desten)
2203 struct ifnet *ifp;
2204 struct rtentry *rt0;
2205 struct mbuf *m;
2206 struct sockaddr *dst;
2207 u_char *desten;
2166nd6_storelladdr(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
2167 struct sockaddr *dst, u_char *desten)
2208{
2209 struct sockaddr_dl *sdl;
2210 struct rtentry *rt;
2211 int error;
2212
2213 if (m->m_flags & M_MCAST) {
2214 int i;
2215

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

2270 return (EINVAL);
2271 }
2272
2273 bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
2274 return (0);
2275}
2276
2277static void
2168{
2169 struct sockaddr_dl *sdl;
2170 struct rtentry *rt;
2171 int error;
2172
2173 if (m->m_flags & M_MCAST) {
2174 int i;
2175

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

2230 return (EINVAL);
2231 }
2232
2233 bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
2234 return (0);
2235}
2236
2237static void
2278clear_llinfo_pqueue(ln)
2279 struct llinfo_nd6 *ln;
2238clear_llinfo_pqueue(struct llinfo_nd6 *ln)
2280{
2281 struct mbuf *m_hold, *m_hold_next;
2282
2283 for (m_hold = ln->ln_hold; m_hold; m_hold = m_hold_next) {
2284 m_hold_next = m_hold->m_nextpkt;
2285 m_hold->m_nextpkt = NULL;
2286 m_freem(m_hold);
2287 }

--- 147 unchanged lines hidden ---
2239{
2240 struct mbuf *m_hold, *m_hold_next;
2241
2242 for (m_hold = ln->ln_hold; m_hold; m_hold = m_hold_next) {
2243 m_hold_next = m_hold->m_nextpkt;
2244 m_hold->m_nextpkt = NULL;
2245 m_freem(m_hold);
2246 }

--- 147 unchanged lines hidden ---