From 4f592c123a8bb037be23d6d4204468b8edda3bcc Mon Sep 17 00:00:00 2001 From: David Gwynne Date: Thu, 23 Nov 2023 23:45:11 +0000 Subject: 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. --- sys/net/if_veb.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'sys/net') 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 @@ -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; -- cgit v1.2.3