diff options
author | Jesse Gross <jesse@kernel.org> | 2016-04-19 18:36:04 -0700 |
---|---|---|
committer | Jesse Gross <jesse@kernel.org> | 2016-09-19 09:52:22 -0700 |
commit | 8d8ab6c2d5743eb229a5e7c27ccd963a2c103adb (patch) | |
tree | d198a78ddf968ab119e029ca998eba2337812cd8 /lib/dpif-netdev.c | |
parent | 56fb20c4a1622c0f19bd2865c6688bdc78d5b40f (diff) | |
download | openvswitch-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.c | 65 |
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 |