mirror of
https://github.com/openvswitch/ovs
synced 2025-09-01 06:45:17 +00:00
dpctl: Add support for using UFID to add/del flows.
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>
This commit is contained in:
41
lib/dpctl.c
41
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, -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) {
|
||||
@@ -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, -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));
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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,
|
||||
|
Reference in New Issue
Block a user