actions: Allow secondary decoding of a flow

Actions may provide information to allow further decoding of
a 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
* Coding style fix for actions_allow_l3_extraction().
  Use {} in conjunction with if statements.

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: Allow actions 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.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

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.18
* Update match_wc_init() to use dl_type_is_ip_any()

v2.14 - v2.17
* No change

v2.13
* First post
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
* 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.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.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.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
* 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
* 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.

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
* 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.18
* 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.18
* No change

v2.12
* Use eth_p_mpls helper

v2.11
* First post
ofproto: Stop action processing on invalid mpls_pop

Stop action processing if mpls_pop is attempted on a packet
with no MPLS LSE present.

Signed-off-by: Simon Horman <horms@verge.net.au>
ofproto: Allow mpls_pop with MPLS ethtype

It is unclear to me why this was prohibited.

Signed-off-by: Simon Horman <horms@verge.net.au>
packets: Limit scope of mh in pop_mpls()

A purely cosmetic change to only define and set mh within the
scope that it is used.

Signed-off-by: Simon Horman <horms@verge.net.au>
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.

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 poped and then an LSE is pussed.

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>
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.

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"