ovn-org/ovn

Why the flow is needed for unknown mac addresses to send to the MC_UNKNOWN multicast group?

amkgi opened this issue · 4 comments

I've noticed the following behavior and I don't understand why it's needed?

[root@vim-ctr01 /]# ovn-trace --detail non_fdp 'inport == "07188e76-5372-41a7-9e71-0c3ab0ad42c6" && eth.src == fa:16:3e:39:d5:97 && eth.dst == 00:4c:73:00:dc:01 && ip4.src == 10.162.21.199 && ip4.dst == 8.8.8.8 && icmp'
# icmp,reg14=0x8,vlan_tci=0x0000,dl_src=fa:16:3e:39:d5:97,dl_dst=00:4c:73:00:dc:01,nw_src=10.162.21.199,nw_dst=8.8.8.8,nw_tos=0,nw_ecn=0,nw_ttl=0,icmp_type=0,icmp_code=0

ingress(dp="non_fdp", inport="07188e")
--------------------------------------
 0. ls_in_port_sec_l2 (northd.c:5597): inport == "07188e", priority 50, uuid 3be76b41
    next;
 3. ls_in_lookup_fdb (northd.c:5634): inport == "07188e", priority 100, uuid 38ca796d
    reg0[11] = lookup_fdb(inport, eth.src);
    /* MAC lookup for 00:4c:73:00:dc:01 found in FDB. */
    next;
24. ls_in_l2_lkup (northd.c:7729): 1, priority 0, uuid 2605e46f
    outport = get_fdb(eth.dst);
    next;
25. ls_in_l2_unknown (northd.c:7734): outport == "none", priority 50, uuid 59522b5d
    outport = "_MC_unknown";
    output;

multicast(dp="non_fdp", mcgroup="_MC_unknown")
----------------------------------------------

    egress(dp="non_fdp", inport="07188e", outport="RTR3-1-port-128")
    ----------------------------------------------------------------
         9. ls_out_port_sec_l2 (northd.c:5695): outport == "RTR3-1-port-128", priority 50, uuid f594fabf
            output;
            /* output to "RTR3-1-port-128", type "" */

    egress(dp="non_fdp", inport="07188e", outport="07188e")
    -------------------------------------------------------
            /* omitting output because inport == outport && !flags.loopback */

    egress(dp="non_fdp", inport="07188e", outport="3b461e")
    -------------------------------------------------------
         9. ls_out_port_sec_l2 (northd.c:5695): outport == "3b461e", priority 50, uuid e07ada58
            output;
            /* output to "3b461e", type "" */

    egress(dp="non_fdp", inport="07188e", outport="877021")
    -------------------------------------------------------
         9. ls_out_port_sec_l2 (northd.c:5695): outport == "877021", priority 50, uuid 385660ff
            output;
            /* output to "877021", type "" */

    egress(dp="non_fdp", inport="07188e", outport="RTR2-1-port-128")
    ----------------------------------------------------------------
         9. ls_out_port_sec_l2 (northd.c:5695): outport == "RTR2-1-port-128", priority 50, uuid 2403208c
            output;
            /* output to "RTR2-1-port-128", type "" */

    egress(dp="non_fdp", inport="07188e", outport="fb8c3a")
    -------------------------------------------------------
         9. ls_out_port_sec_l2 (northd.c:5695): outport == "fb8c3a", priority 50, uuid 4e46aa31
            output;
            /* output to "fb8c3a", type "" */

    egress(dp="non_fdp", inport="07188e", outport="provnet-40617a")
    ---------------------------------------------------------------
         0. ls_out_pre_lb (northd.c:5747): ip && outport == "provnet-40617a", priority 110, uuid c7c458d2
            next;
         9. ls_out_port_sec_l2 (northd.c:5695): outport == "provnet-40617a", priority 50, uuid b114fda3
            output;
            /* output to "provnet-40617a", type "localnet" */

As a result, all VMs on the same hypervisor will receive packets sent from a particular VM if port security is disabled on those VMs.

I had thought that this commit must have had an effect on such flooding, but upon further examining the code, I realized that this behavior is set in all versions of OVN.

Additional info:

ovn-nbctl 21.12.3
Open vSwitch Library 2.17.3
DB Schema 5.35.1

I found in the man pages of ovn-northd:

     Ingress Table 25 Destination unknown

       This table handles the packets whose destination was not found or and looked up in the MAC learning table of the logical switch datapath. It contains the following flows.

              ·      If the logical switch has logical ports with ’unknown’ addresses set, then the below logical flow is added

                     ·      Priority 50 flow with the match outport == none then outputs them to the MC_UNKNOWN multicast group, which ovn-northd populates with all enabled logical ports that  accept  unknown
                            destination packets. As a small optimization, if no logical ports accept unknown destination packets, ovn-northd omits this multicast group and logical flow.

                     If the logical switch has no logical ports with ’unknown’ address set, then the below logical flow is added

                     ·      Priority 50 flow with the match outport == none and drops the packets.

              ·      One priority-0 fallback flow that outputs the packet to the egress stage with the outport learnt from get_fdb action.

But that doesn't provide a reply as to why it's needed.

If you see the man page of ovn-nb [1] in the addresses column of Logical_Switch_Port table, you'd see the below

unknown
                     This indicates that the logical port has an  unknown  set
                     of   Ethernet  addresses.  When  an  OVN  logical  switch
                     processes a unicast Ethernet frame whose destination  MAC
                     address is not in any logical port’s addresses column, it
                     delivers  it  to  the  port  (or  ports)  whose addresses
                     columns include unknown.

So if OVN doesn't know who own the destination mac address of a packet, it floods/forwards it to all the logical ports in that logical switch configured with "unknown" as their address.

Hope it helps.

[1] - https://github.com/ovn-org/ovn/blob/main/ovn-nb.xml#L1521
https://www.ovn.org/support/dist-docs/ovn-nb.5.html

@numansiddique

Is the addresses column set to unknown so that this port can send traffic from itself with different MAC addresses and IP addresses?

@amkgi That is correct. In the case of openstack, if a neutron port has port security disabled, then neutron ovn driver sets the addresses to "unknown" for the corresponding logical port.