diff options
author | bms <bms@FreeBSD.org> | 2007-02-24 11:38:47 +0000 |
---|---|---|
committer | bms <bms@FreeBSD.org> | 2007-02-24 11:38:47 +0000 |
commit | 3e83ac665326a6a015b2179fc28157d9fb7433e2 (patch) | |
tree | 6230b66dd7bf83f11724dee78961a7c0020c9d31 /sys/netinet6 | |
parent | c553ec0508d385c07a87aed036312de1e3a64b03 (diff) | |
download | FreeBSD-src-3e83ac665326a6a015b2179fc28157d9fb7433e2.zip FreeBSD-src-3e83ac665326a6a015b2179fc28157d9fb7433e2.tar.gz |
Make IPv6 multicast forwarding dynamically loadable from a GENERIC kernel.
It is built in the same module as IPv4 multicast forwarding, i.e. ip_mroute.ko,
if and only if IPv6 support is enabled for loadable modules.
Export IPv6 forwarding structs to userland netstat(1) via sysctl(9).
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/in6.c | 2 | ||||
-rw-r--r-- | sys/netinet6/in6_proto.c | 2 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 3 | ||||
-rw-r--r-- | sys/netinet6/ip6_mroute.c | 63 | ||||
-rw-r--r-- | sys/netinet6/ip6_mroute.h | 8 | ||||
-rw-r--r-- | sys/netinet6/ip6_var.h | 4 | ||||
-rw-r--r-- | sys/netinet6/raw_ip6.c | 22 |
7 files changed, 77 insertions, 27 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 230f932..6aa0f9c 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -334,7 +334,7 @@ in6_control(so, cmd, data, ifp, td) switch (cmd) { case SIOCGETSGCNT_IN6: case SIOCGETMIFCNT_IN6: - return (mrt6_ioctl(cmd, data)); + return (mrt6_ioctl ? mrt6_ioctl(cmd, data) : EOPNOTSUPP); } switch(cmd) { diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index 6765102..6b2a92a 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -335,7 +335,7 @@ struct ip6protosw inet6sw[] = { .pr_domain = &inet6domain, .pr_protocol = IPPROTO_PIM, .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, - .pr_input = pim6_input, + .pr_input = encap6_input, .pr_output = rip6_output, .pr_ctloutput = rip6_ctloutput, .pr_usrreqs = &rip6_usrreqs diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 981c43a..099bdc7 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -696,7 +696,8 @@ passin: * ip6_mforward() returns a non-zero value, the packet * must be discarded, else it may be accepted below. */ - if (ip6_mrouter && ip6_mforward(ip6, m->m_pkthdr.rcvif, m)) { + if (ip6_mrouter && ip6_mforward && + ip6_mforward(ip6, m->m_pkthdr.rcvif, m)) { ip6stat.ip6s_cantforward++; m_freem(m); return; diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c index 1f86754..a6c238a 100644 --- a/sys/netinet6/ip6_mroute.c +++ b/sys/netinet6/ip6_mroute.c @@ -96,6 +96,7 @@ #include <sys/socketvar.h> #include <sys/sockio.h> #include <sys/sx.h> +#include <sys/sysctl.h> #include <sys/syslog.h> #include <sys/systm.h> #include <sys/time.h> @@ -114,6 +115,7 @@ #include <netinet6/scope6_var.h> #include <netinet6/nd6.h> #include <netinet6/ip6_mroute.h> +#include <netinet6/ip6protosw.h> #include <netinet6/pim6.h> #include <netinet6/pim6_var.h> @@ -130,6 +132,18 @@ static int socket_send __P((struct socket *, struct mbuf *, static int register_send __P((struct ip6_hdr *, struct mif6 *, struct mbuf *)); +extern struct domain inet6domain; +struct ip6protosw in6_pim_protosw = { + .pr_type = SOCK_RAW, + .pr_domain = &inet6domain, + .pr_protocol = IPPROTO_PIM, + .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, + .pr_input = pim6_input, + .pr_output = rip6_output, + .pr_ctloutput = rip6_ctloutput, + .pr_usrreqs = &rip6_usrreqs +}; + /* * Globals. All but ip6_mrouter, ip6_mrtproto and mrt6stat could be static, * except for netstat or debugging purposes. @@ -137,14 +151,32 @@ static int register_send __P((struct ip6_hdr *, struct mif6 *, struct socket *ip6_mrouter = NULL; int ip6_mrouter_ver = 0; int ip6_mrtproto = IPPROTO_PIM; /* for netstat only */ + +SYSCTL_DECL(_net_inet6); +SYSCTL_DECL(_net_inet6_ip6); +SYSCTL_NODE(_net_inet6, IPPROTO_PIM, pim, CTLFLAG_RW, 0, "PIM"); + struct mrt6stat mrt6stat; +SYSCTL_STRUCT(_net_inet6_ip6, OID_AUTO, mrt6stat, CTLFLAG_RW, + &mrt6stat, mrt6stat, + "Multicast Routing Statistics (struct mrt6stat, netinet6/ip6_mroute.h)"); #define NO_RTE_FOUND 0x1 #define RTE_FOUND 0x2 struct mf6c *mf6ctable[MF6CTBLSIZ]; +SYSCTL_OPAQUE(_net_inet6_ip6, OID_AUTO, mf6ctable, CTLFLAG_RD, + &mf6ctable, sizeof(mf6ctable), "S,*mf6ctable[MF6CTBLSIZ]", + "Multicast Forwarding Table (struct *mf6ctable[MF6CTBLSIZ], " + "netinet6/ip6_mroute.h)"); + u_char n6expire[MF6CTBLSIZ]; + static struct mif6 mif6table[MAXMIFS]; +SYSCTL_OPAQUE(_net_inet6_ip6, OID_AUTO, mif6table, CTLFLAG_RD, + &mif6table, sizeof(mif6table), "S,vif[MAXMIFS]", + "Multicast Interfaces (struct mif[MAXMIFS], netinet6/ip6_mroute.h)"); + #ifdef MRT6DEBUG u_int mrt6debug = 0; /* debug level */ #define DEBUG_MFC 0x02 @@ -187,6 +219,10 @@ static mifi_t nummifs = 0; static mifi_t reg_mif_num = (mifi_t)-1; static struct pim6stat pim6stat; +SYSCTL_STRUCT(_net_inet6_pim, PIM6CTL_STATS, stats, CTLFLAG_RD, + &pim6stat, pim6stat, + "PIM Statistics (struct pim6stat, netinet6/pim_var.h)"); + static int pim6; /* @@ -261,13 +297,17 @@ static int del_m6fc __P((struct mf6cctl *)); static struct callout expire_upcalls_ch; +int X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m); +int X_ip6_mrouter_done(void); +int X_ip6_mrouter_set(struct socket *so, struct sockopt *sopt); +int X_ip6_mrouter_get(struct socket *so, struct sockopt *sopt); +int X_mrt6_ioctl(int cmd, caddr_t data); + /* * Handle MRT setsockopt commands to modify the multicast routing tables. */ int -ip6_mrouter_set(so, sopt) - struct socket *so; - struct sockopt *sopt; +X_ip6_mrouter_set(struct socket *so, struct sockopt *sopt) { int error = 0; int optval; @@ -290,7 +330,7 @@ ip6_mrouter_set(so, sopt) error = ip6_mrouter_init(so, optval, sopt->sopt_name); break; case MRT6_DONE: - error = ip6_mrouter_done(); + error = X_ip6_mrouter_done(); break; case MRT6_ADD_MIF: error = sooptcopyin(sopt, &mifc, sizeof(mifc), sizeof(mifc)); @@ -335,9 +375,7 @@ ip6_mrouter_set(so, sopt) * Handle MRT getsockopt commands */ int -ip6_mrouter_get(so, sopt) - struct socket *so; - struct sockopt *sopt; +X_ip6_mrouter_get(struct socket *so, struct sockopt *sopt) { int error = 0; @@ -356,9 +394,7 @@ ip6_mrouter_get(so, sopt) * Handle ioctl commands to obtain information from the cache */ int -mrt6_ioctl(cmd, data) - int cmd; - caddr_t data; +X_mrt6_ioctl(int cmd, caddr_t data) { switch (cmd) { case SIOCGETSGCNT_IN6: @@ -478,7 +514,7 @@ ip6_mrouter_init(so, v, cmd) * Disable multicast routing */ int -ip6_mrouter_done() +X_ip6_mrouter_done(void) { mifi_t mifi; int i; @@ -993,10 +1029,7 @@ socket_send(s, mm, src) */ int -ip6_mforward(ip6, ifp, m) - struct ip6_hdr *ip6; - struct ifnet *ifp; - struct mbuf *m; +X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m) { struct mf6c *rt; struct mif6 *mifp; diff --git a/sys/netinet6/ip6_mroute.h b/sys/netinet6/ip6_mroute.h index b1de70b..fdff76d 100644 --- a/sys/netinet6/ip6_mroute.h +++ b/sys/netinet6/ip6_mroute.h @@ -268,10 +268,10 @@ struct rtdetq { /* XXX: rtdetq is also defined in ip_mroute.h */ #define MAX_UPQ6 4 /* max. no of pkts in upcall Q */ -int ip6_mrouter_set __P((struct socket *so, struct sockopt *sopt)); -int ip6_mrouter_get __P((struct socket *so, struct sockopt *sopt)); -int ip6_mrouter_done __P((void)); -int mrt6_ioctl __P((int, caddr_t)); +extern int (*ip6_mrouter_set)(struct socket *so, struct sockopt *sopt); +extern int (*ip6_mrouter_get)(struct socket *so, struct sockopt *sopt); +extern int (*ip6_mrouter_done)(void); +extern int (*mrt6_ioctl)(int, caddr_t); #endif /* _KERNEL */ #endif /* !_NETINET6_IP6_MROUTE_H_ */ diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index a0dfec3..91b444b 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -353,7 +353,9 @@ struct ip6aux *ip6_addaux __P((struct mbuf *)); struct ip6aux *ip6_findaux __P((struct mbuf *)); void ip6_delaux __P((struct mbuf *)); -int ip6_mforward __P((struct ip6_hdr *, struct ifnet *, struct mbuf *)); +extern int (*ip6_mforward)(struct ip6_hdr *, struct ifnet *, + struct mbuf *); + int ip6_process_hopopts __P((struct mbuf *, u_int8_t *, int, u_int32_t *, u_int32_t *)); void ip6_savecontrol __P((struct inpcb *, struct mbuf *, struct mbuf **)); diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index cab78eb..643c694 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -122,6 +122,18 @@ extern u_long rip_recvspace; struct rip6stat rip6stat; /* + * Hooks for multicast forwarding. + */ + +struct socket *ip6_mrouter; + +int (*ip6_mrouter_set)(struct socket *, struct sockopt *); +int (*ip6_mrouter_get)(struct socket *, struct sockopt *); +int (*ip6_mrouter_done)(void); +int (*ip6_mforward)(struct ip6_hdr *, struct ifnet *, struct mbuf *); +int (*mrt6_ioctl)(int, caddr_t); + +/* * Setup generic address and protocol structures * for raw_input routine, then pass them along with * mbuf chain. @@ -507,7 +519,8 @@ rip6_ctloutput(so, sopt) case MRT6_ADD_MFC: case MRT6_DEL_MFC: case MRT6_PIM: - error = ip6_mrouter_get(so, sopt); + error = ip6_mrouter_get ? ip6_mrouter_get(so, sopt) : + EOPNOTSUPP; break; case IPV6_CHECKSUM: error = ip6_raw_ctloutput(so, sopt); @@ -527,7 +540,8 @@ rip6_ctloutput(so, sopt) case MRT6_ADD_MFC: case MRT6_DEL_MFC: case MRT6_PIM: - error = ip6_mrouter_set(so, sopt); + error = ip6_mrouter_set ? ip6_mrouter_set(so, sopt) : + EOPNOTSUPP; break; case IPV6_CHECKSUM: error = ip6_raw_ctloutput(so, sopt); @@ -587,9 +601,9 @@ rip6_detach(struct socket *so) inp = sotoinpcb(so); KASSERT(inp != NULL, ("rip6_detach: inp == NULL")); - /* xxx: RSVP */ - if (so == ip6_mrouter) + if (so == ip6_mrouter && ip6_mrouter_done) ip6_mrouter_done(); + /* xxx: RSVP */ INP_INFO_WLOCK(&ripcbinfo); INP_LOCK(inp); if (inp->in6p_icmp6filt) { |