[ovs-dev] [patch_v2] ovn: add local router support (RFC)
Darrell Ball
dlu998 at gmail.com
Tue May 10 04:06:08 UTC 2016
superceded by v3
On Mon, May 9, 2016 at 8:53 PM, Darrell Ball <dlu998 at gmail.com> wrote:
> This patch adds local router support. A logical router can
> be declared local at northbound level via external_ids.
> This is communicated to the southbound database via northd
> which populates the external_id of the datapath_binding table.
> ovn-controller will also allow a chassis to be configured for 1 or
> more local routers.
> When ovn-controller configures openflow rules it looks at whether
> a logical router is local and it so it checks where its chassis
> instance local routers has this particular logical router configured
> as local; if it does, it allows the southbound flows of the local
> logical router to be translated into openflow rules and programmed
> on this chassis. If a logical router is labelled as local but a
> given chassis is not configured for that logical router to be local,
> then the corresponding openflow rules are not programmed on this
> chassis.
>
> v1->v2: enabled more debug in test
> avoid creating patch port where unnecessary
>
> Signed-off-by: Darrell Ball <dlu998 at gmail.com>
> ---
> ovn/controller/chassis.c | 32 +++++-
> ovn/controller/chassis.h | 4 +-
> ovn/controller/lflow.c | 16 ++-
> ovn/controller/lflow.h | 4 +-
> ovn/controller/ovn-controller.8.xml | 8 ++
> ovn/controller/ovn-controller.c | 58 ++++++++++-
> ovn/controller/ovn-controller.h | 4 +
> ovn/controller/patch.c | 24 ++++-
> ovn/controller/patch.h | 4 +-
> ovn/northd/ovn-northd.c | 17 +++-
> ovn/ovn-nb.xml | 6 +-
> ovn/ovn-sb.xml | 8 ++
> tests/ovn.at | 193
> ++++++++++++++++++++++++++++++++++++
> 13 files changed, 359 insertions(+), 19 deletions(-)
>
> diff --git a/ovn/controller/chassis.c b/ovn/controller/chassis.c
> index d40181b..e58145b 100644
> --- a/ovn/controller/chassis.c
> +++ b/ovn/controller/chassis.c
> @@ -24,6 +24,7 @@
> #include "openvswitch/vlog.h"
> #include "ovn/lib/ovn-sb-idl.h"
> #include "ovn-controller.h"
> +#include "sset.h"
>
> VLOG_DEFINE_THIS_MODULE(chassis);
>
> @@ -63,8 +64,16 @@ get_bridge_mappings(const struct smap *ext_ids)
> return bridge_mappings ? bridge_mappings : "";
> }
>
> +static const char *
> +get_local_routers(const struct smap *ext_ids)
> +{
> + const char *local_routers = smap_get(ext_ids, "local-routers");
> + return local_routers ? local_routers : "";
> +}
> +
> void
> -chassis_run(struct controller_ctx *ctx, const char *chassis_id)
> +chassis_run(struct controller_ctx *ctx, const char *chassis_id,
> + struct sset *local_router_datapaths)
> {
> if (!ctx->ovnsb_idl_txn) {
> return;
> @@ -112,6 +121,8 @@ chassis_run(struct controller_ctx *ctx, const char
> *chassis_id)
>
> const char *bridge_mappings = get_bridge_mappings(&cfg->external_ids);
>
> + const char *local_routers = get_local_routers(&cfg->external_ids);
> +
> const struct sbrec_chassis *chassis_rec
> = get_chassis(ctx->ovnsb_idl, chassis_id);
>
> @@ -131,6 +142,17 @@ chassis_run(struct controller_ctx *ctx, const char
> *chassis_id)
> smap_destroy(&new_ids);
> }
>
> + const char *chassis_local_routers
> + = get_local_routers(&chassis_rec->external_ids);
> + if (strcmp(local_routers, chassis_local_routers)) {
> + struct smap new_ids;
> + smap_clone(&new_ids, &chassis_rec->external_ids);
> + smap_replace(&new_ids, "local-router", local_routers);
> + sbrec_chassis_verify_external_ids(chassis_rec);
> + sbrec_chassis_set_external_ids(chassis_rec, &new_ids);
> + smap_destroy(&new_ids);
> + }
> +
> /* Compare desired tunnels against those currently in the
> database. */
> uint32_t cur_tunnels = 0;
> bool same = true;
> @@ -166,12 +188,16 @@ chassis_run(struct controller_ctx *ctx, const char
> *chassis_id)
> chassis_id);
>
> if (!chassis_rec) {
> - struct smap ext_ids = SMAP_CONST1(&ext_ids, "ovn-bridge-mappings",
> - bridge_mappings);
> +
> + struct smap ext_ids = SMAP_INITIALIZER(&ext_ids);
> + smap_add(&ext_ids, "ovn-bridge-mappings",
> + bridge_mappings);
> + smap_add(&ext_ids, "local-routers", local_routers);
> chassis_rec = sbrec_chassis_insert(ctx->ovnsb_idl_txn);
> sbrec_chassis_set_name(chassis_rec, chassis_id);
> sbrec_chassis_set_hostname(chassis_rec, hostname);
> sbrec_chassis_set_external_ids(chassis_rec, &ext_ids);
> + smap_destroy(&ext_ids);
> }
>
> int n_encaps = count_1bits(req_tunnels);
> diff --git a/ovn/controller/chassis.h b/ovn/controller/chassis.h
> index 26017d0..324e3cf 100644
> --- a/ovn/controller/chassis.h
> +++ b/ovn/controller/chassis.h
> @@ -21,9 +21,11 @@
> struct controller_ctx;
> struct ovsdb_idl;
> struct ovsrec_bridge;
> +struct sset;
>
> void chassis_register_ovs_idl(struct ovsdb_idl *);
> -void chassis_run(struct controller_ctx *, const char *chassis_id);
> +void chassis_run(struct controller_ctx *, const char *chassis_id,
> + struct sset *);
> bool chassis_cleanup(struct controller_ctx *, const char *chassis_id);
>
> #endif /* ovn/chassis.h */
> diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c
> index 96b7c66..ec423f8 100644
> --- a/ovn/controller/lflow.c
> +++ b/ovn/controller/lflow.c
> @@ -199,7 +199,8 @@ add_logical_flows(struct controller_ctx *ctx, const
> struct lport_index *lports,
> const struct mcgroup_index *mcgroups,
> const struct hmap *local_datapaths,
> const struct hmap *patched_datapaths,
> - const struct simap *ct_zones, struct hmap *flow_table)
> + const struct simap *ct_zones, struct hmap *flow_table,
> + const struct sset *local_routers)
> {
> uint32_t conj_id_ofs = 1;
>
> @@ -250,6 +251,13 @@ add_logical_flows(struct controller_ctx *ctx, const
> struct lport_index *lports,
> continue;
> }
> }
> + } else {
> + const char *local_router =
> + smap_get(&ldp->external_ids, "local-router");
> + if (local_router && strcmp(local_router, "") &&
> + !is_local_router(local_routers, local_router)) {
> + continue;
> + }
> }
>
> /* Determine translation of logical table IDs to physical table
> IDs. */
> @@ -429,10 +437,12 @@ lflow_run(struct controller_ctx *ctx, const struct
> lport_index *lports,
> const struct mcgroup_index *mcgroups,
> const struct hmap *local_datapaths,
> const struct hmap *patched_datapaths,
> - const struct simap *ct_zones, struct hmap *flow_table)
> + const struct simap *ct_zones, struct hmap *flow_table,
> + const struct sset *local_router_datapaths)
> {
> add_logical_flows(ctx, lports, mcgroups, local_datapaths,
> - patched_datapaths, ct_zones, flow_table);
> + patched_datapaths, ct_zones, flow_table,
> + local_router_datapaths);
> add_neighbor_flows(ctx, lports, flow_table);
> }
>
> diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h
> index a3fc50c..4144481 100644
> --- a/ovn/controller/lflow.h
> +++ b/ovn/controller/lflow.h
> @@ -41,6 +41,7 @@ struct lport_index;
> struct mcgroup_index;
> struct simap;
> struct uuid;
> +struct sset;
>
> /* OpenFlow table numbers.
> *
> @@ -64,7 +65,8 @@ void lflow_run(struct controller_ctx *, const struct
> lport_index *,
> const struct hmap *local_datapaths,
> const struct hmap *patched_datapaths,
> const struct simap *ct_zones,
> - struct hmap *flow_table);
> + struct hmap *flow_table,
> + const struct sset *local_routers);
> void lflow_destroy(void);
>
> #endif /* ovn/lflow.h */
> diff --git a/ovn/controller/ovn-controller.8.xml
> b/ovn/controller/ovn-controller.8.xml
> index 1ee3a6e..582a00b 100644
> --- a/ovn/controller/ovn-controller.8.xml
> +++ b/ovn/controller/ovn-controller.8.xml
> @@ -154,6 +154,14 @@
> value mapping two physical network names to two ovs bridges would
> be:
> <code>physnet1:br-eth0,physnet2:br-eth1</code>.
> </dd>
> + <dt><code>external_ids:local-routers</code></dt>
> + <dd>
> + A set of a local routers on this chassis instance. The logical
> flows of a
> + local logical router datapath are only translated into openflow
> + flows if the chassis is configured for that local logical router.
> + An example set with two local routers would be:
> + <code>local_router_1,local_router_2</code>.
> + </dd>
> </dl>
>
> <h1>Open vSwitch Database Usage</h1>
> diff --git a/ovn/controller/ovn-controller.c
> b/ovn/controller/ovn-controller.c
> index f68f842..e1f8e25 100644
> --- a/ovn/controller/ovn-controller.c
> +++ b/ovn/controller/ovn-controller.c
> @@ -51,6 +51,7 @@
> #include "stream.h"
> #include "unixctl.h"
> #include "util.h"
> +#include "sset.h"
>
> VLOG_DEFINE_THIS_MODULE(main);
>
> @@ -252,6 +253,42 @@ get_ovnsb_remote_probe_interval(struct ovsdb_idl
> *ovs_idl, int *value)
> return false;
> }
>
> +bool is_local_router(const struct sset *local_routers,
> + const char *local_router)
> +{
> +
> + if (!local_routers || !local_router) {
> + return false;
> + }
> +
> + if (sset_find(local_routers, local_router)) {
> + return true;
> + }
> + return false;
> +}
> +
> +static void
> +build_local_routers(const struct smap *ext_ids,
> + struct sset *local_routers)
> +{
> + const char *local_router_cfg = smap_get(ext_ids, "local-routers");
> + if (!local_router_cfg) {
> + local_router_cfg = "";
> + }
> +
> + char *cur, *next, *start;
> + next = start = xstrdup(local_router_cfg);
> + while ((cur = strsep(&next, ",")) && *cur) {
> + char *local_router = cur;
> +
> + if (sset_find(local_routers, local_router)) {
> + continue;
> + }
> + sset_add(local_routers, local_router);
> + }
> + free(start);
> +}
> +
> int
> main(int argc, char *argv[])
> {
> @@ -353,18 +390,30 @@ main(int argc, char *argv[])
>
> struct hmap patched_datapaths =
> HMAP_INITIALIZER(&patched_datapaths);
>
> + struct sset local_routers =
> + SSET_INITIALIZER(&local_routers);
> +
> const struct ovsrec_bridge *br_int = get_br_int(&ctx);
> const char *chassis_id = get_chassis_id(ctx.ovs_idl);
>
> if (chassis_id) {
> - chassis_run(&ctx, chassis_id);
> + chassis_run(&ctx, chassis_id, &local_routers);
> +
> + const struct sbrec_chassis *chassis_rec =
> + get_chassis(ctx.ovnsb_idl, chassis_id);
> + if (chassis_rec) {
> + build_local_routers(&chassis_rec->external_ids,
> + &local_routers);
> + }
> +
> encaps_run(&ctx, br_int, chassis_id);
> binding_run(&ctx, br_int, chassis_id, &ct_zones,
> ct_zone_bitmap,
> &local_datapaths);
> }
>
> if (br_int) {
> - patch_run(&ctx, br_int, &local_datapaths, &patched_datapaths);
> + patch_run(&ctx, br_int, &local_datapaths, &patched_datapaths,
> + &local_routers);
>
> struct lport_index lports;
> struct mcgroup_index mcgroups;
> @@ -377,7 +426,8 @@ main(int argc, char *argv[])
>
> struct hmap flow_table = HMAP_INITIALIZER(&flow_table);
> lflow_run(&ctx, &lports, &mcgroups, &local_datapaths,
> - &patched_datapaths, &ct_zones, &flow_table);
> + &patched_datapaths, &ct_zones, &flow_table,
> + &local_routers);
> if (chassis_id) {
> physical_run(&ctx, mff_ovn_geneve,
> br_int, chassis_id, &ct_zones, &flow_table,
> @@ -404,6 +454,8 @@ main(int argc, char *argv[])
> }
> hmap_destroy(&patched_datapaths);
>
> + sset_destroy(&local_routers);
> +
> unixctl_server_run(unixctl);
>
> unixctl_server_wait(unixctl);
> diff --git a/ovn/controller/ovn-controller.h
> b/ovn/controller/ovn-controller.h
> index 9af7959..012560c 100644
> --- a/ovn/controller/ovn-controller.h
> +++ b/ovn/controller/ovn-controller.h
> @@ -23,6 +23,7 @@
> /* Linux supports a maximum of 64K zones, which seems like a fine
> default. */
> #define MAX_CT_ZONES 65535
>
> +struct sset;
> struct controller_ctx {
> struct ovsdb_idl *ovnsb_idl;
> struct ovsdb_idl_txn *ovnsb_idl_txn;
> @@ -53,6 +54,9 @@ struct patched_datapath {
> struct patched_datapath *get_patched_datapath(const struct hmap *,
> uint32_t tunnel_key);
>
> +bool is_local_router(const struct sset *local_routers,
> + const char *local_router);
> +
> const struct ovsrec_bridge *get_bridge(struct ovsdb_idl *,
> const char *br_name);
>
> diff --git a/ovn/controller/patch.c b/ovn/controller/patch.c
> index 4808146..ba8e601 100644
> --- a/ovn/controller/patch.c
> +++ b/ovn/controller/patch.c
> @@ -268,7 +268,8 @@ static void
> add_logical_patch_ports(struct controller_ctx *ctx,
> const struct ovsrec_bridge *br_int,
> struct shash *existing_ports,
> - struct hmap *patched_datapaths)
> + struct hmap *patched_datapaths,
> + const struct sset *local_routers)
> {
> const struct sbrec_port_binding *binding;
> SBREC_PORT_BINDING_FOR_EACH (binding, ctx->ovnsb_idl) {
> @@ -279,6 +280,20 @@ add_logical_patch_ports(struct controller_ctx *ctx,
> continue;
> }
>
> + const char *local_router =
> + smap_get(&binding->datapath->external_ids,
> "local-router");
> +
> + if (is_local_router(local_routers, local_router)) {
> + VLOG_INFO("local router found");
> + } else {
> + VLOG_INFO("local router not found");
> + }
> +
> + if (local_router && strcmp(local_router, "") &&
> + !is_local_router(local_routers, local_router)) {
> + continue;
> + }
> +
> char *src_name = patch_port_name(local, peer);
> char *dst_name = patch_port_name(peer, local);
> create_patch_port(ctx, "ovn-logical-patch-port", local,
> @@ -286,6 +301,7 @@ add_logical_patch_ports(struct controller_ctx *ctx,
> existing_ports);
> free(dst_name);
> free(src_name);
> +
> add_patched_datapath(patched_datapaths, binding);
> }
> }
> @@ -293,7 +309,8 @@ add_logical_patch_ports(struct controller_ctx *ctx,
>
> void
> patch_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
> - struct hmap *local_datapaths, struct hmap *patched_datapaths)
> + struct hmap *local_datapaths, struct hmap *patched_datapaths,
> + const struct sset *local_routers)
> {
> if (!ctx->ovs_idl_txn) {
> return;
> @@ -313,7 +330,8 @@ patch_run(struct controller_ctx *ctx, const struct
> ovsrec_bridge *br_int,
> * 'existing_ports' any patch ports that do exist in the database and
> * should be there. */
> add_bridge_mappings(ctx, br_int, &existing_ports, local_datapaths);
> - add_logical_patch_ports(ctx, br_int, &existing_ports,
> patched_datapaths);
> + add_logical_patch_ports(ctx, br_int, &existing_ports,
> patched_datapaths,
> + local_routers);
>
> /* Now 'existing_ports' only still contains patch ports that exist in
> the
> * database but shouldn't. Delete them from the database. */
> diff --git a/ovn/controller/patch.h b/ovn/controller/patch.h
> index d5d842e..fa253e5 100644
> --- a/ovn/controller/patch.h
> +++ b/ovn/controller/patch.h
> @@ -25,8 +25,10 @@
> struct controller_ctx;
> struct hmap;
> struct ovsrec_bridge;
> +struct sset;
>
> void patch_run(struct controller_ctx *, const struct ovsrec_bridge
> *br_int,
> - struct hmap *local_datapaths, struct hmap
> *patched_datapaths);
> + struct hmap *local_datapaths, struct hmap
> *patched_datapaths,
> + const struct sset *local_routers);
>
> #endif /* ovn/patch.h */
> diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
> index 9e03606..b271f7f 100644
> --- a/ovn/northd/ovn-northd.c
> +++ b/ovn/northd/ovn-northd.c
> @@ -460,8 +460,21 @@ build_datapaths(struct northd_context *ctx, struct
> hmap *datapaths)
> char uuid_s[UUID_LEN + 1];
> sprintf(uuid_s, UUID_FMT, UUID_ARGS(&od->key));
> const char *key = od->nbs ? "logical-switch" :
> "logical-router";
> - const struct smap id = SMAP_CONST1(&id, key, uuid_s);
> - sbrec_datapath_binding_set_external_ids(od->sb, &id);
> + struct smap ids = SMAP_INITIALIZER(&ids);
> + smap_add(&ids, key, uuid_s);
> +
> + if (od->nbr) {
> + const char *value = smap_get(&od->nbr->external_ids,
> + "local-router");
> +
> + if (value) {
> + smap_add(&ids, "local-router", value);
> + } else {
> + smap_add(&ids, "local-router", "");
> + }
> + }
> + sbrec_datapath_binding_set_external_ids(od->sb, &ids);
> + smap_destroy(&ids);
>
> sbrec_datapath_binding_set_tunnel_key(od->sb, tunnel_key);
> }
> diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml
> index 34251af..5b84d6c 100644
> --- a/ovn/ovn-nb.xml
> +++ b/ovn/ovn-nb.xml
> @@ -639,8 +639,10 @@
> </column>
>
> <group title="Common Columns">
> - <column name="external_ids">
> - See <em>External IDs</em> at the beginning of this document.
> + <column name="external_ids" key="local-router">
> + The CMS populates this optional key with the a local router name,
> which
> + <code>ovn-northd</code> writes into the southbound database
> + <code>datapath_binding</code> table.
> </column>
> </group>
> </table>
> diff --git a/ovn/ovn-sb.xml b/ovn/ovn-sb.xml
> index efd2f9a..aa0d8bd 100644
> --- a/ovn/ovn-sb.xml
> +++ b/ovn/ovn-sb.xml
> @@ -1189,6 +1189,14 @@ tcp.flags = RST;
> corresponding <ref table="Logical_Router" db="OVN_Northbound"/>
> row in
> the <ref db="OVN_Northbound"/> database.
> </column>
> +
> + <column name="external_ids" key="local-router">
> + <code>ovn-northd</code> populates this key with the a local
> router name,
> + which <code>ovn-northd</code> reads from the corresponding logical
> + router in the northbound database. The use of this external_id is
> + optional.
> + </column>
> +
> </group>
>
> <group title="Common Columns">
> diff --git a/tests/ovn.at b/tests/ovn.at
> index 173dc27..d613d62 100644
> --- a/tests/ovn.at
> +++ b/tests/ovn.at
> @@ -2748,3 +2748,196 @@ OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
> OVS_APP_EXIT_AND_WAIT([ovsdb-server])
>
> AT_CLEANUP
> +
> +AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, local router])
> +AT_KEYWORDS([ovnlocalrouter])
> +AT_SKIP_IF([test $HAVE_PYTHON = no])
> +ovn_start
> +
> +# Logical network:
> +# Two LRs - R1 and R2 that are connected to each other as peers in
> 20.0.0.0/24
> +# network. R1 has switch foo (192.168.1.0/24) connected to it.
> +# R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
> +
> +ovn-nbctl create Logical_Router name=R1
> +ovn-nbctl create Logical_Router name=R2 external-ids:local-router=llr2
> +
> +ovn-nbctl lswitch-add foo
> +ovn-nbctl lswitch-add alice
> +ovn-nbctl lswitch-add bob
> +
> +# Connect foo to R1
> +ovn-nbctl -- --id=@lrp create Logical_Router_port name=foo \
> +network=192.168.1.1/24 mac=\"00:00:00:01:02:03\" -- add Logical_Router
> R1 \
> +ports @lrp -- lport-add foo rp-foo
> +
> +ovn-nbctl set Logical_port rp-foo type=router options:router-port=foo \
> +addresses=\"00:00:00:01:02:03\"
> +
> +# Connect alice to R2
> +ovn-nbctl -- --id=@lrp create Logical_Router_port name=alice \
> +network=172.16.1.1/24 mac=\"00:00:00:01:02:04\" -- add Logical_Router R2
> \
> +ports @lrp -- lport-add alice rp-alice
> +
> +ovn-nbctl set Logical_port rp-alice type=router options:router-port=alice
> \
> +addresses=\"00:00:00:01:02:04\"
> +
> +# Connect bob to R1
> +ovn-nbctl -- --id=@lrp create Logical_Router_port name=bob-r1 \
> +network=172.16.2.3/24 mac=\"00:00:00:01:02:06\" -- add Logical_Router R1
> \
> +ports @lrp -- lport-add bob rp-bob-r1
> +
> +ovn-nbctl set Logical_port rp-bob-r1 type=router
> options:router-port=bob-r1 \
> +addresses=\"00:00:00:01:02:06\"
> +
> +# Connect bob to R2
> +ovn-nbctl -- --id=@lrp create Logical_Router_port name=bob \
> +network=172.16.2.1/24 mac=\"00:00:00:01:02:05\" -- add Logical_Router R2
> \
> +ports @lrp -- lport-add bob rp-bob
> +
> +ovn-nbctl set Logical_port rp-bob type=router options:router-port=bob \
> +addresses=\"00:00:00:01:02:05\"
> +
> +# Create logical port foo1 in foo
> +ovn-nbctl lport-add foo foo1 \
> +-- lport-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
> +
> +# Create logical port alice1 in alice
> +ovn-nbctl lport-add alice alice1 \
> +-- lport-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
> +
> +# Create logical port bob1 in bob
> +ovn-nbctl lport-add bob bob1 \
> +-- lport-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
> +
> +# Create two hypervisor and create OVS ports corresponding to logical
> ports.
> +net_add n1
> +
> +sim_add hv1
> +as hv1
> +ovs-vsctl add-br br-phys
> +ovn_attach n1 br-phys 192.168.0.1
> +ovs-vsctl -- add-port br-int hv1-vif1 -- \
> + set interface hv1-vif1 external-ids:iface-id=foo1 \
> + options:tx_pcap=hv1/vif1-tx.pcap \
> + options:rxq_pcap=hv1/vif1-rx.pcap \
> + ofport-request=1
> +
> +
> +sim_add hv2
> +as hv2
> +ovs-vsctl add-br br-phys
> +ovs-vsctl set open . external-ids:local-routers=llr2
> +ovn_attach n1 br-phys 192.168.0.2
> +ovs-vsctl -- add-port br-int hv2-vif1 -- \
> + set interface hv2-vif1 external-ids:iface-id=bob1 \
> + options:tx_pcap=hv2/vif1-tx.pcap \
> + options:rxq_pcap=hv2/vif1-rx.pcap \
> + ofport-request=1
> +
> +ovs-vsctl -- add-port br-int hv2-vif2 -- \
> + set interface hv2-vif2 external-ids:iface-id=alice1 \
> + options:tx_pcap=hv2/vif2-tx.pcap \
> + options:rxq_pcap=hv2/vif2-rx.pcap \
> + ofport-request=2
> +
> +
> +# Pre-populate the hypervisors' ARP tables so that we don't lose any
> +# packets for ARP resolution (native tunneling doesn't queue packets
> +# for ARP resolution).
> +ovn_populate_arp
> +
> +# Allow some time for ovn-northd and ovn-controller to catch up.
> +# XXX This should be more systematic.
> +sleep 1
> +
> +ip_to_hex() {
> + printf "%02x%02x%02x%02x" "$@"
> +}
> +trim_zeros() {
> + sed 's/\(00\)\{1,\}$//'
> +}
> +
> +# Send ip packets between foo1 and bob1
> +src_mac="f00000010203"
> +dst_mac="000000010203"
> +src_ip=`ip_to_hex 192 168 1 2`
> +dst_ip=`ip_to_hex 172 16 2 2`
>
> +packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
> +as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
> +
> +# Send ip packets between bob1 and alice1
> +src_mac="f00000010205"
> +dst_mac="000000010205"
> +src_ip=`ip_to_hex 172 16 2 2`
> +dst_ip=`ip_to_hex 172 16 1 2`
>
> +packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
> +as hv2 ovs-appctl netdev-dummy/receive hv2-vif1 $packet
> +
> +echo "---------NB dump-----"
> +ovn-nbctl show
> +echo "---------------------"
> +ovn-nbctl list logical_router
> +echo "---------------------"
> +ovn-nbctl list logical_router_port
> +echo "---------------------"
> +
> +echo "---------SB dump-----"
> +ovn-sbctl list datapath_binding
> +echo "---------------------"
> +ovn-sbctl list port_binding
> +echo "---------------------"
> +ovn-sbctl dump-flows
> +
> +echo "------ hv1 dump ----------"
> +as hv1 ovs-vsctl show
> +as hv1 ovs-ofctl show br-int
> +as hv1 ovs-ofctl dump-flows br-int
> +echo "------ hv2 dump ----------"
> +as hv2 ovs-vsctl show
> +as hv2 ovs-ofctl show br-int
> +as hv2 ovs-ofctl dump-flows br-int
> +
> +# Packet to Expect at bob1
> +src_mac="000000010206"
> +dst_mac="f00000010205"
> +src_ip=`ip_to_hex 192 168 1 2`
> +dst_ip=`ip_to_hex 172 16 2 2`
>
> +expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
> +
> +$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/vif1-tx.pcap |
> trim_zeros > received.packets
> +echo $expected | trim_zeros > expout
> +AT_CHECK([cat received.packets], [0], [expout])
> +
> +# Packet to Expect at alice1
> +src_mac="000000010204"
> +dst_mac="f00000010204"
> +src_ip=`ip_to_hex 172 16 2 2`
> +dst_ip=`ip_to_hex 172 16 1 2`
>
> +expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
> +
> +$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/vif2-tx.pcap |
> trim_zeros > received1.packets
> +echo $expected | trim_zeros > expout
> +AT_CHECK([cat received1.packets], [0], [expout])
> +
> +for sim in hv1 hv2; do
> + as $sim
> + OVS_APP_EXIT_AND_WAIT([ovn-controller])
> + OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
> + OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> +done
> +
> +as ovn-sb
> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> +
> +as ovn-nb
> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> +
> +as northd
> +OVS_APP_EXIT_AND_WAIT([ovn-northd])
> +
> +as main
> +OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> +
> +AT_CLEANUP
> --
> 1.9.1
>
>
More information about the dev
mailing list