odp: Use encap() for MPLS-encapsulated ODP flow key data

This patch has two components:

1. odp_flow_key_from_flow() is updated to extract encapsulated frame
   information from MPLS flows. It does this by encoding the encapsualted
   frame in an encap() in the resulting ODP key data.

   A subsequent patch will introduce code to set flow->encap_dl_type
   which will activate this change.

2. Update parse_l2_5_onward() to read an MPLS-encapsulated frame
   from inside encap() in ODP key data. This consumes ODP key data
   produced by odp_flow_key_from_flow().

   before: eth(...), eth_type(0x8847), mpls(...), ip(...), tcp(...)
   after: eth(...), eth_type(0x8847), mpls(...), encap(ip(...), tcp(...))

The use of encap() for MPLS-encapsulated frames was suggested by Ben Pfaff
and seems to be in keeping with datapath/README.

Signed-off-by: Simon Horman <horms@verge.net.au>

---

v2.20 (draft)
* Squash "Update parse_l2_5_onward to use encap for MPLS" and
  "odp_flow_key_from_flow: Allow of encapsulated frames" and
  rename the result "odp: Use encap() for MPLS-encapsulated ODP flow key data".

v2.19
* As suggested by Ben Pfaff
  - Remove encap_dl_type parameter from odp_flow_key_from_flow()
  - Use encap for mpls in ODP flow key data.
    before: eth(...), eth_type(0x8847), mpls(...), ip(...), tcp(...)
    after: eth(...), eth_type(0x8847), mpls(...), encap(ip(...), tcp(...))
* Coding style fix for actions_allow_l3_extraction().
  Use {} in conjunction with if statements.
* Enhance actions_allow_l3_extraction to return when the first MPLS_PUSH
  action with a non-MPLS ether type is found rather than when the first
  MPLS_PUSH action is found.
* Remove actions_allow_l3_extraction() and obtain encap_dl_type
  from xlate_actions() instead.
* Removed non-odp_flow_key_from_flow portions.
  These are now present in ofproto: Allow richer matches based on actions().
* Rename patch from
  "actions: Allow secondary decoding of a flow" to
  "actions: odp_flow_key_from_flow: Allow of encapsulated frames"

v2.18
* Update odp_flow_key_from_flow() to use dl_type_is_ip_any() wrapper.
  As odp_flow_key_from_flow() is paramatised over encap_dl_type
  this seems to be a good approach.

v2.17
* Rebase

v2.13 - v2.16
* No change

v2.12
* As suggested by Jarno Rajahalme
  - Use flow->encap_dl_type instead of of obtaining the value
    by scanning the actions.

v2.11
* First post
ofproto-dpif: Make packet element of action_xlate_ctx non-const

This is in preparation for allowing do_xlate_actions to decode flow
information from a packet, thus updating the packet.

Signed-off-by: Simon Horman <horms+renesas@verge.net.au>

---

v2.19
* Initial post
ofproto: Allow richer matches based on actions

If the actions of a flow allow further decoding of L3 and L4 data to
provide a richer match then use this richer match.

For example:

In the case of MPLS, L3 and L4 information may not initially be decoded
from the frame as the ethernet type of the frame is an MPLS type and no
information is known about the type of the inner frame.

However, the type of the inner frame may be provided by an mpls_pop action
in which case L3 and L4 information may be decoded providing a finer
grained match than is otherwise possible.

Signed-off-by: Simon Horman <horms@verge.net.au>

---

v2.19
* As suggested by Ben Pfaff
  - Obtain decode inner_flow in xlate_actions() as it is able to take
    into account resubmit actions.
* Correct typo in comment in flow_miss_is_singleton()
* Update for removal of encap_dl_type parameter from odp_flow_key_from_flow()
* Squashed the non-odp_flow_key_from_flow portions of
  "actions: Allow secondary decoding of a flow"
* Changed patch name from
  "ofproto: Allow actions richer matches based on actions" to
  "ofproto: Allow richer matches based on actions"

v2.16 - v2.18
* No change

v2.15
* Rebase for ovs_assert

v2.14
* No change

v2.13
* Correct indentation in handle_flow_miss_l3_extraction()
* Rebase: Pass encap_dl_type argument to flow_extract_l3_onwards()

v2.12
* Use eth_type_mpls helper
* As suggested by Jarno Rajahalme
  - Use flow->encap_dl_type instead of of obtaining the value
    by scanning the actions.

v2.11
* First post
dpif-netdev: Inner And Outer Flows

This is the user-space datapath component of this change

Allow a flow to be visible in two forms, an outer flow and an inner flow.
This may occur if the actions allow further decoding of a packet to
provide a more fine-grained match. In this case the first-pass
coarse-grained match will hit the outer-flow and the second-pass
fined-grained match will hit the inner-flow.

Inner-flows are not visible to user-space. Rather, they are just an
internal representation to handle the case of actions allowing further
packet decoding. An inner-flow is associated with its outer-flow and
deleted when the outer-flow is deleted. An outer-flow may have more than
one inner-flow but an inner-flow may only have one outer-flow.

For example:

In the case of MPLS, L3 and L4 information may not initially be decoded
from the frame as the ethernet type of the frame is an MPLS type and no
information is known about the type of the inner frame.

However, the type of the inner frame may be provided by an mpls_pop action
in which case L3 and L4 information may be decoded providing a finer
grained match than is otherwise possible.

Signed-off-by: Simon Horman <horms@verge.net.au>

---

v2.19
* Update dpif_netdev_actions_allow_l3_extraction() to so that
  it returns when it finds the first MPLS_POP action with a
  non-MPLS type rather than the first MPLS_POP action.

v2.18
* Update match_wc_init() to use dl_type_is_ip_any()

v2.14 - v2.17
* No change

v2.13
* First post

enhance dpif_netdev_actions_allow_l3_extraction
Add support for dec_mpls_ttl action

This adds support for the OpenFlow 1.1+ dec_mpls_ttl action.
And also adds an NX dec_mpls_ttl action.

The handling of the TTL modification is entirely handled in userspace.

Reviewed-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Simon Horman <horms@verge.net.au>

---

v2.18 - v2.19
* No change

v2.17
* Rebase
* As suggested by Ben Pfaff
  - Use consistent terminology for MPLS.
    + Consistently refer to the MPLS component of a packet as the
      MPLS label stack and entries in the stack as MPLS label stack entries
      (LSE).  An MPLS label is a component of an MPLS label stack entry.
      The other components are the traffic class (TC), time to live (TTL)
      and bottom of stack (BoS) bit.
  - Rename compose_dec_mpls_ttl_action as execute_dec_mpls_ttl_action

v2.13 - v2.16
* No change

v2.12
* Use eth_type_mpls() helper

v2.11 - v2.10
* No change

v2.9
* Update tests for upstream changes

v2.8
* No change

v2.7
* Encode action as OFP11 action in OFP11+ messages

v2.6
* Rebase

v2.5
* First post
Add support for set_mpls_ttl action

This adds support for the OpenFlow 1.1+ set_mpls_ttl action.
And also adds an NX set_mpls_ttl action.

The handling of the TTL modification is entirely handled in userspace.

Reviewed-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Simon Horman <horms@verge.net.au>

---

v2.19
* If a SET_MPLS_TTL action can't be processed
  then stop processing the flow's actions.

v2.18
* No change

v2.17
* As suggested by Ben Pfaff
  - Use consistent terminology for MPLS.
    + Consistently refer to the MPLS component of a packet as the
      MPLS label stack and entries in the stack as MPLS label stack entries
      (LSE).  An MPLS label is a component of an MPLS label stack entry.
      The other components are the traffic class (TC), time to live (TTL)
      and bottom of stack (BoS) bit.
  - Rename compose_set_mpls_ttl_action as execute_set_mpls_ttl_action

v2.13 - v2.16
* No change

v2.12
* Use eth_type_mpls() helper

v2.11
* No change

v2.10
* Check the size of nx_action_mpls_ttl.
  nx_action_pop_mpls was being checked
  due to a cut-and-paste error

v2.9
* Update tests for upstream changes

v2.8
* No change

v2.7
* Encode action as OFP11 action in OFP11+ messages

v2.6
* Rebase

v2.5
* First post
Add support for copy_ttl_out action

This adds support for the OpenFlow 1.1+ copy_ttl_out action.
And also adds an NX copy_ttl_out action.

The implementation does not support copying in the case where the outermost
header is IP as it is unclear to me that Open vSwtich has a notion of an
inner IP header to copy the TLL from.

The handling of the TTL modification is entirely handled in userspace.

Reviewed-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Simon Horman <horms@verge.net.au>

---

v2.19
* If a COPY_TTL_OUT action can't be processed
  then stop processing the flow's actions.

v2.18
* No change

v2.17
* Rebase
  - Update FLOW_WC_SEQ in compose_output_action__()
* As suggested by Ben Pfaff
  - Rename compose_copy_ttl_out_action as execute_copy_ttl_out_action

v2.16
* No change

v2.15
* Rebase
* Mask off wc.masks.mpls_inner_lse in ofputil_normalize_match__()

v2.14
* No change

v2.13
* Remove bogus test. copy_ttl_out from IP to MPLS only makes sense
  if the dl_type of the encapsulated frame is known, which implies
  that the original frame was IP and an mpls_push action has been applied.

v2.10 - v2.12
* No change

v2.9
* Increment FLOW_WC_SEQ
* Update tests for upstream changes

v2.8
* No change

v2.7
* Encode action as OFP11 action in OFP11+ messages

v2.6
* Non-trivial rebase

v2.5
* First post
Add support for copy_ttl_in action

This adds support for the OpenFlow 1.1+ copy_ttl_in action.
And also adds an NX copy_ttl_out action.

The implementation does not support copying in the case where the outermost
header is IP as it is unclear to me that Open vSwtich has a notion of an
inner IP header to copy the TLL from.

The implementation does not support copying in the case where the
outermost and next-to-otermost header is MPLS due to limitations
in the current MPLS implementation which only supports modifying
the outermost MPLS header.

The handling of the TTL modification is entirely handled in userspace.

Reviewed-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Simon Horman <horms@verge.net.au>

---

v2.19
* Rebase
* Do not allow setting of TTL to zero
* Treat this and other illegal conditions
  as grounds to stop a flow's actions.
* Update to preserve nw_ttl on execute_mpls_pop_action()
  This is needed now that prior patches use xlate_actions
  for l3 decoding of MPLS frames.
* Update test to use encap()

v2.18
* No change

v2.17
* As suggested by Ben Pfaff
  - Rename execute_copy_ttl_in_action functions as compose_copy_ttl_in_action

v2.13 - v2.16
* No change

v2.12
* Rebase
* Use eth_type_mpls() helper

v2.10 - v2.11
* No change

v2.9
* Update tests for upstream changes

v2.8
* No change

v2.7
* Correct typo in changelog
* Encode action as OFP11 action in OFP11+ messages

v2.6
* Non-trivial rebase

v2.5
* First post
datapath: Add basic MPLS support to kernel

Allow datapath to recognize and extract MPLS labels into flow keys
and execute actions which push, pop, and set labels on packets.

Based heavily on work by Leo Alterman and Ravi K.

Cc: Ravi K <rkerur@gmail.com>
Cc: Leo Alterman <lalterman@nicira.com>
Reviewed-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Simon Horman <horms@verge.net.au>

---

v2.18 - v2.19
* No change

v2.17
* As suggested by Ben Pfaff
  - Use consistent terminology for MPLS.
    + Consistently refer to the MPLS component of a packet as the
      MPLS label stack and entries in the stack as MPLS label stack entries
      (LSE).  An MPLS label is a component of an MPLS label stack entry.
      The other components are the traffic class (TC), time to live (TTL)
      and bottom of stack (BoS) bit.
  - Rename compose_.*mpls_ functions as execute_.*mpls_

v2.16
* No change

v2.15
* As suggested by Ben Pfaff
  - Use OVS_ACTION_SET to set OVS_KEY_ATTR_MPLS instead of
    OVS_ACTION_ATTR_SET_MPLS

v2.14
* Remove include/linux/openvswitch.h portion which added add
  new key and action attributes. This
  now present in "User-Space MPLS actions and matches"
  which is now a dependency of this patch

v2.13
* As suggested by Jarno Rajahalme
  - Rename mpls_bos element of ovs_skb_cb as l2_size as it is set and used
    regardless of if an MPLS stack is present or not. Update the name of
    helper functions and documentation accordingly.
  - Ensure that skb_cb_mpls_bos() never returns NULL
* Correct endieness in eth_p_mpls()

v2.12
* Update skb and network header on MPLS extraction in ovs_flow_extract()
* Use NULL in skb_cb_mpls_bos()
* Add eth_p_mpls helper

v2.10 - v2.11
* No change

v2.9
* datapath: Always update the mpls bos if  vlan_pop is successful

  Regardless of the details of how a successful
  vlan_pop is achieved, the mpls bos needs to be updated.

  Without this fix it has been observed that the following
  results in malformed packets

v2.8
* No change

v2.7
* Rebase

v2.6
* As suggested by Yamahata-san
  - Do not guard against label == 0 for
    OVS_ACTION_ATTR_SET_MPLS in validate_actions().
    A label of 0 is valid
  - Remove comment stupulating that if
    the top_label element of struct sw_flow_key is 0 then
    there is no MPLS label. An MPLS label of 0 is valid
    and the correct check if ethertype is
    ntohs(ETH_TYPE_MPLS) or ntohs(ETH_TYPE_MPLS_MCAST)

v2.4 - v2.5
* No change

v2.3
* s/mpls_stack/mpls_bos/
  This is in keeping with the naming used in the OpenFlow 1.3 specification

v2.2
* Call skb_reset_mac_header() in skb_cb_set_mpls_stack()
  eth_hdr(skb) is non-NULL when called in skb_cb_set_mpls_stack().
* Add a call to skb_cb_set_mpls_stack() in ovs_packet_cmd_execute().
  I apologise that I have mislaid my notes on this but
  it avoids a kernel panic. I can investigate again if necessary.
* Use struct ovs_action_push_mpls instead of
  __be16 to decode OVS_ACTION_ATTR_PUSH_MPLS in validate_actions(). This is
  consistent with the data format for the attribute.
* Indentation fix in skb_cb_mpls_stack(). [cosmetic]

v2.1
* Manual rebase
datapath: Split ovs_flow_extract

Allow repeated extraction of flow from packets

Split the L3 and above portion of ovs_flow_extract() out into
ovs_flow_extract_l3_onwards() and call ovs_flow_extract_l3_onwards()
from ovs_flow_extract().

This is to allow re-extraction of L3 and higher information using
an ethernet type supplied by actions, for example the mpls_pop.

Signed-off-by: Simon Horman <horms@verge.net.au>

---

v2.18  - v2.19
* No change

v2.17
* Rebase

v2.14 - v2.16
* No change

v2.13
* As suggested by Jarno Rajahalme
  - Update change log to more closely reflect the extent of the
    changes in the patch

v2.12
* Rebase

v2.11
* First post
datapath: Inner And Outer Flows

Allow a flow to be visible in two forms, an outer flow and an inner flow.
This may occur if the actions allow further decoding of a packet to
provide a more fine-grained match. In this case the first-pass
coarse-grained match will hit the outer-flow and the second-pass
fined-grained match will hit the inner-flow.

Inner-flows are not visible to user-space. Rather, they are just an
internal representation to handle the case of actions allowing further
packet decoding. An inner-flow is associated with its outer-flow and
deleted when the outer-flow is deleted. An outer-flow may have more than
one inner-flow but an inner-flow may only have one outer-flow.

For example:

In the case of MPLS, L3 and L4 information may not initially be decoded
from the frame as the ethernet type of the frame is an MPLS type and no
information is known about the type of the inner frame.

However, the type of the inner frame may be provided by an mpls_pop action
in which case L3 and L4 information may be decoded providing a finer
grained match than is otherwise possible.

Signed-off-by: Simon Horman <horms@verge.net.au>

---

v2.19
* Update ovs_actions_allow_l3_extraction() to always return
  htons(0) instead of 0.
* enhance ovs_actions_allow_l3_extraction to look for the first
  MPLS POP action with a non-MPLS ethertype rather than the first
  MPLS POP action.

* Correct logic error in ovs_flow_tbl_next() that prevented facets from
  being dumped by the kernel-datapath. The result being that ovs-vswitchd
  would evict facts from the datapath regardless if they had been
  recently used or not. This may in turn cause flow misses and upcalls
  to ovs-vswitchd.

  This change should be squashed into "datapath: Inner And Outer Flows"
  I plan to do so for the v2.19 post of the MPLS patch-set.

v2.18
* No change

v2.17
* Rebase
* Do not allocate and free actions for outer flows,
  the actions of an inner flow may be shared.

v2.16
* No change

v2.15
* Rebase

v2.14
* No change

v2.13
* Merge "datapath: Allow inner_flows" and
  "datapath: re-lookup a flow if actions allow a more fine grained match"
  and rename the resulting patch "datapath: Inner and Outer Flows".
* As suggested by Jarno Rajahalme
  - Add encap_eth_type to struct sw_flow and use it to store the
    ethernet type supplied by actions of a flow if any. This is
    an optimisation to avoid scanning the actions for each packet.

v2.12
* No change

v2.11
* First post
datapath: ovs_flow_to_nlattrs: use encap_eth_type

The ethernet type of an encapsulated frame may be obtained from
actions. If so it should be used to allow a richer conversion
of a flow to nlattrs.

Signed-off-by: Simon Horman <horms@verge.net.au>

---

v2.18  - v2.19
* No change

v2.17
* Rebase

v2.12 - v2.16
* No change

v2.11
* First post
datapath: ovs_flow_used: use encap_eth_type

The ethernet type of an encapsulated frame may be obtained from
actions. If so it should be used to correct decoding of L3 and L4
packet data.

Signed-off-by: Simon Horman <horms@verge.net.au>

---

v2.14 - v2.19
* No change

v2.13
* As suggested by Jarno Rajahalme
  - Initialise encap_eth_type as 0 in ovs_dp_process_received_packet()

v2.12
* Rebase
* Add dl_type parameter to flow_extract_l3_onwards,
  allowing this patch to be applied independently of
  the rest of the MPLS patch-set.

v2.11
* First post

flow: Split flow_extract

Split the L3 and above portion of flow_extract() out into
flow_extract_l3_onwards() and call flow_extract_l3_onwards()
from flow_extract().

This is to allow re-extraction of l3 and higher information using
flow->encap_dl_type which may be set using information contained
in actions.

Signed-off-by: Simon Horman <horms@verge.net.au>
datapath: Allow IP actions for MPLS

Allow copy_ttl_in to function in the case where:
a) The outer header is MPLS;
b) The next-outer header is IP and;
c) The resulting nw ttl will be different from its existing value

In this circumstance a set ipv4 action will be used to adjust the TTL
but the dl_type of the match will be ETH_P_MPLS_UC or ETH_P_MPLS_MC.

Signed-off-by: Simon Horman <horms@verge.net.au>

---

v2.13 - v2.19
* No change

v2.12
* Use eth_p_mpls helper

v2.11
* First post
ofproto: Enhance checking of ethertype of mpls_pop actions

The current check is not alwaus correct. It ensures ensures that the ether
type of an mpls_pop action is never an MPLS ether type. If a packet has
more than LSE then popping the outer-most LSE will require an mpls_pop
action with an MPLS ether type.

Replace this with logic in execute_mpls_pop_action to processing on invalid
mpls_pop action and check the validity of the ether type based on the
MPLS stack depth.

Also add a test that exercises this by performing an mpls_pop
on a frame with two MPLS Label Stack Entries.

Signed-off-by: Simon Horman <horms@verge.net.au>
ofproto-dpif: Ensure BOS bit of innermost MPLS LSE is set on push

This resolves a situation where the BOS bit of the innermost MPLS LSE
will not be set if all LSEs are popped and then an LSE is pushed.

e.g.
Packet with a single MPLS LSE has the following actions applied:
	pop_mpls:0x800
	push_mpls:0x8847

This patch also adds a test for this condition to the test suite.

Signed-off-by: Simon Horman <horms@verge.net.au>
packet: Always update ethernet type on pop_mpls

It seems to me that regardless of if the bottom of the MPLS label stack is
reached or not, the ethtype of a pop_mpls actions should be used to update
the ethtype of the flow or packet.

A test has been added to exercise this logic.

Also Limit scope of mh in pop_mpls().

Signed-off-by: Simon Horman <horms@verge.net.au>
ofproto-dpif: Update mpls_lse and inner_mpls_lse on MPLS push and pop

Update the mpls_lse to inner_mpls_lse on mpls_pop.
And update the inner_mpls_lse on pop.

This extends the cases where the LSE is tracked the correctly to
a depth of two. For example, the following case is now handled correctly.

A packet with a non-empty MPLS label stack has the following actions applied.
	push_mpls:0x8847
	pop_mpls:0x0800
	push_mpls:0x8847

A test has been added to the test suite for the above case to exercise
this logic.

This does not work correctly if more than two mpls_pop actions are
applied reducing the stack depth by two and an mpls_push action is then
applied. However at this time there are restrictions in place
to disallow multiple mpls_pop actions.

Signed-off-by: Simon Horman <horms@verge.net.au>
ofp-util: Ensure MPLS LSE is correct after mpls_pop

There is insufficient information tracked to determine if after pushing the
outermost MPLS LSE has been modified or .  So if there is an outermost MPLS
LSE persent then always set it to the value in flow. This should be correct
but may result in an unnecessary set action in some cases.

For example:

The following actions are applied to a frame with at least two
MPLS LSE entries:
	pop_mpls:0x8847
	load:21->OXM_OF_MPLS_LABEL[]

Without this change the result will be incorrect unless the
label of the second outermost LSE of the original frame was 21.

A test had been also added to exercise this condition.

Signed-off-by: Simon Horman <horms@verge.net.au>

---

For correctness this patch depends on
"ofproto-dpif: Update mpls_lse and inner_mpls_lse on MPLS push and pop"
Track MPLS label stack entries

This allows the outermost and second-to outermost MPLS LSE entry
to be obtained regardless of arbitrary mpls_push and mpls_pop actions that
may have occurred.

A test has been added to exercise this logic.

Signed-off-by: Simon Horman <horms@verge.net.au>