From: Tonghao Zhang <[email protected]> openvswitch is reactive, and then flows will be installed when receiving packets. This patch add --consistent for dpctl commands to allow user installing flows which will not be deleted.
* This feature can be used with dpdk rte isolate offload mode. (e.g. receiving only tunnel packets.) * And users use it to debug openvswitch. Signed-off-by: Tonghao Zhang <[email protected]> --- lib/dpctl.c | 24 ++++++++++++++++++++++++ lib/dpctl.h | 3 +++ lib/odp-util.c | 11 +++++++++++ lib/odp-util.h | 1 + lib/uuid.h | 3 +++ ofproto/ofproto-dpif-upcall.c | 7 +++++++ 6 files changed, 49 insertions(+) diff --git a/lib/dpctl.c b/lib/dpctl.c index 33202813b..d907eddb4 100644 --- a/lib/dpctl.c +++ b/lib/dpctl.c @@ -1146,6 +1146,12 @@ dpctl_put_flow(int argc, const char *argv[], enum dpif_flow_put_flags flags, ufid_present = true; } + if (ufid_present && dpctl_p->consistent) { + dpctl_error(dpctl_p, -1, + "ufid and consistent are enabled at same time."); + return -1; + } + simap_init(&port_names); DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) { simap_put(&port_names, dpif_port.name, odp_to_u32(dpif_port.port_no)); @@ -1169,6 +1175,11 @@ dpctl_put_flow(int argc, const char *argv[], enum dpif_flow_put_flags flags, goto out_freeactions; } + if (dpctl_p->consistent) { + odp_flow_key_hash_local(key.data, key.size, &ufid); + ufid_present = true; + } + if (!ufid_present && dpctl_p->is_appctl) { /* Generating UFID for this flow so it could be offloaded to HW. We're * not doing that if invoked from ovs-dpctl utility because @@ -1326,6 +1337,17 @@ dpctl_del_flow(int argc, const char *argv[], struct dpctl_params *dpctl_p) goto out; } + if (ufid_present && dpctl_p->consistent) { + dpctl_error(dpctl_p, -1, + "ufid and consistent are enabled at same time."); + goto out; + } + + if (dpctl_p->consistent) { + odp_flow_key_hash_local(key.data, key.size, &ufid); + ufid_present = ufid_generated = true; + } + if (!ufid_present && dpctl_p->is_appctl) { /* While adding flow via appctl we're generating UFID to make HW * offloading possible. Generating UFID here to be sure that such @@ -2670,6 +2692,8 @@ dpctl_unixctl_handler(struct unixctl_conn *conn, int argc, const char *argv[], } else if (!strcmp(arg, "--no-names")) { dpctl_p.names = false; set_names = true; + } else if (!strcmp(arg, "--consistent")) { + dpctl_p.consistent = true; } else { ds_put_format(&ds, "Unrecognized option %s", argv[1]); error = true; diff --git a/lib/dpctl.h b/lib/dpctl.h index 9d0052152..b042663cc 100644 --- a/lib/dpctl.h +++ b/lib/dpctl.h @@ -42,6 +42,9 @@ struct dpctl_params { /* --names: Use port names in output? */ bool names; + /* --consistent: Install consistent flow. */ + bool consistent; + /* Callback for printing. This function is called from dpctl_run_command() * to output data. The 'aux' parameter is set to the 'aux' * member. The 'error' parameter is true if 'string' is an error diff --git a/lib/odp-util.c b/lib/odp-util.c index 252a91bfa..ddf30077c 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -6592,6 +6592,17 @@ odp_flow_key_hash(const void *key, size_t key_len, ovs_u128 *hash) } hash_bytes128(key, key_len, secret, hash); uuid_set_bits_v4((struct uuid *)hash); + + /* Clean up the first bit. */ + hash->u32[0] &= ~0x1; +} + +void +odp_flow_key_hash_local(const void *key, size_t key_len, ovs_u128 *hash) +{ + odp_flow_key_hash(key, key_len, hash); + /* If setting 1, it means flows are consistent. */ + hash->u32[0] |= 0x1; } static void diff --git a/lib/odp-util.h b/lib/odp-util.h index 623a66aa2..dc0ad2332 100644 --- a/lib/odp-util.h +++ b/lib/odp-util.h @@ -244,6 +244,7 @@ void odp_flow_key_from_flow(const struct odp_flow_key_parms *, struct ofpbuf *); void odp_flow_key_from_mask(const struct odp_flow_key_parms *, struct ofpbuf *); void odp_flow_key_hash(const void *key, size_t key_len, ovs_u128 *hash); +void odp_flow_key_hash_local(const void *key, size_t key_len, ovs_u128 *hash); /* Estimated space needed for metadata. */ enum { ODP_KEY_METADATA_SIZE = 9 * 8 }; diff --git a/lib/uuid.h b/lib/uuid.h index fa49354f6..1aab3231e 100644 --- a/lib/uuid.h +++ b/lib/uuid.h @@ -42,6 +42,9 @@ extern "C" { ((unsigned int) ((UUID)->parts[2] & 0xffff)), \ ((unsigned int) ((UUID)->parts[3])) +#define UUID_LOCAL(ufid) \ + (((ufid)->u32[0] & 0x1) == 0x1) + /* Returns a hash value for 'uuid'. This hash value is the same regardless of * whether we are running on a 32-bit or 64-bit or big-endian or little-endian * architecture. */ diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 19b92dfe0..c8ea16c18 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -2685,6 +2685,10 @@ revalidate(struct revalidator *revalidator) bool already_dumped; int error; + if (f->ufid_present && UUID_LOCAL(&(f)->ufid)) { + continue; + } + if (ukey_acquire(udpif, f, &ukey, &error)) { if (error == EBUSY) { /* Another thread is processing this flow, so don't bother @@ -2794,6 +2798,9 @@ revalidator_sweep__(struct revalidator *revalidator, bool purge) CMAP_FOR_EACH(ukey, cmap_node, &umap->cmap) { enum ukey_state ukey_state; + if (ukey->ufid_present && UUID_LOCAL(&(ukey)->ufid)) { + continue; + } /* Handler threads could be holding a ukey lock while it installs a * new flow, so don't hang around waiting for access to it. */ if (ovs_mutex_trylock(&ukey->mutex)) { -- 2.14.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
