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 <[email protected]>
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 <[email protected]>
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev