Fri Nov 6 20:41:22 2009 UTC ()
Fix net.inet6.ip6.accept_rtadv and 'ndp -i <interface> accept_rtadv':

Add a flag ND6_IFF_OVERRIDE_RTADV that tells the kernel to override
ip6_accept_rtadv (net.inet6.ip6.accept_rtadv) on an interface.

Add a routine nd6_accepts_rtadv(ndi) that evaluates both the flags
on the interface represented by ndi and ip6_accept_rtadv, and
returns 'true' if the given interface should accept Router
Advertisements, and 'false' if not.

Now, ND6_IFF_ACCEPT_RTADV works as it was historically documented:
if it is set, then accept router advertisements iff ip6_accept_rtadv
!= 0.  Otherwise, do not accept router advertisements.

If ND6_IFF_OVERRIDE_RTADV is set, then the flag ND6_IFF_ACCEPT_RTADV
overrides ip6_accept_rtadv: if ND6_IFF_ACCEPT_RTADV is set, accept;
otherwise reject.  Ignore ip6_accept_rtadv.

If neither ND6_IFF_ACCEPT_RTADV nor ND6_IFF_OVERRIDE_RTADV is set,
reject Router Advertisements.


(dyoung)
diff -r1.134 -r1.135 src/sys/netinet6/nd6.c
diff -r1.52 -r1.53 src/sys/netinet6/nd6.h
diff -r1.79 -r1.80 src/sys/netinet6/nd6_rtr.c

cvs diff -r1.134 -r1.135 src/sys/netinet6/nd6.c (expand / switch to unified diff)

--- src/sys/netinet6/nd6.c 2009/08/31 12:37:59 1.134
+++ src/sys/netinet6/nd6.c 2009/11/06 20:41:22 1.135
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: nd6.c,v 1.134 2009/08/31 12:37:59 yamt Exp $ */ 1/* $NetBSD: nd6.c,v 1.135 2009/11/06 20:41:22 dyoung Exp $ */
2/* $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $ */ 2/* $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -21,27 +21,27 @@ @@ -21,27 +21,27 @@
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE. 30 * SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.134 2009/08/31 12:37:59 yamt Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.135 2009/11/06 20:41:22 dyoung Exp $");
35 35
36#include "opt_ipsec.h" 36#include "opt_ipsec.h"
37 37
38#include <sys/param.h> 38#include <sys/param.h>
39#include <sys/systm.h> 39#include <sys/systm.h>
40#include <sys/callout.h> 40#include <sys/callout.h>
41#include <sys/malloc.h> 41#include <sys/malloc.h>
42#include <sys/mbuf.h> 42#include <sys/mbuf.h>
43#include <sys/socket.h> 43#include <sys/socket.h>
44#include <sys/socketvar.h> 44#include <sys/socketvar.h>
45#include <sys/sockio.h> 45#include <sys/sockio.h>
46#include <sys/time.h> 46#include <sys/time.h>
47#include <sys/kernel.h> 47#include <sys/kernel.h>
@@ -162,32 +162,31 @@ nd6_ifattach(struct ifnet *ifp) @@ -162,32 +162,31 @@ nd6_ifattach(struct ifnet *ifp)
162{ 162{
163 struct nd_ifinfo *nd; 163 struct nd_ifinfo *nd;
164 164
165 nd = (struct nd_ifinfo *)malloc(sizeof(*nd), M_IP6NDP, M_WAITOK); 165 nd = (struct nd_ifinfo *)malloc(sizeof(*nd), M_IP6NDP, M_WAITOK);
166 memset(nd, 0, sizeof(*nd)); 166 memset(nd, 0, sizeof(*nd));
167 167
168 nd->initialized = 1; 168 nd->initialized = 1;
169 169
170 nd->chlim = IPV6_DEFHLIM; 170 nd->chlim = IPV6_DEFHLIM;
171 nd->basereachable = REACHABLE_TIME; 171 nd->basereachable = REACHABLE_TIME;
172 nd->reachable = ND_COMPUTE_RTIME(nd->basereachable); 172 nd->reachable = ND_COMPUTE_RTIME(nd->basereachable);
173 nd->retrans = RETRANS_TIMER; 173 nd->retrans = RETRANS_TIMER;
174 /* 174 /*
175 * Note that the default value of ip6_accept_rtadv is 0, which means 175 * Note that the default value of ip6_accept_rtadv is 0.
176 * we won't accept RAs by default even if we set ND6_IFF_ACCEPT_RTADV 176 * Because we do not set ND6_IFF_OVERRIDE_RTADV here, we won't
177 * here. 177 * accept RAs by default.
178 */ 178 */
179 nd->flags = (ND6_IFF_PERFORMNUD | 179 nd->flags = ND6_IFF_PERFORMNUD | ND6_IFF_ACCEPT_RTADV;
180 (ip6_accept_rtadv ? ND6_IFF_ACCEPT_RTADV : 0)); 
181 180
182 /* XXX: we cannot call nd6_setmtu since ifp is not fully initialized */ 181 /* XXX: we cannot call nd6_setmtu since ifp is not fully initialized */
183 nd6_setmtu0(ifp, nd); 182 nd6_setmtu0(ifp, nd);
184 183
185 return nd; 184 return nd;
186} 185}
187 186
188void 187void
189nd6_ifdetach(struct nd_ifinfo *nd) 188nd6_ifdetach(struct nd_ifinfo *nd)
190{ 189{
191 190
192 free(nd, M_IP6NDP); 191 free(nd, M_IP6NDP);
193} 192}
@@ -694,26 +693,41 @@ regen_tmpaddr(struct in6_ifaddr *ia6) @@ -694,26 +693,41 @@ regen_tmpaddr(struct in6_ifaddr *ia6)
694 * we do not need additional delay (3rd arg to in6_tmpifadd). 693 * we do not need additional delay (3rd arg to in6_tmpifadd).
695 */ 694 */
696 if ((e = in6_tmpifadd(public_ifa6, 0, 0)) != 0) { 695 if ((e = in6_tmpifadd(public_ifa6, 0, 0)) != 0) {
697 log(LOG_NOTICE, "regen_tmpaddr: failed to create a new" 696 log(LOG_NOTICE, "regen_tmpaddr: failed to create a new"
698 " tmp addr, errno=%d\n", e); 697 " tmp addr, errno=%d\n", e);
699 return -1; 698 return -1;
700 } 699 }
701 return 0; 700 return 0;
702 } 701 }
703 702
704 return -1; 703 return -1;
705} 704}
706 705
 706bool
 707nd6_accepts_rtadv(const struct nd_ifinfo *ndi)
 708{
 709 switch (ndi->flags & (ND6_IFF_ACCEPT_RTADV|ND6_IFF_OVERRIDE_RTADV)) {
 710 case ND6_IFF_OVERRIDE_RTADV|ND6_IFF_ACCEPT_RTADV:
 711 return true;
 712 case ND6_IFF_ACCEPT_RTADV:
 713 return ip6_accept_rtadv != 0;
 714 case ND6_IFF_OVERRIDE_RTADV:
 715 case 0:
 716 default:
 717 return false;
 718 }
 719}
 720
707/* 721/*
708 * Nuke neighbor cache/prefix/default router management table, right before 722 * Nuke neighbor cache/prefix/default router management table, right before
709 * ifp goes away. 723 * ifp goes away.
710 */ 724 */
711void 725void
712nd6_purge(struct ifnet *ifp) 726nd6_purge(struct ifnet *ifp)
713{ 727{
714 struct nd_ifinfo *ndi = ND_IFINFO(ifp); 728 struct nd_ifinfo *ndi = ND_IFINFO(ifp);
715 struct llinfo_nd6 *ln, *nln; 729 struct llinfo_nd6 *ln, *nln;
716 struct nd_defrouter *dr, *ndr; 730 struct nd_defrouter *dr, *ndr;
717 struct nd_prefix *pr, *npr; 731 struct nd_prefix *pr, *npr;
718 732
719 /* 733 /*
@@ -757,27 +771,27 @@ nd6_purge(struct ifnet *ifp) @@ -757,27 +771,27 @@ nd6_purge(struct ifnet *ifp)
757 * which removes all the associated interface addresses 771 * which removes all the associated interface addresses
758 * by itself. 772 * by itself.
759 * (jinmei@kame.net 20010129) 773 * (jinmei@kame.net 20010129)
760 */ 774 */
761 prelist_remove(pr); 775 prelist_remove(pr);
762 } 776 }
763 } 777 }
764 778
765 /* cancel default outgoing interface setting */ 779 /* cancel default outgoing interface setting */
766 if (nd6_defifindex == ifp->if_index) 780 if (nd6_defifindex == ifp->if_index)
767 nd6_setdefaultiface(0); 781 nd6_setdefaultiface(0);
768 782
769 /* XXX: too restrictive? */ 783 /* XXX: too restrictive? */
770 if (!ip6_forwarding && ndi && (ndi->flags & ND6_IFF_ACCEPT_RTADV)) { 784 if (!ip6_forwarding && ndi && nd6_accepts_rtadv(ndi)) {
771 /* refresh default router list */ 785 /* refresh default router list */
772 defrouter_select(); 786 defrouter_select();
773 } 787 }
774 788
775 /* 789 /*
776 * Nuke neighbor cache entries for the ifp. 790 * Nuke neighbor cache entries for the ifp.
777 * Note that rt->rt_ifp may not be the same as ifp, 791 * Note that rt->rt_ifp may not be the same as ifp,
778 * due to KAME goto ours hack. See RTM_RESOLVE case in 792 * due to KAME goto ours hack. See RTM_RESOLVE case in
779 * nd6_rtrequest(), and ip6_input(). 793 * nd6_rtrequest(), and ip6_input().
780 */ 794 */
781 ln = llinfo_nd6.ln_next; 795 ln = llinfo_nd6.ln_next;
782 while (ln != NULL && ln != &llinfo_nd6) { 796 while (ln != NULL && ln != &llinfo_nd6) {
783 struct rtentry *rt; 797 struct rtentry *rt;
@@ -1875,27 +1889,27 @@ fail: @@ -1875,27 +1889,27 @@ fail:
1875 * created, it might affect the selection policy. 1889 * created, it might affect the selection policy.
1876 * Question: can we restrict the first condition to the "is_newentry" 1890 * Question: can we restrict the first condition to the "is_newentry"
1877 * case? 1891 * case?
1878 * XXX: when we hear an RA from a new router with the link-layer 1892 * XXX: when we hear an RA from a new router with the link-layer
1879 * address option, defrouter_select() is called twice, since 1893 * address option, defrouter_select() is called twice, since
1880 * defrtrlist_update called the function as well. However, I believe 1894 * defrtrlist_update called the function as well. However, I believe
1881 * we can compromise the overhead, since it only happens the first 1895 * we can compromise the overhead, since it only happens the first
1882 * time. 1896 * time.
1883 * XXX: although defrouter_select() should not have a bad effect 1897 * XXX: although defrouter_select() should not have a bad effect
1884 * for those are not autoconfigured hosts, we explicitly avoid such 1898 * for those are not autoconfigured hosts, we explicitly avoid such
1885 * cases for safety. 1899 * cases for safety.
1886 */ 1900 */
1887 if (do_update && ln->ln_router && !ip6_forwarding && 1901 if (do_update && ln->ln_router && !ip6_forwarding &&
1888 (ndi->flags & ND6_IFF_ACCEPT_RTADV)) 1902 nd6_accepts_rtadv(ndi))
1889 defrouter_select(); 1903 defrouter_select();
1890 1904
1891 return rt; 1905 return rt;
1892} 1906}
1893 1907
1894static void 1908static void
1895nd6_slowtimo(void *ignored_arg) 1909nd6_slowtimo(void *ignored_arg)
1896{ 1910{
1897 struct nd_ifinfo *nd6if; 1911 struct nd_ifinfo *nd6if;
1898 struct ifnet *ifp; 1912 struct ifnet *ifp;
1899 1913
1900 mutex_enter(softnet_lock); 1914 mutex_enter(softnet_lock);
1901 KERNEL_LOCK(1, NULL); 1915 KERNEL_LOCK(1, NULL);

cvs diff -r1.52 -r1.53 src/sys/netinet6/nd6.h (expand / switch to unified diff)

--- src/sys/netinet6/nd6.h 2009/01/15 18:20:48 1.52
+++ src/sys/netinet6/nd6.h 2009/11/06 20:41:22 1.53
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: nd6.h,v 1.52 2009/01/15 18:20:48 christos Exp $ */ 1/* $NetBSD: nd6.h,v 1.53 2009/11/06 20:41:22 dyoung Exp $ */
2/* $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $ */ 2/* $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -80,32 +80,55 @@ struct nd_ifinfo { @@ -80,32 +80,55 @@ struct nd_ifinfo {
80 u_int32_t basereachable; /* BaseReachableTime */ 80 u_int32_t basereachable; /* BaseReachableTime */
81 u_int32_t reachable; /* Reachable Time */ 81 u_int32_t reachable; /* Reachable Time */
82 u_int32_t retrans; /* Retrans Timer */ 82 u_int32_t retrans; /* Retrans Timer */
83 u_int32_t flags; /* Flags */ 83 u_int32_t flags; /* Flags */
84 int recalctm; /* BaseReacable re-calculation timer */ 84 int recalctm; /* BaseReacable re-calculation timer */
85 u_int8_t chlim; /* CurHopLimit */ 85 u_int8_t chlim; /* CurHopLimit */
86 u_int8_t initialized; /* Flag to see the entry is initialized */ 86 u_int8_t initialized; /* Flag to see the entry is initialized */
87 /* the following 3 members are for privacy extension for addrconf */ 87 /* the following 3 members are for privacy extension for addrconf */
88 u_int8_t randomseed0[8]; /* upper 64 bits of MD5 digest */ 88 u_int8_t randomseed0[8]; /* upper 64 bits of MD5 digest */
89 u_int8_t randomseed1[8]; /* lower 64 bits (usually the EUI64 IFID) */ 89 u_int8_t randomseed1[8]; /* lower 64 bits (usually the EUI64 IFID) */
90 u_int8_t randomid[8]; /* current random ID */ 90 u_int8_t randomid[8]; /* current random ID */
91}; 91};
92 92
93#define ND6_IFF_PERFORMNUD 0x1 93#define ND6_IFF_PERFORMNUD 0x01
94#define ND6_IFF_ACCEPT_RTADV 0x2 94#define ND6_IFF_ACCEPT_RTADV 0x02 /* See "RTADV Key", below. */
95#define ND6_IFF_PREFER_SOURCE 0x4 /* XXX: not related to ND. */ 95#define ND6_IFF_PREFER_SOURCE 0x04 /* XXX: not related to ND. */
96#define ND6_IFF_IFDISABLED 0x8 /* IPv6 operation is disabled due to 96#define ND6_IFF_IFDISABLED 0x08 /* IPv6 operation is disabled due to
97 * DAD failure. (XXX: not ND-specific) 97 * DAD failure. (XXX: not ND-specific)
98 */ 98 */
 99#define ND6_IFF_OVERRIDE_RTADV 0x10 /* See "RTADV Key", below. */
 100
 101/*
 102 * RTADV Key
 103 *
 104 * The flags ND6_IFF_ACCEPT_RTADV and ND6_IFF_OVERRIDE_RTADV form a
 105 * tri-state variable. (There are actually four different states, but
 106 * two of the states are functionally identical.)
 107 *
 108 * ND6_IFF_OVERRIDE_RTADV or 0: This interface does not accept
 109 * Router Advertisements.
 110 *
 111 * ND6_IFF_OVERRIDE_RTADV|
 112 * ND6_IFF_ACCEPT_RTADV: This interface accepts Router
 113 * Advertisements regardless of the
 114 * global setting, ip6_accept_rtadv.
 115 *
 116 * ND6_IFF_ACCEPT_RTADV: This interface follows the global setting,
 117 * ip6_accept_rtadv. If ip6_accept_rtadv == 0,
 118 * this interface does not accept Router
 119 * Advertisements. If ip6_accept_rtadv != 0,
 120 * this interface does accept them.
 121 */
99 122
100#ifdef _KERNEL 123#ifdef _KERNEL
101#define ND_IFINFO(ifp) \ 124#define ND_IFINFO(ifp) \
102 (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->nd_ifinfo) 125 (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->nd_ifinfo)
103#define IN6_LINKMTU(ifp) \ 126#define IN6_LINKMTU(ifp) \
104 ((ND_IFINFO(ifp)->linkmtu && ND_IFINFO(ifp)->linkmtu < (ifp)->if_mtu) \ 127 ((ND_IFINFO(ifp)->linkmtu && ND_IFINFO(ifp)->linkmtu < (ifp)->if_mtu) \
105 ? ND_IFINFO(ifp)->linkmtu \ 128 ? ND_IFINFO(ifp)->linkmtu \
106 : ((ND_IFINFO(ifp)->maxmtu && ND_IFINFO(ifp)->maxmtu < (ifp)->if_mtu) \ 129 : ((ND_IFINFO(ifp)->maxmtu && ND_IFINFO(ifp)->maxmtu < (ifp)->if_mtu) \
107 ? ND_IFINFO(ifp)->maxmtu : (ifp)->if_mtu)) 130 ? ND_IFINFO(ifp)->maxmtu : (ifp)->if_mtu))
108#endif 131#endif
109 132
110struct in6_nbrinfo { 133struct in6_nbrinfo {
111 char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */ 134 char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */
@@ -427,17 +450,18 @@ void defrouter_select(void); @@ -427,17 +450,18 @@ void defrouter_select(void);
427void defrtrlist_del(struct nd_defrouter *); 450void defrtrlist_del(struct nd_defrouter *);
428void prelist_remove(struct nd_prefix *); 451void prelist_remove(struct nd_prefix *);
429int nd6_prelist_add(struct nd_prefixctl *, struct nd_defrouter *, 452int nd6_prelist_add(struct nd_prefixctl *, struct nd_defrouter *,
430 struct nd_prefix **); 453 struct nd_prefix **);
431int nd6_prefix_onlink(struct nd_prefix *); 454int nd6_prefix_onlink(struct nd_prefix *);
432int nd6_prefix_offlink(struct nd_prefix *); 455int nd6_prefix_offlink(struct nd_prefix *);
433void pfxlist_onlink_check(void); 456void pfxlist_onlink_check(void);
434struct nd_defrouter *defrouter_lookup(const struct in6_addr *, struct ifnet *); 457struct nd_defrouter *defrouter_lookup(const struct in6_addr *, struct ifnet *);
435struct nd_prefix *nd6_prefix_lookup(struct nd_prefixctl *); 458struct nd_prefix *nd6_prefix_lookup(struct nd_prefixctl *);
436int in6_ifdel(struct ifnet *, struct in6_addr *); 459int in6_ifdel(struct ifnet *, struct in6_addr *);
437void rt6_flush(struct in6_addr *, struct ifnet *); 460void rt6_flush(struct in6_addr *, struct ifnet *);
438int nd6_setdefaultiface(int); 461int nd6_setdefaultiface(int);
439int in6_tmpifadd(const struct in6_ifaddr *, int, int); 462int in6_tmpifadd(const struct in6_ifaddr *, int, int);
 463bool nd6_accepts_rtadv(const struct nd_ifinfo *);
440 464
441#endif /* _KERNEL */ 465#endif /* _KERNEL */
442 466
443#endif /* !_NETINET6_ND6_H_ */ 467#endif /* !_NETINET6_ND6_H_ */

cvs diff -r1.79 -r1.80 src/sys/netinet6/nd6_rtr.c (expand / switch to unified diff)

--- src/sys/netinet6/nd6_rtr.c 2009/07/25 23:12:09 1.79
+++ src/sys/netinet6/nd6_rtr.c 2009/11/06 20:41:22 1.80
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: nd6_rtr.c,v 1.79 2009/07/25 23:12:09 tonnerre Exp $ */ 1/* $NetBSD: nd6_rtr.c,v 1.80 2009/11/06 20:41:22 dyoung Exp $ */
2/* $KAME: nd6_rtr.c,v 1.95 2001/02/07 08:09:47 itojun Exp $ */ 2/* $KAME: nd6_rtr.c,v 1.95 2001/02/07 08:09:47 itojun Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -21,27 +21,27 @@ @@ -21,27 +21,27 @@
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE. 30 * SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.79 2009/07/25 23:12:09 tonnerre Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.80 2009/11/06 20:41:22 dyoung Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38#include <sys/malloc.h> 38#include <sys/malloc.h>
39#include <sys/mbuf.h> 39#include <sys/mbuf.h>
40#include <sys/socket.h> 40#include <sys/socket.h>
41#include <sys/sockio.h> 41#include <sys/sockio.h>
42#include <sys/time.h> 42#include <sys/time.h>
43#include <sys/kernel.h> 43#include <sys/kernel.h>
44#include <sys/errno.h> 44#include <sys/errno.h>
45#include <sys/ioctl.h> 45#include <sys/ioctl.h>
46#include <sys/syslog.h> 46#include <sys/syslog.h>
47 47
@@ -112,27 +112,27 @@ int ip6_temp_regen_advance = TEMPADDR_RE @@ -112,27 +112,27 @@ int ip6_temp_regen_advance = TEMPADDR_RE
112void 112void
113nd6_rs_input(struct mbuf *m, int off, int icmp6len) 113nd6_rs_input(struct mbuf *m, int off, int icmp6len)
114{ 114{
115 struct ifnet *ifp = m->m_pkthdr.rcvif; 115 struct ifnet *ifp = m->m_pkthdr.rcvif;
116 struct nd_ifinfo *ndi = ND_IFINFO(ifp); 116 struct nd_ifinfo *ndi = ND_IFINFO(ifp);
117 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 117 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
118 struct nd_router_solicit *nd_rs; 118 struct nd_router_solicit *nd_rs;
119 struct in6_addr saddr6 = ip6->ip6_src; 119 struct in6_addr saddr6 = ip6->ip6_src;
120 char *lladdr = NULL; 120 char *lladdr = NULL;
121 int lladdrlen = 0; 121 int lladdrlen = 0;
122 union nd_opts ndopts; 122 union nd_opts ndopts;
123 123
124 /* If I'm not a router, ignore it. */ 124 /* If I'm not a router, ignore it. */
125 if ((ndi->flags & ND6_IFF_ACCEPT_RTADV) || !ip6_forwarding) 125 if (nd6_accepts_rtadv(ndi) || !ip6_forwarding)
126 goto freeit; 126 goto freeit;
127 127
128 /* Sanity checks */ 128 /* Sanity checks */
129 if (ip6->ip6_hlim != 255) { 129 if (ip6->ip6_hlim != 255) {
130 nd6log((LOG_ERR, 130 nd6log((LOG_ERR,
131 "nd6_rs_input: invalid hlim (%d) from %s to %s on %s\n", 131 "nd6_rs_input: invalid hlim (%d) from %s to %s on %s\n",
132 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src), 132 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src),
133 ip6_sprintf(&ip6->ip6_dst), if_name(ifp))); 133 ip6_sprintf(&ip6->ip6_dst), if_name(ifp)));
134 goto bad; 134 goto bad;
135 } 135 }
136 136
137 /* 137 /*
138 * Don't update the neighbor cache, if src = ::. 138 * Don't update the neighbor cache, if src = ::.
@@ -200,27 +200,27 @@ nd6_ra_input(struct mbuf *m, int off, in @@ -200,27 +200,27 @@ nd6_ra_input(struct mbuf *m, int off, in
200 int flags; /* = nd_ra->nd_ra_flags_reserved; */ 200 int flags; /* = nd_ra->nd_ra_flags_reserved; */
201 int is_managed = ((flags & ND_RA_FLAG_MANAGED) != 0); 201 int is_managed = ((flags & ND_RA_FLAG_MANAGED) != 0);
202 int is_other = ((flags & ND_RA_FLAG_OTHER) != 0); 202 int is_other = ((flags & ND_RA_FLAG_OTHER) != 0);
203#endif 203#endif
204 int mcast = 0; 204 int mcast = 0;
205 union nd_opts ndopts; 205 union nd_opts ndopts;
206 struct nd_defrouter *dr; 206 struct nd_defrouter *dr;
207 207
208 /* 208 /*
209 * We only accept RAs only when 209 * We only accept RAs only when
210 * the system-wide variable allows the acceptance, and 210 * the system-wide variable allows the acceptance, and
211 * per-interface variable allows RAs on the receiving interface. 211 * per-interface variable allows RAs on the receiving interface.
212 */ 212 */
213 if (!(ndi->flags & ND6_IFF_ACCEPT_RTADV)) 213 if (!nd6_accepts_rtadv(ndi))
214 goto freeit; 214 goto freeit;
215 215
216 if (ip6->ip6_hlim != 255) { 216 if (ip6->ip6_hlim != 255) {
217 nd6log((LOG_ERR, 217 nd6log((LOG_ERR,
218 "nd6_ra_input: invalid hlim (%d) from %s to %s on %s\n", 218 "nd6_ra_input: invalid hlim (%d) from %s to %s on %s\n",
219 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src), 219 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src),
220 ip6_sprintf(&ip6->ip6_dst), if_name(ifp))); 220 ip6_sprintf(&ip6->ip6_dst), if_name(ifp)));
221 goto bad; 221 goto bad;
222 } 222 }
223 223
224 if (!IN6_IS_ADDR_LINKLOCAL(&saddr6)) { 224 if (!IN6_IS_ADDR_LINKLOCAL(&saddr6)) {
225 nd6log((LOG_ERR, 225 nd6log((LOG_ERR,
226 "nd6_ra_input: src %s is not link-local\n", 226 "nd6_ra_input: src %s is not link-local\n",
@@ -480,27 +480,27 @@ defrouter_lookup(const struct in6_addr * @@ -480,27 +480,27 @@ defrouter_lookup(const struct in6_addr *
480 480
481void 481void
482defrtrlist_del(struct nd_defrouter *dr) 482defrtrlist_del(struct nd_defrouter *dr)
483{ 483{
484 struct nd_ifinfo *ndi = ND_IFINFO(dr->ifp); 484 struct nd_ifinfo *ndi = ND_IFINFO(dr->ifp);
485 struct nd_defrouter *deldr = NULL; 485 struct nd_defrouter *deldr = NULL;
486 struct nd_prefix *pr; 486 struct nd_prefix *pr;
487 487
488 /* 488 /*
489 * Flush all the routing table entries that use the router 489 * Flush all the routing table entries that use the router
490 * as a next hop. 490 * as a next hop.
491 */ 491 */
492 /* XXX: better condition? */ 492 /* XXX: better condition? */
493 if (!ip6_forwarding && (ndi->flags & ND6_IFF_ACCEPT_RTADV)) 493 if (!ip6_forwarding && nd6_accepts_rtadv(ndi))
494 rt6_flush(&dr->rtaddr, dr->ifp); 494 rt6_flush(&dr->rtaddr, dr->ifp);
495 495
496 if (dr->installed) { 496 if (dr->installed) {
497 deldr = dr; 497 deldr = dr;
498 defrouter_delreq(dr); 498 defrouter_delreq(dr);
499 } 499 }
500 TAILQ_REMOVE(&nd_defrouter, dr, dr_entry); 500 TAILQ_REMOVE(&nd_defrouter, dr, dr_entry);
501 501
502 /* 502 /*
503 * Also delete all the pointers to the router in each prefix lists. 503 * Also delete all the pointers to the router in each prefix lists.
504 */ 504 */
505 LIST_FOREACH(pr, &nd_prefix, ndpr_entry) { 505 LIST_FOREACH(pr, &nd_prefix, ndpr_entry) {
506 struct nd_pfxrouter *pfxrtr; 506 struct nd_pfxrouter *pfxrtr;
@@ -636,27 +636,27 @@ defrouter_select(void) @@ -636,27 +636,27 @@ defrouter_select(void)
636 if (!TAILQ_FIRST(&nd_defrouter)) { 636 if (!TAILQ_FIRST(&nd_defrouter)) {
637 splx(s); 637 splx(s);
638 return; 638 return;
639 } 639 }
640 640
641 /* 641 /*
642 * Search for a (probably) reachable router from the list. 642 * Search for a (probably) reachable router from the list.
643 * We just pick up the first reachable one (if any), assuming that 643 * We just pick up the first reachable one (if any), assuming that
644 * the ordering rule of the list described in defrtrlist_update(). 644 * the ordering rule of the list described in defrtrlist_update().
645 */ 645 */
646 for (dr = TAILQ_FIRST(&nd_defrouter); dr; 646 for (dr = TAILQ_FIRST(&nd_defrouter); dr;
647 dr = TAILQ_NEXT(dr, dr_entry)) { 647 dr = TAILQ_NEXT(dr, dr_entry)) {
648 ndi = ND_IFINFO(dr->ifp); 648 ndi = ND_IFINFO(dr->ifp);
649 if ((ndi->flags & ND6_IFF_ACCEPT_RTADV)) 649 if (nd6_accepts_rtadv(ndi))
650 continue; 650 continue;
651 651
652 if (selected_dr == NULL && 652 if (selected_dr == NULL &&
653 (rt = nd6_lookup(&dr->rtaddr, 0, dr->ifp)) != NULL && 653 (rt = nd6_lookup(&dr->rtaddr, 0, dr->ifp)) != NULL &&
654 (ln = (struct llinfo_nd6 *)rt->rt_llinfo) != NULL && 654 (ln = (struct llinfo_nd6 *)rt->rt_llinfo) != NULL &&
655 ND6_IS_LLINFO_PROBREACH(ln)) { 655 ND6_IS_LLINFO_PROBREACH(ln)) {
656 selected_dr = dr; 656 selected_dr = dr;
657 } 657 }
658 658
659 if (dr->installed && !installed_dr) 659 if (dr->installed && !installed_dr)
660 installed_dr = dr; 660 installed_dr = dr;
661 else if (dr->installed && installed_dr) { 661 else if (dr->installed && installed_dr) {
662 /* this should not happen. warn for diagnosis. */ 662 /* this should not happen. warn for diagnosis. */