summaryrefslogtreecommitdiff
path: root/lib/meta-flow.c
diff options
context:
space:
mode:
authorJesse Gross <jesse@nicira.com>2015-04-30 18:09:57 -0700
committerJesse Gross <jesse@nicira.com>2015-06-25 11:08:58 -0700
commit9558d2a548e18fc520c282399ff403639887173d (patch)
tree3716cf08e4b20f05a9b9dd2fa6be9d0564caf6f0 /lib/meta-flow.c
parentec1f6f327e379723f5af4eefa46da49f92753976 (diff)
downloadopenvswitch-9558d2a548e18fc520c282399ff403639887173d.tar.gz
tunnel: Geneve TLV handling support for OpenFlow.
The current support for Geneve in OVS is exactly equivalent to VXLAN: it is possible to set and match on the VNI but not on any options contained in the header. This patch enables the use of options. The goal for Geneve support is not to add support for any particular option but to allow end users or controllers to specify what they would like to match. That is, the full range of Geneve's capabilities should be exposed without modifying the code (the one exception being options that require per-packet computation in the fast path). The main issue with supporting Geneve options is how to integrate the fields into the existing OpenFlow pipeline. All existing operations are referred to by their NXM/OXM field name - matches, action generation, arithmetic operations (i.e. tranfer to a register). However, the Geneve option space is exactly the same as the OXM space, so a direct mapping is not feasible. Instead, we create a pool of 64 NXMs that are then dynamically mapped on Geneve option TLVs using OpenFlow. Once mapped, these fields become first-class citizens in the OpenFlow pipeline. An example of how to use Geneve options: ovs-ofctl add-geneve-map br0 {class=0xffff,type=0,len=4}->tun_metadata0 ovs-ofctl add-flow br0 in_port=LOCAL,actions=set_field:0xffffffff->tun_metadata0,1 This will add a 4 bytes option (filled will all 1's) to all packets coming from the LOCAL port and then send then out to port 1. A limitation of this patch is that although the option table is specified for a particular switch over OpenFlow, it is currently global to all switches. This will be addressed in a future patch. Based on work originally done by Madhu Challa. Ben Pfaff also significantly improved the comments. Signed-off-by: Madhu Challa <challa@noironetworks.com> Signed-off-by: Jesse Gross <jesse@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'lib/meta-flow.c')
-rw-r--r--lib/meta-flow.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index 55b2c6559..21a13b479 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -33,6 +33,7 @@
#include "random.h"
#include "shash.h"
#include "socket-util.h"
+#include "tun-metadata.h"
#include "unaligned.h"
#include "util.h"
#include "openvswitch/vlog.h"
@@ -189,6 +190,12 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
return !wc->masks.tunnel.gbp_id;
case MFF_TUN_GBP_FLAGS:
return !wc->masks.tunnel.gbp_flags;
+ CASE_MFF_TUN_METADATA: {
+ union mf_value value;
+
+ tun_metadata_read(&wc->masks.tunnel.metadata, mf, &value);
+ return is_all_zeros(&value.tun_metadata, mf->n_bytes);
+ }
case MFF_METADATA:
return !wc->masks.metadata;
case MFF_IN_PORT:
@@ -480,6 +487,7 @@ mf_is_value_valid(const struct mf_field *mf, const union mf_value *value)
case MFF_TUN_FLAGS:
case MFF_TUN_GBP_ID:
case MFF_TUN_GBP_FLAGS:
+ CASE_MFF_TUN_METADATA:
case MFF_METADATA:
case MFF_IN_PORT:
case MFF_SKB_PRIORITY:
@@ -602,6 +610,9 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
case MFF_TUN_TOS:
value->u8 = flow->tunnel.ip_tos;
break;
+ CASE_MFF_TUN_METADATA:
+ tun_metadata_read(&flow->tunnel.metadata, mf, value);
+ break;
case MFF_METADATA:
value->be64 = flow->metadata;
@@ -816,6 +827,9 @@ mf_set_value(const struct mf_field *mf,
case MFF_TUN_TTL:
match_set_tun_ttl(match, value->u8);
break;
+ CASE_MFF_TUN_METADATA:
+ tun_metadata_set_match(mf, value, NULL, match);
+ break;
case MFF_METADATA:
match_set_metadata(match, value->be64);
@@ -1098,6 +1112,8 @@ mf_set_flow_value(const struct mf_field *mf,
case MFF_TUN_TTL:
flow->tunnel.ip_ttl = value->u8;
break;
+ CASE_MFF_TUN_METADATA:
+ tun_metadata_write(&flow->tunnel.metadata, mf, value);
case MFF_METADATA:
flow->metadata = value->be64;
@@ -1362,6 +1378,9 @@ mf_set_wild(const struct mf_field *mf, struct match *match)
case MFF_TUN_TTL:
match_set_tun_ttl_masked(match, 0, 0);
break;
+ CASE_MFF_TUN_METADATA:
+ tun_metadata_set_match(mf, NULL, NULL, match);
+ break;
case MFF_METADATA:
match_set_metadata_masked(match, htonll(0), htonll(0));
@@ -1616,6 +1635,9 @@ mf_set(const struct mf_field *mf,
case MFF_TUN_TOS:
match_set_tun_tos_masked(match, value->u8, mask->u8);
break;
+ CASE_MFF_TUN_METADATA:
+ tun_metadata_set_match(mf, value, mask, match);
+ break;
case MFF_METADATA:
match_set_metadata_masked(match, value->be64, mask->be64);