Track number of ethernet vlans in a frame 73/873/8
authorChris Luke <chrisy@flirble.org>
Mon, 25 Apr 2016 18:26:55 +0000 (14:26 -0400)
committerDave Barach <openvpp@barachs.net>
Thu, 28 Apr 2016 11:37:30 +0000 (11:37 +0000)
commit194ebc58b6e362c7cc950ba2386567bfdbfbab55
tree927dd4fe75586d31b1adf2a2e12c47228db0dddf
parent473bf23be85e861f95d69992b09b0b7d7a6efa2e
Track number of ethernet vlans in a frame

Adds flags to the packet buffer to track the number of VLANs in
the current Ethernet frame. We use two bits to signify 0, 1 or
2 VLANs. The value 3 signififies an unknown quantity of VLANs,
which includes "three or more" which is not widely supported.
We place the bits in the vlib_buffer section; that is not the
opaque section, so that all subordinate nodes can use it.

For background, see the discussion thread at
https://lists.fd.io/pipermail/vpp-dev/2016-March/000354.html

The helper macro ethernet_buffer_header_size(buffer) uses
these bits stored in "buffer" to calculate the Ethernet header
size.

The macro ethernet_buffer_set_vlan_count(buffer, count) sets the
appropriate bit values based on the number in "count".

By current frame we are referring to the case where a packet
that arrives from the wire is carrying an encapsulated Ethernet
packet. Once decapsulated that inner packet becomes the current
frame.

There are two places where this value is set; For most Ethernet
frames this will be in the "ethernet-input" node when that node
parses the Ethernet header. The second place is whenever
vnet_update_l2_len() is used to update the layer 2 opaque data.
Typically this function is used by nodes just before they send
a packet into l2-input.

These bits are zeroed in vlib_buffer_init_for_free_list()
meaning that wherever the buffer comes from they have a reasonable
value (eg, if ip4/ip6 generates the packet.)

Primarily this VLAN counter is used by nodes below "ethernet-
input" and "l2-input" to determine where the start of the
current Ethernet header is. There is opaque data set by
"ethernet-input" storing the offset of the current Ethernet
header but, since this is opaque, it's not usable by downstream
nodes. Previously several nodes have made assumptions regarding
the location of the Ethernet header, including that it is always
at the start of the packet buffer (incorrect when we have
encapsulated packets) or that it is exactly
sizeof(ethernet_header_t) away (incorrect when we have VLAN tags.)

One notable case where this functionality is required is in
ip6_neighbor when it generates a response to a received neighbor
soliciation request; it reuses the incoming Ethernet header
in-situ and thus needs to reliably know where that header begins.

Also, at the suggestion of Dave Barach, this patch removes
definition of HGSHM bits in the buffer flags since they are
unused and unlikely to ever be.

Change-Id: I00e4b9ced5ef814a776020c395d1774aba6185b3
Signed-off-by: Chris Luke <chrisy@flirble.org>
vlib/vlib/buffer.h
vnet/vnet/buffer.h
vnet/vnet/classify/ip_classify.c
vnet/vnet/dhcpv6/proxy_node.c
vnet/vnet/ethernet/ethernet.h
vnet/vnet/ethernet/node.c
vnet/vnet/ip/ip6_neighbor.c
vnet/vnet/l2/l2_input.h
vnet/vnet/l2/l2_vtr.h