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;