Skip to content

Commit

Permalink
pinctrl: Update ecmp-nexthop mac resolving L2 address.
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: 0-day Robot <robot@bytheb.org>
  • Loading branch information
LorenzoBianconi authored and ovsrobot committed Dec 20, 2024
1 parent b88ad9c commit ec011ab
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 15 deletions.
5 changes: 5 additions & 0 deletions controller/ovn-controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -5011,6 +5011,10 @@ main(int argc, char *argv[])
= ovsdb_idl_index_create2(ovnsb_idl_loop.idl,
&sbrec_fdb_col_mac,
&sbrec_fdb_col_dp_key);
struct ovsdb_idl_index *sbrec_ecmp_by_nexthop
= ovsdb_idl_index_create2(ovnsb_idl_loop.idl,
&sbrec_ecmp_nexthop_col_nexthop,
&sbrec_ecmp_nexthop_col_port);
struct ovsdb_idl_index *sbrec_mac_binding_by_datapath
= mac_binding_by_datapath_index_create(ovnsb_idl_loop.idl);
struct ovsdb_idl_index *sbrec_static_mac_binding_by_datapath
Expand Down Expand Up @@ -5749,6 +5753,7 @@ main(int argc, char *argv[])
sbrec_igmp_group,
sbrec_ip_multicast,
sbrec_fdb_by_dp_key_mac,
sbrec_ecmp_by_nexthop,
sbrec_controller_event_table_get(
ovnsb_idl_loop.idl),
sbrec_service_monitor_table_get(
Expand Down
88 changes: 73 additions & 15 deletions controller/pinctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,16 @@ static void pinctrl_handle_put_mac_binding(const struct flow *md,
OVS_REQUIRES(pinctrl_mutex);
static void init_put_mac_bindings(void);
static void destroy_put_mac_bindings(void);
static const struct sbrec_ecmp_nexthop *ecmp_nexthop_lookup(
struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
const char *nexthop,
const struct sbrec_port_binding *pb);
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);
static void wait_put_mac_bindings(struct ovsdb_idl_txn *ovnsb_idl_txn);
static void send_mac_binding_buffered_pkts(struct rconn *swconn)
Expand Down Expand Up @@ -236,6 +241,7 @@ static void send_garp_rarp_prepare(
struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_name,
struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
const struct sbrec_ecmp_nexthop_table *ecmp_nh_table,
const struct ovsrec_bridge *,
const struct sbrec_chassis *,
Expand Down Expand Up @@ -4047,6 +4053,7 @@ 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_controller_event_table *ce_table,
const struct sbrec_service_monitor_table *svc_mon_table,
const struct sbrec_mac_binding_table *mac_binding_table,
Expand All @@ -4063,12 +4070,14 @@ pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
ovs_mutex_lock(&pinctrl_mutex);
run_put_mac_bindings(ovnsb_idl_txn, sbrec_datapath_binding_by_key,
sbrec_port_binding_by_key,
sbrec_mac_binding_by_lport_ip);
sbrec_mac_binding_by_lport_ip,
sbrec_ecmp_by_nexthop);
run_put_vport_bindings(ovnsb_idl_txn, sbrec_datapath_binding_by_key,
sbrec_port_binding_by_key, chassis);
send_garp_rarp_prepare(ovnsb_idl_txn, sbrec_port_binding_by_datapath,
sbrec_port_binding_by_name,
sbrec_mac_binding_by_lport_ip, ecmp_nh_table,
sbrec_mac_binding_by_lport_ip,
sbrec_ecmp_by_nexthop, ecmp_nh_table,
br_int, chassis, local_datapaths, active_tunnels,
ovs_table);
prepare_ipv6_ras(local_active_ports_ras, sbrec_port_binding_by_name);
Expand Down Expand Up @@ -4715,8 +4724,10 @@ send_mac_binding_buffered_pkts(struct rconn *swconn)
static void
mac_binding_add_to_sb(struct ovsdb_idl_txn *ovnsb_idl_txn,
struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
const char *logical_port,
const struct sbrec_datapath_binding *dp,
const struct sbrec_port_binding *pb,
struct eth_addr ea, const char *ip,
bool update_only)
{
Expand Down Expand Up @@ -4746,6 +4757,12 @@ mac_binding_add_to_sb(struct ovsdb_idl_txn *ovnsb_idl_txn,
sbrec_mac_binding_set_timestamp(b, time_wall_msec());
}
}

const struct sbrec_ecmp_nexthop *ecmp_nh =
ecmp_nexthop_lookup(sbrec_ecmp_by_nexthop, ip, pb);
if (ecmp_nh) {
sbrec_ecmp_nexthop_set_mac(ecmp_nh, mac_string);
}
}

/* Simulate the effect of a GARP on local datapaths, i.e., create MAC_Bindings
Expand All @@ -4754,6 +4771,7 @@ mac_binding_add_to_sb(struct ovsdb_idl_txn *ovnsb_idl_txn,
static void
send_garp_locally(struct ovsdb_idl_txn *ovnsb_idl_txn,
struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
const struct hmap *local_datapaths,
const struct sbrec_port_binding *in_pb,
struct eth_addr ea, ovs_be32 ip)
Expand Down Expand Up @@ -4783,17 +4801,34 @@ send_garp_locally(struct ovsdb_idl_txn *ovnsb_idl_txn,

ip_format_masked(ip, OVS_BE32_MAX, &ip_s);
mac_binding_add_to_sb(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
remote->logical_port, remote->datapath,
ea, ds_cstr(&ip_s), update_only);
sbrec_ecmp_by_nexthop, remote->logical_port,
remote->datapath, remote, ea, ds_cstr(&ip_s),
update_only);
ds_destroy(&ip_s);
}
}

static const struct sbrec_ecmp_nexthop *
ecmp_nexthop_lookup(struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
const char *nexthop, const struct sbrec_port_binding *pb)
{
struct sbrec_ecmp_nexthop *ecmp_nh =
sbrec_ecmp_nexthop_index_init_row(sbrec_ecmp_by_nexthop);
sbrec_ecmp_nexthop_index_set_nexthop(ecmp_nh, nexthop);
sbrec_ecmp_nexthop_index_set_port(ecmp_nh, pb);
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. */
Expand All @@ -4816,8 +4851,9 @@ 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,
ds_cstr(&ip_s), false);
sbrec_ecmp_by_nexthop, pb->logical_port,
pb->datapath, pb, mb->data.mac, ds_cstr(&ip_s),
false);
ds_destroy(&ip_s);
}

Expand All @@ -4827,7 +4863,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) {
Expand All @@ -4842,7 +4879,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);
}
}
Expand Down Expand Up @@ -4992,6 +5030,7 @@ add_garp_rarp(const char *name, const struct eth_addr ea, ovs_be32 ip,
static void
send_garp_rarp_update(struct ovsdb_idl_txn *ovnsb_idl_txn,
struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
const struct hmap *local_datapaths,
const struct sbrec_port_binding *binding_rec,
struct shash *nat_addresses,
Expand Down Expand Up @@ -5035,8 +5074,9 @@ send_garp_rarp_update(struct ovsdb_idl_txn *ovnsb_idl_txn,
binding_rec->tunnel_key);
send_garp_locally(ovnsb_idl_txn,
sbrec_mac_binding_by_lport_ip,
local_datapaths, binding_rec, laddrs->ea,
laddrs->ipv4_addrs[i].addr);
sbrec_ecmp_by_nexthop,
local_datapaths, binding_rec,
laddrs->ea, laddrs->ipv4_addrs[i].addr);

}
free(name);
Expand Down Expand Up @@ -5105,7 +5145,8 @@ send_garp_rarp_update(struct ovsdb_idl_txn *ovnsb_idl_txn,
binding_rec->tunnel_key);
if (ip) {
send_garp_locally(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
local_datapaths, binding_rec, laddrs.ea, ip);
sbrec_ecmp_by_nexthop, local_datapaths,
binding_rec, laddrs.ea, ip);
}

destroy_lport_addresses(&laddrs);
Expand Down Expand Up @@ -6723,6 +6764,7 @@ send_garp_rarp_prepare(struct ovsdb_idl_txn *ovnsb_idl_txn,
struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_name,
struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
struct ovsdb_idl_index *sbrec_ecmp_by_nexthop,
const struct sbrec_ecmp_nexthop_table *ecmp_nh_table,
const struct ovsrec_bridge *br_int,
const struct sbrec_chassis *chassis,
Expand Down Expand Up @@ -6784,6 +6826,7 @@ send_garp_rarp_prepare(struct ovsdb_idl_txn *ovnsb_idl_txn,
if (pb && !smap_get_bool(&pb->options, "disable_garp_rarp", false)) {
send_garp_rarp_update(ovnsb_idl_txn,
sbrec_mac_binding_by_lport_ip,
sbrec_ecmp_by_nexthop,
local_datapaths, pb, &nat_addresses,
garp_max_timeout, garp_continuous);
}
Expand All @@ -6796,8 +6839,9 @@ send_garp_rarp_prepare(struct ovsdb_idl_txn *ovnsb_idl_txn,
= lport_lookup_by_name(sbrec_port_binding_by_name, gw_port);
if (pb && !smap_get_bool(&pb->options, "disable_garp_rarp", false)) {
send_garp_rarp_update(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
local_datapaths, pb, &nat_addresses,
garp_max_timeout, garp_continuous);
sbrec_ecmp_by_nexthop, local_datapaths, pb,
&nat_addresses, garp_max_timeout,
garp_continuous);
}
}

Expand All @@ -6806,7 +6850,21 @@ send_garp_rarp_prepare(struct ovsdb_idl_txn *ovnsb_idl_txn,
const struct sbrec_ecmp_nexthop *sb_ecmp_nexthop;
SBREC_ECMP_NEXTHOP_TABLE_FOR_EACH (sb_ecmp_nexthop, ecmp_nh_table) {
const struct sbrec_port_binding *pb = sb_ecmp_nexthop->port;
if (pb && !strcmp(pb->type, "l3gateway") && pb->chassis == chassis) {
if (!pb || pb->chassis != chassis) {
continue;
}

/* Update mac binding if not already set. */
if (!strcmp(sb_ecmp_nexthop->mac, "")) {
const struct sbrec_mac_binding *mb =
mac_binding_lookup(sbrec_mac_binding_by_lport_ip,
pb->logical_port, sb_ecmp_nexthop->nexthop);
if (ovnsb_idl_txn && mb) {
sbrec_ecmp_nexthop_set_mac(sb_ecmp_nexthop, mb->mac);
}
}

if (!strcmp(pb->type, "l3gateway")) {
send_arp_nd_update(pb, sb_ecmp_nexthop->nexthop,
max_arp_nd_timeout, continuous_arp_nd);
}
Expand Down
1 change: 1 addition & 0 deletions controller/pinctrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_controller_event_table *,
const struct sbrec_service_monitor_table *,
const struct sbrec_mac_binding_table *,
Expand Down

0 comments on commit ec011ab

Please sign in to comment.