summaryrefslogtreecommitdiff
path: root/net/openvswitch/flow.c
diff options
context:
space:
mode:
authorJesse Gross <jesse@nicira.com>2014-10-03 15:35:33 -0700
committerDavid S. Miller <davem@davemloft.net>2014-10-06 00:32:21 -0400
commitf5796684069e0c71c65bce6a6d4766114aec1396 (patch)
treea4906c8cba2b6c2d116e7b72a71f9e1020b476cb /net/openvswitch/flow.c
parent6b205b2ca17e88ef5e10451b720056b790cc63a5 (diff)
openvswitch: Add support for Geneve tunneling.
The Openvswitch implementation is completely agnostic to the options that are in use and can handle newly defined options without further work. It does this by simply matching on a byte array of options and allowing userspace to setup flows on this array. Signed-off-by: Jesse Gross <jesse@nicira.com> Singed-off-by: Ansis Atteka <aatteka@nicira.com> Signed-off-by: Andy Zhou <azhou@nicira.com> Acked-by: Thomas Graf <tgraf@noironetworks.com> Acked-by: Pravin B Shelar <pshelar@nicira.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/openvswitch/flow.c')
-rw-r--r--net/openvswitch/flow.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 2924cb340868..62db02ba36bc 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -448,6 +448,9 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
int error;
struct ethhdr *eth;
+ /* Flags are always used as part of stats */
+ key->tp.flags = 0;
+
skb_reset_mac_header(skb);
/* Link layer. We are guaranteed to have at least the 14 byte Ethernet
@@ -646,10 +649,23 @@ int ovs_flow_key_extract(struct ovs_tunnel_info *tun_info,
struct sk_buff *skb, struct sw_flow_key *key)
{
/* Extract metadata from packet. */
- if (tun_info)
+ if (tun_info) {
memcpy(&key->tun_key, &tun_info->tunnel, sizeof(key->tun_key));
- else
+
+ if (tun_info->options) {
+ BUILD_BUG_ON((1 << (sizeof(tun_info->options_len) *
+ 8)) - 1
+ > sizeof(key->tun_opts));
+ memcpy(GENEVE_OPTS(key, tun_info->options_len),
+ tun_info->options, tun_info->options_len);
+ key->tun_opts_len = tun_info->options_len;
+ } else {
+ key->tun_opts_len = 0;
+ }
+ } else {
+ key->tun_opts_len = 0;
memset(&key->tun_key, 0, sizeof(key->tun_key));
+ }
key->phy.priority = skb->priority;
key->phy.in_port = OVS_CB(skb)->input_vport->port_no;