diff options
author | Gurucharan Shetty <gshetty@nicira.com> | 2013-09-23 22:58:46 -0700 |
---|---|---|
committer | Gurucharan Shetty <gshetty@nicira.com> | 2013-10-01 18:09:38 -0700 |
commit | 0a37839c03307cc4cc726d27a7348c05d469c5eb (patch) | |
tree | 6bf284bda19f723cc29f152af5e95a247d0cde3c /lib | |
parent | 363591508db8f17045c9159522ad9511e63cba2e (diff) |
ovs-dpctl, ofproto/trace: Show and handle the in_port name in flows.
With this commit, whenever the verbosity is enabled with '-m'
option, the ovs-dpctl dump-flows command will display the flows with
in_port field showing the name instead of a port number.
Conversely, one can also use a name in the in_port field with del-flow,
add-flow and mod-flow commands of ovs-dpctl. One should also be able
to use the port name when supplying the datapath flow as an input
to ofproto/trace command.
Signed-off-by: Gurucharan Shetty <gshetty@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/dpif.c | 2 | ||||
-rw-r--r-- | lib/odp-util.c | 75 | ||||
-rw-r--r-- | lib/odp-util.h | 14 |
3 files changed, 77 insertions, 14 deletions
@@ -1349,7 +1349,7 @@ log_flow_message(const struct dpif *dpif, int error, const char *operation, if (error) { ds_put_format(&ds, "(%s) ", ovs_strerror(error)); } - odp_flow_format(key, key_len, mask, mask_len, &ds, true); + odp_flow_format(key, key_len, mask, mask_len, NULL, &ds, true); if (stats) { ds_put_cstr(&ds, ", "); dpif_flow_stats_format(stats, &ds); diff --git a/lib/odp-util.c b/lib/odp-util.c index 0785c6a4..5c7ccfb6 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -51,7 +51,8 @@ static const char *delimiters = ", \t\r\n"; static int parse_odp_key_mask_attr(const char *, const struct simap *port_names, struct ofpbuf *, struct ofpbuf *); static void format_odp_key_attr(const struct nlattr *a, - const struct nlattr *ma, struct ds *ds, + const struct nlattr *ma, + const struct hmap *portno_names, struct ds *ds, bool verbose); /* Returns one the following for the action with the given OVS_ACTION_ATTR_* @@ -401,7 +402,7 @@ format_odp_action(struct ds *ds, const struct nlattr *a) break; case OVS_ACTION_ATTR_SET: ds_put_cstr(ds, "set("); - format_odp_key_attr(nl_attr_get(a), NULL, ds, true); + format_odp_key_attr(nl_attr_get(a), NULL, NULL, ds, true); ds_put_cstr(ds, ")"); break; case OVS_ACTION_ATTR_PUSH_VLAN: @@ -935,10 +936,49 @@ odp_mask_attr_is_exact(const struct nlattr *ma) return is_exact; } +void +odp_portno_names_set(struct hmap *portno_names, odp_port_t port_no, + char *port_name) +{ + struct odp_portno_names *odp_portno_names; + + odp_portno_names = xmalloc(sizeof *odp_portno_names); + odp_portno_names->port_no = port_no; + odp_portno_names->name = xstrdup(port_name); + hmap_insert(portno_names, &odp_portno_names->hmap_node, + hash_odp_port(port_no)); +} + +static char * +odp_portno_names_get(const struct hmap *portno_names, odp_port_t port_no) +{ + struct odp_portno_names *odp_portno_names; + + HMAP_FOR_EACH_IN_BUCKET (odp_portno_names, hmap_node, + hash_odp_port(port_no), portno_names) { + if (odp_portno_names->port_no == port_no) { + return odp_portno_names->name; + } + } + return NULL; +} + +void +odp_portno_names_destroy(struct hmap *portno_names) +{ + struct odp_portno_names *odp_portno_names, *odp_portno_names_next; + HMAP_FOR_EACH_SAFE (odp_portno_names, odp_portno_names_next, + hmap_node, portno_names) { + hmap_remove(portno_names, &odp_portno_names->hmap_node); + free(odp_portno_names->name); + free(odp_portno_names); + } +} static void format_odp_key_attr(const struct nlattr *a, const struct nlattr *ma, - struct ds *ds, bool verbose) + const struct hmap *portno_names, struct ds *ds, + bool verbose) { struct flow_tnl tun_key; enum ovs_key_attr attr = nl_attr_type(a); @@ -981,10 +1021,11 @@ format_odp_key_attr(const struct nlattr *a, const struct nlattr *ma, case OVS_KEY_ATTR_ENCAP: if (ma && nl_attr_get_size(ma) && nl_attr_get_size(a)) { odp_flow_format(nl_attr_get(a), nl_attr_get_size(a), - nl_attr_get(ma), nl_attr_get_size(ma), ds, verbose); - } else if (nl_attr_get_size(a)) { - odp_flow_format(nl_attr_get(a), nl_attr_get_size(a), NULL, 0, ds, + nl_attr_get(ma), nl_attr_get_size(ma), NULL, ds, verbose); + } else if (nl_attr_get_size(a)) { + odp_flow_format(nl_attr_get(a), nl_attr_get_size(a), NULL, 0, NULL, + ds, verbose); } break; @@ -1038,9 +1079,19 @@ format_odp_key_attr(const struct nlattr *a, const struct nlattr *ma, break; case OVS_KEY_ATTR_IN_PORT: - ds_put_format(ds, "%"PRIu32, nl_attr_get_u32(a)); - if (!is_exact) { - ds_put_format(ds, "/%#"PRIx32, nl_attr_get_u32(ma)); + if (portno_names && verbose && is_exact) { + char *name = odp_portno_names_get(portno_names, + u32_to_odp(nl_attr_get_u32(a))); + if (name) { + ds_put_format(ds, "%s", name); + } else { + ds_put_format(ds, "%"PRIu32, nl_attr_get_u32(a)); + } + } else { + ds_put_format(ds, "%"PRIu32, nl_attr_get_u32(a)); + if (!is_exact) { + ds_put_format(ds, "/%#"PRIx32, nl_attr_get_u32(ma)); + } } break; @@ -1364,7 +1415,7 @@ generate_all_wildcard_mask(struct ofpbuf *ofp, const struct nlattr *key) void odp_flow_format(const struct nlattr *key, size_t key_len, const struct nlattr *mask, size_t mask_len, - struct ds *ds, bool verbose) + const struct hmap *portno_names, struct ds *ds, bool verbose) { if (key_len) { const struct nlattr *a; @@ -1398,7 +1449,7 @@ odp_flow_format(const struct nlattr *key, size_t key_len, if (!first_field) { ds_put_char(ds, ','); } - format_odp_key_attr(a, ma, ds, verbose); + format_odp_key_attr(a, ma, portno_names, ds, verbose); first_field = false; } ofpbuf_clear(&ofp); @@ -1435,7 +1486,7 @@ void odp_flow_key_format(const struct nlattr *key, size_t key_len, struct ds *ds) { - odp_flow_format(key, key_len, NULL, 0, ds, true); + odp_flow_format(key, key_len, NULL, 0, NULL, ds, true); } static void diff --git a/lib/odp-util.h b/lib/odp-util.h index 4abf5434..2712cb00 100644 --- a/lib/odp-util.h +++ b/lib/odp-util.h @@ -23,6 +23,7 @@ #include <string.h> #include <linux/openvswitch.h> #include "hash.h" +#include "hmap.h" #include "openflow/openflow.h" #include "util.h" @@ -42,6 +43,16 @@ void format_odp_actions(struct ds *, const struct nlattr *odp_actions, int odp_actions_from_string(const char *, const struct simap *port_names, struct ofpbuf *odp_actions); +/* A map from odp port number to its name. */ +struct odp_portno_names { + struct hmap_node hmap_node; /* A node in a port number to name hmap. */ + odp_port_t port_no; /* Port number in the datapath. */ + char *name; /* Name associated with the above 'port_no'. */ +}; + +void odp_portno_names_set(struct hmap *portno_names, odp_port_t port_no, + char *port_name); +void odp_portno_names_destroy(struct hmap *portno_names); /* The maximum number of bytes that odp_flow_key_from_flow() appends to a * buffer. This is the upper bound on the length of a nlattr-formatted flow * key that ovs-vswitchd fully understands. @@ -94,7 +105,8 @@ enum odp_key_fitness odp_tun_key_from_attr(const struct nlattr *, void odp_flow_format(const struct nlattr *key, size_t key_len, const struct nlattr *mask, size_t mask_len, - struct ds *, bool verbose); + const struct hmap *portno_names, struct ds *, + bool verbose); void odp_flow_key_format(const struct nlattr *, size_t, struct ds *); int odp_flow_from_string(const char *s, const struct simap *port_names, |