git: 80e76c61ccc4 - main - pf: set scope in pf_refragment6()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 16 Mar 2023 10:01:25 UTC
The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=80e76c61ccc47651ca1be34b912d53536db34e6f commit 80e76c61ccc47651ca1be34b912d53536db34e6f Author: Kristof Provost <kp@FreeBSD.org> AuthorDate: 2023-03-13 09:27:59 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2023-03-16 09:59:04 +0000 pf: set scope in pf_refragment6() Link-local traffic needs to have a scope embedded before it's passed on to ip6_output(). Do so in pf_refragment6(), because when we end up here in the output path we may have passed through ip6_output() already (before being reassembled), where the scope would have been removed. Re-embed the scope so that link-local traffic is sent correctly. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D39062 --- sys/netpfil/pf/pf_norm.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c index bc5f6d38a2bf..8d36e72d71b2 100644 --- a/sys/netpfil/pf/pf_norm.c +++ b/sys/netpfil/pf/pf_norm.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include <netinet/ip.h> #include <netinet/ip_var.h> #include <netinet6/ip6_var.h> +#include <netinet6/scope6_var.h> #include <netinet/tcp.h> #include <netinet/tcp_fsm.h> #include <netinet/tcp_seq.h> @@ -946,6 +947,7 @@ pf_refragment6(struct ifnet *ifp, struct mbuf **m0, struct m_tag *mtag, bool forward) { struct mbuf *m = *m0, *t; + struct ip6_hdr *hdr; struct pf_fragment_tag *ftag = (struct pf_fragment_tag *)(mtag + 1); struct pf_pdesc pd; uint32_t frag_id; @@ -972,13 +974,17 @@ pf_refragment6(struct ifnet *ifp, struct mbuf **m0, struct m_tag *mtag, *(mtod(m, char *) + off) = IPPROTO_FRAGMENT; m = *m0; } else { - struct ip6_hdr *hdr; - hdr = mtod(m, struct ip6_hdr *); proto = hdr->ip6_nxt; hdr->ip6_nxt = IPPROTO_FRAGMENT; } + /* In case of link-local traffic we'll need a scope set. */ + hdr = mtod(m, struct ip6_hdr *); + + in6_setscope(&hdr->ip6_src, ifp, NULL); + in6_setscope(&hdr->ip6_dst, ifp, NULL); + /* The MTU must be a multiple of 8 bytes, or we risk doing the * fragmentation wrong. */ maxlen = maxlen & ~7;