On Tue, Jul 07, 2015 at 10:30:05PM -0700, Jesse Gross wrote: > The kernel implementation of Geneve options stores the TLV option > data in the flow exactly as received, without any further parsing. > This is then translated to known options for the purposes of matching > on flow setup (which will then install a datapath flow in the form > the kernel is expecting). > > The userspace implementation behaves a little bit differently - it > looks up known options as each packet is received. The reason for this > is there is a much tighter coupling between datapath and flow translation > and the representation is generally expected to be the same. This works > but it incurs work on a per-packet basis that could be done per-flow > instead. > > This introduces a small translation step for Geneve packets between > datapath and flow lookup for the userspace datapath in order to > allow the same kind of processing that the kernel does. > > Signed-off-by: Jesse Gross <je...@nicira.com>
Here's a comment for struct tun_metadata with a little more detail, to try to make sure I understand it correctly: /* Tunnel option data, plus metadata to aid in their interpretation. * * Option data exists in two forms. Most of the time, the code path we're in * determines which form is in use; in the occasional case where there is * ambiguity, code can distinguish based on whether 'tab' is nonnull. The * two cases are: * * - In places where we are doing per-packet fast path processing * (i.e. userspace datapath), 'opts.gnv' is raw packet data from the * tunnel header and 'present.len' indicates the length of the data * stored there. 'tab' is NULL. * * - In all other cases, we are doing flow-based processing (such as during * upcalls) and options are reordered into pre-allocated locations. * 'present.map' is indexed by type, that is, by the <i> in * TUN_METADATA<i>, so that e.g. TUN_METADATA5 is present if 'present.map * & (1ULL << 5)' is nonzero. The actual data for TUN_METADATA5, if * present, might be anywhere in 'opts.u8' (not necessarily even * contiguous), and finding it requires referring to 'tab', which is * nonnull. */ Similarly for struct odp_flow_key_parms: /* Some fields have different representation for flow setup and per- * packet processing (i.e. different between ofproto-dpif and userspace * datapath). This flag indicates that these fields are already in the * per-packet format rather than per-flow, which is the normal input. * In particular, if false, the struct tun_metadata in the input flow is * in the per-flow format (using 'present.map' and 'opts.u8'); if true, * struct tun_metadata is in the per-packet format (using 'present.len' * and 'opts.gnv'). */ bool udpif_no_xlate; Do we need 'udpif_no_xlate'? That is, can odp_flow_key_from_flow() check whether flow->tun.metadata.tab != NULL to distinguish the cases? s/uncoverted/unconverted/ (or maybe just s/uncoverted/raw/) in comment on tun_metadata_from_geneve_header(). dpif_netdev_mask_from_nlattrs() adds an extra blank line before } else { Acked-by: Ben Pfaff <b...@nicira.com> _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev