The branch main has been updated by kp:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=80e76c61ccc47651ca1be34b912d53536db34e6f

commit 80e76c61ccc47651ca1be34b912d53536db34e6f
Author:     Kristof Provost <[email protected]>
AuthorDate: 2023-03-13 09:27:59 +0000
Commit:     Kristof Provost <[email protected]>
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;

Reply via email to