Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F161083416
D55242.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D55242.diff
View Options
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -279,17 +279,6 @@
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) {
case SIOCAADDRCTL_POLICY:
case SIOCDADDRCTL_POLICY:
@@ -615,6 +604,12 @@
in6_control(struct socket *so, u_long cmd, void *data,
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));
}
diff --git a/sys/netinet6/ip6_mroute.h b/sys/netinet6/ip6_mroute.h
--- a/sys/netinet6/ip6_mroute.h
+++ b/sys/netinet6/ip6_mroute.h
@@ -288,7 +288,7 @@
extern int (*ip6_mrouter_get)(struct socket *so, struct sockopt *sopt);
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 /* !_NETINET6_IP6_MROUTE_H_ */
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
@@ -216,8 +216,11 @@
static int
sysctl_mfctable(SYSCTL_HANDLER_ARGS)
{
- return (SYSCTL_OUT(req, &V_mfctables[0].mfchashtbl,
- sizeof(V_mfctables[0].mfchashtbl)));
+ int fibnum;
+
+ 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,
CTLTYPE_OPAQUE | CTLFLAG_RD,
@@ -229,13 +232,15 @@
sysctl_mif6table(SYSCTL_HANDLER_ARGS)
{
struct mif6_sctl *out;
+ struct mf6ctable *mfct;
int error;
+ mfct = &V_mfctables[curthread->td_proc->p_fibnum];
out = malloc(sizeof(struct mif6_sctl) * MAXMIFS, M_TEMP,
M_WAITOK | M_ZERO);
for (int i = 0; i < MAXMIFS; 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_rate_limit = mifp->m6_rate_limit;
@@ -287,7 +292,8 @@
#define MRT6_DLOG(m, fmt, ...)
#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 UPCALL_EXPIRE 6 /* number of timeouts */
@@ -342,13 +348,13 @@
#endif /* UPCALL_TIMING */
static int ip6_mrouter_init(struct socket *, int, int);
-static int add_m6fc(struct mf6cctl *);
-static int add_m6if(struct mif6ctl *);
-static int del_m6fc(struct mf6cctl *);
-static int del_m6if(mifi_t *);
-static int del_m6if_locked(mifi_t *);
-static int get_mif6_cnt(struct sioc_mif_req6 *);
-static int get_sg_cnt(struct sioc_sg_req6 *);
+static int add_m6fc(struct mf6ctable *, struct mf6cctl *);
+static int add_m6if(struct mf6ctable *, int, struct mif6ctl *);
+static int del_m6fc(struct mf6ctable *, struct mf6cctl *);
+static int del_m6if(struct mf6ctable *, mifi_t *);
+static int del_m6if_locked(struct mf6ctable *, mifi_t *);
+static int get_mif6_cnt(struct mf6ctable *, struct sioc_mif_req6 *);
+static int get_sg_cnt(struct mf6ctable *, struct sioc_sg_req6 *);
VNET_DEFINE_STATIC(struct callout, expire_upcalls_ch);
#define V_expire_upcalls_ch VNET(expire_upcalls_ch)
@@ -357,7 +363,7 @@
static void X_ip6_mrouter_done(struct socket *);
static int X_ip6_mrouter_set(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 *
mf6c_find(const struct mf6ctable *mfct, const struct in6_addr *origin,
@@ -376,6 +382,17 @@
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.
*/
@@ -389,7 +406,7 @@
struct mf6cctl mfcc;
mifi_t mifi;
- mfct = &V_mfctables[0];
+ mfct = somfctable(so);
if (so != mfct->router && sopt->sopt_name != MRT6_INIT)
return (EPERM);
@@ -411,25 +428,25 @@
error = sooptcopyin(sopt, &mifc, sizeof(mifc), sizeof(mifc));
if (error)
break;
- error = add_m6if(&mifc);
+ error = add_m6if(mfct, so->so_fibnum, &mifc);
break;
case MRT6_ADD_MFC:
error = sooptcopyin(sopt, &mfcc, sizeof(mfcc), sizeof(mfcc));
if (error)
break;
- error = add_m6fc(&mfcc);
+ error = add_m6fc(mfct, &mfcc);
break;
case MRT6_DEL_MFC:
error = sooptcopyin(sopt, &mfcc, sizeof(mfcc), sizeof(mfcc));
if (error)
break;
- error = del_m6fc(&mfcc);
+ error = del_m6fc(mfct, &mfcc);
break;
case MRT6_DEL_MIF:
error = sooptcopyin(sopt, &mifi, sizeof(mifi), sizeof(mifi));
if (error)
break;
- error = del_m6if(&mifi);
+ error = del_m6if(mfct, &mifi);
break;
case MRT6_PIM:
error = sooptcopyin(sopt, &optval, sizeof(optval),
@@ -455,7 +472,7 @@
struct mf6ctable *mfct;
int error = 0;
- mfct = &V_mfctables[0];
+ mfct = somfctable(so);
if (so != mfct->router)
return (EACCES);
@@ -471,24 +488,27 @@
* Handle ioctl commands to obtain information from the cache
*/
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;
error = priv_check(curthread, PRIV_NETINET_MROUTE);
if (error)
return (error);
- error = EINVAL;
+
+ mfct = &V_mfctables[fibnum];
switch (cmd) {
case SIOCGETSGCNT_IN6:
- error = get_sg_cnt((struct sioc_sg_req6 *)data);
+ error = get_sg_cnt(mfct, (struct sioc_sg_req6 *)data);
break;
case SIOCGETMIFCNT_IN6:
- error = get_mif6_cnt((struct sioc_mif_req6 *)data);
+ error = get_mif6_cnt(mfct, (struct sioc_mif_req6 *)data);
break;
default:
+ error = EINVAL;
break;
}
@@ -499,7 +519,7 @@
* returns the packet, byte, rpf-failure count for the source group provided
*/
static int
-get_sg_cnt(struct sioc_sg_req6 *req)
+get_sg_cnt(struct mf6ctable *mfct, struct sioc_sg_req6 *req)
{
struct mf6c *rt;
int ret;
@@ -507,8 +527,7 @@
ret = 0;
MFC6_LOCK();
- rt = mf6c_find(&V_mfctables[0], &req->src.sin6_addr,
- &req->grp.sin6_addr);
+ rt = mf6c_find(mfct, &req->src.sin6_addr, &req->grp.sin6_addr);
if (rt == NULL) {
ret = ESRCH;
} else {
@@ -525,16 +544,14 @@
* returns the input and output packet and byte counts on the mif provided
*/
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;
int ret;
ret = 0;
mifi = req->mifi;
- mfct = &V_mfctables[0];
MIF6_LOCK();
if (mifi >= mfct->nummifs) {
@@ -559,6 +576,7 @@
if ((*i != 1) && (*i != 0))
return (EINVAL);
+ /* XXX-MJ */
V_pim6 = *i;
return (0);
@@ -577,7 +595,7 @@
if (v != 1)
return (ENOPROTOOPT);
- mfct = &V_mfctables[0];
+ mfct = somfctable(so);
MROUTER6_LOCK();
if (mfct->router != NULL) {
@@ -595,7 +613,7 @@
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);
MFC6_UNLOCK();
@@ -618,7 +636,7 @@
struct mf6c *rt;
struct rtdetq *rte;
- mfct = &V_mfctables[0];
+ mfct = somfctable(so);
MROUTER6_LOCK();
if (mfct->router != so) {
@@ -690,9 +708,8 @@
* Add a mif to the mif table
*/
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 mif6 *mifp;
struct ifnet *ifp;
@@ -704,7 +721,6 @@
MIF6_UNLOCK();
return (EINVAL);
}
- mfct = &V_mfctables[0];
mifp = &mfct->miftable[mifcp->mif6c_mifi];
if (mifp->m6_ifp != NULL) {
MIF6_UNLOCK();
@@ -743,6 +759,10 @@
MIF6_UNLOCK();
return (EOPNOTSUPP);
}
+ if (ifp->if_fib != fibnum) {
+ MIF6_UNLOCK();
+ return (EADDRNOTAVAIL);
+ }
error = if_allmulti(ifp, 1);
if (error) {
@@ -775,16 +795,14 @@
* Delete a mif from the mif table
*/
static int
-del_m6if_locked(mifi_t *mifip)
+del_m6if_locked(struct mf6ctable *mfct, mifi_t *mifip)
{
- struct mf6ctable *mfct;
struct mif6 *mifp;
mifi_t mifi;
struct ifnet *ifp;
MIF6_LOCK_ASSERT();
- mfct = &V_mfctables[0];
if (*mifip >= mfct->nummifs)
return (EINVAL);
mifp = &mfct->miftable[*mifip];
@@ -818,12 +836,12 @@
}
static int
-del_m6if(mifi_t *mifip)
+del_m6if(struct mf6ctable *mfct, mifi_t *mifip)
{
int cc;
MIF6_LOCK();
- cc = del_m6if_locked(mifip);
+ cc = del_m6if_locked(mfct, mifip);
MIF6_UNLOCK();
return (cc);
@@ -833,17 +851,14 @@
* Add an mfc entry
*/
static int
-add_m6fc(struct mf6cctl *mfccp)
+add_m6fc(struct mf6ctable *mfct, 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];
- mfct = &V_mfctables[0];
-
MFC6_LOCK();
rt = mf6c_find(mfct, &mfccp->mf6cc_origin.sin6_addr,
&mfccp->mf6cc_mcastgrp.sin6_addr);
@@ -1004,19 +1019,17 @@
* Delete an mfc entry
*/
static int
-del_m6fc(struct mf6cctl *mfccp)
+del_m6fc(struct mf6ctable *mfct, struct mf6cctl *mfccp)
{
#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);
@@ -1139,7 +1152,7 @@
return (0);
}
- mfct = &V_mfctables[0];
+ mfct = &V_mfctables[M_GETFIB(m)];
MFC6_LOCK();
/*
@@ -1331,20 +1344,17 @@
* Call from the Slow Timeout mechanism, every half second.
*/
static void
-expire_upcalls(void *arg)
+expire_upcalls(struct mf6ctable *mfct)
{
#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 (mfct->nexpire[i] == 0)
continue;
@@ -1382,8 +1392,21 @@
}
}
}
- 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();
}
@@ -1753,7 +1776,7 @@
int pimlen;
int minlen;
- mfct = &V_mfctables[0];
+ mfct = &V_mfctables[M_GETFIB(m)];
PIM6STAT_INC(pim6s_rcv_total);
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -145,7 +145,7 @@
int (*ip6_mrouter_get)(struct socket *, struct sockopt *);
void (*ip6_mrouter_done)(struct socket *);
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 ip6_hdr *ip6;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Jul 1, 10:20 AM (17 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34554872
Default Alt Text
D55242.diff (11 KB)
Attached To
Mode
D55242: ip6_mroute: FIBify
Attached
Detach File
Event Timeline
Log In to Comment