[ovs-dev] [PATCH v4 2/4] ofproto: Probe for masked set action support.

Jarno Rajahalme jrajahalme at nicira.com
Mon Aug 11 16:14:59 UTC 2014


Signed-off-by: Jarno Rajahalme <jrajahalme at nicira.com>
Reviewed-by: YAMAMOTO Takashi <yamamoto at valinux.co.jp>
---
 ofproto/ofproto-dpif-xlate.c |   18 +++++++++----
 ofproto/ofproto-dpif-xlate.h |    3 ++-
 ofproto/ofproto-dpif.c       |   58 +++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 72 insertions(+), 7 deletions(-)

diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 4aedb59..d103a03 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -106,6 +106,10 @@ struct xbridge {
     /* Number of MPLS label stack entries that the datapath supports
      * in matches. */
     size_t max_mpls_depth;
+
+    /* True if the datapath supports masked data in OVS_ACTION_ATTR_SET
+     * actions. */
+    bool masked_set_action;
 };
 
 struct xbundle {
@@ -367,7 +371,8 @@ static void xlate_xbridge_set(struct xbridge *xbridge,
                               bool forward_bpdu, bool has_in_band,
                               bool enable_recirc,
                               bool variable_length_userdata,
-                              size_t max_mpls_depth);
+                              size_t max_mpls_depth,
+                              bool masked_set_action);
 static void xlate_xbundle_set(struct xbundle *xbundle,
                               enum port_vlan_mode vlan_mode, int vlan,
                               unsigned long *trunks, bool use_priority_tags,
@@ -431,7 +436,8 @@ xlate_xbridge_set(struct xbridge *xbridge,
                   bool forward_bpdu, bool has_in_band,
                   bool enable_recirc,
                   bool variable_length_userdata,
-                  size_t max_mpls_depth)
+                  size_t max_mpls_depth,
+                  bool masked_set_action)
 {
     if (xbridge->ml != ml) {
         mac_learning_unref(xbridge->ml);
@@ -477,6 +483,7 @@ xlate_xbridge_set(struct xbridge *xbridge,
     xbridge->enable_recirc = enable_recirc;
     xbridge->variable_length_userdata = variable_length_userdata;
     xbridge->max_mpls_depth = max_mpls_depth;
+    xbridge->masked_set_action = masked_set_action;
 }
 
 static void
@@ -552,7 +559,7 @@ xlate_xbridge_copy(struct xbridge *xbridge)
                       xbridge->ipfix, xbridge->netflow, xbridge->frag,
                       xbridge->forward_bpdu, xbridge->has_in_band,
                       xbridge->enable_recirc, xbridge->variable_length_userdata,
-                      xbridge->max_mpls_depth);
+                      xbridge->max_mpls_depth, xbridge->masked_set_action);
     LIST_FOR_EACH (xbundle, list_node, &xbridge->xbundles) {
         xlate_xbundle_copy(new_xbridge, xbundle);
     }
@@ -706,7 +713,8 @@ xlate_ofproto_set(struct ofproto_dpif *ofproto, const char *name,
                   bool forward_bpdu, bool has_in_band,
                   bool enable_recirc,
                   bool variable_length_userdata,
-                  size_t max_mpls_depth)
+                  size_t max_mpls_depth,
+                  bool masked_set_action)
 {
     struct xbridge *xbridge;
 
@@ -726,7 +734,7 @@ xlate_ofproto_set(struct ofproto_dpif *ofproto, const char *name,
     xlate_xbridge_set(xbridge, dpif, miss_rule, no_packet_in_rule, ml, stp,
                       ms, mbridge, sflow, ipfix, netflow, frag, forward_bpdu,
                       has_in_band, enable_recirc, variable_length_userdata,
-                      max_mpls_depth);
+                      max_mpls_depth, masked_set_action);
 }
 
 static void
diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h
index 4bdf2d3..36ac9e7 100644
--- a/ofproto/ofproto-dpif-xlate.h
+++ b/ofproto/ofproto-dpif-xlate.h
@@ -147,7 +147,8 @@ void xlate_ofproto_set(struct ofproto_dpif *, const char *name,
                        enum ofp_config_flags, bool forward_bpdu,
                        bool has_in_band, bool enable_recirc,
                        bool variable_length_userdata,
-                       size_t mpls_label_stack_length);
+                       size_t mpls_label_stack_length,
+                       bool masked_set_action);
 void xlate_remove_ofproto(struct ofproto_dpif *);
 
 void xlate_bundle_set(struct ofproto_dpif *, struct ofbundle *,
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 48d0b82..b667ea5 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -263,6 +263,10 @@ struct dpif_backer {
      * False if the datapath supports only 8-byte (or shorter) userdata. */
     bool variable_length_userdata;
 
+    /* True if the datapath supports masked data in OVS_ACTION_ATTR_SET
+     * actions. */
+    bool masked_set_action;
+
     /* Maximum number of MPLS label stack entries that the datapath supports
      * in a match */
     size_t max_mpls_depth;
@@ -602,7 +606,8 @@ type_run(const char *type)
                               connmgr_has_in_band(ofproto->up.connmgr),
                               ofproto->backer->enable_recirc,
                               ofproto->backer->variable_length_userdata,
-                              ofproto->backer->max_mpls_depth);
+                              ofproto->backer->max_mpls_depth,
+                              ofproto->backer->masked_set_action);
 
             HMAP_FOR_EACH (bundle, hmap_node, &ofproto->bundles) {
                 xlate_bundle_set(ofproto, bundle, bundle->name,
@@ -827,6 +832,7 @@ struct odp_garbage {
 static bool check_variable_length_userdata(struct dpif_backer *backer);
 static size_t check_max_mpls_depth(struct dpif_backer *backer);
 static bool check_recirc(struct dpif_backer *backer);
+static bool check_masked_set_action(struct dpif_backer *backer);
 
 static int
 open_dpif_backer(const char *type, struct dpif_backer **backerp)
@@ -923,6 +929,7 @@ open_dpif_backer(const char *type, struct dpif_backer **backerp)
     backer->enable_recirc = check_recirc(backer);
     backer->variable_length_userdata = check_variable_length_userdata(backer);
     backer->max_mpls_depth = check_max_mpls_depth(backer);
+    backer->masked_set_action = check_masked_set_action(backer);
     backer->rid_pool = recirc_id_pool_create();
 
     error = dpif_recv_set(backer->dpif, backer->recv_set_enable);
@@ -1113,6 +1120,55 @@ check_max_mpls_depth(struct dpif_backer *backer)
     return n;
 }
 
+/* Tests whether 'backer''s datapath supports masked data in
+ * OVS_ACTION_ATTR_SET actions.  We need to disable some features on older
+ * datapaths that don't support this feature. */
+static bool
+check_masked_set_action(struct dpif_backer *backer)
+{
+    struct eth_header *eth;
+    struct ofpbuf actions;
+    struct dpif_execute execute;
+    struct ofpbuf packet;
+    int error;
+    struct ovs_key_ethernet key, mask;
+
+    /* Compose a set action that will cause an EINVAL error on older
+     * datapaths that don't support masked set actions.
+     * Avoid using a full mask, as it could be translated to a non-masked
+     * set action instead. */
+    ofpbuf_init(&actions, 64);
+    memset(&key, 0x53, sizeof key);
+    memset(&mask, 0x7f, sizeof mask);
+    commit_masked_set_action(&actions, OVS_KEY_ATTR_ETHERNET, &key, &mask,
+                             sizeof key);
+
+    /* Compose a dummy ethernet packet. */
+    ofpbuf_init(&packet, ETH_HEADER_LEN);
+    eth = ofpbuf_put_zeros(&packet, ETH_HEADER_LEN);
+    eth->eth_type = htons(0x1234);
+
+    /* Execute the actions.  On older datapaths this fails with EINVAL, on
+     * newer datapaths it succeeds. */
+    execute.actions = ofpbuf_data(&actions);
+    execute.actions_len = ofpbuf_size(&actions);
+    execute.packet = &packet;
+    execute.md = PKT_METADATA_INITIALIZER(0);
+    execute.needs_help = false;
+
+    error = dpif_execute(backer->dpif, &execute);
+
+    ofpbuf_uninit(&packet);
+    ofpbuf_uninit(&actions);
+
+    if (error) {
+        /* Masked set action is not supported. */
+        VLOG_INFO("%s: datapath does not support masked set action feature.",
+                  dpif_name(backer->dpif));
+    }
+    return !error;
+}
+
 static int
 construct(struct ofproto *ofproto_)
 {
-- 
1.7.10.4




More information about the dev mailing list