[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