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

Reply via email to