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();