summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorbms <bms@FreeBSD.org>2007-02-24 11:38:47 +0000
committerbms <bms@FreeBSD.org>2007-02-24 11:38:47 +0000
commit3e83ac665326a6a015b2179fc28157d9fb7433e2 (patch)
tree6230b66dd7bf83f11724dee78961a7c0020c9d31 /sys/netinet6
parentc553ec0508d385c07a87aed036312de1e3a64b03 (diff)
downloadFreeBSD-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.c2
-rw-r--r--sys/netinet6/in6_proto.c2
-rw-r--r--sys/netinet6/ip6_input.c3
-rw-r--r--sys/netinet6/ip6_mroute.c63
-rw-r--r--sys/netinet6/ip6_mroute.h8
-rw-r--r--sys/netinet6/ip6_var.h4
-rw-r--r--sys/netinet6/raw_ip6.c22
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) {
OpenPOWER on IntegriCloud