Signed-off-by: Jarno Rajahalme <jarno.rajaha...@nsn.com>
---
 datapath/datapath.c |   19 ++++++++++++++++++-
 datapath/flow.c     |   15 +++++++++++++--
 datapath/flow.h     |    5 +++--
 3 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/datapath/datapath.c b/datapath/datapath.c
index 2e01740..81b1d53 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -374,8 +374,9 @@ static int queue_userspace_packet(struct net *net, int 
dp_ifindex,
        len = sizeof(struct ovs_header);
        len += nla_total_size(skb->len);
        len += nla_total_size(FLOW_BUFSIZE);
+       len += 3 * nla_total_size(4); /* packet offsets */
        if (upcall_info->cmd == OVS_PACKET_CMD_ACTION)
-               len += nla_total_size(8);
+               len += nla_total_size(8); /* possible USERDATA */
 
        user_skb = genlmsg_new(len, GFP_ATOMIC);
        if (!user_skb) {
@@ -391,6 +392,22 @@ static int queue_userspace_packet(struct net *net, int 
dp_ifindex,
        ovs_flow_key_to_nlattrs(upcall_info->key, user_skb);
        nla_nest_end(user_skb, nla);
 
+       {
+               u32 l3_offset = skb_network_offset(skb);
+               u32 l4_offset = skb_transport_offset(skb);
+
+               nla_put_u32(user_skb, OVS_PACKET_ATTR_L2_SIZE, l3_offset);
+               nla_put_u32(user_skb, OVS_PACKET_ATTR_L3_OFFSET, l3_offset);
+
+               /* Set the L4 offset attribute only if transport offset is
+                * valid. */
+               if ((upcall_info->key->eth.type == htons(ETH_P_IP)
+                    || upcall_info->key->eth.type == htons(ETH_P_IPV6))
+                   && l4_offset > l3_offset)
+                       nla_put_u32(user_skb, OVS_PACKET_ATTR_L4_OFFSET,
+                                   l4_offset);
+       }
+
        if (upcall_info->userdata)
                nla_put_u64(user_skb, OVS_PACKET_ATTR_USERDATA,
                            nla_get_u64(upcall_info->userdata));
diff --git a/datapath/flow.c b/datapath/flow.c
index 4c85e81..e3185aa 100644
--- a/datapath/flow.c
+++ b/datapath/flow.c
@@ -856,6 +856,7 @@ const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
 
        /* Not upstream. */
        [OVS_KEY_ATTR_TUN_ID] = sizeof(__be64),
+       [OVS_KEY_ATTR_HASH] = sizeof(u32),
 };
 
 static int ipv4_flow_from_nlattrs(struct sw_flow_key *swkey,
@@ -1279,11 +1280,17 @@ int ovs_flow_key_from_nlattrs(struct sw_flow_key *swkey,
                memcpy(swkey->ipv4.arp.tha, arp_key->arp_tha, ETH_ALEN);
        }
 
+       /* Userspace provides the hash back to us only when the key
+        * has been unmodified. */
+       if (attrs & (1ULL << OVS_KEY_ATTR_HASH)) {
+               swkey->hash = nla_get_u32(a[OVS_KEY_ATTR_HASH]);
+               attrs &= ~(1ULL << OVS_KEY_ATTR_HASH);
+       } else
+               swkey->hash = ovs_flow_hash(swkey, flow_key_start(swkey));
+
        if (attrs)
                return -EINVAL;
 
-       swkey->hash = ovs_flow_hash(swkey, flow_key_start(swkey));
-
        return 0;
 }
 
@@ -1389,6 +1396,10 @@ int ovs_flow_key_to_nlattrs(const struct sw_flow_key 
*swkey, struct sk_buff *skb
        struct ovs_key_ethernet *eth_key;
        struct nlattr *nla, *encap;
 
+       /* Put hash first so that it is easy to find or ignore */
+       if (nla_put_u32(skb, OVS_KEY_ATTR_HASH, swkey->hash))
+               goto nla_put_failure;
+
        if (swkey->phy.priority &&
            nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, swkey->phy.priority))
                goto nla_put_failure;
diff --git a/datapath/flow.h b/datapath/flow.h
index dc9c000..5491fd0 100644
--- a/datapath/flow.h
+++ b/datapath/flow.h
@@ -187,10 +187,11 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies);
  *  OVS_KEY_ATTR_IPV6                   40    --     4     44
  *  OVS_KEY_ATTR_ICMPV6                  2     2     4      8
  *  OVS_KEY_ATTR_ND                     28    --     4     32
+ *  OVS_KEY_ATTR_HASH                    4    --     4      8
  *  ----------------------------------------------------------
- *  total                                                 220
+ *  total                                                 228
  */
-#define FLOW_BUFSIZE 220
+#define FLOW_BUFSIZE 228
 
 int ovs_flow_key_to_nlattrs(const struct sw_flow_key *, struct sk_buff *);
 int ovs_flow_key_from_nlattrs(struct sw_flow_key *,
-- 
1.7.10.4

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

Reply via email to