Page MenuHomeFreeBSD

Do not fragment forwarded IPv6 datagrams that were send by dummynet

Authored by ae on Nov 2 2021, 4:56 PM.


Group Reviewers

Packets that were handled by dummynet are going to the wire via
ip6_output() function. Thus it is possible, that IPv6 datagram will be
fragmented if egress interface has lower MTU.

This can be tracked by follow this path:

ip6_input -> ip6_tryforward -> pfil_run_hooks(PFIL_IN),
  pfil_run_hooks(PFIL_OUT|PFIL_FWD) -> dummynet_io ->
  dummynet_send -> ip6_output -> ip6_fragment

Diff Detail

rS FreeBSD src repository - subversion
Lint Passed
No Test Coverage
Build Status
Buildable 42525
Build 39413: arc lint + arc unit

Event Timeline

ae held this revision as a draft.
ae published this revision for review.Nov 2 2021, 4:57 PM
ae edited the summary of this revision. (Show Details)
ae added reviewers: network, bz, melifaro.
kp added a subscriber: kp.

Looks good to me, but I think we need to fix pf too:

diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 9595650dbc36..54438ff2cf8d 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -6360,7 +6360,7 @@ pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t a

 static bool
-pf_pdesc_to_dnflow(int dir, const struct pf_pdesc *pd,
+pf_pdesc_to_dnflow(int dir, int pflags, const struct pf_pdesc *pd,
     const struct pf_krule *r, const struct pf_kstate *s,
     struct ip_fw_args *dnflow)
@@ -6381,6 +6381,9 @@ pf_pdesc_to_dnflow(int dir, const struct pf_pdesc *pd,
                dnflow->flags |= IPFW_ARGS_OUT;

+       if (pflags & PFIL_FWD)
+               dnflow->flags |= IPFW_ARGS_FWD;
        if (dir != dndir && pd->act.dnrpipe) {
                dnflow-> = pd->act.dnrpipe;
@@ -6883,7 +6886,8 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *
                        } else {
                                struct ip_fw_args dnflow;

-                               if (pf_pdesc_to_dnflow(dir, &pd, r, s, &dnflow)) {
+                               if (pf_pdesc_to_dnflow(dir, pflags, &pd, r,
+                                   s, &dnflow)) {
                                        ip_dn_io_ptr(m0, &dnflow);
                                        if (*m0 == NULL)
                                                action = PF_DROP;
@@ -7242,7 +7246,8 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb
                                return (action);

-                       if (pf_pdesc_to_dnflow(dir, &pd, r, s, &dnflow)) {
+                       if (pf_pdesc_to_dnflow(dir, pflags, &pd, r, s,
+                           &dnflow)) {
                                ip_dn_io_ptr(m0, &dnflow);

                                if (*m0 == NULL) {
This revision is now accepted and ready to land.Nov 3 2021, 12:44 PM