Skip to content

Commit

Permalink
dpctl: Add support for using UFID to add/del flows.
Browse files Browse the repository at this point in the history
Parse "ufid:<foo>" at the beginning of a flow specification and use it
for flow manipulation if present.

Signed-off-by: Joe Stringer <joestringer@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
  • Loading branch information
joestringer committed Dec 15, 2014
1 parent 348efd0 commit 534a19b
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 4 deletions.
41 changes: 37 additions & 4 deletions lib/dpctl.c
Expand Up @@ -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) {
Expand All @@ -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, -n, "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) {
Expand All @@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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, -n, "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));
Expand All @@ -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;
}

Expand Down
35 changes: 35 additions & 0 deletions lib/odp-util.c
Expand Up @@ -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 (ovs_scan(s, "ufid:")) {
size_t n;

s += 5;
if (ovs_scan(s, "0x")) {
s += 2;
}

n = strspn(s, "0123456789abcdefABCDEF");
if (n != 32) {
return -EINVAL;
}

if (!ovs_scan(s, "%"SCNx64, &ufid->u64.hi)) {
return -EINVAL;
}
s += 16;

if (!ovs_scan(s, "%"SCNx64, &ufid->u64.lo)) {
return -EINVAL;
}
s += 16;
s += strspn(s, delimiters);

return s - s_;
}

return 0;
}

void
odp_format_ufid(const ovs_u128 *ufid, struct ds *ds)
{
Expand Down
1 change: 1 addition & 0 deletions lib/odp-util.h
Expand Up @@ -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,
Expand Down

0 comments on commit 534a19b

Please sign in to comment.