On 1/23/26 11:38 AM, Dumitru Ceara wrote: > Hi all, > > Thanks for the patch and discussion! I'll add my own opinion below. > > On 1/23/26 7:30 AM, Ales Musil wrote: >> On Thu, Jan 22, 2026 at 7:40 PM Mark Michelson <[email protected]> wrote: >> >>> In the commit title and description, "compliant" is misspelled as >>> "complaint". It is spelled correctly in the code, though. >>> >>> I have comments below, both regarding the code submission and to >>> respond to Ilya's remarks. >>> >>> On Thu, Jan 22, 2026 at 12:18 PM Ilya Maximets <[email protected]> wrote: >>>> >>>> On 1/22/26 3:27 PM, Ales Musil via dev wrote: >>>>> The RFC defines a Virtual Router Redundancy Protocol [0], in order >>>>> for that protocol to work the workload might "spoof" MAC address >>>>> within ARP or ND request/response. This wasn't allowed as the port >>>>> security is specifically designed against spoofing and checks if >>>>> the port security MAC address is the same for source of ARP/ND >>>>> and the inner source/target address. To make the port security >>>>> complaint add an option which when enabled will add extra flows >>>>> that match on the MAC address range specified by the RFC. >>>>> >>>>> [0] https://datatracker.ietf.org/doc/html/rfc5798 >>>>> Reported-at: https://issues.redhat.com/browse/FDP-2979 >>>>> Signed-off-by: Ales Musil <[email protected]> >>>>> --- >>>>> NEWS | 2 + >>>>> controller/lflow.c | 67 ++++++++++++++++++++ >>>>> ovn-nb.xml | 9 +++ >>>>> tests/ovn.at | 149 >>> +++++++++++++++++++++++++++++++++++++++++++++ >>>>> 4 files changed, 227 insertions(+) >>>>> >>>>> diff --git a/NEWS b/NEWS >>>>> index dc9d28f2c..e58f8ee1e 100644 >>>>> --- a/NEWS >>>>> +++ b/NEWS >>>>> @@ -87,6 +87,8 @@ Post v25.09.0 >>>>> other_config column. >>>>> - Introduce the capability to specify multiple ips for >>> ovn-evpn-local-ip >>>>> option. >>>>> + - Add an LSP option called "port-security-rfc5798-compliant", this >>>>> + allows VRRP v3 (RFC 5798) to work with port security enabled. >>>> >>>> Hi, Ales. >>>> >>>> This option name seems a bit misleading, as someone seeing it may assume >>>> that just enbaling it will allow the port to participate in VRRPv3. But >>>> it's not the case as port security will drop all the actual VRRP traffic, >>>> unless the virtual router mac address is also added to the port security, >>>> as all the actual VRRP packets with have this address as a source. As >>> per >>>> RFC itself: >>>> >>>> Note: VRRP packets are transmitted with the virtual router MAC >>>> address as the source MAC address to ensure that learning bridges >>>> correctly determine the LAN segment the virtual router is >>>> attached to. >>>> >>>> We should either add explicit indication that this option only affects >>>> ARP/ND packets, which would still be a bit confusing and will make the >>>> name even longer, or just have one knob like port-security-allow-vrrpv3 >>>> that also allows all the actual VRRP traffic, so users don't have to >>>> add all the possible router IDs into port security. This option may >>>> potentially accept a list of allowed router IDs or "yes" for all, but >>>> that can be added later if necessary. >>> >>> If this is the case, then does this mean that non-ARP and non-ND VRRP >>> traffic will still be dropped by port security flows when this option >>> is enabled? If so, then it seems like allowing the ARPs and NDs is >>> only getting rid of the surface issue. The ARPs/NDs will be allowed >>> through, but then other VRRP traffic will still be dropped. Is that >>> OK? It seems like we're going to immediately get a complaint about >>> this patch not actually fixing the problem if that's the case. I think >>> Ilya is on the right track by suggesting that we allow all VRRP >>> traffic with this option, not just the ARP/ND packets. >>> > > The bug report was about ARP replies not being allowed. VRRP ARP > replies for the virtual IP are special: > > https://datatracker.ietf.org/doc/html/rfc5798#section-8.1.2 > > When a host sends an ARP request for one of the virtual router IPv4 > addresses, the Virtual Router Master MUST respond to the ARP request > with an ARP response that indicates the virtual MAC address for the > virtual router. Note that the source address of the Ethernet frame > of this ARP response is the physical MAC address of the physical > router. > > The traffic the virtual router actually forwards, IP traffic, is sent > using the _virtual_ MAC as source, i.e., from 00-00-5E-00-01-{VRID} (for > IPv4). > > But as the RFC states, the ARP replies are sent from with eth.src == > _physical_ MAC of the VRRP member and arp.sha == 00-00-5E-00-01-{VRID}. > > Actual VRRP protocol packets are multicast and use the _physical_ MAC > address as source.
I suppose, you meant "virtual" here. See the note at the end of https://datatracker.ietf.org/doc/html/rfc5798#section-7.2 that I cited before. > > So, in order for ALL this to work, the CMS must _anyway_ configure two > MACs (physical and 00-00-5E-00-01-{VRID}) in the port_security field of > the LSP. That is true. But why not save users from extra configuration and just allow the new knob to allow both the ARP/ND and the VRRP and the routed traffic? AFAIU, anyone setting the option will always have to set the MACs in the port_security column as well. There is no point in setting the option and not adding virtual MAC to the port_security list as well. So I'm not sure why we're forcing users to do that when we already adding a special vrrp knob. > > The problem is that port security semantics in OVN are too strict and > don't allow the mismatch between physical MAC and inner VRRP MAC for > ARPs/ND. > > So the knob is _only_ about arp/nd VRRP RFC 5798 compliance, in my opinion. > >> >> It is specifically said in the documentation that this applies >> only to ARP/ND, the user is expected to configure all MACs they >> want to allow in port security as usual. We can change the name of >> the option to make it more explicit. Also the regular traffic doesn't >> have any issues if it's configured properly, this option is there for >> the only part that cannot be configured in any way now. >> > > Maybe "port-security-rfc5798-arp-nd-compliant"? It's long but it's > explicit enough. We could also do "port-security-vrrp-arp-nd-compliant" > I guess. > > Regards, > Dumitru > >> >>>> >>>> I didn't read too deep into the code, but see a few comments inline. >>>> >>>> Best rgeards, Ilya Maximets. >>>> >>>>> >>>>> OVN v25.09.0 - xxx xx xxxx >>>>> -------------------------- >>>>> diff --git a/controller/lflow.c b/controller/lflow.c >>>>> index b0998e605..93d9d090e 100644 >>>>> --- a/controller/lflow.c >>>>> +++ b/controller/lflow.c >>>>> @@ -2551,6 +2551,11 @@ build_in_port_sec_arp_flows(const struct >>> sbrec_port_binding *pb, >>>>> return; >>>>> } >>>>> >>>>> + bool vrrp_compliant = >>>>> + smap_get_bool(&pb->options, >>> "port-security-rfc5798-compliant", false); >>>>> + const struct eth_addr vrrp_mac = ETH_ADDR_C(00,00,5e,00,01,00); >>> >>> Nit: This and all the other const eth_addrs should be "static" as well. >>> >>>>> + const struct eth_addr vrrp_mask = ETH_ADDR_C(ff,ff,ff,ff,ff,00); >>>>> + >>>>> build_port_sec_allow_action(ofpacts); >>>>> >>>>> if (!ps_addr->n_ipv4_addrs) { >>>>> @@ -2561,6 +2566,9 @@ build_in_port_sec_arp_flows(const struct >>> sbrec_port_binding *pb, >>>>> * match - "inport == pb->port && eth.src == ps_addr.ea && >>>>> * arp && arp.sha == ps_addr.ea" >>>>> * action - "port_sec_failed = 0;" >>>>> + * If port security is configured to be VRRP (RFC5798) >>> compliant add >>>> >>>> Just the ARP flows do not make it RFC-compliant. >>>> >>>>> + * an extra flow to match on >>>>> + * arp.sha == 00:00:5e:00:01:00/ff:ff:ff:ff:ff:00 >>>>> */ >>>>> reset_match_for_port_sec_flows(pb, MFF_LOG_INPORT, m); >>>>> match_set_dl_src(m, ps_addr->ea); >>>>> @@ -2569,6 +2577,13 @@ build_in_port_sec_arp_flows(const struct >>> sbrec_port_binding *pb, >>>>> ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, 90, >>>>> pb->header_.uuid.parts[0], m, ofpacts, >>>>> &pb->header_.uuid); >>>>> + >>>>> + if (vrrp_compliant) { >>>>> + match_set_arp_sha_masked(m, vrrp_mac, vrrp_mask); >>>>> + ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, >>> 90, >>>>> + pb->header_.uuid.parts[0], m, ofpacts, >>>>> + &pb->header_.uuid); >>>>> + } >>>>> } >>>>> >>>>> /* Add the below logical flow equivalent OF rules in >>> 'in_port_sec_nd' >>>>> @@ -2577,6 +2592,9 @@ build_in_port_sec_arp_flows(const struct >>> sbrec_port_binding *pb, >>>>> * match - "inport == pb->port && eth.src == ps_addr.ea && >>>>> * arp && arp.sha == ps_addr.ea && arp.spa == >>> {ps_addr.ipv4_addrs}" >>>>> * action - "port_sec_failed = 0;" >>>>> + * If port security is configured to be VRRP (RFC5798) compliant >>> add >>>>> + * an extra flow to match on >>>>> + * arp.sha == 00:00:5e:00:01:00/ff:ff:ff:ff:ff:00 >>>>> */ >>>>> for (size_t j = 0; j < ps_addr->n_ipv4_addrs; j++) { >>>>> reset_match_for_port_sec_flows(pb, MFF_LOG_INPORT, m); >>>>> @@ -2594,6 +2612,13 @@ build_in_port_sec_arp_flows(const struct >>> sbrec_port_binding *pb, >>>>> ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, 90, >>>>> pb->header_.uuid.parts[0], m, ofpacts, >>>>> &pb->header_.uuid); >>>>> + >>>>> + if (vrrp_compliant) { >>>>> + match_set_arp_sha_masked(m, vrrp_mac, vrrp_mask); >>>>> + ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, >>> 90, >>>>> + pb->header_.uuid.parts[0], m, ofpacts, >>>>> + &pb->header_.uuid); >>>>> + } >>>>> } >>>>> } >>>>> >>>>> @@ -2701,6 +2726,11 @@ build_in_port_sec_nd_flows(const struct >>> sbrec_port_binding *pb, >>>>> struct match *m, struct ofpbuf *ofpacts, >>>>> struct ovn_desired_flow_table *flow_table) >>>>> { >>>>> + bool vrrp_compliant = >>>>> + smap_get_bool(&pb->options, >>> "port-security-rfc5798-compliant", false); >>>>> + const struct eth_addr vrrp_mac = ETH_ADDR_C(00,00,5e,00,02,00); >>>>> + const struct eth_addr vrrp_mask = ETH_ADDR_C(ff,ff,ff,ff,ff,00); >>>>> + >>>>> build_port_sec_allow_action(ofpacts); >>>>> >>>>> /* Add the below logical flow equivalent OF rules in >>> 'in_port_sec_nd' >>>>> @@ -2710,6 +2740,9 @@ build_in_port_sec_nd_flows(const struct >>> sbrec_port_binding *pb, >>>>> * icmp6 && icmp6.code == 135 && icmp6.type == 0 && >>>>> * ip6.tll == 255 && nd.sll == {00:00:00:00:00:00, >>> ps_addr.ea}" >>>>> * action - "port_sec_failed = 0;" >>>>> + * If port security is configured to be VRRP (RFC5798) compliant >>> add >>>>> + * an extra flow to match on >>>>> + * nd.sll == 00:00:5e:00:02:00/ff:ff:ff:ff:ff:00 >>>>> */ >>>>> reset_match_for_port_sec_flows(pb, MFF_LOG_INPORT, m); >>>>> match_set_dl_type(m, htons(ETH_TYPE_IPV6)); >>>>> @@ -2728,6 +2761,13 @@ build_in_port_sec_nd_flows(const struct >>> sbrec_port_binding *pb, >>>>> pb->header_.uuid.parts[0], m, ofpacts, >>>>> &pb->header_.uuid); >>>>> >>>>> + if (vrrp_compliant) { >>>>> + match_set_arp_sha_masked(m, vrrp_mac, vrrp_mask); >>>>> + ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, 90, >>>>> + pb->header_.uuid.parts[0], m, ofpacts, >>>>> + &pb->header_.uuid); >>>>> + } >>>>> + >>>>> match_set_icmp_type(m, 136); >>>>> match_set_icmp_code(m, 0); >>>>> if (ps_addr->n_ipv6_addrs) { >>>>> @@ -2739,6 +2779,9 @@ build_in_port_sec_nd_flows(const struct >>> sbrec_port_binding *pb, >>>>> * nd.tll == {00:00:00:00:00:00, ps_addr.ea} && >>>>> * nd.target == {ps_addr.ipv6_addrs, lla}" >>>>> * action - "port_sec_failed = 0;" >>>>> + * If port security is configured to be VRRP (RFC5798) >>> compliant add >>>>> + * an extra flow to match on >>>>> + * nd.tll == 00:00:5e:00:02:00/ff:ff:ff:ff:ff:00 >>>>> */ >>>>> struct in6_addr lla; >>>>> in6_generate_lla(ps_addr->ea, &lla); >>>>> @@ -2754,6 +2797,13 @@ build_in_port_sec_nd_flows(const struct >>> sbrec_port_binding *pb, >>>>> pb->header_.uuid.parts[0], m, ofpacts, >>>>> &pb->header_.uuid); >>>>> >>>>> + if (vrrp_compliant) { >>>>> + match_set_arp_tha_masked(m, vrrp_mac, vrrp_mask); >>>>> + ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, >>> 90, >>>>> + pb->header_.uuid.parts[0], m, ofpacts, >>>>> + &pb->header_.uuid); >>>>> + } >>>>> + >>>>> for (size_t j = 0; j < ps_addr->n_ipv6_addrs; j++) { >>>>> reset_match_for_port_sec_flows(pb, MFF_LOG_INPORT, m); >>>>> match_set_dl_src(m, ps_addr->ea); >>>>> @@ -2781,6 +2831,13 @@ build_in_port_sec_nd_flows(const struct >>> sbrec_port_binding *pb, >>>>> ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, >>> 90, >>>>> pb->header_.uuid.parts[0], m, ofpacts, >>>>> &pb->header_.uuid); >>>>> + >>>>> + if (vrrp_compliant) { >>>>> + match_set_arp_tha_masked(m, vrrp_mac, vrrp_mask); >>>>> + ofctrl_add_flow(flow_table, >>> OFTABLE_CHK_IN_PORT_SEC_ND, 90, >>>>> + pb->header_.uuid.parts[0], m, ofpacts, >>>>> + &pb->header_.uuid); >>>>> + } >>>>> } >>>>> } else { >>>>> /* Add the below logical flow equivalent OF rules in >>> 'in_port_sec_nd' >>>>> @@ -2790,6 +2847,9 @@ build_in_port_sec_nd_flows(const struct >>> sbrec_port_binding *pb, >>>>> * icmp6.code == 136 && icmp6.type == 0 && ip6.tll >>> == 255 && >>>>> * nd.tll == {00:00:00:00:00:00, ps_addr.ea}" >>>>> * action - "port_sec_failed = 0;" >>>>> + * If port security is configured to be VRRP (RFC5798) >>> compliant add >>>>> + * extra an flow to match on >>>>> + * nd.tll == 00:00:5e:00:02:00/ff:ff:ff:ff:ff:00 >>>>> */ >>>>> match_set_arp_tha(m, eth_addr_zero); >>>>> ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, 90, >>>>> @@ -2800,6 +2860,13 @@ build_in_port_sec_nd_flows(const struct >>> sbrec_port_binding *pb, >>>>> ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, 90, >>>>> pb->header_.uuid.parts[0], m, ofpacts, >>>>> &pb->header_.uuid); >>>>> + >>>>> + if (vrrp_compliant) { >>>>> + match_set_arp_tha_masked(m, vrrp_mac, vrrp_mask); >>>>> + ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, >>> 90, >>>>> + pb->header_.uuid.parts[0], m, ofpacts, >>>>> + &pb->header_.uuid); >>>>> + } >>>>> } >>>>> } >>>>> >>>>> diff --git a/ovn-nb.xml b/ovn-nb.xml >>>>> index e74c0d010..4e95a13b6 100644 >>>>> --- a/ovn-nb.xml >>>>> +++ b/ovn-nb.xml >>>>> @@ -1674,6 +1674,15 @@ >>>>> <ref table="Interface" db="vswitch"/> table. This in >>> turn will >>>>> make OVS vswitchd update the MTU of the linked interface. >>>>> </column> >>>>> + >>>>> + <column name="options" key="port-security-rfc5798-compliant" >>>>> + type='{"type": "boolean"}'> >>>>> + Allows the inner ARP SHA or ND TLL/SLL to be within the >>> range of >>>>> + MAC addresses specified by RFC 5798. The result is a >>> masked match >>>>> + that allows the whole range of MAC addresses to pass >>> through. >>>>> + This option is only applicable if <ref >>> column="port_security"/> >>>>> + is populated. >>>>> + </column> >>>>> </group> >>>>> </group> >>>>> >>>>> diff --git a/tests/ovn.at b/tests/ovn.at >>>>> index d5ee90e17..4455b7580 100644 >>>>> --- a/tests/ovn.at >>>>> +++ b/tests/ovn.at >>>>> @@ -44181,3 +44181,152 @@ check ovn-nbctl --wait=hv lsp-set-type >>> down_ext localnet >>>>> OVN_CLEANUP([hv1],[hv2]) >>>>> AT_CLEANUP >>>>> ]) >>>>> + >>>>> +OVN_FOR_EACH_NORTHD([ >>>>> +AT_SETUP([Port security - RFC 5798]) >>>>> +AT_SKIP_IF([test $HAVE_SCAPY = no]) >>>>> +ovn_start >>>>> +net_add n1 >>>>> +sim_add hv1 >>>>> +as hv1 >>>>> +ovs-vsctl add-br br-phys >>>> >>>> check >>>> >>>>> +ovn_attach n1 br-phys 192.168.0.1 >>>>> + >>>>> +check ovn-nbctl ls-add ls >>>>> + >>>>> +check ovn-nbctl lsp-add ls lsp1 >>>>> +check ovn-nbctl lsp-set-addresses lsp1 "00:00:00:00:10:01 >>> 192.168.10.1 fd10::1" >>>>> + >>>>> +check ovn-nbctl lsp-add ls lsp2 >>>>> +check ovn-nbctl lsp-set-addresses lsp2 "00:00:00:00:10:02 >>> 192.168.10.2 fd10::2" >>>>> + >>>>> +check ovs-vsctl -- add-port br-int vif1 -- \ >>>>> + set interface vif1 external-ids:iface-id=lsp1 \ >>>>> + options:tx_pcap=hv1/vif1-tx.pcap \ >>>>> + options:rxq_pcap=hv1/vif1-rx.pcap >>>>> + >>>>> +check ovs-vsctl -- add-port br-int vif2 -- \ >>>>> + set interface vif2 external-ids:iface-id=lsp2 \ >>>>> + options:tx_pcap=hv1/vif2-tx.pcap \ >>>>> + options:rxq_pcap=hv1/vif2-rx.pcap >>>>> + >>>>> +wait_for_ports_up >>>>> + >>>>> +test_arp() { >>>>> + local dropped=$1 >>>>> + >>>>> + packet=$(fmt_pkt " >>>>> + Ether(dst='ff:ff:ff:ff:ff:ff', src='00:00:00:00:10:01') / >>>>> + ARP(op=1, hwsrc='00:00:5e:00:01:05', >>> hwdst='ff:ff:ff:ff:ff:ff', psrc='192.168.10.1', pdst='192.168.10.2') >>>>> + ") >>>>> + as hv1 ovs-appctl netdev-dummy/receive vif1 $packet >>>> >>>> Need to check that this actually worked. >>>> >>>>> + >>>>> + packet=$(fmt_pkt " >>>>> + Ether(dst='ff:ff:ff:ff:ff:ff', src='00:00:00:00:10:01') / >>>>> + ARP(op=2, hwsrc='00:00:5e:00:01:05', >>> hwdst='ff:ff:ff:ff:ff:ff', psrc='192.168.10.1', pdst='192.168.10.1') >>>>> + ") >>>> >>>> Indentation is different here for some reason. >>>> >>>>> + as hv1 ovs-appctl netdev-dummy/receive vif1 $packet >>>> >>>> check >>>> >>>>> + >>>>> + if [[ "$dropped" != "yes" ]]; then >>>>> + echo $packet >> vif2.expected >>>> >>>> Why are we sending two packets, but expecting only the second one? >>> >>> The first ARP has pdst not equal to lsp1's IP address, so it's >>> expected to be dropped by port security, even if VRRP compliance is >>> enabled. It's a control to ensure that a packet that should always be >>> dropped is not slipping through when VRRP compliance is enabled. The >>> second ARP has pdst equal to lsp1's IP address, so it is expected to >>> be dropped only if VRRP compliance is disabled. >>> >> >> We are sending ARP and gARP, ARP will be replied by LS lflows >> so it will never arrive to the second port, gARP will go through >> that's why we expected one packet for each port. One ARP reply >> and second gARP. The same happens with ND packets. >> >> >>> >>>> >>>>> + packet=$(fmt_pkt " >>>>> + Ether(dst='00:00:00:00:10:01', src='00:00:00:00:10:02') / >>>>> + ARP(op=2, hwsrc='00:00:00:00:10:02', >>> hwdst='00:00:5e:00:01:05', psrc='192.168.10.2', pdst='192.168.10.1') >>>>> + ") >>>>> + echo $packet >> vif1.expected >>>>> + fi >>>>> +} >>>>> +test_nd() { >>>>> + local dropped=$1 >>>>> + >>>>> + packet=$(fmt_pkt " >>>>> + Ether(dst='33:33:ff:ff:ff:ff', src='00:00:00:00:10:01') / >>>> >>>> This is not a correct IPv6 multicast address. >>>> >>>>> + IPv6(src='fd10::1', dst='ff02::1:ff00:2') / >>>>> + ICMPv6ND_NS(tgt='fd10::2') / >>>>> + ICMPv6NDOptSrcLLAddr(lladdr='00:00:5e:00:02:05') >>>>> + ") >>>>> + as hv1 ovs-appctl netdev-dummy/receive vif1 $packet >>>> >>>> check >>>> >>>>> + >>>>> + packet=$(fmt_pkt " >>>>> + Ether(dst='ff:ff:ff:ff:ff:ff', src='00:00:00:00:10:01') / >>>> >>>> Address. >>>> >>>>> + IPv6(src='fd10::1', dst='ff01::1') / >>>>> + ICMPv6ND_NA(tgt='fd10::1') / >>>>> + ICMPv6NDOptDstLLAddr(lladdr='00:00:5e:00:02:05') >>>>> + ") >>>>> + as hv1 ovs-appctl netdev-dummy/receive vif1 $packet >>>> >>>> check >>>> >>>>> + >>>>> + if [[ "$dropped" != "yes" ]]; then >>>>> + echo $packet >> vif2.expected >>>>> + >>>>> + packet=$(fmt_pkt " >>>>> + Ether(dst='00:00:00:00:10:01', >>> src='00:00:00:00:10:02') / >>>>> + IPv6(src='fd10::2', dst='fd10::1') / >>>>> + ICMPv6ND_NA(tgt='fd10::2', R=0, S=1, O=1) / >>>>> + ICMPv6NDOptDstLLAddr(lladdr='00:00:00:00:10:02') >>>>> + ") >>>>> + echo $packet >> vif1.expected >>>>> + fi >>>>> +} >>>>> + >>>>> +reset_pcap_and_expected() { >>>>> + reset_pcap_file vif1 hv1/vif1 >>>>> + reset_pcap_file vif2 hv1/vif2 >>>>> + >>>>> + : > vif1.expected >>>>> + : > vif2.expected >>>>> +} >>>>> + >>>>> +AS_BOX([Without port security]) >>>>> +reset_pcap_and_expected >>>>> + >>>>> +test_arp no >>>>> +test_nd no >>>>> + >>>>> +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected]) >>>>> +OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [vif2.expected]) >>>>> + >>>>> +AS_BOX([With MAC only port security]) >>>>> +reset_pcap_and_expected >>>>> +check ovn-nbctl --wait=hv lsp-set-port-security lsp1 >>> "00:00:00:00:10:01" >>>>> + >>>>> +test_arp yes >>>>> +test_nd yes >>>>> + >>>>> +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected]) >>>>> +OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [vif2.expected]) >>>>> + >>>>> +AS_BOX([With MAC + IP port security]) >>>>> +reset_pcap_and_expected >>>>> +check ovn-nbctl --wait=hv lsp-set-port-security lsp1 >>> "00:00:00:00:10:01 192.168.10.1 fd10::1" >>>>> + >>>>> +test_arp yes >>>>> +test_nd yes >>>>> + >>>>> +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected]) >>>>> +OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [vif2.expected]) >>>>> + >>>>> +AS_BOX([With MAC only port security, compatibility enabled]) >>>>> +reset_pcap_and_expected >>>>> +check ovn-nbctl lsp-set-options lsp1 >>> port-security-rfc5798-compliant=true >>>>> +check ovn-nbctl --wait=hv lsp-set-port-security lsp1 >>> "00:00:00:00:10:01" >>>>> + >>>>> +test_arp no >>>>> +test_nd no >>>>> + >>>>> +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected]) >>>>> +OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [vif2.expected]) >>>>> + >>>>> +AS_BOX([With MAC + IP port security, compatibility enabled]) >>>>> +reset_pcap_and_expected >>>>> +check ovn-nbctl --wait=hv lsp-set-port-security lsp1 >>> "00:00:00:00:10:01 192.168.10.1 fd10::1" >>>>> + >>>>> +test_arp no >>>>> +test_nd no >>>>> + >>>>> +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected]) >>>>> +OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [vif2.expected]) >>>>> + >>>>> +OVN_CLEANUP([hv1]) >>>>> + >>>>> +AT_CLEANUP >>>>> +]) >>>> >>>> _______________________________________________ >>>> dev mailing list >>>> [email protected] >>>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev >>>> >>> >>> >> > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
