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() */
};