[ovs-dev] [PATCH 2/2] vswitchd: Log all tunnel parameters of given flow.
Pravin B Shelar
pshelar at nicira.com
Tue Nov 20 18:15:52 UTC 2012
Signed-off-by: Pravin B Shelar <pshelar at nicira.com>
---
lib/flow.c | 30 ++++++++
lib/flow.h | 19 +++++
lib/match.c | 44 ++++++++---
lib/meta-flow.c | 211 +++++++++++++++++++++++++++++++++++++++++++++++++++-
lib/meta-flow.h | 13 +++-
lib/odp-util.c | 45 ++---------
tests/ovs-ofctl.at | 2 +
7 files changed, 310 insertions(+), 54 deletions(-)
diff --git a/lib/flow.c b/lib/flow.c
index 7084079..f285b0d 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -479,6 +479,36 @@ flow_to_string(const struct flow *flow)
}
void
+format_flags(struct ds *ds, const char *(*bit_to_string)(uint32_t),
+ uint32_t flags, char del)
+{
+ uint32_t bad = 0;
+
+ if (!flags) {
+ return;
+ }
+ while (flags) {
+ uint32_t bit = rightmost_1bit(flags);
+ const char *s;
+
+ s = bit_to_string(bit);
+ if (s) {
+ ds_put_format(ds, "%s%c", s, del);
+ } else {
+ bad |= bit;
+ }
+
+ flags &= ~bit;
+ }
+
+ if (bad) {
+ ds_put_format(ds, "0x%"PRIx32"%c", bad, del);
+ }
+ ds_chomp(ds, del);
+}
+
+
+void
flow_format(struct ds *ds, const struct flow *flow)
{
struct match match;
diff --git a/lib/flow.h b/lib/flow.h
index 5f4b8cb..1180594 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -56,6 +56,22 @@ BUILD_ASSERT_DECL(FLOW_NW_FRAG_LATER == NX_IP_FRAG_LATER);
#define FLOW_TNL_F_DONT_FRAGMENT (1 << 0)
#define FLOW_TNL_F_CSUM (1 << 1)
#define FLOW_TNL_F_KEY (1 << 2)
+
+static inline const char *
+flow_tun_flag_to_string(uint32_t flags)
+{
+ switch (flags) {
+ case FLOW_TNL_F_DONT_FRAGMENT:
+ return "df";
+ case FLOW_TNL_F_CSUM:
+ return "csum";
+ case FLOW_TNL_F_KEY:
+ return "key";
+ default:
+ return NULL;
+ }
+}
+
struct flow_tnl {
ovs_be64 tun_id;
ovs_be32 ip_src;
@@ -122,6 +138,9 @@ void flow_zero_wildcards(struct flow *, const struct flow_wildcards *);
void flow_get_metadata(const struct flow *, struct flow_metadata *);
char *flow_to_string(const struct flow *);
+void format_flags(struct ds *ds, const char *(*bit_to_string)(uint32_t),
+ uint32_t flags, char del);
+
void flow_format(struct ds *, const struct flow *);
void flow_print(FILE *, const struct flow *);
static inline int flow_compare_3way(const struct flow *, const struct flow *);
diff --git a/lib/match.c b/lib/match.c
index 81b7173..bf595c9 100644
--- a/lib/match.c
+++ b/lib/match.c
@@ -642,6 +642,35 @@ format_be16_masked(struct ds *s, const char *name,
}
}
+static void
+flow_tunnel_format(const struct match *match, struct ds *s)
+{
+ const struct flow_wildcards *wc = &match->wc;
+ const struct flow_tnl *tnl = &match->flow.tunnel;
+
+ switch (wc->masks.tunnel.tun_id) {
+ case 0:
+ return;
+ case CONSTANT_HTONLL(UINT64_MAX):
+ ds_put_format(s, "tun_id=%#"PRIx64, ntohll(tnl->tun_id));
+ break;
+ default:
+ ds_put_format(s, "tun_id=%#"PRIx64"/%#"PRIx64,
+ ntohll(tnl->tun_id),
+ ntohll(wc->masks.tunnel.tun_id));
+ break;
+ }
+ if (tnl->ip_dst) {
+ ds_put_format(s, ",tun_src="IP_FMT",tun_dst="IP_FMT","
+ "tun_tos=0x%"PRIx8",tun_ttl=%"PRIu8",tun_flags",
+ IP_ARGS(&tnl->ip_src),
+ IP_ARGS(&tnl->ip_dst),
+ tnl->ip_tos, tnl->ip_ttl);
+ format_flags(s, flow_tun_flag_to_string, tnl->flags, '.');
+ }
+ ds_put_char(s, ',');
+}
+
/* Appends a string representation of 'match' to 's'. If 'priority' is
* different from OFP_DEFAULT_PRIORITY, includes it in 's'. */
void
@@ -716,18 +745,9 @@ match_format(const struct match *match, struct ds *s, unsigned int priority)
break;
}
}
- switch (wc->masks.tunnel.tun_id) {
- case 0:
- break;
- case CONSTANT_HTONLL(UINT64_MAX):
- ds_put_format(s, "tun_id=%#"PRIx64",", ntohll(f->tunnel.tun_id));
- break;
- default:
- ds_put_format(s, "tun_id=%#"PRIx64"/%#"PRIx64",",
- ntohll(f->tunnel.tun_id),
- ntohll(wc->masks.tunnel.tun_id));
- break;
- }
+
+ flow_tunnel_format(match, s);
+
switch (wc->masks.metadata) {
case 0:
break;
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index 0b97049..7f68ac1 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -28,6 +28,7 @@
#include "dynamic-string.h"
#include "ofp-errors.h"
#include "ofp-util.h"
+#include "odp-util.h"
#include "packets.h"
#include "random.h"
#include "shash.h"
@@ -56,6 +57,51 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
NXM_NX_TUN_ID, "NXM_NX_TUN_ID",
NXM_NX_TUN_ID, "NXM_NX_TUN_ID",
}, {
+ MFF_TUN_SRC, "tun_src", NULL,
+ MF_FIELD_SIZES(be32),
+ MFM_NONE,
+ MFS_IPV4,
+ MFP_NONE,
+ false,
+ 0, NULL,
+ 0, NULL,
+ }, {
+ MFF_TUN_DST, "tun_dst", NULL,
+ MF_FIELD_SIZES(be32),
+ MFM_NONE,
+ MFS_IPV4,
+ MFP_NONE,
+ false,
+ 0, NULL,
+ 0, NULL,
+ }, {
+ MFF_TUN_FLAGS, "tun_flags", NULL,
+ MF_FIELD_SIZES(be16),
+ MFM_NONE,
+ MFS_TNL_FLAGS,
+ MFP_NONE,
+ false,
+ 0, NULL,
+ 0, NULL,
+ }, {
+ MFF_TUN_TOS, "tun_tos", NULL,
+ 1, 8,
+ MFM_NONE,
+ MFS_HEXADECIMAL,
+ MFP_NONE,
+ false,
+ 0, NULL,
+ 0, NULL,
+ }, {
+ MFF_TUN_TTL, "tun_ttl", NULL,
+ 1, 8,
+ MFM_NONE,
+ MFS_HEXADECIMAL,
+ MFP_NONE,
+ false,
+ 0, NULL,
+ 0, NULL,
+ }, {
MFF_METADATA, "metadata", NULL,
MF_FIELD_SIZES(be64),
MFM_FULLY,
@@ -573,7 +619,7 @@ bool
mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
{
switch (mf->id) {
- case MFF_TUN_ID:
+ CASE_MFF_TUN_ID:
return !wc->masks.tunnel.tun_id;
case MFF_METADATA:
return !wc->masks.metadata;
@@ -670,7 +716,7 @@ mf_get_mask(const struct mf_field *mf, const struct flow_wildcards *wc,
union mf_value *mask)
{
switch (mf->id) {
- case MFF_TUN_ID:
+ CASE_MFF_TUN_ID:
mask->be64 = wc->masks.tunnel.tun_id;
break;
case MFF_METADATA:
@@ -886,7 +932,7 @@ bool
mf_is_value_valid(const struct mf_field *mf, const union mf_value *value)
{
switch (mf->id) {
- case MFF_TUN_ID:
+ CASE_MFF_TUN_ID:
case MFF_METADATA:
case MFF_IN_PORT:
CASE_MFF_REGS:
@@ -955,6 +1001,22 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
case MFF_TUN_ID:
value->be64 = flow->tunnel.tun_id;
break;
+ case MFF_TUN_SRC:
+ value->be32 = flow->tunnel.ip_src;
+ break;
+ case MFF_TUN_DST:
+ value->be32 = flow->tunnel.ip_dst;
+ break;
+ case MFF_TUN_FLAGS:
+ value->u16 = flow->tunnel.flags;
+ break;
+ case MFF_TUN_TTL:
+ value->u8 = flow->tunnel.ip_ttl;
+ break;
+ case MFF_TUN_TOS:
+ value->u8 = flow->tunnel.ip_tos;
+ break;
+
case MFF_METADATA:
value->be64 = flow->metadata;
break;
@@ -1098,6 +1160,22 @@ mf_set_value(const struct mf_field *mf,
case MFF_TUN_ID:
match_set_tun_id(match, value->be64);
break;
+ case MFF_TUN_SRC:
+ match->flow.tunnel.ip_src = value->be32;
+ break;
+ case MFF_TUN_DST:
+ match->flow.tunnel.ip_dst = value->be32;
+ break;
+ case MFF_TUN_FLAGS:
+ match->flow.tunnel.flags = value->u16;
+ break;
+ case MFF_TUN_TTL:
+ match->flow.tunnel.ip_tos = value->u8;
+ break;
+ case MFF_TUN_TOS:
+ match->flow.tunnel.ip_ttl = value->u8;
+ break;
+
case MFF_METADATA:
match_set_metadata(match, value->be64);
break;
@@ -1241,6 +1319,22 @@ mf_set_flow_value(const struct mf_field *mf,
case MFF_TUN_ID:
flow->tunnel.tun_id = value->be64;
break;
+ case MFF_TUN_SRC:
+ flow->tunnel.ip_src = value->be32;
+ break;
+ case MFF_TUN_DST:
+ flow->tunnel.ip_dst = value->be32;
+ break;
+ case MFF_TUN_FLAGS:
+ flow->tunnel.flags = value->u16;
+ break;
+ case MFF_TUN_TTL:
+ flow->tunnel.ip_tos = value->u8;
+ break;
+ case MFF_TUN_TOS:
+ flow->tunnel.ip_ttl = value->u8;
+ break;
+
case MFF_METADATA:
flow->metadata = value->be64;
break;
@@ -1399,6 +1493,22 @@ mf_set_wild(const struct mf_field *mf, struct match *match)
case MFF_TUN_ID:
match_set_tun_id_masked(match, htonll(0), htonll(0));
break;
+ case MFF_TUN_SRC:
+ match->flow.tunnel.ip_src = 0;
+ break;
+ case MFF_TUN_DST:
+ match->flow.tunnel.ip_dst = 0;
+ break;
+ case MFF_TUN_FLAGS:
+ match->flow.tunnel.flags = 0;
+ break;
+ case MFF_TUN_TTL:
+ match->flow.tunnel.ip_tos = 0;
+ break;
+ case MFF_TUN_TOS:
+ match->flow.tunnel.ip_ttl = 0;
+ break;
+
case MFF_METADATA:
match_set_metadata_masked(match, htonll(0), htonll(0));
@@ -1579,6 +1689,22 @@ mf_set(const struct mf_field *mf,
case MFF_TUN_ID:
match_set_tun_id_masked(match, value->be64, mask->be64);
break;
+ case MFF_TUN_SRC:
+ match->flow.tunnel.ip_src = value->be32;
+ break;
+ case MFF_TUN_DST:
+ match->flow.tunnel.ip_dst = value->be32;
+ break;
+ case MFF_TUN_FLAGS:
+ match->flow.tunnel.flags = value->u16;
+ break;
+ case MFF_TUN_TTL:
+ match->flow.tunnel.ip_ttl = value->u8;
+ break;
+ case MFF_TUN_TOS:
+ match->flow.tunnel.ip_tos = value->u8;
+ break;
+
case MFF_METADATA:
match_set_metadata_masked(match, value->be64, mask->be64);
break;
@@ -1736,7 +1862,7 @@ mf_random_value(const struct mf_field *mf, union mf_value *value)
random_bytes(value, mf->n_bytes);
switch (mf->id) {
- case MFF_TUN_ID:
+ CASE_MFF_TUN_ID:
case MFF_METADATA:
case MFF_IN_PORT:
CASE_MFF_REGS:
@@ -1995,6 +2121,70 @@ mf_from_frag_string(const char *s, uint8_t *valuep, uint8_t *maskp)
"\"yes\", \"first\", \"later\", \"not_first\"", s);
}
+static int
+ofp_tun_parse_flags(const char *s_, const char *(*bit_to_string)(uint32_t),
+ uint32_t *res)
+{
+ uint32_t result = 0;
+ char *save_ptr = NULL;
+ char *name;
+ int rc = 0;
+ char *s = xstrdup(s_);
+
+ for (name = strtok_r((char *)s, " .", &save_ptr); name;
+ name = strtok_r(NULL, " .", &save_ptr)) {
+
+ unsigned long long int flags;
+ uint32_t bit;
+ int n0;
+
+ if (sscanf(name, "%lli%n", &flags, &n0) > 0 && n0 > 0) {
+ result |= flags;
+ continue;
+ }
+
+ for (bit = 1; bit; bit <<= 1) {
+ const char *fname = bit_to_string(bit);
+ size_t len;
+
+ if (!fname) {
+ continue;
+ }
+
+ len = strlen(fname);
+ if (!strncmp(name, fname, len)) {
+ result |= bit;
+ break;
+ }
+ }
+
+ if (!bit) {
+ rc = -ENOENT;
+ goto out;
+ }
+ }
+
+ *res = result;
+out:
+ free(s);
+ return rc;
+}
+
+static char *
+mf_from_tun_flags_string(const char *s, uint16_t *valuep)
+{
+ uint32_t flags;
+
+ if (!ofp_tun_parse_flags(s, flow_tun_flag_to_string, &flags)) {
+ *valuep = (uint16_t) flags;
+ return NULL;
+ }
+
+ return xasprintf("%s: unknown tunnel flags (valid flags are \"df\", "
+ "\"csum\", \"key\"", s);
+}
+
+
/* Parses 's', a string value for field 'mf', into 'value' and 'mask'. Returns
* NULL if successful, otherwise a malloc()'d string describing the error. */
char *
@@ -2027,6 +2217,9 @@ mf_parse(const struct mf_field *mf, const char *s,
case MFS_FRAG:
return mf_from_frag_string(s, &value->u8, &mask->u8);
+
+ case MFS_TNL_FLAGS:
+ return mf_from_tun_flags_string(s, &value->u16);
}
NOT_REACHED();
}
@@ -2104,6 +2297,12 @@ mf_format_frag_string(const uint8_t *valuep, const uint8_t *maskp,
ds_put_cstr(s, "<error>");
}
+static void
+mf_format_tnl_flags_string(const uint16_t *valuep, struct ds *s)
+{
+ format_flags(s, flow_tun_flag_to_string, *valuep, '.');
+}
+
/* Appends to 's' a string representation of field 'mf' whose value is in
* 'value' and 'mask'. 'mask' may be NULL to indicate an exact match. */
void
@@ -2149,6 +2348,10 @@ mf_format(const struct mf_field *mf,
mf_format_frag_string(&value->u8, &mask->u8, s);
break;
+ case MFS_TNL_FLAGS:
+ mf_format_tnl_flags_string(&value->u16, s);
+ break;
+
default:
NOT_REACHED();
}
diff --git a/lib/meta-flow.h b/lib/meta-flow.h
index 60bfeca..02b7bfe 100644
--- a/lib/meta-flow.h
+++ b/lib/meta-flow.h
@@ -32,6 +32,11 @@ struct match;
enum mf_field_id {
/* Metadata. */
MFF_TUN_ID, /* be64 */
+ MFF_TUN_SRC, /* be32 */
+ MFF_TUN_DST, /* be32 */
+ MFF_TUN_FLAGS, /* be16 */
+ MFF_TUN_TTL, /* u8 */
+ MFF_TUN_TOS, /* u8 */
MFF_METADATA, /* be64 */
MFF_IN_PORT, /* be16 */
@@ -112,6 +117,10 @@ enum mf_field_id {
MFF_N_IDS
};
+#define CASE_MFF_TUN_ID \
+case MFF_TUN_ID: case MFF_TUN_SRC: case MFF_TUN_DST: \
+case MFF_TUN_FLAGS: case MFF_TUN_TTL: case MFF_TUN_TOS
+
/* Use this macro as CASE_MFF_REGS: in a switch statement to choose all of the
* MFF_REGx cases. */
#if FLOW_N_REGS == 1
@@ -195,7 +204,8 @@ enum mf_string {
MFS_IPV4,
MFS_IPV6,
MFS_OFP_PORT, /* An OpenFlow port number or name. */
- MFS_FRAG /* no, yes, first, later, not_later */
+ MFS_FRAG, /* no, yes, first, later, not_later */
+ MFS_TNL_FLAGS, /* ref: flow.tunnel - flow.h */
};
struct mf_field {
@@ -251,6 +261,7 @@ struct mf_field {
/* The representation of a field's value. */
union mf_value {
uint8_t u8;
+ uint16_t u16;
ovs_be16 be16;
ovs_be32 be32;
ovs_be64 be64;
diff --git a/lib/odp-util.c b/lib/odp-util.c
index 3884b4d..97859ce 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -189,38 +189,6 @@ slow_path_reason_to_string(uint32_t data)
}
}
-static void
-format_flags(struct ds *ds, const char *(*bit_to_string)(uint32_t),
- uint32_t flags)
-{
- uint32_t bad = 0;
-
- ds_put_format(ds, "(");
- if (!flags) {
- goto out;
- }
- while (flags) {
- uint32_t bit = rightmost_1bit(flags);
- const char *s;
-
- s = bit_to_string(bit);
- if (s) {
- ds_put_format(ds, "%s,", s);
- } else {
- bad |= bit;
- }
-
- flags &= ~bit;
- }
-
- if (bad) {
- ds_put_format(ds, "0x%"PRIx32",", bad);
- }
- ds_chomp(ds, ',');
-out:
- ds_put_format(ds, ")");
-}
-
static int
parse_flags(const char *s, const char *(*bit_to_string)(uint32_t),
uint32_t *res)
@@ -304,8 +272,10 @@ format_odp_userspace_action(struct ds *ds, const struct nlattr *attr)
break;
case USER_ACTION_COOKIE_SLOW_PATH:
- ds_put_cstr(ds, ",slow_path");
- format_flags(ds, slow_path_reason_to_string, cookie.slow_path.reason);
+ ds_put_cstr(ds, ",slow_path(");
+ format_flags(ds, slow_path_reason_to_string,
+ cookie.slow_path.reason, ',');
+ ds_put_format(ds, ")");
break;
case USER_ACTION_COOKIE_UNSPEC:
@@ -761,14 +731,15 @@ format_odp_key_attr(const struct nlattr *a, struct ds *ds)
case OVS_KEY_ATTR_IPV4_TUNNEL:
ipv4_tun_key = nl_attr_get(a);
ds_put_format(ds, "(tun_id=0x%"PRIx64",src="IP_FMT",dst="IP_FMT","
- "tos=0x%"PRIx8",ttl=%"PRIu8",flags",
+ "tos=0x%"PRIx8",ttl=%"PRIu8",flags(",
ntohll(ipv4_tun_key->tun_id),
IP_ARGS(&ipv4_tun_key->ipv4_src),
IP_ARGS(&ipv4_tun_key->ipv4_dst),
ipv4_tun_key->ipv4_tos, ipv4_tun_key->ipv4_ttl);
- format_flags(ds, tun_flag_to_string, ipv4_tun_key->tun_flags);
- ds_put_format(ds, ")");
+ format_flags(ds, tun_flag_to_string,
+ ipv4_tun_key->tun_flags, ',');
+ ds_put_format(ds, "))");
break;
case OVS_KEY_ATTR_IN_PORT:
diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at
index 1d9158c..97f9c66 100644
--- a/tests/ovs-ofctl.at
+++ b/tests/ovs-ofctl.at
@@ -46,6 +46,7 @@ actions=set_tunnel:0x1234,set_tunnel64:0x9876,set_tunnel:0x123456789
actions=multipath(eth_src, 50, hrw, 12, 0, NXM_NX_REG0[0..3]),multipath(symmetric_l4, 1024, iter_hash, 5000, 5050, NXM_NX_REG0[0..12])
table=1,actions=drop
tun_id=0x1234000056780000/0xffff0000ffff0000,actions=drop
+tun_id=0x1234000056780000/0xffff0000ffff0000,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=0x3,tun_ttl=0x2,tun_flags=key.csum actions=drop
metadata=0x1234ffff5678ffff/0xffff0000ffff0000,actions=drop
actions=bundle(eth_src,50,active_backup,ofport,slaves:1)
actions=bundle(symmetric_l4,60,hrw,ofport,slaves:2,3)
@@ -80,6 +81,7 @@ NXT_FLOW_MOD: ADD table:255 actions=set_tunnel:0x1234,set_tunnel64:0x9876,set_tu
NXT_FLOW_MOD: ADD table:255 actions=multipath(eth_src,50,hrw,12,0,NXM_NX_REG0[0..3]),multipath(symmetric_l4,1024,iter_hash,5000,5050,NXM_NX_REG0[0..12])
NXT_FLOW_MOD: ADD table:1 actions=drop
NXT_FLOW_MOD: ADD table:255 tun_id=0x1234000056780000/0xffff0000ffff0000 actions=drop
+NXT_FLOW_MOD: ADD table:255 tun_id=0x1234000056780000/0xffff0000ffff0000 actions=drop
NXT_FLOW_MOD: ADD table:255 metadata=0x1234000056780000/0xffff0000ffff0000 actions=drop
NXT_FLOW_MOD: ADD table:255 actions=bundle(eth_src,50,active_backup,ofport,slaves:1)
NXT_FLOW_MOD: ADD table:255 actions=bundle(symmetric_l4,60,hrw,ofport,slaves:2,3)
--
1.7.10
More information about the dev
mailing list