Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F152456742
D55238.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
26 KB
Referenced Files
None
Subscribers
None
D55238.id.diff
View Options
diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c
--- a/sys/netinet6/ip6_mroute.c
+++ b/sys/netinet6/ip6_mroute.c
@@ -106,6 +106,7 @@
#include <net/if_var.h>
#include <net/if_private.h>
#include <net/if_types.h>
+#include <net/route.h>
#include <net/vnet.h>
#include <netinet/in.h>
@@ -124,9 +125,13 @@
static MALLOC_DEFINE(M_MRTABLE6, "mf6c", "multicast forwarding cache entry");
-static int ip6_mdq(struct mbuf *, struct ifnet *, struct mf6c *);
+struct mf6ctable;
+
+static int ip6_mdq(struct mf6ctable *, struct mbuf *, struct ifnet *,
+ struct mf6c *);
static void phyint_send(struct ip6_hdr *, struct mif6 *, struct mbuf *);
-static int register_send(struct ip6_hdr *, struct mif6 *, struct mbuf *);
+static int register_send(struct mf6ctable *, struct ip6_hdr *, mifi_t,
+ struct mbuf *);
static int set_pim6(int *);
static int socket_send(struct socket *, struct mbuf *,
struct sockaddr_in6 *);
@@ -146,9 +151,6 @@
.input = pim6_input
};
-VNET_DEFINE_STATIC(int, ip6_mrouter_ver) = 0;
-#define V_ip6_mrouter_ver VNET(ip6_mrouter_ver)
-
SYSCTL_DECL(_net_inet6);
SYSCTL_DECL(_net_inet6_ip6);
static SYSCTL_NODE(_net_inet6, IPPROTO_PIM, pim,
@@ -172,15 +174,6 @@
#define MROUTER6_LOCK_INIT() sx_init(MROUTER6_LOCKPTR(), "mrouter6")
#define MROUTER6_LOCK_DESTROY() sx_destroy(MROUTER6_LOCKPTR())
-VNET_DEFINE_STATIC(struct socket *, ip6_mrouter);
-#define V_ip6_mrouter VNET(ip6_mrouter)
-
-static struct mf6c *mf6ctable[MF6CTBLSIZ];
-SYSCTL_OPAQUE(_net_inet6_ip6, OID_AUTO, mf6ctable, CTLFLAG_RD,
- &mf6ctable, sizeof(mf6ctable), "S,*mf6ctable[MF6CTBLSIZ]",
- "IPv6 Multicast Forwarding Table (struct *mf6ctable[MF6CTBLSIZ], "
- "netinet6/ip6_mroute.h)");
-
static struct mtx mfc6_mtx;
#define MFC6_LOCKPTR() (&mfc6_mtx)
#define MFC6_LOCK() mtx_lock(MFC6_LOCKPTR())
@@ -191,9 +184,42 @@
NULL, MTX_DEF)
#define MFC6_LOCK_DESTROY() mtx_destroy(MFC6_LOCKPTR())
-static u_char n6expire[MF6CTBLSIZ];
+struct mf6ctable {
+ struct socket *router;
+ int router_ver;
+ struct mf6c *mfchashtbl[MF6CTBLSIZ];
+ u_char nexpire[MF6CTBLSIZ];
+ int nummifs;
+ struct mif6 miftable[MAXMIFS];
+
+ /*
+ * 'Interfaces' associated with decapsulator (so we can tell packets
+ * that went through it from ones that get reflected by a broken
+ * gateway). Different from IPv4 register_if, these interfaces are
+ * linked into the system ifnet list, because per-interface IPv6
+ * statistics are maintained in ifp->if_afdata. But it does not have
+ * any routes point to them. I.e., packets can't be sent this way.
+ * They only exist as a placeholder for multicast source verification.
+ */
+ struct ifnet *register_if;
+ mifi_t register_mif;
+};
+
+VNET_DEFINE_STATIC(struct mf6ctable *, mfctables);
+#define V_mfctables VNET(mfctables)
+
+static int
+sysctl_mfctable(SYSCTL_HANDLER_ARGS)
+{
+ return (SYSCTL_OUT(req, &V_mfctables[0].mfchashtbl,
+ sizeof(V_mfctables[0].mfchashtbl)));
+}
+SYSCTL_PROC(_net_inet6_ip6, OID_AUTO, mf6ctable,
+ CTLTYPE_OPAQUE | CTLFLAG_RD,
+ NULL, 0, sysctl_mfctable, "S,*mf6c[MF6CTBLSIZ]",
+ "IPv6 Multicast Forwarding Table (struct mf6c *[MF6CTBLSIZ], "
+ "netinet6/ip6_mroute.h)");
-static struct mif6 mif6table[MAXMIFS];
static int
sysctl_mif6table(SYSCTL_HANDLER_ARGS)
{
@@ -203,17 +229,20 @@
out = malloc(sizeof(struct mif6_sctl) * MAXMIFS, M_TEMP,
M_WAITOK | M_ZERO);
for (int i = 0; i < MAXMIFS; i++) {
- out[i].m6_flags = mif6table[i].m6_flags;
- out[i].m6_rate_limit = mif6table[i].m6_rate_limit;
- out[i].m6_lcl_addr = mif6table[i].m6_lcl_addr;
- if (mif6table[i].m6_ifp != NULL)
- out[i].m6_ifp = mif6table[i].m6_ifp->if_index;
+ struct mif6_sctl *outp = &out[i];
+ struct mif6 *mifp = &V_mfctables[0].miftable[i];
+
+ outp->m6_flags = mifp->m6_flags;
+ outp->m6_rate_limit = mifp->m6_rate_limit;
+ outp->m6_lcl_addr = mifp->m6_lcl_addr;
+ if (mifp->m6_ifp != NULL)
+ outp->m6_ifp = mifp->m6_ifp->if_index;
else
- out[i].m6_ifp = 0;
- out[i].m6_pkt_in = mif6table[i].m6_pkt_in;
- out[i].m6_pkt_out = mif6table[i].m6_pkt_out;
- out[i].m6_bytes_in = mif6table[i].m6_bytes_in;
- out[i].m6_bytes_out = mif6table[i].m6_bytes_out;
+ outp->m6_ifp = 0;
+ outp->m6_pkt_in = mifp->m6_pkt_in;
+ outp->m6_pkt_out = mifp->m6_pkt_out;
+ outp->m6_bytes_in = mifp->m6_bytes_in;
+ outp->m6_bytes_out = mifp->m6_bytes_out;
}
error = SYSCTL_OUT(req, out, sizeof(struct mif6_sctl) * MAXMIFS);
free(out, M_TEMP);
@@ -257,25 +286,6 @@
#define EXPIRE_TIMEOUT (hz / 4) /* 4x / second */
#define UPCALL_EXPIRE 6 /* number of timeouts */
-/*
- * 'Interfaces' associated with decapsulator (so we can tell
- * packets that went through it from ones that get reflected
- * by a broken gateway). Different from IPv4 register_if,
- * these interfaces are linked into the system ifnet list,
- * because per-interface IPv6 statistics are maintained in
- * ifp->if_afdata. But it does not have any routes point
- * to them. I.e., packets can't be sent this way. They
- * only exist as a placeholder for multicast source
- * verification.
- */
-static struct ifnet *multicast_register_if6;
-
-/*
- * Private variables.
- */
-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_RW,
&pim6stat, pim6stat,
@@ -335,7 +345,8 @@
static int get_mif6_cnt(struct sioc_mif_req6 *);
static int get_sg_cnt(struct sioc_sg_req6 *);
-static struct callout expire_upcalls_ch;
+VNET_DEFINE_STATIC(struct callout, expire_upcalls_ch);
+#define V_expire_upcalls_ch VNET(expire_upcalls_ch)
static int X_ip6_mforward(struct ip6_hdr *, struct ifnet *, struct mbuf *);
static void X_ip6_mrouter_done(struct socket *);
@@ -344,12 +355,13 @@
static int X_mrt6_ioctl(u_long, caddr_t);
static struct mf6c *
-mf6c_find(const struct in6_addr *origin, const struct in6_addr *group)
+mf6c_find(const struct mf6ctable *mfct, const struct in6_addr *origin,
+ const struct in6_addr *group)
{
MFC6_LOCK_ASSERT();
- for (struct mf6c *rt = mf6ctable[MF6CHASH(*origin, *group)]; rt != NULL;
- rt = rt->mf6c_next) {
+ for (struct mf6c *rt = mfct->mfchashtbl[MF6CHASH(*origin, *group)];
+ rt != NULL; rt = rt->mf6c_next) {
if (IN6_ARE_ADDR_EQUAL(&rt->mf6c_origin.sin6_addr, origin) &&
IN6_ARE_ADDR_EQUAL(&rt->mf6c_mcastgrp.sin6_addr, group) &&
rt->mf6c_stall == NULL)
@@ -365,13 +377,15 @@
static int
X_ip6_mrouter_set(struct socket *so, struct sockopt *sopt)
{
+ struct mf6ctable *mfct;
int error = 0;
int optval;
struct mif6ctl mifc;
struct mf6cctl mfcc;
mifi_t mifi;
- if (so != V_ip6_mrouter && sopt->sopt_name != MRT6_INIT)
+ mfct = &V_mfctables[0];
+ if (so != mfct->router && sopt->sopt_name != MRT6_INIT)
return (EPERM);
switch (sopt->sopt_name) {
@@ -433,9 +447,11 @@
static int
X_ip6_mrouter_get(struct socket *so, struct sockopt *sopt)
{
+ struct mf6ctable *mfct;
int error = 0;
- if (so != V_ip6_mrouter)
+ mfct = &V_mfctables[0];
+ if (so != mfct->router)
return (EACCES);
switch (sopt->sopt_name) {
@@ -486,8 +502,8 @@
ret = 0;
MFC6_LOCK();
-
- rt = mf6c_find(&req->src.sin6_addr, &req->grp.sin6_addr);
+ rt = mf6c_find(&V_mfctables[0], &req->src.sin6_addr,
+ &req->grp.sin6_addr);
if (rt == NULL) {
ret = ESRCH;
} else {
@@ -495,7 +511,6 @@
req->bytecnt = rt->mf6c_byte_cnt;
req->wrong_if = rt->mf6c_wrong_if;
}
-
MFC6_UNLOCK();
return (ret);
@@ -507,21 +522,25 @@
static int
get_mif6_cnt(struct sioc_mif_req6 *req)
{
+ struct mf6ctable *mfct;
mifi_t mifi;
int ret;
ret = 0;
mifi = req->mifi;
+ mfct = &V_mfctables[0];
MIF6_LOCK();
- if (mifi >= nummifs) {
+ if (mifi >= mfct->nummifs) {
ret = EINVAL;
} else {
- req->icount = mif6table[mifi].m6_pkt_in;
- req->ocount = mif6table[mifi].m6_pkt_out;
- req->ibytes = mif6table[mifi].m6_bytes_in;
- req->obytes = mif6table[mifi].m6_bytes_out;
+ struct mif6 *mif = &mfct->miftable[mifi];
+
+ req->icount = mif->m6_pkt_in;
+ req->ocount = mif->m6_pkt_out;
+ req->ibytes = mif->m6_bytes_in;
+ req->obytes = mif->m6_bytes_out;
}
MIF6_UNLOCK();
@@ -546,32 +565,33 @@
static int
ip6_mrouter_init(struct socket *so, int v, int cmd)
{
+ struct mf6ctable *mfct;
MRT6_DLOG(DEBUG_ANY, "%s: socket %p", __func__, so);
if (v != 1)
return (ENOPROTOOPT);
+ mfct = &V_mfctables[0];
MROUTER6_LOCK();
- if (V_ip6_mrouter != NULL) {
+ if (mfct->router != NULL) {
MROUTER6_UNLOCK();
return (EADDRINUSE);
}
MFC6_LOCK();
V_ip6_mrouting_enabled = true;
- V_ip6_mrouter = so;
- V_ip6_mrouter_ver = cmd;
+ mfct->router = so;
+ mfct->router_ver = cmd;
- bzero((caddr_t)mf6ctable, sizeof(mf6ctable));
- bzero((caddr_t)n6expire, sizeof(n6expire));
+ bzero(&mfct->mfchashtbl, sizeof(mfct->mfchashtbl));
+ bzero(&mfct->nexpire, sizeof(mfct->nexpire));
V_pim6 = 0;/* used for stubbing out/in pim stuff */
- callout_init_mtx(&expire_upcalls_ch, MFC6_LOCKPTR(), 0);
- callout_reset(&expire_upcalls_ch, EXPIRE_TIMEOUT,
- expire_upcalls, NULL);
+ callout_reset(&V_expire_upcalls_ch, EXPIRE_TIMEOUT, expire_upcalls,
+ curvnet);
MFC6_UNLOCK();
MROUTER6_UNLOCK();
@@ -587,14 +607,16 @@
static void
X_ip6_mrouter_done(struct socket *so)
{
+ struct mf6ctable *mfct;
mifi_t mifi;
u_long i;
struct mf6c *rt;
struct rtdetq *rte;
+ mfct = &V_mfctables[0];
MROUTER6_LOCK();
- if (V_ip6_mrouter != so) {
+ if (mfct->router != so) {
MROUTER6_UNLOCK();
return;
}
@@ -603,15 +625,16 @@
* For each phyint in use, disable promiscuous reception of all IPv6
* multicasts.
*/
- for (mifi = 0; mifi < nummifs; mifi++) {
- if (mif6table[mifi].m6_ifp &&
- !(mif6table[mifi].m6_flags & MIFF_REGISTER)) {
- if_allmulti(mif6table[mifi].m6_ifp, 0);
+ for (mifi = 0; mifi < mfct->nummifs; mifi++) {
+ struct mif6 *mif = &mfct->miftable[mifi];
+
+ if (mif->m6_ifp && !(mif->m6_flags & MIFF_REGISTER)) {
+ if_allmulti(mif->m6_ifp, 0);
}
}
MFC6_LOCK();
- bzero((caddr_t)mif6table, sizeof(mif6table));
- nummifs = 0;
+ bzero(mfct->miftable, sizeof(mfct->miftable));
+ mfct->nummifs = 0;
V_pim6 = 0; /* used to stub out/in pim specific code */
@@ -619,7 +642,7 @@
* Free all multicast forwarding cache entries.
*/
for (i = 0; i < MF6CTBLSIZ; i++) {
- rt = mf6ctable[i];
+ rt = mfct->mfchashtbl[i];
while (rt) {
struct mf6c *frt;
@@ -635,23 +658,21 @@
free(frt, M_MRTABLE6);
}
}
- bzero((caddr_t)mf6ctable, sizeof(mf6ctable));
-
- V_ip6_mrouter = NULL;
+ mfct->router = NULL;
+ mfct->router_ver = 0;
V_ip6_mrouting_enabled = false;
- V_ip6_mrouter_ver = 0;
- MFC6_UNLOCK();
- callout_drain(&expire_upcalls_ch);
+ bzero(mfct->mfchashtbl, sizeof(mfct->mfchashtbl));
+ MFC6_UNLOCK();
/*
* Reset register interface
*/
- if (reg_mif_num != (mifi_t)-1 && multicast_register_if6 != NULL) {
- if_detach(multicast_register_if6);
- if_free(multicast_register_if6);
- reg_mif_num = (mifi_t)-1;
- multicast_register_if6 = NULL;
+ if (mfct->register_mif != (mifi_t)-1 && mfct->register_if != NULL) {
+ if_detach(mfct->register_if);
+ if_free(mfct->register_if);
+ mfct->register_mif = (mifi_t)-1;
+ mfct->register_if = NULL;
}
MROUTER6_UNLOCK();
@@ -666,6 +687,7 @@
static int
add_m6if(struct mif6ctl *mifcp)
{
+ struct mf6ctable *mfct;
struct epoch_tracker et;
struct mif6 *mifp;
struct ifnet *ifp;
@@ -677,7 +699,8 @@
MIF6_UNLOCK();
return (EINVAL);
}
- mifp = mif6table + mifcp->mif6c_mifi;
+ mfct = &V_mfctables[0];
+ mifp = &mfct->miftable[mifcp->mif6c_mifi];
if (mifp->m6_ifp != NULL) {
MIF6_UNLOCK();
return (EADDRINUSE); /* XXX: is it appropriate? */
@@ -692,14 +715,14 @@
NET_EPOCH_EXIT(et); /* XXXGL: unsafe ifp */
if (mifcp->mif6c_flags & MIFF_REGISTER) {
- if (reg_mif_num == (mifi_t)-1) {
+ if (mfct->register_mif == (mifi_t)-1) {
ifp = if_alloc(IFT_OTHER);
if_initname(ifp, "register_mif", 0);
ifp->if_flags |= IFF_LOOPBACK;
if_attach(ifp);
- multicast_register_if6 = ifp;
- reg_mif_num = mifcp->mif6c_mifi;
+ mfct->register_if = ifp;
+ mfct->register_mif = mifcp->mif6c_mifi;
/*
* it is impossible to guess the ifindex of the
* register interface. So mif6c_pifi is automatically
@@ -707,7 +730,7 @@
*/
mifcp->mif6c_pifi = ifp->if_index;
} else {
- ifp = multicast_register_if6;
+ ifp = mfct->register_if;
}
} else {
/* Make sure the interface supports multicast */
@@ -733,8 +756,8 @@
mifp->m6_bytes_out = 0;
/* Adjust nummifs up if the mifi is higher than nummifs */
- if (nummifs <= mifcp->mif6c_mifi)
- nummifs = mifcp->mif6c_mifi + 1;
+ if (mfct->nummifs <= mifcp->mif6c_mifi)
+ mfct->nummifs = mifcp->mif6c_mifi + 1;
MIF6_UNLOCK();
MRT6_DLOG(DEBUG_ANY, "mif #%d, phyint %s", mifcp->mif6c_mifi,
@@ -749,14 +772,17 @@
static int
del_m6if_locked(mifi_t *mifip)
{
- struct mif6 *mifp = mif6table + *mifip;
+ struct mf6ctable *mfct;
+ struct mif6 *mifp;
mifi_t mifi;
struct ifnet *ifp;
MIF6_LOCK_ASSERT();
- if (*mifip >= nummifs)
+ mfct = &V_mfctables[0];
+ if (*mifip >= mfct->nummifs)
return (EINVAL);
+ mifp = &mfct->miftable[*mifip];
if (mifp->m6_ifp == NULL)
return (EINVAL);
@@ -765,23 +791,23 @@
ifp = mifp->m6_ifp;
if_allmulti(ifp, 0);
} else {
- if (reg_mif_num != (mifi_t)-1 &&
- multicast_register_if6 != NULL) {
- if_detach(multicast_register_if6);
- if_free(multicast_register_if6);
- reg_mif_num = (mifi_t)-1;
- multicast_register_if6 = NULL;
+ if (mfct->register_mif != (mifi_t)-1 &&
+ mfct->register_if != NULL) {
+ if_detach(mfct->register_if);
+ if_free(mfct->register_if);
+ mfct->register_mif = (mifi_t)-1;
+ mfct->register_if = NULL;
}
}
- bzero((caddr_t)mifp, sizeof(*mifp));
+ bzero(mifp, sizeof(*mifp));
/* Adjust nummifs down */
- for (mifi = nummifs; mifi > 0; mifi--)
- if (mif6table[mifi - 1].m6_ifp)
+ for (mifi = mfct->nummifs; mifi > 0; mifi--)
+ if (mfct->miftable[mifi - 1].m6_ifp != NULL)
break;
- nummifs = mifi;
- MRT6_DLOG(DEBUG_ANY, "mif %d, nummifs %d", *mifip, nummifs);
+ mfct->nummifs = mifi;
+ MRT6_DLOG(DEBUG_ANY, "mif %d, nummifs %d", *mifip, mfct->nummifs);
return (0);
}
@@ -804,15 +830,17 @@
static int
add_m6fc(struct mf6cctl *mfccp)
{
+ struct mf6ctable *mfct;
struct mf6c *rt;
u_long hash;
struct rtdetq *rte;
u_short nstl;
char ip6bufo[INET6_ADDRSTRLEN], ip6bufg[INET6_ADDRSTRLEN];
- MFC6_LOCK();
+ mfct = &V_mfctables[0];
- rt = mf6c_find(&mfccp->mf6cc_origin.sin6_addr,
+ MFC6_LOCK();
+ rt = mf6c_find(mfct, &mfccp->mf6cc_origin.sin6_addr,
&mfccp->mf6cc_mcastgrp.sin6_addr);
/* If an entry already exists, just update the fields */
if (rt) {
@@ -833,7 +861,7 @@
*/
hash = MF6CHASH(mfccp->mf6cc_origin.sin6_addr,
mfccp->mf6cc_mcastgrp.sin6_addr);
- for (rt = mf6ctable[hash], nstl = 0; rt; rt = rt->mf6c_next) {
+ for (rt = mfct->mfchashtbl[hash], nstl = 0; rt; rt = rt->mf6c_next) {
if (IN6_ARE_ADDR_EQUAL(&rt->mf6c_origin.sin6_addr,
&mfccp->mf6cc_origin.sin6_addr) &&
IN6_ARE_ADDR_EQUAL(&rt->mf6c_mcastgrp.sin6_addr,
@@ -866,12 +894,12 @@
rt->mf6c_wrong_if = 0;
rt->mf6c_expire = 0; /* Don't clean this guy up */
- n6expire[hash]--;
+ mfct->nexpire[hash]--;
/* free packets Qed at the end of this entry */
for (rte = rt->mf6c_stall; rte != NULL; ) {
struct rtdetq *n = rte->next;
- ip6_mdq(rte->m, rte->ifp, rt);
+ ip6_mdq(mfct, rte->m, rte->ifp, rt);
m_freem(rte->m);
#ifdef UPCALL_TIMING
collate(&(rte->t));
@@ -892,7 +920,7 @@
ip6_sprintf(ip6bufg, &mfccp->mf6cc_mcastgrp.sin6_addr),
mfccp->mf6cc_parent);
- for (rt = mf6ctable[hash]; rt; rt = rt->mf6c_next) {
+ for (rt = mfct->mfchashtbl[hash]; rt; rt = rt->mf6c_next) {
if (IN6_ARE_ADDR_EQUAL(&rt->mf6c_origin.sin6_addr,
&mfccp->mf6cc_origin.sin6_addr)&&
IN6_ARE_ADDR_EQUAL(&rt->mf6c_mcastgrp.sin6_addr,
@@ -907,7 +935,7 @@
rt->mf6c_wrong_if = 0;
if (rt->mf6c_expire)
- n6expire[hash]--;
+ mfct->nexpire[hash]--;
rt->mf6c_expire = 0;
}
}
@@ -932,8 +960,8 @@
rt->mf6c_stall = NULL;
/* link into table */
- rt->mf6c_next = mf6ctable[hash];
- mf6ctable[hash] = rt;
+ rt->mf6c_next = mfct->mfchashtbl[hash];
+ mfct->mfchashtbl[hash] = rt;
}
}
@@ -976,12 +1004,14 @@
#ifdef MRT6DEBUG
char ip6bufo[INET6_ADDRSTRLEN], ip6bufg[INET6_ADDRSTRLEN];
#endif
+ struct mf6ctable *mfct;
struct sockaddr_in6 origin;
struct sockaddr_in6 mcastgrp;
struct mf6c *rt;
struct mf6c **nptr;
u_long hash;
+ mfct = &V_mfctables[0];
origin = mfccp->mf6cc_origin;
mcastgrp = mfccp->mf6cc_mcastgrp;
hash = MF6CHASH(origin.sin6_addr, mcastgrp.sin6_addr);
@@ -992,7 +1022,7 @@
MFC6_LOCK();
- nptr = &mf6ctable[hash];
+ nptr = &mfct->mfchashtbl[hash];
while ((rt = *nptr) != NULL) {
if (IN6_ARE_ADDR_EQUAL(&origin.sin6_addr,
&rt->mf6c_origin.sin6_addr) &&
@@ -1054,6 +1084,7 @@
static int
X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m)
{
+ struct mf6ctable *mfct;
struct rtdetq *rte;
struct mbuf *mb0;
struct mf6c *rt;
@@ -1103,18 +1134,19 @@
return (0);
}
+ mfct = &V_mfctables[0];
MFC6_LOCK();
/*
* Determine forwarding mifs from the forwarding cache table
*/
- rt = mf6c_find(&ip6->ip6_src, &ip6->ip6_dst);
+ rt = mf6c_find(mfct, &ip6->ip6_src, &ip6->ip6_dst);
MRT6STAT_INC(mrt6s_mfc_lookups);
/* Entry exists, so forward if necessary */
if (rt) {
MFC6_UNLOCK();
- return (ip6_mdq(m, ifp, rt));
+ return (ip6_mdq(mfct, m, ifp, rt));
}
/*
@@ -1150,7 +1182,7 @@
/* is there an upcall waiting for this packet? */
hash = MF6CHASH(ip6->ip6_src, ip6->ip6_dst);
- for (rt = mf6ctable[hash]; rt; rt = rt->mf6c_next) {
+ for (rt = mfct->mfchashtbl[hash]; rt; rt = rt->mf6c_next) {
if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_src,
&rt->mf6c_origin.sin6_addr) &&
IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
@@ -1192,7 +1224,7 @@
#ifdef MRT6_OINIT
oim = NULL;
#endif
- switch (V_ip6_mrouter_ver) {
+ switch (mfct->router_ver) {
#ifdef MRT6_OINIT
case MRT6_OINIT:
oim = mtod(mm, struct omrt6msg *);
@@ -1214,11 +1246,11 @@
}
MRT6_DLOG(DEBUG_FORWARD, "getting the iif info in the kernel");
- for (mifp = mif6table, mifi = 0;
- mifi < nummifs && mifp->m6_ifp != ifp; mifp++, mifi++)
- ;
+ for (mifp = mfct->miftable, mifi = 0;
+ mifi < mfct->nummifs && mifp->m6_ifp != ifp; mifp++, mifi++)
+ ;
- switch (V_ip6_mrouter_ver) {
+ switch (mfct->router_ver) {
#ifdef MRT6_OINIT
case MRT6_OINIT:
oim->im6_mif = mifi;
@@ -1229,7 +1261,7 @@
break;
}
- if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) {
+ if (socket_send(mfct->router, mm, &sin6) < 0) {
log(LOG_WARNING, "ip6_mforward: ip6_mrouter "
"socket queue full\n");
MRT6STAT_INC(mrt6s_upq_sockfull);
@@ -1251,12 +1283,12 @@
rt->mf6c_mcastgrp.sin6_len = sizeof(struct sockaddr_in6);
rt->mf6c_mcastgrp.sin6_addr = ip6->ip6_dst;
rt->mf6c_expire = UPCALL_EXPIRE;
- n6expire[hash]++;
+ mfct->nexpire[hash]++;
rt->mf6c_parent = MF6C_INCOMPLETE_PARENT;
/* link into table */
- rt->mf6c_next = mf6ctable[hash];
- mf6ctable[hash] = rt;
+ rt->mf6c_next = mfct->mfchashtbl[hash];
+ mfct->mfchashtbl[hash] = rt;
/* Add this entry to the end of the queue */
rt->mf6c_stall = rte;
} else {
@@ -1294,21 +1326,24 @@
* Call from the Slow Timeout mechanism, every half second.
*/
static void
-expire_upcalls(void *unused)
+expire_upcalls(void *arg)
{
#ifdef MRT6DEBUG
char ip6bufo[INET6_ADDRSTRLEN], ip6bufg[INET6_ADDRSTRLEN];
#endif
+ struct mf6ctable *mfct;
struct rtdetq *rte;
struct mf6c *mfc, **nptr;
u_long i;
MFC6_LOCK_ASSERT();
+ CURVNET_SET((struct vnet *)arg);
+ mfct = &V_mfctables[0];
for (i = 0; i < MF6CTBLSIZ; i++) {
- if (n6expire[i] == 0)
+ if (mfct->nexpire[i] == 0)
continue;
- nptr = &mf6ctable[i];
+ nptr = &mfct->mfchashtbl[i];
while ((mfc = *nptr) != NULL) {
rte = mfc->mf6c_stall;
/*
@@ -1333,7 +1368,7 @@
rte = n;
} while (rte != NULL);
MRT6STAT_INC(mrt6s_cache_cleanups);
- n6expire[i]--;
+ mfct->nexpire[i]--;
*nptr = mfc->mf6c_next;
free(mfc, M_MRTABLE6);
@@ -1342,15 +1377,18 @@
}
}
}
- callout_reset(&expire_upcalls_ch, EXPIRE_TIMEOUT,
- expire_upcalls, NULL);
+ callout_reset(&V_expire_upcalls_ch, EXPIRE_TIMEOUT,
+ expire_upcalls, curvnet);
+
+ CURVNET_RESTORE();
}
/*
* Packet forwarding routine once entry in the cache is made
*/
static int
-ip6_mdq(struct mbuf *m, struct ifnet *ifp, struct mf6c *rt)
+ip6_mdq(struct mf6ctable *mfct, struct mbuf *m, struct ifnet *ifp,
+ struct mf6c *rt)
{
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
mifi_t mifi, iif;
@@ -1367,13 +1405,13 @@
* for its origin.
*/
mifi = rt->mf6c_parent;
- if (mifi >= nummifs || mif6table[mifi].m6_ifp != ifp) {
+ if (mifi >= mfct->nummifs || mfct->miftable[mifi].m6_ifp != ifp) {
MRT6STAT_INC(mrt6s_wrong_if);
rt->mf6c_wrong_if++;
- if (mifi >= nummifs)
+ if (mifi >= mfct->nummifs)
return (0);
- mifp = &mif6table[mifi];
+ mifp = &mfct->miftable[mifi];
MRT6_DLOG(DEBUG_FORWARD,
"wrong if: ifid %d mifi %d mififid %x", ifp->if_index,
mifi, mifp->m6_ifp->if_index);
@@ -1412,7 +1450,7 @@
oim = NULL;
#endif
im = NULL;
- switch (V_ip6_mrouter_ver) {
+ switch (mfct->router_ver) {
#ifdef MRT6_OINIT
case MRT6_OINIT:
oim = mtod(mm, struct omrt6msg *);
@@ -1430,12 +1468,12 @@
return (EINVAL);
}
- for (mifp = mif6table, iif = 0;
- iif < nummifs && mifp->m6_ifp != ifp;
+ for (mifp = mfct->miftable, iif = 0;
+ iif < mfct->nummifs && mifp->m6_ifp != ifp;
mifp++, iif++)
;
- switch (V_ip6_mrouter_ver) {
+ switch (mfct->router_ver) {
#ifdef MRT6_OINIT
case MRT6_OINIT:
oim->im6_mif = iif;
@@ -1450,7 +1488,7 @@
MRT6STAT_INC(mrt6s_upcalls);
- if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) {
+ if (socket_send(mfct->router, mm, &sin6) < 0) {
MRT6_DLOG(DEBUG_ANY,
"ip6_mrouter socket queue full");
MRT6STAT_INC(mrt6s_upq_sockfull);
@@ -1460,14 +1498,16 @@
return (0);
}
+ mifp = &mfct->miftable[mifi];
+
/* If I sourced this packet, it counts as output, else it was input. */
if (m->m_pkthdr.rcvif == NULL) {
/* XXX: is rcvif really NULL when output?? */
- mif6table[mifi].m6_pkt_out++;
- mif6table[mifi].m6_bytes_out += plen;
+ mifp->m6_pkt_out++;
+ mifp->m6_bytes_out += plen;
} else {
- mif6table[mifi].m6_pkt_in++;
- mif6table[mifi].m6_bytes_in += plen;
+ mifp->m6_pkt_in++;
+ mifp->m6_bytes_in += plen;
}
rt->mf6c_pkt_cnt++;
rt->mf6c_byte_cnt += plen;
@@ -1483,7 +1523,8 @@
IP6STAT_INC(ip6s_badscope);
return (error);
}
- for (mifp = mif6table, mifi = 0; mifi < nummifs; mifp++, mifi++) {
+ for (mifp = mfct->miftable, mifi = 0; mifi < mfct->nummifs;
+ mifp++, mifi++) {
if (IF_ISSET(mifi, &rt->mf6c_ifset)) {
/*
* check if the outgoing packet is going to break
@@ -1491,12 +1532,12 @@
* XXX For packets through PIM register tunnel
* interface, we believe a routing daemon.
*/
- if (!(mif6table[rt->mf6c_parent].m6_flags &
+ if (!(mfct->miftable[rt->mf6c_parent].m6_flags &
MIFF_REGISTER) &&
- !(mif6table[mifi].m6_flags & MIFF_REGISTER)) {
- if (in6_setscope(&src0, mif6table[mifi].m6_ifp,
+ !(mifp->m6_flags & MIFF_REGISTER)) {
+ if (in6_setscope(&src0, mifp->m6_ifp,
&oszone) ||
- in6_setscope(&dst0, mif6table[mifi].m6_ifp,
+ in6_setscope(&dst0, mifp->m6_ifp,
&odzone) ||
iszone != oszone ||
idzone != odzone) {
@@ -1508,7 +1549,7 @@
mifp->m6_pkt_out++;
mifp->m6_bytes_out += plen;
if (mifp->m6_flags & MIFF_REGISTER)
- register_send(ip6, mifp, m);
+ register_send(mfct, ip6, mifi, m);
else
phyint_send(ip6, mifp, m);
}
@@ -1619,7 +1660,8 @@
}
static int
-register_send(struct ip6_hdr *ip6, struct mif6 *mif, struct mbuf *m)
+register_send(struct mf6ctable *mfct, struct ip6_hdr *ip6, mifi_t mifi,
+ struct mbuf *m)
{
#ifdef MRT6DEBUG
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
@@ -1663,12 +1705,12 @@
im6->im6_msgtype = MRT6MSG_WHOLEPKT;
im6->im6_mbz = 0;
- im6->im6_mif = mif - mif6table;
+ im6->im6_mif = mifi;
/* iif info is not given for reg. encap.n */
MRT6STAT_INC(mrt6s_upcalls);
- if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) {
+ if (socket_send(mfct->router, mm, &sin6) < 0) {
MRT6_DLOG(DEBUG_ANY, "ip6_mrouter socket queue full");
MRT6STAT_INC(mrt6s_upq_sockfull);
return (ENOBUFS);
@@ -1700,11 +1742,14 @@
static int
pim6_input(struct mbuf *m, int off, int proto, void *arg __unused)
{
- struct pim *pim; /* pointer to a pim struct */
+ struct mf6ctable *mfct;
+ struct pim *pim;
struct ip6_hdr *ip6;
int pimlen;
int minlen;
+ mfct = &V_mfctables[0];
+
PIM6STAT_INC(pim6s_rcv_total);
/*
@@ -1792,9 +1837,10 @@
PIM6STAT_INC(pim6s_rcv_registers);
- if ((reg_mif_num >= nummifs) || (reg_mif_num == (mifi_t) -1)) {
+ if (mfct->register_mif >= mfct->nummifs ||
+ mfct->register_mif == (mifi_t)-1) {
MRT6_DLOG(DEBUG_PIM, "register mif not set: %d",
- reg_mif_num);
+ mfct->register_mif);
m_freem(m);
return (IPPROTO_DONE);
}
@@ -1861,10 +1907,10 @@
MRT6_DLOG(DEBUG_PIM, "forwarding decapsulated register: "
"src %s, dst %s, mif %d",
ip6_sprintf(ip6bufs, &eip6->ip6_src),
- ip6_sprintf(ip6bufd, &eip6->ip6_dst), reg_mif_num);
+ ip6_sprintf(ip6bufd, &eip6->ip6_dst), mfct->register_mif);
- if_simloop(mif6table[reg_mif_num].m6_ifp, m,
- dst.sin6_family, 0);
+ if_simloop(mfct->miftable[mfct->register_mif].m6_ifp, m,
+ dst.sin6_family, 0);
/* prepare the register head to send to the mrouting daemon */
m = mcp;
@@ -1880,6 +1926,27 @@
return (rip6_input(&m, &off, proto));
}
+static void
+vnet_mroute_init(const void *unused __unused)
+{
+ V_mfctables = mallocarray(V_rt_numfibs, sizeof(*V_mfctables),
+ M_MRTABLE6, M_WAITOK | M_ZERO);
+
+ callout_init_mtx(&V_expire_upcalls_ch, MFC6_LOCKPTR(), 0);
+}
+VNET_SYSINIT(vnet_mroute6_init, SI_SUB_PROTO_MC, SI_ORDER_ANY, vnet_mroute_init,
+ NULL);
+
+static void
+vnet_mroute_uninit(const void *unused __unused)
+{
+ callout_drain(&V_expire_upcalls_ch);
+ free(V_mfctables, M_MRTABLE6);
+ V_mfctables = NULL;
+}
+VNET_SYSUNINIT(vnet_mroute6_uninit, SI_SUB_PROTO_MC, SI_ORDER_ANY,
+ vnet_mroute_uninit, NULL);
+
static int
ip6_mroute_modevent(module_t mod, int type, void *unused)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 16, 2:10 AM (1 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30640848
Default Alt Text
D55238.id.diff (26 KB)
Attached To
Mode
D55238: ip6_mroute: Start putting global variables into a structure
Attached
Detach File
Event Timeline
Log In to Comment