[ovs-dev] [PATCH 2/2] ovn: Fix localnet ports on the same chassis.
Kyle Mestery
mestery at mestery.com
Tue Jan 19 15:27:40 UTC 2016
On Mon, Jan 18, 2016 at 9:45 AM, Russell Bryant <russell at ovn.org> wrote:
> Multiple logical ports on the same chassis that were connected to the
> same physical network via localnet ports were not able to send packets
> to each other. This was because ovn-controller created a single patch
> port between br-int and the physical network access bridge and used it
> for all localnet ports.
>
> The fix implemented here is to create a separate patch port for every
> logical port of type=localnet. An optimization is included where these
> ports are only created if the localnet port is on a logical switch with
> another logical port with an associated local VIF.
>
> A nice side effect of this fix is that the code in physical.c got a lot
> simpler, as localnet ports are now handled mostly like local VIFs.
>
> Fixes: c02819293d52 ("ovn: Add "localnet" logical port type.")
> Reported-by: Han Zhou <zhouhan at gmail.com>
> Reported-at: http://openvswitch.org/pipermail/dev/2016-January/064413.html
> Signed-off-by: Russell Bryant <russell at ovn.org>
I have tested this series out on a 4 node system (1 AIO control node, 2
compute nodes, and a separate ovn-northd/OVSDB node), and it does indeed
work as advertised! Nice work Russell!
Tested-By: Kyle Mestery <mestery at mestery.com>
Acked-By: Kyle Mestery <mestery at mestery.com>
> ---
> ovn/controller/ovn-controller.c | 10 +-
> ovn/controller/patch.c | 80 +++++++++-----
> ovn/controller/patch.h | 4 +-
> ovn/controller/physical.c | 237 +++++++++-------------------------------
> ovn/controller/physical.h | 3 +-
> tests/ovn-controller.at | 39 ++++---
> tests/ovn.at | 10 +-
> 7 files changed, 140 insertions(+), 243 deletions(-)
>
> diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c
> index aefe1a5..b4d3fd3 100644
> --- a/ovn/controller/ovn-controller.c
> +++ b/ovn/controller/ovn-controller.c
> @@ -285,11 +285,6 @@ main(int argc, char *argv[])
> const struct ovsrec_bridge *br_int = get_br_int(&ctx);
> const char *chassis_id = get_chassis_id(ctx.ovs_idl);
>
> - /* Map bridges to local nets from ovn-bridge-mappings */
> - if (br_int) {
> - patch_run(&ctx, br_int);
> - }
> -
> if (chassis_id) {
> chassis_run(&ctx, chassis_id);
> encaps_run(&ctx, br_int, chassis_id);
> @@ -298,6 +293,8 @@ main(int argc, char *argv[])
> }
>
> if (br_int) {
> + patch_run(&ctx, br_int, &local_datapaths);
> +
> enum mf_field_id mff_ovn_geneve = ofctrl_run(br_int);
>
> pinctrl_run(&ctx, br_int);
> @@ -306,8 +303,7 @@ main(int argc, char *argv[])
> lflow_run(&ctx, &flow_table, &ct_zones);
> if (chassis_id) {
> physical_run(&ctx, mff_ovn_geneve,
> - br_int, chassis_id, &ct_zones, &flow_table,
> - &local_datapaths);
> + br_int, chassis_id, &ct_zones, &flow_table);
> }
> ofctrl_put(&flow_table);
> hmap_destroy(&flow_table);
> diff --git a/ovn/controller/patch.c b/ovn/controller/patch.c
> index 07a3540..a48da6d 100644
> --- a/ovn/controller/patch.c
> +++ b/ovn/controller/patch.c
> @@ -18,6 +18,7 @@
> #include "patch.h"
>
> #include "hash.h"
> +#include "lib/hmap.h"
> #include "lib/vswitch-idl.h"
> #include "openvswitch/vlog.h"
> #include "ovn-controller.h"
> @@ -95,27 +96,6 @@ create_patch_port(struct controller_ctx *ctx,
> free(ports);
> }
>
> -/* Creates a pair of patch ports that connect bridges 'b1' and 'b2', using a
> - * port named 'name1' and 'name2' in each respective bridge.
> - * external-ids:'key' in each port is initialized to 'value'.
> - *
> - * If one or both of the ports already exists, leaves it there and removes it
> - * from 'existing_ports'. */
> -static void
> -create_patch_ports(struct controller_ctx *ctx,
> - const char *key, const char *value,
> - const struct ovsrec_bridge *b1,
> - const struct ovsrec_bridge *b2,
> - struct shash *existing_ports)
> -{
> - char *name1 = patch_port_name(b1->name, b2->name);
> - char *name2 = patch_port_name(b2->name, b1->name);
> - create_patch_port(ctx, key, value, b1, name1, b2, name2, existing_ports);
> - create_patch_port(ctx, key, value, b2, name2, b1, name1, existing_ports);
> - free(name2);
> - free(name1);
> -}
> -
> static void
> remove_port(struct controller_ctx *ctx,
> const struct ovsrec_port *port)
> @@ -153,7 +133,8 @@ remove_port(struct controller_ctx *ctx,
> static void
> add_bridge_mappings(struct controller_ctx *ctx,
> const struct ovsrec_bridge *br_int,
> - struct shash *existing_ports)
> + struct shash *existing_ports,
> + struct hmap *local_datapaths)
> {
> /* Get ovn-bridge-mappings. */
> const char *mappings_cfg = "";
> @@ -166,7 +147,8 @@ add_bridge_mappings(struct controller_ctx *ctx,
> }
> }
>
> - /* Create patch ports. */
> + /* Parse bridge mappings. */
> + struct shash bridge_mappings = SHASH_INITIALIZER(&bridge_mappings);
> char *cur, *next, *start;
> next = start = xstrdup(mappings_cfg);
> while ((cur = strsep(&next, ",")) && *cur) {
> @@ -187,10 +169,53 @@ add_bridge_mappings(struct controller_ctx *ctx,
> continue;
> }
>
> - create_patch_ports(ctx, "ovn-localnet-port", network,
> - br_int, ovs_bridge, existing_ports);
> + shash_add(&bridge_mappings, network, ovs_bridge);
> }
> free(start);
> +
> + const struct sbrec_port_binding *binding;
> + SBREC_PORT_BINDING_FOR_EACH (binding, ctx->ovnsb_idl) {
> + if (strcmp(binding->type, "localnet")) {
> + /* Not a binding for a localnet port. */
> + continue;
> + }
> +
> + struct hmap_node *ld;
> + ld = hmap_first_with_hash(local_datapaths,
> + binding->datapath->tunnel_key);
> + if (!ld) {
> + /* This localnet port is on a datapath with no
> + * logical ports bound to this chassis, so there's no need
> + * to create patch ports for it. */
> + continue;
> + }
> +
> + const char *network = smap_get(&binding->options, "network_name");
> + if (!network) {
> + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
> + VLOG_ERR_RL(&rl, "localnet port '%s' has no network name.",
> + binding->logical_port);
> + continue;
> + }
> + struct ovsrec_bridge *br_ln = shash_find_data(&bridge_mappings, network);
> + if (!br_ln) {
> + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
> + VLOG_ERR_RL(&rl, "localnet port '%s' has no bridge.",
> + binding->logical_port);
> + continue;
> + }
> +
> + char *name1 = patch_port_name(br_int->name, binding->logical_port);
> + char *name2 = patch_port_name(binding->logical_port, br_int->name);
> + create_patch_port(ctx, "ovn-localnet-port", binding->logical_port,
> + br_int, name1, br_ln, name2, existing_ports);
> + create_patch_port(ctx, "ovn-localnet-port", binding->logical_port,
> + br_ln, name2, br_int, name1, existing_ports);
> + free(name1);
> + free(name2);
> + }
> +
> + shash_destroy(&bridge_mappings);
> }
>
> /* Add one OVS patch port for each OVN logical patch port.
> @@ -241,7 +266,8 @@ add_logical_patch_ports(struct controller_ctx *ctx,
> }
>
> void
> -patch_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int)
> +patch_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
> + struct hmap *local_datapaths)
> {
> if (!ctx->ovs_idl_txn) {
> return;
> @@ -260,7 +286,7 @@ patch_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int)
> /* Create in the database any patch ports that should exist. Remove from
> * 'existing_ports' any patch ports that do exist in the database and
> * should be there. */
> - add_bridge_mappings(ctx, br_int, &existing_ports);
> + add_bridge_mappings(ctx, br_int, &existing_ports, local_datapaths);
> add_logical_patch_ports(ctx, br_int, &existing_ports);
>
> /* Now 'existing_ports' only still contains patch ports that exist in the
> diff --git a/ovn/controller/patch.h b/ovn/controller/patch.h
> index f7db2fc..38ee7a8 100644
> --- a/ovn/controller/patch.h
> +++ b/ovn/controller/patch.h
> @@ -23,8 +23,10 @@
> * physical bridges, as directed by other-config:ovn-bridge-mappings. */
>
> struct controller_ctx;
> +struct hmap;
> struct ovsrec_bridge;
>
> -void patch_run(struct controller_ctx *, const struct ovsrec_bridge *br_int);
> +void patch_run(struct controller_ctx *, const struct ovsrec_bridge *br_int,
> + struct hmap *local_datapaths);
>
> #endif /* ovn/patch.h */
> diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c
> index 1ed36b1..ac3edc2 100644
> --- a/ovn/controller/physical.c
> +++ b/ovn/controller/physical.c
> @@ -138,12 +138,10 @@ put_stack(enum mf_field_id field, struct ofpact_stack *stack)
> void
> physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
> const struct ovsrec_bridge *br_int, const char *this_chassis_id,
> - const struct simap *ct_zones, struct hmap *flow_table,
> - struct hmap *local_datapaths)
> + const struct simap *ct_zones, struct hmap *flow_table)
> {
> struct simap localvif_to_ofport = SIMAP_INITIALIZER(&localvif_to_ofport);
> struct hmap tunnels = HMAP_INITIALIZER(&tunnels);
> - struct simap localnet_to_ofport = SIMAP_INITIALIZER(&localnet_to_ofport);
>
> for (int i = 0; i < br_int->n_ports; i++) {
> const struct ovsrec_port *port_rec = br_int->ports[i];
> @@ -178,7 +176,8 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
> * local logical port. */
> bool is_patch = !strcmp(iface_rec->type, "patch");
> if (is_patch && localnet) {
> - simap_put(&localnet_to_ofport, localnet, ofport);
> + /* localnet patch ports can be handled just like VIFs. */
> + simap_put(&localvif_to_ofport, localnet, ofport);
> break;
> } else if (is_patch && logpatch) {
> /* Logical patch ports can be handled just like VIFs. */
> @@ -219,24 +218,6 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
> struct ofpbuf ofpacts;
> ofpbuf_init(&ofpacts, 0);
>
> - struct binding_elem {
> - struct ovs_list list_elem;
> - const struct sbrec_port_binding *binding;
> - };
> - /* The bindings for a given VLAN on a localnet port. */
> - struct localnet_vlan {
> - struct hmap_node node;
> - int tag;
> - struct ovs_list bindings;
> - };
> - /* A hash of localnet_vlans, hashed on VLAN ID, for a localnet port */
> - struct localnet_bindings {
> - ofp_port_t ofport;
> - struct hmap vlans;
> - };
> - /* Maps from network name to "struct localnet_bindings". */
> - struct shash localnet_inputs = SHASH_INITIALIZER(&localnet_inputs);
> -
> /* Set up flows in table 0 for physical-to-logical translation and in table
> * 64 for logical-to-physical translation. */
> const struct sbrec_port_binding *binding;
> @@ -247,36 +228,23 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
> * - If the port is a VIF on the chassis we're managing, the
> * OpenFlow port for the VIF. 'tun' will be NULL.
> *
> - * In this or the next case, for a container nested inside a VM
> - * and accessible via a VLAN, 'tag' is the VLAN ID; otherwise
> - * 'tag' is 0.
> + * The same logic handles logical patch ports, as well as
> + * localnet patch ports.
> + *
> + * For a container nested inside a VM and accessible via a VLAN,
> + * 'tag' is the VLAN ID; otherwise 'tag' is 0.
> *
> - * The same logic handles logical patch ports.
> + * For a localnet patch port, if a VLAN ID was configured, 'tag'
> + * is set to that VLAN ID; otherwise 'tag' is 0.
> *
> * - If the port is on a remote chassis, the OpenFlow port for a
> * tunnel to the VIF's remote chassis. 'tun' identifies that
> * tunnel.
> - *
> - * - If the port is a "localnet" port for a network that is
> - * attached to the chassis we're managing, the OpenFlow port for
> - * the localnet port (a patch port).
> - *
> - * The "localnet" port may be configured with a VLAN ID. If so,
> - * 'tag' will be set to that VLAN ID; otherwise 'tag' is 0.
> */
>
> int tag = 0;
> ofp_port_t ofport;
> - if (!strcmp(binding->type, "localnet")) {
> - const char *network = smap_get(&binding->options, "network_name");
> - if (!network) {
> - continue;
> - }
> - ofport = u16_to_ofp(simap_get(&localnet_to_ofport, network));
> - if (ofport && binding->tag) {
> - tag = *binding->tag;
> - }
> - } else if (binding->parent_port) {
> + if (binding->parent_port && *binding->parent_port) {
> if (!binding->tag) {
> continue;
> }
> @@ -288,6 +256,9 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
> } else {
> ofport = u16_to_ofp(simap_get(&localvif_to_ofport,
> binding->logical_port));
> + if (!strcmp(binding->type, "localnet") && ofport && binding->tag) {
> + tag = *binding->tag;
> + }
> }
>
> const struct chassis_tunnel *tun = NULL;
> @@ -324,64 +295,48 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
> * input port, MFF_LOG_DATAPATH to the logical datapath, and
> * resubmit into the logical ingress pipeline starting at table
> * 16. */
> - if (!strcmp(binding->type, "localnet")) {
> - /* The same OpenFlow port may correspond to localnet ports
> - * attached to more than one logical datapath, so keep track of
> - * all associated bindings and add a flow at the end. */
> -
> - const char *network
> - = smap_get(&binding->options, "network_name");
> - struct localnet_bindings *ln_bindings;
> - struct hmap_node *node;
> - struct localnet_vlan *ln_vlan;
> -
> - ln_bindings = shash_find_data(&localnet_inputs, network);
> - if (!ln_bindings) {
> - ln_bindings = xmalloc(sizeof *ln_bindings);
> - ln_bindings->ofport = ofport;
> - hmap_init(&ln_bindings->vlans);
> - shash_add(&localnet_inputs, network, ln_bindings);
> - }
> - node = hmap_first_with_hash(&ln_bindings->vlans, tag);
> - if (node) {
> - ASSIGN_CONTAINER(ln_vlan, node, node);
> - } else {
> - ln_vlan = xmalloc(sizeof *ln_vlan);
> - ln_vlan->tag = tag;
> - list_init(&ln_vlan->bindings);
> - hmap_insert(&ln_bindings->vlans, &ln_vlan->node, tag);
> - }
> -
> - struct binding_elem *b = xmalloc(sizeof *b);
> - b->binding = binding;
> - list_insert(&ln_vlan->bindings, &b->list_elem);
> - } else {
> - ofpbuf_clear(&ofpacts);
> - match_init_catchall(&match);
> - match_set_in_port(&match, ofport);
> - if (tag) {
> - match_set_dl_vlan(&match, htons(tag));
> - }
> + ofpbuf_clear(&ofpacts);
> + match_init_catchall(&match);
> + match_set_in_port(&match, ofport);
> + if (tag) {
> + match_set_dl_vlan(&match, htons(tag));
> + } else if (!strcmp(binding->type, "localnet")) {
> + /* Match priority-tagged frames, e.g. VLAN ID 0.
> + *
> + * We'll add a second flow for frames that lack any 802.1Q
> + * header later. */
> + match_set_dl_tci_masked(&match, htons(VLAN_CFI),
> + htons(VLAN_VID_MASK | VLAN_CFI));
> + }
>
> - if (zone_id) {
> - put_load(zone_id, MFF_LOG_CT_ZONE, 0, 32, &ofpacts);
> - }
> + /* Strip vlans. */
> + if (tag) {
> + ofpact_put_STRIP_VLAN(&ofpacts);
> + }
> + uint32_t ofpacts_orig_size = ofpacts.size;
>
> - /* Set MFF_LOG_DATAPATH and MFF_LOG_INPORT. */
> - put_load(binding->datapath->tunnel_key, MFF_LOG_DATAPATH, 0, 64,
> - &ofpacts);
> - put_load(binding->tunnel_key, MFF_LOG_INPORT, 0, 32,
> - &ofpacts);
> + if (zone_id) {
> + put_load(zone_id, MFF_LOG_CT_ZONE, 0, 32, &ofpacts);
> + }
>
> - /* Strip vlans. */
> - if (tag) {
> - ofpact_put_STRIP_VLAN(&ofpacts);
> - }
> + /* Set MFF_LOG_DATAPATH and MFF_LOG_INPORT. */
> + put_load(binding->datapath->tunnel_key, MFF_LOG_DATAPATH, 0, 64,
> + &ofpacts);
> + put_load(binding->tunnel_key, MFF_LOG_INPORT, 0, 32,
> + &ofpacts);
>
> - /* Resubmit to first logical ingress pipeline table. */
> - put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, &ofpacts);
> - ofctrl_add_flow(flow_table, OFTABLE_PHY_TO_LOG,
> - tag ? 150 : 100, &match, &ofpacts);
> + /* Resubmit to first logical ingress pipeline table. */
> + put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, &ofpacts);
> + ofctrl_add_flow(flow_table, OFTABLE_PHY_TO_LOG,
> + tag ? 150 : 100, &match, &ofpacts);
> +
> + if (!tag && !strcmp(binding->type, "localnet")) {
> + /* Add a second flow for frames that lack any 802.1Q
> + * header. For these, drop the OFPACT_STRIP_VLAN
> + * action. */
> + ofpbuf_pull(&ofpacts, ofpacts_orig_size);
> + match_set_dl_tci_masked(&match, 0, htons(VLAN_CFI));
> + ofctrl_add_flow(flow_table, 0, 100, &match, &ofpacts);
> }
>
> /* Table 33, priority 100.
> @@ -530,22 +485,12 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
> &remote_ofpacts);
> put_resubmit(OFTABLE_DROP_LOOPBACK, &remote_ofpacts);
> } else if (simap_contains(&localvif_to_ofport,
> - port->parent_port
> + port->parent_port && *port->parent_port
> ? port->parent_port : port->logical_port)) {
> put_load(port->tunnel_key, MFF_LOG_OUTPORT, 0, 32, &ofpacts);
> put_resubmit(OFTABLE_DROP_LOOPBACK, &ofpacts);
> } else if (port->chassis) {
> sset_add(&remote_chassis, port->chassis->name);
> - } else if (!strcmp(port->type, "localnet")) {
> - const char *network = smap_get(&port->options, "network_name");
> - if (!network) {
> - continue;
> - }
> - if (!simap_contains(&localnet_to_ofport, network)) {
> - continue;
> - }
> - put_load(port->tunnel_key, MFF_LOG_OUTPORT, 0, 32, &ofpacts);
> - put_resubmit(OFTABLE_DROP_LOOPBACK, &ofpacts);
> }
> }
>
> @@ -713,80 +658,4 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
> free(tun);
> }
> hmap_destroy(&tunnels);
> -
> - /* Table 0, Priority 100.
> - * ======================
> - *
> - * We have now determined the full set of port bindings associated with
> - * each "localnet" network. Only create flows for datapaths that have
> - * another local binding. Otherwise, we know it would just be dropped.
> - */
> - struct shash_node *ln_bindings_node, *ln_bindings_node_next;
> - SHASH_FOR_EACH_SAFE (ln_bindings_node, ln_bindings_node_next,
> - &localnet_inputs) {
> - struct localnet_bindings *ln_bindings = ln_bindings_node->data;
> - struct localnet_vlan *ln_vlan, *ln_vlan_next;
> - HMAP_FOR_EACH_SAFE (ln_vlan, ln_vlan_next, node, &ln_bindings->vlans) {
> - struct match match;
> - match_init_catchall(&match);
> - match_set_in_port(&match, ln_bindings->ofport);
> - if (ln_vlan->tag) {
> - match_set_dl_vlan(&match, htons(ln_vlan->tag));
> - } else {
> - /* Match priority-tagged frames, e.g. VLAN ID 0.
> - *
> - * We'll add a second flow for frames that lack any 802.1Q
> - * header later. */
> - match_set_dl_tci_masked(&match, htons(VLAN_CFI),
> - htons(VLAN_VID_MASK | VLAN_CFI));
> - }
> -
> - struct ofpbuf ofpacts;
> - ofpbuf_init(&ofpacts, 0);
> -
> - ofpact_put_STRIP_VLAN(&ofpacts);
> - uint32_t ofpacts_orig_size = ofpacts.size;
> -
> - struct binding_elem *b;
> - LIST_FOR_EACH_POP (b, list_elem, &ln_vlan->bindings) {
> - struct hmap_node *ld;
> - ld = hmap_first_with_hash(local_datapaths,
> - b->binding->datapath->tunnel_key);
> - if (ld) {
> - /* Set MFF_LOG_DATAPATH and MFF_LOG_INPORT. */
> - put_load(b->binding->datapath->tunnel_key, MFF_LOG_DATAPATH,
> - 0, 64, &ofpacts);
> - put_load(b->binding->tunnel_key, MFF_LOG_INPORT, 0, 32,
> - &ofpacts);
> - put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, &ofpacts);
> - }
> -
> - free(b);
> - }
> -
> - if (ofpacts.size > ofpacts_orig_size) {
> - ofctrl_add_flow(flow_table, 0, 100, &match, &ofpacts);
> -
> - if (!ln_vlan->tag) {
> - /* Add a second flow for frames that lack any 802.1Q
> - * header. For these, drop the OFPACT_STRIP_VLAN
> - * action. */
> - ofpbuf_pull(&ofpacts, ofpacts_orig_size);
> - match_set_dl_tci_masked(&match, 0, htons(VLAN_CFI));
> - ofctrl_add_flow(flow_table, 0, 100, &match, &ofpacts);
> - }
> - }
> -
> - ofpbuf_uninit(&ofpacts);
> -
> - hmap_remove(&ln_bindings->vlans, &ln_vlan->node);
> - free(ln_vlan);
> - }
> - shash_delete(&localnet_inputs, ln_bindings_node);
> - hmap_destroy(&ln_bindings->vlans);
> - free(ln_bindings);
> - }
> - shash_destroy(&localnet_inputs);
> -
> - simap_destroy(&localnet_to_ofport);
> }
> diff --git a/ovn/controller/physical.h b/ovn/controller/physical.h
> index 826b99b..2906937 100644
> --- a/ovn/controller/physical.h
> +++ b/ovn/controller/physical.h
> @@ -43,7 +43,6 @@ struct simap;
> void physical_register_ovs_idl(struct ovsdb_idl *);
> void physical_run(struct controller_ctx *, enum mf_field_id mff_ovn_geneve,
> const struct ovsrec_bridge *br_int, const char *chassis_id,
> - const struct simap *ct_zones, struct hmap *flow_table,
> - struct hmap *local_datapaths);
> + const struct simap *ct_zones, struct hmap *flow_table);
>
> #endif /* ovn/physical.h */
> diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
> index bc93471..117e15e 100644
> --- a/tests/ovn-controller.at
> +++ b/tests/ovn-controller.at
> @@ -49,21 +49,30 @@ patch
> # Initially there should be no patch ports.
> check_patches
>
> -# Configure two ovn-bridge mappings to create two patch ports.
> +# Configure two ovn-bridge mappings, but no patch ports should be created yet
> AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0,physnet2:br-eth1])
> -check_patches \
> - 'br-eth0 patch-br-eth0-to-br-int patch-br-int-to-br-eth0' \
> - 'br-int patch-br-int-to-br-eth0 patch-br-eth0-to-br-int' \
> - 'br-eth1 patch-br-eth1-to-br-int patch-br-int-to-br-eth1' \
> - 'br-int patch-br-int-to-br-eth1 patch-br-eth1-to-br-int'
> +check_patches
> +
> +# Create a localnet port, but we should still have no patch ports, as they
> +# won't be created until there's a localnet port on a logical switch with
> +# another logical port bound to this chassis.
> +ovn-sbctl \
> + -- --id=@dp101 create Datapath_Binding tunnel_key=101 \
> + -- create Port_Binding datapath=@dp101 logical_port=localnet1 tunnel_key=101 \
> + type=localnet options:network_name=physnet1
> +check_patches
>
> -# Change the mapping and the patch ports should change.
> -AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth2,physnet2:br-eth1])
> +# Create a localnet port on a logical switch with a port bound to this chassis.
> +# Now we should get some patch ports created.
> +ovn-sbctl \
> + -- --id=@dp102 create Datapath_Binding tunnel_key=102 \
> + -- create Port_Binding datapath=@dp102 logical_port=localnet2 tunnel_key=1 \
> + type=localnet options:network_name=physnet1 \
> + -- create Port_Binding datapath=@dp102 logical_port=localvif2 tunnel_key=2
> +ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2
> check_patches \
> - 'br-eth2 patch-br-eth2-to-br-int patch-br-int-to-br-eth2' \
> - 'br-int patch-br-int-to-br-eth2 patch-br-eth2-to-br-int' \
> - 'br-eth1 patch-br-eth1-to-br-int patch-br-int-to-br-eth1' \
> - 'br-int patch-br-int-to-br-eth1 patch-br-eth1-to-br-int'
> + 'br-int patch-br-int-to-localnet2 patch-localnet2-to-br-int' \
> + 'br-eth0 patch-localnet2-to-br-int patch-br-int-to-localnet2'
>
> # Add logical patch ports.
> AT_CHECK([ovn-sbctl \
> @@ -77,10 +86,8 @@ AT_CHECK([ovn-sbctl \
> <3>
> ])
> check_patches \
> - 'br-eth2 patch-br-eth2-to-br-int patch-br-int-to-br-eth2' \
> - 'br-int patch-br-int-to-br-eth2 patch-br-eth2-to-br-int' \
> - 'br-eth1 patch-br-eth1-to-br-int patch-br-int-to-br-eth1' \
> - 'br-int patch-br-int-to-br-eth1 patch-br-eth1-to-br-int' \
> + 'br-int patch-br-int-to-localnet2 patch-localnet2-to-br-int' \
> + 'br-eth0 patch-localnet2-to-br-int patch-br-int-to-localnet2' \
> 'br-int patch-foo-to-bar patch-bar-to-foo' \
> 'br-int patch-bar-to-foo patch-foo-to-bar'
>
> diff --git a/tests/ovn.at b/tests/ovn.at
> index b990116..22c3b84 100644
> --- a/tests/ovn.at
> +++ b/tests/ovn.at
> @@ -830,9 +830,8 @@ test_packet 21 f00000000011 f00000000021 2111 11
>
> # lp11 and lp12 are on the same network (phys, untagged)
> # and on the same hypervisor
> -# TODO this is broken.
> -#test_packet 11 f00000000012 f00000000011 1112 12
> -#test_packet 12 f00000000011 f00000000012 1211 11
> +test_packet 11 f00000000012 f00000000011 1112 12
> +test_packet 12 f00000000011 f00000000012 1211 11
>
> # lp13 and lp23 are on the same network (phys, VLAN 101)
> # and on different hypervisors
> @@ -841,9 +840,8 @@ test_packet 23 f00000000013 f00000000023 2313 13
>
> # lp13 and lp14 are on the same network (phys, VLAN 101)
> # and on the same hypervisor
> -# TODO this is broken.
> -#test_packet 13 f00000000014 f00000000013 1314 14
> -#test_packet 14 f00000000013 f00000000014 1413 13
> +test_packet 13 f00000000014 f00000000013 1314 14
> +test_packet 14 f00000000013 f00000000014 1413 13
>
> # Ports that should not be able to communicate
> test_packet 11 f00000000013 f00000000011 1113
> --
> 2.5.0
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
More information about the dev
mailing list