Merge branch 'mainstream'
[sliver-openvswitch.git] / lib / odp-util.c
index 50b7e81..a09042e 100644 (file)
@@ -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, struct ds *ds,
+                                bool verbose);
 
 /* Returns one the following for the action with the given OVS_ACTION_ATTR_*
  * 'type':
@@ -399,7 +400,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);
+        format_odp_key_attr(nl_attr_get(a), NULL, ds, true);
         ds_put_cstr(ds, ")");
         break;
     case OVS_ACTION_ATTR_PUSH_VLAN:
@@ -897,6 +898,12 @@ tun_key_to_attr(struct ofpbuf *a, const struct flow_tnl *tun_key)
     nl_msg_end_nested(a, tun_key_ofs);
 }
 
+static bool
+odp_mask_attr_is_wildcard(const struct nlattr *ma)
+{
+    return is_all_zeros(nl_attr_get(ma), nl_attr_get_size(ma));
+}
+
 static bool
 odp_mask_attr_is_exact(const struct nlattr *ma)
 {
@@ -929,7 +936,7 @@ odp_mask_attr_is_exact(const struct nlattr *ma)
 
 static void
 format_odp_key_attr(const struct nlattr *a, const struct nlattr *ma,
-                    struct ds *ds)
+                    struct ds *ds, bool verbose)
 {
     struct flow_tnl tun_key;
     enum ovs_key_attr attr = nl_attr_type(a);
@@ -972,9 +979,10 @@ 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);
+                            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);
+            odp_flow_format(nl_attr_get(a), nl_attr_get_size(a), NULL, 0, ds,
+                            verbose);
         }
         break;
 
@@ -1337,7 +1345,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)
+                struct ds *ds, bool verbose)
 {
     if (key_len) {
         const struct nlattr *a;
@@ -1345,22 +1353,35 @@ odp_flow_format(const struct nlattr *key, size_t key_len,
         bool has_ethtype_key = false;
         const struct nlattr *ma = NULL;
         struct ofpbuf ofp;
+        bool first_field = true;
 
         ofpbuf_init(&ofp, 100);
         NL_ATTR_FOR_EACH (a, left, key, key_len) {
-            if (a != key) {
-                ds_put_char(ds, ',');
-            }
-            if (nl_attr_type(a) == OVS_KEY_ATTR_ETHERTYPE) {
+            bool is_nested_attr;
+            bool is_wildcard = false;
+            int attr_type = nl_attr_type(a);
+
+            if (attr_type == OVS_KEY_ATTR_ETHERTYPE) {
                 has_ethtype_key = true;
             }
+
+            is_nested_attr = (odp_flow_key_attr_len(attr_type) == -2);
+
             if (mask && mask_len) {
                 ma = nl_attr_find__(mask, mask_len, nl_attr_type(a));
-                if (!ma) {
+                is_wildcard = ma ? odp_mask_attr_is_wildcard(ma) : true;
+            }
+
+            if (verbose || !is_wildcard  || is_nested_attr) {
+                if (is_wildcard && !ma) {
                     ma = generate_all_wildcard_mask(&ofp, a);
                 }
+                if (!first_field) {
+                    ds_put_char(ds, ',');
+                }
+                format_odp_key_attr(a, ma, ds, verbose);
+                first_field = false;
             }
-            format_odp_key_attr(a, ma, ds);
             ofpbuf_clear(&ofp);
         }
         ofpbuf_uninit(&ofp);
@@ -1395,7 +1416,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);
+    odp_flow_format(key, key_len, NULL, 0, ds, true);
 }
 
 static void
@@ -2334,17 +2355,13 @@ odp_flow_key_from_flow__(struct ofpbuf *buf, const struct flow *data,
      * treat 'data' as a mask. */
     is_mask = (data != flow);
 
-    if (flow->skb_priority) {
-        nl_msg_put_u32(buf, OVS_KEY_ATTR_PRIORITY, data->skb_priority);
-    }
+    nl_msg_put_u32(buf, OVS_KEY_ATTR_PRIORITY, data->skb_priority);
 
     if (flow->tunnel.ip_dst || is_mask) {
         tun_key_to_attr(buf, &data->tunnel);
     }
 
-    if (flow->skb_mark) {
-        nl_msg_put_u32(buf, OVS_KEY_ATTR_SKB_MARK, data->skb_mark);
-    }
+    nl_msg_put_u32(buf, OVS_KEY_ATTR_SKB_MARK, data->pkt_mark);
 
     /* Add an ingress port attribute if this is a mask or 'odp_in_port'
      * is not the magical value "ODPP_NONE". */
@@ -2915,7 +2932,7 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_len,
     }
 
     if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_SKB_MARK)) {
-        flow->skb_mark = nl_attr_get_u32(attrs[OVS_KEY_ATTR_SKB_MARK]);
+        flow->pkt_mark = nl_attr_get_u32(attrs[OVS_KEY_ATTR_SKB_MARK]);
         expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_SKB_MARK;
     }
 
@@ -3027,11 +3044,11 @@ commit_set_action(struct ofpbuf *odp_actions, enum ovs_key_attr key_type,
 }
 
 void
-odp_put_skb_mark_action(const uint32_t skb_mark,
+odp_put_pkt_mark_action(const uint32_t pkt_mark,
                         struct ofpbuf *odp_actions)
 {
-    commit_set_action(odp_actions, OVS_KEY_ATTR_SKB_MARK, &skb_mark,
-                      sizeof(skb_mark));
+    commit_set_action(odp_actions, OVS_KEY_ATTR_SKB_MARK, &pkt_mark,
+                      sizeof(pkt_mark));
 }
 
 /* If any of the flow key data that ODP actions can modify are different in
@@ -3289,18 +3306,18 @@ commit_set_priority_action(const struct flow *flow, struct flow *base,
 }
 
 static void
-commit_set_skb_mark_action(const struct flow *flow, struct flow *base,
+commit_set_pkt_mark_action(const struct flow *flow, struct flow *base,
                            struct ofpbuf *odp_actions,
                            struct flow_wildcards *wc)
 {
-    if (base->skb_mark == flow->skb_mark) {
+    if (base->pkt_mark == flow->pkt_mark) {
         return;
     }
 
-    memset(&wc->masks.skb_mark, 0xff, sizeof wc->masks.skb_mark);
-    base->skb_mark = flow->skb_mark;
+    memset(&wc->masks.pkt_mark, 0xff, sizeof wc->masks.pkt_mark);
+    base->pkt_mark = flow->pkt_mark;
 
-    odp_put_skb_mark_action(base->skb_mark, odp_actions);
+    odp_put_pkt_mark_action(base->pkt_mark, odp_actions);
 }
 /* If any of the flow key data that ODP actions can modify are different in
  * 'base' and 'flow', appends ODP actions to 'odp_actions' that change the flow
@@ -3322,5 +3339,5 @@ commit_odp_actions(const struct flow *flow, struct flow *base,
      */
     commit_mpls_action(flow, base, odp_actions, wc);
     commit_set_priority_action(flow, base, odp_actions, wc);
-    commit_set_skb_mark_action(flow, base, odp_actions, wc);
+    commit_set_pkt_mark_action(flow, base, odp_actions, wc);
 }