superceded by v3 On Mon, May 9, 2016 at 8:53 PM, Darrell Ball <dlu...@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 <dlu...@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 > > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev