On 1/29/26 5:39 PM, Anton Arefiev wrote:
> From: Vasyl Saienko <[email protected]>
> 

Hi Anton, Vasyl,

Sorry for the long delay in reviewing this.

> Populate Ucast_Macs_Remote table from MAC addresses learned via
> FDB table. This will allow communication betwen different

Typo: betwen

> switches plugged to same logical network via VTEP.
> 
> Signed-Off-By: Vasyl Saienko <[email protected]>
> ---
>  controller-vtep/vtep.c       | 119 ++++++++++++++++++++++++++++++++++-
>  tests/ovn-controller-vtep.at |  28 +++++++++
>  2 files changed, 145 insertions(+), 2 deletions(-)
> 
> diff --git a/controller-vtep/vtep.c b/controller-vtep/vtep.c
> index ccdd4e549..cfe1456b1 100644
> --- a/controller-vtep/vtep.c
> +++ b/controller-vtep/vtep.c
> @@ -275,7 +275,9 @@ vtep_lswitch_run(struct shash *vtep_pbs, struct sset 
> *vtep_pswitches,
>  static void
>  vtep_macs_run(struct ovsdb_idl_txn *vtep_idl_txn, struct shash 
> *ucast_macs_rmts,
>                struct shash *mcast_macs_rmts, struct shash *physical_locators,
> -              struct shash *vtep_lswitches, struct shash *non_vtep_pbs)
> +              struct shash *vtep_lswitches, struct shash *non_vtep_pbs,
> +              struct sset *vtep_pswitches, struct shash *vtep_pbs,
> +              struct shash *lp_fdbs)
>  {
>      struct shash_node *node;
>      struct hmap ls_map;
> @@ -451,6 +453,117 @@ vtep_macs_run(struct ovsdb_idl_txn *vtep_idl_txn, 
> struct shash *ucast_macs_rmts,
>          }
>      }
>  
> +    /* Handle dynamically leart MACs from remote VTEPs registered in

Typo: leart

> +     * FDB table. */
> +    SHASH_FOR_EACH (node, vtep_pbs) {
> +        const struct sbrec_port_binding *port_binding_rec = node->data;
> +
> +        const struct sbrec_chassis *chassis_rec = port_binding_rec->chassis;
> +        if (!chassis_rec) {
> +            continue;
> +        }
> +
> +        const char *pswitch_name = smap_get(&port_binding_rec->options,
> +                                            "vtep-physical-switch");
> +        /* Ignore macs learned by ourselfs */

Typo: ourselfs

> +        if (sset_find(vtep_pswitches, pswitch_name)) {

I'd add a "if (!pswitch_name || .." here in case the SB has been
mangled, to prevent crashing in sset_find if pswitch_name is NULL.

> +            continue;
> +        }
> +        int64_t tnl_key = port_binding_rec->datapath->tunnel_key;
> +
> +        struct ls_hash_node *ls_node;
> +        HMAP_FOR_EACH_WITH_HASH (ls_node, hmap_node,
> +                                 hash_uint64((uint64_t) tnl_key),
> +                                 &ls_map) {
> +            if (ls_node->vtep_ls->tunnel_key[0] == tnl_key) {
> +                break;
> +            }
> +        }
> +        /* If 'ls_node' is NULL, that means no vtep logical switch is
> +         * attached to the corresponding ovn logical datapath, so pass.
> +         */
> +        if (!ls_node) {
> +            continue;
> +        }
> +
> +        const char *chassis_ip = get_chassis_vtep_ip(chassis_rec);
> +        /* Unreachable chassis, continue. */
> +        if (!chassis_ip) {
> +            static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
> +            VLOG_INFO_RL(&rl, "VTEP tunnel encap on chassis (%s) not found",
> +                         chassis_rec->name);
> +            continue;
> +        }
> +
> +        const struct vteprec_physical_locator *pl =
> +            shash_find_data(physical_locators, chassis_ip);
> +        if (!pl) {
> +            pl = create_pl(vtep_idl_txn, chassis_ip);
> +            shash_add(physical_locators, chassis_ip, pl);
> +        }
> +
> +        const struct vteprec_physical_locator *ls_pl =
> +            shash_find_data(&ls_node->physical_locators, chassis_ip);
> +        if (!ls_pl) {
> +            struct vtep_rec_physical_locator_list_entry *ploc_entry =
> +                xmalloc(sizeof *ploc_entry);
> +            ploc_entry->vteprec_ploc = pl;
> +            ovs_list_push_back(&ls_node->locators_list,
> +                               &ploc_entry->locators_node);
> +            shash_add(&ls_node->physical_locators, chassis_ip, pl);
> +        }
> +
> +        char *fdb_dp_port_key =
> +            xasprintf("%"PRId64"_%"PRId64,
> +                      port_binding_rec->datapath->tunnel_key,
> +                      port_binding_rec->tunnel_key);
> +        struct lp_fdb_node_data *sbrec_lp_fdb =
> +            shash_find_data(lp_fdbs, fdb_dp_port_key);
> +        free(fdb_dp_port_key);
> +
> +        if (!sbrec_lp_fdb) {
> +            continue;
> +        }
> +
> +        struct shash_node *sbrec_fdb_node;
> +        SHASH_FOR_EACH (sbrec_fdb_node, &sbrec_lp_fdb->mac_fdbs) {
> +            const struct sbrec_fdb *fdb = sbrec_fdb_node->data;
> +
> +            const struct vteprec_ucast_macs_remote *umr;
> +            const struct sbrec_port_binding *conflict;
> +
> +            char *mac = fdb->mac;
> +
> +            /* Checks for duplicate MAC in the same vtep logical switch. */
> +            conflict = shash_find_data(&ls_node->added_macs, mac);
> +            if (conflict) {

We're missing a rl definition here.

> +                VLOG_WARN_RL("MAC address (%s) has already been known to be "
> +                             "on logical port (%s) in the same logical "
> +                             "datapath, so just ignore this logical port 
> (%s)",
> +                             mac, conflict->logical_port,
> +                             port_binding_rec->logical_port);
> +                continue;
> +            }
> +            shash_add(&ls_node->added_macs, mac, port_binding_rec);
> +
> +            char *mac_ip_tnlkey = xasprintf("%s_%s_%"PRId64, mac, chassis_ip,
> +                                            tnl_key);
> +            umr = shash_find_data(ucast_macs_rmts, mac_ip_tnlkey);
> +            /* If finds the 'umr' entry for the mac, ip, and tnl_key, deletes
> +             * the entry from shash so that it is not garbage collected.
> +             *
> +             * If not found, creates a new 'umr' entry. */
> +            if (umr && umr->logical_switch == ls_node->vtep_ls) {
> +                shash_find_and_delete(ucast_macs_rmts, mac_ip_tnlkey);
> +            } else {
> +                const struct vteprec_ucast_macs_remote *new_umr;
> +                new_umr = create_umr(vtep_idl_txn, mac, ls_node->vtep_ls);
> +                vteprec_ucast_macs_remote_set_locator(new_umr, pl);
> +            }
> +            free(mac_ip_tnlkey);
> +        }
> +    }
> +
>      /* Removes all remaining 'umr's, since they do not exist anymore. */
>      SHASH_FOR_EACH (node, ucast_macs_rmts) {
>          vteprec_ucast_macs_remote_delete(node->data);
> @@ -773,7 +886,9 @@ vtep_run(struct controller_vtep_ctx *ctx)
>      vtep_lswitch_run(&vtep_pbs, &vtep_pswitches, &vtep_lswitches);
>      vtep_macs_run(ctx->vtep_idl_txn, &ucast_macs_rmts,
>                    &mcast_macs_rmts, &physical_locators,
> -                  &vtep_lswitches, &non_vtep_pbs);
> +                  &vtep_lswitches, &non_vtep_pbs,
> +                  &vtep_pswitches, &vtep_pbs,
> +                  &lp_fdbs);
>      vtep_local_macs(ctx, &vtep_pbs, &vtep_pswitches, &vtep_lswitches,
>                      &lp_fdbs);
>  
> diff --git a/tests/ovn-controller-vtep.at b/tests/ovn-controller-vtep.at
> index 27be219bf..2d20886e9 100644
> --- a/tests/ovn-controller-vtep.at
> +++ b/tests/ovn-controller-vtep.at
> @@ -610,6 +610,34 @@ OVS_WAIT_UNTIL([test -n "`vtep-ctl list Ucast_Macs_Local 
> | grep aa:bb:cc:dd:ff:0
>  wait_row_count fdb 1 mac='"aa:bb:cc:dd:ff:01"'
>  wait_row_count fdb 1 mac='"aa:bb:cc:dd:ff:02"'
>  
> +# Switch context
> +as
> +
> +# Make sure we see

Maybe:

# Make sure we see correct remote MACs.

> +OVS_WAIT_UNTIL([test -n "`vtep-ctl list-remote-macs lswitch0 | grep 
> aa:bb:cc:dd:ff:01`"])
> +OVS_WAIT_UNTIL([test -z "`vtep-ctl list-remote-macs lswitch1 | grep 
> aa:bb:cc:dd:ff:01`"])
> +
> +OVS_WAIT_UNTIL([test -n "`vtep-ctl list-remote-macs lswitch1 | grep 
> aa:bb:cc:dd:ff:02`"])
> +OVS_WAIT_UNTIL([test -z "`vtep-ctl list-remote-macs lswitch0 | grep 
> aa:bb:cc:dd:ff:02`"])
> +

This can be simplified to:

OVS_WAIT_UNTIL([vtep-ctl list-remote-macs lswitch0 | grep -q
aa:bb:cc:dd:ff:01])
OVS_WAIT_WHILE([vtep-ctl list-remote-macs lswitch1 | grep -q
aa:bb:cc:dd:ff:01])

OVS_WAIT_UNTIL([vtep-ctl list-remote-macs lswitch1 | grep -q
aa:bb:cc:dd:ff:02])
OVS_WAIT_WHILE([vtep-ctl list-remote-macs lswitch0 | grep -q
aa:bb:cc:dd:ff:02])

> +# Switch context to br-vtep1
> +as br-vtep1
> +
> +# Remove local MACs
> +AT_CHECK([ovs-ofctl -O OpenFlow14 del-flows br-vtep1_vtep_ls1 
> "table=mac_learning_table,dl_dst=aa:bb:cc:dd:ff:01"])
> +AT_CHECK([ovs-ofctl -O OpenFlow14 del-flows br-vtep1_vtep_ls2 
> "table=mac_learning_table,dl_dst=aa:bb:cc:dd:ff:02"])
> +
> +# Switch context
> +as
> +
> +# Ensure remote MACs gone
> +OVS_WAIT_UNTIL([test -z "`vtep-ctl list-remote-macs lswitch0 | grep 
> aa:bb:cc:dd:ff:01`"])
> +OVS_WAIT_UNTIL([test -z "`vtep-ctl list-remote-macs lswitch1 | grep 
> aa:bb:cc:dd:ff:02`"])

Same here:
OVS_WAIT_WHILE([vtep-ctl list-remote-macs lswitch0 | grep -q
aa:bb:cc:dd:ff:01])
OVS_WAIT_WHILE([vtep-ctl list-remote-macs lswitch1 | grep -q
aa:bb:cc:dd:ff:02])

> +
> +# Check that MACs are removed from FDB table
> +wait_row_count fdb 0 mac='"aa:bb:cc:dd:ff:01"'
> +wait_row_count fdb 0 mac='"aa:bb:cc:dd:ff:02"'
> +
>  OVN_CONTROLLER_VTEP_STOP
>  AT_CLEANUP
>  

As most of these were minor things to fix, I took care of the changes
and applied this to main.

Regards,
Dumitru

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

Reply via email to