[ovs-dev] [PATCHv3] dpctl: Add support for using UFID to add/del flows.
Joe Stringer
joestringer at nicira.com
Fri Dec 5 19:45:11 UTC 2014
Parse "ufid:<foo>" at the beginning of a flow specification and use it
for flow manipulation if present.
Signed-off-by: Joe Stringer <joestringer at nicira.com>
---
v3: Fix build on windows.
v2: Rebase.
---
lib/dpctl.c | 41 +++++++++++++++++++++++++++++++++++++----
lib/odp-util.c | 35 +++++++++++++++++++++++++++++++++++
lib/odp-util.h | 1 +
3 files changed, 73 insertions(+), 4 deletions(-)
diff --git a/lib/dpctl.c b/lib/dpctl.c
index 4e41fe4..7dc4714 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -819,9 +819,11 @@ dpctl_put_flow(int argc, const char *argv[], enum dpif_flow_put_flags flags,
struct ofpbuf key;
struct ofpbuf mask;
struct dpif *dpif;
+ ovs_u128 ufid;
+ bool ufid_present;
char *dp_name;
struct simap port_names;
- int error;
+ int n, error;
dp_name = argc == 4 ? xstrdup(argv[1]) : get_one_dp(dpctl_p);
if (!dp_name) {
@@ -834,6 +836,15 @@ dpctl_put_flow(int argc, const char *argv[], enum dpif_flow_put_flags flags,
return error;
}
+ ufid_present = false;
+ n = odp_ufid_from_string(key_s, &ufid);
+ if (n < 0) {
+ dpctl_error(dpctl_p, error, "parsing flow ufid");
+ return -n;
+ } else if (n) {
+ key_s += n;
+ ufid_present = true;
+ }
simap_init(&port_names);
DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) {
@@ -860,7 +871,8 @@ dpctl_put_flow(int argc, const char *argv[], enum dpif_flow_put_flags flags,
ofpbuf_size(&mask) == 0 ? NULL : ofpbuf_data(&mask),
ofpbuf_size(&mask),
ofpbuf_data(&actions), ofpbuf_size(&actions),
- NULL, dpctl_p->print_statistics ? &stats : NULL);
+ ufid_present ? &ufid : NULL,
+ dpctl_p->print_statistics ? &stats : NULL);
if (error) {
dpctl_error(dpctl_p, error, "updating flow table");
goto out_freeactions;
@@ -916,9 +928,11 @@ dpctl_del_flow(int argc, const char *argv[], struct dpctl_params *dpctl_p)
struct ofpbuf key;
struct ofpbuf mask; /* To be ignored. */
struct dpif *dpif;
+ ovs_u128 ufid;
+ bool ufid_present;
char *dp_name;
struct simap port_names;
- int error;
+ int n, error;
dp_name = argc == 3 ? xstrdup(argv[1]) : get_one_dp(dpctl_p);
if (!dp_name) {
@@ -931,6 +945,16 @@ dpctl_del_flow(int argc, const char *argv[], struct dpctl_params *dpctl_p)
return error;
}
+ ufid_present = false;
+ n = odp_ufid_from_string(key_s, &ufid);
+ if (n < 0) {
+ dpctl_error(dpctl_p, error, "parsing flow ufid");
+ return -n;
+ } else if (n) {
+ key_s += n;
+ ufid_present = true;
+ }
+
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));
@@ -946,10 +970,19 @@ dpctl_del_flow(int argc, const char *argv[], struct dpctl_params *dpctl_p)
}
error = dpif_flow_del(dpif,
- ofpbuf_data(&key), ofpbuf_size(&key), NULL,
+ ofpbuf_data(&key), ofpbuf_size(&key),
+ ufid_present ? &ufid : NULL,
dpctl_p->print_statistics ? &stats : NULL);
if (error) {
dpctl_error(dpctl_p, error, "deleting flow");
+ if (error == ENOENT && !ufid_present) {
+ struct ds s;
+
+ ds_init(&s);
+ ds_put_format(&s, "Perhaps you need to specify a UFID?");
+ dpctl_print(dpctl_p, "%s\n", ds_cstr(&s));
+ ds_destroy(&s);
+ }
goto out;
}
diff --git a/lib/odp-util.c b/lib/odp-util.c
index a89d5f8..54cdf1d 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -1999,6 +1999,41 @@ generate_all_wildcard_mask(struct ofpbuf *ofp, const struct nlattr *key)
return ofpbuf_base(ofp);
}
+int
+odp_ufid_from_string(const char *s_, ovs_u128 *ufid)
+{
+ const char *s = s_;
+
+ if (!strncmp(s, "ufid:", 5)) {
+ const char *upper;
+ size_t n;
+
+ s += 5;
+ n = strspn(s, "0123456789abcdefABCDEF");
+ if (!n || n > 32) {
+ return -EINVAL;
+ }
+
+ upper = s;
+ if (n > 16) {
+ char lower[17];
+
+ ovs_strlcpy(lower, s, n - 16 + 1);
+ ufid->u64.lo = strtoull(lower, NULL, 16);
+ upper += (n - 16);
+ } else {
+ ufid->u64.lo = 0;
+ }
+ ufid->u64.hi = strtoull(upper, NULL, 16);
+ s += n;
+ s += strspn(s, delimiters);
+
+ return s - s_;
+ }
+
+ return 0;
+}
+
void
odp_format_ufid(const ovs_u128 *ufid, struct ds *ds)
{
diff --git a/lib/odp-util.h b/lib/odp-util.h
index 27a5ca7..9c990cd 100644
--- a/lib/odp-util.h
+++ b/lib/odp-util.h
@@ -145,6 +145,7 @@ struct odputil_keybuf {
enum odp_key_fitness odp_tun_key_from_attr(const struct nlattr *,
struct flow_tnl *);
+int odp_ufid_from_string(const char *s_, ovs_u128 *ufid);
void odp_format_ufid(const ovs_u128 *ufid, struct ds *);
void odp_flow_format(const struct nlattr *key, size_t key_len,
const struct nlattr *mask, size_t mask_len,
--
1.7.10.4
More information about the dev
mailing list