[ovs-dev] [PATCH 09/11] datapath: Pass more packet metadata to userspace.
Jarno Rajahalme
jarno.rajahalme at nsn.com
Mon Feb 11 14:46:25 UTC 2013
Signed-off-by: Jarno Rajahalme <jarno.rajahalme at 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
More information about the dev
mailing list