diff options
author | Bruce M Simpson <bms@FreeBSD.org> | 2009-04-29 19:19:13 +0000 |
---|---|---|
committer | Bruce M Simpson <bms@FreeBSD.org> | 2009-04-29 19:19:13 +0000 |
commit | 33cde13046eaba762428c55bb5d5e07c1a7c5f33 (patch) | |
tree | 51d9a006ee48417962ce45f044b7e5603910fe13 /sys/netinet6/ip6_mroute.c | |
parent | af7bd9a4f4fca52a1c9c48858b5e18d332ca03b9 (diff) | |
download | src-33cde13046eaba762428c55bb5d5e07c1a7c5f33.tar.gz src-33cde13046eaba762428c55bb5d5e07c1a7c5f33.zip |
Bite the bullet, and make the IPv6 SSM and MLDv2 mega-commit:
import from p4 bms_netdev. Summary of changes:
* Connect netinet6/in6_mcast.c to build.
The legacy KAME KPIs are mostly preserved.
* Eliminate now dead code from ip6_output.c.
Don't do mbuf bingo, we are not going to do RFC 2292 style
CMSG tricks for multicast options as they are not required
by any current IPv6 normative reference.
* Refactor transports (UDP, raw_ip6) to do own mcast filtering.
SCTP, TCP unaffected by this change.
* Add ip6_msource, in6_msource structs to in6_var.h.
* Hookup mld_ifinfo state to in6_ifextra, allocate from
domifattach path.
* Eliminate IN6_LOOKUP_MULTI(), it is no longer referenced.
Kernel consumers which need this should use in6m_lookup().
* Refactor IPv6 socket group memberships to use a vector (like IPv4).
* Update ifmcstat(8) for IPv6 SSM.
* Add witness lock order for IN6_MULTI_LOCK.
* Move IN6_MULTI_LOCK out of lower ip6_output()/ip6_input() paths.
* Introduce IP6STAT_ADD/SUB/INC/DEC as per rwatson's IPv4 cleanup.
* Update carp(4) for new IPv6 SSM KPIs.
* Virtualize ip6_mrouter socket.
Changes mostly localized to IPv6 MROUTING.
* Don't do a local group lookup in MROUTING.
* Kill unused KAME prototypes in6_purgemkludge(), in6_restoremkludge().
* Preserve KAME DAD timer jitter behaviour in MLDv1 compatibility mode.
* Bump __FreeBSD_version to 800084.
* Update UPDATING.
NOTE WELL:
* This code hasn't been tested against real MLDv2 queriers
(yet), although the on-wire protocol has been verified in Wireshark.
* There are a few unresolved issues in the socket layer APIs to
do with scope ID propagation.
* There is a LOR present in ip6_output()'s use of
in6_setscope() which needs to be resolved. See comments in mld6.c.
This is believed to be benign and can't be avoided for the moment
without re-introducing an indirect netisr.
This work was mostly derived from the IGMPv3 implementation, and
has been sponsored by a third party.
Notes
Notes:
svn path=/head/; revision=191672
Diffstat (limited to 'sys/netinet6/ip6_mroute.c')
-rw-r--r-- | sys/netinet6/ip6_mroute.c | 34 |
1 files changed, 18 insertions, 16 deletions
diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c index 29201d65d6ae..a88a9a17af27 100644 --- a/sys/netinet6/ip6_mroute.c +++ b/sys/netinet6/ip6_mroute.c @@ -93,6 +93,7 @@ __FBSDID("$FreeBSD$"); #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/module.h> +#include <sys/domain.h> #include <sys/protosw.h> #include <sys/signalvar.h> #include <sys/socket.h> @@ -140,6 +141,7 @@ static int set_pim6(int *); static int socket_send(struct socket *, struct mbuf *, struct sockaddr_in6 *); +extern int in6_mcast_loop; extern struct domain inet6domain; static const struct encaptab *pim6_encap_cookie; @@ -367,7 +369,7 @@ X_ip6_mrouter_set(struct socket *so, struct sockopt *sopt) struct mf6cctl mfcc; mifi_t mifi; - if (so != ip6_mrouter && sopt->sopt_name != MRT6_INIT) + if (so != V_ip6_mrouter && sopt->sopt_name != MRT6_INIT) return (EACCES); switch (sopt->sopt_name) { @@ -432,7 +434,7 @@ X_ip6_mrouter_get(struct socket *so, struct sockopt *sopt) INIT_VNET_INET6(curvnet); int error = 0; - if (so != ip6_mrouter) + if (so != V_ip6_mrouter) return (EACCES); switch (sopt->sopt_name) { @@ -560,12 +562,12 @@ ip6_mrouter_init(struct socket *so, int v, int cmd) MROUTER6_LOCK(); - if (ip6_mrouter != NULL) { + if (V_ip6_mrouter != NULL) { MROUTER6_UNLOCK(); return (EADDRINUSE); } - ip6_mrouter = so; + V_ip6_mrouter = so; V_ip6_mrouter_ver = cmd; bzero((caddr_t)mf6ctable, sizeof(mf6ctable)); @@ -601,7 +603,7 @@ X_ip6_mrouter_done(void) MROUTER6_LOCK(); - if (ip6_mrouter == NULL) { + if (V_ip6_mrouter == NULL) { MROUTER6_UNLOCK(); return (EINVAL); } @@ -657,7 +659,7 @@ X_ip6_mrouter_done(void) multicast_register_if6 = NULL; } - ip6_mrouter = NULL; + V_ip6_mrouter = NULL; V_ip6_mrouter_ver = 0; MROUTER6_UNLOCK(); @@ -1293,7 +1295,7 @@ X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m) break; } - if (socket_send(ip6_mrouter, mm, &sin6) < 0) { + if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) { log(LOG_WARNING, "ip6_mforward: ip6_mrouter " "socket queue full\n"); mrt6stat.mrt6s_upq_sockfull++; @@ -1531,7 +1533,7 @@ ip6_mdq(struct mbuf *m, struct ifnet *ifp, struct mf6c *rt) mrt6stat.mrt6s_upcalls++; - if (socket_send(ip6_mrouter, mm, &sin6) < 0) { + if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) { #ifdef MRT6DEBUG if (V_mrt6debug) log(LOG_WARNING, "mdq, ip6_mrouter socket queue full\n"); @@ -1603,10 +1605,11 @@ phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m) struct mbuf *mb_copy; struct ifnet *ifp = mifp->m6_ifp; int error = 0; - struct in6_multi *in6m; struct sockaddr_in6 *dst6; u_long linkmtu; + dst6 = &mifp->m6_route.ro_dst; + /* * Make a new reference to the packet; make sure that * the IPv6 header is actually copied, not just referenced, @@ -1648,17 +1651,16 @@ phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m) } /* - * If we belong to the destination multicast group - * on the outgoing interface, loop back a copy. + * If configured to loop back multicasts by default, + * loop back a copy now. */ - dst6 = &mifp->m6_route.ro_dst; - IN6_LOOKUP_MULTI(ip6->ip6_dst, ifp, in6m); - if (in6m != NULL) { + if (in6_mcast_loop) { dst6->sin6_len = sizeof(struct sockaddr_in6); dst6->sin6_family = AF_INET6; dst6->sin6_addr = ip6->ip6_dst; ip6_mloopback(ifp, m, &mifp->m6_route.ro_dst); } + /* * Put the packet into the sending queue of the outgoing interface * if it would fit in the MTU of the interface. @@ -1759,7 +1761,7 @@ register_send(struct ip6_hdr *ip6, struct mif6 *mif, struct mbuf *m) /* iif info is not given for reg. encap.n */ mrt6stat.mrt6s_upcalls++; - if (socket_send(ip6_mrouter, mm, &sin6) < 0) { + if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) { #ifdef MRT6DEBUG if (V_mrt6debug) log(LOG_WARNING, @@ -2056,7 +2058,7 @@ ip6_mroute_modevent(module_t mod, int type, void *unused) break; case MOD_UNLOAD: - if (ip6_mrouter != NULL) + if (V_ip6_mrouter != NULL) return EINVAL; if (pim6_encap_cookie) { |