ip6_mroute: FIBify
Modify the control plane (ioctl and socket option handlers) to use the routing socket FIB to index into the mfctable array. Modify the forwarding plane to use the mbuf's FIB to determine which routing table to use. MFC after: 2 weeks Sponsored by: Stormshield Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D55242
This commit is contained in:
+6
-11
@@ -279,17 +279,6 @@ in6_control_ioctl(u_long cmd, void *data,
|
|||||||
ifra->ifra_vhid = 0;
|
ifra->ifra_vhid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (cmd) {
|
|
||||||
case SIOCGETSGCNT_IN6:
|
|
||||||
case SIOCGETMIFCNT_IN6:
|
|
||||||
/*
|
|
||||||
* XXX mrt_ioctl has a 3rd, unused, FIB argument in route.c.
|
|
||||||
* We cannot see how that would be needed, so do not adjust the
|
|
||||||
* KPI blindly; more likely should clean up the IPv4 variant.
|
|
||||||
*/
|
|
||||||
return (mrt6_ioctl ? mrt6_ioctl(cmd, data) : EOPNOTSUPP);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCAADDRCTL_POLICY:
|
case SIOCAADDRCTL_POLICY:
|
||||||
case SIOCDADDRCTL_POLICY:
|
case SIOCDADDRCTL_POLICY:
|
||||||
@@ -615,6 +604,12 @@ int
|
|||||||
in6_control(struct socket *so, u_long cmd, void *data,
|
in6_control(struct socket *so, u_long cmd, void *data,
|
||||||
struct ifnet *ifp, struct thread *td)
|
struct ifnet *ifp, struct thread *td)
|
||||||
{
|
{
|
||||||
|
switch (cmd) {
|
||||||
|
case SIOCGETSGCNT_IN6:
|
||||||
|
case SIOCGETMIFCNT_IN6:
|
||||||
|
return (mrt6_ioctl ?
|
||||||
|
mrt6_ioctl(cmd, data, so->so_fibnum) : EOPNOTSUPP);
|
||||||
|
}
|
||||||
return (in6_control_ioctl(cmd, data, ifp, td ? td->td_ucred : NULL));
|
return (in6_control_ioctl(cmd, data, ifp, td ? td->td_ucred : NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+77
-54
@@ -216,8 +216,11 @@ static eventhandler_tag rtnumfibs_change_tag;
|
|||||||
static int
|
static int
|
||||||
sysctl_mfctable(SYSCTL_HANDLER_ARGS)
|
sysctl_mfctable(SYSCTL_HANDLER_ARGS)
|
||||||
{
|
{
|
||||||
return (SYSCTL_OUT(req, &V_mfctables[0].mfchashtbl,
|
int fibnum;
|
||||||
sizeof(V_mfctables[0].mfchashtbl)));
|
|
||||||
|
fibnum = curthread->td_proc->p_fibnum;
|
||||||
|
return (SYSCTL_OUT(req, &V_mfctables[fibnum].mfchashtbl,
|
||||||
|
sizeof(struct mfc6c *) * MF6CTBLSIZ));
|
||||||
}
|
}
|
||||||
SYSCTL_PROC(_net_inet6_ip6, OID_AUTO, mf6ctable,
|
SYSCTL_PROC(_net_inet6_ip6, OID_AUTO, mf6ctable,
|
||||||
CTLTYPE_OPAQUE | CTLFLAG_RD,
|
CTLTYPE_OPAQUE | CTLFLAG_RD,
|
||||||
@@ -229,13 +232,15 @@ static int
|
|||||||
sysctl_mif6table(SYSCTL_HANDLER_ARGS)
|
sysctl_mif6table(SYSCTL_HANDLER_ARGS)
|
||||||
{
|
{
|
||||||
struct mif6_sctl *out;
|
struct mif6_sctl *out;
|
||||||
|
struct mf6ctable *mfct;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
mfct = &V_mfctables[curthread->td_proc->p_fibnum];
|
||||||
out = malloc(sizeof(struct mif6_sctl) * MAXMIFS, M_TEMP,
|
out = malloc(sizeof(struct mif6_sctl) * MAXMIFS, M_TEMP,
|
||||||
M_WAITOK | M_ZERO);
|
M_WAITOK | M_ZERO);
|
||||||
for (int i = 0; i < MAXMIFS; i++) {
|
for (int i = 0; i < MAXMIFS; i++) {
|
||||||
struct mif6_sctl *outp = &out[i];
|
struct mif6_sctl *outp = &out[i];
|
||||||
struct mif6 *mifp = &V_mfctables[0].miftable[i];
|
struct mif6 *mifp = &mfct->miftable[i];
|
||||||
|
|
||||||
outp->m6_flags = mifp->m6_flags;
|
outp->m6_flags = mifp->m6_flags;
|
||||||
outp->m6_rate_limit = mifp->m6_rate_limit;
|
outp->m6_rate_limit = mifp->m6_rate_limit;
|
||||||
@@ -287,7 +292,8 @@ VNET_DEFINE_STATIC(u_int, mrt6debug) = 0; /* debug level */
|
|||||||
#define MRT6_DLOG(m, fmt, ...)
|
#define MRT6_DLOG(m, fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void expire_upcalls(void *);
|
static void expire_upcalls(struct mf6ctable *);
|
||||||
|
static void expire_upcalls_all(void *);
|
||||||
#define EXPIRE_TIMEOUT (hz / 4) /* 4x / second */
|
#define EXPIRE_TIMEOUT (hz / 4) /* 4x / second */
|
||||||
#define UPCALL_EXPIRE 6 /* number of timeouts */
|
#define UPCALL_EXPIRE 6 /* number of timeouts */
|
||||||
|
|
||||||
@@ -342,13 +348,13 @@ static void collate(struct timeval *);
|
|||||||
#endif /* UPCALL_TIMING */
|
#endif /* UPCALL_TIMING */
|
||||||
|
|
||||||
static int ip6_mrouter_init(struct socket *, int, int);
|
static int ip6_mrouter_init(struct socket *, int, int);
|
||||||
static int add_m6fc(struct mf6cctl *);
|
static int add_m6fc(struct mf6ctable *, struct mf6cctl *);
|
||||||
static int add_m6if(struct mif6ctl *);
|
static int add_m6if(struct mf6ctable *, int, struct mif6ctl *);
|
||||||
static int del_m6fc(struct mf6cctl *);
|
static int del_m6fc(struct mf6ctable *, struct mf6cctl *);
|
||||||
static int del_m6if(mifi_t *);
|
static int del_m6if(struct mf6ctable *, mifi_t *);
|
||||||
static int del_m6if_locked(mifi_t *);
|
static int del_m6if_locked(struct mf6ctable *, mifi_t *);
|
||||||
static int get_mif6_cnt(struct sioc_mif_req6 *);
|
static int get_mif6_cnt(struct mf6ctable *, struct sioc_mif_req6 *);
|
||||||
static int get_sg_cnt(struct sioc_sg_req6 *);
|
static int get_sg_cnt(struct mf6ctable *, struct sioc_sg_req6 *);
|
||||||
|
|
||||||
VNET_DEFINE_STATIC(struct callout, expire_upcalls_ch);
|
VNET_DEFINE_STATIC(struct callout, expire_upcalls_ch);
|
||||||
#define V_expire_upcalls_ch VNET(expire_upcalls_ch)
|
#define V_expire_upcalls_ch VNET(expire_upcalls_ch)
|
||||||
@@ -357,7 +363,7 @@ static int X_ip6_mforward(struct ip6_hdr *, struct ifnet *, struct mbuf *);
|
|||||||
static void X_ip6_mrouter_done(struct socket *);
|
static void X_ip6_mrouter_done(struct socket *);
|
||||||
static int X_ip6_mrouter_set(struct socket *, struct sockopt *);
|
static int X_ip6_mrouter_set(struct socket *, struct sockopt *);
|
||||||
static int X_ip6_mrouter_get(struct socket *, struct sockopt *);
|
static int X_ip6_mrouter_get(struct socket *, struct sockopt *);
|
||||||
static int X_mrt6_ioctl(u_long, caddr_t);
|
static int X_mrt6_ioctl(u_long, caddr_t, int);
|
||||||
|
|
||||||
static struct mf6c *
|
static struct mf6c *
|
||||||
mf6c_find(const struct mf6ctable *mfct, const struct in6_addr *origin,
|
mf6c_find(const struct mf6ctable *mfct, const struct in6_addr *origin,
|
||||||
@@ -376,6 +382,17 @@ mf6c_find(const struct mf6ctable *mfct, const struct in6_addr *origin,
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct mf6ctable *
|
||||||
|
somfctable(struct socket *so)
|
||||||
|
{
|
||||||
|
int fib;
|
||||||
|
|
||||||
|
fib = atomic_load_int(&so->so_fibnum);
|
||||||
|
KASSERT(fib >= 0 && fib < V_nmfctables,
|
||||||
|
("%s: so_fibnum %d out of range", __func__, fib));
|
||||||
|
return (&V_mfctables[fib]);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle MRT setsockopt commands to modify the multicast routing tables.
|
* Handle MRT setsockopt commands to modify the multicast routing tables.
|
||||||
*/
|
*/
|
||||||
@@ -389,7 +406,7 @@ X_ip6_mrouter_set(struct socket *so, struct sockopt *sopt)
|
|||||||
struct mf6cctl mfcc;
|
struct mf6cctl mfcc;
|
||||||
mifi_t mifi;
|
mifi_t mifi;
|
||||||
|
|
||||||
mfct = &V_mfctables[0];
|
mfct = somfctable(so);
|
||||||
if (so != mfct->router && sopt->sopt_name != MRT6_INIT)
|
if (so != mfct->router && sopt->sopt_name != MRT6_INIT)
|
||||||
return (EPERM);
|
return (EPERM);
|
||||||
|
|
||||||
@@ -411,25 +428,25 @@ X_ip6_mrouter_set(struct socket *so, struct sockopt *sopt)
|
|||||||
error = sooptcopyin(sopt, &mifc, sizeof(mifc), sizeof(mifc));
|
error = sooptcopyin(sopt, &mifc, sizeof(mifc), sizeof(mifc));
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
error = add_m6if(&mifc);
|
error = add_m6if(mfct, so->so_fibnum, &mifc);
|
||||||
break;
|
break;
|
||||||
case MRT6_ADD_MFC:
|
case MRT6_ADD_MFC:
|
||||||
error = sooptcopyin(sopt, &mfcc, sizeof(mfcc), sizeof(mfcc));
|
error = sooptcopyin(sopt, &mfcc, sizeof(mfcc), sizeof(mfcc));
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
error = add_m6fc(&mfcc);
|
error = add_m6fc(mfct, &mfcc);
|
||||||
break;
|
break;
|
||||||
case MRT6_DEL_MFC:
|
case MRT6_DEL_MFC:
|
||||||
error = sooptcopyin(sopt, &mfcc, sizeof(mfcc), sizeof(mfcc));
|
error = sooptcopyin(sopt, &mfcc, sizeof(mfcc), sizeof(mfcc));
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
error = del_m6fc(&mfcc);
|
error = del_m6fc(mfct, &mfcc);
|
||||||
break;
|
break;
|
||||||
case MRT6_DEL_MIF:
|
case MRT6_DEL_MIF:
|
||||||
error = sooptcopyin(sopt, &mifi, sizeof(mifi), sizeof(mifi));
|
error = sooptcopyin(sopt, &mifi, sizeof(mifi), sizeof(mifi));
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
error = del_m6if(&mifi);
|
error = del_m6if(mfct, &mifi);
|
||||||
break;
|
break;
|
||||||
case MRT6_PIM:
|
case MRT6_PIM:
|
||||||
error = sooptcopyin(sopt, &optval, sizeof(optval),
|
error = sooptcopyin(sopt, &optval, sizeof(optval),
|
||||||
@@ -455,7 +472,7 @@ X_ip6_mrouter_get(struct socket *so, struct sockopt *sopt)
|
|||||||
struct mf6ctable *mfct;
|
struct mf6ctable *mfct;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
mfct = &V_mfctables[0];
|
mfct = somfctable(so);
|
||||||
if (so != mfct->router)
|
if (so != mfct->router)
|
||||||
return (EACCES);
|
return (EACCES);
|
||||||
|
|
||||||
@@ -471,24 +488,27 @@ X_ip6_mrouter_get(struct socket *so, struct sockopt *sopt)
|
|||||||
* Handle ioctl commands to obtain information from the cache
|
* Handle ioctl commands to obtain information from the cache
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
X_mrt6_ioctl(u_long cmd, caddr_t data)
|
X_mrt6_ioctl(u_long cmd, caddr_t data, int fibnum)
|
||||||
{
|
{
|
||||||
|
struct mf6ctable *mfct;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = priv_check(curthread, PRIV_NETINET_MROUTE);
|
error = priv_check(curthread, PRIV_NETINET_MROUTE);
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
return (error);
|
||||||
error = EINVAL;
|
|
||||||
|
mfct = &V_mfctables[fibnum];
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCGETSGCNT_IN6:
|
case SIOCGETSGCNT_IN6:
|
||||||
error = get_sg_cnt((struct sioc_sg_req6 *)data);
|
error = get_sg_cnt(mfct, (struct sioc_sg_req6 *)data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIOCGETMIFCNT_IN6:
|
case SIOCGETMIFCNT_IN6:
|
||||||
error = get_mif6_cnt((struct sioc_mif_req6 *)data);
|
error = get_mif6_cnt(mfct, (struct sioc_mif_req6 *)data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
error = EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,7 +519,7 @@ X_mrt6_ioctl(u_long cmd, caddr_t data)
|
|||||||
* returns the packet, byte, rpf-failure count for the source group provided
|
* returns the packet, byte, rpf-failure count for the source group provided
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
get_sg_cnt(struct sioc_sg_req6 *req)
|
get_sg_cnt(struct mf6ctable *mfct, struct sioc_sg_req6 *req)
|
||||||
{
|
{
|
||||||
struct mf6c *rt;
|
struct mf6c *rt;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -507,8 +527,7 @@ get_sg_cnt(struct sioc_sg_req6 *req)
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
MFC6_LOCK();
|
MFC6_LOCK();
|
||||||
rt = mf6c_find(&V_mfctables[0], &req->src.sin6_addr,
|
rt = mf6c_find(mfct, &req->src.sin6_addr, &req->grp.sin6_addr);
|
||||||
&req->grp.sin6_addr);
|
|
||||||
if (rt == NULL) {
|
if (rt == NULL) {
|
||||||
ret = ESRCH;
|
ret = ESRCH;
|
||||||
} else {
|
} else {
|
||||||
@@ -525,16 +544,14 @@ get_sg_cnt(struct sioc_sg_req6 *req)
|
|||||||
* returns the input and output packet and byte counts on the mif provided
|
* returns the input and output packet and byte counts on the mif provided
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
get_mif6_cnt(struct sioc_mif_req6 *req)
|
get_mif6_cnt(struct mf6ctable *mfct, struct sioc_mif_req6 *req)
|
||||||
{
|
{
|
||||||
struct mf6ctable *mfct;
|
|
||||||
mifi_t mifi;
|
mifi_t mifi;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
mifi = req->mifi;
|
mifi = req->mifi;
|
||||||
|
|
||||||
mfct = &V_mfctables[0];
|
|
||||||
MIF6_LOCK();
|
MIF6_LOCK();
|
||||||
|
|
||||||
if (mifi >= mfct->nummifs) {
|
if (mifi >= mfct->nummifs) {
|
||||||
@@ -559,6 +576,7 @@ set_pim6(int *i)
|
|||||||
if ((*i != 1) && (*i != 0))
|
if ((*i != 1) && (*i != 0))
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
|
||||||
|
/* XXX-MJ */
|
||||||
V_pim6 = *i;
|
V_pim6 = *i;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
@@ -577,7 +595,7 @@ ip6_mrouter_init(struct socket *so, int v, int cmd)
|
|||||||
if (v != 1)
|
if (v != 1)
|
||||||
return (ENOPROTOOPT);
|
return (ENOPROTOOPT);
|
||||||
|
|
||||||
mfct = &V_mfctables[0];
|
mfct = somfctable(so);
|
||||||
MROUTER6_LOCK();
|
MROUTER6_LOCK();
|
||||||
|
|
||||||
if (mfct->router != NULL) {
|
if (mfct->router != NULL) {
|
||||||
@@ -595,7 +613,7 @@ ip6_mrouter_init(struct socket *so, int v, int cmd)
|
|||||||
|
|
||||||
V_pim6 = 0;/* used for stubbing out/in pim stuff */
|
V_pim6 = 0;/* used for stubbing out/in pim stuff */
|
||||||
|
|
||||||
callout_reset(&V_expire_upcalls_ch, EXPIRE_TIMEOUT, expire_upcalls,
|
callout_reset(&V_expire_upcalls_ch, EXPIRE_TIMEOUT, expire_upcalls_all,
|
||||||
curvnet);
|
curvnet);
|
||||||
|
|
||||||
MFC6_UNLOCK();
|
MFC6_UNLOCK();
|
||||||
@@ -618,7 +636,7 @@ X_ip6_mrouter_done(struct socket *so)
|
|||||||
struct mf6c *rt;
|
struct mf6c *rt;
|
||||||
struct rtdetq *rte;
|
struct rtdetq *rte;
|
||||||
|
|
||||||
mfct = &V_mfctables[0];
|
mfct = somfctable(so);
|
||||||
MROUTER6_LOCK();
|
MROUTER6_LOCK();
|
||||||
|
|
||||||
if (mfct->router != so) {
|
if (mfct->router != so) {
|
||||||
@@ -690,9 +708,8 @@ static struct sockaddr_in6 sin6 = { sizeof(sin6), AF_INET6 };
|
|||||||
* Add a mif to the mif table
|
* Add a mif to the mif table
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
add_m6if(struct mif6ctl *mifcp)
|
add_m6if(struct mf6ctable *mfct, int fibnum, struct mif6ctl *mifcp)
|
||||||
{
|
{
|
||||||
struct mf6ctable *mfct;
|
|
||||||
struct epoch_tracker et;
|
struct epoch_tracker et;
|
||||||
struct mif6 *mifp;
|
struct mif6 *mifp;
|
||||||
struct ifnet *ifp;
|
struct ifnet *ifp;
|
||||||
@@ -704,7 +721,6 @@ add_m6if(struct mif6ctl *mifcp)
|
|||||||
MIF6_UNLOCK();
|
MIF6_UNLOCK();
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
mfct = &V_mfctables[0];
|
|
||||||
mifp = &mfct->miftable[mifcp->mif6c_mifi];
|
mifp = &mfct->miftable[mifcp->mif6c_mifi];
|
||||||
if (mifp->m6_ifp != NULL) {
|
if (mifp->m6_ifp != NULL) {
|
||||||
MIF6_UNLOCK();
|
MIF6_UNLOCK();
|
||||||
@@ -743,6 +759,10 @@ add_m6if(struct mif6ctl *mifcp)
|
|||||||
MIF6_UNLOCK();
|
MIF6_UNLOCK();
|
||||||
return (EOPNOTSUPP);
|
return (EOPNOTSUPP);
|
||||||
}
|
}
|
||||||
|
if (ifp->if_fib != fibnum) {
|
||||||
|
MIF6_UNLOCK();
|
||||||
|
return (EADDRNOTAVAIL);
|
||||||
|
}
|
||||||
|
|
||||||
error = if_allmulti(ifp, 1);
|
error = if_allmulti(ifp, 1);
|
||||||
if (error) {
|
if (error) {
|
||||||
@@ -775,16 +795,14 @@ add_m6if(struct mif6ctl *mifcp)
|
|||||||
* Delete a mif from the mif table
|
* Delete a mif from the mif table
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
del_m6if_locked(mifi_t *mifip)
|
del_m6if_locked(struct mf6ctable *mfct, mifi_t *mifip)
|
||||||
{
|
{
|
||||||
struct mf6ctable *mfct;
|
|
||||||
struct mif6 *mifp;
|
struct mif6 *mifp;
|
||||||
mifi_t mifi;
|
mifi_t mifi;
|
||||||
struct ifnet *ifp;
|
struct ifnet *ifp;
|
||||||
|
|
||||||
MIF6_LOCK_ASSERT();
|
MIF6_LOCK_ASSERT();
|
||||||
|
|
||||||
mfct = &V_mfctables[0];
|
|
||||||
if (*mifip >= mfct->nummifs)
|
if (*mifip >= mfct->nummifs)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
mifp = &mfct->miftable[*mifip];
|
mifp = &mfct->miftable[*mifip];
|
||||||
@@ -818,12 +836,12 @@ del_m6if_locked(mifi_t *mifip)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
del_m6if(mifi_t *mifip)
|
del_m6if(struct mf6ctable *mfct, mifi_t *mifip)
|
||||||
{
|
{
|
||||||
int cc;
|
int cc;
|
||||||
|
|
||||||
MIF6_LOCK();
|
MIF6_LOCK();
|
||||||
cc = del_m6if_locked(mifip);
|
cc = del_m6if_locked(mfct, mifip);
|
||||||
MIF6_UNLOCK();
|
MIF6_UNLOCK();
|
||||||
|
|
||||||
return (cc);
|
return (cc);
|
||||||
@@ -833,17 +851,14 @@ del_m6if(mifi_t *mifip)
|
|||||||
* Add an mfc entry
|
* Add an mfc entry
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
add_m6fc(struct mf6cctl *mfccp)
|
add_m6fc(struct mf6ctable *mfct, struct mf6cctl *mfccp)
|
||||||
{
|
{
|
||||||
struct mf6ctable *mfct;
|
|
||||||
struct mf6c *rt;
|
struct mf6c *rt;
|
||||||
u_long hash;
|
u_long hash;
|
||||||
struct rtdetq *rte;
|
struct rtdetq *rte;
|
||||||
u_short nstl;
|
u_short nstl;
|
||||||
char ip6bufo[INET6_ADDRSTRLEN], ip6bufg[INET6_ADDRSTRLEN];
|
char ip6bufo[INET6_ADDRSTRLEN], ip6bufg[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
mfct = &V_mfctables[0];
|
|
||||||
|
|
||||||
MFC6_LOCK();
|
MFC6_LOCK();
|
||||||
rt = mf6c_find(mfct, &mfccp->mf6cc_origin.sin6_addr,
|
rt = mf6c_find(mfct, &mfccp->mf6cc_origin.sin6_addr,
|
||||||
&mfccp->mf6cc_mcastgrp.sin6_addr);
|
&mfccp->mf6cc_mcastgrp.sin6_addr);
|
||||||
@@ -1004,19 +1019,17 @@ collate(struct timeval *t)
|
|||||||
* Delete an mfc entry
|
* Delete an mfc entry
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
del_m6fc(struct mf6cctl *mfccp)
|
del_m6fc(struct mf6ctable *mfct, struct mf6cctl *mfccp)
|
||||||
{
|
{
|
||||||
#ifdef MRT6DEBUG
|
#ifdef MRT6DEBUG
|
||||||
char ip6bufo[INET6_ADDRSTRLEN], ip6bufg[INET6_ADDRSTRLEN];
|
char ip6bufo[INET6_ADDRSTRLEN], ip6bufg[INET6_ADDRSTRLEN];
|
||||||
#endif
|
#endif
|
||||||
struct mf6ctable *mfct;
|
|
||||||
struct sockaddr_in6 origin;
|
struct sockaddr_in6 origin;
|
||||||
struct sockaddr_in6 mcastgrp;
|
struct sockaddr_in6 mcastgrp;
|
||||||
struct mf6c *rt;
|
struct mf6c *rt;
|
||||||
struct mf6c **nptr;
|
struct mf6c **nptr;
|
||||||
u_long hash;
|
u_long hash;
|
||||||
|
|
||||||
mfct = &V_mfctables[0];
|
|
||||||
origin = mfccp->mf6cc_origin;
|
origin = mfccp->mf6cc_origin;
|
||||||
mcastgrp = mfccp->mf6cc_mcastgrp;
|
mcastgrp = mfccp->mf6cc_mcastgrp;
|
||||||
hash = MF6CHASH(origin.sin6_addr, mcastgrp.sin6_addr);
|
hash = MF6CHASH(origin.sin6_addr, mcastgrp.sin6_addr);
|
||||||
@@ -1139,7 +1152,7 @@ X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
mfct = &V_mfctables[0];
|
mfct = &V_mfctables[M_GETFIB(m)];
|
||||||
MFC6_LOCK();
|
MFC6_LOCK();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1331,20 +1344,17 @@ X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m)
|
|||||||
* Call from the Slow Timeout mechanism, every half second.
|
* Call from the Slow Timeout mechanism, every half second.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
expire_upcalls(void *arg)
|
expire_upcalls(struct mf6ctable *mfct)
|
||||||
{
|
{
|
||||||
#ifdef MRT6DEBUG
|
#ifdef MRT6DEBUG
|
||||||
char ip6bufo[INET6_ADDRSTRLEN], ip6bufg[INET6_ADDRSTRLEN];
|
char ip6bufo[INET6_ADDRSTRLEN], ip6bufg[INET6_ADDRSTRLEN];
|
||||||
#endif
|
#endif
|
||||||
struct mf6ctable *mfct;
|
|
||||||
struct rtdetq *rte;
|
struct rtdetq *rte;
|
||||||
struct mf6c *mfc, **nptr;
|
struct mf6c *mfc, **nptr;
|
||||||
u_long i;
|
u_long i;
|
||||||
|
|
||||||
MFC6_LOCK_ASSERT();
|
MFC6_LOCK_ASSERT();
|
||||||
CURVNET_SET((struct vnet *)arg);
|
|
||||||
|
|
||||||
mfct = &V_mfctables[0];
|
|
||||||
for (i = 0; i < MF6CTBLSIZ; i++) {
|
for (i = 0; i < MF6CTBLSIZ; i++) {
|
||||||
if (mfct->nexpire[i] == 0)
|
if (mfct->nexpire[i] == 0)
|
||||||
continue;
|
continue;
|
||||||
@@ -1382,8 +1392,21 @@ expire_upcalls(void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
callout_reset(&V_expire_upcalls_ch, EXPIRE_TIMEOUT,
|
}
|
||||||
expire_upcalls, curvnet);
|
|
||||||
|
/*
|
||||||
|
* Clean up the cache entry if upcall is not serviced
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
expire_upcalls_all(void *arg)
|
||||||
|
{
|
||||||
|
CURVNET_SET((struct vnet *)arg);
|
||||||
|
|
||||||
|
for (int i = 0; i < V_nmfctables; i++)
|
||||||
|
expire_upcalls(&V_mfctables[i]);
|
||||||
|
|
||||||
|
callout_reset(&V_expire_upcalls_ch, EXPIRE_TIMEOUT, expire_upcalls_all,
|
||||||
|
curvnet);
|
||||||
|
|
||||||
CURVNET_RESTORE();
|
CURVNET_RESTORE();
|
||||||
}
|
}
|
||||||
@@ -1753,7 +1776,7 @@ pim6_input(struct mbuf *m, int off, int proto, void *arg __unused)
|
|||||||
int pimlen;
|
int pimlen;
|
||||||
int minlen;
|
int minlen;
|
||||||
|
|
||||||
mfct = &V_mfctables[0];
|
mfct = &V_mfctables[M_GETFIB(m)];
|
||||||
|
|
||||||
PIM6STAT_INC(pim6s_rcv_total);
|
PIM6STAT_INC(pim6s_rcv_total);
|
||||||
|
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ 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_get)(struct socket *so, struct sockopt *sopt);
|
||||||
extern void (*ip6_mrouter_done)(struct socket *so);
|
extern void (*ip6_mrouter_done)(struct socket *so);
|
||||||
|
|
||||||
extern int (*mrt6_ioctl)(u_long, caddr_t);
|
extern int (*mrt6_ioctl)(u_long, caddr_t, int);
|
||||||
#endif /* _KERNEL */
|
#endif /* _KERNEL */
|
||||||
|
|
||||||
#endif /* !_NETINET6_IP6_MROUTE_H_ */
|
#endif /* !_NETINET6_IP6_MROUTE_H_ */
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ int (*ip6_mrouter_set)(struct socket *, struct sockopt *);
|
|||||||
int (*ip6_mrouter_get)(struct socket *, struct sockopt *);
|
int (*ip6_mrouter_get)(struct socket *, struct sockopt *);
|
||||||
void (*ip6_mrouter_done)(struct socket *);
|
void (*ip6_mrouter_done)(struct socket *);
|
||||||
int (*ip6_mforward)(struct ip6_hdr *, struct ifnet *, struct mbuf *);
|
int (*ip6_mforward)(struct ip6_hdr *, struct ifnet *, struct mbuf *);
|
||||||
int (*mrt6_ioctl)(u_long, caddr_t);
|
int (*mrt6_ioctl)(u_long, caddr_t, int);
|
||||||
|
|
||||||
struct rip6_inp_match_ctx {
|
struct rip6_inp_match_ctx {
|
||||||
struct ip6_hdr *ip6;
|
struct ip6_hdr *ip6;
|
||||||
|
|||||||
Reference in New Issue
Block a user