summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorhrs <hrs@FreeBSD.org>2013-07-02 16:58:15 +0000
committerhrs <hrs@FreeBSD.org>2013-07-02 16:58:15 +0000
commit50e0add9e4de4d5547753f15e5df2059b5ee1f11 (patch)
tree8775244886e162bc495c5bb160eb522c8ecc72c6 /sys/netinet6
parentb3bce89084554d40481243aa35610916fd7cf077 (diff)
downloadFreeBSD-src-50e0add9e4de4d5547753f15e5df2059b5ee1f11.zip
FreeBSD-src-50e0add9e4de4d5547753f15e5df2059b5ee1f11.tar.gz
- Allow ND6_IFF_AUTO_LINKLOCAL for IFT_BRIDGE. An interface with IFT_BRIDGE
is initialized with !ND6_IFF_AUTO_LINKLOCAL && !ND6_IFF_ACCEPT_RTADV regardless of net.inet6.ip6.accept_rtadv and net.inet6.ip6.auto_linklocal. To configure an autoconfigured link-local address (RFC 4862), the following rc.conf(5) configuration can be used: ifconfig_bridge0_ipv6="inet6 auto_linklocal" - if_bridge(4) now removes IPv6 addresses on a member interface to be added when the parent interface or one of the existing member interfaces has an IPv6 address. if_bridge(4) merges each link-local scope zone which the member interfaces form respectively, so it causes address scope violation. Removal of the IPv6 addresses prevents it. - if_lagg(4) now removes IPv6 addresses on a member interfaces unconditionally. - Set reasonable flags to non-IPv6-capable interfaces. [*] Submitted by: rpaulo [*] MFC after: 1 week
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6.c26
-rw-r--r--sys/netinet6/in6_ifattach.c15
-rw-r--r--sys/netinet6/in6_var.h1
-rw-r--r--sys/netinet6/nd6.c24
4 files changed, 51 insertions, 15 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 80359c1..9e005c5 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1987,6 +1987,32 @@ in6ifa_ifpwithaddr(struct ifnet *ifp, struct in6_addr *addr)
}
/*
+ * Find a link-local scoped address on ifp and return it if any.
+ */
+struct in6_ifaddr *
+in6ifa_llaonifp(struct ifnet *ifp)
+{
+ struct sockaddr_in6 *sin6;
+ struct ifaddr *ifa;
+
+ if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)
+ return (NULL);
+ if_addr_rlock(ifp);
+ TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+ if (ifa->ifa_addr->sa_family != AF_INET6)
+ continue;
+ sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
+ if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr) ||
+ IN6_IS_ADDR_MC_INTFACELOCAL(&sin6->sin6_addr) ||
+ IN6_IS_ADDR_MC_NODELOCAL(&sin6->sin6_addr))
+ break;
+ }
+ if_addr_runlock(ifp);
+
+ return ((struct in6_ifaddr *)ifa);
+}
+
+/*
* Convert IP6 address to printable (loggable) representation. Caller
* has to make sure that ip6buf is at least INET6_ADDRSTRLEN long.
*/
diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c
index 85890ab..674356a 100644
--- a/sys/netinet6/in6_ifattach.c
+++ b/sys/netinet6/in6_ifattach.c
@@ -266,6 +266,7 @@ found:
/* get EUI64 */
switch (ifp->if_type) {
+ case IFT_BRIDGE:
case IFT_ETHER:
case IFT_L2VLAN:
case IFT_FDDI:
@@ -727,6 +728,8 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp)
switch (ifp->if_type) {
case IFT_PFLOG:
case IFT_PFSYNC:
+ ND_IFINFO(ifp)->flags &= ~ND6_IFF_AUTO_LINKLOCAL;
+ ND_IFINFO(ifp)->flags |= ND6_IFF_IFDISABLED;
return;
}
@@ -734,7 +737,6 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp)
* quirks based on interface type
*/
switch (ifp->if_type) {
-#ifdef IFT_STF
case IFT_STF:
/*
* 6to4 interface is a very special kind of beast.
@@ -742,8 +744,8 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp)
* linklocals for 6to4 interface, but there's no use and
* it is rather harmful to have one.
*/
- goto statinit;
-#endif
+ ND_IFINFO(ifp)->flags &= ~ND6_IFF_AUTO_LINKLOCAL;
+ break;
default:
break;
}
@@ -777,8 +779,7 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp)
/*
* assign a link-local address, if there's none.
*/
- if (ifp->if_type != IFT_BRIDGE &&
- !(ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) &&
+ if (!(ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) &&
ND_IFINFO(ifp)->flags & ND6_IFF_AUTO_LINKLOCAL) {
int error;
@@ -795,10 +796,6 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp)
ifa_free(&ia->ia_ifa);
}
-#ifdef IFT_STF /* XXX */
-statinit:
-#endif
-
/* update dynamically. */
if (V_in6_maxmtu < ifp->if_mtu)
V_in6_maxmtu = ifp->if_mtu;
diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h
index 3b4e89e..b3f7218 100644
--- a/sys/netinet6/in6_var.h
+++ b/sys/netinet6/in6_var.h
@@ -800,6 +800,7 @@ void in6_setmaxmtu(void);
int in6_if2idlen(struct ifnet *);
struct in6_ifaddr *in6ifa_ifpforlinklocal(struct ifnet *, int);
struct in6_ifaddr *in6ifa_ifpwithaddr(struct ifnet *, struct in6_addr *);
+struct in6_ifaddr *in6ifa_llaonifp(struct ifnet *);
char *ip6_sprintf(char *, const struct in6_addr *);
int in6_addr2zoneid(struct ifnet *, struct in6_addr *, u_int32_t *);
int in6_matchlen(struct in6_addr *, struct in6_addr *);
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index 0e30825..0a67a8a 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -176,13 +176,25 @@ nd6_ifattach(struct ifnet *ifp)
nd->flags = ND6_IFF_PERFORMNUD;
- /* A loopback interface always has ND6_IFF_AUTO_LINKLOCAL. */
- if (V_ip6_auto_linklocal || (ifp->if_flags & IFF_LOOPBACK))
+ /* A loopback interface always has ND6_IFF_AUTO_LINKLOCAL.
+ * XXXHRS: Clear ND6_IFF_AUTO_LINKLOCAL on an IFT_BRIDGE interface by
+ * default regardless of the V_ip6_auto_linklocal configuration to
+ * give a reasonable default behavior.
+ */
+ if ((V_ip6_auto_linklocal && ifp->if_type != IFT_BRIDGE) ||
+ (ifp->if_flags & IFF_LOOPBACK))
nd->flags |= ND6_IFF_AUTO_LINKLOCAL;
-
- /* A loopback interface does not need to accept RTADV. */
- if (V_ip6_accept_rtadv && !(ifp->if_flags & IFF_LOOPBACK))
- nd->flags |= ND6_IFF_ACCEPT_RTADV;
+ /*
+ * A loopback interface does not need to accept RTADV.
+ * XXXHRS: Clear ND6_IFF_ACCEPT_RTADV on an IFT_BRIDGE interface by
+ * default regardless of the V_ip6_accept_rtadv configuration to
+ * prevent the interface from accepting RA messages arrived
+ * on one of the member interfaces with ND6_IFF_ACCEPT_RTADV.
+ */
+ if (V_ip6_accept_rtadv &&
+ !(ifp->if_flags & IFF_LOOPBACK) &&
+ (ifp->if_type != IFT_BRIDGE))
+ nd->flags |= ND6_IFF_ACCEPT_RTADV;
if (V_ip6_no_radr && !(ifp->if_flags & IFF_LOOPBACK))
nd->flags |= ND6_IFF_NO_RADR;
OpenPOWER on IntegriCloud