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.diff -r1.134 -r1.135 src/sys/netinet6/nd6.c
(dyoung)
--- 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 | |||
188 | void | 187 | void | |
189 | nd6_ifdetach(struct nd_ifinfo *nd) | 188 | nd6_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 | |||
706 | bool | |||
707 | nd6_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 | */ | |
711 | void | 725 | void | |
712 | nd6_purge(struct ifnet *ifp) | 726 | nd6_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 | |||
1894 | static void | 1908 | static void | |
1895 | nd6_slowtimo(void *ignored_arg) | 1909 | nd6_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); |
--- 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 | |||
110 | struct in6_nbrinfo { | 133 | struct 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); | |||
427 | void defrtrlist_del(struct nd_defrouter *); | 450 | void defrtrlist_del(struct nd_defrouter *); | |
428 | void prelist_remove(struct nd_prefix *); | 451 | void prelist_remove(struct nd_prefix *); | |
429 | int nd6_prelist_add(struct nd_prefixctl *, struct nd_defrouter *, | 452 | int nd6_prelist_add(struct nd_prefixctl *, struct nd_defrouter *, | |
430 | struct nd_prefix **); | 453 | struct nd_prefix **); | |
431 | int nd6_prefix_onlink(struct nd_prefix *); | 454 | int nd6_prefix_onlink(struct nd_prefix *); | |
432 | int nd6_prefix_offlink(struct nd_prefix *); | 455 | int nd6_prefix_offlink(struct nd_prefix *); | |
433 | void pfxlist_onlink_check(void); | 456 | void pfxlist_onlink_check(void); | |
434 | struct nd_defrouter *defrouter_lookup(const struct in6_addr *, struct ifnet *); | 457 | struct nd_defrouter *defrouter_lookup(const struct in6_addr *, struct ifnet *); | |
435 | struct nd_prefix *nd6_prefix_lookup(struct nd_prefixctl *); | 458 | struct nd_prefix *nd6_prefix_lookup(struct nd_prefixctl *); | |
436 | int in6_ifdel(struct ifnet *, struct in6_addr *); | 459 | int in6_ifdel(struct ifnet *, struct in6_addr *); | |
437 | void rt6_flush(struct in6_addr *, struct ifnet *); | 460 | void rt6_flush(struct in6_addr *, struct ifnet *); | |
438 | int nd6_setdefaultiface(int); | 461 | int nd6_setdefaultiface(int); | |
439 | int in6_tmpifadd(const struct in6_ifaddr *, int, int); | 462 | int in6_tmpifadd(const struct in6_ifaddr *, int, int); | |
463 | bool 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_ */ |
--- 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 | |||
112 | void | 112 | void | |
113 | nd6_rs_input(struct mbuf *m, int off, int icmp6len) | 113 | nd6_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 | |||
481 | void | 481 | void | |
482 | defrtrlist_del(struct nd_defrouter *dr) | 482 | defrtrlist_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. */ |