aboutsummaryrefslogtreecommitdiff
path: root/sys/net/if.c
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2022-01-27 05:58:50 +0000
committerEd Maste <emaste@FreeBSD.org>2022-05-05 18:38:07 +0000
commit4d7a1361ef3227fd3d78c7a5da132cbba351dc9d (patch)
tree53d87c48e3be6a829e68e610d5caa62b8b74a688 /sys/net/if.c
parent80e60e236d85d13cd2a34973dd408477288efa38 (diff)
downloadsrc-4d7a1361ef3227fd3d78c7a5da132cbba351dc9d.tar.gz
src-4d7a1361ef3227fd3d78c7a5da132cbba351dc9d.zip
ifnet/mbuf: provide KPI to serialize/restore m->m_pkthdr.rcvif
Supplement ifindex table with generation count and use it to serialize & restore an ifnet pointer. Reviewed by: kp Differential revision: https://reviews.freebsd.org/D33266 Fun note: git show e6abef09187a (cherry picked from commit e1882428dcbbafd2814d7e17b977a8f686784b39)
Diffstat (limited to 'sys/net/if.c')
-rw-r--r--sys/net/if.c49
1 files changed, 36 insertions, 13 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 3b303fe42e99..ff7071cea364 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -313,7 +313,10 @@ VNET_DEFINE(struct ifgrouphead, ifg_head);
/* 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 @@ sysctl_ifcount(SYSCTL_HANDLER_ARGS)
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 @@ ifnet_byindex(u_int idx)
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 @@ ifnet_byindex_ref(u_int idx)
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);
+}
+
/*
* Network interface utility routines.
*
@@ -557,13 +578,13 @@ if_alloc_domain(u_char type, int numa_domain)
* 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;
@@ -579,7 +600,8 @@ if_alloc_domain(u_char type, int numa_domain)
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);
@@ -654,9 +676,10 @@ if_free(struct ifnet *ifp)
* 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();
@@ -805,7 +828,7 @@ if_attach_internal(struct ifnet *ifp, bool vmove)
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;
@@ -4494,8 +4517,8 @@ if_show_ifnet(struct ifnet *ifp)
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);
@@ -4550,7 +4573,7 @@ DB_SHOW_ALL_COMMAND(ifnets, db_show_all_ifnets)
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);