AT_BANNER([mcast snooping]) AT_SETUP([mcast - check multicasts to trunk ports are not duplicated]) OVS_VSWITCHD_START([]) AT_CHECK([ ovs-vsctl set bridge br0 \ datapath_type=dummy \ mcast_snooping_enable=true \ other-config:mcast-snooping-disable-flood-unregistered=true ], [0]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) # Create an access port p1 on vlan 1725, and a trunk port p2. AT_CHECK([ ovs-vsctl add-port br0 p1 tag=1725 -- set Interface p1 type=dummy \ other-config:hwaddr=aa:55:aa:55:00:01 ofport_request=1 \ -- add-port br0 p2 -- set Interface p2 type=dummy \ other-config:hwaddr=aa:55:aa:55:00:02 ofport_request=2 ], [0]) AT_CHECK([ovs-appctl dpif/show], [0], [dnl dummy@ovs-dummy: hit:0 missed:0 br0: br0 65534/100: (dummy-internal) p1 1/1: (dummy) p2 2/2: (dummy) ]) ovs-appctl time/stop # Send IGMPv3 query on p2 with vlan 1725 # 5c:8a:38:55:25:52 > 01:00:5e:00:00:01, ethertype 802.1Q (0x8100), length 64: vlan 1725, p 0, ethertype IPv4, # 172.17.25.1 > 224.0.0.1: igmp query v3 AT_CHECK([ovs-appctl netdev-dummy/receive p2 \ '01005e0000015c8a38552552810006bd080046c000240000000001027f00ac111901e0000001940400001164ec1e00000000027d000000000000000000000000']) # Send IGMPv3 query on p2 with vlan 1728 # 5c:8a:38:55:25:52 > 01:00:5e:00:00:01, ethertype 802.1Q (0x8100), length 64: vlan 1728, p 0, ethertype IPv4, # 172.17.28.1 > 224.0.0.1: igmp query v3 AT_CHECK([ovs-appctl netdev-dummy/receive p2 \ '01005e0000015c8a38552552810006c0080046c000240000000001027c00ac111c01e0000001940400001164ec1e00000000027d000000000000000000000000']) AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl port VLAN GROUP Age 2 1725 querier 0 2 1728 querier 0 ]) AT_CHECK([ovs-vsctl set Interface p2 options:tx_pcap=p2.pcap]) # Send a multicast packet on p1 AT_CHECK([ ovs-appctl netdev-dummy/receive p1 \ 'in_port(1),eth(src=aa:55:aa:55:00:01,dst=01:00:5e:5e:01:01),eth_type(0x0800),ipv4(src=10.0.0.1,dst=239.94.1.1,proto=17,tos=0,ttl=64,frag=no),udp(src=0,dst=8000)' ]) # Check this packet was forwarded exactly once to p2 and has vlan tag 1725 # aa:55:aa:55:00:01 > 01:00:5e:5e:01:01, ethertype 802.1Q (0x8100), length 46: vlan 1725, p 0, ethertype IPv4, # 10.0.0.1.0 > 239.94.1.1.8000: UDP, length 0 AT_CHECK([ovs-pcap p2.pcap > p2.pcap.txt 2>&1]) AT_CHECK([cat p2.pcap.txt], [0], [dnl 01005e5e0101aa55aa550001810006bd08004500005c00000000401180310a000001ef5e010100001f40004801ba000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f ]) # Clear the mdb, send a IGMP packet with invalid checksum and make sure it # does not end up in the mdb. AT_CHECK([ovs-appctl mdb/flush br0], [0], [dnl table successfully flushed ]) AT_CHECK([ovs-appctl netdev-dummy/receive p2 \ '01005e0000015c8a38552552810006bd080046c000240000000001027f00ac111901e0000001940400001164ec1000000000027d000000000000000000000000']) AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl port VLAN GROUP Age ]) # First send a valid packet to make sure it populates the mdb. Than Clear # the mdb, send a MLD packet with invalid checksum and make sure it does # not end up in the mdb. AT_CHECK([ovs-appctl netdev-dummy/receive p2 \ '3333ff0e4c67000c290e4c6786dd600000000020000100000000000000000000000000000000ff0200000000000000000001ff0e4c673a000502000001008300e7b800000000ff0200000000000000000001ff0e4c67']) AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl port VLAN GROUP Age 2 0 ff02::1:ff0e:4c67 0 ]) AT_CHECK([ovs-appctl mdb/flush br0], [0], [dnl table successfully flushed ]) AT_CHECK([ovs-appctl netdev-dummy/receive p2 \ '3333ff0e4c67000c290e4c6786dd600000000020000100000000000000000000000000000000ff0200000000000000000001ff0e4c673a000502000001008300e7b000000000ff0200000000000000000001ff0e4c67']) AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl port VLAN GROUP Age ]) OVS_VSWITCHD_STOP AT_CLEANUP AT_SETUP([mcast - delete the port mdb when vlan configuration changed]) OVS_VSWITCHD_START([]) AT_CHECK([ ovs-vsctl set bridge br0 \ datapath_type=dummy \ mcast_snooping_enable=true \ other-config:mcast-snooping-disable-flood-unregistered=false ], [0]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) AT_CHECK([ ovs-vsctl add-port br0 p1 -- set Interface p1 type=dummy \ other-config:hwaddr=aa:55:aa:55:00:01 ofport_request=1 \ -- add-port br0 p2 \ -- set Interface p2 type=dummy other-config:hwaddr=aa:55:aa:55:00:02 ofport_request=2 \ -- add-port br0 p3 \ -- set Interface p3 type=dummy other-config:hwaddr=aa:55:aa:55:00:03 ofport_request=3 ], [0]) ovs-appctl time/stop # send report packets AT_CHECK([ ovs-appctl netdev-dummy/receive p1 \ '01005E010101000C29A027A18100000108004500001C000100004002CBAEAC10221EE001010112140CE9E0010101' ovs-appctl netdev-dummy/receive p1 \ '01005E010101000C29A027A28100000208004500001C000100004002CBAEAC10221EE001010112140CE9E0010101' ], [0]) # send query packets AT_CHECK([ ovs-appctl netdev-dummy/receive p3 \ '01005E010101000C29A027D18100000108004500001C000100004002CBCBAC102201E00101011114EEEB00000000' ovs-appctl netdev-dummy/receive p3 \ '01005E010101000C29A027D28100000208004500001C000100004002CBCAAC102202E00101011114EEEB00000000' ], [0]) AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl port VLAN GROUP Age 1 1 224.1.1.1 0 1 2 224.1.1.1 0 3 1 querier 0 3 2 querier 0 ]) AT_CHECK([ovs-vsctl set port p3 tag=2], [0]) AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl port VLAN GROUP Age 1 1 224.1.1.1 0 1 2 224.1.1.1 0 ]) AT_CLEANUP AT_SETUP([mcast - delete the port mdb when port destroyed]) OVS_VSWITCHD_START([]) AT_CHECK([ ovs-vsctl set bridge br0 \ datapath_type=dummy \ mcast_snooping_enable=true \ other-config:mcast-snooping-disable-flood-unregistered=false ], [0]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) AT_CHECK([ ovs-vsctl add-port br0 p1 -- set Interface p1 type=dummy \ other-config:hwaddr=aa:55:aa:55:00:01 ofport_request=1 \ -- add-port br0 p2 \ -- set Interface p2 type=dummy other-config:hwaddr=aa:55:aa:55:00:02 ofport_request=2 \ ], [0]) ovs-appctl time/stop # send report packets AT_CHECK([ ovs-appctl netdev-dummy/receive p1 \ '01005E010101000C29A027A18100000108004500001C000100004002CBAEAC10221EE001010112140CE9E0010101' ovs-appctl netdev-dummy/receive p1 \ '01005E010101000C29A027A28100000208004500001C000100004002CBAEAC10221EE001010112140CE9E0010101' ], [0]) # send query packets AT_CHECK([ ovs-appctl netdev-dummy/receive p2 \ '01005E010101000C29A027D18100000108004500001C000100004002CBCBAC102201E00101011114EEEB00000000' ovs-appctl netdev-dummy/receive p2 \ '01005E010101000C29A027D28100000208004500001C000100004002CBCAAC102202E00101011114EEEB00000000' ], [0]) AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl port VLAN GROUP Age 1 1 224.1.1.1 0 1 2 224.1.1.1 0 2 1 querier 0 2 2 querier 0 ]) AT_CHECK([ovs-vsctl del-port br0 p2], [0]) AT_CHECK([ovs-appctl mdb/show br0], [0], [dnl port VLAN GROUP Age 1 1 224.1.1.1 0 1 2 224.1.1.1 0 ]) AT_CLEANUP AT_SETUP([mcast - igmp flood for non-snoop enabled]) OVS_VSWITCHD_START([]) AT_CHECK([ ovs-vsctl set bridge br0 \ datapath_type=dummy], [0]) add_of_ports br0 1 2 AT_CHECK([ovs-ofctl add-flow br0 action=normal]) ovs-appctl time/stop dnl Basic scenario - needs to flood for IGMP followed by unicast ICMP dnl in reverse direction AT_CHECK([ovs-appctl netdev-dummy/receive p1 \ '0101000c29a0aa55aa550001080046c00028000040000102d3494565eb4ae0000016940400002200f9020000000104000000e00000fb000000000000']) AT_CHECK([ovs-appctl netdev-dummy/receive p2 \ 'aa55aa5500010101000c29a008004500001c00010000400164dc0a0101010a0101020800f7ffffffffff']) AT_CHECK([ovs-appctl dpctl/dump-flows | grep -e .*ipv4 | sort | dnl strip_stats | strip_used | strip_recirc | dnl sed -e 's/,packet_type(ns=[[0-9]]*,id=[[0-9]]*),/,/'], [0], [dnl recirc_id(),in_port(1),eth(src=aa:55:aa:55:00:01,dst=01:01:00:0c:29:a0),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions:100,2 recirc_id(),in_port(2),eth(src=01:01:00:0c:29:a0,dst=aa:55:aa:55:00:01),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions:1 ]) ovs-appctl time/warp 100000 dnl Next we should clear the flows and install a complex case AT_CHECK([ovs-ofctl del-flows br0]) AT_DATA([flows.txt], [dnl table=0, arp actions=NORMAL table=0, ip,in_port=1 actions=ct(table=1,zone=64000) table=0, in_port=2 actions=output:1 table=1, ip,ct_state=+trk+inv actions=drop table=1 ip,in_port=1,icmp,ct_state=+trk+new actions=output:2 table=1, in_port=1,ip,ct_state=+trk+new actions=controller(userdata=00.de.ad.be.ef.ca.fe.01) table=1, in_port=1,ip,ct_state=+trk+est actions=output:2 ]) AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) ovs-appctl time/warp 100000 dnl Send the IGMP, followed by a unicast ICMP - ensure we won't black hole AT_CHECK([ovs-appctl netdev-dummy/receive p1 \ '0101000c29a0aa55aa550001080046c00028000040000102d3494565eb4ae0000016940400002200f9020000000104000000e00000fb000000000000']) AT_CHECK([ovs-appctl netdev-dummy/receive p1 \ 'aa55aa550001aa55aa55000208004500001c00010000400164dc0a0101010a0101020800f7ffffffffff']) AT_CHECK([ovs-appctl dpctl/dump-flows | grep -e .*ipv4 | sort | dnl strip_stats | strip_used | strip_recirc | dnl sed 's/pid=[[0-9]]*,// s/,packet_type(ns=[[0-9]]*,id=[[0-9]]*),/,/'], [0], [dnl recirc_id(),in_port(1),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:0.0s, actions:ct(zone=64000),recirc() recirc_id(),in_port(1),ct_state(+new-inv+trk),eth_type(0x0800),ipv4(proto=1,frag=no), packets:0, bytes:0, used:never, actions:2 recirc_id(),in_port(1),ct_state(+new-inv+trk),eth_type(0x0800),ipv4(proto=2,frag=no), packets:0, bytes:0, used:never, actions:userspace(controller(reason=1,dont_send=0,continuation=0,recirc_id=,rule_cookie=0,controller_id=0,max_len=65535)) ]) AT_CLEANUP