This patch adds support for skb mark matching and set action.

Signed-off-by: Ansis Atteka <aatt...@nicira.com>
---
 datapath/actions.c          |    4 ++++
 datapath/datapath.c         |    1 +
 datapath/flow.c             |   15 +++++++++++++++
 datapath/flow.h             |    6 ++++--
 include/linux/openvswitch.h |    1 +
 lib/dpif-netdev.c           |    1 +
 lib/odp-util.c              |    3 +++
 7 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/datapath/actions.c b/datapath/actions.c
index 76c9823..5da4b74 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -435,6 +435,10 @@ static int execute_set_action(struct sk_buff *skb,
                skb->priority = nla_get_u32(nested_attr);
                break;
 
+       case OVS_KEY_ATTR_SKB_MARK:
+               skb->mark = nla_get_u32(nested_attr);
+               break;
+
        case OVS_KEY_ATTR_TUN_ID:
                /* If we're only using the TUN_ID action, store the value in a
                 * temporary instance of struct ovs_key_ipv4_tunnel on the 
stack.
diff --git a/datapath/datapath.c b/datapath/datapath.c
index e359ac0..44828c6 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -590,6 +590,7 @@ static int validate_set(const struct nlattr *a,
        const struct ovs_key_ipv4_tunnel *tun_key;
        const struct ovs_key_ipv6 *ipv6_key;
 
+       case OVS_KEY_ATTR_SKB_MARK:
        case OVS_KEY_ATTR_PRIORITY:
        case OVS_KEY_ATTR_TUN_ID:
        case OVS_KEY_ATTR_ETHERNET:
diff --git a/datapath/flow.c b/datapath/flow.c
index 41c624e..d6a4f3a 100644
--- a/datapath/flow.c
+++ b/datapath/flow.c
@@ -624,6 +624,7 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, 
struct sw_flow_key *key,
        if (OVS_CB(skb)->tun_key)
                memcpy(&key->tun_key, OVS_CB(skb)->tun_key, 
sizeof(key->tun_key));
        key->phy.in_port = in_port;
+       key->phy.skb_mark = skb->mark;
 
        skb_reset_mac_header(skb);
 
@@ -835,6 +836,7 @@ const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
        [OVS_KEY_ATTR_ENCAP] = -1,
        [OVS_KEY_ATTR_PRIORITY] = sizeof(u32),
        [OVS_KEY_ATTR_IN_PORT] = sizeof(u32),
+       [OVS_KEY_ATTR_SKB_MARK] = sizeof(u32),
        [OVS_KEY_ATTR_ETHERNET] = sizeof(struct ovs_key_ethernet),
        [OVS_KEY_ATTR_VLAN] = sizeof(__be16),
        [OVS_KEY_ATTR_ETHERTYPE] = sizeof(__be16),
@@ -1024,6 +1026,10 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int 
*key_lenp,
        } else {
                swkey->phy.in_port = DP_MAX_PORTS;
        }
+       if (attrs & (1 << OVS_KEY_ATTR_SKB_MARK)) {
+               swkey->phy.skb_mark = nla_get_u32(a[OVS_KEY_ATTR_SKB_MARK]);
+               attrs &= ~(1 << OVS_KEY_ATTR_SKB_MARK);
+       }
 
        if (attrs & (1ULL << OVS_KEY_ATTR_TUN_ID) &&
            attrs & (1ULL << OVS_KEY_ATTR_IPV4_TUNNEL)) {
@@ -1203,6 +1209,7 @@ int ovs_flow_metadata_from_nlattrs(struct sw_flow *flow, 
int key_len, const stru
 
        flow->key.phy.in_port = DP_MAX_PORTS;
        flow->key.phy.priority = 0;
+       flow->key.phy.skb_mark = 0;
        memset(tun_key, 0, sizeof(flow->key.tun_key));
 
        nla_for_each_nested(nla, attr, rem) {
@@ -1254,6 +1261,10 @@ int ovs_flow_metadata_from_nlattrs(struct sw_flow *flow, 
int key_len, const stru
                                        return -EINVAL;
                                flow->key.phy.in_port = nla_get_u32(nla);
                                break;
+
+                       case OVS_KEY_ATTR_SKB_MARK:
+                               flow->key.phy.skb_mark = nla_get_u32(nla);
+                               break;
                        }
                }
        }
@@ -1291,6 +1302,10 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, 
struct sk_buff *skb)
            nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port))
                goto nla_put_failure;
 
+       if (swkey->phy.skb_mark &&
+           nla_put_u32(skb, OVS_KEY_ATTR_SKB_MARK, swkey->phy.skb_mark))
+               goto nla_put_failure;
+
        nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key));
        if (!nla)
                goto nla_put_failure;
diff --git a/datapath/flow.h b/datapath/flow.h
index 54f0fcd..fb69ac5 100644
--- a/datapath/flow.h
+++ b/datapath/flow.h
@@ -45,6 +45,7 @@ struct sw_flow_key {
        struct {
                u32     priority;       /* Packet QoS priority. */
                u16     in_port;        /* Input switch port (or DP_MAX_PORTS). 
*/
+               u32     skb_mark;       /* SKB mark. */
        } phy;
        struct {
                u8     src[ETH_ALEN];   /* Ethernet source address. */
@@ -147,6 +148,7 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies);
  *  OVS_KEY_ATTR_TUN_ID        8    --     4     12
  *  OVS_KEY_ATTR_IPV4_TUNNEL  24    --     4     28
  *  OVS_KEY_ATTR_IN_PORT       4    --     4      8
+ *  OVS_KEY_ATTR_SKB_MARK      4    --     4      8
  *  OVS_KEY_ATTR_ETHERNET     12    --     4     16
  *  OVS_KEY_ATTR_ETHERTYPE     2     2     4      8  (outer VLAN ethertype)
  *  OVS_KEY_ATTR_8021Q         4    --     4      8
@@ -156,9 +158,9 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies);
  *  OVS_KEY_ATTR_ICMPV6        2     2     4      8
  *  OVS_KEY_ATTR_ND           28    --     4     32
  *  -------------------------------------------------
- *  total                                       184
+ *  total                                       192
  */
-#define FLOW_BUFSIZE 184
+#define FLOW_BUFSIZE 192
 
 int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *);
 int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h
index c4823d9..9898f6e 100644
--- a/include/linux/openvswitch.h
+++ b/include/linux/openvswitch.h
@@ -281,6 +281,7 @@ enum ovs_key_attr {
        OVS_KEY_ATTR_ARP,       /* struct ovs_key_arp */
        OVS_KEY_ATTR_ND,        /* struct ovs_key_nd */
        OVS_KEY_ATTR_IPV4_TUNNEL,  /* struct ovs_key_ipv4_tunnel */
+       OVS_KEY_ATTR_SKB_MARK,  /* u32 skb->mark */
        OVS_KEY_ATTR_TUN_ID = 63,  /* be64 tunnel ID */
        __OVS_KEY_ATTR_MAX
 };
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 4ce4147..d58df34 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -1189,6 +1189,7 @@ execute_set_action(struct ofpbuf *packet, const struct 
nlattr *a)
     case OVS_KEY_ATTR_TUN_ID:
     case OVS_KEY_ATTR_PRIORITY:
     case OVS_KEY_ATTR_IPV4_TUNNEL:
+    case OVS_KEY_ATTR_SKB_MARK:
         /* not implemented */
         break;
 
diff --git a/lib/odp-util.c b/lib/odp-util.c
index 08823e2..3d0a1c7 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -93,6 +93,7 @@ ovs_key_attr_to_string(enum ovs_key_attr attr)
     case OVS_KEY_ATTR_UNSPEC: return "unspec";
     case OVS_KEY_ATTR_ENCAP: return "encap";
     case OVS_KEY_ATTR_PRIORITY: return "priority";
+    case OVS_KEY_ATTR_SKB_MARK: return "skb_mark";
     case OVS_KEY_ATTR_TUN_ID: return "tun_id";
     case OVS_KEY_ATTR_IPV4_TUNNEL: return "ipv4_tunnel";
     case OVS_KEY_ATTR_IN_PORT: return "in_port";
@@ -602,6 +603,7 @@ odp_flow_key_attr_len(uint16_t type)
     switch ((enum ovs_key_attr) type) {
     case OVS_KEY_ATTR_ENCAP: return -2;
     case OVS_KEY_ATTR_PRIORITY: return 4;
+    case OVS_KEY_ATTR_SKB_MARK: return 4;
     case OVS_KEY_ATTR_TUN_ID: return 8;
     case OVS_KEY_ATTR_IPV4_TUNNEL: return sizeof(struct ovs_key_ipv4_tunnel);
     case OVS_KEY_ATTR_IN_PORT: return 4;
@@ -813,6 +815,7 @@ format_odp_key_attr(const struct nlattr *a, struct ds *ds)
         break;
     }
 
+    case OVS_KEY_ATTR_SKB_MARK:
     case OVS_KEY_ATTR_UNSPEC:
     case __OVS_KEY_ATTR_MAX:
     default:
-- 
1.7.9.5

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to