@@ -180,7 +180,8 @@ static void
put_encapsulation(enum mf_field_id mff_ovn_geneve,
const struct chassis_tunnel *tun,
const struct sbrec_datapath_binding *datapath,
- uint16_t outport, struct ofpbuf *ofpacts)
+ uint16_t outport, bool is_ramp_switch,
+ struct ofpbuf *ofpacts)
{
if (tun->type == GENEVE) {
put_load(datapath->tunnel_key, MFF_TUN_ID, 0, 24, ofpacts);
@@ -191,7 +192,10 @@ put_encapsulation(enum mf_field_id mff_ovn_geneve,
MFF_TUN_ID, 0, 64, ofpacts);
put_move(MFF_LOG_INPORT, 0, MFF_TUN_ID, 40, 15, ofpacts);
} else if (tun->type == VXLAN) {
- put_load(datapath->tunnel_key, MFF_TUN_ID, 0, 24, ofpacts);
+ uint64_t vni = (is_ramp_switch?
+ datapath->tunnel_key :
+ datapath->tunnel_key | ((uint64_t) outport << 12));
+ put_load(vni, MFF_TUN_ID, 0, 24, ofpacts);
} else {
OVS_NOT_REACHED();
}
@@ -323,8 +327,9 @@ put_remote_port_redirect_overlay(const struct
if (!rem_tun) {
return;
}
- put_encapsulation(mff_ovn_geneve, tun, binding->datapath,
- port_key, ofpacts_p);
+ put_encapsulation(mff_ovn_geneve, tun, binding->datapath, port_key,
+ !strcmp(binding->type, "vtep"),
+ ofpacts_p);
/* Output to tunnel. */
ofpact_put_OUTPUT(ofpacts_p)->port = rem_tun->ofport;
} else {
@@ -360,8 +365,9 @@ put_remote_port_redirect_overlay(const struct
return;
}
- put_encapsulation(mff_ovn_geneve, tun, binding->datapath,
- port_key, ofpacts_p);
+ put_encapsulation(mff_ovn_geneve, tun, binding->datapath, port_key,
+ !strcmp(binding->type, "vtep"),
+ ofpacts_p);
/* Output to tunnels with active/backup */
struct ofpact_bundle *bundle = ofpact_put_BUNDLE(ofpacts_p);
@@ -1370,7 +1376,7 @@ consider_mc_group(enum mf_field_id mff_ovn_geneve,
if (!prev || tun->type != prev->type) {
put_encapsulation(mff_ovn_geneve, tun, mc->datapath,
- mc->tunnel_key, &remote_ofpacts);
+ mc->tunnel_key, true, &remote_ofpacts);
prev = tun;
}
ofpact_put_OUTPUT(&remote_ofpacts)->port = tun->ofport;
@@ -1615,11 +1621,12 @@ physical_run(struct physical_ctx *p_ctx,
* Process packets that arrive from a remote hypervisor (by matching
* on tunnel in_port). */
- /* Add flows for Geneve and STT encapsulations. These
- * encapsulations have metadata about the ingress and egress logical
- * ports. We set MFF_LOG_DATAPATH, MFF_LOG_INPORT, and
- * MFF_LOG_OUTPORT from the tunnel key data, then resubmit to table
- * 33 to handle packets to the local hypervisor. */
+ /* Add flows for Geneve, STT and VXLAN encapsulations. Geneve and STT
+ * encapsulations have metadata about the ingress and egress logical ports.
+ * VXLAN encapsulations have metadata about the egress logical port only.
+ * We set MFF_LOG_DATAPATH, MFF_LOG_INPORT, and MFF_LOG_OUTPORT from the
+ * tunnel key data where possible, then resubmit to table 33 to handle
+ * packets to the local hypervisor. */
HMAP_FOR_EACH (tun, hmap_node, &tunnels) {
struct match match = MATCH_CATCHALL_INITIALIZER;
match_set_in_port(&match, tun->ofport);
@@ -1636,8 +1643,10 @@ physical_run(struct physical_ctx *p_ctx,
put_move(MFF_TUN_ID, 24, MFF_LOG_OUTPORT, 0, 16, &ofpacts);
put_move(MFF_TUN_ID, 0, MFF_LOG_DATAPATH, 0, 24, &ofpacts);
} else if (tun->type == VXLAN) {
- /* We'll handle VXLAN later. */
- continue;
+ /* Add flows for non-VTEP tunnels. Split VNI into two 12-bit
+ * sections and use them for datapath and outport IDs. */
+ put_move(MFF_TUN_ID, 12, MFF_LOG_OUTPORT, 0, 12, &ofpacts);
+ put_move(MFF_TUN_ID, 0, MFF_LOG_DATAPATH, 0, 12, &ofpacts);
} else {
OVS_NOT_REACHED();
}
@@ -1648,11 +1657,7 @@ physical_run(struct physical_ctx *p_ctx,
&ofpacts, hc_uuid);
}
- /* Add flows for VXLAN encapsulations. Due to the limited amount of
- * metadata, we only support VXLAN for connections to gateways. The
- * VNI is used to populate MFF_LOG_DATAPATH. The gateway's logical
- * port is set to MFF_LOG_INPORT. Then the packet is resubmitted to
- * table 16 to determine the logical egress port. */
+ /* Handle ramp switch encapsulations. */
HMAP_FOR_EACH (tun, hmap_node, &tunnels) {
if (tun->type != VXLAN) {
continue;
@@ -1660,7 +1665,9 @@ physical_run(struct physical_ctx *p_ctx,
SBREC_PORT_BINDING_TABLE_FOR_EACH (binding,
p_ctx->port_binding_table) {
- struct match match = MATCH_CATCHALL_INITIALIZER;
+ if (strcmp(binding->type, "vtep")) {
+ continue;
+ }
if (!binding->chassis ||
!encaps_tunnel_id_match(tun->chassis_id,
@@ -1668,18 +1675,24 @@ physical_run(struct physical_ctx *p_ctx,
continue;
}
+ struct match match = MATCH_CATCHALL_INITIALIZER;
match_set_in_port(&match, tun->ofport);
+ ofpbuf_clear(&ofpacts);
+
+ /* Add flows for ramp switches. The VNI is used to populate
+ * MFF_LOG_DATAPATH. The gateway's logical port is set to
+ * MFF_LOG_INPORT. Then the packet is resubmitted to table 8
+ * to determine the logical egress port. */
match_set_tun_id(&match, htonll(binding->datapath->tunnel_key));
- ofpbuf_clear(&ofpacts);
put_move(MFF_TUN_ID, 0, MFF_LOG_DATAPATH, 0, 24, &ofpacts);
put_load(binding->tunnel_key, MFF_LOG_INPORT, 0, 15, &ofpacts);
- /* For packets received from a vxlan tunnel, set a flag to that
+ /* For packets received from a ramp tunnel, set a flag to that
* effect. */
- put_load(1, MFF_LOG_FLAGS, MLF_RCV_FROM_VXLAN_BIT, 1, &ofpacts);
+ put_load(1, MFF_LOG_FLAGS, MLF_RCV_FROM_RAMP_BIT, 1, &ofpacts);
put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, &ofpacts);
- ofctrl_add_flow(flow_table, OFTABLE_PHY_TO_LOG, 100,
+ ofctrl_add_flow(flow_table, OFTABLE_PHY_TO_LOG, 110,
binding->header_.uuid.parts[0],
&match, &ofpacts, hc_uuid);
}
@@ -1696,7 +1709,7 @@ physical_run(struct physical_ctx *p_ctx,
struct match match;
match_init_catchall(&match);
match_set_reg_masked(&match, MFF_LOG_FLAGS - MFF_REG0,
- MLF_RCV_FROM_VXLAN, MLF_RCV_FROM_VXLAN);
+ MLF_RCV_FROM_RAMP, MLF_RCV_FROM_RAMP);
/* Resubmit to table 33. */
ofpbuf_clear(&ofpacts);
@@ -51,7 +51,7 @@ void ovn_init_symtab(struct shash *symtab);
/* MFF_LOG_FLAGS_REG bit assignments */
enum mff_log_flags_bits {
MLF_ALLOW_LOOPBACK_BIT = 0,
- MLF_RCV_FROM_VXLAN_BIT = 1,
+ MLF_RCV_FROM_RAMP_BIT = 1,
MLF_FORCE_SNAT_FOR_DNAT_BIT = 2,
MLF_FORCE_SNAT_FOR_LB_BIT = 3,
MLF_LOCAL_ONLY_BIT = 4,
@@ -64,11 +64,11 @@ enum mff_log_flags {
/* Allow outputting back to inport. */
MLF_ALLOW_LOOPBACK = (1 << MLF_ALLOW_LOOPBACK_BIT),
- /* Indicate that a packet was received from a VXLAN tunnel to
- * compensate for the lack of egress port information available in
- * VXLAN encapsulation. Egress port information is available for
- * Geneve and STT tunnel types. */
- MLF_RCV_FROM_VXLAN = (1 << MLF_RCV_FROM_VXLAN_BIT),
+ /* Indicate that a packet was received from a ramp switch to compensate for
+ * the lack of egress port information available in ramp switch
+ * encapsulation. Egress port information is available for Geneve, STT and
+ * regular VXLAN tunnel types. */
+ MLF_RCV_FROM_RAMP = (1 << MLF_RCV_FROM_RAMP_BIT),
/* Indicate that a packet needs a force SNAT in the gateway router when
* DNAT has taken place. */
@@ -16,6 +16,7 @@
#ifndef OVN_UTIL_H
#define OVN_UTIL_H 1
+#include "lib/ovn-sb-idl.h"
#include "lib/packets.h"
#include "include/ovn/version.h"
@@ -107,6 +108,10 @@ void ovn_conn_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
#define OVN_MAX_DP_KEY_LOCAL (OVN_MAX_DP_KEY - OVN_MAX_DP_GLOBAL_NUM)
#define OVN_MIN_DP_KEY_GLOBAL (OVN_MAX_DP_KEY_LOCAL + 1)
#define OVN_MAX_DP_KEY_GLOBAL OVN_MAX_DP_KEY
+
+#define OVN_MAX_DP_VXLAN_KEY ((1u << 12) - 1)
+#define OVN_MAX_DP_VXLAN_KEY_LOCAL (OVN_MAX_DP_KEY - OVN_MAX_DP_GLOBAL_NUM)
+
struct hmap;
void ovn_destroy_tnlids(struct hmap *tnlids);
void ovn_add_tnlid(struct hmap *set, uint32_t tnlid);
@@ -64,6 +64,7 @@ struct northd_context {
struct ovsdb_idl *ovnsb_idl;
struct ovsdb_idl_txn *ovnnb_txn;
struct ovsdb_idl_txn *ovnsb_txn;
+ struct ovsdb_idl_index *sbrec_chassis_by_name;
struct ovsdb_idl_index *sbrec_ha_chassis_grp_by_name;
struct ovsdb_idl_index *sbrec_mcast_group_by_name_dp;
struct ovsdb_idl_index *sbrec_ip_mcast_by_dp;
@@ -1189,12 +1190,34 @@ join_datapaths(struct northd_context *ctx, struct hmap *datapaths,
}
}
+static int is_vxlan_mode(struct ovsdb_idl *ovnsb_idl)
+{
+ const struct sbrec_chassis *chassis, *chassis_next;
+ SBREC_CHASSIS_FOR_EACH_SAFE (chassis, chassis_next, ovnsb_idl) {
+ for (int i = 0; i < chassis->n_encaps; i++) {
+ if (!strcmp(chassis->encaps[i]->type, "vxlan")) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+static uint32_t
+get_ovn_max_dp_key_local(struct northd_context *ctx) {
+ if (is_vxlan_mode(ctx->ovnsb_idl)) {
+ /* TODO: what to do with global tunids? */
+ return OVN_MAX_DP_VXLAN_KEY;
+ }
+ return OVN_MAX_DP_KEY - OVN_MAX_DP_GLOBAL_NUM;
+}
+
static uint32_t
-ovn_datapath_allocate_key(struct hmap *dp_tnlids)
+ovn_datapath_allocate_key(struct northd_context *ctx, struct hmap *dp_tnlids)
{
static uint32_t hint;
return ovn_allocate_tnlid(dp_tnlids, "datapath", OVN_MIN_DP_KEY_LOCAL,
- OVN_MAX_DP_KEY_LOCAL, &hint);
+ get_ovn_max_dp_key_local(ctx), &hint);
}
/* Updates the southbound Datapath_Binding table so that it contains the
@@ -1237,7 +1260,7 @@ build_datapaths(struct northd_context *ctx, struct hmap *datapaths,
}
}
if (!tunnel_key) {
- tunnel_key = ovn_datapath_allocate_key(&dp_tnlids);
+ tunnel_key = ovn_datapath_allocate_key(ctx, &dp_tnlids);
if (!tunnel_key) {
break;
}
@@ -12110,32 +12133,34 @@ ovnnb_db_run(struct northd_context *ctx,
}
}
- if (!mac_addr_prefix || !monitor_mac) {
- struct smap options;
- smap_clone(&options, &nb->options);
+ struct smap options;
+ smap_clone(&options, &nb->options);
- if (!mac_addr_prefix) {
- eth_addr_random(&mac_prefix);
- memset(&mac_prefix.ea[3], 0, 3);
+ if (!mac_addr_prefix) {
+ eth_addr_random(&mac_prefix);
+ memset(&mac_prefix.ea[3], 0, 3);
- smap_add_format(&options, "mac_prefix",
- "%02"PRIx8":%02"PRIx8":%02"PRIx8,
- mac_prefix.ea[0], mac_prefix.ea[1],
- mac_prefix.ea[2]);
- }
+ smap_add_format(&options, "mac_prefix",
+ "%02"PRIx8":%02"PRIx8":%02"PRIx8,
+ mac_prefix.ea[0], mac_prefix.ea[1],
+ mac_prefix.ea[2]);
+ }
- if (!monitor_mac) {
- eth_addr_random(&svc_monitor_mac_ea);
- snprintf(svc_monitor_mac, sizeof svc_monitor_mac,
- ETH_ADDR_FMT, ETH_ADDR_ARGS(svc_monitor_mac_ea));
- smap_replace(&options, "svc_monitor_mac", svc_monitor_mac);
- }
+ if (!monitor_mac) {
+ eth_addr_random(&svc_monitor_mac_ea);
+ snprintf(svc_monitor_mac, sizeof svc_monitor_mac,
+ ETH_ADDR_FMT, ETH_ADDR_ARGS(svc_monitor_mac_ea));
+ smap_replace(&options, "svc_monitor_mac", svc_monitor_mac);
+ }
- nbrec_nb_global_verify_options(nb);
- nbrec_nb_global_set_options(nb, &options);
+ char *max_tunid = xasprintf("%d", get_ovn_max_dp_key_local(ctx));
+ smap_replace(&options, "max_tunid", max_tunid);
+ free(max_tunid);
- smap_destroy(&options);
- }
+ nbrec_nb_global_verify_options(nb);
+ nbrec_nb_global_set_options(nb, &options);
+
+ smap_destroy(&options);
/* Update the probe interval. */
northd_probe_interval_nb = get_probe_interval(ovnnb_db, nb);
@@ -13009,6 +13034,10 @@ main(int argc, char *argv[])
ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_chassis);
ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_chassis_col_name);
ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_chassis_col_other_config);
+ ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_chassis_col_encaps);
+
+ ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_encap);
+ ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_encap_col_type);
ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_chassis_private);
ovsdb_idl_add_column(ovnsb_idl_loop.idl,
@@ -13122,6 +13151,7 @@ main(int argc, char *argv[])
.ovnnb_txn = ovsdb_idl_loop_run(&ovnnb_idl_loop),
.ovnsb_idl = ovnsb_idl_loop.idl,
.ovnsb_txn = ovsdb_idl_loop_run(&ovnsb_idl_loop),
+ .sbrec_chassis_by_name = sbrec_chassis_by_name,
.sbrec_ha_chassis_grp_by_name = sbrec_ha_chassis_grp_by_name,
.sbrec_mcast_group_by_name_dp = sbrec_mcast_group_by_name_dp,
.sbrec_ip_mcast_by_dp = sbrec_ip_mcast_by_dp,
@@ -1163,11 +1163,14 @@
<p>
Geneve and STT tunnels pass this field as part of the tunnel key.
- Although VXLAN tunnels do not explicitly carry a logical input port,
- OVN only uses VXLAN to communicate with gateways that from OVN's
+ Ramp switch VXLAN tunnels do not explicitly carry a logical input port,
+ but since they are used to communicate with gateways that from OVN's
perspective consist of only a single logical port, so that OVN can set
the logical input port field to this one on ingress to the OVN logical
- pipeline.
+ pipeline. As for regular VXLAN tunnels, they don't carry input port
+ field at all. This puts additional limitations on cluster
+ capabilities that are described in
+ <code>Tunnel Encapsulations</code> section.
</p>
</dd>
@@ -1183,15 +1186,15 @@
</p>
<p>
- Geneve and STT tunnels pass this field as part of the tunnel key.
- VXLAN tunnels do not transmit the logical output port field.
- Since VXLAN tunnels do not carry a logical output port field in
- the tunnel key, when a packet is received from VXLAN tunnel by
- an OVN hypervisor, the packet is resubmitted to table 8 to
- determine the output port(s); when the packet reaches table 32,
+ Geneve, STT and regular VXLAN tunnels pass this field as part of the
+ tunnel key. Ramp switch VXLAN tunnels do not transmit the logical
+ output port field, and since they do not carry a logical output port
+ field in the tunnel key, when a packet is received from ramp switch
+ VXLAN tunnel by an OVN hypervisor, the packet is resubmitted to table 8
+ to determine the output port(s); when the packet reaches table 32,
these packets are resubmitted to table 33 for local delivery by
- checking a MLF_RCV_FROM_VXLAN flag, which is set when the packet
- arrives from a VXLAN tunnel.
+ checking a MLF_RCV_FROM_RAMP flag, which is set when the packet
+ arrives from a ramp tunnel.
</p>
</dd>
@@ -1263,15 +1266,16 @@
</p>
<p>
- Table 0 also processes packets that arrive from other chassis. It
+ Table 0 also processes packets that arrive from other chassis. It
distinguishes them from other packets by ingress port, which is a
- tunnel. As with packets just entering the OVN pipeline, the actions
- annotate these packets with logical datapath and logical ingress port
- metadata. In addition, the actions set the logical output port field,
+ tunnel. As with packets just entering the OVN pipeline, the actions
+ annotate these packets with logical datapath metadata. For tunnel types
+ that support it, they are also annotated with logical ingress port
+ metadata. In addition, the actions set the logical output port field,
which is available because in OVN tunneling occurs after the logical
- output port is known. These three pieces of information are obtained
+ output port is known. These pieces of information are obtained
from the tunnel encapsulation metadata (see <code>Tunnel
- Encapsulations</code> for encoding details). Then the actions resubmit
+ Encapsulations</code> for encoding details). Then the actions resubmit
to table 33 to enter the logical egress pipeline.
</p>
</li>
@@ -1430,12 +1434,12 @@
<ul>
<li>
- A higher-priority rule to match packets received from VXLAN tunnels,
- based on flag MLF_RCV_FROM_VXLAN, and resubmit these packets to table
- 33 for local delivery. Packets received from VXLAN tunnels reach
- here because of a lack of logical output port field in the tunnel key
- and thus these packets needed to be submitted to table 8 to
- determine the output port.
+ A higher-priority rule to match packets received from ramp switch
+ tunnels, based on flag MLF_RCV_FROM_RAMP, and resubmit these packets
+ to table 33 for local delivery. Packets received from ramp switch
+ tunnels reach here because of a lack of logical output port field in
+ the tunnel key and thus these packets needed to be submitted to table
+ 8 to determine the output port.
</li>
<li>
A higher-priority rule to match packets received from ports of type
@@ -2658,9 +2662,9 @@
<h2>Tunnel Encapsulations</h2>
<p>
- OVN annotates logical network packets that it sends from one hypervisor to
- another with the following three pieces of metadata, which are encoded in
- an encapsulation-specific fashion:
+ In general, OVN annotates logical network packets that it sends from one
+ hypervisor to another with the following three pieces of metadata, which
+ are encoded in an encapsulation-specific fashion:
</p>
<ul>
@@ -2686,16 +2690,57 @@
</ul>
<p>
- For hypervisor-to-hypervisor traffic, OVN supports only Geneve and STT
- encapsulations, for the following reasons:
+ When VXLAN is enabled on any hypervisor in a cluster, datapath and egress
+ port identifier ranges are reduced to 12-bits. This is done because only
+ STT and Geneve provide the large space for metadata (over 32 bits per
+ packet). To accommodate for VXLAN, 24 bits available are split as
+ follows:
+ </p>
+
+ <ul>
+ <li>
+ 12-bit logical datapath identifier, derived from the
+ <code>tunnel_key</code> column in the OVN Southbound
+ <code>Datapath_Binding</code> table.
+ </li>
+
+ <li>
+ 12-bit logical egress port identifier. IDs 0 through 32767 have the same
+ meaning as for logical ingress ports. IDs 32768 through 65535,
+ inclusive, may be assigned to logical multicast groups (see the
+ <code>tunnel_key</code> column in the OVN Southbound
+ <code>Multicast_Group</code> table).
+ </li>
+
+ <li>
+ No logical ingress port identifier.
+ </li>
+ </ul>
+
+ <p>
+ The limited space available for metadata when VXLAN tunnels are enabled
+ in a cluster put the following functional limitations onto features
+ available to users:
</p>
<ul>
<li>
- Only STT and Geneve support the large amounts of metadata (over 32 bits
- per packet) that OVN uses (as described above).
+ The maximum number of networks is reduced to 4096.
+ </li>
+ <li>
+ The maximum number of ports per network is reduced to 4096. (Including
+ multicast group ports.)
+ </li>
+ <li>
+ ACLs matching against logical ingress port identifiers are not supported.
</li>
+ </ul>
+ <p>
+ In addition to functional limitations described above, the following
+ should be considered before enabling it in your cluster:
+ </p>
+ <ul>
<li>
STT and Geneve use randomized UDP or TCP source ports that allows
efficient distribution among multiple paths in environments that use ECMP
@@ -180,6 +180,13 @@
</p>
</column>
+ <column name="options" key="max_tunid">
+ <p>
+ The maximum supported tunnel ID. Depends on types of encapsulation
+ enabled in the cluster.
+ </p>
+ </column>
+
<group title="Options for configuring interconnection route advertisement">
<p>
These options control how routes are advertised between OVN
@@ -215,7 +215,7 @@ net_attach () {
# ovn_az_attach AZ NETWORK BRIDGE IP [MASKLEN]
ovn_az_attach() {
- local az=$1 net=$2 bridge=$3 ip=$4 masklen=${5-24}
+ local az=$1 net=$2 bridge=$3 ip=$4 masklen=${5-24} encap=${6-geneve,vxlan}
net_attach $net $bridge || return 1
mac=`ovs-vsctl get Interface $bridge mac_in_use | sed s/\"//g`
@@ -232,7 +232,7 @@ ovn_az_attach() {
ovs-vsctl \
-- set Open_vSwitch . external-ids:system-id=$sandbox \
-- set Open_vSwitch . external-ids:ovn-remote=$ovn_remote \
- -- set Open_vSwitch . external-ids:ovn-encap-type=geneve,vxlan \
+ -- set Open_vSwitch . external-ids:ovn-encap-type=$encap \
-- set Open_vSwitch . external-ids:ovn-encap-ip=$ip \
-- --may-exist add-br br-int \
-- set bridge br-int fail-mode=secure other-config:disable-in-band=true \
@@ -17907,612 +17907,583 @@ AT_CHECK([ovn-nbctl -u $sockfile show])
AT_CLEANUP
-AT_SETUP([ovn -- 2 HVs, 2 lports/HV, localnet ports, DVR N-S ARP handling])
-ovn_start
-
-# In this test cases we create 3 switches, all connected to same
-# physical network (through br-phys on each HV). LS1 and LS2 have
-# 1 VIF each. Each HV has 1 VIF port. The first digit
-# of VIF port name indicates the hypervisor it is bound to, e.g.
-# lp23 means VIF 3 on hv2.
-#
-# All the switches are connected to a logical router "router".
-#
-# Each switch's VLAN tag and their logical switch ports are:
-# - ls1:
-# - tagged with VLAN 101
-# - ports: lp11
-# - ls2:
-# - tagged with VLAN 201
-# - ports: lp22
-# - ls-underlay:
-# - tagged with VLAN 1000
-# Note: a localnet port is created for each switch to connect to
-# physical network.
-
-for i in 1 2; do
- ls_name=ls$i
- ovn-nbctl ls-add $ls_name
- ln_port_name=ln$i
- if test $i -eq 1; then
- ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
- elif test $i -eq 2; then
- ovn-nbctl lsp-add $ls_name $ln_port_name "" 201
- fi
- ovn-nbctl lsp-set-addresses $ln_port_name unknown
- ovn-nbctl lsp-set-type $ln_port_name localnet
- ovn-nbctl lsp-set-options $ln_port_name network_name=phys
-done
-
-# lsp_to_ls LSP
-#
-# Prints the name of the logical switch that contains LSP.
-lsp_to_ls () {
- case $1 in dnl (
- lp?[[11]]) echo ls1 ;; dnl (
- lp?[[12]]) echo ls2 ;; dnl (
- *) AT_FAIL_IF([:]) ;;
- esac
-}
-
-vif_to_hv () {
- case $1 in dnl (
- vif[[1]]?) echo hv1 ;; dnl (
- vif[[2]]?) echo hv2 ;; dnl (
- vif?[[north]]?) echo hv4 ;; dnl (
- *) AT_FAIL_IF([:]) ;;
- esac
-}
-
-ip_to_hex() {
- printf "%02x%02x%02x%02x" "$@"
-}
-
-net_add n1
-for i in 1 2; do
- sim_add hv$i
- as hv$i
- ovs-vsctl add-br br-phys
- ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
- ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:$i$i"
- ovn_attach n1 br-phys 192.168.0.$i
-
- ovs-vsctl add-port br-int vif$i$i -- \
- set Interface vif$i$i external-ids:iface-id=lp$i$i \
- options:tx_pcap=hv$i/vif$i$i-tx.pcap \
- options:rxq_pcap=hv$i/vif$i$i-rx.pcap \
- ofport-request=$i$i
-
- lsp_name=lp$i$i
- ls_name=$(lsp_to_ls $lsp_name)
-
- ovn-nbctl lsp-add $ls_name $lsp_name
- ovn-nbctl lsp-set-addresses $lsp_name "f0:00:00:00:00:$i$i 192.168.$i.$i"
- ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$i
-
- OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
-
-done
-
-ovn-nbctl ls-add ls-underlay
-ovn-nbctl lsp-add ls-underlay ln3 "" 1000
-ovn-nbctl lsp-set-addresses ln3 unknown
-ovn-nbctl lsp-set-type ln3 localnet
-ovn-nbctl lsp-set-options ln3 network_name=phys
-
-ovn-nbctl ls-add ls-north
-ovn-nbctl lsp-add ls-north ln4 "" 1000
-ovn-nbctl lsp-set-addresses ln4 unknown
-ovn-nbctl lsp-set-type ln4 localnet
-ovn-nbctl lsp-set-options ln4 network_name=phys
-
-# Add a VM on ls-north
-ovn-nbctl lsp-add ls-north lp-north
-ovn-nbctl lsp-set-addresses lp-north "f0:f0:00:00:00:11 172.31.0.10"
-ovn-nbctl lsp-set-port-security lp-north f0:f0:00:00:00:11
-
-# Add 3rd hypervisor
-sim_add hv3
-as hv3 ovs-vsctl add-br br-phys
-as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-as hv3 ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:33"
-as hv3 ovn_attach n1 br-phys 192.168.0.3
-
-# Add 4th hypervisor
-sim_add hv4
-as hv4 ovs-vsctl add-br br-phys
-as hv4 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-as hv4 ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:44"
-as hv4 ovn_attach n1 br-phys 192.168.0.4
-
-as hv4 ovs-vsctl add-port br-int vif-north -- \
- set Interface vif-north external-ids:iface-id=lp-north \
- options:tx_pcap=hv4/vif-north-tx.pcap \
- options:rxq_pcap=hv4/vif-north-rx.pcap \
- ofport-request=44
-
-ovn-nbctl lr-add router
-ovn-nbctl lrp-add router router-to-ls1 00:00:01:01:02:03 192.168.1.3/24
-ovn-nbctl lrp-add router router-to-ls2 00:00:01:01:02:05 192.168.2.3/24
-ovn-nbctl lrp-add router router-to-underlay 00:00:01:01:02:07 172.31.0.1/24
-
-ovn-nbctl lsp-add ls1 ls1-to-router -- set Logical_Switch_Port ls1-to-router type=router \
- options:router-port=router-to-ls1 -- lsp-set-addresses ls1-to-router router
-ovn-nbctl lsp-add ls2 ls2-to-router -- set Logical_Switch_Port ls2-to-router type=router \
- options:router-port=router-to-ls2 -- lsp-set-addresses ls2-to-router router
-ovn-nbctl lsp-add ls-underlay underlay-to-router -- set Logical_Switch_Port \
- underlay-to-router type=router \
- options:router-port=router-to-underlay \
- -- lsp-set-addresses underlay-to-router router
-
-
-OVN_POPULATE_ARP
-
-# lsp_to_ls LSP
-#
-# Prints the name of the logical switch that contains LSP.
-lsp_to_ls () {
- case $1 in dnl (
- lp?[[11]]) echo ls1 ;; dnl (
- lp?[[12]]) echo ls2 ;; dnl (
- *) AT_FAIL_IF([:]) ;;
- esac
-}
-
-vif_to_ls () {
- case $1 in dnl (
- vif?[[11]]) echo ls1 ;; dnl (
- vif?[[12]]) echo ls2 ;; dnl (
- vif-north) echo ls-north ;; dnl (
- *) AT_FAIL_IF([:]) ;;
- esac
-}
-
-hv_to_num () {
- case $1 in dnl (
- hv1) echo 1 ;; dnl (
- hv2) echo 2 ;; dnl (
- hv3) echo 3 ;; dnl (
- hv4) echo 4 ;; dnl (
- *) AT_FAIL_IF([:]) ;;
- esac
-}
-
-vif_to_num () {
- case $1 in dnl (
- vif22) echo 22 ;; dnl (
- vif21) echo 21 ;; dnl (
- vif11) echo 11 ;; dnl (
- *) AT_FAIL_IF([:]) ;;
- esac
-}
-
-vif_to_hv () {
- case $1 in dnl (
- vif[[1]]?) echo hv1 ;; dnl (
- vif[[2]]?) echo hv2 ;; dnl (
- vif-north) echo hv4 ;; dnl (
- *) AT_FAIL_IF([:]) ;;
- esac
-}
-
-vif_to_lrp () {
- echo router-to-`vif_to_ls $1`
-}
-
-ip_to_hex() {
- printf "%02x%02x%02x%02x" "$@"
-}
-
-# test_arp INPORT SHA SPA TPA [REPLY_HA]
-#
-# Causes a packet to be received on INPORT. The packet is an ARP
-# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
-# it should be the hardware address of the target to expect to receive in an
-# ARP reply; otherwise no reply is expected.
-#
-# INPORT is an logical switch port number, e.g. 11 for vif11.
-# SHA and REPLY_HA are each 12 hex digits.
-# SPA and TPA are each 8 hex digits.
-test_arp() {
- local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
- local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
- hv=`vif_to_hv $inport`
- as $hv ovs-appctl netdev-dummy/receive $inport $request
-
- if test X$reply_ha = X; then
- # Expect to receive the broadcast ARP on the other logical switch ports
- # if no reply is expected.
- local i j
- for i in 1 2 3; do
- for j in 1 2 3; do
- if test $i$j != $inport; then
- echo $request >> $i$j.expected
- fi
- done
- done
- else
- # Expect to receive the reply, if any.
- local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
- local reply_vid=${sha}${reply_ha}810003e808060001080006040002${reply_ha}${tpa}${sha}${spa}
- echo $reply_vid >> ${inport}_vid.expected
- echo $reply >> $inport.expected
- fi
-}
-
-sip=`ip_to_hex 172 31 0 10`
-tip=`ip_to_hex 172 31 0 1`
-
-# Set a hypervisor as gateway chassis, for router port 172.31.0.1
-ovn-nbctl lrp-set-gateway-chassis router-to-underlay hv3
-ovn-nbctl --wait=sb sync
-
-# Dump a bunch of info helpful for debugging if there's a failure.
-
-echo "------ OVN dump ------"
-ovn-nbctl show
-ovn-sbctl show
-ovn-sbctl list port_binding
-ovn-sbctl list mac_binding
-
-echo "------ hv1 dump ------"
-as hv1 ovs-vsctl show
-as hv1 ovs-vsctl list Open_Vswitch
-
-echo "------ hv2 dump ------"
-as hv2 ovs-vsctl show
-as hv2 ovs-vsctl list Open_Vswitch
-
-echo "------ hv3 dump ------"
-as hv3 ovs-vsctl show
-as hv3 ovs-vsctl list Open_Vswitch
-
-echo "------ hv4 dump ------"
-as hv4 ovs-vsctl show
-as hv4 ovs-vsctl list Open_Vswitch
-
-OVS_WAIT_UNTIL([test x`ovn-sbctl --bare --columns chassis find port_binding logical_port=cr-router-to-underlay | wc -l` = x1])
-
-test_arp vif-north f0f000000011 $sip $tip 000001010207
-
-# Confirm that vif-north gets a single ARP reply
-OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv4/vif-north-tx.pcap], [vif-north.expected])
-
-# Confirm that only redirect chassis allowed arp resolution.
-OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv3/br-phys_n1-tx.pcap], [vif-north_vid.expected])
-
-# Confirm that other OVN chassis did not generate ARP reply.
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap > hv1/br-phys_n1-tx.packets
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap > hv2/br-phys_n1-tx.packets
-
-AT_CHECK([grep 000001010207 hv1/br-phys_n1-tx.packets | wc -l], [0], [[0
-]])
-AT_CHECK([grep 000001010207 hv2/br-phys_n1-tx.packets | wc -l], [0], [[0
-]])
-
-echo "----------- Post Traffic hv1 dump -----------"
-as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
-as hv1 ovs-appctl fdb/show br-phys
-
-echo "----------- Post Traffic hv2 dump -----------"
-as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
-as hv2 ovs-appctl fdb/show br-phys
-
-echo "----------- Post Traffic hv3 dump -----------"
-as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
-as hv3 ovs-appctl fdb/show br-phys
-
-echo "----------- Post Traffic hv4 dump -----------"
-as hv4 ovs-ofctl -O OpenFlow13 dump-flows br-int
-as hv4 ovs-appctl fdb/show br-phys
-
-OVN_CLEANUP([hv1],[hv2],[hv3],[hv4])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- 2 HVs, 2 lports/HV, localnet ports, DVR N-S Ping])
-ovn_start
-
-# In this test cases we create 3 switches, all connected to same
-# physical network (through br-phys on each HV). LS1 and LS2 have
-# 1 VIF each. Each HV has 1 VIF port. The first digit
-# of VIF port name indicates the hypervisor it is bound to, e.g.
-# lp23 means VIF 3 on hv2.
-#
-# All the switches are connected to a logical router "router".
-#
-# Each switch's VLAN tag and their logical switch ports are:
-# - ls1:
-# - tagged with VLAN 101
-# - ports: lp11
-# - ls2:
-# - tagged with VLAN 201
-# - ports: lp22
-# - ls-underlay:
-# - tagged with VLAN 1000
-# Note: a localnet port is created for each switch to connect to
-# physical network.
-
-for i in 1 2; do
- ls_name=ls$i
- ovn-nbctl ls-add $ls_name
- ln_port_name=ln$i
- if test $i -eq 1; then
- ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
- elif test $i -eq 2; then
- ovn-nbctl lsp-add $ls_name $ln_port_name "" 201
- fi
- ovn-nbctl lsp-set-addresses $ln_port_name unknown
- ovn-nbctl lsp-set-type $ln_port_name localnet
- ovn-nbctl lsp-set-options $ln_port_name network_name=phys
-done
-
-# lsp_to_ls LSP
-#
-# Prints the name of the logical switch that contains LSP.
-lsp_to_ls () {
- case $1 in dnl (
- lp?[[11]]) echo ls1 ;; dnl (
- lp?[[12]]) echo ls2 ;; dnl (
- *) AT_FAIL_IF([:]) ;;
- esac
-}
+m4_define([DVR_N_S_ARP_HANDLING],
+ [AT_SETUP([ovn -- 2 HVs, 2 lports/HV, localnet ports, DVR N-S ARP handling, encap $1])
+ set -x
+ encap=$1
+ ovn_start
+
+ # In this test cases we create 3 switches, all connected to same
+ # physical network (through br-phys on each HV). LS1 and LS2 have
+ # 1 VIF each. Each HV has 1 VIF port. The first digit
+ # of VIF port name indicates the hypervisor it is bound to, e.g.
+ # lp23 means VIF 3 on hv2.
+ #
+ # All the switches are connected to a logical router "router".
+ #
+ # Each switch's VLAN tag and their logical switch ports are:
+ # - ls1:
+ # - tagged with VLAN 101
+ # - ports: lp11
+ # - ls2:
+ # - tagged with VLAN 201
+ # - ports: lp22
+ # - ls-underlay:
+ # - tagged with VLAN 1000
+ # Note: a localnet port is created for each switch to connect to
+ # physical network.
+
+ for i in 1 2; do
+ ls_name=ls$i
+ ovn-nbctl ls-add $ls_name
+ ln_port_name=ln$i
+ if test $i -eq 1; then
+ ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
+ elif test $i -eq 2; then
+ ovn-nbctl lsp-add $ls_name $ln_port_name "" 201
+ fi
+ ovn-nbctl lsp-set-addresses $ln_port_name unknown
+ ovn-nbctl lsp-set-type $ln_port_name localnet
+ ovn-nbctl lsp-set-options $ln_port_name network_name=phys
+ done
+
+ # lsp_to_ls LSP
+ #
+ # Prints the name of the logical switch that contains LSP.
+ lsp_to_ls () {
+ case ${1} in dnl (
+ lp?[[11]]) echo ls1 ;; dnl (
+ lp?[[12]]) echo ls2 ;; dnl (
+ *) AT_FAIL_IF([:]) ;;
+ esac
+ }
-vif_to_hv () {
- case $1 in dnl (
- vif[[1]]?) echo hv1 ;; dnl (
- vif[[2]]?) echo hv2 ;; dnl (
- vif?[[north]]?) echo hv4 ;; dnl (
- *) AT_FAIL_IF([:]) ;;
- esac
-}
+ vif_to_hv () {
+ case $1 in dnl (
+ vif[[1]]?) echo hv1 ;; dnl (
+ vif[[2]]?) echo hv2 ;; dnl (
+ vif?[[north]]?) echo hv4 ;; dnl (
+ *) AT_FAIL_IF([:]) ;;
+ esac
+ }
-ip_to_hex() {
- printf "%02x%02x%02x%02x" "$@"
-}
+ net_add n1
+ for i in 1 2; do
+ sim_add hv$i
+ as hv$i
+ ovs-vsctl add-br br-phys
+ ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
+ ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:$i$i"
+ ovn_attach n1 br-phys 192.168.0.$i 24 $encap
+
+ ovs-vsctl add-port br-int vif$i$i -- \
+ set Interface vif$i$i external-ids:iface-id=lp$i$i \
+ options:tx_pcap=hv$i/vif$i$i-tx.pcap \
+ options:rxq_pcap=hv$i/vif$i$i-rx.pcap \
+ ofport-request=$i$i
+
+ lsp_name=lp$i$i
+ ls_name=$(lsp_to_ls $lsp_name)
+
+ ovn-nbctl lsp-add $ls_name $lsp_name
+ ovn-nbctl lsp-set-addresses $lsp_name "f0:00:00:00:00:$i$i 192.168.$i.$i"
+ ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$i
+
+ OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
+
+ done
+
+ ovn-nbctl ls-add ls-underlay
+ ovn-nbctl lsp-add ls-underlay ln3 "" 1000
+ ovn-nbctl lsp-set-addresses ln3 unknown
+ ovn-nbctl lsp-set-type ln3 localnet
+ ovn-nbctl lsp-set-options ln3 network_name=phys
+
+ ovn-nbctl ls-add ls-north
+ ovn-nbctl lsp-add ls-north ln4 "" 1000
+ ovn-nbctl lsp-set-addresses ln4 unknown
+ ovn-nbctl lsp-set-type ln4 localnet
+ ovn-nbctl lsp-set-options ln4 network_name=phys
+
+ # Add a VM on ls-north
+ ovn-nbctl lsp-add ls-north lp-north
+ ovn-nbctl lsp-set-addresses lp-north "f0:f0:00:00:00:11 172.31.0.10"
+ ovn-nbctl lsp-set-port-security lp-north f0:f0:00:00:00:11
+
+ # Add 3rd hypervisor
+ sim_add hv3
+ as hv3 ovs-vsctl add-br br-phys
+ as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
+ as hv3 ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:33"
+ as hv3 ovn_attach n1 br-phys 192.168.0.3 24 $encap
+
+ # Add 4th hypervisor
+ sim_add hv4
+ as hv4 ovs-vsctl add-br br-phys
+ as hv4 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
+ as hv4 ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:44"
+ as hv4 ovn_attach n1 br-phys 192.168.0.4 24 $encap
+
+ as hv4 ovs-vsctl add-port br-int vif-north -- \
+ set Interface vif-north external-ids:iface-id=lp-north \
+ options:tx_pcap=hv4/vif-north-tx.pcap \
+ options:rxq_pcap=hv4/vif-north-rx.pcap \
+ ofport-request=44
+
+ ovn-nbctl lr-add router
+ ovn-nbctl lrp-add router router-to-ls1 00:00:01:01:02:03 192.168.1.3/24
+ ovn-nbctl lrp-add router router-to-ls2 00:00:01:01:02:05 192.168.2.3/24
+ ovn-nbctl lrp-add router router-to-underlay 00:00:01:01:02:07 172.31.0.1/24
+
+ ovn-nbctl lsp-add ls1 ls1-to-router -- set Logical_Switch_Port ls1-to-router type=router \
+ options:router-port=router-to-ls1 -- lsp-set-addresses ls1-to-router router
+ ovn-nbctl lsp-add ls2 ls2-to-router -- set Logical_Switch_Port ls2-to-router type=router \
+ options:router-port=router-to-ls2 -- lsp-set-addresses ls2-to-router router
+ ovn-nbctl lsp-add ls-underlay underlay-to-router -- set Logical_Switch_Port \
+ underlay-to-router type=router \
+ options:router-port=router-to-underlay \
+ -- lsp-set-addresses underlay-to-router router
+
+
+ OVN_POPULATE_ARP
+
+ vif_to_hv () {
+ case ${1} in dnl (
+ vif[[1]]?) echo hv1 ;; dnl (
+ vif[[2]]?) echo hv2 ;; dnl (
+ vif-north) echo hv4 ;; dnl (
+ *) AT_FAIL_IF([:]) ;;
+ esac
+ }
-net_add n1
-for i in 1 2; do
- sim_add hv$i
- as hv$i
- ovs-vsctl add-br br-phys
- ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
- ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:$i$i"
- ovn_attach n1 br-phys 192.168.0.$i
+ # test_arp INPORT SHA SPA TPA [REPLY_HA]
+ #
+ # Causes a packet to be received on INPORT. The packet is an ARP
+ # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
+ # it should be the hardware address of the target to expect to receive in an
+ # ARP reply; otherwise no reply is expected.
+ #
+ # INPORT is an logical switch port number, e.g. 11 for vif11.
+ # SHA and REPLY_HA are each 12 hex digits.
+ # SPA and TPA are each 8 hex digits.
+ test_arp() {
+ local inport=${1} sha=${2} spa=${3} tpa=${4} reply_ha=${5}
+ local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
+ hv=`vif_to_hv $inport`
+ as $hv ovs-appctl netdev-dummy/receive $inport $request
+
+ if test X$reply_ha = X; then
+ # Expect to receive the broadcast ARP on the other logical switch ports
+ # if no reply is expected.
+ local i j
+ for i in 1 2 3; do
+ for j in 1 2 3; do
+ if test $i$j != $inport; then
+ echo $request >> $i$j.expected
+ fi
+ done
+ done
+ else
+ # Expect to receive the reply, if any.
+ local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
+ local reply_vid=${sha}${reply_ha}810003e808060001080006040002${reply_ha}${tpa}${sha}${spa}
+ echo $reply_vid >> ${inport}_vid.expected
+ echo $reply >> $inport.expected
+ fi
+ }
- ovs-vsctl add-port br-int vif$i$i -- \
- set Interface vif$i$i external-ids:iface-id=lp$i$i \
- options:tx_pcap=hv$i/vif$i$i-tx.pcap \
- options:rxq_pcap=hv$i/vif$i$i-rx.pcap \
- ofport-request=$i$i
+ sip=`printf "%02x%02x%02x%02x" 172 31 0 10`
+ tip=`printf "%02x%02x%02x%02x" 172 31 0 1`
- lsp_name=lp$i$i
- ls_name=$(lsp_to_ls $lsp_name)
+ # Set a hypervisor as gateway chassis, for router port 172.31.0.1
+ ovn-nbctl lrp-set-gateway-chassis router-to-underlay hv3
+ ovn-nbctl --wait=sb sync
- ovn-nbctl lsp-add $ls_name $lsp_name
- ovn-nbctl lsp-set-addresses $lsp_name "f0:00:00:00:00:$i$i 192.168.$i.$i"
- ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$i
+ # Dump a bunch of info helpful for debugging if there's a failure.
- OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
+ echo "------ OVN dump ------"
+ ovn-nbctl show
+ ovn-sbctl show
+ ovn-sbctl list port_binding
+ ovn-sbctl list mac_binding
-done
+ echo "------ hv1 dump ------"
+ as hv1 ovs-vsctl show
+ as hv1 ovs-vsctl list Open_Vswitch
-ovn-nbctl ls-add ls-underlay
-ovn-nbctl lsp-add ls-underlay ln3 "" 1000
-ovn-nbctl lsp-set-addresses ln3 unknown
-ovn-nbctl lsp-set-type ln3 localnet
-ovn-nbctl lsp-set-options ln3 network_name=phys
+ echo "------ hv2 dump ------"
+ as hv2 ovs-vsctl show
+ as hv2 ovs-vsctl list Open_Vswitch
-ovn-nbctl ls-add ls-north
-ovn-nbctl lsp-add ls-north ln4 "" 1000
-ovn-nbctl lsp-set-addresses ln4 unknown
-ovn-nbctl lsp-set-type ln4 localnet
-ovn-nbctl lsp-set-options ln4 network_name=phys
+ echo "------ hv3 dump ------"
+ as hv3 ovs-vsctl show
+ as hv3 ovs-vsctl list Open_Vswitch
-# Add a VM on ls-north
-ovn-nbctl lsp-add ls-north lp-north
-ovn-nbctl lsp-set-addresses lp-north "f0:f0:00:00:00:11 172.31.0.10"
-ovn-nbctl lsp-set-port-security lp-north f0:f0:00:00:00:11
+ echo "------ hv4 dump ------"
+ as hv4 ovs-vsctl show
+ as hv4 ovs-vsctl list Open_Vswitch
-# Add 3rd hypervisor
-sim_add hv3
-as hv3 ovs-vsctl add-br br-phys
-as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-as hv3 ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:33"
-as hv3 ovn_attach n1 br-phys 192.168.0.3
+ OVS_WAIT_UNTIL([test x`ovn-sbctl --bare --columns chassis find port_binding logical_port=cr-router-to-underlay | wc -l` = x1])
-# Add 4th hypervisor
-sim_add hv4
-as hv4 ovs-vsctl add-br br-phys
-as hv4 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-as hv4 ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:44"
-as hv4 ovn_attach n1 br-phys 192.168.0.4
+ test_arp vif-north f0f000000011 $sip $tip 000001010207
-as hv4 ovs-vsctl add-port br-int vif-north -- \
- set Interface vif-north external-ids:iface-id=lp-north \
- options:tx_pcap=hv4/vif-north-tx.pcap \
- options:rxq_pcap=hv4/vif-north-rx.pcap \
- ofport-request=44
+ # Confirm that vif-north gets a single ARP reply
+ OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv4/vif-north-tx.pcap], [vif-north.expected])
-ovn-nbctl lr-add router
-ovn-nbctl lrp-add router router-to-ls1 00:00:01:01:02:03 192.168.1.3/24
-ovn-nbctl lrp-add router router-to-ls2 00:00:01:01:02:05 192.168.2.3/24
-ovn-nbctl lrp-add router router-to-underlay 00:00:01:01:02:07 172.31.0.1/24
+ # Confirm that only redirect chassis allowed arp resolution.
+ OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv3/br-phys_n1-tx.pcap], [vif-north_vid.expected])
-ovn-nbctl lsp-add ls1 ls1-to-router -- set Logical_Switch_Port ls1-to-router type=router \
- options:router-port=router-to-ls1 -- lsp-set-addresses ls1-to-router router
-ovn-nbctl lsp-add ls2 ls2-to-router -- set Logical_Switch_Port ls2-to-router type=router \
- options:router-port=router-to-ls2 -- lsp-set-addresses ls2-to-router router
-ovn-nbctl lsp-add ls-underlay underlay-to-router -- set Logical_Switch_Port \
- underlay-to-router type=router \
- options:router-port=router-to-underlay \
- -- lsp-set-addresses underlay-to-router router
+ # Confirm that other OVN chassis did not generate ARP reply.
+ $PYTHON "$ovs_srcdir//utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap > hv1/br-phys_n1-tx.packets
+ $PYTHON "$ovs_srcdir//utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap > hv2/br-phys_n1-tx.packets
-ovn-nbctl lrp-set-gateway-chassis router-to-underlay hv3
-ovn-nbctl lrp-set-redirect-type router-to-underlay bridged
+ AT_CHECK([grep 000001010207 hv1/br-phys_n1-tx.packets | wc -l], [0], [[0
+]])
+ AT_CHECK([grep 000001010207 hv2/br-phys_n1-tx.packets | wc -l], [0], [[0
+]])
-ovn-nbctl --wait=sb sync
+ # validate max_tunid reflects the type of encapsulation used
+ max_tunid=`ovn-nbctl get NB_Global . options:max_tunid | sed s/":"//g | sed s/\"//g`
+ echo $max_tunid
+ if [[ $encap = vxlan ]]; then
+ max_tunid_expected=4095
+ else
+ max_tunid_expected=16711680
+ fi
+ AT_CHECK([test $max_tunid -eq $max_tunid_expected])
+
+ echo "----------- Post Traffic hv1 dump -----------"
+ as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
+ as hv1 ovs-appctl fdb/show br-phys
+
+ echo "----------- Post Traffic hv2 dump -----------"
+ as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
+ as hv2 ovs-appctl fdb/show br-phys
+
+ echo "----------- Post Traffic hv3 dump -----------"
+ as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
+ as hv3 ovs-appctl fdb/show br-phys
+
+ echo "----------- Post Traffic hv4 dump -----------"
+ as hv4 ovs-ofctl -O OpenFlow13 dump-flows br-int
+ as hv4 ovs-appctl fdb/show br-phys
+
+ OVN_CLEANUP([hv1],[hv2],[hv3],[hv4])
+
+ AT_CLEANUP])
+
+DVR_N_S_ARP_HANDLING([geneve])
+DVR_N_S_ARP_HANDLING([vxlan])
+
+m4_define([DVR_N_S_PING],
+ [AT_SETUP([ovn -- 2 HVs, 2 lports/HV, localnet ports, DVR N-S Ping, encap $1])
+ AT_KEYWORDS([$1])
+ encap=$1
+ ovn_start
+
+ # In this test cases we create 3 switches, all connected to same
+ # physical network (through br-phys on each HV). LS1 and LS2 have
+ # 1 VIF each. Each HV has 1 VIF port. The first digit
+ # of VIF port name indicates the hypervisor it is bound to, e.g.
+ # lp23 means VIF 3 on hv2.
+ #
+ # All the switches are connected to a logical router "router".
+ #
+ # Each switch's VLAN tag and their logical switch ports are:
+ # - ls1:
+ # - tagged with VLAN 101
+ # - ports: lp11
+ # - ls2:
+ # - tagged with VLAN 201
+ # - ports: lp22
+ # - ls-underlay:
+ # - tagged with VLAN 1000
+ # Note: a localnet port is created for each switch to connect to
+ # physical network.
+
+ for i in 1 2; do
+ ls_name=ls$i
+ ovn-nbctl ls-add $ls_name
+ ln_port_name=ln$i
+ if test $i -eq 1; then
+ ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
+ elif test $i -eq 2; then
+ ovn-nbctl lsp-add $ls_name $ln_port_name "" 201
+ fi
+ ovn-nbctl lsp-set-addresses $ln_port_name unknown
+ ovn-nbctl lsp-set-type $ln_port_name localnet
+ ovn-nbctl lsp-set-options $ln_port_name network_name=phys
+ done
+
+ # lsp_to_ls LSP
+ #
+ # Prints the name of the logical switch that contains LSP.
+ lsp_to_ls () {
+ case ${1} in dnl (
+ lp?[[11]]) echo ls1 ;; dnl (
+ lp?[[12]]) echo ls2 ;; dnl (
+ *) AT_FAIL_IF([:]) ;;
+ esac
+ }
+ vif_to_hv () {
+ case ${1} in dnl (
+ vif[[1]]?) echo hv1 ;; dnl (
+ vif[[2]]?) echo hv2 ;; dnl (
+ vif?[[north]]?) echo hv4 ;; dnl (
+ *) AT_FAIL_IF([:]) ;;
+ esac
+ }
-OVN_POPULATE_ARP
+ ip_to_hex() {
+ printf "%02x%02x%02x%02x" "$@"
+ }
-# lsp_to_ls LSP
-#
-# Prints the name of the logical switch that contains LSP.
-lsp_to_ls () {
- case $1 in dnl (
- lp?[[11]]) echo ls1 ;; dnl (
- lp?[[12]]) echo ls2 ;; dnl (
- *) AT_FAIL_IF([:]) ;;
- esac
-}
+ net_add n1
+ for i in 1 2; do
+ sim_add hv$i
+ as hv$i
+ ovs-vsctl add-br br-phys
+ ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
+ ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:$i$i"
+ ovn_attach n1 br-phys 192.168.0.$i 24 $encap
+
+ ovs-vsctl add-port br-int vif$i$i -- \
+ set Interface vif$i$i external-ids:iface-id=lp$i$i \
+ options:tx_pcap=hv$i/vif$i$i-tx.pcap \
+ options:rxq_pcap=hv$i/vif$i$i-rx.pcap \
+ ofport-request=$i$i
+
+ lsp_name=lp$i$i
+ ls_name=$(lsp_to_ls $lsp_name)
+
+ ovn-nbctl lsp-add $ls_name $lsp_name
+ ovn-nbctl lsp-set-addresses $lsp_name "f0:00:00:00:00:$i$i 192.168.$i.$i"
+ ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$i
+
+ OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
+
+ done
+
+ ovn-nbctl ls-add ls-underlay
+ ovn-nbctl lsp-add ls-underlay ln3 "" 1000
+ ovn-nbctl lsp-set-addresses ln3 unknown
+ ovn-nbctl lsp-set-type ln3 localnet
+ ovn-nbctl lsp-set-options ln3 network_name=phys
+
+ ovn-nbctl ls-add ls-north
+ ovn-nbctl lsp-add ls-north ln4 "" 1000
+ ovn-nbctl lsp-set-addresses ln4 unknown
+ ovn-nbctl lsp-set-type ln4 localnet
+ ovn-nbctl lsp-set-options ln4 network_name=phys
+
+ # Add a VM on ls-north
+ ovn-nbctl lsp-add ls-north lp-north
+ ovn-nbctl lsp-set-addresses lp-north "f0:f0:00:00:00:11 172.31.0.10"
+ ovn-nbctl lsp-set-port-security lp-north f0:f0:00:00:00:11
+
+ # Add 3rd hypervisor
+ sim_add hv3
+ as hv3 ovs-vsctl add-br br-phys
+ as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
+ as hv3 ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:33"
+ as hv3 ovn_attach n1 br-phys 192.168.0.3 24 $encap
+
+ # Add 4th hypervisor
+ sim_add hv4
+ as hv4 ovs-vsctl add-br br-phys
+ as hv4 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
+ as hv4 ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:44"
+ as hv4 ovn_attach n1 br-phys 192.168.0.4 24 $encap
+
+ as hv4 ovs-vsctl add-port br-int vif-north -- \
+ set Interface vif-north external-ids:iface-id=lp-north \
+ options:tx_pcap=hv4/vif-north-tx.pcap \
+ options:rxq_pcap=hv4/vif-north-rx.pcap \
+ ofport-request=44
+
+ ovn-nbctl lr-add router
+ ovn-nbctl lrp-add router router-to-ls1 00:00:01:01:02:03 192.168.1.3/24
+ ovn-nbctl lrp-add router router-to-ls2 00:00:01:01:02:05 192.168.2.3/24
+ ovn-nbctl lrp-add router router-to-underlay 00:00:01:01:02:07 172.31.0.1/24
+
+ ovn-nbctl lsp-add ls1 ls1-to-router -- set Logical_Switch_Port ls1-to-router type=router \
+ options:router-port=router-to-ls1 -- lsp-set-addresses ls1-to-router router
+ ovn-nbctl lsp-add ls2 ls2-to-router -- set Logical_Switch_Port ls2-to-router type=router \
+ options:router-port=router-to-ls2 -- lsp-set-addresses ls2-to-router router
+ ovn-nbctl lsp-add ls-underlay underlay-to-router -- set Logical_Switch_Port \
+ underlay-to-router type=router \
+ options:router-port=router-to-underlay \
+ -- lsp-set-addresses underlay-to-router router
+
+ ovn-nbctl lrp-set-gateway-chassis router-to-underlay hv3
+ ovn-nbctl lrp-set-redirect-type router-to-underlay bridged
+
+ ovn-nbctl --wait=sb sync
+
+
+ OVN_POPULATE_ARP
+
+ # lsp_to_ls LSP
+ #
+ # Prints the name of the logical switch that contains LSP.
+ lsp_to_ls () {
+ case ${1} in dnl (
+ lp?[[11]]) echo ls1 ;; dnl (
+ lp?[[12]]) echo ls2 ;; dnl (
+ *) AT_FAIL_IF([:]) ;;
+ esac
+ }
-vif_to_ls () {
- case $1 in dnl (
- vif?[[11]]) echo ls1 ;; dnl (
- vif?[[12]]) echo ls2 ;; dnl (
- vif-north) echo ls-north ;; dnl (
- *) AT_FAIL_IF([:]) ;;
- esac
-}
+ vif_to_ls () {
+ case ${1} in dnl (
+ vif?[[11]]) echo ls1 ;; dnl (
+ vif?[[12]]) echo ls2 ;; dnl (
+ vif-north) echo ls-north ;; dnl (
+ *) AT_FAIL_IF([:]) ;;
+ esac
+ }
-hv_to_num () {
- case $1 in dnl (
- hv1) echo 1 ;; dnl (
- hv2) echo 2 ;; dnl (
- hv3) echo 3 ;; dnl (
- hv4) echo 4 ;; dnl (
- *) AT_FAIL_IF([:]) ;;
- esac
-}
+ hv_to_num () {
+ case ${1} in dnl (
+ hv1) echo 1 ;; dnl (
+ hv2) echo 2 ;; dnl (
+ hv3) echo 3 ;; dnl (
+ hv4) echo 4 ;; dnl (
+ *) AT_FAIL_IF([:]) ;;
+ esac
+ }
-vif_to_num () {
- case $1 in dnl (
- vif22) echo 22 ;; dnl (
- vif21) echo 21 ;; dnl (
- vif11) echo 11 ;; dnl (
- *) AT_FAIL_IF([:]) ;;
- esac
-}
+ vif_to_num () {
+ case ${1} in dnl (
+ vif22) echo 22 ;; dnl (
+ vif21) echo 21 ;; dnl (
+ vif11) echo 11 ;; dnl (
+ *) AT_FAIL_IF([:]) ;;
+ esac
+ }
-vif_to_hv () {
- case $1 in dnl (
- vif[[1]]?) echo hv1 ;; dnl (
- vif[[2]]?) echo hv2 ;; dnl (
- vif-north) echo hv4 ;; dnl (
- *) AT_FAIL_IF([:]) ;;
- esac
-}
+ vif_to_hv () {
+ case ${1} in dnl (
+ vif[[1]]?) echo hv1 ;; dnl (
+ vif[[2]]?) echo hv2 ;; dnl (
+ vif-north) echo hv4 ;; dnl (
+ *) AT_FAIL_IF([:]) ;;
+ esac
+ }
-vif_to_lrp () {
- echo router-to-`vif_to_ls $1`
-}
+ vif_to_lrp () {
+ echo router-to-`vif_to_ls ${1}`
+ }
-ip_to_hex() {
- printf "%02x%02x%02x%02x" "$@"
-}
+ ip_to_hex() {
+ printf "%02x%02x%02x%02x" "${@}"
+ }
-test_ip() {
- # This packet has bad checksums but logical L3 routing doesn't check.
- local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 outport=$6
- local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
- shift; shift; shift; shift; shift
- hv=`vif_to_hv $inport`
- as $hv ovs-appctl netdev-dummy/receive $inport $packet
- in_ls=`vif_to_ls $inport`
- for outport; do
- out_ls=`vif_to_ls $outport`
- if test $in_ls = $out_ls; then
- # Ports on the same logical switch receive exactly the same packet.
- echo $packet
- else
- # Routing decrements TTL and updates source and dest MAC
- # (and checksum).
- out_lrp=`vif_to_lrp $outport`
- # For North-South, packet will come via gateway chassis, i.e hv3
- if test $inport = vif-north; then
- echo f0000000001100000101020308004500001c000000003f110100${src_ip}${dst_ip}0035111100080000 >> $outport.expected
- fi
- if test $outport = vif-north; then
- echo f0f00000001100000101020708004500001c000000003e110200${src_ip}${dst_ip}0035111100080000 >> $outport.expected
- fi
- fi >> $outport.expected
- done
-}
+ test_ip() {
+ # This packet has bad checksums but logical L3 routing doesn't check.
+ local inport=${1} src_mac=${2} dst_mac=${3} src_ip=${4} dst_ip=${5} outport=${6}
+ local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
+ shift; shift; shift; shift; shift
+ hv=`vif_to_hv $inport`
+ as $hv ovs-appctl netdev-dummy/receive $inport $packet
+ in_ls=`vif_to_ls $inport`
+ for outport; do
+ out_ls=`vif_to_ls $outport`
+ if test $in_ls = $out_ls; then
+ # Ports on the same logical switch receive exactly the same packet.
+ echo $packet
+ else
+ # Routing decrements TTL and updates source and dest MAC
+ # (and checksum).
+ out_lrp=`vif_to_lrp $outport`
+ # For North-South, packet will come via gateway chassis, i.e hv3
+ if test $inport = vif-north; then
+ echo f0000000001100000101020308004500001c000000003f110100${src_ip}${dst_ip}0035111100080000 >> $outport.expected
+ fi
+ if test $outport = vif-north; then
+ echo f0f00000001100000101020708004500001c000000003e110200${src_ip}${dst_ip}0035111100080000 >> $outport.expected
+ fi
+ fi >> $outport.expected
+ done
+ }
-# Dump a bunch of info helpful for debugging if there's a failure.
+ # Dump a bunch of info helpful for debugging if there's a failure.
-echo "------ OVN dump ------"
-ovn-nbctl show
-ovn-sbctl show
-ovn-sbctl list port_binding
-ovn-sbctl list mac_binding
+ echo "------ OVN dump ------"
+ ovn-nbctl show
+ ovn-sbctl show
+ ovn-sbctl list port_binding
+ ovn-sbctl list mac_binding
-echo "------ hv1 dump ------"
-as hv1 ovs-vsctl show
-as hv1 ovs-vsctl list Open_Vswitch
+ echo "------ hv1 dump ------"
+ as hv1 ovs-vsctl show
+ as hv1 ovs-vsctl list Open_Vswitch
-echo "------ hv2 dump ------"
-as hv2 ovs-vsctl show
-as hv2 ovs-vsctl list Open_Vswitch
+ echo "------ hv2 dump ------"
+ as hv2 ovs-vsctl show
+ as hv2 ovs-vsctl list Open_Vswitch
-echo "------ hv3 dump ------"
-as hv3 ovs-vsctl show
-as hv3 ovs-vsctl list Open_Vswitch
+ echo "------ hv3 dump ------"
+ as hv3 ovs-vsctl show
+ as hv3 ovs-vsctl list Open_Vswitch
-echo "------ hv4 dump ------"
-as hv4 ovs-vsctl show
-as hv4 ovs-vsctl list Open_Vswitch
+ echo "------ hv4 dump ------"
+ as hv4 ovs-vsctl show
+ as hv4 ovs-vsctl list Open_Vswitch
-echo "Send traffic North to South"
+ echo "Send traffic North to South"
-sip=`ip_to_hex 172 31 0 10`
-dip=`ip_to_hex 192 168 1 1`
-test_ip vif-north f0f000000011 000001010207 $sip $dip vif11
+ sip=`ip_to_hex 172 31 0 10`
+ dip=`ip_to_hex 192 168 1 1`
+ test_ip vif-north f0f000000011 000001010207 $sip $dip vif11
-# Confirm that North to south traffic works fine.
-OVN_CHECK_PACKETS([hv1/vif11-tx.pcap], [vif11.expected])
+ # Confirm that North to south traffic works fine.
+ OVN_CHECK_PACKETS([hv1/vif11-tx.pcap], [vif11.expected])
-echo "Send traffic South to Nouth"
-sip=`ip_to_hex 192 168 1 1`
-dip=`ip_to_hex 172 31 0 10`
-test_ip vif11 f00000000011 000001010203 $sip $dip vif-north
+ echo "Send traffic South to Nouth"
+ sip=`ip_to_hex 192 168 1 1`
+ dip=`ip_to_hex 172 31 0 10`
+ test_ip vif11 f00000000011 000001010203 $sip $dip vif-north
-# Confirm that South to North traffic works fine.
-OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv4/vif-north-tx.pcap], [vif-north.expected])
+ # Confirm that South to North traffic works fine.
+ OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv4/vif-north-tx.pcap], [vif-north.expected])
-# Confirm that packets did not go out via tunnel port.
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=33 | grep NXM_NX_TUN_METADATA0 | grep n_packets=0 | wc -l], [0], [[0
+ # Confirm that packets did not go out via tunnel port.
+ AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=33 | grep NXM_NX_TUN_METADATA0 | grep n_packets=0 | wc -l], [0], [[0
]])
-# Confirm that packet went out via localnet port
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=65 | grep priority=150 | grep src=00:00:01:01:02:07 | grep n_packets=1 | wc -l], [0], [[1
+ # Confirm that packet went out via localnet port
+ AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=65 | grep priority=150 | grep src=00:00:01:01:02:07 | grep n_packets=1 | wc -l], [0], [[1
]])
-echo "----------- Post Traffic hv1 dump -----------"
-as hv1 ovs-ofctl dump-flows br-int
-as hv1 ovs-ofctl show br-phys
-as hv1 ovs-appctl fdb/show br-phys
+ echo "----------- Post Traffic hv1 dump -----------"
+ as hv1 ovs-ofctl dump-flows br-int
+ as hv1 ovs-ofctl show br-phys
+ as hv1 ovs-appctl fdb/show br-phys
-echo "----------- Post Traffic hv2 dump -----------"
-as hv2 ovs-ofctl dump-flows br-int
-as hv2 ovs-ofctl show br-phys
-as hv2 ovs-appctl fdb/show br-phys
+ echo "----------- Post Traffic hv2 dump -----------"
+ as hv2 ovs-ofctl dump-flows br-int
+ as hv2 ovs-ofctl show br-phys
+ as hv2 ovs-appctl fdb/show br-phys
-echo "----------- Post Traffic hv3 dump -----------"
-as hv3 ovs-ofctl dump-flows br-int
-as hv3 ovs-ofctl show br-phys
-as hv3 ovs-appctl fdb/show br-phys
+ echo "----------- Post Traffic hv3 dump -----------"
+ as hv3 ovs-ofctl dump-flows br-int
+ as hv3 ovs-ofctl show br-phys
+ as hv3 ovs-appctl fdb/show br-phys
-echo "----------- Post Traffic hv4 dump -----------"
-as hv4 ovs-ofctl dump-flows br-int
-as hv4 ovs-ofctl show br-phys
-as hv4 ovs-appctl fdb/show br-phys
+ echo "----------- Post Traffic hv4 dump -----------"
+ as hv4 ovs-ofctl dump-flows br-int
+ as hv4 ovs-ofctl show br-phys
+ as hv4 ovs-appctl fdb/show br-phys
-OVN_CLEANUP([hv1],[hv2],[hv3],[hv4])
+ OVN_CLEANUP([hv1],[hv2],[hv3],[hv4])
-AT_CLEANUP
+ AT_CLEANUP])
+
+DVR_N_S_PING([geneve])
+DVR_N_S_PING([vxlan])
AT_SETUP([ovn -- ARP lookup before learning])
AT_KEYWORDS([virtual ports])
Because of limited space in VXLAN VNI to pass over all three of - datapath id, ingress port, egress port - the implementation ignores ingress; and splits the remaining 24 bits of VNI into two chunks, 12 bits each - one for datapath and one for egress port. This also bumps priority for ramp switch flows to 110 to prioritize them over regular non-ramp VXLAN flows. Limitations: because ingress port is not passed, ACLs that rely on it won't work with VXLAN; reduced number of networks and ports per network (max 4096 for both). NB consumers may use NB_Global options:max_tunid to determine maximum capacity for logical switches supported by the setup. Renamed MLF_RCV_FROM_VXLAN_BIT into MLF_RCV_FROM_RAMP_BIT to reflect the new use case. Added test scenarios that ping through VXLAN tunnel between two hypervisors added. Also max_tunid is validated. Signed-off-by: Ihar Hrachyshka <ihrachys@redhat.com> --- Changes: - v2: run several dvr connectivity tests with vxlan tunnels. - v2: update ovn-architecture.7 documentation. - v3: added is_vxlan helper. - v4: reduce max tunid when vxlan is enabled in cluster. - v4: added options:max_tunid key for NB_Global. - v5: rebased. - v5: renamed MLF_RCV_FROM_VXLAN -> MLF_RCV_FROM_RAMP. - v5: simplify flows for vxlan non-ramp scenario, don't match against tun_id. - v5: bumped priority for ramp flows to 110 to prioritize them over regular non-ramp vxlan flows. --- controller/physical.c | 63 +- include/ovn/logical-fields.h | 12 +- lib/ovn-util.h | 5 + northd/ovn-northd.c | 78 ++- ovn-architecture.7.xml | 105 +++- ovn-nb.xml | 7 + tests/ovn-macros.at | 4 +- tests/ovn.at | 1083 +++++++++++++++++----------------- 8 files changed, 714 insertions(+), 643 deletions(-)