ARP requests sent through localnet port from physical network are
processed only on chassis hosting the HA group, while requests for
distributed NAT are also distributed across chassis.
Previously, the case where a VIF port exists on the same logical switch
connected to the physical network was not handled. Now, for each VIF port
on such an external switch, ARP requests are processed on the chassis that
hosts that port.
Code simply iterates over all ports within the logical switch, which is
considered acceptable since there are typically not a lot other non-VIF
ports on an external switch.
Fixed I-P: vif ports are processed incrementally, so if switch with connection
to the physical network was created and then a vif port was added,
ls_arp processing node would not work process this update.
Fixes: 1b4058b ("northd: Process external arps on ha chassis.")
Reported-at: https://redhat.atlassian.net/browse/FDP-3767
Signed-off-by: Alexandra Rukomoinikova <[email protected]>
---
northd/northd.c | 25 ++++++++++++++++++
northd/northd.h | 6 +++++
tests/ovn-northd.at | 17 +++++++-----
tests/system-ovn.at | 64 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 106 insertions(+), 6 deletions(-)
diff --git a/northd/northd.c b/northd/northd.c
index 6ff505ca1..f55dbc1d5 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -4812,6 +4812,10 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn
*ovnsb_idl_txn,
struct nbrec_logical_switch_port *new_nbsp = changed_ls->ports[j];
op = ovn_port_find_in_datapath(od, new_nbsp);
+ if (!hmapx_is_empty(&od->phys_ports)) {
+ goto fail;
+ }
+
if (!op) {
if (!lsp_can_be_inc_processed(new_nbsp)) {
goto fail;
@@ -10066,6 +10070,8 @@ build_drop_arp_nd_flows_for_unbound_router_ports(struct
ovn_port *op,
* router connection ports that requires chassis residence.
* ARP requests coming from localnet/l2gateway ports
* allowed for processing on resident chassis only.
+ * If logical switch has VIF port, ARP requests are allowed
+ * to be processed on the chassis hosting this VIF port.
*/
static void
build_lswitch_arp_chassis_resident(const struct ovn_datapath *od,
@@ -10133,6 +10139,25 @@ build_lswitch_arp_chassis_resident(const struct
ovn_datapath *od,
}
}
+ HMAP_FOR_EACH (op, dp_node, &od->ports) {
+ if (!port_is_vif(op)) {
+ continue;
+ }
+
+ for (size_t i = 0; i < op->n_lsp_addrs; i++) {
+ for (size_t j = 0; j < op->lsp_addrs[i].n_ipv4_addrs; j++) {
+ ds_clear(&match);
+ ds_put_format(&match,
+ REGBIT_EXT_ARP " == 1 && arp.tpa == %s "
+ "&& is_chassis_resident(%s)",
+ op->lsp_addrs[i].ipv4_addrs[j].addr_s,
+ op->json_key);
+ ovn_lflow_add(lflows, od, S_SWITCH_IN_APPLY_PORT_SEC, 85,
+ ds_cstr(&match), "next;", ar->lflow_ref);
+ }
+ }
+ }
+
ovn_lflow_add(lflows, od, S_SWITCH_IN_APPLY_PORT_SEC, 70,
REGBIT_EXT_ARP" == 1", "drop;", ar->lflow_ref);
}
diff --git a/northd/northd.h b/northd/northd.h
index 81ab07600..7092f6001 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -1178,6 +1178,12 @@ od_is_centralized(const struct ovn_datapath *od)
return !od->is_distributed;
}
+static inline bool
+port_is_vif(const struct ovn_port *op)
+{
+ return op->sb ? !strcmp(op->sb->type, "") : 0;
+}
+
struct ovn_port *ovn_port_find(const struct hmap *ports, const char *name);
void build_igmp_lflows(struct hmap *igmp_groups,
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 3f237b076..9d1d00380 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -19702,15 +19702,10 @@ check ovn-nbctl lr-add lr1
check ovn-nbctl lrp-add lr1 down_link f0:00:00:00:00:f1 192.168.1.1/24
check ovn-nbctl ls-add ls1
-check ovn-nbctl lsp-add ls1 up_link
check ovn-nbctl lsp-add ls1 down_vif1
check ovn-nbctl lsp-add ls1 down_vif2
check ovn-nbctl lsp-add ls1 down_ext
-
-check ovn-nbctl set Logical_Switch_Port up_link \
- type=router \
- options:router-port=down_link \
- addresses=router
+check ovn-nbctl lsp-add-router-port ls1 up_link down_link
check ovn-nbctl lsp-set-addresses down_vif1 'f0:00:00:00:00:01 192.168.1.101'
check ovn-nbctl lsp-set-addresses down_vif2 'f0:00:00:00:00:02 192.168.1.102'
@@ -19728,6 +19723,8 @@ AT_CHECK([ovn-sbctl lflow-list ls1 | grep
ls_in_apply_port_sec | ovn_strip_lflow
table=??(ls_in_apply_port_sec), priority=50 , match=(reg0[[15]] == 1),
action=(drop;)
table=??(ls_in_apply_port_sec), priority=70 , match=(reg0[[22]] == 1),
action=(drop;)
table=??(ls_in_apply_port_sec), priority=75 , match=(reg0[[22]] == 1 &&
is_chassis_resident("cr-down_link")), action=(next;)
+ table=??(ls_in_apply_port_sec), priority=85 , match=(reg0[[22]] == 1 &&
arp.tpa == 192.168.1.101 && is_chassis_resident("down_vif1")), action=(next;)
+ table=??(ls_in_apply_port_sec), priority=85 , match=(reg0[[22]] == 1 &&
arp.tpa == 192.168.1.102 && is_chassis_resident("down_vif2")), action=(next;)
])
# Check nat adding to dgr attached to logical switch trigger ls-arp flow.
@@ -19740,6 +19737,8 @@ AT_CHECK([ovn-sbctl lflow-list ls1 | grep
ls_in_apply_port_sec | ovn_strip_lflow
table=??(ls_in_apply_port_sec), priority=70 , match=(reg0[[22]] == 1),
action=(drop;)
table=??(ls_in_apply_port_sec), priority=75 , match=(reg0[[22]] == 1 &&
is_chassis_resident("cr-down_link")), action=(next;)
table=??(ls_in_apply_port_sec), priority=85 , match=(reg0[[22]] == 1 &&
arp.tpa == 192.168.0.3 && is_chassis_resident("down_vif1")), action=(next;)
+ table=??(ls_in_apply_port_sec), priority=85 , match=(reg0[[22]] == 1 &&
arp.tpa == 192.168.1.101 && is_chassis_resident("down_vif1")), action=(next;)
+ table=??(ls_in_apply_port_sec), priority=85 , match=(reg0[[22]] == 1 &&
arp.tpa == 192.168.1.102 && is_chassis_resident("down_vif2")), action=(next;)
])
check ovn-nbctl --wait=sb lr-nat-del lr1 dnat_and_snat 192.168.0.3
@@ -19748,6 +19747,8 @@ AT_CHECK([ovn-sbctl lflow-list ls1 | grep
ls_in_apply_port_sec | ovn_strip_lflow
table=??(ls_in_apply_port_sec), priority=50 , match=(reg0[[15]] == 1),
action=(drop;)
table=??(ls_in_apply_port_sec), priority=70 , match=(reg0[[22]] == 1),
action=(drop;)
table=??(ls_in_apply_port_sec), priority=75 , match=(reg0[[22]] == 1 &&
is_chassis_resident("cr-down_link")), action=(next;)
+ table=??(ls_in_apply_port_sec), priority=85 , match=(reg0[[22]] == 1 &&
arp.tpa == 192.168.1.101 && is_chassis_resident("down_vif1")), action=(next;)
+ table=??(ls_in_apply_port_sec), priority=85 , match=(reg0[[22]] == 1 &&
arp.tpa == 192.168.1.102 && is_chassis_resident("down_vif2")), action=(next;)
])
# Check changing logical port type to l2gateway.
@@ -19757,6 +19758,8 @@ AT_CHECK([ovn-sbctl lflow-list ls1 | grep
ls_in_apply_port_sec | ovn_strip_lflow
table=??(ls_in_apply_port_sec), priority=50 , match=(reg0[[15]] == 1),
action=(drop;)
table=??(ls_in_apply_port_sec), priority=70 , match=(reg0[[22]] == 1),
action=(drop;)
table=??(ls_in_apply_port_sec), priority=75 , match=(reg0[[22]] == 1 &&
is_chassis_resident("cr-down_link")), action=(next;)
+ table=??(ls_in_apply_port_sec), priority=85 , match=(reg0[[22]] == 1 &&
arp.tpa == 192.168.1.101 && is_chassis_resident("down_vif1")), action=(next;)
+ table=??(ls_in_apply_port_sec), priority=85 , match=(reg0[[22]] == 1 &&
arp.tpa == 192.168.1.102 && is_chassis_resident("down_vif2")), action=(next;)
])
# Check changing logical port type to vif.
@@ -19773,6 +19776,8 @@ AT_CHECK([ovn-sbctl lflow-list ls1 | grep
ls_in_apply_port_sec | ovn_strip_lflow
table=??(ls_in_apply_port_sec), priority=50 , match=(reg0[[15]] == 1),
action=(drop;)
table=??(ls_in_apply_port_sec), priority=70 , match=(reg0[[22]] == 1),
action=(drop;)
table=??(ls_in_apply_port_sec), priority=75 , match=(reg0[[22]] == 1 &&
is_chassis_resident("cr-down_link")), action=(next;)
+ table=??(ls_in_apply_port_sec), priority=85 , match=(reg0[[22]] == 1 &&
arp.tpa == 192.168.1.101 && is_chassis_resident("down_vif1")), action=(next;)
+ table=??(ls_in_apply_port_sec), priority=85 , match=(reg0[[22]] == 1 &&
arp.tpa == 192.168.1.102 && is_chassis_resident("down_vif2")), action=(next;)
])
# Check changing removing logical port.
diff --git a/tests/system-ovn.at b/tests/system-ovn.at
index 582ed194b..0648c44b6 100644
--- a/tests/system-ovn.at
+++ b/tests/system-ovn.at
@@ -21814,3 +21814,67 @@ OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port
patch-.*/d
AT_CLEANUP
])
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([VIF port connected to localnet network])
+#
+# Topology:
+# (fabric) -- localnet-port -- LS --- DGP(chassis2) -- LR
+# |
+# |
+# VM (chassis1)
+#
+It is expected that ARP requests to this port are allowed on the chesis that
hosts this port.
+
+ovn_start
+OVS_TRAFFIC_VSWITCHD_START()
+ADD_BR([br-int])
+ADD_BR([br-ext])
+
+ovs-ofctl add-flow br-ext action=normal
+# Set external-ids in br-int needed for ovn-controller
+ovs-vsctl \
+ -- set Open_vSwitch . external-ids:system-id=hv1 \
+ -- set Open_vSwitch .
external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
+ -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
+ -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
+ -- set Open_vSwitch . external-ids:ovn-bridge-mappings=phynet:br-ext
+ -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
+
+# Start ovn-controller
+start_daemon ovn-controller
+
+check ovn-nbctl lr-add lr1
+check ovn-nbctl ls-add public
+
+check ovn-nbctl lrp-add lr1 rp-public 00:00:02:01:02:03 172.31.1.1/24
+check ovn-nbctl lsp-add-router-port public public-rp rp-public
+check ovn-nbctl lsp-add-localnet-port public localnet phynet
+check ovn-nbctl lrp-set-gateway-chassis rp-public hv2
+check ovn-nbctl --wait=hv sync
+
+ADD_NAMESPACES(ext)
+ADD_VETH(ext, ext, br-ext, "172.31.1.3/24", "f0:00:00:01:02:04", \
+ "172.31.1.1")
+
+ADD_NAMESPACES(lsp)
+ADD_VETH(lsp, lsp, br-int, "172.31.1.2/24", "f0:00:00:01:02:03", \
+ "172.31.1.1")
+
+check ovn-nbctl lsp-add public lsp
+check ovn-nbctl lsp-set-addresses lsp "f0:00:00:01:02:03 172.31.1.2"
+check ovn-nbctl --wait=hv sync
+
+NS_CHECK_EXEC([ext], [ping -q -c 3 -i 0.3 -w 2 172.31.1.2 | FORMAT_PING], \
+[0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+OVN_CLEANUP_CONTROLLER([hv1])
+OVN_CLEANUP_NORTHD
+as
+OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
+/connection dropped.*/d"])
+
+AT_CLEANUP
+])
--
2.48.1
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev