Flow of broadcast/multicast packets in pf when a bridge is present

Andreas Longwitz longwitz at incore.de
Mon Dec 23 16:43:23 UTC 2019


On a server with a bridge running FreeBSD 12.1-STABLE r354175 I try to
understand the flow of broadcast/multicast packets in pf.

The bridge interface is defined with
  ifconfig_bridge0="inet 192.168.0.125/24 addm em0 addm em1 up,
further I use
  net.link.bridge.inherit_mac=1,
the other net.link.bridge sysctls are default.

For an incoming broadcast packet on em0 I would expect that pf_test() is
called with dir=PF_IN two times: for if=em0 and for if=bridge0. Indeed
this happens:

  ether_input --> bridge_input --> bridge_forward --> bridge_pfil

and bridge_pfil calls pfil_run_hooks first for em0 and second for
bridge0. This is not done with the original packet but a clone (mbuf mc)
created by bridge_input before bridge_forward is called. Next
bridge_input does reinject another copy of the original packet truncated
to length max_protohdr to the bridge:

  /*
   * Reinject the mbuf as arriving on the bridge so we have a
   * chance at claiming multicast packets. We can not loop back
   * here from ether_input as a bridge is never a member of a
   * bridge.
   */
   KASSERT(bifp->if_bridge == NULL,
      ("loop created in bridge_input"));
   mc2 = m_dup(m, M_NOWAIT);
   if (mc2 != NULL) {
      /* Keep the layer3 header aligned */
      int i = min(mc2->m_pkthdr.len, max_protohdr);
      mc2 = m_copyup(mc2, i, ETHER_ALIGN);
   }
   if (mc2 != NULL) {
      mc2->m_pkthdr.rcvif = bifp;
      (*bifp->if_input)(bifp, mc2);
   }

This coding was committed in rev 150099, 150551 and 153622. pf_test()
sees and counts this shortened packet for if=bridge0 and I really do not
understand the reason why this reinject is done.

At last pf_test() is called once more (for if=em0) when bridge_input
finishes with

 /* Return the original packet for local processing. */
 return (m);

This time pf_test() sees the original packet on if=em0, but I do not see
a way in the pf rules to distinguish this packet from the packet pf has
seen first.


Andreas


More information about the freebsd-pf mailing list