|
|
ebb439 |
From 4027dae96c587d68a7c15b798a7016cffbe9fd48 Mon Sep 17 00:00:00 2001
|
|
|
ebb439 |
From: Dumitru Ceara <dceara@redhat.com>
|
|
|
ebb439 |
Date: Tue, 3 Nov 2020 16:51:04 +0100
|
|
|
ebb439 |
Subject: [PATCH 1/2] pinctrl: Directly update MAC_Bindings created by self
|
|
|
ebb439 |
originated GARPs.
|
|
|
ebb439 |
|
|
|
ebb439 |
OVN uses GARPs to announce changes to locally owned NAT addresses. This is
|
|
|
ebb439 |
OK when updating upstream router caches but is unnecessary for updating OVN
|
|
|
ebb439 |
logical router MAC_Bindings.
|
|
|
ebb439 |
|
|
|
ebb439 |
ovn-controller already has the information required for directly
|
|
|
ebb439 |
updating/inserting the MAC_Bindings that would be created by neighbor
|
|
|
ebb439 |
routers.
|
|
|
ebb439 |
|
|
|
ebb439 |
This also has the advantage that GARPs don't necessarily need to be flooded
|
|
|
ebb439 |
in the complete L2 domain of the switch and that router patch ports can be
|
|
|
ebb439 |
skipped. An upcoming commit will take advantage of this.
|
|
|
ebb439 |
|
|
|
ebb439 |
Suggested-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
|
|
|
ebb439 |
Fixes: 81e928526b8a ("ovn-controller: Inject GARPs to logical switch pipeline to update neighbors")
|
|
|
ebb439 |
Acked-by: Mark Michelson <mmichels@redhat.com>
|
|
|
ebb439 |
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
|
|
|
ebb439 |
Signed-off-by: Numan Siddique <numans@ovn.org>
|
|
|
ebb439 |
(cherry picked from upstream commit a2b88dc5136507e727e4bcdc4bf6fde559f519a9)
|
|
|
ebb439 |
|
|
|
ebb439 |
Change-Id: I2209707359d268e7d80ed114e187e7ff13e7176c
|
|
|
ebb439 |
---
|
|
|
ebb439 |
controller/pinctrl.c | 105 +++++++++++++++++++++++++++++++++++++++++----------
|
|
|
ebb439 |
1 file changed, 85 insertions(+), 20 deletions(-)
|
|
|
ebb439 |
|
|
|
ebb439 |
diff --git a/controller/pinctrl.c b/controller/pinctrl.c
|
|
|
ebb439 |
index f15afc5..dd9fff9 100644
|
|
|
ebb439 |
--- a/controller/pinctrl.c
|
|
|
ebb439 |
+++ b/controller/pinctrl.c
|
|
|
ebb439 |
@@ -200,8 +200,10 @@ static void init_send_garps_rarps(void);
|
|
|
ebb439 |
static void destroy_send_garps_rarps(void);
|
|
|
ebb439 |
static void send_garp_rarp_wait(long long int send_garp_rarp_time);
|
|
|
ebb439 |
static void send_garp_rarp_prepare(
|
|
|
ebb439 |
+ struct ovsdb_idl_txn *ovnsb_idl_txn,
|
|
|
ebb439 |
struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
|
|
|
ebb439 |
struct ovsdb_idl_index *sbrec_port_binding_by_name,
|
|
|
ebb439 |
+ struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
|
|
|
ebb439 |
const struct ovsrec_bridge *,
|
|
|
ebb439 |
const struct sbrec_chassis *,
|
|
|
ebb439 |
const struct hmap *local_datapaths,
|
|
|
ebb439 |
@@ -3145,8 +3147,9 @@ pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
|
|
|
ebb439 |
sbrec_mac_binding_by_lport_ip);
|
|
|
ebb439 |
run_put_vport_bindings(ovnsb_idl_txn, sbrec_datapath_binding_by_key,
|
|
|
ebb439 |
sbrec_port_binding_by_key, chassis);
|
|
|
ebb439 |
- send_garp_rarp_prepare(sbrec_port_binding_by_datapath,
|
|
|
ebb439 |
- sbrec_port_binding_by_name, br_int, chassis,
|
|
|
ebb439 |
+ send_garp_rarp_prepare(ovnsb_idl_txn, sbrec_port_binding_by_datapath,
|
|
|
ebb439 |
+ sbrec_port_binding_by_name,
|
|
|
ebb439 |
+ sbrec_mac_binding_by_lport_ip, br_int, chassis,
|
|
|
ebb439 |
local_datapaths, active_tunnels);
|
|
|
ebb439 |
prepare_ipv6_ras(local_datapaths);
|
|
|
ebb439 |
prepare_ipv6_prefixd(ovnsb_idl_txn, sbrec_port_binding_by_name,
|
|
|
ebb439 |
@@ -3837,6 +3840,64 @@ mac_binding_lookup(struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
|
|
|
ebb439 |
return retval;
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
+/* Update or add an IP-MAC binding for 'logical_port'. */
|
|
|
ebb439 |
+static void
|
|
|
ebb439 |
+mac_binding_add(struct ovsdb_idl_txn *ovnsb_idl_txn,
|
|
|
ebb439 |
+ struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
|
|
|
ebb439 |
+ const char *logical_port,
|
|
|
ebb439 |
+ const struct sbrec_datapath_binding *dp,
|
|
|
ebb439 |
+ struct eth_addr ea, const char *ip)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ /* Convert ethernet argument to string form for database. */
|
|
|
ebb439 |
+ char mac_string[ETH_ADDR_STRLEN + 1];
|
|
|
ebb439 |
+ snprintf(mac_string, sizeof mac_string, ETH_ADDR_FMT, ETH_ADDR_ARGS(ea));
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ const struct sbrec_mac_binding *b =
|
|
|
ebb439 |
+ mac_binding_lookup(sbrec_mac_binding_by_lport_ip, logical_port, ip);
|
|
|
ebb439 |
+ if (!b) {
|
|
|
ebb439 |
+ b = sbrec_mac_binding_insert(ovnsb_idl_txn);
|
|
|
ebb439 |
+ sbrec_mac_binding_set_logical_port(b, logical_port);
|
|
|
ebb439 |
+ sbrec_mac_binding_set_ip(b, ip);
|
|
|
ebb439 |
+ sbrec_mac_binding_set_mac(b, mac_string);
|
|
|
ebb439 |
+ sbrec_mac_binding_set_datapath(b, dp);
|
|
|
ebb439 |
+ } else if (strcmp(b->mac, mac_string)) {
|
|
|
ebb439 |
+ sbrec_mac_binding_set_mac(b, mac_string);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+/* Simulate the effect of a GARP on local datapaths, i.e., create MAC_Bindings
|
|
|
ebb439 |
+ * on peer router datapaths.
|
|
|
ebb439 |
+ */
|
|
|
ebb439 |
+static void
|
|
|
ebb439 |
+send_garp_locally(struct ovsdb_idl_txn *ovnsb_idl_txn,
|
|
|
ebb439 |
+ struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
|
|
|
ebb439 |
+ const struct hmap *local_datapaths,
|
|
|
ebb439 |
+ const struct sbrec_port_binding *in_pb,
|
|
|
ebb439 |
+ struct eth_addr ea, ovs_be32 ip)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ const struct local_datapath *ldp =
|
|
|
ebb439 |
+ get_local_datapath(local_datapaths, in_pb->datapath->tunnel_key);
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ ovs_assert(ldp);
|
|
|
ebb439 |
+ for (size_t i = 0; i < ldp->n_peer_ports; i++) {
|
|
|
ebb439 |
+ const struct sbrec_port_binding *local = ldp->peer_ports[i].local;
|
|
|
ebb439 |
+ const struct sbrec_port_binding *remote = ldp->peer_ports[i].remote;
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ /* Skip "ingress" port. */
|
|
|
ebb439 |
+ if (local == in_pb) {
|
|
|
ebb439 |
+ continue;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ struct ds ip_s = DS_EMPTY_INITIALIZER;
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ ip_format_masked(ip, OVS_BE32_MAX, &ip_s);
|
|
|
ebb439 |
+ mac_binding_add(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
|
|
|
ebb439 |
+ remote->logical_port, remote->datapath,
|
|
|
ebb439 |
+ ea, ds_cstr(&ip_s));
|
|
|
ebb439 |
+ ds_destroy(&ip_s);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
static void
|
|
|
ebb439 |
run_put_mac_binding(struct ovsdb_idl_txn *ovnsb_idl_txn,
|
|
|
ebb439 |
struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
|
|
|
ebb439 |
@@ -3863,20 +3924,8 @@ run_put_mac_binding(struct ovsdb_idl_txn *ovnsb_idl_txn,
|
|
|
ebb439 |
|
|
|
ebb439 |
struct ds ip_s = DS_EMPTY_INITIALIZER;
|
|
|
ebb439 |
ipv6_format_mapped(&pmb->ip_key, &ip_s);
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- /* Update or add an IP-MAC binding for this logical port. */
|
|
|
ebb439 |
- const struct sbrec_mac_binding *b =
|
|
|
ebb439 |
- mac_binding_lookup(sbrec_mac_binding_by_lport_ip, pb->logical_port,
|
|
|
ebb439 |
- ds_cstr(&ip_s));
|
|
|
ebb439 |
- if (!b) {
|
|
|
ebb439 |
- b = sbrec_mac_binding_insert(ovnsb_idl_txn);
|
|
|
ebb439 |
- sbrec_mac_binding_set_logical_port(b, pb->logical_port);
|
|
|
ebb439 |
- sbrec_mac_binding_set_ip(b, ds_cstr(&ip_s));
|
|
|
ebb439 |
- sbrec_mac_binding_set_mac(b, mac_string);
|
|
|
ebb439 |
- sbrec_mac_binding_set_datapath(b, pb->datapath);
|
|
|
ebb439 |
- } else if (strcmp(b->mac, mac_string)) {
|
|
|
ebb439 |
- sbrec_mac_binding_set_mac(b, mac_string);
|
|
|
ebb439 |
- }
|
|
|
ebb439 |
+ mac_binding_add(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
|
|
|
ebb439 |
+ pb->logical_port, pb->datapath, pmb->mac, ds_cstr(&ip_s));
|
|
|
ebb439 |
ds_destroy(&ip_s);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
@@ -4018,7 +4067,10 @@ add_garp_rarp(const char *name, const struct eth_addr ea, ovs_be32 ip,
|
|
|
ebb439 |
|
|
|
ebb439 |
/* Add or update a vif for which GARPs need to be announced. */
|
|
|
ebb439 |
static void
|
|
|
ebb439 |
-send_garp_rarp_update(const struct sbrec_port_binding *binding_rec,
|
|
|
ebb439 |
+send_garp_rarp_update(struct ovsdb_idl_txn *ovnsb_idl_txn,
|
|
|
ebb439 |
+ struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
|
|
|
ebb439 |
+ const struct hmap *local_datapaths,
|
|
|
ebb439 |
+ const struct sbrec_port_binding *binding_rec,
|
|
|
ebb439 |
struct shash *nat_addresses)
|
|
|
ebb439 |
{
|
|
|
ebb439 |
volatile struct garp_rarp_data *garp_rarp = NULL;
|
|
|
ebb439 |
@@ -4044,6 +4096,11 @@ send_garp_rarp_update(const struct sbrec_port_binding *binding_rec,
|
|
|
ebb439 |
laddrs->ipv4_addrs[i].addr,
|
|
|
ebb439 |
binding_rec->datapath->tunnel_key,
|
|
|
ebb439 |
binding_rec->tunnel_key);
|
|
|
ebb439 |
+ send_garp_locally(ovnsb_idl_txn,
|
|
|
ebb439 |
+ sbrec_mac_binding_by_lport_ip,
|
|
|
ebb439 |
+ local_datapaths, binding_rec, laddrs->ea,
|
|
|
ebb439 |
+ laddrs->ipv4_addrs[i].addr);
|
|
|
ebb439 |
+
|
|
|
ebb439 |
}
|
|
|
ebb439 |
free(name);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
@@ -4079,6 +4136,10 @@ send_garp_rarp_update(const struct sbrec_port_binding *binding_rec,
|
|
|
ebb439 |
laddrs.ea, ip,
|
|
|
ebb439 |
binding_rec->datapath->tunnel_key,
|
|
|
ebb439 |
binding_rec->tunnel_key);
|
|
|
ebb439 |
+ if (ip) {
|
|
|
ebb439 |
+ send_garp_locally(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
|
|
|
ebb439 |
+ local_datapaths, binding_rec, laddrs.ea, ip);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
|
|
|
ebb439 |
destroy_lport_addresses(&laddrs);
|
|
|
ebb439 |
break;
|
|
|
ebb439 |
@@ -5355,8 +5416,10 @@ send_garp_rarp_run(struct rconn *swconn, long long int *send_garp_rarp_time)
|
|
|
ebb439 |
/* Called by pinctrl_run(). Runs with in the main ovn-controller
|
|
|
ebb439 |
* thread context. */
|
|
|
ebb439 |
static void
|
|
|
ebb439 |
-send_garp_rarp_prepare(struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
|
|
|
ebb439 |
+send_garp_rarp_prepare(struct ovsdb_idl_txn *ovnsb_idl_txn,
|
|
|
ebb439 |
+ struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
|
|
|
ebb439 |
struct ovsdb_idl_index *sbrec_port_binding_by_name,
|
|
|
ebb439 |
+ struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
|
|
|
ebb439 |
const struct ovsrec_bridge *br_int,
|
|
|
ebb439 |
const struct sbrec_chassis *chassis,
|
|
|
ebb439 |
const struct hmap *local_datapaths,
|
|
|
ebb439 |
@@ -5395,7 +5458,8 @@ send_garp_rarp_prepare(struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
|
|
|
ebb439 |
const struct sbrec_port_binding *pb = lport_lookup_by_name(
|
|
|
ebb439 |
sbrec_port_binding_by_name, iface_id);
|
|
|
ebb439 |
if (pb) {
|
|
|
ebb439 |
- send_garp_rarp_update(pb, &nat_addresses);
|
|
|
ebb439 |
+ send_garp_rarp_update(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
|
|
|
ebb439 |
+ local_datapaths, pb, &nat_addresses);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
@@ -5405,7 +5469,8 @@ send_garp_rarp_prepare(struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
|
|
|
ebb439 |
const struct sbrec_port_binding *pb
|
|
|
ebb439 |
= lport_lookup_by_name(sbrec_port_binding_by_name, gw_port);
|
|
|
ebb439 |
if (pb) {
|
|
|
ebb439 |
- send_garp_rarp_update(pb, &nat_addresses);
|
|
|
ebb439 |
+ send_garp_rarp_update(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
|
|
|
ebb439 |
+ local_datapaths, pb, &nat_addresses);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
--
|
|
|
ebb439 |
1.8.3.1
|
|
|
ebb439 |
|