On 11/7/24 16:06, Lorenzo Bianconi wrote:
> On Nov 07, Dumitru Ceara wrote:
>> On 11/7/24 15:17, Lorenzo Bianconi wrote:
>>>> Hi Lorenzo,
>>>>
>>>> On 9/19/24 19:08, Lorenzo Bianconi wrote:
>>>>> Set the mac address column in the ECMP_Nexthop table updating
>>>>> sb MAC_Binding table. This is a preliminary patch to introduce the
>>>>> capability to flush stale ECMP CT entries.
>>>>>
>>>
>>> [...]
>>>>> +const struct sbrec_ecmp_nexthop *
>>>>> +ecmp_nexthop_lookup(struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
>>>>> +                    const char *nexthop)
>>>>
>>>> static?
>>>
>>> ack, I will fix it
>>>
>>>>
>>>>> +{
>>>>> +    struct sbrec_ecmp_nexthop *ecmp_nh =
>>>>> +            sbrec_ecmp_nexthop_index_init_row(sbrec_ecmp_by_nexthop);
>>>>> +    sbrec_ecmp_nexthop_set_nexthop(ecmp_nh, nexthop);
>>>>> +    const struct sbrec_ecmp_nexthop *retval =
>>>>> +            sbrec_ecmp_nexthop_index_find(sbrec_ecmp_by_nexthop, 
>>>>> ecmp_nh);
>>>>> +    sbrec_ecmp_nexthop_index_destroy_row(ecmp_nh);
>>>>> +
>>>>> +    return retval;
>>>>> +}
>>>>> +
>>>>>  static void
>>>>>  run_put_mac_binding(struct ovsdb_idl_txn *ovnsb_idl_txn,
>>>>>                      struct ovsdb_idl_index 
>>>>> *sbrec_datapath_binding_by_key,
>>>>>                      struct ovsdb_idl_index *sbrec_port_binding_by_key,
>>>>>                      struct ovsdb_idl_index 
>>>>> *sbrec_mac_binding_by_lport_ip,
>>>>> +                    struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
>>>>>                      const struct mac_binding *mb)
>>>>>  {
>>>>>      /* Convert logical datapath and logical port key into lport. */
>>>>> @@ -4930,8 +4951,13 @@ run_put_mac_binding(struct ovsdb_idl_txn 
>>>>> *ovnsb_idl_txn,
>>>>>      struct ds ip_s = DS_EMPTY_INITIALIZER;
>>>>>      ipv6_format_mapped(&mb->data.ip, &ip_s);
>>>>>      mac_binding_add_to_sb(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
>>>>> -                          pb->logical_port, pb->datapath, mb->data.mac,
>>>>> +                          pb->logical_port, pb->datapath, mac_string,
>>>>>                            ds_cstr(&ip_s), false);
>>>>> +    const struct sbrec_ecmp_nexthop *ecmp_nh =
>>>>> +        ecmp_nexthop_lookup(sbrec_ecmp_by_nexthop, ds_cstr(&ip_s));
>>>>> +    if (ecmp_nh) {
>>>>> +        sbrec_ecmp_nexthop_set_mac(ecmp_nh, mac_string);
>>>>> +    }
>>>>
>>>> Instead of doing the ecmp nexthop mac update here I'd do it inside
>>>> mac_binding_add_to_sb().  It would also cover the case when the next-hop
>>>> is an OVN logical router port.  And it would avoid duplicating the code
>>>> that builds the 'mac_string' string.
>>>
>>> ack, I will fix it.
>>>
>>>>
>>>>>      ds_destroy(&ip_s);
>>>>>  }
>>>>>  
>>>>> @@ -4941,7 +4967,8 @@ static void
>>>>>  run_put_mac_bindings(struct ovsdb_idl_txn *ovnsb_idl_txn,
>>>>>                       struct ovsdb_idl_index 
>>>>> *sbrec_datapath_binding_by_key,
>>>>>                       struct ovsdb_idl_index *sbrec_port_binding_by_key,
>>>>> -                     struct ovsdb_idl_index 
>>>>> *sbrec_mac_binding_by_lport_ip)
>>>>> +                     struct ovsdb_idl_index 
>>>>> *sbrec_mac_binding_by_lport_ip,
>>>>> +                     struct ovsdb_idl_index *sbrec_ecmp_by_nexthop)
>>>>>      OVS_REQUIRES(pinctrl_mutex)
>>>>>  {
>>>>>      if (!ovnsb_idl_txn) {
>>>>> @@ -4956,7 +4983,8 @@ run_put_mac_bindings(struct ovsdb_idl_txn 
>>>>> *ovnsb_idl_txn,
>>>>>              run_put_mac_binding(ovnsb_idl_txn,
>>>>>                                  sbrec_datapath_binding_by_key,
>>>>>                                  sbrec_port_binding_by_key,
>>>>> -                                sbrec_mac_binding_by_lport_ip, mb);
>>>>> +                                sbrec_mac_binding_by_lport_ip,
>>>>> +                                sbrec_ecmp_by_nexthop, mb);
>>>>>              mac_binding_remove(&put_mac_bindings, mb);
>>>>>          }
>>>>>      }
>>>>> diff --git a/controller/pinctrl.h b/controller/pinctrl.h
>>>>> index 5c8ea7aea..f1968f31c 100644
>>>>> --- a/controller/pinctrl.h
>>>>> +++ b/controller/pinctrl.h
>>>>> @@ -50,6 +50,7 @@ void pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
>>>>>                   struct ovsdb_idl_index *sbrec_igmp_groups,
>>>>>                   struct ovsdb_idl_index *sbrec_ip_multicast_opts,
>>>>>                   struct ovsdb_idl_index *sbrec_fdb_by_dp_key_mac,
>>>>> +                 struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
>>>>>                   const struct sbrec_dns_table *,
>>>>>                   const struct sbrec_controller_event_table *,
>>>>>                   const struct sbrec_service_monitor_table *,
>>>>> diff --git a/northd/en-northd.c b/northd/en-northd.c
>>>>> index b8227617b..b3e612958 100644
>>>>> --- a/northd/en-northd.c
>>>>> +++ b/northd/en-northd.c
>>>>> @@ -412,9 +412,13 @@ en_ecmp_nexthop_run(struct engine_node *node, void 
>>>>> *data OVS_UNUSED)
>>>>>          engine_get_input_data("static_routes", node);
>>>>>      const struct sbrec_ecmp_nexthop_table *sbrec_ecmp_nexthop_table =
>>>>>          EN_OVSDB_GET(engine_get_input("SB_ecmp_nexthop", node));
>>>>> +    struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip =
>>>>> +        engine_ovsdb_node_get_index(engine_get_input("SB_mac_binding", 
>>>>> node),
>>>>> +                                    "sbrec_mac_binding_by_lport_ip");
>>>>>  
>>>>>      build_ecmp_nexthop_table(eng_ctx->ovnsb_idl_txn,
>>>>>                               &static_routes_data->parsed_routes,
>>>>> +                             sbrec_mac_binding_by_lport_ip,
>>>>>                               sbrec_ecmp_nexthop_table);
>>>>>      engine_set_node_state(node, EN_UPDATED);
>>>>>  }
>>>>> diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c
>>>>> index cdc080ef0..d29bdca3e 100644
>>>>> --- a/northd/inc-proc-northd.c
>>>>> +++ b/northd/inc-proc-northd.c
>>>>> @@ -266,6 +266,7 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
>>>>>      engine_add_input(&en_bfd_sync, &en_route_policies, NULL);
>>>>>      engine_add_input(&en_bfd_sync, &en_northd, 
>>>>> bfd_sync_northd_change_handler);
>>>>>  
>>>>> +    engine_add_input(&en_ecmp_nexthop, &en_sb_mac_binding, NULL);
>>>>>      engine_add_input(&en_ecmp_nexthop, &en_sb_ecmp_nexthop, NULL);
>>>>>      engine_add_input(&en_ecmp_nexthop, &en_static_routes, NULL);
>>>>>  
>>>>> @@ -369,6 +370,8 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
>>>>>          = static_mac_binding_index_create(sb->idl);
>>>>>      struct ovsdb_idl_index *sbrec_mac_binding_by_datapath
>>>>>          = mac_binding_by_datapath_index_create(sb->idl);
>>>>> +    struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip
>>>>> +        = mac_binding_by_lport_ip_index_create(sb->idl);
>>>>>      struct ovsdb_idl_index *fdb_by_dp_key =
>>>>>          ovsdb_idl_index_create1(sb->idl, &sbrec_fdb_col_dp_key);
>>>>>  
>>>>> @@ -395,6 +398,9 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
>>>>>      engine_ovsdb_node_add_index(&en_sb_mac_binding,
>>>>>                                  "sbrec_mac_binding_by_datapath",
>>>>>                                  sbrec_mac_binding_by_datapath);
>>>>> +    engine_ovsdb_node_add_index(&en_sb_mac_binding,
>>>>> +                                "sbrec_mac_binding_by_lport_ip",
>>>>> +                                sbrec_mac_binding_by_lport_ip);
>>>>>      engine_ovsdb_node_add_index(&en_sb_fdb,
>>>>>                                  "fdb_by_dp_key",
>>>>>                                  fdb_by_dp_key);
>>>>> diff --git a/northd/northd.c b/northd/northd.c
>>>>> index 3e3bb84ef..4e99e2687 100644
>>>>> --- a/northd/northd.c
>>>>> +++ b/northd/northd.c
>>>>> @@ -10669,6 +10669,7 @@ void
>>>>>  build_ecmp_nexthop_table(
>>>>>          struct ovsdb_idl_txn *ovnsb_txn,
>>>>>          struct hmap *routes,
>>>>> +        struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
>>>>>          const struct sbrec_ecmp_nexthop_table *sbrec_ecmp_nexthop_table)
>>>>>  {
>>>>>      if (!ovnsb_txn) {
>>>>> @@ -10699,6 +10700,22 @@ build_ecmp_nexthop_table(
>>>>>              sb_ecmp_nexthop = sbrec_ecmp_nexthop_insert(ovnsb_txn);
>>>>>              sbrec_ecmp_nexthop_set_nexthop(sb_ecmp_nexthop, r->nexthop);
>>>>>              sbrec_ecmp_nexthop_set_port(sb_ecmp_nexthop, 
>>>>> pr->out_port->key);
>>>>> +
>>>>> +            struct sbrec_mac_binding *mb_index_row =
>>>>> +                sbrec_mac_binding_index_init_row(
>>>>> +                        sbrec_mac_binding_by_lport_ip);
>>>>> +            sbrec_mac_binding_index_set_ip(mb_index_row, r->nexthop);
>>>>> +            sbrec_mac_binding_index_set_logical_port(mb_index_row,
>>>>> +                                                     pr->out_port->key);
>>>>> +
>>>>> +            const struct sbrec_mac_binding *mb =
>>>>> +                
>>>>> sbrec_mac_binding_index_find(sbrec_mac_binding_by_lport_ip,
>>>>> +                                             mb_index_row);
>>>>> +            if (mb) {
>>>>> +                sbrec_ecmp_nexthop_set_mac(sb_ecmp_nexthop, mb->mac);
>>>>> +            }
>>>>
>>>> Maintaining this index and looking up is costly (O(log n)) for each mac
>>>> binding insertion and for each static route.  If we update the mac
>>>> address in ovn-controller like I suggested inside
>>>> mac_binding_add_to_sb() can't we avoid doing it in ovn-northd?
>>>
>>> I guess we have some races/issue when a given mac entry is removed from the
>>> mac_binding table. What do you think? If you think it is not a problem, I 
>>> can
>>> remove it.
>>>
>>
>> Do you have an example of such a race?  I'm not sure I understand the
>> problem.
> 
> Maybe I missing something, but what does it happen if the given mac address
> is resolved by ovn-controller running mac_binding_add_to_sb() before the
> related SBREC_ECMP_NEXTHOP entry is created in build_ecmp_nexthop_table()?
> 

Good point, ovn-controller should do the lookup then when processing the
SB.ECMP_nexthop addition/updae to the SB.  ovn-controller already
maintains the mac_binding by port and IP already.

> Regards,
> Lorenzo
> 
>>
>> Thanks,
>> Dumitru
>>
>>>>
>>>>> +
>>>>> +            sbrec_mac_binding_index_destroy_row(mb_index_row);
>>>>>          }
>>>>>          sset_add(&nb_nexthops_sset, r->nexthop);
>>>>>      }
>>>>> diff --git a/northd/northd.h b/northd/northd.h
>>>>> index c4c2a5d7e..83239197f 100644
>>>>> --- a/northd/northd.h
>>>>> +++ b/northd/northd.h
>>>>> @@ -747,6 +747,7 @@ void bfd_sync_init(struct bfd_sync_data *);
>>>>>  void bfd_sync_destroy(struct bfd_sync_data *);
>>>>>  
>>>>>  void build_ecmp_nexthop_table(struct ovsdb_idl_txn *, struct hmap *,
>>>>> +                              struct ovsdb_idl_index *,
>>>>
>>>> Please add a name, the type is not explicit enough.
>>>
>>> ack, I will fix it.
>>>
>>> Regards,
>>> Lorenzo
>>>
>>>>
>>>>>                                const struct sbrec_ecmp_nexthop_table *);
>>>>>  
>>>>>  struct lflow_table;
>>>>
>>>> Regards,
>>>> Dumitru
>>>>
>>

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

Reply via email to