git: 12c542cd0e9e - main - dummynet: do not store struct ifnet pointers
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 20 May 2022 12:51:16 UTC
The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=12c542cd0e9efc1ad9f20f1035402c0acf6d403f commit 12c542cd0e9efc1ad9f20f1035402c0acf6d403f Author: Kristof Provost <kp@FreeBSD.org> AuthorDate: 2022-05-19 13:12:54 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2022-05-20 12:49:30 +0000 dummynet: do not store struct ifnet pointers The dn_pkt_tag tag contained a struct ifnet pointer. If we persist that across NET_EPOCH boundaries (as we did in dummynet) we risk panics if the interface is removed between the packet being enqueued and it being dequeued. Convert the pointer into an index/generation pair and restore it when the packet is taken out of the queue. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D35256 --- sys/netpfil/ipfw/ip_dn_io.c | 10 +++++++--- sys/netpfil/ipfw/ip_dn_private.h | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/sys/netpfil/ipfw/ip_dn_io.c b/sys/netpfil/ipfw/ip_dn_io.c index 824e7450fb8f..98f9d08495df 100644 --- a/sys/netpfil/ipfw/ip_dn_io.c +++ b/sys/netpfil/ipfw/ip_dn_io.c @@ -766,12 +766,12 @@ dummynet_send(struct mbuf *m) /* extract the dummynet info, rename the tag * to carry reinject info. */ + ifp = ifnet_byindexgen(pkt->if_index, pkt->if_idxgen); if (pkt->dn_dir == (DIR_OUT | PROTO_LAYER2) && - pkt->ifp == NULL) { + ifp == NULL) { dst = DIR_DROP; } else { dst = pkt->dn_dir; - ifp = pkt->ifp; tag->m_tag_cookie = MTAG_IPFW_RULE; tag->m_tag_id = 0; } @@ -852,7 +852,11 @@ tag_mbuf(struct mbuf *m, int dir, struct ip_fw_args *fwa) /* only keep this info */ dt->rule.info &= (IPFW_ONEPASS | IPFW_IS_DUMMYNET); dt->dn_dir = dir; - dt->ifp = fwa->flags & IPFW_ARGS_OUT ? fwa->ifp : NULL; + if (fwa->flags & IPFW_ARGS_OUT && fwa->ifp != NULL) { + NET_EPOCH_ASSERT(); + dt->if_index = fwa->ifp->if_index; + dt->if_idxgen = fwa->ifp->if_idxgen; + } /* dt->output tame is updated as we move through */ dt->output_time = V_dn_cfg.curr_time; dt->iphdr_off = (dir & PROTO_LAYER2) ? ETHER_HDR_LEN : 0; diff --git a/sys/netpfil/ipfw/ip_dn_private.h b/sys/netpfil/ipfw/ip_dn_private.h index d7df31b85345..1cd38a2c94d8 100644 --- a/sys/netpfil/ipfw/ip_dn_private.h +++ b/sys/netpfil/ipfw/ip_dn_private.h @@ -374,7 +374,8 @@ struct dn_pkt_tag { int dn_dir; /* action when packet comes out.*/ /* see ip_fw_private.h */ uint64_t output_time; /* when the pkt is due for delivery*/ - struct ifnet *ifp; /* interface, for ip_output */ + uint16_t if_index; + uint16_t if_idxgen; struct _ip6dn_args ip6opt; /* XXX ipv6 options */ uint16_t iphdr_off; /* IP header offset for mtodo() */ };