|
|
ebb439 |
From ab83b9905ec3531b3d8b975f8035ca32d9254091 Mon Sep 17 00:00:00 2001
|
|
|
ebb439 |
From: Dumitru Ceara <dceara@redhat.com>
|
|
|
ebb439 |
Date: Tue, 3 Nov 2020 16:51:21 +0100
|
|
|
ebb439 |
Subject: [PATCH 2/2] ovn-northd: Limit self originated ARP/ND broadcast
|
|
|
ebb439 |
domain.
|
|
|
ebb439 |
|
|
|
ebb439 |
Considering the following large scale deployment:
|
|
|
ebb439 |
external-network -- public-logical-switch -- router-1 -- sw1 -- VIF-1
|
|
|
ebb439 |
-- router-2 -- sw2 -- VIF-2
|
|
|
ebb439 |
...
|
|
|
ebb439 |
-- router-n -- swn -- VIF-n
|
|
|
ebb439 |
|
|
|
ebb439 |
To avoid hitting the max number of OVS resubmits (4K currently) OVN already
|
|
|
ebb439 |
restricted the broadcast domain for ARP/ND requests received from the
|
|
|
ebb439 |
external network and targeting an OVN-owned IP (e.g., owned by router-x).
|
|
|
ebb439 |
Such packets are not flooded in the broadcast domain of the public logical
|
|
|
ebb439 |
switch and instead are forwarded only to the port connecting router-x.
|
|
|
ebb439 |
|
|
|
ebb439 |
However, the max number of OVS resubmits can also be hit in the following
|
|
|
ebb439 |
scenarios:
|
|
|
ebb439 |
- router-x tries to resolve an IP owned by router-y (e.g., VIF-x trying to
|
|
|
ebb439 |
reach VIF-y via floating IP).
|
|
|
ebb439 |
- router-x tries to resolve an IP owned by the external network.
|
|
|
ebb439 |
|
|
|
ebb439 |
Because ARP/ND requests in the above cases are originated by OVN router ports
|
|
|
ebb439 |
they were being flooded in the complete broadcast domain of the public
|
|
|
ebb439 |
logical switch.
|
|
|
ebb439 |
|
|
|
ebb439 |
Instead, we now create a new Multicast_Group for each logical switch and add
|
|
|
ebb439 |
all non-router ports to it. ARP/ND requests are now forwarded to the router
|
|
|
ebb439 |
port that owns the IP (if any) and then flooded in this restricted MC_FLOOD_L2
|
|
|
ebb439 |
broadcast domain.
|
|
|
ebb439 |
|
|
|
ebb439 |
Fixes: 32f5ebb06226 ("ovn-northd: Limit ARP/ND broadcast domain whenever possible.")
|
|
|
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 8c6a5bc21847dab8ccbe18ab1e4b563ddca13379)
|
|
|
ebb439 |
|
|
|
ebb439 |
Change-Id: Ic35a6e7531d09374c0b3ba9c8be3bd986adc7941
|
|
|
ebb439 |
---
|
|
|
ebb439 |
lib/mcast-group-index.h | 1 +
|
|
|
ebb439 |
northd/ovn-northd.8.xml | 19 +++++------
|
|
|
ebb439 |
northd/ovn-northd.c | 84 ++++++++++++++++++++++++++++++-------------------
|
|
|
ebb439 |
tests/ovn.at | 50 ++++++++++++++---------------
|
|
|
ebb439 |
4 files changed, 86 insertions(+), 68 deletions(-)
|
|
|
ebb439 |
|
|
|
ebb439 |
diff --git a/lib/mcast-group-index.h b/lib/mcast-group-index.h
|
|
|
ebb439 |
index ba995ba..72af117 100644
|
|
|
ebb439 |
--- a/lib/mcast-group-index.h
|
|
|
ebb439 |
+++ b/lib/mcast-group-index.h
|
|
|
ebb439 |
@@ -30,6 +30,7 @@ enum ovn_mcast_tunnel_keys {
|
|
|
ebb439 |
OVN_MCAST_MROUTER_FLOOD_TUNNEL_KEY,
|
|
|
ebb439 |
OVN_MCAST_MROUTER_STATIC_TUNNEL_KEY,
|
|
|
ebb439 |
OVN_MCAST_STATIC_TUNNEL_KEY,
|
|
|
ebb439 |
+ OVN_MCAST_FLOOD_L2_TUNNEL_KEY,
|
|
|
ebb439 |
OVN_MIN_IP_MULTICAST,
|
|
|
ebb439 |
OVN_MAX_IP_MULTICAST = OVN_MAX_MULTICAST,
|
|
|
ebb439 |
};
|
|
|
ebb439 |
diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
|
|
|
ebb439 |
index f1c7c9b..8206982 100644
|
|
|
ebb439 |
--- a/northd/ovn-northd.8.xml
|
|
|
ebb439 |
+++ b/northd/ovn-northd.8.xml
|
|
|
ebb439 |
@@ -1367,18 +1367,19 @@ output;
|
|
|
ebb439 |
|
|
|
ebb439 |
|
|
|
ebb439 |
|
|
|
ebb439 |
- Priority-80 flows for each port connected to a logical router
|
|
|
ebb439 |
- matching self originated GARP/ARP request/ND packets. These packets
|
|
|
ebb439 |
- are flooded to the MC_FLOOD which contains all logical
|
|
|
ebb439 |
- ports.
|
|
|
ebb439 |
+ Priority-80 flows for each IP address/VIP/NAT address owned by a
|
|
|
ebb439 |
+ router port connected to the switch. These flows match ARP requests
|
|
|
ebb439 |
+ and ND packets for the specific IP addresses. Matched packets are
|
|
|
ebb439 |
+ forwarded only to the router that owns the IP address and to the
|
|
|
ebb439 |
+ MC_FLOOD_L2 multicast group which contains all non-router
|
|
|
ebb439 |
+ logical ports.
|
|
|
ebb439 |
|
|
|
ebb439 |
|
|
|
ebb439 |
|
|
|
ebb439 |
- Priority-75 flows for each IP address/VIP/NAT address owned by a
|
|
|
ebb439 |
- router port connected to the switch. These flows match ARP requests
|
|
|
ebb439 |
- and ND packets for the specific IP addresses. Matched packets are
|
|
|
ebb439 |
- forwarded only to the router that owns the IP address and, if
|
|
|
ebb439 |
- present, to the localnet port of the logical switch.
|
|
|
ebb439 |
+ Priority-75 flows for each port connected to a logical router
|
|
|
ebb439 |
+ matching self originated ARP request/ND packets. These packets
|
|
|
ebb439 |
+ are flooded to the MC_FLOOD_L2 which contains all
|
|
|
ebb439 |
+ non-router logical ports.
|
|
|
ebb439 |
|
|
|
ebb439 |
|
|
|
ebb439 |
|
|
|
ebb439 |
diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
|
|
|
ebb439 |
index ecbe98e..ce291ec 100644
|
|
|
ebb439 |
--- a/northd/ovn-northd.c
|
|
|
ebb439 |
+++ b/northd/ovn-northd.c
|
|
|
ebb439 |
@@ -1493,6 +1493,12 @@ lsp_is_external(const struct nbrec_logical_switch_port *nbsp)
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
static bool
|
|
|
ebb439 |
+lsp_is_router(const struct nbrec_logical_switch_port *nbsp)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ return !strcmp(nbsp->type, "router");
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+static bool
|
|
|
ebb439 |
lrport_is_enabled(const struct nbrec_logical_router_port *lrport)
|
|
|
ebb439 |
{
|
|
|
ebb439 |
return !lrport->enabled || *lrport->enabled;
|
|
|
ebb439 |
@@ -2424,7 +2430,7 @@ join_logical_ports(struct northd_context *ctx,
|
|
|
ebb439 |
* to their peers. */
|
|
|
ebb439 |
struct ovn_port *op;
|
|
|
ebb439 |
HMAP_FOR_EACH (op, key_node, ports) {
|
|
|
ebb439 |
- if (op->nbsp && !strcmp(op->nbsp->type, "router") && !op->derived) {
|
|
|
ebb439 |
+ if (op->nbsp && lsp_is_router(op->nbsp) && !op->derived) {
|
|
|
ebb439 |
const char *peer_name = smap_get(&op->nbsp->options, "router-port");
|
|
|
ebb439 |
if (!peer_name) {
|
|
|
ebb439 |
continue;
|
|
|
ebb439 |
@@ -3105,7 +3111,7 @@ ovn_port_update_sbrec(struct northd_context *ctx,
|
|
|
ebb439 |
|
|
|
ebb439 |
sbrec_port_binding_set_nat_addresses(op->sb, NULL, 0);
|
|
|
ebb439 |
} else {
|
|
|
ebb439 |
- if (strcmp(op->nbsp->type, "router")) {
|
|
|
ebb439 |
+ if (!lsp_is_router(op->nbsp)) {
|
|
|
ebb439 |
uint32_t queue_id = smap_get_int(
|
|
|
ebb439 |
&op->sb->options, "qdisc_queue_id", 0);
|
|
|
ebb439 |
bool has_qos = port_has_qos_params(&op->nbsp->options);
|
|
|
ebb439 |
@@ -3808,6 +3814,10 @@ static const struct multicast_group mc_static =
|
|
|
ebb439 |
static const struct multicast_group mc_unknown =
|
|
|
ebb439 |
{ MC_UNKNOWN, OVN_MCAST_UNKNOWN_TUNNEL_KEY };
|
|
|
ebb439 |
|
|
|
ebb439 |
+#define MC_FLOOD_L2 "_MC_flood_l2"
|
|
|
ebb439 |
+static const struct multicast_group mc_flood_l2 =
|
|
|
ebb439 |
+ { MC_FLOOD_L2, OVN_MCAST_FLOOD_L2_TUNNEL_KEY };
|
|
|
ebb439 |
+
|
|
|
ebb439 |
static bool
|
|
|
ebb439 |
multicast_group_equal(const struct multicast_group *a,
|
|
|
ebb439 |
const struct multicast_group *b)
|
|
|
ebb439 |
@@ -6372,12 +6382,11 @@ build_lswitch_rport_arp_req_self_orig_flow(struct ovn_port *op,
|
|
|
ebb439 |
sset_add(&all_eth_addrs, nat->external_mac);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- /* Self originated (G)ARP requests/ND need to be flooded as usual.
|
|
|
ebb439 |
- * Determine that packets are self originated by also matching on
|
|
|
ebb439 |
- * source MAC. Matching on ingress port is not reliable in case this
|
|
|
ebb439 |
- * is a VLAN-backed network.
|
|
|
ebb439 |
- * Priority: 80.
|
|
|
ebb439 |
+ /* Self originated ARP requests/ND need to be flooded to the L2 domain
|
|
|
ebb439 |
+ * (except on router ports). Determine that packets are self originated
|
|
|
ebb439 |
+ * by also matching on source MAC. Matching on ingress port is not
|
|
|
ebb439 |
+ * reliable in case this is a VLAN-backed network.
|
|
|
ebb439 |
+ * Priority: 75.
|
|
|
ebb439 |
*/
|
|
|
ebb439 |
const char *eth_addr;
|
|
|
ebb439 |
|
|
|
ebb439 |
@@ -6393,7 +6402,7 @@ build_lswitch_rport_arp_req_self_orig_flow(struct ovn_port *op,
|
|
|
ebb439 |
ds_cstr(ð_src));
|
|
|
ebb439 |
ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, priority,
|
|
|
ebb439 |
ds_cstr(&match),
|
|
|
ebb439 |
- "outport = \""MC_FLOOD"\"; output;");
|
|
|
ebb439 |
+ "outport = \""MC_FLOOD_L2"\"; output;");
|
|
|
ebb439 |
|
|
|
ebb439 |
sset_destroy(&all_eth_addrs);
|
|
|
ebb439 |
ds_destroy(ð_src);
|
|
|
ebb439 |
@@ -6439,14 +6448,16 @@ build_lswitch_rport_arp_req_flow_for_ip(struct sset *ips,
|
|
|
ebb439 |
ds_chomp(&match, ',');
|
|
|
ebb439 |
ds_put_cstr(&match, "}");
|
|
|
ebb439 |
|
|
|
ebb439 |
- /* Send a the packet only to the router pipeline and skip flooding it
|
|
|
ebb439 |
- * in the broadcast domain (except for the localnet port).
|
|
|
ebb439 |
+ /* Send a the packet to the router pipeline. If the switch has non-router
|
|
|
ebb439 |
+ * ports then flood it there as well.
|
|
|
ebb439 |
*/
|
|
|
ebb439 |
- for (size_t i = 0; i < od->n_localnet_ports; i++) {
|
|
|
ebb439 |
- ds_put_format(&actions, "clone { outport = %s; output; }; ",
|
|
|
ebb439 |
- od->localnet_ports[i]->json_key);
|
|
|
ebb439 |
+ if (od->n_router_ports != od->nbs->n_ports) {
|
|
|
ebb439 |
+ ds_put_format(&actions, "clone {outport = %s; output; }; "
|
|
|
ebb439 |
+ "outport = \""MC_FLOOD_L2"\"; output;",
|
|
|
ebb439 |
+ patch_op->json_key);
|
|
|
ebb439 |
+ } else {
|
|
|
ebb439 |
+ ds_put_format(&actions, "outport = %s; output;", patch_op->json_key);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
- ds_put_format(&actions, "outport = %s; output;", patch_op->json_key);
|
|
|
ebb439 |
ovn_lflow_add_with_hint(lflows, od, S_SWITCH_IN_L2_LKUP, priority,
|
|
|
ebb439 |
ds_cstr(&match), ds_cstr(&actions), stage_hint);
|
|
|
ebb439 |
|
|
|
ebb439 |
@@ -6476,14 +6487,9 @@ build_lswitch_rport_arp_req_flows(struct ovn_port *op,
|
|
|
ebb439 |
return;
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
- /* Self originated (G)ARP requests/ND need to be flooded as usual.
|
|
|
ebb439 |
- * Priority: 80.
|
|
|
ebb439 |
- */
|
|
|
ebb439 |
- build_lswitch_rport_arp_req_self_orig_flow(op, 80, sw_od, lflows);
|
|
|
ebb439 |
-
|
|
|
ebb439 |
/* Forward ARP requests for owned IP addresses (L3, VIP, NAT) only to this
|
|
|
ebb439 |
* router port.
|
|
|
ebb439 |
- * Priority: 75.
|
|
|
ebb439 |
+ * Priority: 80.
|
|
|
ebb439 |
*/
|
|
|
ebb439 |
struct sset all_ips_v4 = SSET_INITIALIZER(&all_ips_v4);
|
|
|
ebb439 |
struct sset all_ips_v6 = SSET_INITIALIZER(&all_ips_v6);
|
|
|
ebb439 |
@@ -6558,17 +6564,28 @@ build_lswitch_rport_arp_req_flows(struct ovn_port *op,
|
|
|
ebb439 |
|
|
|
ebb439 |
if (!sset_is_empty(&all_ips_v4)) {
|
|
|
ebb439 |
build_lswitch_rport_arp_req_flow_for_ip(&all_ips_v4, AF_INET, sw_op,
|
|
|
ebb439 |
- sw_od, 75, lflows,
|
|
|
ebb439 |
+ sw_od, 80, lflows,
|
|
|
ebb439 |
stage_hint);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
if (!sset_is_empty(&all_ips_v6)) {
|
|
|
ebb439 |
build_lswitch_rport_arp_req_flow_for_ip(&all_ips_v6, AF_INET6, sw_op,
|
|
|
ebb439 |
- sw_od, 75, lflows,
|
|
|
ebb439 |
+ sw_od, 80, lflows,
|
|
|
ebb439 |
stage_hint);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
sset_destroy(&all_ips_v4);
|
|
|
ebb439 |
sset_destroy(&all_ips_v6);
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ /* Self originated ARP requests/ND need to be flooded as usual.
|
|
|
ebb439 |
+ *
|
|
|
ebb439 |
+ * However, if the switch doesn't have any non-router ports we shouldn't
|
|
|
ebb439 |
+ * even try to flood.
|
|
|
ebb439 |
+ *
|
|
|
ebb439 |
+ * Priority: 75.
|
|
|
ebb439 |
+ */
|
|
|
ebb439 |
+ if (sw_od->n_router_ports != sw_od->nbs->n_ports) {
|
|
|
ebb439 |
+ build_lswitch_rport_arp_req_self_orig_flow(op, 75, sw_od, lflows);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
static void
|
|
|
ebb439 |
@@ -6908,7 +6925,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
|
|
|
ebb439 |
* - port type is localport
|
|
|
ebb439 |
*/
|
|
|
ebb439 |
if (check_lsp_is_up &&
|
|
|
ebb439 |
- !lsp_is_up(op->nbsp) && strcmp(op->nbsp->type, "router") &&
|
|
|
ebb439 |
+ !lsp_is_up(op->nbsp) && !lsp_is_router(op->nbsp) &&
|
|
|
ebb439 |
strcmp(op->nbsp->type, "localport")) {
|
|
|
ebb439 |
continue;
|
|
|
ebb439 |
}
|
|
|
ebb439 |
@@ -6983,8 +7000,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
|
|
|
ebb439 |
"flags.loopback = 1; "
|
|
|
ebb439 |
"output; "
|
|
|
ebb439 |
"};",
|
|
|
ebb439 |
- !strcmp(op->nbsp->type, "router") ?
|
|
|
ebb439 |
- "nd_na_router" : "nd_na",
|
|
|
ebb439 |
+ lsp_is_router(op->nbsp) ? "nd_na_router" : "nd_na",
|
|
|
ebb439 |
op->lsp_addrs[i].ea_s,
|
|
|
ebb439 |
op->lsp_addrs[i].ipv6_addrs[j].addr_s,
|
|
|
ebb439 |
op->lsp_addrs[i].ipv6_addrs[j].addr_s,
|
|
|
ebb439 |
@@ -7066,7 +7082,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
|
|
|
ebb439 |
continue;
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
- if (!lsp_is_enabled(op->nbsp) || !strcmp(op->nbsp->type, "router")) {
|
|
|
ebb439 |
+ if (!lsp_is_enabled(op->nbsp) || lsp_is_router(op->nbsp)) {
|
|
|
ebb439 |
/* Don't add the DHCP flows if the port is not enabled or if the
|
|
|
ebb439 |
* port is a router port. */
|
|
|
ebb439 |
continue;
|
|
|
ebb439 |
@@ -7326,7 +7342,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
|
|
|
ebb439 |
* broadcast flooding of ARP/ND requests in table 19. We direct the
|
|
|
ebb439 |
* requests only to the router port that owns the IP address.
|
|
|
ebb439 |
*/
|
|
|
ebb439 |
- if (!strcmp(op->nbsp->type, "router")) {
|
|
|
ebb439 |
+ if (lsp_is_router(op->nbsp)) {
|
|
|
ebb439 |
build_lswitch_rport_arp_req_flows(op->peer, op->od, op, lflows,
|
|
|
ebb439 |
&op->nbsp->header_);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
@@ -10786,7 +10802,7 @@ build_arp_resolve_flows_for_lrouter_port(
|
|
|
ebb439 |
&op->nbrp->header_);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
}
|
|
|
ebb439 |
- } else if (op->od->n_router_ports && strcmp(op->nbsp->type, "router")
|
|
|
ebb439 |
+ } else if (op->od->n_router_ports && !lsp_is_router(op->nbsp)
|
|
|
ebb439 |
&& strcmp(op->nbsp->type, "virtual")) {
|
|
|
ebb439 |
/* This is a logical switch port that backs a VM or a container.
|
|
|
ebb439 |
* Extract its addresses. For each of the address, go through all
|
|
|
ebb439 |
@@ -10870,7 +10886,7 @@ build_arp_resolve_flows_for_lrouter_port(
|
|
|
ebb439 |
}
|
|
|
ebb439 |
}
|
|
|
ebb439 |
}
|
|
|
ebb439 |
- } else if (op->od->n_router_ports && strcmp(op->nbsp->type, "router")
|
|
|
ebb439 |
+ } else if (op->od->n_router_ports && !lsp_is_router(op->nbsp)
|
|
|
ebb439 |
&& !strcmp(op->nbsp->type, "virtual")) {
|
|
|
ebb439 |
/* This is a virtual port. Add ARP replies for the virtual ip with
|
|
|
ebb439 |
* the mac of the present active virtual parent.
|
|
|
ebb439 |
@@ -10974,7 +10990,7 @@ build_arp_resolve_flows_for_lrouter_port(
|
|
|
ebb439 |
}
|
|
|
ebb439 |
}
|
|
|
ebb439 |
}
|
|
|
ebb439 |
- } else if (!strcmp(op->nbsp->type, "router")) {
|
|
|
ebb439 |
+ } else if (lsp_is_router(op->nbsp)) {
|
|
|
ebb439 |
/* This is a logical switch port that connects to a router. */
|
|
|
ebb439 |
|
|
|
ebb439 |
/* The peer of this switch port is the router port for which
|
|
|
ebb439 |
@@ -11929,6 +11945,10 @@ build_mcast_groups(struct northd_context *ctx,
|
|
|
ebb439 |
} else if (op->nbsp && lsp_is_enabled(op->nbsp)) {
|
|
|
ebb439 |
ovn_multicast_add(mcast_groups, &mc_flood, op);
|
|
|
ebb439 |
|
|
|
ebb439 |
+ if (!lsp_is_router(op->nbsp)) {
|
|
|
ebb439 |
+ ovn_multicast_add(mcast_groups, &mc_flood_l2, op);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+
|
|
|
ebb439 |
/* If this port is connected to a multicast router then add it
|
|
|
ebb439 |
* to the MC_MROUTER_FLOOD group.
|
|
|
ebb439 |
*/
|
|
|
ebb439 |
@@ -12372,7 +12392,7 @@ handle_port_binding_changes(struct northd_context *ctx, struct hmap *ports,
|
|
|
ebb439 |
continue;
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
- bool up = (sb->chassis || !strcmp(op->nbsp->type, "router"));
|
|
|
ebb439 |
+ bool up = (sb->chassis || lsp_is_router(op->nbsp));
|
|
|
ebb439 |
if (!op->nbsp->up || *op->nbsp->up != up) {
|
|
|
ebb439 |
nbrec_logical_switch_port_set_up(op->nbsp, &up, 1);
|
|
|
ebb439 |
}
|
|
|
ebb439 |
diff --git a/tests/ovn.at b/tests/ovn.at
|
|
|
ebb439 |
index ea4a6da..180fb91 100644
|
|
|
ebb439 |
--- a/tests/ovn.at
|
|
|
ebb439 |
+++ b/tests/ovn.at
|
|
|
ebb439 |
@@ -3626,7 +3626,7 @@ test_ip() {
|
|
|
ebb439 |
done
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
-# test_arp INPORT SHA SPA TPA FLOOD [REPLY_HA]
|
|
|
ebb439 |
+# test_arp INPORT SHA SPA TPA [REPLY_HA]
|
|
|
ebb439 |
#
|
|
|
ebb439 |
# Causes a packet to be received on INPORT. The packet is an ARP
|
|
|
ebb439 |
# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
|
|
|
ebb439 |
@@ -3637,25 +3637,21 @@ test_ip() {
|
|
|
ebb439 |
# SHA and REPLY_HA are each 12 hex digits.
|
|
|
ebb439 |
# SPA and TPA are each 8 hex digits.
|
|
|
ebb439 |
test_arp() {
|
|
|
ebb439 |
- local inport=$1 sha=$2 spa=$3 tpa=$4 flood=$5 reply_ha=$6
|
|
|
ebb439 |
+ local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
|
|
|
ebb439 |
local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
|
|
|
ebb439 |
hv=hv`vif_to_hv $inport`
|
|
|
ebb439 |
as $hv ovs-appctl netdev-dummy/receive vif$inport $request
|
|
|
ebb439 |
as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
|
|
|
ebb439 |
|
|
|
ebb439 |
# Expect to receive the broadcast ARP on the other logical switch ports if
|
|
|
ebb439 |
- # IP address is not configured on the switch patch port or on the router
|
|
|
ebb439 |
- # port (i.e, $flood == 1).
|
|
|
ebb439 |
+ # IP address is not configured to the switch patch port.
|
|
|
ebb439 |
local i=`vif_to_ls $inport`
|
|
|
ebb439 |
local j k
|
|
|
ebb439 |
for j in 1 2 3; do
|
|
|
ebb439 |
for k in 1 2 3; do
|
|
|
ebb439 |
- # Skip ingress port.
|
|
|
ebb439 |
- if test $i$j$k == $inport; then
|
|
|
ebb439 |
- continue
|
|
|
ebb439 |
- fi
|
|
|
ebb439 |
-
|
|
|
ebb439 |
- if test X$flood == X1; then
|
|
|
ebb439 |
+ # 192.168.33.254 is configured to the switch patch port for lrp33,
|
|
|
ebb439 |
+ # so no ARP flooding expected for it.
|
|
|
ebb439 |
+ if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
|
|
|
ebb439 |
echo $request >> $i$j$k.expected
|
|
|
ebb439 |
fi
|
|
|
ebb439 |
done
|
|
|
ebb439 |
@@ -3792,9 +3788,9 @@ for i in 1 2 3; do
|
|
|
ebb439 |
otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
|
|
|
ebb439 |
externalip=`ip_to_hex 1 2 3 4` # Some other IP not in subnet
|
|
|
ebb439 |
|
|
|
ebb439 |
- test_arp $i$j$k $smac $sip $rip 0 $rmac #4
|
|
|
ebb439 |
- test_arp $i$j$k $smac $otherip $rip 0 $rmac #5
|
|
|
ebb439 |
- test_arp $i$j$k $smac $sip $otherip 1 #6
|
|
|
ebb439 |
+ test_arp $i$j$k $smac $sip $rip $rmac #4
|
|
|
ebb439 |
+ test_arp $i$j$k $smac $otherip $rip $rmac #5
|
|
|
ebb439 |
+ test_arp $i$j$k $smac $sip $otherip #6
|
|
|
ebb439 |
|
|
|
ebb439 |
# When rip is 192.168.33.254, ARP request from externalip won't be
|
|
|
ebb439 |
# filtered, because 192.168.33.254 is configured to switch peer port
|
|
|
ebb439 |
@@ -3803,7 +3799,7 @@ for i in 1 2 3; do
|
|
|
ebb439 |
if test $i = 3 && test $j = 3; then
|
|
|
ebb439 |
lrp33_rsp=$rmac
|
|
|
ebb439 |
fi
|
|
|
ebb439 |
- test_arp $i$j$k $smac $externalip $rip 0 $lrp33_rsp #7
|
|
|
ebb439 |
+ test_arp $i$j$k $smac $externalip $rip $lrp33_rsp #7
|
|
|
ebb439 |
|
|
|
ebb439 |
# MAC binding should be learned from ARP request.
|
|
|
ebb439 |
host_mac_pretty=f0:00:00:00:0$i:$j$k
|
|
|
ebb439 |
@@ -19895,7 +19891,7 @@ match_r1_metadata="metadata=0x${r1_dp_key}"
|
|
|
ebb439 |
send_arp_request 1 0 ${src_mac} $(ip_to_hex 10 0 0 254) $(ip_to_hex 10 0 0 1)
|
|
|
ebb439 |
|
|
|
ebb439 |
# Verify that the ARP request is sent only to rtr1.
|
|
|
ebb439 |
-match_arp_req="priority=75.*${match_sw_metadata}.*arp_tpa=10.0.0.1,arp_op=1"
|
|
|
ebb439 |
+match_arp_req="priority=80.*${match_sw_metadata}.*arp_tpa=10.0.0.1,arp_op=1"
|
|
|
ebb439 |
match_send_rtr1="load:0x${r1_tnl_key}->NXM_NX_REG15"
|
|
|
ebb439 |
match_send_rtr2="load:0x${r2_tnl_key}->NXM_NX_REG15"
|
|
|
ebb439 |
|
|
|
ebb439 |
@@ -19919,7 +19915,7 @@ dst_ipv6=00100000000000000000000000000001
|
|
|
ebb439 |
send_nd_ns 1 0 ${src_mac} ${src_ipv6} ${dst_ipv6} 751d
|
|
|
ebb439 |
|
|
|
ebb439 |
# Verify that the ND_NS is sent only to rtr1.
|
|
|
ebb439 |
-match_nd_ns="priority=75.*${match_sw_metadata}.*icmp_type=135.*nd_target=10::1"
|
|
|
ebb439 |
+match_nd_ns="priority=80.*${match_sw_metadata}.*icmp_type=135.*nd_target=10::1"
|
|
|
ebb439 |
|
|
|
ebb439 |
as hv1
|
|
|
ebb439 |
OVS_WAIT_UNTIL([
|
|
|
ebb439 |
@@ -19951,7 +19947,7 @@ ovn-nbctl --wait=hv sync
|
|
|
ebb439 |
send_arp_request 1 0 ${src_mac} $(ip_to_hex 10 0 0 254) $(ip_to_hex 10 0 0 11)
|
|
|
ebb439 |
|
|
|
ebb439 |
# Verify that the ARP request is sent only to rtr1.
|
|
|
ebb439 |
-match_arp_req="priority=75.*${match_sw_metadata}.*arp_tpa=10.0.0.11,arp_op=1"
|
|
|
ebb439 |
+match_arp_req="priority=80.*${match_sw_metadata}.*arp_tpa=10.0.0.11,arp_op=1"
|
|
|
ebb439 |
match_send_rtr1="load:0x${r1_tnl_key}->NXM_NX_REG15"
|
|
|
ebb439 |
match_send_rtr2="load:0x${r2_tnl_key}->NXM_NX_REG15"
|
|
|
ebb439 |
|
|
|
ebb439 |
@@ -19975,7 +19971,7 @@ dst_ipv6=00100000000000000000000000000011
|
|
|
ebb439 |
send_nd_ns 1 0 ${src_mac} ${src_ipv6} ${dst_ipv6} 751d
|
|
|
ebb439 |
|
|
|
ebb439 |
# Verify that the ND_NS is sent only to rtr1.
|
|
|
ebb439 |
-match_nd_ns="priority=75.*${match_sw_metadata}.*icmp_type=135.*nd_target=10::11"
|
|
|
ebb439 |
+match_nd_ns="priority=80.*${match_sw_metadata}.*icmp_type=135.*nd_target=10::11"
|
|
|
ebb439 |
|
|
|
ebb439 |
as hv1
|
|
|
ebb439 |
OVS_WAIT_UNTIL([
|
|
|
ebb439 |
@@ -20015,7 +20011,7 @@ ovn-nbctl --wait=hv sync
|
|
|
ebb439 |
# - 10.0.0.22, 10::22 - LB VIPs.
|
|
|
ebb439 |
# - 10.0.0.222, 10::222 - DNAT IPs.
|
|
|
ebb439 |
as hv1
|
|
|
ebb439 |
-AT_CHECK([ovs-ofctl dump-flows br-int | grep -E "priority=75,.*${match_sw_metadata}" | grep -oE "arp_tpa=[[0-9.]]+" | sort], [0], [dnl
|
|
|
ebb439 |
+AT_CHECK([ovs-ofctl dump-flows br-int | grep -E "priority=80,.*${match_sw_metadata}" | grep -oE "arp_tpa=[[0-9.]]+" | sort], [0], [dnl
|
|
|
ebb439 |
arp_tpa=10.0.0.1
|
|
|
ebb439 |
arp_tpa=10.0.0.11
|
|
|
ebb439 |
arp_tpa=10.0.0.111
|
|
|
ebb439 |
@@ -20025,7 +20021,7 @@ arp_tpa=10.0.0.2
|
|
|
ebb439 |
arp_tpa=10.0.0.22
|
|
|
ebb439 |
arp_tpa=10.0.0.222
|
|
|
ebb439 |
])
|
|
|
ebb439 |
-AT_CHECK([ovs-ofctl dump-flows br-int | grep -E "priority=75,.*${match_sw_metadata}" | grep -oE "nd_target=[[0-9a-f:]]+" | sort], [0], [dnl
|
|
|
ebb439 |
+AT_CHECK([ovs-ofctl dump-flows br-int | grep -E "priority=80,.*${match_sw_metadata}" | grep -oE "nd_target=[[0-9a-f:]]+" | sort], [0], [dnl
|
|
|
ebb439 |
nd_target=10::1
|
|
|
ebb439 |
nd_target=10::11
|
|
|
ebb439 |
nd_target=10::111
|
|
|
ebb439 |
@@ -20041,10 +20037,10 @@ nd_target=fe80::200:ff:fe00:200
|
|
|
ebb439 |
# For sw1-rtr1:
|
|
|
ebb439 |
# - 20.0.0.1, 20::1, fe80::200:1ff:fe00:0 - interface IPs.
|
|
|
ebb439 |
as hv1
|
|
|
ebb439 |
-AT_CHECK([ovs-ofctl dump-flows br-int | grep -E "priority=75,.*${match_sw1_metadata}" | grep -oE "arp_tpa=[[0-9.]]+" | sort], [0], [dnl
|
|
|
ebb439 |
+AT_CHECK([ovs-ofctl dump-flows br-int | grep -E "priority=80,.*${match_sw1_metadata}" | grep -oE "arp_tpa=[[0-9.]]+" | sort], [0], [dnl
|
|
|
ebb439 |
arp_tpa=20.0.0.1
|
|
|
ebb439 |
])
|
|
|
ebb439 |
-AT_CHECK([ovs-ofctl dump-flows br-int | grep -E "priority=75,.*${match_sw1_metadata}" | grep -oE "nd_target=[[0-9a-f:]]+" | sort], [0], [dnl
|
|
|
ebb439 |
+AT_CHECK([ovs-ofctl dump-flows br-int | grep -E "priority=80,.*${match_sw1_metadata}" | grep -oE "nd_target=[[0-9a-f:]]+" | sort], [0], [dnl
|
|
|
ebb439 |
nd_target=20::1
|
|
|
ebb439 |
nd_target=fe80::200:1ff:fe00:0
|
|
|
ebb439 |
])
|
|
|
ebb439 |
@@ -20056,13 +20052,13 @@ nd_target=fe80::200:1ff:fe00:0
|
|
|
ebb439 |
# - 00:00:00:01:00:00 - dnat_and_snat external MAC.
|
|
|
ebb439 |
# - 00:00:00:02:00:00 - dnat_and_snat external MAC.
|
|
|
ebb439 |
as hv1
|
|
|
ebb439 |
-AT_CHECK([ovs-ofctl dump-flows br-int | grep -E "priority=80,.*${match_sw_metadata}.*arp_op=1" | grep -oE "dl_src=[[0-9a-f:]]+" | sort], [0], [dnl
|
|
|
ebb439 |
+AT_CHECK([ovs-ofctl dump-flows br-int | grep -E "priority=75,.*${match_sw_metadata}.*arp_op=1" | grep -oE "dl_src=[[0-9a-f:]]+" | sort], [0], [dnl
|
|
|
ebb439 |
dl_src=00:00:00:00:01:00
|
|
|
ebb439 |
dl_src=00:00:00:00:02:00
|
|
|
ebb439 |
dl_src=00:00:00:01:00:00
|
|
|
ebb439 |
dl_src=00:00:00:02:00:00
|
|
|
ebb439 |
])
|
|
|
ebb439 |
-AT_CHECK([ovs-ofctl dump-flows br-int | grep -E "priority=80,.*${match_sw_metadata}.*icmp_type=135" | grep -oE "dl_src=[[0-9a-f:]]+" | sort], [0], [dnl
|
|
|
ebb439 |
+AT_CHECK([ovs-ofctl dump-flows br-int | grep -E "priority=75,.*${match_sw_metadata}.*icmp_type=135" | grep -oE "dl_src=[[0-9a-f:]]+" | sort], [0], [dnl
|
|
|
ebb439 |
dl_src=00:00:00:00:01:00
|
|
|
ebb439 |
dl_src=00:00:00:00:02:00
|
|
|
ebb439 |
dl_src=00:00:00:01:00:00
|
|
|
ebb439 |
@@ -20072,7 +20068,7 @@ dl_src=00:00:00:02:00:00
|
|
|
ebb439 |
# Self originated ARP/NS with SMACs owned by rtr1-sw1 should be flooded:
|
|
|
ebb439 |
# - 00:00:01:00:00:00 - interface MAC.
|
|
|
ebb439 |
as hv1
|
|
|
ebb439 |
-AT_CHECK([ovs-ofctl dump-flows br-int | grep -E "priority=80,.*${match_sw1_metadata}.*arp_op=1" | grep -oE "dl_src=[[0-9a-f:]]+" | sort], [0], [dnl
|
|
|
ebb439 |
+AT_CHECK([ovs-ofctl dump-flows br-int | grep -E "priority=75,.*${match_sw1_metadata}.*arp_op=1" | grep -oE "dl_src=[[0-9a-f:]]+" | sort], [0], [dnl
|
|
|
ebb439 |
dl_src=00:00:01:00:00:00
|
|
|
ebb439 |
])
|
|
|
ebb439 |
|
|
|
ebb439 |
@@ -20080,7 +20076,7 @@ dl_src=00:00:01:00:00:00
|
|
|
ebb439 |
send_arp_request 1 0 ${src_mac} $(ip_to_hex 10 0 0 254) $(ip_to_hex 10 0 0 111)
|
|
|
ebb439 |
|
|
|
ebb439 |
# Verify that the ARP request is sent only to rtr1.
|
|
|
ebb439 |
-match_arp_req="priority=75.*${match_sw_metadata}.*arp_tpa=10.0.0.111,arp_op=1"
|
|
|
ebb439 |
+match_arp_req="priority=80.*${match_sw_metadata}.*arp_tpa=10.0.0.111,arp_op=1"
|
|
|
ebb439 |
match_send_rtr1="load:0x${r1_tnl_key}->NXM_NX_REG15"
|
|
|
ebb439 |
match_send_rtr2="load:0x${r2_tnl_key}->NXM_NX_REG15"
|
|
|
ebb439 |
|
|
|
ebb439 |
@@ -20144,7 +20140,7 @@ dst_ipv6=00100000000000000000000000000111
|
|
|
ebb439 |
send_nd_ns 1 0 ${src_mac} ${src_ipv6} ${dst_ipv6} 751d
|
|
|
ebb439 |
|
|
|
ebb439 |
# Verify that the ND_NS is sent only to rtr1.
|
|
|
ebb439 |
-match_nd_ns="priority=75.*${match_sw_metadata}.*icmp_type=135.*nd_target=10::111"
|
|
|
ebb439 |
+match_nd_ns="priority=80.*${match_sw_metadata}.*icmp_type=135.*nd_target=10::111"
|
|
|
ebb439 |
|
|
|
ebb439 |
as hv1
|
|
|
ebb439 |
OVS_WAIT_UNTIL([
|
|
|
ebb439 |
--
|
|
|
ebb439 |
1.8.3.1
|
|
|
ebb439 |
|