summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/ip6_mroute.c
diff options
context:
space:
mode:
authorbms <bms@FreeBSD.org>2009-04-29 19:19:13 +0000
committerbms <bms@FreeBSD.org>2009-04-29 19:19:13 +0000
commit32a71137f08bc028578417de36a241d7e6011f58 (patch)
tree51d9a006ee48417962ce45f044b7e5603910fe13 /sys/netinet6/ip6_mroute.c
parent51a4d1c4a3d279a3638c0b40f351aa93f965c7df (diff)
downloadFreeBSD-src-32a71137f08bc028578417de36a241d7e6011f58.zip
FreeBSD-src-32a71137f08bc028578417de36a241d7e6011f58.tar.gz
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.
Diffstat (limited to 'sys/netinet6/ip6_mroute.c')
-rw-r--r--sys/netinet6/ip6_mroute.c34
1 files changed, 18 insertions, 16 deletions
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 <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) {
OpenPOWER on IntegriCloud