On Tue, Mar 19, 2019 at 12:33 AM Ankur Sharma <[email protected]> wrote:
> Hi Numan, > > Thanks a lot for comment. > Sure, I am ok either ways, i.e whether we want to read > “ovn-chassis-mac-mappings” from OVSDB on each chassis or from OVN > northbound DB. > Just wanted to make sure that we follow only ONE approach. > > From OVN as a platform perspective, ovn-chassis-mac-mappings looks similar > to ovn-encap-ip, ovn-bridge-mappings etc. > However, we can deviate from that if it simplifies adoption by CMS and > community is inclined towards it as well. > > I would say it would be good to get feedback from others on this before deciding the approach you take. Since I am suggesting to add the mac and chassis name information in OVN Northbound db, others may have some reservations. Presently we do add chassis related information in the 'Gateway_Chassis' table in Northbound db. Thanks Numan > > Thanks again for the feedback. > > Regards, > Ankur > > > > *From:* Numan Siddique <[email protected]> > *Sent:* Friday, March 15, 2019 11:27 PM > *To:* Ankur Sharma <[email protected]> > *Cc:* [email protected] > *Subject:* Re: [ovs-dev] [RFC PATCH v1 3/6] L3 E-W Support in ovn, > replace router port mac with chassis mac. > > > > > > > > On Wed, Mar 6, 2019 at 3:15 AM Ankur Sharma <[email protected]> > wrote: > > Hi Numan, > > Thank you so much for review and initial comments. > Please find my response inline. > > Please go through the explanations and we can discuss further from there. > > > Thanks again for review. > > Regards, > Ankur > > *From:* Numan Siddique <[email protected]> > *Sent:* Wednesday, February 27, 2019 6:00 AM > *To:* Ankur Sharma <[email protected]> > *Cc:* [email protected] > *Subject:* Re: [ovs-dev] [RFC PATCH v1 3/6] L3 E-W Support in ovn, > replace router port mac with chassis mac. > > > > > > > > On Thu, Feb 21, 2019 at 4:10 AM Ankur Sharma <[email protected]> > wrote: > > Background: > [1] https://mail.openvswitch.org/pipermail/ovs-dev/2018-October/353066.html > [mail.openvswitch.org] > <https://urldefense.proofpoint.com/v2/url?u=https-3A__mail.openvswitch.org_pipermail_ovs-2Ddev_2018-2DOctober_353066.html&d=DwMFaQ&c=s883GpUCOChKOHiocYtGcg&r=mZwX9gFQgeJHzTg-68aCJgsODyUEVsHGFOfL90J6MJY&m=loh6pMwgaWsIa-IhZIQPE1Ar3vWj_gufFqEu-KCDtrY&s=H_XhzdGFWY5TNEkoXHLE2FTd67qwGcdvtMLNysKD2ng&e=> > [2] > https://docs.google.com/document/d/1uoQH478wM1OZ16HrxzbOUvk5LvFnfNEWbkPT6Zmm9OU/edit?usp=sharing > [docs.google.com] > <https://urldefense.proofpoint.com/v2/url?u=https-3A__docs.google.com_document_d_1uoQH478wM1OZ16HrxzbOUvk5LvFnfNEWbkPT6Zmm9OU_edit-3Fusp-3Dsharing&d=DwMFaQ&c=s883GpUCOChKOHiocYtGcg&r=mZwX9gFQgeJHzTg-68aCJgsODyUEVsHGFOfL90J6MJY&m=loh6pMwgaWsIa-IhZIQPE1Ar3vWj_gufFqEu-KCDtrY&s=HjTglktnxsL-Hi1RzVFn7AOWganM1qYaEgX5I320Euk&e=> > > This Series: > Layer 2, Layer 3 E-W and Layer 3 N-S (NO NAT) changes for vlan > backed distributed logical router. > > This Patch: > a. Introduce per physical network chassic mac bindings in ovs. > For example: > > ovn-chassis-mac-mappings="physnet1:aa:bb:cc:dd:ee:ff,physnet2:a1:b2:c3:d4:e5:f6" > > > > I had a quick look on this patch. I have few concerns. > > > > - The approach taken here adding > "ovn-chassis-mac-mappings="physnet1:aa:bb:cc:dd:ee:ff,physnet2:a1:b2:c3:d4:e5:f6"" > in the > > ovs db of each chassis could be problematic. This requires that CMS > execute this command when ever a logical switch of type vlan is created. > > In the case of OpenStack, a user can create a provider network of type > vlan any time and delete it any time. It would require > > for the customer/CMS to set this value on all chassis. This would not > be feasible. > > > [ANKUR]: Sorry, may be the documentation or patch did not clarify it > properly. > Chassis mac is not tied with logical entities, i.e Logical switch of type > vlan creation will not need an additional step of chassis mac > configuration. Chassis mac is a one time configuration (per chassis) and > should be seen as equivalent to “ovn-encap-ip”. > Consumption of chassis-mac is backward compatible, i.e existing deployment > need not program it and there deployments will continue to use router port > mac , when packet goes on wire. > > > > - In the present approach, the flows to set the mac address of the > chassis is added in table 65. Probably that's not the right place. > > And these flows will not be transparent and we cant map it to any > logical flows or to any of the OVN DB contents. > > Utilities like ovn-trace cannot really trace the packet since the > mac-mappings are not visible to it. > > [ANKUR]: The reason for doing it in table=65 are following: > a. Replacing router port mac with a chassis mac is done ONLY before > sending the packet on wire. > b. For above reason, logical pipeline need not see this mac at all, > logical pipelines should operation on router port mac only. > > c. We should see this operation (replacing router port mac with chassis > mac) as equivalent to overlay encapsulation or vlan tagging by localnet > ports. > > d. i.e Encapsulation is done in table=32 (just before sending the packet > on wire during ingress pipeline) or tagging the packet with vlan (for > localnet ports) is done in table=65 (just before sending the packet on wire > in egress pipeline). > e. You have raised a very good point about ovn-trace. How do we represent > overlay encapsulation or vlan tagging by localnet port in ovn-trace output. > If we do, then its my bad, I should have had changes for ovn-trace as well. > > > > Sorry for the late reply. Thanks for the detailed explanation. > > I get your point now. > > I still feel it would be better if it can be expressed from Northbound DB. > If we take deployment tools like Tripleo for openstack, it needs > > to set the "ovn-chassis-mac-mappings" for each chassis during deployment > (and it needs to generate the macs). CMS like networking-ovn > > (Openstack neutron plugin) can easily generate the MACs and set it when > ever a logical switch with localnet port is created. > > If you see, when a localnet port is created we need to define the > "physical network name". In the above example, it would be "phsynet1 and > physnet2". > > > > It would be good to get other's opinion on this. > > > > Thanks > > Numan > > > > > > > > > > I think we can express the mac-mappings in the OVN Northbound DB. My > suggestion would be to do the following > > - Add a new column 'mac-mappings' (or a better appropriate name) in > Logical_Switch_Port of type map. > > > > - This column should be set by CMS for logical port of type 'localnet'. > The key of this map would be "chassis name" and the value would be mac > address to use. > > Eg. "chassis1": "aa:bb:cc:dd:ee:01" > > "chassis2": "aa:bb:cc:dd:ee:02" > > > > - With the above column probably we don't need patch 1/2 of this series. > Each localnet port will have a differenet "network_name". > > OVN doesn't need to know if the network type is vlan or geneve for a > logical switch. If a logical switch has a localnet port, it means > > it corresponds to a physical network. > > > > - CMS can easily set these values. It can read the Southbound DB to know > the chasiss names. > > > > - ovn-northd can read this and add appropriate logical flows to set the > chassis specific mac addresses. It could be similar to "get_arp()" OVN > action in which case > > ovn-controller can add flows in table 67 (or appropriate) which will set > eth.dst. > > > > Or > > we can add a new action "is_chassis(chassis1)" which will be true only > on that chassis. > > And we can have logical flows in the logical switch pipeline something > like > > > > match=... && is_chassis(chassis1), action = (eth.dst = > aa:bb:cc:dd:ee:01; ...) > > match=... && is_chassis(chassis2), action = (eth.dst = > aa:bb:cc:dd:ee:02; ...) > > > [ANKUR]: > We can discuss further on this. Please go through my replies (looks like > some concepts were not well documented by me and hence the confusion) and > we can take it forward from there. > > > > Any Thoughts or comments ? > > > > Thanks > > Numan > > > > > > > > > > b. Replace router port mac with a chassis specific mac, > read from a. above. > For example: > cookie=0x0, duration=67765.830s, table=65, n_packets=0, n_bytes=0, > idle_age=65534, hard_age=65534, priority=150,reg15=0x1,metadata=0x4, > dl_src=00:00:01:01:02:03 actions=mod_dl_src:aa:bb:cc:dd:ee:ff, > mod_vlan_vid:1000,output:16 > > Signed-off-by: Ankur Sharma <[email protected]> > --- > ovn/controller/bfd.c | 5 +- > ovn/controller/binding.c | 12 +-- > ovn/controller/chassis.c | 66 +++++++++++- > ovn/controller/chassis.h | 4 + > ovn/controller/ovn-controller.8.xml | 7 ++ > ovn/controller/ovn-controller.c | 2 +- > ovn/controller/ovn-controller.h | 5 +- > ovn/controller/physical.c | 96 +++++++++++++++++ > ovn/ovn-sb.xml | 8 ++ > tests/ovn.at [ovn.at] > <https://urldefense.proofpoint.com/v2/url?u=http-3A__ovn.at&d=DwMFaQ&c=s883GpUCOChKOHiocYtGcg&r=mZwX9gFQgeJHzTg-68aCJgsODyUEVsHGFOfL90J6MJY&m=loh6pMwgaWsIa-IhZIQPE1Ar3vWj_gufFqEu-KCDtrY&s=UMr17hvb7f_HksiQoi98N7CVc2uV8cVEf4UxuZz5mAA&e=> > | 199 +++++++++++++++++++++++++++++++++++- > 10 files changed, 390 insertions(+), 14 deletions(-) > > diff --git a/ovn/controller/bfd.c b/ovn/controller/bfd.c > index 94dad23..1ee48a5 100644 > --- a/ovn/controller/bfd.c > +++ b/ovn/controller/bfd.c > @@ -121,8 +121,9 @@ bfd_travel_gw_related_chassis( > LIST_FOR_EACH_POP (dp_binding, node, &dp_list) { > dp = dp_binding->dp; > free(dp_binding); > - for (size_t i = 0; i < dp->n_peer_dps; i++) { > - const struct sbrec_datapath_binding *pdp = dp->peer_dps[i]; > + for (size_t i = 0; i < dp->n_peer_ports; i++) { > + const struct sbrec_datapath_binding *pdp = > + dp->peer_ports[i]->datapath; > if (!pdp) { > continue; > } > diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c > index 021ecdd..53ee032 100644 > --- a/ovn/controller/binding.c > +++ b/ovn/controller/binding.c > @@ -159,13 +159,11 @@ add_local_datapath__(struct ovsdb_idl_index > *sbrec_datapath_binding_by_key, > sbrec_port_binding_by_name, > peer->datapath, false, > depth + 1, local_datapaths); > - ld->n_peer_dps++; > - ld->peer_dps = xrealloc( > - ld->peer_dps, > - ld->n_peer_dps * sizeof *ld->peer_dps); > - ld->peer_dps[ld->n_peer_dps - 1] = > datapath_lookup_by_key( > - sbrec_datapath_binding_by_key, > - peer->datapath->tunnel_key); > + ld->n_peer_ports++; > + ld->peer_ports = xrealloc(ld->peer_ports, > + ld->n_peer_ports * > + sizeof *ld->peer_ports); > + ld->peer_ports[ld->n_peer_ports - 1] = peer; > } > } > } > diff --git a/ovn/controller/chassis.c b/ovn/controller/chassis.c > index 797c16c..88e3630 100644 > --- a/ovn/controller/chassis.c > +++ b/ovn/controller/chassis.c > @@ -22,6 +22,7 @@ > #include "lib/vswitch-idl.h" > #include "openvswitch/dynamic-string.h" > #include "openvswitch/vlog.h" > +#include "openvswitch/ofp-parse.h" > #include "ovn/lib/chassis-index.h" > #include "ovn/lib/ovn-sb-idl.h" > #include "ovn-controller.h" > @@ -68,6 +69,12 @@ get_bridge_mappings(const struct smap *ext_ids) > } > > static const char * > +get_chassis_mac_mappings(const struct smap *ext_ids) > +{ > + return smap_get_def(ext_ids, "ovn-chassis-mac-mappings", ""); > +} > + > +static const char * > get_cms_options(const struct smap *ext_ids) > { > return smap_get_def(ext_ids, "ovn-cms-options", ""); > @@ -130,6 +137,7 @@ chassis_run(struct ovsdb_idl_txn *ovnsb_idl_txn, > const char *datapath_type = > br_int && br_int->datapath_type ? br_int->datapath_type : ""; > const char *cms_options = get_cms_options(&cfg->external_ids); > + const char *chassis_macs = > get_chassis_mac_mappings(&cfg->external_ids); > > struct ds iface_types = DS_EMPTY_INITIALIZER; > ds_put_cstr(&iface_types, ""); > @@ -157,18 +165,22 @@ chassis_run(struct ovsdb_idl_txn *ovnsb_idl_txn, > = smap_get_def(&chassis_rec->external_ids, "iface-types", ""); > const char *chassis_cms_options > = get_cms_options(&chassis_rec->external_ids); > + const char *chassis_mac_mappings > + = get_chassis_mac_mappings(&chassis_rec->external_ids); > > /* If any of the external-ids should change, update them. */ > if (strcmp(bridge_mappings, chassis_bridge_mappings) || > strcmp(datapath_type, chassis_datapath_type) || > strcmp(iface_types_str, chassis_iface_types) || > - strcmp(cms_options, chassis_cms_options)) { > + strcmp(cms_options, chassis_cms_options) || > + strcmp(chassis_macs, chassis_mac_mappings)) { > struct smap new_ids; > smap_clone(&new_ids, &chassis_rec->external_ids); > smap_replace(&new_ids, "ovn-bridge-mappings", > bridge_mappings); > smap_replace(&new_ids, "datapath-type", datapath_type); > smap_replace(&new_ids, "iface-types", iface_types_str); > smap_replace(&new_ids, "ovn-cms-options", cms_options); > + smap_replace(&new_ids, "ovn-chassis-mac-mappings", > chassis_macs); > sbrec_chassis_verify_external_ids(chassis_rec); > sbrec_chassis_set_external_ids(chassis_rec, &new_ids); > smap_destroy(&new_ids); > @@ -246,6 +258,58 @@ chassis_run(struct ovsdb_idl_txn *ovnsb_idl_txn, > return chassis_rec; > } > > +bool > +chassis_get_mac(const struct sbrec_chassis *chassis_rec, > + const char *bridge_mapping, > + struct eth_addr *chassis_mac) > +{ > + const char *tokens > + = get_chassis_mac_mappings(&chassis_rec->external_ids); > + char *save_ptr = NULL; > + char *token; > + bool ret = false; > + > + if (!strlen(tokens)) { > + return false; > + } > + > + char *tokstr = xstrdup(tokens); > + > + /* Format for a chassis mac configuration is: > + * ovn-chassis-mac-mappings="bridge-name1:MAC1,bridge-name2:MAC2" > + */ > + for (token = strtok_r(tokstr, ",", &save_ptr); > + token != NULL; > + token = strtok_r(NULL, ",", &save_ptr)) { > + char *save_ptr2 = NULL; > + char *chassis_mac_bridge = strtok_r(token, ":", &save_ptr2); > + char *chassis_mac_str = strtok_r(NULL, "", &save_ptr2); > + > + if (!strcmp(chassis_mac_bridge, bridge_mapping)) { > + struct eth_addr temp_mac; > + char *err_str = NULL; > + > + ret = true; > + > + // Return the first chassis mac. > + if ((err_str = str_to_mac(chassis_mac_str, &temp_mac))) { > + free(err_str); > + ret = false; > + continue; > + } > + > + memcpy(chassis_mac, &temp_mac, sizeof(struct eth_addr)); > + > + goto done; > + } > + } > + > +done: > + free(tokstr); > + > + return ret; > +} > + > /* Returns true if the database is all cleaned up, false if more work is > * required. */ > bool > diff --git a/ovn/controller/chassis.h b/ovn/controller/chassis.h > index 6b1c357..b61e87f 100644 > --- a/ovn/controller/chassis.h > +++ b/ovn/controller/chassis.h > @@ -17,6 +17,7 @@ > #define OVN_CHASSIS_H 1 > > #include <stdbool.h> > +#include "openvswitch/types.h" > > struct ovsdb_idl; > struct ovsdb_idl_index; > @@ -32,6 +33,9 @@ const struct sbrec_chassis *chassis_run( > struct ovsdb_idl_index *sbrec_chassis_by_name, > const struct ovsrec_open_vswitch_table *, > const char *chassis_id, const struct ovsrec_bridge *br_int); > +bool chassis_get_mac(const struct sbrec_chassis *chassis, > + const char *bridge_mapping, > + struct eth_addr *chassis_mac); > bool chassis_cleanup(struct ovsdb_idl_txn *ovnsb_idl_txn, > const struct sbrec_chassis *); > > diff --git a/ovn/controller/ovn-controller.8.xml > b/ovn/controller/ovn-controller.8.xml > index 8035638..3baa6c9 100644 > --- a/ovn/controller/ovn-controller.8.xml > +++ b/ovn/controller/ovn-controller.8.xml > @@ -159,6 +159,13 @@ > specific to this particular chassis. An example would be: > <code>cms_option1,cms_option2:foo</code>. > </dd> > + <dt><code>external_ids:ovn-chassis-mac-mappings</code></dt> > + <dd> > + A list of key-value pairs that map a chassis specific mac to > + a physical network name. An example > + value mapping two chassis macs to two physical network names > would be: > + > <code>physnet1:aa:bb:cc:dd:ee:ff,physnet2:a1:b2:c3:d4:e5:f6</code>. > + </dd> > </dl> > > <p> > diff --git a/ovn/controller/ovn-controller.c > b/ovn/controller/ovn-controller.c > index 2098f28..e8d002e 100644 > --- a/ovn/controller/ovn-controller.c > +++ b/ovn/controller/ovn-controller.c > @@ -840,7 +840,7 @@ main(int argc, char *argv[]) > struct local_datapath *cur_node, *next_node; > HMAP_FOR_EACH_SAFE (cur_node, next_node, hmap_node, > &local_datapaths) { > - free(cur_node->peer_dps); > + free(cur_node->peer_ports); > hmap_remove(&local_datapaths, &cur_node->hmap_node); > free(cur_node); > } > diff --git a/ovn/controller/ovn-controller.h > b/ovn/controller/ovn-controller.h > index b13b371..9f02162 100644 > --- a/ovn/controller/ovn-controller.h > +++ b/ovn/controller/ovn-controller.h > @@ -59,8 +59,9 @@ struct local_datapath { > /* True if this datapath contains an l3gateway port located on this > * hypervisor. */ > bool has_local_l3gateway; > - const struct sbrec_datapath_binding **peer_dps; > - size_t n_peer_dps; > + > + const struct sbrec_port_binding **peer_ports; > + size_t n_peer_ports; > }; > > struct local_datapath *get_local_datapath(const struct hmap *, > diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c > index ab3b02a..fad68e4 100644 > --- a/ovn/controller/physical.c > +++ b/ovn/controller/physical.c > @@ -20,6 +20,7 @@ > #include "gchassis.h" > #include "lflow.h" > #include "lport.h" > +#include "chassis.h" > #include "lib/bundle.h" > #include "openvswitch/poll-loop.h" > #include "lib/uuid.h" > @@ -30,6 +31,7 @@ > #include "openvswitch/ofp-actions.h" > #include "openvswitch/ofpbuf.h" > #include "openvswitch/vlog.h" > +#include "openvswitch/ofp-parse.h" > #include "ovn-controller.h" > #include "ovn/lib/chassis-index.h" > #include "ovn/lib/ovn-sb-idl.h" > @@ -188,6 +190,94 @@ get_zone_ids(const struct sbrec_port_binding *binding, > } > > static void > +put_replace_router_port_mac_flows(const struct sbrec_port_binding > *localnet_port, > + const struct sbrec_chassis *chassis, > + const struct hmap *local_datapaths, > + struct ofpbuf *ofpacts_p, > + ofp_port_t ofport, > + struct hmap *flow_table) > +{ > + struct local_datapath *ld = get_local_datapath(local_datapaths, > + > localnet_port->datapath-> > + tunnel_key); > + uint32_t dp_key = localnet_port->datapath->tunnel_key; > + uint32_t port_key = localnet_port->tunnel_key; > + int tag = *localnet_port->tag; > + const char *network = smap_get(&localnet_port->options, > "network_name"); > + struct eth_addr chassis_mac; > + > + ovs_assert(ld); > + > + if (!network) { > + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); > + VLOG_WARN_RL(&rl, "Physical network not configured for datapath: > %ld " > + "with localnet port", > + localnet_port->datapath->tunnel_key); > + return; > + } > + > + // Get chassis mac > + if (chassis_get_mac(chassis, network, &chassis_mac) == false) { > + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); > + /* Keeping the log level low for backward compatibility. > + * Chassis mac is a new configuration. > + */ > + VLOG_DBG_RL(&rl, "Could not get chassis mac for network: %s", > network); > + return; > + } > + > + for (int i = 0; i < ld->n_peer_ports; i++) { > + const struct sbrec_port_binding *rport_binding = > ld->peer_ports[i]; > + struct eth_addr router_port_mac; > + char *err_str = NULL; > + struct match match; > + struct ofpact_mac *replace_mac; > + > + /* Table 65, priority 150. > + * ======================= > + * > + * Implements output to localnet port. > + * a. Flow replaces ingress router port mac with a chassis mac. > + * b. Flow appends the vlan id localnet port is configured with. > + */ > + match_init_catchall(&match); > + ofpbuf_clear(ofpacts_p); > + > + ovs_assert(rport_binding->n_mac == 1); > + if ((err_str = str_to_mac(rport_binding->mac[0], > &router_port_mac))) { > + // Parsing of mac failed. > + VLOG_WARN("Parsing or router port mac failed for router port: > %s, " > + "with error: %s", rport_binding->logical_port, > err_str); > + free(err_str); > + return; > + } > + > + // Replace Mac flow > + > + replace_mac = ofpact_put_SET_ETH_SRC(ofpacts_p); > + replace_mac->mac = chassis_mac; > + > + match_set_metadata(&match, htonll(dp_key)); > + match_set_reg(&match, MFF_LOG_OUTPORT - MFF_REG0, port_key); > + match_set_dl_src(&match, router_port_mac); > + > + if (tag) { > + struct ofpact_vlan_vid *vlan_vid; > + vlan_vid = ofpact_put_SET_VLAN_VID(ofpacts_p); > + vlan_vid->vlan_vid = tag; > + vlan_vid->push_vlan_if_needed = true; > + } > + > + ofpact_put_OUTPUT(ofpacts_p)->port = ofport; > + > + ofctrl_add_flow(flow_table, OFTABLE_LOG_TO_PHY, 150, 0, > + &match, ofpacts_p); > + } > + > + return; > +} > + > +static void > put_local_common_flows(uint32_t dp_key, uint32_t port_key, > uint32_t parent_port_key, > const struct zone_ids *zone_ids, > @@ -656,6 +746,12 @@ consider_port_binding(struct ovsdb_idl_index > *sbrec_chassis_by_name, > } > ofctrl_add_flow(flow_table, OFTABLE_LOG_TO_PHY, 100, 0, > &match, ofpacts_p); > + > + if (!strcmp(binding->type, "localnet")) { > + put_replace_router_port_mac_flows(binding, chassis, > local_datapaths, > + ofpacts_p, ofport, > flow_table); > + } > + > } else if (!tun && !is_ha_remote) { > /* Remote port connected by localnet port */ > /* Table 33, priority 100. > diff --git a/ovn/ovn-sb.xml b/ovn/ovn-sb.xml > index 01ef892..059f1a2 100644 > --- a/ovn/ovn-sb.xml > +++ b/ovn/ovn-sb.xml > @@ -293,6 +293,14 @@ > See <code>ovn-controller</code>(8) for more information. > </column> > > + <column name="external_ids" key="ovn-chassis-mac-mappings"> > + <code>ovn-controller</code> populates this key with the set of > options > + configured in the <ref table="Open_vSwitch" > + column="external_ids:ovn-chassis-mac-mappings"/> column of the > Open_vSwitch > + database's <ref table="Open_vSwitch" db="Open_vSwitch"/> table. > + See <code>ovn-controller</code>(8) for more information. > + </column> > + > <group title="Common Columns"> > The overall purpose of these columns is described under <code>Common > Columns</code> at the beginning of this document. > diff --git a/tests/ovn.at [ovn.at] > <https://urldefense.proofpoint.com/v2/url?u=http-3A__ovn.at&d=DwMFaQ&c=s883GpUCOChKOHiocYtGcg&r=mZwX9gFQgeJHzTg-68aCJgsODyUEVsHGFOfL90J6MJY&m=loh6pMwgaWsIa-IhZIQPE1Ar3vWj_gufFqEu-KCDtrY&s=UMr17hvb7f_HksiQoi98N7CVc2uV8cVEf4UxuZz5mAA&e=> > b/tests/ovn.at [ovn.at] > <https://urldefense.proofpoint.com/v2/url?u=http-3A__ovn.at&d=DwMFaQ&c=s883GpUCOChKOHiocYtGcg&r=mZwX9gFQgeJHzTg-68aCJgsODyUEVsHGFOfL90J6MJY&m=loh6pMwgaWsIa-IhZIQPE1Ar3vWj_gufFqEu-KCDtrY&s=UMr17hvb7f_HksiQoi98N7CVc2uV8cVEf4UxuZz5mAA&e=> > index cfdbf41..138e58b 100644 > --- a/tests/ovn.at [ovn.at] > <https://urldefense.proofpoint.com/v2/url?u=http-3A__ovn.at&d=DwMFaQ&c=s883GpUCOChKOHiocYtGcg&r=mZwX9gFQgeJHzTg-68aCJgsODyUEVsHGFOfL90J6MJY&m=loh6pMwgaWsIa-IhZIQPE1Ar3vWj_gufFqEu-KCDtrY&s=UMr17hvb7f_HksiQoi98N7CVc2uV8cVEf4UxuZz5mAA&e=> > +++ b/tests/ovn.at [ovn.at] > <https://urldefense.proofpoint.com/v2/url?u=http-3A__ovn.at&d=DwMFaQ&c=s883GpUCOChKOHiocYtGcg&r=mZwX9gFQgeJHzTg-68aCJgsODyUEVsHGFOfL90J6MJY&m=loh6pMwgaWsIa-IhZIQPE1Ar3vWj_gufFqEu-KCDtrY&s=UMr17hvb7f_HksiQoi98N7CVc2uV8cVEf4UxuZz5mAA&e=> > @@ -2911,7 +2911,7 @@ test_ip() { > local > packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000 > shift; shift; shift; shift; shift > hv=hv`vif_to_hv $inport` > - as $hv ovs-appctl netdev-dummy/receive vif$inport $packet > + as $hv ovs-appctl netdev-dummy/receive $inport $packet > in_ls=`vif_to_ls $inport` > in_lrp=`vif_to_lrp $inport` > for outport; do > @@ -12088,3 +12088,200 @@ ovn-nbctl list logical_switch_port > ovn-nbctl list logical_router_port > > AT_CLEANUP > + > +AT_SETUP([ovn -- 2 HVs, 2 lports/HV, localnet ports, DVR chassis mac]) > +ovn_start > + > + > +# In this test cases we create 2 switches, all connected to same > +# physical network (through br-phys on each HV). Each switch has > +# 1 VIF. 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. > +# > +# 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 > +# > +# 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 vlan > + 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_ls () { > + case $1 in dnl ( > + vif?[[11]]) echo ls1 ;; dnl ( > + vif?[[12]]) echo ls2 ;; dnl ( > + *) AT_FAIL_IF([:]) ;; > + esac > +} > + > +hv_to_num () { > + case $1 in dnl ( > + hv1) echo 1 ;; dnl ( > + hv2) echo 2 ;; dnl ( > + *) AT_FAIL_IF([:]) ;; > + esac > +} > + > +vif_to_num () { > + case $1 in dnl ( > + vif22) echo 22 ;; dnl ( > + vif21) echo 21 ;; dnl ( > + *) AT_FAIL_IF([:]) ;; > + esac > +} > + > +vif_to_hv () { > + case $1 in dnl ( > + vif[[1]]?) echo hv1 ;; dnl ( > + vif[[2]]?) echo hv2 ;; dnl ( > + *) AT_FAIL_IF([:]) ;; > + esac > +} > + > +vif_to_lrp () { > + echo router-to-`vif_to_ls $1` > +} > + > +hv_to_chassis_mac () { > + case $1 in dnl ( > + hv[[1]]) echo aa:bb:cc:dd:ee:11 ;; dnl ( > + hv[[2]]) echo aa:bb:cc:dd:ee:22 ;; 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 lr-add router > +ovn-nbctl lrp-add router router-to-ls1 00:00:01:01:02:03 192.168.1.3/24 > +ovn-nbctl [192.168.1.3] > <https://urldefense.proofpoint.com/v2/url?u=http-3A__192.168.1.3_24-2Bovn-2Dnbctl&d=DwMFaQ&c=s883GpUCOChKOHiocYtGcg&r=mZwX9gFQgeJHzTg-68aCJgsODyUEVsHGFOfL90J6MJY&m=loh6pMwgaWsIa-IhZIQPE1Ar3vWj_gufFqEu-KCDtrY&s=J6zHmqz8BNYqbuWqlQDuktQcKOMCkEeOeMe9frPw3l4&e=> > lrp-add router router-to-ls2 00:00:01:01:02:05 192.168.2.3/24 > [192.168.2.3] > <https://urldefense.proofpoint.com/v2/url?u=http-3A__192.168.2.3_24&d=DwMFaQ&c=s883GpUCOChKOHiocYtGcg&r=mZwX9gFQgeJHzTg-68aCJgsODyUEVsHGFOfL90J6MJY&m=loh6pMwgaWsIa-IhZIQPE1Ar3vWj_gufFqEu-KCDtrY&s=-2eThN-BA2d0Th6gEAU487Y-Zs_4JvegAFK95EpZ-MM&e=> > + > +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 --wait=sb sync > +#ovn-sbctl dump-flows > + > +ovn-nbctl show > +ovn-sbctl show > + > +OVN_POPULATE_ARP > + > +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 > + local > packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000 > + shift; shift; shift; shift; shift > + hv=`vif_to_hv $inport` > + hv_num=`hv_to_num $hv` > + chassis_mac=`hv_to_chassis_mac $hv` > + as $hv ovs-appctl netdev-dummy/receive $inport $packet > + #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet > + in_ls=`vif_to_ls $inport` > + in_lrp=`vif_to_lrp $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). > + outport_num=`vif_to_num $outport` > + out_lrp=`vif_to_lrp $outport` > + echo > f000000000${outport_num}aabbccddee${hv_num}${hv_num}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000 > + fi >> $outport.expected > + done > +} > + > +# Dump a bunch of info helpful for debugging if there's a failure. > + > +echo "------ OVN dump ------" > +ovn-nbctl show > +ovn-sbctl show > + > +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 "Send traffic" > +sip=`ip_to_hex 192 168 1 1` > +dip=`ip_to_hex 192 168 2 2` > +test_ip vif11 f00000000011 000001010203 $sip $dip vif22 > + > +sleep 1 > + > +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 > + > +OVN_CHECK_PACKETS([hv2/vif22-tx.pcap], [vif22.expected]) > + > +OVN_CLEANUP([hv1],[hv2]) > + > +AT_CLEANUP > -- > 1.8.3.1 > > _______________________________________________ > dev mailing list > [email protected] > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > [mail.openvswitch.org] > <https://urldefense.proofpoint.com/v2/url?u=https-3A__mail.openvswitch.org_mailman_listinfo_ovs-2Ddev&d=DwMFaQ&c=s883GpUCOChKOHiocYtGcg&r=mZwX9gFQgeJHzTg-68aCJgsODyUEVsHGFOfL90J6MJY&m=loh6pMwgaWsIa-IhZIQPE1Ar3vWj_gufFqEu-KCDtrY&s=hVfkPQDzo6FwvQ11oDcQN9YyY_A_gIcTi9uGsqq3Stg&e=> > > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
