summaryrefslogtreecommitdiff
path: root/lib/dpif-netdev.c
diff options
context:
space:
mode:
authorJesse Gross <jesse@kernel.org>2016-04-19 18:36:04 -0700
committerJesse Gross <jesse@kernel.org>2016-09-19 09:52:22 -0700
commit8d8ab6c2d5743eb229a5e7c27ccd963a2c103adb (patch)
treed198a78ddf968ab119e029ca998eba2337812cd8 /lib/dpif-netdev.c
parent56fb20c4a1622c0f19bd2865c6688bdc78d5b40f (diff)
downloadopenvswitch-8d8ab6c2d5743eb229a5e7c27ccd963a2c103adb.tar.gz
tun-metadata: Manage tunnel TLV mapping table on a per-bridge basis.
When using tunnel TLVs (at the moment, this means Geneve options), a controller must first map the class and type onto an appropriate OXM field so that it can be used in OVS flow operations. This table is managed using OpenFlow extensions. The original code that added support for TLVs made the mapping table global as a simplification. However, this is not really logically correct as the OpenFlow management commands are operating on a per-bridge basis. This removes the original limitation to make the table per-bridge. One nice result of this change is that it is generally clearer whether the tunnel metadata is in datapath or OpenFlow format. Rather than allowing ad-hoc format changes and trying to handle both formats in the tunnel metadata functions, the format is more clearly separated by function. Datapaths (both kernel and userspace) use datapath format and it is not changed during the upcall process. At the beginning of action translation, tunnel metadata is converted to OpenFlow format and flows and wildcards are translated back at the end of the process. As an additional benefit, this change improves performance in some flow setup situations by keeping the tunnel metadata in the original packet format in more cases. This helps when copies need to be made as the amount of data touched is only what is present in the packet rather than the maximum amount of metadata supported. Co-authored-by: Madhu Challa <challa@noironetworks.com> Signed-off-by: Madhu Challa <challa@noironetworks.com> Signed-off-by: Jesse Gross <jesse@kernel.org> Acked-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'lib/dpif-netdev.c')
-rw-r--r--lib/dpif-netdev.c65
1 files changed, 4 insertions, 61 deletions
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index ecc7cea8d..6e09e44eb 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -2117,8 +2117,7 @@ dpif_netdev_mask_from_nlattrs(const struct nlattr *key, uint32_t key_len,
{
enum odp_key_fitness fitness;
- fitness = odp_flow_key_to_mask_udpif(mask_key, mask_key_len, key,
- key_len, wc, flow);
+ fitness = odp_flow_key_to_mask(mask_key, mask_key_len, wc, flow);
if (fitness) {
/* This should not happen: it indicates that
* odp_flow_key_from_mask() and odp_flow_key_to_mask()
@@ -2149,7 +2148,7 @@ dpif_netdev_flow_from_nlattrs(const struct nlattr *key, uint32_t key_len,
{
odp_port_t in_port;
- if (odp_flow_key_to_flow_udpif(key, key_len, flow)) {
+ if (odp_flow_key_to_flow(key, key_len, flow)) {
/* This should not happen: it indicates that odp_flow_key_from_flow()
* and odp_flow_key_to_flow() disagree on the acceptable form of a
* flow. Log the problem as an error, with enough details to enable
@@ -3784,27 +3783,11 @@ dp_netdev_upcall(struct dp_netdev_pmd_thread *pmd, struct dp_packet *packet_,
struct ofpbuf *actions, struct ofpbuf *put_actions)
{
struct dp_netdev *dp = pmd->dp;
- struct flow_tnl orig_tunnel;
- int err;
if (OVS_UNLIKELY(!dp->upcall_cb)) {
return ENODEV;
}
- /* Upcall processing expects the Geneve options to be in the translated
- * format but we need to retain the raw format for datapath use. */
- orig_tunnel.flags = flow->tunnel.flags;
- if (flow->tunnel.flags & FLOW_TNL_F_UDPIF) {
- orig_tunnel.metadata.present.len = flow->tunnel.metadata.present.len;
- memcpy(orig_tunnel.metadata.opts.gnv, flow->tunnel.metadata.opts.gnv,
- flow->tunnel.metadata.present.len);
- err = tun_metadata_from_geneve_udpif(&orig_tunnel, &orig_tunnel,
- &flow->tunnel);
- if (err) {
- return err;
- }
- }
-
if (OVS_UNLIKELY(!VLOG_DROP_DBG(&upcall_rl))) {
struct ds ds = DS_EMPTY_INITIALIZER;
char *packet_str;
@@ -3831,48 +3814,8 @@ dp_netdev_upcall(struct dp_netdev_pmd_thread *pmd, struct dp_packet *packet_,
ds_destroy(&ds);
}
- err = dp->upcall_cb(packet_, flow, ufid, pmd->core_id, type, userdata,
- actions, wc, put_actions, dp->upcall_aux);
- if (err && err != ENOSPC) {
- return err;
- }
-
- /* Translate tunnel metadata masks to datapath format. */
- if (wc) {
- if (wc->masks.tunnel.metadata.present.map) {
- struct geneve_opt opts[TLV_TOT_OPT_SIZE /
- sizeof(struct geneve_opt)];
-
- if (orig_tunnel.flags & FLOW_TNL_F_UDPIF) {
- tun_metadata_to_geneve_udpif_mask(&flow->tunnel,
- &wc->masks.tunnel,
- orig_tunnel.metadata.opts.gnv,
- orig_tunnel.metadata.present.len,
- opts);
- } else {
- orig_tunnel.metadata.present.len = 0;
- }
-
- memset(&wc->masks.tunnel.metadata, 0,
- sizeof wc->masks.tunnel.metadata);
- memcpy(&wc->masks.tunnel.metadata.opts.gnv, opts,
- orig_tunnel.metadata.present.len);
- }
- wc->masks.tunnel.metadata.present.len = 0xff;
- }
-
- /* Restore tunnel metadata. We need to use the saved options to ensure
- * that any unknown options are not lost. The generated mask will have
- * the same structure, matching on types and lengths but wildcarding
- * option data we don't care about. */
- if (orig_tunnel.flags & FLOW_TNL_F_UDPIF) {
- memcpy(&flow->tunnel.metadata.opts.gnv, orig_tunnel.metadata.opts.gnv,
- orig_tunnel.metadata.present.len);
- flow->tunnel.metadata.present.len = orig_tunnel.metadata.present.len;
- flow->tunnel.flags |= FLOW_TNL_F_UDPIF;
- }
-
- return err;
+ return dp->upcall_cb(packet_, flow, ufid, pmd->core_id, type, userdata,
+ actions, wc, put_actions, dp->upcall_aux);
}
static inline uint32_t