From 32a71137f08bc028578417de36a241d7e6011f58 Mon Sep 17 00:00:00 2001 From: bms Date: Wed, 29 Apr 2009 19:19:13 +0000 Subject: 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. --- sys/netinet6/ip6_mroute.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'sys/netinet6/ip6_mroute.c') diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c index 29201d6..a88a9a1 100644 --- a/sys/netinet6/ip6_mroute.c +++ b/sys/netinet6/ip6_mroute.c @@ -93,6 +93,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -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) { -- cgit v1.1