diff options
author | Gleb Smirnoff <glebius@FreeBSD.org> | 2022-01-27 05:58:50 +0000 |
---|---|---|
committer | Ed Maste <emaste@FreeBSD.org> | 2022-05-05 18:38:07 +0000 |
commit | 4d7a1361ef3227fd3d78c7a5da132cbba351dc9d (patch) | |
tree | 53d87c48e3be6a829e68e610d5caa62b8b74a688 /sys/net/if.c | |
parent | 80e60e236d85d13cd2a34973dd408477288efa38 (diff) | |
download | src-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.c | 49 |
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); |