On Fri, 2022-06-17 at 11:07 +0200, Ales Musil wrote:
> The new chassis column in MAC_Binding should
> act as an "owner" order of that particular row.
> This can be utilized by MAC binding aging mechanism,
> where only single is responsible for that particular
> record. In order to keep it consistent the chassis
> that owns the MAC binding is the one that created it,
> with one exception, when the MAC of the binding has
> changed the ownership is transferred to the controller
> that made this update. MAC binding rows without
> chassis are removed by northd.
>
> Reported-at: https://bugzilla.redhat.com/2084668
> Signed-off-by: Ales Musil <[email protected]>
> ---
> controller/pinctrl.c | 35 ++++++++++++++++++++++++-----------
> northd/northd.c | 12 ++++++++++++
> northd/ovn-northd.c | 2 +-
> ovn-sb.ovsschema | 6 +++++-
> ovn-sb.xml | 5 +++++
> tests/ovn.at | 39 +++++++++++++++++++++++++--------------
> 6 files changed, 72 insertions(+), 27 deletions(-)
>
> diff --git a/controller/pinctrl.c b/controller/pinctrl.c
> index 9a1a0faa1..b95336ec0 100644
> --- a/controller/pinctrl.c
> +++ b/controller/pinctrl.c
> @@ -192,7 +192,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,
> + const struct sbrec_chassis *chassis)
> 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)
> @@ -3508,7 +3509,7 @@ pinctrl_run(struct ovsdb_idl_txn
> *ovnsb_idl_txn,
> pinctrl_set_br_int_name_(br_int->name);
> 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, chassis);
> 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,
> @@ -4163,6 +4164,7 @@ mac_binding_add_to_sb(struct ovsdb_idl_txn
> *ovnsb_idl_txn,
> struct ovsdb_idl_index
> *sbrec_mac_binding_by_lport_ip,
> const char *logical_port,
> const struct sbrec_datapath_binding *dp,
> + const struct sbrec_chassis *chassis,
> struct eth_addr ea, const char *ip,
> bool update_only)
> {
> @@ -4181,8 +4183,11 @@ mac_binding_add_to_sb(struct ovsdb_idl_txn
> *ovnsb_idl_txn,
> sbrec_mac_binding_set_ip(b, ip);
> sbrec_mac_binding_set_mac(b, mac_string);
> sbrec_mac_binding_set_datapath(b, dp);
> + sbrec_mac_binding_set_chassis(b, chassis);
> } else if (strcmp(b->mac, mac_string)) {
> sbrec_mac_binding_set_mac(b, mac_string);
> + /* Transfer ownership to current chassis if we have seen
> never MAC */
> + sbrec_mac_binding_set_chassis(b, chassis);
> }
> }
>
> @@ -4194,6 +4199,7 @@ send_garp_locally(struct ovsdb_idl_txn
> *ovnsb_idl_txn,
> struct ovsdb_idl_index
> *sbrec_mac_binding_by_lport_ip,
> const struct hmap *local_datapaths,
> const struct sbrec_port_binding *in_pb,
> + const struct sbrec_chassis *chassis,
> struct eth_addr ea, ovs_be32 ip)
> {
> if (!ovnsb_idl_txn) {
> @@ -4221,7 +4227,7 @@ 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,
> + remote->logical_port, remote-
> >datapath, chassis,
> ea, ds_cstr(&ip_s), update_only);
> ds_destroy(&ip_s);
> }
> @@ -4232,7 +4238,8 @@ 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,
> - const struct mac_binding *mb)
> + const struct mac_binding *mb,
> + const struct sbrec_chassis *chassis)
> {
> /* Convert logical datapath and logical port key into lport. */
> const struct sbrec_port_binding *pb = lport_lookup_by_key(
> @@ -4254,7 +4261,7 @@ run_put_mac_binding(struct ovsdb_idl_txn
> *ovnsb_idl_txn,
> struct ds ip_s = DS_EMPTY_INITIALIZER;
> ipv6_format_mapped(&mb->ip, &ip_s);
> mac_binding_add_to_sb(ovnsb_idl_txn,
> sbrec_mac_binding_by_lport_ip,
> - pb->logical_port, pb->datapath, mb->mac,
> + pb->logical_port, pb->datapath, chassis,
> mb->mac,
> ds_cstr(&ip_s), false);
> ds_destroy(&ip_s);
> }
> @@ -4265,7 +4272,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,
> + const struct sbrec_chassis *chassis)
> OVS_REQUIRES(pinctrl_mutex)
> {
> if (!ovnsb_idl_txn) {
> @@ -4277,7 +4285,7 @@ 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);
> + mb, chassis);
> }
> ovn_mac_bindings_flush(&put_mac_bindings);
> }
> @@ -4392,6 +4400,7 @@ send_garp_rarp_update(struct ovsdb_idl_txn
> *ovnsb_idl_txn,
> struct ovsdb_idl_index
> *sbrec_mac_binding_by_lport_ip,
> const struct hmap *local_datapaths,
> const struct sbrec_port_binding *binding_rec,
> + const struct sbrec_chassis *chassis,
> struct shash *nat_addresses)
> {
> volatile struct garp_rarp_data *garp_rarp = NULL;
> @@ -4425,7 +4434,8 @@ 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,
> + local_datapaths, binding_rec,
> + chassis, laddrs->ea,
> laddrs->ipv4_addrs[i].addr);
>
> }
> @@ -4465,7 +4475,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);
> + local_datapaths, binding_rec, chassis,
> + laddrs.ea, ip);
> }
>
> destroy_lport_addresses(&laddrs);
> @@ -5808,7 +5819,8 @@ send_garp_rarp_prepare(struct ovsdb_idl_txn
> *ovnsb_idl_txn,
> if (pb) {
> send_garp_rarp_update(ovnsb_idl_txn,
> sbrec_mac_binding_by_lport_ip,
> - local_datapaths, pb,
> &nat_addresses);
> + local_datapaths, pb, chassis,
> + &nat_addresses);
> }
> }
>
> @@ -5819,7 +5831,8 @@ send_garp_rarp_prepare(struct ovsdb_idl_txn
> *ovnsb_idl_txn,
> = lport_lookup_by_name(sbrec_port_binding_by_name,
> gw_port);
> if (pb) {
> send_garp_rarp_update(ovnsb_idl_txn,
> sbrec_mac_binding_by_lport_ip,
> - local_datapaths, pb,
> &nat_addresses);
> + local_datapaths, pb, chassis,
> + &nat_addresses);
> }
> }
>
> diff --git a/northd/northd.c b/northd/northd.c
> index 0d6ebccde..214fdddc9 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -15623,6 +15623,17 @@ handle_port_binding_changes(struct
> northd_input *input_data,
> }
> }
>
> +static void
> +remove_orphaned_mac_bindings(struct northd_input *input_data) {
> + const struct sbrec_mac_binding *mb;
> + SBREC_MAC_BINDING_TABLE_FOR_EACH_SAFE (mb,
> + input_data-
> >sbrec_mac_binding_table) {
> + if (!mb->chassis) {
> + sbrec_mac_binding_delete(mb);
> + }
> + }
> +}
> +
> /* Handle a fairly small set of changes in the southbound database.
> */
> static void
> ovnsb_db_run(struct northd_input *input_data,
> @@ -15641,6 +15652,7 @@ ovnsb_db_run(struct northd_input *input_data,
> if (ovnsb_txn) {
> update_sb_ha_group_ref_chassis(input_data,
> &ha_ref_chassis_map);
> + remove_orphaned_mac_bindings(input_data);
> }
> shash_destroy(&ha_ref_chassis_map);
> }
> diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
> index e4e980720..a69b642b6 100644
> --- a/northd/ovn-northd.c
> +++ b/northd/ovn-northd.c
> @@ -112,7 +112,7 @@ static const char *rbac_port_binding_update[] =
> static const char *rbac_mac_binding_auth[] =
> {""};
> static const char *rbac_mac_binding_update[] =
> - {"logical_port", "ip", "mac", "datapath"};
> + {"logical_port", "ip", "mac", "datapath", "chassis"};
>
> static const char *rbac_svc_monitor_auth[] =
> {""};
> diff --git a/ovn-sb.ovsschema b/ovn-sb.ovsschema
> index 3b78ea6f6..abb881761 100644
> --- a/ovn-sb.ovsschema
> +++ b/ovn-sb.ovsschema
> @@ -1,7 +1,7 @@
> {
> "name": "OVN_Southbound",
> "version": "20.23.0",
Need to bump the schema version so upgrades of existing DBs work
correctly, otherwise:
2022-06-22T16:54:33.291Z|00034|ovn_northd|INFO|ovn-northd lock acquired. This
ovn-northd instance is now active.
2022-06-22T16:54:33.293Z|00035|ovsdb_idl|WARN|MAC_Binding table in
OVN_Southbound database lacks chassis column (database needs upgrade?)
2022-06-22T16:54:33.293Z|00036|ovsdb_idl|WARN|Port_Binding table in
OVN_Southbound database lacks additional_chassis column (database needs
upgrade?)
2022-06-22T16:54:33.293Z|00037|ovsdb_idl|WARN|Port_Binding table in
OVN_Southbound database lacks additional_encap column (database needs upgrade?)
2022-06-22T16:54:33.293Z|00038|ovsdb_idl|WARN|Port_Binding table in
OVN_Southbound database lacks requested_additional_chassis column (database
needs upgrade?)
and ovn-controller will also be unhappy.
Dan
> - "cksum": "4045988377 28575",
> + "cksum": "2450182539 28828",
> "tables": {
> "SB_Global": {
> "columns": {
> @@ -260,6 +260,10 @@
> "logical_port": {"type": "string"},
> "ip": {"type": "string"},
> "mac": {"type": "string"},
> + "chassis": {"type": {"key": {"type": "uuid",
> + "refTable": "Chassis",
> + "refType": "weak"},
> + "min": 0, "max": 1}},
> "datapath": {"type": {"key": {"type": "uuid",
> "refTable":
> "Datapath_Binding"}}}},
> "indexes": [["logical_port", "ip"]],
> diff --git a/ovn-sb.xml b/ovn-sb.xml
> index 898f3676a..842c24b70 100644
> --- a/ovn-sb.xml
> +++ b/ovn-sb.xml
> @@ -3606,6 +3606,11 @@ tcp.flags = RST;
> <column name="mac">
> The Ethernet address to which the IP is bound.
> </column>
> +
> + <column name="chassis">
> + The chassis that "owns" the MAC binding.
> + </column>
> +
> <column name="datapath">
> The logical datapath to which the logical port belongs.
> </column>
> diff --git a/tests/ovn.at b/tests/ovn.at
> index 59d51f3e0..d71a08cdd 100644
> --- a/tests/ovn.at
> +++ b/tests/ovn.at
> @@ -9038,9 +9038,13 @@ ovn-nbctl lsp-add ls0 lp1
> ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
> ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
> dp_uuid=$(fetch_column Datapath_Binding _uuid)
> -ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid
> logical_port=lp0 mac="mac1"
> -ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid
> logical_port=lp1 mac="mac2"
> -ovn-sbctl find MAC_Binding
> +chassis=$(fetch_column Chassis _uuid name=hv1)
> +ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid
> logical_port=lp0 mac="mac1" chassis=$chassis
> +ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid
> logical_port=lp1 mac="mac2" chassis=$chassis
> +
> +wait_row_count MAC_Binding 1 logical_port=lp0
> +wait_row_count MAC_Binding 1 logical_port=lp1
> +
> # Delete port lp0 and check that its MAC_Binding is deleted.
> ovn-nbctl lsp-del lp0
> ovn-sbctl find MAC_Binding
> @@ -18916,8 +18920,9 @@ AT_CHECK([as hv1 ovs-ofctl dump-flows br-int
> \
> ]])
> dp_uuid=$(ovn-sbctl find datapath_binding | grep sw0 -B2 | grep
> _uuid | \
> awk '{print $3}')
> +chassis=$(fetch_column Chassis _uuid name=hv1)
> ovn-sbctl create MAC_Binding ip=172.168.0.3 datapath=$dp_uuid \
> -logical_port=lr0-public mac="00\:00\:00\:12\:af\:11"
> +logical_port=lr0-public mac="00\:00\:00\:12\:af\:11"
> chassis=$chassis
>
> # Try different gateway mtus and send a 142-byte packet
> (corresponding
> # to a 124-byte MTU). If the MTU is less than 124, ovn-controller
> @@ -18987,7 +18992,7 @@ ovn-nbctl lr-nat-add lr1 snat 2000::1
> 1000::/64
> dp_uuid=$(ovn-sbctl find datapath_binding | grep sw0 -B2 | grep
> _uuid | \
> awk '{print $3}')
> ovn-sbctl create MAC_Binding ip=172.168.0.3 datapath=$dp_uuid \
> -logical_port=lr1-public mac="00\:00\:00\:12\:af\:11"
> +logical_port=lr1-public mac="00\:00\:00\:12\:af\:11"
> chassis=$chassis
>
> # Try different gateway mtus and send a 142-byte packet
> (corresponding
> # to a 124-byte MTU). If the MTU is less than 124, ovn-controller
> @@ -19339,9 +19344,11 @@ check ovn-sbctl --all destroy mac_binding
>
> # Create a mac_binding entry on lr0-pub for 172.24.4.200 with a
> # wrong mac, expecting it to be updated with the real mac.
> +ovn-sbctl list chassis
> lr0_dp=$(fetch_column Datapath_Binding _uuid external_ids:name=lr0)
> +chassis=$(fetch_column Chassis _uuid name=hv1)
> ovn-sbctl create mac_binding datapath=$lr0_dp logical_port=lr0-pub \
> - ip=172.24.4.200 mac=\"aa:aa:aa:aa:aa:aa\"
> + ip=172.24.4.200 mac=\"aa:aa:aa:aa:aa:aa\" chassis=$chassis
>
> check ovn-nbctl lr-nat-add lr0 dnat_and_snat 172.24.4.100 10.0.0.10
> check ovn-nbctl lr-nat-add lr1 dnat_and_snat 172.24.4.200 20.0.0.10
> @@ -25851,18 +25858,19 @@ wait_for_ports_up
>
> wait_row_count datapath_binding 1 external-ids:name=lr0
> lr0_dp_uuid=$(ovn-sbctl --bare --columns _uuid list datapath_binding
> lr0)
> +chassis=$(fetch_column Chassis _uuid name=hv1)
>
> AT_CHECK(
> [ovn-sbctl create mac_binding datapath=$lr0_dp_uuid
> ip=172.168.0.120 \
> - logical_port=lr0-public mac="10\:54\:00\:00\:00\:03"
> + logical_port=lr0-public mac="10\:54\:00\:00\:00\:03"
> chassis=$chassis
> ovn-sbctl create mac_binding datapath=$lr0_dp_uuid
> ip=172.168.0.200 \
> - logical_port=lr0-public mac="10\:54\:00\:00\:00\:04"
> + logical_port=lr0-public mac="10\:54\:00\:00\:00\:04"
> chassis=$chassis
> ovn-sbctl create mac_binding datapath=$lr0_dp_uuid ip="bef0\:\:4"
> \
> - logical_port=lr0-public mac="10\:54\:00\:00\:00\:05"
> + logical_port=lr0-public mac="10\:54\:00\:00\:00\:05"
> chassis=$chassis
> ovn-sbctl create mac_binding datapath=$lr0_dp_uuid ip="bef0\:\:5"
> \
> - logical_port=lr0-public mac="10\:54\:00\:00\:00\:06"
> + logical_port=lr0-public mac="10\:54\:00\:00\:00\:06"
> chassis=$chassis
> ovn-sbctl create mac_binding datapath=$lr0_dp_uuid ip="bef0\:\:6"
> \
> - logical_port=lr0-public mac="10\:54\:00\:00\:00\:07"
> + logical_port=lr0-public mac="10\:54\:00\:00\:00\:07"
> chassis=$chassis
> ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
> ip_prefix="\:\:/64" nexthop="bef0\:\:4" -- add Logical_Router
> lr0 \
> static_routes @lrt],
> @@ -29334,9 +29342,10 @@ AS_BOX([Test routing])
> # Before sending add mac_binding entry for 10.0.0.14
>
> lr0_dp_uuid=$(fetch_column datapath_binding _uuid
> external_ids:name=lr0)
> +chassis=$(fetch_column Chassis _uuid name=hv1)
>
> ovn-sbctl create mac_binding ip=10.0.0.14 logical_port=lr0-sw0 \
> -mac="50\:54\:00\:00\:00\:14" datapath=$lr0_dp_uuid
> +mac="50\:54\:00\:00\:00\:14" datapath=$lr0_dp_uuid chassis=$chassis
>
> # Wait till the mac_binding flows appear in hv1
> OVS_WAIT_UNTIL([test 1 = $(as hv1 ovs-ofctl dump-flows br-int
> table=66 \
> @@ -31496,8 +31505,9 @@ test_mac_binding_flows() {
> }
> # Create SB MAC_Binding entry on external gateway port
> lr0_dp_uuid=$(fetch_column datapath_binding _uuid
> external_ids:name=lr0)
> +chassis=$(fetch_column Chassis _uuid name=hv1)
>
> -ovn-sbctl create mac_binding ip=172.16.1.1 logical_port=lr0-ext-ls0
> mac="00\:00\:11\:22\:33\:44" datapath=$lr0_dp_uuid
> +ovn-sbctl create mac_binding ip=172.16.1.1 logical_port=lr0-ext-ls0
> mac="00\:00\:11\:22\:33\:44" datapath=$lr0_dp_uuid chassis=$chassis
> test_mac_binding_flows 100 00:00:11:22:33:44 1
>
> # Create Static_MAC_Binding entry on external gateway port. This
> should have
> @@ -31595,7 +31605,8 @@ test_mac_binding_flows() {
>
> # Create SB MAC_Binding entry on external gateway port
> gw_dp_uuid=$(fetch_column datapath_binding _uuid
> external_ids:name=gw)
> -ovn-sbctl create mac_binding ip=192.168.10.10 logical_port=gw-public
> mac="00\:00\:00\:00\:10\:10" datapath=$gw_dp_uuid
> +chassis=$(fetch_column Chassis _uuid name=hv1)
> +ovn-sbctl create mac_binding ip=192.168.10.10 logical_port=gw-public
> mac="00\:00\:00\:00\:10\:10" datapath=$gw_dp_uuid chassis=$chassis
>
> test_mac_binding_flows hv1 00\:00\:00\:00\:10\:10 1
> test_mac_binding_flows hv2 00\:00\:00\:00\:10\:10 0
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev