git: 488626e55384 - main - pf: copy out rather than m_pullup() in pf_test_eth_rule()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 23 Jun 2022 08:44:49 UTC
The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=488626e55384e253326b92f7aab1cc62add2f7e7 commit 488626e55384e253326b92f7aab1cc62add2f7e7 Author: Kristof Provost <kp@FreeBSD.org> AuthorDate: 2022-06-22 14:52:24 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2022-06-23 07:50:44 +0000 pf: copy out rather than m_pullup() in pf_test_eth_rule() Don't change the mbuf chain layout. We've encountered alignment issues in the tcp syncookie code on armv7, which are triggered by the m_pullup() here. Reviewed by: mjg Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D35551 --- sys/netpfil/pf/pf.c | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 172ed52dbc03..275e1fcdbeb4 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -3848,6 +3848,12 @@ pf_match_eth_tag(struct mbuf *m, struct pf_keth_rule *r, int *tag, int mtag) static int pf_test_eth_rule(int dir, struct pfi_kkif *kif, struct mbuf **m0) { +#ifdef INET + struct ip ip; +#endif +#ifdef INET6 + struct ip6_hdr ip6; +#endif struct mbuf *m = *m0; struct ether_header *e; struct pf_keth_rule *r, *rm, *a = NULL; @@ -3893,39 +3899,25 @@ pf_test_eth_rule(int dir, struct pfi_kkif *kif, struct mbuf **m0) switch (proto) { #ifdef INET case ETHERTYPE_IP: { - struct ip *ip; - m = m_pullup(m, sizeof(struct ether_header) + - sizeof(struct ip)); - if (m == NULL) { - *m0 = NULL; - return (PF_DROP); - } af = AF_INET; - ip = mtodo(m, sizeof(struct ether_header)); - src = (struct pf_addr *)&ip->ip_src; - dst = (struct pf_addr *)&ip->ip_dst; + m_copydata(m, sizeof(struct ether_header), sizeof(ip), + (caddr_t)&ip); + src = (struct pf_addr *)&ip.ip_src; + dst = (struct pf_addr *)&ip.ip_dst; break; } #endif /* INET */ #ifdef INET6 case ETHERTYPE_IPV6: { - struct ip6_hdr *ip6; - m = m_pullup(m, sizeof(struct ether_header) + - sizeof(struct ip6_hdr)); - if (m == NULL) { - *m0 = NULL; - return (PF_DROP); - } af = AF_INET6; - ip6 = mtodo(m, sizeof(struct ether_header)); - src = (struct pf_addr *)&ip6->ip6_src; - dst = (struct pf_addr *)&ip6->ip6_dst; + m_copydata(m, sizeof(struct ether_header), sizeof(ip6), + (caddr_t)&ip6); + src = (struct pf_addr *)&ip6.ip6_src; + dst = (struct pf_addr *)&ip6.ip6_dst; break; } #endif /* INET6 */ } - e = mtod(m, struct ether_header *); - *m0 = m; PF_RULES_RLOCK();