Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146344501
D33266.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D33266.diff
View Options
diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c
--- a/sys/kern/kern_mbuf.c
+++ b/sys/kern/kern_mbuf.c
@@ -1635,6 +1635,28 @@
counter_u64_add(snd_tag_count, -1);
}
+void
+m_rcvif_serialize(struct mbuf *m)
+{
+ u_short idx, gen;
+
+ M_ASSERTPKTHDR(m);
+ idx = m->m_pkthdr.rcvif->if_index;
+ gen = m->m_pkthdr.rcvif->if_idxgen;
+ m->m_pkthdr.rcvidx = idx;
+ m->m_pkthdr.rcvgen = gen;
+}
+
+struct ifnet *
+m_rcvif_restore(struct mbuf *m)
+{
+
+ M_ASSERTPKTHDR(m);
+
+ return ((m->m_pkthdr.rcvif = ifnet_byindexgen(m->m_pkthdr.rcvidx,
+ m->m_pkthdr.rcvgen)));
+}
+
/*
* Allocate an mbuf with anonymous external pages.
*/
diff --git a/sys/net/if.c b/sys/net/if.c
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -313,7 +313,10 @@
/* Table of ifnet by index. */
static int if_index;
static int if_indexlim = 8;
-static struct ifnet **ifindex_table;
+static struct ifindex_entry {
+ struct ifnet *ife_ifnet;
+ uint16_t ife_gencnt;
+} *ifindex_table;
SYSCTL_NODE(_net_link_generic, IFMIB_SYSTEM, system,
CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
@@ -325,8 +328,8 @@
IFNET_RLOCK();
for (int i = 1; i <= if_index; i++)
- if (ifindex_table[i] != NULL &&
- ifindex_table[i]->if_vnet == curvnet)
+ if (ifindex_table[i].ife_ifnet != NULL &&
+ ifindex_table[i].ife_ifnet->if_vnet == curvnet)
rv = i;
IFNET_RUNLOCK();
@@ -370,7 +373,7 @@
if (__predict_false(idx > if_index))
return (NULL);
- ifp = ck_pr_load_ptr(&ifindex_table[idx]);
+ ifp = ck_pr_load_ptr(&ifindex_table[idx].ife_ifnet);
if (curvnet != NULL && ifp != NULL && ifp->if_vnet != curvnet)
ifp = NULL;
@@ -391,6 +394,24 @@
return (ifp);
}
+struct ifnet *
+ifnet_byindexgen(uint16_t idx, uint16_t gen)
+{
+ struct ifnet *ifp;
+
+ NET_EPOCH_ASSERT();
+
+ if (__predict_false(idx > if_index))
+ return (NULL);
+
+ ifp = ck_pr_load_ptr(&ifindex_table[idx].ife_ifnet);
+
+ if (ifindex_table[idx].ife_gencnt == gen)
+ return (ifp);
+ else
+ return (NULL);
+}
+
struct ifaddr *
ifaddr_byindex(u_short idx)
{
@@ -571,13 +592,13 @@
* next slot.
*/
for (idx = 1; idx <= if_index; idx++) {
- if (ifindex_table[idx] == NULL)
+ if (ifindex_table[idx].ife_ifnet == NULL)
break;
}
/* Catch if_index overflow. */
if (idx >= if_indexlim) {
- struct ifnet **new, **old;
+ struct ifindex_entry *new, *old;
int newlim;
newlim = if_indexlim * 2;
@@ -593,7 +614,8 @@
if_index = idx;
ifp->if_index = idx;
- ck_pr_store_ptr(&ifindex_table[idx], ifp);
+ ifp->if_idxgen = ifindex_table[idx].ife_gencnt;
+ ck_pr_store_ptr(&ifindex_table[idx].ife_ifnet, ifp);
IFNET_WUNLOCK();
return (ifp);
@@ -668,9 +690,10 @@
* virtualized and interface would outlive the vnet.
*/
IFNET_WLOCK();
- MPASS(ifindex_table[ifp->if_index] == ifp);
- ck_pr_store_ptr(&ifindex_table[ifp->if_index], NULL);
- while (if_index > 0 && ifindex_table[if_index] == NULL)
+ MPASS(ifindex_table[ifp->if_index].ife_ifnet == ifp);
+ ck_pr_store_ptr(&ifindex_table[ifp->if_index].ife_ifnet, NULL);
+ ifindex_table[ifp->if_index].ife_gencnt++;
+ while (if_index > 0 && ifindex_table[if_index].ife_ifnet == NULL)
if_index--;
IFNET_WUNLOCK();
@@ -819,7 +842,7 @@
struct sockaddr_dl *sdl;
struct ifaddr *ifa;
- MPASS(ifindex_table[ifp->if_index] == ifp);
+ MPASS(ifindex_table[ifp->if_index].ife_ifnet == ifp);
#ifdef VIMAGE
ifp->if_vnet = curvnet;
@@ -4508,8 +4531,8 @@
IF_DB_PRINTF("%d", if_dunit);
IF_DB_PRINTF("%s", if_description);
IF_DB_PRINTF("%u", if_index);
+ IF_DB_PRINTF("%d", if_idxgen);
IF_DB_PRINTF("%u", if_refcount);
- IF_DB_PRINTF("%d", if_index_reserved);
IF_DB_PRINTF("%p", if_softc);
IF_DB_PRINTF("%p", if_l2com);
IF_DB_PRINTF("%p", if_llsoftc);
@@ -4564,7 +4587,7 @@
u_short idx;
for (idx = 1; idx <= if_index; idx++) {
- ifp = ifindex_table[idx];
+ ifp = ifindex_table[idx].ife_ifnet;
if (ifp == NULL)
continue;
db_printf( "%20s ifp=%p\n", ifp->if_xname, ifp);
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -334,7 +334,7 @@
const char *if_dname; /* driver name */
int if_dunit; /* unit or IF_DUNIT_NONE */
u_short if_index; /* numeric abbreviation for this if */
- short if_index_reserved; /* spare space to grow if_index */
+ u_short if_idxgen; /* ... and its generation count */
char if_xname[IFNAMSIZ]; /* external name (name + unit) */
char *if_description; /* interface description */
@@ -644,6 +644,13 @@
struct ifnet *ifnet_byindex(u_int);
struct ifnet *ifnet_byindex_ref(u_int);
+/*
+ * ifnet_byindexgen() looks up ifnet by index and generation count,
+ * attempting to restore a weak pointer that had been stored across
+ * the epoch.
+ */
+struct ifnet *ifnet_byindexgen(uint16_t idx, uint16_t gen);
+
/*
* Given the index, ifaddr_byindex() returns the one and only
* link-level ifaddr for the interface. You are not supposed to use
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -159,6 +159,10 @@
union {
struct m_snd_tag *snd_tag; /* send tag, if any */
struct ifnet *rcvif; /* rcv interface */
+ struct {
+ uint16_t rcvidx; /* rcv interface index ... */
+ uint16_t rcvgen; /* ... and generation count */
+ };
};
SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */
int32_t len; /* total packet length */
@@ -862,6 +866,8 @@
void m_snd_tag_init(struct m_snd_tag *, struct ifnet *,
const struct if_snd_tag_sw *);
void m_snd_tag_destroy(struct m_snd_tag *);
+void m_rcvif_serialize(struct mbuf *);
+struct ifnet *m_rcvif_restore(struct mbuf *);
static __inline int
m_gettype(int size)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Mar 2, 10:28 PM (5 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29171552
Default Alt Text
D33266.diff (5 KB)
Attached To
Mode
D33266: ifnet/mbuf: provide KPI to serialize/restore m->m_pkthdr.rcvif
Attached
Detach File
Event Timeline
Log In to Comment