On 2/3/26 8:34 AM, 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
> compliant add an special literal which when specified will allow
> user to add any/all MAC addresses defined by VRRPv3. The traffic
> from and to those additional MAC addresses will be allowed as
> well as permutations of ARP/ND inner MACs combined with the
> physical MAC as a source.
> 
> [0] https://datatracker.ietf.org/doc/html/rfc9568
> Reported-at: https://issues.redhat.com/browse/FDP-2979
> Signed-off-by: Ales Musil <[email protected]>
> Acked-by: Jacob Tanenbaum <[email protected]>
> ---
> v2: Rebase on top of latest main.
>     Update the RFC url.
>     Add Jacob's ack.

Hi Ales,

Thanks for the patch!  It seems correct to me, I just had some minor
findings below.

I'm fine if you address them while merging the patch if there are no
further comments.  It would be nice to also hear Ilya's opinion first
though as he was part of the discussions on the previous versions.

If nothing else needs to change feel free to add my ack after fixing up
the small issues I flagged below.

Acked-by: Dumitru Ceara <[email protected]>

> ---
>  NEWS               |   3 +
>  controller/lflow.c | 823 ++++++++++++++++++++++++++++-----------------
>  ovn-nb.xml         |  33 ++
>  tests/ovn.at       | 751 +++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 1302 insertions(+), 308 deletions(-)
> 
> diff --git a/NEWS b/NEWS
> index b7268c835..5276f2c29 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -93,6 +93,9 @@ Post v25.09.0
>       other_config column.
>     - Introduce the capability to specify multiple ips for ovn-evpn-local-ip
>       option.
> +   - Add support for special port_security prefix "VRRPv3". This prefix 
> allows
> +     CMS to specify one physical MAC and multiple VRRPv3 MAC addresses.
> +     The VRRPv3 MAC also accepts masked format.
>  
>  OVN v25.09.0 - xxx xx xxxx
>  --------------------------
> diff --git a/controller/lflow.c b/controller/lflow.c
> index 94fd8807c..6b87727b5 100644
> --- a/controller/lflow.c
> +++ b/controller/lflow.c
> @@ -2340,6 +2340,125 @@ add_port_sec_flows(const struct shash *binding_lports,
>      }
>  }
>  
> +struct masked_ip4_addr {
> +    ovs_be32 addr;
> +    ovs_be32 mask;
> +    ovs_be32 bcast;
> +};
> +
> +struct masked_ip6_addr {
> +    struct in6_addr addr;
> +    struct in6_addr mask;
> +};
> +
> +struct masked_eth_addr {
> +    struct eth_addr addr;
> +    struct eth_addr mask;
> +};
> +
> +struct port_security_addresses {
> +    struct eth_addr phys_addr;
> +    /* Vector of 'struct masked_eth_addr'. */
> +    struct vector vrrp4;
> +    /* Vector of 'struct masked_eth_addr'. */
> +    struct vector vrrp6;
> +    /* Vector of 'struct masked_ip4_addr' .*/
> +    struct vector ip4;
> +    /* Vector of 'struct masked_ip6_addr' .*/
> +    struct vector ip6;
> +};
> +
> +static const struct masked_eth_addr maddr_any_vrrp4 = {
> +    .addr = ETH_ADDR_C(00,00,5e,00,01,00),
> +    .mask = ETH_ADDR_C(ff,ff,ff,ff,ff,00)
> +};
> +static const struct masked_eth_addr maddr_any_vrrp6 = {
> +    .addr = ETH_ADDR_C(00,00,5e,00,02,00),
> +    .mask = ETH_ADDR_C(ff,ff,ff,ff,ff,00)
> +};
> +
> +static bool
> +port_security_addresses_add_vrrp_mac(struct port_security_addresses *ps_addr,
> +                                     struct eth_addr mac, unsigned int plen)
> +{
> +    /* Only the last byte contains ID for VRRPv3. */
> +    if (plen < 40) {
> +        return false;
> +    }
> +
> +    /* If the masked portion is non-zero, the host can only use
> +     * the specified MAC address.  If zero, the host is allowed
> +     * to use any MAC address within the mask.
> +     */
> +    struct eth_addr mask = eth_addr_create_mask(plen);
> +    struct masked_eth_addr maddr = (struct masked_eth_addr) {
> +        .addr = mac,
> +        .mask = (eth_addr_to_uint64(mac) & ~eth_addr_to_uint64(mask))
> +            ? eth_addr_exact : mask,

Nit: I think "?" should be under "=".

> +    };
> +
> +    /* The exact match on VRRPv3 MAC ending with zero is not allowed, the
> +     * id is starting from 1. */
> +    if (plen == 48 && (eth_addr_equals(mac, maddr_any_vrrp4.addr) ||
> +        eth_addr_equals(mac, maddr_any_vrrp6.addr))) {

Nit: I find this hard to read.

I think I'd use two ifs, e.g.:

if (plen == 48) {
   if (eth_addr_equals(mac, maddr_any_vrrp4.addr) ||
       eth_addr_equals(mac, maddr_any_vrrp6.addr))) {

       return false;
   }
}

> +        return false;
> +    }
> +
> +    if (eth_addr_equal_except(maddr_any_vrrp4.addr, mac,
> +                              maddr_any_vrrp4.mask)) {
> +        vector_push(&ps_addr->vrrp4, &maddr);
> +        return true;
> +    }
> +
> +    if (eth_addr_equal_except(maddr_any_vrrp6.addr, mac,
> +                              maddr_any_vrrp6.mask)) {
> +        vector_push(&ps_addr->vrrp6, &maddr);
> +        return true;
> +    }
> +
> +    return false;
> +}
> +
> +static bool
> +port_security_addresses_add_ip(struct port_security_addresses *ps_addr,
> +                               struct in6_addr ip, unsigned int plen)
> +{
> +    /* When the netmask is applied, if the host portion is
> +     * non-zero, the host can only use the specified
> +     * address.  If zero, the host is allowed to use any
> +     * address in the subnet. Also add broadcast in the special case
> +     * of matching only the specified address.
> +     */
> +    if (IN6_IS_ADDR_V4MAPPED(&ip)) {
> +        if (plen > 32) {
> +            return false;
> +        }
> +
> +        ovs_be32 addr = in6_addr_get_mapped_ipv4(&ip);
> +        ovs_be32 mask = be32_prefix_mask(plen);
> +
> +        struct masked_ip4_addr maddr = (struct masked_ip4_addr) {
> +            .addr = addr,
> +            .mask = (addr & ~mask) ? OVS_BE32_MAX : mask,
> +            .bcast = (addr & ~mask) ? addr | ~mask : htonl(0),

Nit: maybe:

.bcast = (addr & ~mask) ? (addr | ~mask) : htonl(0),

> +        };
> +        vector_push(&ps_addr->ip4, &maddr);
> +    } else {
> +        if (plen > 128) {
> +            return false;
> +        }
> +
> +        struct in6_addr mask = ipv6_create_mask(plen);
> +        struct masked_ip6_addr maddr = (struct masked_ip6_addr) {
> +            .addr = ip,
> +            .mask = !ipv6_addr_is_host_zero(&ip, &mask) ? in6addr_exact : 
> mask,
> +        };
> +        vector_push(&ps_addr->ip6, &maddr);
> +    }
> +
> +    return true;
> +}
> +
>  static void
>  reset_match_for_port_sec_flows(const struct sbrec_port_binding *pb,
>                                 enum mf_field_id reg_id, struct match *match)
> @@ -2446,24 +2565,39 @@ build_in_port_sec_default_flows(const struct 
> sbrec_port_binding *pb,
>                      &pb->header_.uuid);
>  }
>  
> +static void
> +build_out_port_sec_default_flows(const struct sbrec_port_binding *pb,
> +                                struct match *m, struct ofpbuf *ofpacts,
> +                                struct ovn_desired_flow_table *flow_table)
> +{
> +    /* Add the below logical flow equivalent OF rules in 'out_port_sec_nd'
> +     * table.
> +     * priority: 80
> +     * match - "outport == pb->logical_port"
> +     * action - "port_sec_failed = 1;"
> +     * descrption: "Drop all traffic"
> +     */
> +    reset_match_for_port_sec_flows(pb, MFF_LOG_OUTPORT, m);
> +    build_port_sec_deny_action(ofpacts);
> +    ofctrl_add_flow(flow_table, OFTABLE_CHK_OUT_PORT_SEC, 80,
> +                    pb->header_.uuid.parts[0], m, ofpacts,
> +                    &pb->header_.uuid);
> +}
> +
>  static void
>  build_in_port_sec_no_ip_flows(const struct sbrec_port_binding *pb,
> -                              struct lport_addresses *ps_addr,
> +                              struct eth_addr mac, struct eth_addr mask,
>                                struct match *m, struct ofpbuf *ofpacts,
>                                struct ovn_desired_flow_table *flow_table)
>  {
> -    if (ps_addr->n_ipv4_addrs || ps_addr->n_ipv6_addrs) {
> -        return;
> -    }
> -
>      /* Add the below logical flow equivalent OF rules in 'in_port_sec' table.
>       * priority: 90
> -     * match - "inport == pb->logical_port && eth.src == ps_addr.ea"
> +     * match - "inport == pb->logical_port && eth.src == mac/mask"
>       * action - "next;"
>       * description: "Advance the packet for ARP/ND check"
>       */
>      reset_match_for_port_sec_flows(pb, MFF_LOG_INPORT, m);
> -    match_set_dl_src(m, ps_addr->ea);
> +    match_set_dl_src_masked(m, mac, mask);
>      build_port_sec_adv_nd_check(ofpacts);
>      ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC, 90,
>                      pb->header_.uuid.parts[0], m, ofpacts,
> @@ -2472,43 +2606,26 @@ build_in_port_sec_no_ip_flows(const struct 
> sbrec_port_binding *pb,
>  
>  static void
>  build_in_port_sec_ip4_flows(const struct sbrec_port_binding *pb,
> -                           struct lport_addresses *ps_addr,
> -                           struct match *m, struct ofpbuf *ofpacts,
> -                           struct ovn_desired_flow_table *flow_table)
> +                            struct eth_addr mac, struct eth_addr mask,
> +                            const struct vector *ip4_addrs,
> +                            struct match *m, struct ofpbuf *ofpacts,
> +                            struct ovn_desired_flow_table *flow_table)
>  {
> -    if (!ps_addr->n_ipv4_addrs) {
> -        /* If no IPv4 addresses, then 'pb' is not allowed to send IPv4 
> traffic.
> -         * build_in_port_sec_default_flows() takes care of this scenario. */
> -        return;
> -    }
> -
>      /* Advance all traffic from the port security eth address for ND check. 
> */
>      build_port_sec_allow_action(ofpacts);
> +    reset_match_for_port_sec_flows(pb, MFF_LOG_INPORT, m);
> +    match_set_dl_src_masked(m, mac, mask);
> +    match_set_dl_type(m, htons(ETH_TYPE_IP));
>  
>      /* Add the below logical flow equivalent OF rules in in_port_sec.
>       * priority: 90
> -     * match - "inport == pb->port && eth.src == ps_addr.ea &&
> -     *         ip4.src == {ps_addr.ipv4_addrs}"
> +     * match - "inport == pb->port && eth.src == mac/mask &&
> +     *         ip4.src == {ip4}"
>       * action - "port_sec_failed = 0;"
>       */
> -    for (size_t j = 0; j < ps_addr->n_ipv4_addrs; j++) {
> -        reset_match_for_port_sec_flows(pb, MFF_LOG_INPORT, m);
> -        match_set_dl_src(m, ps_addr->ea);
> -        match_set_dl_type(m, htons(ETH_TYPE_IP));
> -
> -        ovs_be32 mask = ps_addr->ipv4_addrs[j].mask;
> -        /* When the netmask is applied, if the host portion is
> -         * non-zero, the host can only use the specified
> -         * address.  If zero, the host is allowed to use any
> -         * address in the subnet.
> -         */
> -        if (ps_addr->ipv4_addrs[j].plen == 32 ||
> -                ps_addr->ipv4_addrs[j].addr & ~mask) {
> -            match_set_nw_src(m, ps_addr->ipv4_addrs[j].addr);
> -        } else {
> -            match_set_nw_src_masked(m, ps_addr->ipv4_addrs[j].addr, mask);
> -        }
> -
> +    const struct masked_ip4_addr *ip;
> +    VECTOR_FOR_EACH_PTR (ip4_addrs, ip) {
> +        match_set_nw_src_masked(m, ip->addr, ip->mask);
>          ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC, 90,
>                          pb->header_.uuid.parts[0], m, ofpacts,
>                          &pb->header_.uuid);
> @@ -2516,20 +2633,14 @@ build_in_port_sec_ip4_flows(const struct 
> sbrec_port_binding *pb,
>  
>      /* Add the below logical flow equivalent OF rules in in_port_sec.
>       * priority: 90
> -     * match - "inport == pb->port && eth.src == ps_addr.ea &&
> +     * match - "inport == pb->port && eth.src == mac/mask &&
>       *          ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 &&
>       *          udp.src == 67 && udp.dst == 68"
>       * action - "port_sec_failed = 0;"
>       * description: "Allow the DHCP requests."
>       */
> -    reset_match_for_port_sec_flows(pb, MFF_LOG_INPORT, m);
> -    match_set_dl_src(m, ps_addr->ea);
> -    match_set_dl_type(m, htons(ETH_TYPE_IP));
> -
> -    ovs_be32 ip4 = htonl(0);
> -    match_set_nw_src(m, ip4);
> -    ip4 = htonl(0xffffffff);
> -    match_set_nw_dst(m, ip4);
> +    match_set_nw_src(m, htonl(0));
> +    match_set_nw_dst(m, htonl(0xffffffff));
>      match_set_nw_proto(m, IPPROTO_UDP);
>      match_set_tp_src(m, htons(68));
>      match_set_tp_dst(m, htons(67));
> @@ -2542,33 +2653,39 @@ build_in_port_sec_ip4_flows(const struct 
> sbrec_port_binding *pb,
>  /* Adds the OF rules to allow ARP packets in 'in_port_sec_nd' table. */
>  static void
>  build_in_port_sec_arp_flows(const struct sbrec_port_binding *pb,
> -                           struct lport_addresses *ps_addr,
> -                           struct match *m, struct ofpbuf *ofpacts,
> -                           struct ovn_desired_flow_table *flow_table)
> +                            struct eth_addr phys_mac,
> +                            const struct vector *ip4_addrs,
> +                            const struct vector *vrrp4_addrs,
> +                            struct match *m, struct ofpbuf *ofpacts,
> +                            struct ovn_desired_flow_table *flow_table)
>  {
> -    if (!ps_addr->n_ipv4_addrs && ps_addr->n_ipv6_addrs) {
> -        /* No ARP is allowed as only IPv6 addresses are configured. */
> -        return;
> -    }
> -
>      build_port_sec_allow_action(ofpacts);
> +    reset_match_for_port_sec_flows(pb, MFF_LOG_INPORT, m);
> +    match_set_dl_src(m, phys_mac);
> +    match_set_dl_type(m, htons(ETH_TYPE_ARP));
>  
> -    if (!ps_addr->n_ipv4_addrs) {
> +    if (vector_is_empty(ip4_addrs)) {
>          /* No IPv4 addresses.
>           * Add the below logical flow equivalent OF rules in 'in_port_sec_nd'
>           * table.
>           * priority: 90
> -         * match - "inport == pb->port && eth.src == ps_addr.ea &&
> -         *          arp && arp.sha == ps_addr.ea"
> +         * match - "inport == pb->port && eth.src == phys_mac &&
> +         *          arp && arp.sha == {phys_mac, vrrp4_addrs}"
>           * action - "port_sec_failed = 0;"
>           */
> -        reset_match_for_port_sec_flows(pb, MFF_LOG_INPORT, m);
> -        match_set_dl_src(m, ps_addr->ea);
> -        match_set_dl_type(m, htons(ETH_TYPE_ARP));
> -        match_set_arp_sha(m, ps_addr->ea);
> +
> +        match_set_arp_sha(m, phys_mac);
>          ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, 90,
>                          pb->header_.uuid.parts[0], m, ofpacts,
>                          &pb->header_.uuid);
> +
> +        struct masked_eth_addr *mmac;
> +        VECTOR_FOR_EACH_PTR (vrrp4_addrs, mmac) {
> +            match_set_arp_sha_masked(m, mmac->addr, mmac->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'
> @@ -2578,74 +2695,60 @@ build_in_port_sec_arp_flows(const struct 
> sbrec_port_binding *pb,
>       *         arp && arp.sha == ps_addr.ea && arp.spa == 
> {ps_addr.ipv4_addrs}"
>       * action - "port_sec_failed = 0;"
>       */
> -    for (size_t j = 0; j < ps_addr->n_ipv4_addrs; j++) {
> -        reset_match_for_port_sec_flows(pb, MFF_LOG_INPORT, m);
> -        match_set_dl_src(m, ps_addr->ea);
> -        match_set_dl_type(m, htons(ETH_TYPE_ARP));
> -        match_set_arp_sha(m, ps_addr->ea);
> -
> -        ovs_be32 mask = ps_addr->ipv4_addrs[j].mask;
> -        if (ps_addr->ipv4_addrs[j].plen == 32 ||
> -                ps_addr->ipv4_addrs[j].addr & ~mask) {
> -            match_set_nw_src(m, ps_addr->ipv4_addrs[j].addr);
> -        } else {
> -            match_set_nw_src_masked(m, ps_addr->ipv4_addrs[j].addr, mask);
> -        }
> +    const struct masked_ip4_addr *ip;
> +    VECTOR_FOR_EACH_PTR (ip4_addrs, ip) {
> +        match_set_nw_src_masked(m, ip->addr, ip->mask);
> +
> +        match_set_arp_sha(m, phys_mac);
>          ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, 90,
>                          pb->header_.uuid.parts[0], m, ofpacts,
>                          &pb->header_.uuid);
> +
> +        struct masked_eth_addr *mmac;
> +        VECTOR_FOR_EACH_PTR (vrrp4_addrs, mmac) {
> +            match_set_arp_sha_masked(m, mmac->addr, mmac->mask);
> +            ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, 90,
> +                            pb->header_.uuid.parts[0], m, ofpacts,
> +                            &pb->header_.uuid);
> +        }
>      }
>  }
>  
>  static void
>  build_in_port_sec_ip6_flows(const struct sbrec_port_binding *pb,
> -                           struct lport_addresses *ps_addr,
> -                           struct match *m, struct ofpbuf *ofpacts,
> -                           struct ovn_desired_flow_table *flow_table)
> +                            struct eth_addr mac, struct eth_addr mask,
> +                            const struct vector *ip6_addrs,
> +                            struct match *m, struct ofpbuf *ofpacts,
> +                            struct ovn_desired_flow_table *flow_table)
>  {
> -    if (!ps_addr->n_ipv6_addrs) {
> -        /* If no IPv6 addresses, then 'pb' is not allowed to send IPv6 
> traffic.
> -         * build_in_port_sec_default_flows() takes care of this scenario. */
> -        return;
> -    }
> -
>      /* Add the below logical flow equivalent OF rules in 'in_port_sec_nd'
>       * table.
>       * priority: 90
> -     * match - "inport == pb->port && eth.src == ps_addr.ea &&
> +     * match - "inport == pb->port && eth.src == mac/mask &&
>       *         ip6.src == {ps_addr.ipv6_addrs, lla}"
>       * action - "next;"
>       * description - Advance the packet for Neighbor Solicit/Adv check.
>       */
>      build_port_sec_adv_nd_check(ofpacts);
> +    reset_match_for_port_sec_flows(pb, MFF_LOG_INPORT, m);
> +    match_set_dl_src_masked(m, mac, mask);
> +    match_set_dl_type(m, htons(ETH_TYPE_IPV6));
>  
> -    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);
> -        match_set_dl_type(m, htons(ETH_TYPE_IPV6));
> -
> -        if (ps_addr->ipv6_addrs[j].plen == 128
> -            || !ipv6_addr_is_host_zero(&ps_addr->ipv6_addrs[j].addr,
> -                                        &ps_addr->ipv6_addrs[j].mask)) {
> -            match_set_ipv6_src(m, &ps_addr->ipv6_addrs[j].addr);
> -        } else {
> -            match_set_ipv6_src_masked(m, &ps_addr->ipv6_addrs[j].network,
> -                                        &ps_addr->ipv6_addrs[j].mask);
> -        }
> -
> +    const struct masked_ip6_addr *ip;
> +    VECTOR_FOR_EACH_PTR (ip6_addrs, ip) {
> +        match_set_ipv6_src_masked(m, &ip->addr, &ip->mask);
>          ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC, 90,
>                          pb->header_.uuid.parts[0], m, ofpacts,
>                          &pb->header_.uuid);
>      }
>  
> -    reset_match_for_port_sec_flows(pb, MFF_LOG_INPORT, m);
> -    match_set_dl_src(m, ps_addr->ea);
> -    match_set_dl_type(m, htons(ETH_TYPE_IPV6));
>  
>      struct in6_addr lla;
> -    in6_generate_lla(ps_addr->ea, &lla);
> -    match_set_ipv6_src(m, &lla);
> +    in6_generate_lla(mac, &lla);
> +    unsigned int plen = 128 - 48 + eth_addr_get_prefix_len(mask);
> +    struct in6_addr lla_mask = ipv6_create_mask(plen);
>  
> +    match_set_ipv6_src_masked(m, &lla, &lla_mask);
>      ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC, 90,
>                      pb->header_.uuid.parts[0], m, ofpacts,
>                      &pb->header_.uuid);
> @@ -2660,11 +2763,12 @@ build_in_port_sec_ip6_flows(const struct 
> sbrec_port_binding *pb,
>       */
>      build_port_sec_allow_action(ofpacts);
>      match_set_ipv6_src(m, &in6addr_any);
> -    struct in6_addr ip6, mask;
> -    char *err = ipv6_parse_masked("ff02::/16", &ip6, &mask);
> +
> +    struct in6_addr ip6, ip_mask;
> +    char *err = ipv6_parse_masked("ff02::/16", &ip6, &ip_mask);
>      ovs_assert(!err);
>  
> -    match_set_ipv6_dst_masked(m, &ip6, &mask);
> +    match_set_ipv6_dst_masked(m, &ip6, &ip_mask);
>      match_set_nw_proto(m, IPPROTO_ICMPV6);
>      match_set_icmp_type(m, 131);
>      match_set_icmp_code(m, 0);
> @@ -2697,99 +2801,111 @@ build_in_port_sec_ip6_flows(const struct 
> sbrec_port_binding *pb,
>   * 'in_port_sec_nd' table. */
>  static void
>  build_in_port_sec_nd_flows(const struct sbrec_port_binding *pb,
> -                           struct lport_addresses *ps_addr,
> +                           struct eth_addr phys_mac,
> +                           const struct vector *ip6_addrs,
> +                           const struct vector *vrrp6_addrs,
>                             struct match *m, struct ofpbuf *ofpacts,
>                             struct ovn_desired_flow_table *flow_table)
>  {
>      build_port_sec_allow_action(ofpacts);
> +    reset_match_for_port_sec_flows(pb, MFF_LOG_INPORT, m);
> +    match_set_dl_src(m, phys_mac);
> +    match_set_dl_type(m, htons(ETH_TYPE_IPV6));
> +    match_set_nw_proto(m, IPPROTO_ICMPV6);
> +    match_set_icmp_code(m, 0);
> +    match_set_nw_ttl(m, 255);
>  
>      /* Add the below logical flow equivalent OF rules in 'in_port_sec_nd'
>       * table.
>       * priority: 90
> -     * match - "inport == pb->port && eth.src == ps_addr.ea &&
> -     *          icmp6 && icmp6.code == 135 && icmp6.type == 0 &&
> -     *          ip6.tll == 255 && nd.sll == {00:00:00:00:00:00, ps_addr.ea}"
> +     * match - "inport == pb->port && eth.src == phys_mac &&
> +     *          icmp6 && icmp6.type == 135 && icmp6.code == 0 &&
> +     *          ip6.tll == 255 &&
> +     *          nd.sll == {00:00:00:00:00:00, phys_mac, vrrp6_addrs}"
>       * action - "port_sec_failed = 0;"
>       */
> -    reset_match_for_port_sec_flows(pb, MFF_LOG_INPORT, m);
> -    match_set_dl_type(m, htons(ETH_TYPE_IPV6));
> -    match_set_nw_proto(m, IPPROTO_ICMPV6);
> -    match_set_dl_src(m, ps_addr->ea);
> -    match_set_nw_ttl(m, 255);
> +
>      match_set_icmp_type(m, 135);
> -    match_set_icmp_code(m, 0);
>  
>      match_set_arp_sha(m, eth_addr_zero);
>      ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, 90,
>                      pb->header_.uuid.parts[0], m, ofpacts,
>                      &pb->header_.uuid);
>  
> -    match_set_arp_sha(m, ps_addr->ea);
> +    match_set_arp_sha(m, phys_mac);
>      ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, 90,
>                      pb->header_.uuid.parts[0], m, ofpacts,
>                      &pb->header_.uuid);
>  
> +    struct masked_eth_addr *mmac;
> +    VECTOR_FOR_EACH_PTR (vrrp6_addrs, mmac) {
> +        match_set_arp_sha_masked(m, mmac->addr, mmac->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_arp_sha_masked(m, eth_addr_zero, eth_addr_zero);
>      match_set_icmp_type(m, 136);
> -    match_set_icmp_code(m, 0);
> -    if (ps_addr->n_ipv6_addrs) {
> +    if (!vector_is_empty(ip6_addrs)) {
>          /* Add the below logical flow equivalent OF rules in 'in_port_sec_nd'
>           * table if IPv6 addresses are configured.
>           * priority: 90
> -         * match - "inport == pb->port && eth.src == ps_addr.ea && icmp6 &&
> -         *          icmp6.code == 136 && icmp6.type == 0 && ip6.tll == 255 &&
> -         *          nd.tll == {00:00:00:00:00:00, ps_addr.ea} &&
> -         *          nd.target == {ps_addr.ipv6_addrs, lla}"
> +         * match - "inport == pb->port && eth.src == phys_mac && icmp6 &&
> +         *          icmp6.type == 136 && icmp6.code == 0 && ip6.tll == 255 &&
> +         *          nd.tll == {00:00:00:00:00:00, phys_mac, vrrp6_addrs} &&
> +         *          nd.target == {lla, ip6_addrs}"
>           * action - "port_sec_failed = 0;"
>           */
>          struct in6_addr lla;
> -        in6_generate_lla(ps_addr->ea, &lla);
> -        match_set_arp_tha(m, eth_addr_zero);
> -
> +        in6_generate_lla(phys_mac, &lla);
>          match_set_nd_target(m, &lla);
> +
> +        match_set_arp_tha(m, eth_addr_zero);
>          ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, 90,
>                          pb->header_.uuid.parts[0], m, ofpacts,
>                          &pb->header_.uuid);
> -        match_set_arp_tha(m, ps_addr->ea);
> -        match_set_nd_target(m, &lla);
> +
> +        match_set_arp_tha(m, phys_mac);
>          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);
> -            match_set_dl_type(m, htons(ETH_TYPE_IPV6));
> -            match_set_nw_proto(m, IPPROTO_ICMPV6);
> -            match_set_nw_ttl(m, 255);
> -            match_set_icmp_type(m, 136);
> -            match_set_icmp_code(m, 0);
> -            match_set_arp_tha(m, eth_addr_zero);
> +        VECTOR_FOR_EACH_PTR (vrrp6_addrs, mmac) {
> +            match_set_arp_tha_masked(m, mmac->addr, mmac->mask);
> +            ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, 90,
> +                            pb->header_.uuid.parts[0], m, ofpacts,
> +                            &pb->header_.uuid);
> +        }
>  
> -            if (ps_addr->ipv6_addrs[j].plen == 128
> -                || !ipv6_addr_is_host_zero(&ps_addr->ipv6_addrs[j].addr,
> -                                            &ps_addr->ipv6_addrs[j].mask)) {
> -                match_set_nd_target(m, &ps_addr->ipv6_addrs[j].addr);
> -            } else {
> -                match_set_nd_target_masked(m, 
> &ps_addr->ipv6_addrs[j].network,
> -                                           &ps_addr->ipv6_addrs[j].mask);
> -            }
> +        const struct masked_ip6_addr *ip;
> +        VECTOR_FOR_EACH_PTR (ip6_addrs, ip) {
> +            match_set_nd_target_masked(m, &ip->addr, &ip->mask);
>  
> +            match_set_arp_tha(m, eth_addr_zero);
>              ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, 90,
>                              pb->header_.uuid.parts[0], m, ofpacts,
>                              &pb->header_.uuid);
>  
> -            match_set_arp_tha(m, ps_addr->ea);
> +            match_set_arp_tha(m, phys_mac);
>              ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, 90,
>                              pb->header_.uuid.parts[0], m, ofpacts,
>                              &pb->header_.uuid);
> +
> +            VECTOR_FOR_EACH_PTR (vrrp6_addrs, mmac) {
> +                match_set_arp_tha_masked(m, mmac->addr, mmac->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'
>           * table if no IPv6 addresses are configured.
>           * priority: 90
> -         * match - "inport == pb->port && eth.src == ps_addr.ea && icmp6 &&
> +         * match - "inport == pb->port && eth.src == phys_mac && icmp6 &&
>           *          icmp6.code == 136 && icmp6.type == 0 && ip6.tll == 255 &&
> -         *          nd.tll == {00:00:00:00:00:00, ps_addr.ea}"
> +         *          nd.tll == {00:00:00:00:00:00, phys_mac, vrrp6_addrs}"
>           * action - "port_sec_failed = 0;"
>           */
>          match_set_arp_tha(m, eth_addr_zero);
> @@ -2797,27 +2913,34 @@ build_in_port_sec_nd_flows(const struct 
> sbrec_port_binding *pb,
>                          pb->header_.uuid.parts[0], m, ofpacts,
>                          &pb->header_.uuid);
>  
> -        match_set_arp_tha(m, ps_addr->ea);
> +        match_set_arp_tha(m, phys_mac);
>          ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, 90,
>                          pb->header_.uuid.parts[0], m, ofpacts,
>                          &pb->header_.uuid);
> +
> +        VECTOR_FOR_EACH_PTR (vrrp6_addrs, mmac) {
> +            match_set_arp_tha_masked(m, mmac->addr, mmac->mask);
> +            ofctrl_add_flow(flow_table, OFTABLE_CHK_IN_PORT_SEC_ND, 90,
> +                            pb->header_.uuid.parts[0], m, ofpacts,
> +                            &pb->header_.uuid);
> +        }
>      }
>  }
>  
>  static void
>  build_out_port_sec_no_ip_flows(const struct sbrec_port_binding *pb,
> -                               struct lport_addresses *ps_addr,
> +                               struct eth_addr mac, struct eth_addr mask,
>                                 struct match *m, struct ofpbuf *ofpacts,
>                                 struct ovn_desired_flow_table *flow_table)
>  {
>      /* Add the below logical flow equivalent OF rules in 'out_port_sec' 
> table.
>       * priority: 85
> -     * match - "outport == pb->logical_port && eth.dst == ps_addr.ea"
> +     * match - "outport == pb->logical_port && eth.dst == mac/mask"
>       * action - "port_sec_failed = 0;"
>       * description: "Allow the packet if eth.dst matches."
>       */
>      reset_match_for_port_sec_flows(pb, MFF_LOG_OUTPORT, m);
> -    match_set_dl_dst(m, ps_addr->ea);
> +    match_set_dl_dst_masked(m, mac, mask);
>      build_port_sec_allow_action(ofpacts);
>      ofctrl_add_flow(flow_table, OFTABLE_CHK_OUT_PORT_SEC, 85,
>                      pb->header_.uuid.parts[0], m, ofpacts,
> @@ -2826,97 +2949,70 @@ build_out_port_sec_no_ip_flows(const struct 
> sbrec_port_binding *pb,
>  
>  static void
>  build_out_port_sec_ip4_flows(const struct sbrec_port_binding *pb,
> -                            struct lport_addresses *ps_addr,
> -                            struct match *m, struct ofpbuf *ofpacts,
> -                            struct ovn_desired_flow_table *flow_table)
> +                             struct eth_addr mac, struct eth_addr mask,
> +                             const struct vector *ip4_addrs,
> +                             struct match *m, struct ofpbuf *ofpacts,
> +                             struct ovn_desired_flow_table *flow_table)
>  {
> -    if (!ps_addr->n_ipv4_addrs && !ps_addr->n_ipv6_addrs) {
> -         /* No IPv4 and no IPv6 addresses in the port security.
> -          * Both IPv4 and IPv6 traffic should be delivered to the
> -          * lport. build_out_port_sec_no_ip_flows() takes care of
> -          * adding the required flow(s) to allow. */
> -        return;
> -    }
> +    reset_match_for_port_sec_flows(pb, MFF_LOG_OUTPORT, m);
> +    match_set_dl_dst_masked(m, mac, mask);
> +    match_set_dl_type(m, htons(ETH_TYPE_IP));
>  
>      /* Add the below logical flow equivalent OF rules in 'out_port_sec' 
> table.
>       * priority: 90
> -     * match - "outport == pb->logical_port && eth.dst == ps_addr.ea && ip4"
> +     * match - "outport == pb->logical_port && eth.dst == mac/mask && ip4"
>       * action - "port_sec_failed = 1;"
>       * description: Default drop IPv4 packets.  If IPv4 addresses are
>       *              configured, then higher priority flows are added
>       *              to allow specific IPv4 packets.
>       */
> -    reset_match_for_port_sec_flows(pb, MFF_LOG_OUTPORT, m);
> -    match_set_dl_dst(m, ps_addr->ea);
> -    match_set_dl_type(m, htons(ETH_TYPE_IP));
> +
>      build_port_sec_deny_action(ofpacts);
>      ofctrl_add_flow(flow_table, OFTABLE_CHK_OUT_PORT_SEC, 90,
>                      pb->header_.uuid.parts[0], m, ofpacts,
>                      &pb->header_.uuid);
>  
> -    if (!ps_addr->n_ipv4_addrs) {
> +    if (vector_is_empty(ip4_addrs)) {
>          return;
>      }
>  
> +    build_port_sec_allow_action(ofpacts);
>      /* Add the below logical flow equivalent OF rules in 'out_port_sec' 
> table.
>       * priority: 95
> -     * match - "outport == pb->logical_port && eth.dst == ps_addr.ea &&
> -     *          ip4.dst == {ps_addr.ipv4_addrs, 255.255.255.255, 
> 224.0.0.0/4},"
> +     * match - "outport == pb->logical_port && eth.dst == mac/mask &&
> +     *          ip4.dst == {ip4_addrs, 255.255.255.255, 224.0.0.0/4},"
>       * action - "port_sec_failed = 0;"
>       */
> -    build_port_sec_allow_action(ofpacts);
> -    for (size_t j = 0; j < ps_addr->n_ipv4_addrs; j++) {
> -        reset_match_for_port_sec_flows(pb, MFF_LOG_OUTPORT, m);
> -        match_set_dl_dst(m, ps_addr->ea);
> -        match_set_dl_type(m, htons(ETH_TYPE_IP));
> -        ovs_be32 mask = ps_addr->ipv4_addrs[j].mask;
> -        if (ps_addr->ipv4_addrs[j].plen == 32
> -                || ps_addr->ipv4_addrs[j].addr & ~mask) {
> -
> -            if (ps_addr->ipv4_addrs[j].plen != 32) {
> -                /* Special case to allow bcast traffic.
> -                 * Eg. If ps_addr is 10.0.0.4/24, then add the below flow
> -                 * priority: 95
> -                 * match - "outport == pb->logical_port &&
> -                 *          eth.dst == ps_addr.ea &&
> -                 *          ip4.dst == 10.0.0.255"
> -                 * action - "port_sec_failed = 0;"
> -                 */
> -                ovs_be32 bcast_addr;
> -                ovs_assert(ip_parse(ps_addr->ipv4_addrs[j].bcast_s,
> -                                    &bcast_addr));
> -                match_set_nw_dst(m, bcast_addr);
> -                ofctrl_add_flow(flow_table, OFTABLE_CHK_OUT_PORT_SEC, 95,
> -                                pb->header_.uuid.parts[0], m, ofpacts,
> -                                &pb->header_.uuid);
> -            }
> -
> -            match_set_nw_dst(m, ps_addr->ipv4_addrs[j].addr);
> -        } else {
> -            /* host portion is zero */
> -            match_set_nw_dst_masked(m, ps_addr->ipv4_addrs[j].addr,
> -                                    mask);
> -        }
> -
> +    const struct masked_ip4_addr *ip;
> +    VECTOR_FOR_EACH_PTR (ip4_addrs, ip) {
> +        match_set_nw_dst_masked(m, ip->addr, ip->mask);
>          ofctrl_add_flow(flow_table, OFTABLE_CHK_OUT_PORT_SEC, 95,
>                          pb->header_.uuid.parts[0], m, ofpacts,
>                          &pb->header_.uuid);
> -    }
>  
> -    reset_match_for_port_sec_flows(pb, MFF_LOG_OUTPORT, m);
> -    match_set_dl_dst(m, ps_addr->ea);
> -    match_set_dl_type(m, htons(ETH_TYPE_IP));
> +        if (ip->bcast) {
> +            /* Special case to allow bcast traffic.
> +             * Eg. If address is 10.0.0.4/24, then add the below flow
> +             * priority: 95
> +             * match - "outport == pb->logical_port &&
> +             *          eth.dst == ps_addr.ea &&
> +             *          ip4.dst == 10.0.0.255"
> +             * action - "port_sec_failed = 0;"
> +             */
> +            match_set_nw_dst(m, ip->bcast);
> +            ofctrl_add_flow(flow_table, OFTABLE_CHK_OUT_PORT_SEC, 95,
> +                            pb->header_.uuid.parts[0], m, ofpacts,
> +                            &pb->header_.uuid);
> +        }
> +    }
>  
> -    ovs_be32 ip4 = htonl(0xffffffff);
> -    match_set_nw_dst(m, ip4);
> +    match_set_nw_dst(m, htonl(0xffffffff));
>      ofctrl_add_flow(flow_table, OFTABLE_CHK_OUT_PORT_SEC, 95,
>                      pb->header_.uuid.parts[0], m, ofpacts,
>                      &pb->header_.uuid);
>  
>      /* Allow 224.0.0.0/4 traffic. */
> -    ip4 = htonl(0xe0000000);
> -    ovs_be32 mask = htonl(0xf0000000);
> -    match_set_nw_dst_masked(m, ip4, mask);
> +    match_set_nw_dst_masked(m, htonl(0xe0000000), htonl(0xf0000000));
>      ofctrl_add_flow(flow_table, OFTABLE_CHK_OUT_PORT_SEC, 95,
>                      pb->header_.uuid.parts[0], m, ofpacts,
>                      &pb->header_.uuid);
> @@ -2924,112 +3020,234 @@ build_out_port_sec_ip4_flows(const struct 
> sbrec_port_binding *pb,
>  
>  static void
>  build_out_port_sec_ip6_flows(const struct sbrec_port_binding *pb,
> -                            struct lport_addresses *ps_addr,
> -                            struct match *m, struct ofpbuf *ofpacts,
> -                            struct ovn_desired_flow_table *flow_table)
> +                             struct eth_addr mac, struct eth_addr mask,
> +                             const struct vector *ip6_addrs,
> +                             struct match *m, struct ofpbuf *ofpacts,
> +                             struct ovn_desired_flow_table *flow_table)
>  {
> -    if (!ps_addr->n_ipv4_addrs && !ps_addr->n_ipv6_addrs) {
> -        /* No IPv4 and no IPv6 addresses in the port security.
> -         * Both IPv4 and IPv6 traffic should be delivered to the
> -         * lport. build_out_port_sec_no_ip_flows() takes care of
> -         * adding the required flow(s) to allow. */
> -        return;
> -    }
> +    reset_match_for_port_sec_flows(pb, MFF_LOG_OUTPORT, m);
> +    match_set_dl_dst_masked(m, mac, mask);
> +    match_set_dl_type(m, htons(ETH_TYPE_IPV6));
>  
>      /* Add the below logical flow equivalent OF rules in 'out_port_sec' 
> table.
>       * priority: 90
> -     * match - "outport == pb->logical_port && eth.dst == ps_addr.ea && ip6"
> +     * match - "outport == pb->logical_port && eth.dst == mac/mask && ip6"
>       * action - "port_sec_failed = 1;"
>       * description: Default drop IPv6 packets.  If IPv6 addresses are
>       *              configured, then higher priority flows are added
>       *              to allow specific IPv6 packets.
>       */
> -    reset_match_for_port_sec_flows(pb, MFF_LOG_OUTPORT, m);
> -    match_set_dl_dst(m, ps_addr->ea);
> -    match_set_dl_type(m, htons(ETH_TYPE_IPV6));
>      build_port_sec_deny_action(ofpacts);
>      ofctrl_add_flow(flow_table, OFTABLE_CHK_OUT_PORT_SEC, 90,
>                      pb->header_.uuid.parts[0], m, ofpacts,
>                      &pb->header_.uuid);
>  
> -    if (!ps_addr->n_ipv6_addrs) {
> +    if (vector_is_empty(ip6_addrs)) {
>          return;
>      }
>  
> +    build_port_sec_allow_action(ofpacts);
>      /* Add the below logical flow equivalent OF rules in 'out_port_sec' 
> table.
>       * priority: 95
> -     * match - "outport == pb->logical_port && eth.dst == ps_addr.ea &&
> -     *          ip6.dst == {ps_addr.ipv6_addrs, lla, ff00::/8},"
> +     * match - "outport == pb->logical_port && eth.dst == mac/mask &&
> +     *          ip6.dst == {mac/mask, ip6_addrs, lla, ff00::/8},"
>       * action - "port_sec_failed = 0;"
>       */
> -    build_port_sec_allow_action(ofpacts);
> -    for (size_t j = 0; j < ps_addr->n_ipv6_addrs; j++) {
> -        reset_match_for_port_sec_flows(pb, MFF_LOG_OUTPORT, m);
> -        match_set_dl_dst(m, ps_addr->ea);
> -        match_set_dl_type(m, htons(ETH_TYPE_IPV6));
> -
> -        if (ps_addr->ipv6_addrs[j].plen == 128
> -            || !ipv6_addr_is_host_zero(&ps_addr->ipv6_addrs[j].addr,
> -                                        &ps_addr->ipv6_addrs[j].mask)) {
> -            match_set_ipv6_dst(m, &ps_addr->ipv6_addrs[j].addr);
> -        } else {
> -            match_set_ipv6_dst_masked(m, &ps_addr->ipv6_addrs[j].network,
> -                                      &ps_addr->ipv6_addrs[j].mask);
> -        }
> -
> +    const struct masked_ip6_addr *ip;
> +    VECTOR_FOR_EACH_PTR (ip6_addrs, ip) {
> +        match_set_ipv6_dst_masked(m, &ip->addr, &ip->mask);
>          ofctrl_add_flow(flow_table, OFTABLE_CHK_OUT_PORT_SEC, 95,
>                          pb->header_.uuid.parts[0], m, ofpacts,
>                          &pb->header_.uuid);
>      }
>  
>      struct in6_addr lla;
> -    in6_generate_lla(ps_addr->ea, &lla);
> +    in6_generate_lla(mac, &lla);
> +    unsigned int plen = 128 - 48 + eth_addr_get_prefix_len(mask);
> +    struct in6_addr lla_mask = ipv6_create_mask(plen);
>  
> -    reset_match_for_port_sec_flows(pb, MFF_LOG_OUTPORT, m);
> -    match_set_dl_dst(m, ps_addr->ea);
> -    match_set_dl_type(m, htons(ETH_TYPE_IPV6));
> -    match_set_ipv6_dst(m, &lla);
> +    match_set_ipv6_dst_masked(m, &lla, &lla_mask);
>      ofctrl_add_flow(flow_table, OFTABLE_CHK_OUT_PORT_SEC, 95,
>                      pb->header_.uuid.parts[0], m, ofpacts,
>                      &pb->header_.uuid);
>  
> -    struct in6_addr ip6, mask;
> -    char *err = ipv6_parse_masked("ff00::/8", &ip6, &mask);
> +    struct in6_addr ip6, ip_mask;
> +    char *err = ipv6_parse_masked("ff00::/8", &ip6, &ip_mask);
>      ovs_assert(!err);
>  
> -    match_set_ipv6_dst_masked(m, &ip6, &mask);
> +    match_set_ipv6_dst_masked(m, &ip6, &ip_mask);
>      ofctrl_add_flow(flow_table, OFTABLE_CHK_OUT_PORT_SEC, 95,
>                      pb->header_.uuid.parts[0], m, ofpacts,
>                      &pb->header_.uuid);
>  }
>  
>  static void
> -consider_port_sec_flows(const struct sbrec_port_binding *pb,
> -                        struct ovn_desired_flow_table *flow_table)
> +build_port_sec_entry_flows(const struct sbrec_port_binding *pb,
> +                           const struct port_security_addresses *ps_addr,
> +                           struct match *m, struct ofpbuf *ofpacts,
> +                           struct ovn_desired_flow_table *flow_table)
>  {
> -    if (!pb->n_port_security) {
> -        return;
> +    const struct masked_eth_addr *maddr;
> +
> +    /* Input no-ip flows. */
> +    if (vector_is_empty(&ps_addr->ip4) && vector_is_empty(&ps_addr->ip6)) {
> +        build_in_port_sec_no_ip_flows(pb, ps_addr->phys_addr, eth_addr_exact,
> +                                      m, ofpacts, flow_table);
> +
> +        VECTOR_FOR_EACH_PTR (&ps_addr->vrrp4, maddr) {
> +            build_in_port_sec_no_ip_flows(pb, maddr->addr, maddr->mask,
> +                                          m, ofpacts, flow_table);
> +        }
> +
> +        VECTOR_FOR_EACH_PTR (&ps_addr->vrrp6, maddr) {
> +            build_in_port_sec_no_ip_flows(pb, maddr->addr, maddr->mask,
> +                                          m, ofpacts, flow_table);
> +        }
>      }
>  
> -    struct lport_addresses *ps_addrs;   /* Port security addresses. */
> -    size_t n_ps_addrs = 0;
> +    /* Input IPv4 flows. */
> +    if (!vector_is_empty(&ps_addr->ip4)) {
> +        build_in_port_sec_ip4_flows(pb, ps_addr->phys_addr, eth_addr_exact,
> +                                    &ps_addr->ip4, m, ofpacts, flow_table);
>  
> -    ps_addrs = xmalloc(sizeof *ps_addrs * pb->n_port_security);
> -    for (size_t i = 0; i < pb->n_port_security; i++) {
> -        if (!extract_lsp_addresses(pb->port_security[i],
> -                                    &ps_addrs[n_ps_addrs])) {
> -            static struct vlog_rate_limit rl
> -                = VLOG_RATE_LIMIT_INIT(1, 1);
> -            VLOG_WARN_RL(&rl, "invalid syntax '%s' in port "
> -                         "security. No MAC address found",
> -                         pb->port_security[i]);
> -            continue;
> +        VECTOR_FOR_EACH_PTR (&ps_addr->vrrp4, maddr) {
> +            build_in_port_sec_ip4_flows(pb, maddr->addr, maddr->mask,
> +                                        &ps_addr->ip4, m, ofpacts, 
> flow_table);
> +        }
> +    }
> +
> +    /* Input ARP flows. */
> +    if (!vector_is_empty(&ps_addr->ip4) || vector_is_empty(&ps_addr->ip6)) {
> +        build_in_port_sec_arp_flows(pb, ps_addr->phys_addr, &ps_addr->ip4,
> +                                    &ps_addr->vrrp4, m, ofpacts, flow_table);
> +    }
> +
> +

Nit: no need for the newline.

> +    /* Input Ipv6 flows. */
> +    if (!vector_is_empty(&ps_addr->ip6)) {
> +        build_in_port_sec_ip6_flows(pb, ps_addr->phys_addr, eth_addr_exact,
> +                                    &ps_addr->ip6, m, ofpacts, flow_table);
> +
> +        VECTOR_FOR_EACH_PTR (&ps_addr->vrrp6, maddr) {
> +            build_in_port_sec_ip6_flows(pb, maddr->addr, maddr->mask,
> +                                        &ps_addr->ip6, m, ofpacts, 
> flow_table);
> +        }
> +    }
> +
> +    /* Input ND flows. */
> +    build_in_port_sec_nd_flows(pb, ps_addr->phys_addr, &ps_addr->ip6,
> +                               &ps_addr->vrrp6, m, ofpacts, flow_table);
> +
> +    /* Output no-ip flows. */
> +    build_out_port_sec_no_ip_flows(pb, ps_addr->phys_addr, eth_addr_exact,
> +                                   m, ofpacts, flow_table);
> +
> +    VECTOR_FOR_EACH_PTR (&ps_addr->vrrp4, maddr) {
> +        build_out_port_sec_no_ip_flows(pb, maddr->addr, maddr->mask,
> +                                       m, ofpacts, flow_table);
> +    }
> +
> +    VECTOR_FOR_EACH_PTR (&ps_addr->vrrp6, maddr) {
> +        build_out_port_sec_no_ip_flows(pb, maddr->addr, maddr->mask,
> +                                       m, ofpacts, flow_table);
> +    }
> +
> +    /* Output IPv4 flows. */
> +    if (!vector_is_empty(&ps_addr->ip4) || !vector_is_empty(&ps_addr->ip6)) {
> +        build_out_port_sec_ip4_flows(pb, ps_addr->phys_addr, eth_addr_exact,
> +                                     &ps_addr->ip4, m, ofpacts, flow_table);
> +
> +        VECTOR_FOR_EACH_PTR (&ps_addr->vrrp4, maddr) {
> +            build_out_port_sec_ip4_flows(pb, maddr->addr, maddr->mask,
> +                                         &ps_addr->ip4, m, ofpacts,
> +                                         flow_table);
> +        }
> +    }
> +
> +    /* Output Ipv6 flows. */
> +    if (!vector_is_empty(&ps_addr->ip4) || !vector_is_empty(&ps_addr->ip6)) {
> +        build_out_port_sec_ip6_flows(pb, ps_addr->phys_addr, eth_addr_exact,
> +                                     &ps_addr->ip6, m, ofpacts, flow_table);
> +
> +        VECTOR_FOR_EACH_PTR (&ps_addr->vrrp6, maddr) {
> +            build_out_port_sec_ip6_flows(pb, maddr->addr, maddr->mask,
> +                                         &ps_addr->ip6, m, ofpacts,
> +                                         flow_table);
> +        }
> +    }
> +}
> +
> +static bool
> +port_security_addresses_parse_entry(const char *entry, const char *lsp,
> +                                    struct port_security_addresses *ps_addr)
> +{
> +    static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
> +
> +    bool vrrpv3 = !strncmp(entry, "VRRPv3", 6);
> +    int n = vrrpv3 ? 7 : 0;
> +
> +    if (!ovs_scan_len(entry, &n, ETH_ADDR_SCAN_FMT,
> +                      ETH_ADDR_SCAN_ARGS(ps_addr->phys_addr))) {
> +        VLOG_WARN_RL(&rl, "invalid syntax '%s' in port security for LSP %s: "
> +                     "No MAC address found", entry, lsp);
> +        return false;
> +    }
> +
> +    bool ok = true;

Maybe a newline here?

> +    /* Only MAC address is provided. */
> +    if (!entry[n]) {
> +        goto vrrp_check;
> +    }
> +
> +

Nit: one newline is enough.

> +    char *save_ptr = NULL;
> +    char *tokstr = xstrdup(entry + n);
> +    for (char *token = strtok_r(tokstr, " ", &save_ptr);
> +         token != NULL;
> +         token = strtok_r(NULL, " ", &save_ptr)) {
> +        struct eth_addr mac;
> +        struct in6_addr ip;
> +        unsigned int plen;
> +
> +        if (vrrpv3 && eth_addr_parse_masked(token, &mac, &plen)) {
> +            if (!port_security_addresses_add_vrrp_mac(ps_addr, mac, plen)) {
> +                VLOG_WARN_RL(&rl, "invalid syntax '%s' in port security for"
> +                             " LSP %s: Invalid VRRPv3 MAC", token, lsp);
> +                ok = false;
> +                break;
> +            }
> +        } else if (ip46_parse_cidr(token, &ip, &plen)) {
> +            if (!port_security_addresses_add_ip(ps_addr, ip, plen)) {
> +                VLOG_WARN_RL(&rl, "invalid syntax '%s' in port security for"
> +                             " LSP %s: Invalid IP", token, lsp);
> +                ok = false;
> +                break;
> +            }
> +        } else {
> +            VLOG_WARN_RL(&rl, "invalid syntax '%s' in port security for"
> +                         " LSP %s: Invalid IP or MAC", token, lsp);
> +            ok = false;
> +            break;
>          }
> -        n_ps_addrs++;
>      }
>  
> -    if (!n_ps_addrs) {
> -        free(ps_addrs);
> +    free(tokstr);
> +
> +vrrp_check:
> +    if (vrrpv3 && vector_is_empty(&ps_addr->vrrp4) &&
> +        vector_is_empty(&ps_addr->vrrp6)) {
> +        vector_push(&ps_addr->vrrp4, &maddr_any_vrrp4);
> +        vector_push(&ps_addr->vrrp6, &maddr_any_vrrp6);
> +    }
> +
> +    return ok;
> +}
> +
> +static void
> +consider_port_sec_flows(const struct sbrec_port_binding *pb,
> +                        struct ovn_desired_flow_table *flow_table)
> +{
> +    if (!pb->n_port_security) {
>          return;
>      }
>  
> @@ -3037,48 +3255,37 @@ consider_port_sec_flows(const struct 
> sbrec_port_binding *pb,
>      uint64_t stub[1024 / 8];
>      struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(stub);
>  
> -    build_in_port_sec_default_flows(pb, &match, &ofpacts, flow_table);
> -
> -    for (size_t i = 0; i < n_ps_addrs; i++) {
> -        build_in_port_sec_no_ip_flows(pb, &ps_addrs[i], &match, &ofpacts,
> -                                      flow_table);
> -        build_in_port_sec_ip4_flows(pb, &ps_addrs[i], &match, &ofpacts,
> -                                    flow_table);
> -        build_in_port_sec_arp_flows(pb, &ps_addrs[i], &match, &ofpacts,
> -                                    flow_table);
> -        build_in_port_sec_ip6_flows(pb, &ps_addrs[i], &match, &ofpacts,
> -                                    flow_table);
> -        build_in_port_sec_nd_flows(pb, &ps_addrs[i], &match, &ofpacts,
> -                                   flow_table);
> -    }
> +    bool flows_installed = false;
> +    struct port_security_addresses ps_addr = (struct 
> port_security_addresses) {
> +        .phys_addr = eth_addr_zero,
> +        .vrrp4 = VECTOR_EMPTY_INITIALIZER(struct masked_eth_addr),
> +        .vrrp6 = VECTOR_EMPTY_INITIALIZER(struct masked_eth_addr),
> +        .ip4 = VECTOR_EMPTY_INITIALIZER(struct masked_ip4_addr),
> +        .ip6 = VECTOR_EMPTY_INITIALIZER(struct masked_ip6_addr),
> +    };

Nit: I'd add port_security_addresses_init()/clear()/destroy() helpers.
But I won't insist. :)

>  
> -    /* Out port security. */
> +    for (size_t i = 0; i < pb->n_port_security; i++) {
> +        if (port_security_addresses_parse_entry(pb->port_security[i],
> +                                                pb->logical_port, &ps_addr)) 
> {
> +            build_port_sec_entry_flows(pb, &ps_addr, &match,
> +                                       &ofpacts, flow_table);
> +            flows_installed = true;
> +        }
>  
> -    /* Add the below logical flow equivalent OF rules in 'out_port_sec_nd'
> -     * table.
> -     * priority: 80
> -     * match - "outport == pb->logical_port"
> -     * action - "port_sec_failed = 1;"
> -     * descrption: "Drop all traffic"
> -     */
> -    reset_match_for_port_sec_flows(pb, MFF_LOG_OUTPORT, &match);
> -    build_port_sec_deny_action(&ofpacts);
> -    ofctrl_add_flow(flow_table, OFTABLE_CHK_OUT_PORT_SEC, 80,
> -                    pb->header_.uuid.parts[0], &match, &ofpacts,
> -                    &pb->header_.uuid);
> +        vector_clear(&ps_addr.vrrp4);
> +        vector_clear(&ps_addr.vrrp6);
> +        vector_clear(&ps_addr.ip4);
> +        vector_clear(&ps_addr.ip6);
> +    }
>  
> -    for (size_t i = 0; i < n_ps_addrs; i++) {
> -        build_out_port_sec_no_ip_flows(pb, &ps_addrs[i], &match, &ofpacts,
> -                                       flow_table);
> -        build_out_port_sec_ip4_flows(pb, &ps_addrs[i], &match, &ofpacts,
> -                                       flow_table);
> -        build_out_port_sec_ip6_flows(pb, &ps_addrs[i], &match, &ofpacts,
> -                                       flow_table);
> +    if (flows_installed) {
> +        build_in_port_sec_default_flows(pb, &match, &ofpacts, flow_table);
> +        build_out_port_sec_default_flows(pb, &match, &ofpacts, flow_table);
>      }
>  
>      ofpbuf_uninit(&ofpacts);
> -    for (size_t i = 0; i < n_ps_addrs; i++) {
> -        destroy_lport_addresses(&ps_addrs[i]);
> -    }
> -    free(ps_addrs);
> +    vector_destroy(&ps_addr.vrrp4);
> +    vector_destroy(&ps_addr.vrrp6);
> +    vector_destroy(&ps_addr.ip4);
> +    vector_destroy(&ps_addr.ip6);
>  }
> diff --git a/ovn-nb.xml b/ovn-nb.xml
> index e9ca27413..a0a465be4 100644
> --- a/ovn-nb.xml
> +++ b/ovn-nb.xml
> @@ -2057,6 +2057,15 @@
>            addresses within an element may be space or comma separated.
>          </p>
>  
> +        <p>
> +          There is also special prefix "VRRPv3" that allows specification of

Nit: "This also supports the special prefix ..."

> +          single physical MAC and multiple VRRPv3 MAC addresses. The format
> +          allows the same definition of multiple IP addresses associated with

Nit: "same" sounds weird here.  Maybe "As for non VRRPv3 entries,
multiple IP addresses can be associated with the specified MACs"?

> +          the MACs specified. "VRRPv3" without single physical MAC translates
> +          allowing traffic for the whole "VRRPv3" range of MACs. See more in
> +          the examples.
> +        </p>
> +
>          <p>
>            This column is provided as a convenience to cloud management 
> systems,
>            but all of the features that it implements can be implemented as 
> ACLs
> @@ -2102,6 +2111,30 @@
>              255.255.255.255, and any address in 224.0.0.0/4.  The host may 
> not
>              send or receive any IPv6 (including IPv6 Neighbor Discovery) 
> traffic.
>            </dd>
> +
> +          <dt><code>"VRRPv3 &lt;PHYSICAL_MAC&gt;"</code></dt>
> +          <dd>
> +            The host may send traffic from and receive traffic to the
> +            specified physical MAC addresses, and to all VRRPv3 MAC 
> addresses.

I'd specify the VRRPv3 MAC formats here explicitly, i.e.,
00-00-5E-00-01-XX and 00-00-5E-00-02-XX.

> +            This also affects the permutations of inner MAC for ARP/ND. The

"the permutations" doesn't sound explicit enough to me.  I'd just skip
it and only leave the sentence below, I think.

> +            ARP/ND can be sent with physical MAC as a source and the inner
> +            SHA/TLL/SLL can be the physical MAC or any VRRPv3 MAC.
> +          </dd>
> +
> +          <dt><code>"VRRPv3 &lt;PHYSICAL_MAC&gt;
> +                    &lt;VRRPV3_MACv4_1&gt;/[&lt;MASK1&gt;]
> +                    &lt;VRRPV3_MACv4_N&gt;
> +                    &lt;VRRPV3_MACv6_1&gt;/[&lt;MASK2&gt;]
> +                    &lt;VRRPV3_MACv6_N&gt;"</code></dt>
> +          <dd>
> +            The host may send traffic from and receive traffic to the
> +            specified physical MAC addresses, and to all VRRPv3 MAC addresses
> +            specified in the option. Also note that the MAC addresses can
> +            be provided with a mask between /40 and /48 prefix.
> +            This also affects the permutations of inner MAC for ARP/ND. The

Same here.

> +            ARP/ND can be sent with physical MAC as a source and the inner
> +            SHA/TLL/SLL can be the physical MAC or provided VRRPv3 MAC.
> +          </dd>
>          </dl>
>        </column>
>      </group>
> diff --git a/tests/ovn.at b/tests/ovn.at
> index 8cb0e0a6f..d6bf965a4 100644
> --- a/tests/ovn.at
> +++ b/tests/ovn.at
> @@ -44243,3 +44243,754 @@ 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 - VRRPv3 ARP/ND])
> +AT_SKIP_IF([test $HAVE_SCAPY = no])
> +ovn_start
> +net_add n1
> +sim_add hv1
> +as hv1
> +check ovs-vsctl add-br br-phys
> +ovn_attach n1 br-phys 192.168.0.1
> +
> +check ovn-nbctl ls-add ls \
> +    -- set logical_switch ls other-config:requested-tnl-key=1
> +
> +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" \
> +    -- set logical_switch_port lsp1 options:requested-tnl-key=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" \
> +    -- set logical_switch_port lsp2 options:requested-tnl-key=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')
> +    ")
> +    check as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
> +
> +    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')
> +    ")
> +    check as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
> +
> +    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') /
> +            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:00:00:01', src='00:00:00:00:10:01') /
> +        IPv6(src='fd10::1', dst='ff02::1:ff00:2') /
> +        ICMPv6ND_NS(tgt='fd10::2') /
> +        ICMPv6NDOptSrcLLAddr(lladdr='00:00:5e:00:02:05')
> +    ")
> +    check as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
> +
> +    packet=$(fmt_pkt "
> +        Ether(dst='33:33:ff:00:00:01', src='00:00:00:00:10:01') /
> +        IPv6(src='fd10::1', dst='ff02::1:ff00:1') /
> +        ICMPv6ND_NA(tgt='fd10::1') /
> +        ICMPv6NDOptDstLLAddr(lladdr='00:00:5e:00:02:05')
> +    ")
> +    check as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
> +
> +    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])
> +
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [1])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC_ND | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [1])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_OUT_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [1])
> +
> +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])
> +
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=80,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=95,arp,reg14=0x1,metadata=0x1 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC_ND | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, priority=80,arp,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=135 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=136 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_sha=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_OUT_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_OUT_PORT_SEC, priority=80,reg15=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0->NXM_NX_REG10[[12]]
> +])
> +
> +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])
> +
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=80,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=131,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=135,icmp_code=0
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=143,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ip,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_src=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=fd10::1
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=fe80::200:ff:fe00:1001
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,udp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_src=0.0.0.0,nw_dst=255.255.255.255,tp_src=68,tp_dst=67
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=95,arp,reg14=0x1,metadata=0x1 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC_ND | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, priority=80,arp,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=135 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=136 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_spa=192.168.10.1,arp_sha=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_OUT_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_OUT_PORT_SEC, priority=80,reg15=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=224.0.0.0/4
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=255.255.255.255
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=fd10::1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=fe80::200:ff:fe00:1001
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=ff00::/8
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +
> +
> +AS_BOX([With MAC only port security, VRRPv3=any])
> +reset_pcap_and_expected
> +check ovn-nbctl --wait=hv lsp-set-port-security lsp1 "VRRPv3 
> 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])
> +
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=80,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:01:00/ff:ff:ff:ff:ff:00 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:00/ff:ff:ff:ff:ff:00 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=95,arp,reg14=0x1,metadata=0x1 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC_ND | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, priority=80,arp,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=135 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=136 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_sha=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_sha=00:00:5e:00:01:00/ff:ff:ff:ff:ff:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:5e:00:02:00/ff:ff:ff:ff:ff:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_tll=00:00:5e:00:02:00/ff:ff:ff:ff:ff:00
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_OUT_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_OUT_PORT_SEC, priority=80,reg15=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:00/ff:ff:ff:ff:ff:00 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:00/ff:ff:ff:ff:ff:00 
> actions=load:0->NXM_NX_REG10[[12]]
> +])
> +
> +AS_BOX([With MAC + IP port security, VRRPv3=any])
> +reset_pcap_and_expected
> +check ovn-nbctl --wait=hv lsp-set-port-security lsp1 "VRRPv3 
> 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])
> +
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=80,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=131,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=135,icmp_code=0
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=143,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:00/ff:ff:ff:ff:ff:00,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=131,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:00/ff:ff:ff:ff:ff:00,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=135,icmp_code=0
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:00/ff:ff:ff:ff:ff:00,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=143,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ip,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_src=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ip,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:01:00/ff:ff:ff:ff:ff:00,nw_src=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=fd10::1
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=fe80::200:ff:fe00:1001
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:00/ff:ff:ff:ff:ff:00,ipv6_src=fd10::1
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:00/ff:ff:ff:ff:ff:00,ipv6_src=fe80::200:5eff:fe00:200/120
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,udp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_src=0.0.0.0,nw_dst=255.255.255.255,tp_src=68,tp_dst=67
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,udp,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:01:00/ff:ff:ff:ff:ff:00,nw_src=0.0.0.0,nw_dst=255.255.255.255,tp_src=68,tp_dst=67
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=95,arp,reg14=0x1,metadata=0x1 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC_ND | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, priority=80,arp,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=135 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=136 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_spa=192.168.10.1,arp_sha=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_spa=192.168.10.1,arp_sha=00:00:5e:00:01:00/ff:ff:ff:ff:ff:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:5e:00:02:00/ff:ff:ff:ff:ff:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:5e:00:02:00/ff:ff:ff:ff:ff:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:5e:00:02:00/ff:ff:ff:ff:ff:00
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_OUT_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_OUT_PORT_SEC, priority=80,reg15=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:00/ff:ff:ff:ff:ff:00 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:00/ff:ff:ff:ff:ff:00 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:00/ff:ff:ff:ff:ff:00
>  actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:00/ff:ff:ff:ff:ff:00
>  actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=224.0.0.0/4
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=255.255.255.255
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:00/ff:ff:ff:ff:ff:00,nw_dst=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:00/ff:ff:ff:ff:ff:00,nw_dst=224.0.0.0/4
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:00/ff:ff:ff:ff:ff:00,nw_dst=255.255.255.255
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=fd10::1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=fe80::200:ff:fe00:1001
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=ff00::/8
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:00/ff:ff:ff:ff:ff:00,ipv6_dst=fd10::1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:00/ff:ff:ff:ff:ff:00,ipv6_dst=fe80::200:5eff:fe00:200/120
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:00/ff:ff:ff:ff:ff:00,ipv6_dst=ff00::/8
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +
> +AS_BOX([With MAC only port security, VRRPv3 valid IPv4])
> +reset_pcap_and_expected
> +check ovn-nbctl --wait=hv lsp-set-port-security lsp1 "VRRPv3 
> 00:00:00:00:10:01 00:00:5e:00:01:05"
> +
> +test_arp no
> +test_nd yes
> +
> +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
> +OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [vif2.expected])
> +
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=80,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:01:05 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=95,arp,reg14=0x1,metadata=0x1 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC_ND | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, priority=80,arp,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=135 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=136 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_sha=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_sha=00:00:5e:00:01:05
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_OUT_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_OUT_PORT_SEC, priority=80,reg15=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:05 
> actions=load:0->NXM_NX_REG10[[12]]
> +])
> +
> +AS_BOX([With MAC + IP port security, VRRPv3 valid IPv4])
> +reset_pcap_and_expected
> +check ovn-nbctl --wait=hv lsp-set-port-security lsp1 "VRRPv3 
> 00:00:00:00:10:01 00:00:5e:00:01:05 192.168.10.1 fd10::1"
> +
> +test_arp no
> +test_nd yes
> +
> +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
> +OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [vif2.expected])
> +
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=80,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=131,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=135,icmp_code=0
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=143,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ip,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_src=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ip,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:01:05,nw_src=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=fd10::1
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=fe80::200:ff:fe00:1001
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,udp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_src=0.0.0.0,nw_dst=255.255.255.255,tp_src=68,tp_dst=67
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,udp,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:01:05,nw_src=0.0.0.0,nw_dst=255.255.255.255,tp_src=68,tp_dst=67
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=95,arp,reg14=0x1,metadata=0x1 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC_ND | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, priority=80,arp,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=135 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=136 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_spa=192.168.10.1,arp_sha=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_spa=192.168.10.1,arp_sha=00:00:5e:00:01:05
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_OUT_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_OUT_PORT_SEC, priority=80,reg15=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:05 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:05 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=224.0.0.0/4
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=255.255.255.255
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:05,nw_dst=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:05,nw_dst=224.0.0.0/4
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:05,nw_dst=255.255.255.255
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=fd10::1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=fe80::200:ff:fe00:1001
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=ff00::/8
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +
> +AS_BOX([With MAC only port security, VRRPv3 valid IPv6])
> +reset_pcap_and_expected
> +check ovn-nbctl --wait=hv lsp-set-port-security lsp1 "VRRPv3 
> 00:00:00:00:10:01 00:00:5e:00:02:05"
> +
> +test_arp yes
> +test_nd no
> +
> +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
> +OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [vif2.expected])
> +
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=80,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:05 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=95,arp,reg14=0x1,metadata=0x1 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC_ND | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, priority=80,arp,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=135 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=136 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_sha=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:5e:00:02:05
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_tll=00:00:5e:00:02:05
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_OUT_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_OUT_PORT_SEC, priority=80,reg15=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:05 
> actions=load:0->NXM_NX_REG10[[12]]
> +])
> +
> +AS_BOX([With MAC + IP port security, VRRPv3 valid IPv6])
> +reset_pcap_and_expected
> +check ovn-nbctl --wait=hv lsp-set-port-security lsp1 "VRRPv3 
> 00:00:00:00:10:01 00:00:5e:00:02:05 192.168.10.1 fd10::1"
> +
> +test_arp yes
> +test_nd no
> +
> +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
> +OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [vif2.expected])
> +
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=80,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=131,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=135,icmp_code=0
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=143,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:05,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=131,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:05,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=135,icmp_code=0
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:05,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=143,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ip,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_src=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=fd10::1
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=fe80::200:ff:fe00:1001
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:05,ipv6_src=fd10::1
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:05,ipv6_src=fe80::200:5eff:fe00:205
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,udp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_src=0.0.0.0,nw_dst=255.255.255.255,tp_src=68,tp_dst=67
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=95,arp,reg14=0x1,metadata=0x1 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC_ND | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, priority=80,arp,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=135 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=136 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_spa=192.168.10.1,arp_sha=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:5e:00:02:05
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:5e:00:02:05
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:5e:00:02:05
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_OUT_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_OUT_PORT_SEC, priority=80,reg15=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:05 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:05 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=224.0.0.0/4
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=255.255.255.255
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=fd10::1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=fe80::200:ff:fe00:1001
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=ff00::/8
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:05,ipv6_dst=fd10::1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:05,ipv6_dst=fe80::200:5eff:fe00:205
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:05,ipv6_dst=ff00::/8
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +
> +AS_BOX([With MAC only port security, VRRPv3 valid IPv4 + IPv6])
> +reset_pcap_and_expected
> +check ovn-nbctl --wait=hv lsp-set-port-security lsp1 "VRRPv3 
> 00:00:00:00:10:01 00:00:5e:00:01:05 00:00:5e:00:02:05"
> +
> +test_arp no
> +test_nd no
> +
> +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
> +OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [vif2.expected])
> +
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=80,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:01:05 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:05 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=95,arp,reg14=0x1,metadata=0x1 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC_ND | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, priority=80,arp,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=135 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=136 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_sha=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_sha=00:00:5e:00:01:05
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:5e:00:02:05
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_tll=00:00:5e:00:02:05
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_OUT_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_OUT_PORT_SEC, priority=80,reg15=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:05 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:05 
> actions=load:0->NXM_NX_REG10[[12]]
> +])
> +
> +AS_BOX([With MAC + IP port security, VRRPv3 valid IPv4 + IPv6])
> +reset_pcap_and_expected
> +check ovn-nbctl --wait=hv lsp-set-port-security lsp1 "VRRPv3 
> 00:00:00:00:10:01 00:00:5e:00:01:05 00:00:5e:00:02:05 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])
> +
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=80,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=131,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=135,icmp_code=0
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=143,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:05,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=131,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:05,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=135,icmp_code=0
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:05,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=143,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ip,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_src=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ip,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:01:05,nw_src=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=fd10::1
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=fe80::200:ff:fe00:1001
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:05,ipv6_src=fd10::1
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:05,ipv6_src=fe80::200:5eff:fe00:205
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,udp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_src=0.0.0.0,nw_dst=255.255.255.255,tp_src=68,tp_dst=67
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,udp,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:01:05,nw_src=0.0.0.0,nw_dst=255.255.255.255,tp_src=68,tp_dst=67
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=95,arp,reg14=0x1,metadata=0x1 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC_ND | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, priority=80,arp,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=135 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=136 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_spa=192.168.10.1,arp_sha=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_spa=192.168.10.1,arp_sha=00:00:5e:00:01:05
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:5e:00:02:05
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:5e:00:02:05
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:5e:00:02:05
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_OUT_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_OUT_PORT_SEC, priority=80,reg15=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:05 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:05 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:05 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:05 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=224.0.0.0/4
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=255.255.255.255
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:05,nw_dst=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:05,nw_dst=224.0.0.0/4
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:05,nw_dst=255.255.255.255
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=fd10::1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=fe80::200:ff:fe00:1001
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=ff00::/8
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:05,ipv6_dst=fd10::1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:05,ipv6_dst=fe80::200:5eff:fe00:205
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:05,ipv6_dst=ff00::/8
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +
> +AS_BOX([With MAC only port security, VRRPv3 masked IPv4 + IPv6])
> +reset_pcap_and_expected
> +check ovn-nbctl --wait=hv lsp-set-port-security lsp1 "VRRPv3 
> 00:00:00:00:10:01 00:00:5e:00:01:00/45 00:00:5e:00:02:00/45"
> +
> +test_arp no
> +test_nd no
> +
> +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
> +OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [vif2.expected])
> +
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=80,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:01:00/ff:ff:ff:ff:ff:f8 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:00/ff:ff:ff:ff:ff:f8 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=95,arp,reg14=0x1,metadata=0x1 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC_ND | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, priority=80,arp,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=135 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=136 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_sha=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_sha=00:00:5e:00:01:00/ff:ff:ff:ff:ff:f8
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:5e:00:02:00/ff:ff:ff:ff:ff:f8
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_tll=00:00:5e:00:02:00/ff:ff:ff:ff:ff:f8
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_OUT_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_OUT_PORT_SEC, priority=80,reg15=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:00/ff:ff:ff:ff:ff:f8 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:00/ff:ff:ff:ff:ff:f8 
> actions=load:0->NXM_NX_REG10[[12]]
> +])
> +
> +AS_BOX([With MAC + IP port security, VRRPv3 masked IPv4 + IPv6])
> +reset_pcap_and_expected
> +check ovn-nbctl --wait=hv lsp-set-port-security lsp1 "VRRPv3 
> 00:00:00:00:10:01 00:00:5e:00:01:00/45 00:00:5e:00:02:00/45 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])
> +
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=80,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=131,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=135,icmp_code=0
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=143,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:00/ff:ff:ff:ff:ff:f8,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=131,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:00/ff:ff:ff:ff:ff:f8,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=135,icmp_code=0
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:00/ff:ff:ff:ff:ff:f8,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=143,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ip,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_src=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ip,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:01:00/ff:ff:ff:ff:ff:f8,nw_src=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=fd10::1
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=fe80::200:ff:fe00:1001
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:00/ff:ff:ff:ff:ff:f8,ipv6_src=fd10::1
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:00/ff:ff:ff:ff:ff:f8,ipv6_src=fe80::200:5eff:fe00:200/125
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,udp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_src=0.0.0.0,nw_dst=255.255.255.255,tp_src=68,tp_dst=67
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,udp,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:01:00/ff:ff:ff:ff:ff:f8,nw_src=0.0.0.0,nw_dst=255.255.255.255,tp_src=68,tp_dst=67
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=95,arp,reg14=0x1,metadata=0x1 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC_ND | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, priority=80,arp,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=135 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=136 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_spa=192.168.10.1,arp_sha=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_spa=192.168.10.1,arp_sha=00:00:5e:00:01:00/ff:ff:ff:ff:ff:f8
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:5e:00:02:00/ff:ff:ff:ff:ff:f8
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:5e:00:02:00/ff:ff:ff:ff:ff:f8
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:5e:00:02:00/ff:ff:ff:ff:ff:f8
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_OUT_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_OUT_PORT_SEC, priority=80,reg15=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:00/ff:ff:ff:ff:ff:f8 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:00/ff:ff:ff:ff:ff:f8 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:00/ff:ff:ff:ff:ff:f8
>  actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:00/ff:ff:ff:ff:ff:f8
>  actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=224.0.0.0/4
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=255.255.255.255
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:00/ff:ff:ff:ff:ff:f8,nw_dst=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:00/ff:ff:ff:ff:ff:f8,nw_dst=224.0.0.0/4
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:00/ff:ff:ff:ff:ff:f8,nw_dst=255.255.255.255
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=fd10::1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=fe80::200:ff:fe00:1001
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=ff00::/8
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:00/ff:ff:ff:ff:ff:f8,ipv6_dst=fd10::1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:00/ff:ff:ff:ff:ff:f8,ipv6_dst=fe80::200:5eff:fe00:200/125
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:00/ff:ff:ff:ff:ff:f8,ipv6_dst=ff00::/8
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +
> +AS_BOX([With MAC + IP port security, VRRPv3 valid but different IPv4 + IPv6])
> +reset_pcap_and_expected
> +check ovn-nbctl --wait=hv lsp-set-port-security lsp1 "VRRPv3 
> 00:00:00:00:10:01 00:00:5e:00:01:01 00:00:5e:00:02: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])
> +
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=80,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=131,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=135,icmp_code=0
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=143,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=131,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=135,icmp_code=0
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:01,ipv6_src=::,ipv6_dst=ff02::/16,icmp_type=143,icmp_code=0
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ip,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_src=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ip,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:01:01,nw_src=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=fd10::1
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,ipv6_src=fe80::200:ff:fe00:1001
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:01,ipv6_src=fd10::1
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,ipv6,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:02:01,ipv6_src=fe80::200:5eff:fe00:201
>  actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,udp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_src=0.0.0.0,nw_dst=255.255.255.255,tp_src=68,tp_dst=67
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, 
> priority=90,udp,reg14=0x1,metadata=0x1,dl_src=00:00:5e:00:01:01,nw_src=0.0.0.0,nw_dst=255.255.255.255,tp_src=68,tp_dst=67
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC, priority=95,arp,reg14=0x1,metadata=0x1 
> actions=resubmit(,OFTABLE_CHK_IN_PORT_SEC_ND)
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_IN_PORT_SEC_ND | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, priority=80,arp,reg14=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=135 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=80,icmp6,reg14=0x1,metadata=0x1,nw_ttl=255,icmp_type=136 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_spa=192.168.10.1,arp_sha=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,arp,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,arp_spa=192.168.10.1,arp_sha=00:00:5e:00:01:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=00:00:5e:00:02:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fd10::1,nd_tll=00:00:5e:00:02:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:00:00:00:00
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:00:00:10:01
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_IN_PORT_SEC_ND, 
> priority=90,icmp6,reg14=0x1,metadata=0x1,dl_src=00:00:00:00:10:01,nw_ttl=255,icmp_type=136,icmp_code=0,nd_target=fe80::200:ff:fe00:1001,nd_tll=00:00:5e:00:02:01
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +AT_CHECK([ovs-ofctl dump-flows br-int table=OFTABLE_CHK_OUT_PORT_SEC | 
> ofctl_strip_all | sort | grep -v NXST_FLOW], [0], [dnl
> + table=OFTABLE_CHK_OUT_PORT_SEC, priority=80,reg15=0x1,metadata=0x1 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:01 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=85,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:01 
> actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:01 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=90,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:01 
> actions=load:0x1->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=224.0.0.0/4
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,nw_dst=255.255.255.255
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:01,nw_dst=192.168.10.1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:01,nw_dst=224.0.0.0/4
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ip,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:01:01,nw_dst=255.255.255.255
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=fd10::1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=fe80::200:ff:fe00:1001
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:00:00:10:01,ipv6_dst=ff00::/8
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:01,ipv6_dst=fd10::1
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:01,ipv6_dst=fe80::200:5eff:fe00:201
>  actions=load:0->NXM_NX_REG10[[12]]
> + table=OFTABLE_CHK_OUT_PORT_SEC, 
> priority=95,ipv6,reg15=0x1,metadata=0x1,dl_dst=00:00:5e:00:02:01,ipv6_dst=ff00::/8
>  actions=load:0->NXM_NX_REG10[[12]]
> +])
> +
> +OVN_CLEANUP([hv1
> +/Invalid VRRPv3 MAC address specified/d])

I think there's no invalid config in the test above so we never generate
this log.  Should we add two small negative tests, maybe for
00:00:5E:00:01:00/48 and 00:00:5E:00:02:00/48 ?

> +AT_CLEANUP
> +])

Thanks,
Dumitru

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to