diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2023-11-23 23:45:11 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2023-11-23 23:45:11 +0000 |
commit | 4f592c123a8bb037be23d6d4204468b8edda3bcc (patch) | |
tree | 99235d7d30755808bb07b42121b978403538f27a /sys/net | |
parent | 0615daf9d387c9a48b49cb0eee470980c1ee3021 (diff) |
avoid passing weird mbuf chains to pf when pushing out a veb.
pf expects the ip header to be in the first mbuf of the chain we
pass to pf_test, but in some situations the ethernet header is the
only data in the first mbuf. after we remove the ethernet header,
the first mbuf had no data in it which confused pf. fix this by
passing all packets to ip_check on output as well as input. ip input
handlers do all the necessary m_pullups.
found by Mark Patruck.
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if_veb.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/sys/net/if_veb.c b/sys/net/if_veb.c index df405678fa3..cbdc3fb7d53 100644 --- a/sys/net/if_veb.c +++ b/sys/net/if_veb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_veb.c,v 1.31 2023/05/16 14:32:54 jan Exp $ */ +/* $OpenBSD: if_veb.c,v 1.32 2023/11/23 23:45:10 dlg Exp $ */ /* * Copyright (c) 2021 David Gwynne <dlg@openbsd.org> @@ -612,6 +612,7 @@ veb_pf(struct ifnet *ifp0, int dir, struct mbuf *m) { struct ether_header *eh, copy; const struct veb_pf_ip_family *fam; + int hlen; /* * pf runs on vport interfaces when they enter or leave the @@ -640,11 +641,9 @@ veb_pf(struct ifnet *ifp0, int dir, struct mbuf *m) copy = *eh; m_adj(m, sizeof(*eh)); - if (dir == PF_IN) { - m = (*fam->ip_check)(ifp0, m); - if (m == NULL) - return (NULL); - } + m = (*fam->ip_check)(ifp0, m); + if (m == NULL) + return (NULL); if (pf_test(fam->af, dir, ifp0, &m) != PF_PASS) { m_freem(m); @@ -660,12 +659,14 @@ veb_pf(struct ifnet *ifp0, int dir, struct mbuf *m) return (NULL); } - m = m_prepend(m, sizeof(*eh), M_DONTWAIT); + hlen = roundup(sizeof(*eh), sizeof(long)); + m = m_prepend(m, hlen, M_DONTWAIT); if (m == NULL) return (NULL); /* checksum? */ + m_adj(m, hlen - sizeof(*eh)); eh = mtod(m, struct ether_header *); *eh = copy; |