[ovs-dev] [PATCH 02/15] actions: odp_flow_key_from_flow: Allow of encapsulated frames

Simon Horman horms at verge.net.au
Fri Feb 15 09:55:56 UTC 2013


Actions may provide information to allow further decoding of a flow.
This allows decoding of encapsulated frames.

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.

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

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

---

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.
    after: eth(...), eth_type(0x8847), mpls(...), encap(ip(...), tcp(...))
    before: eth(...), eth_type(0x8847), mpls(...), 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
---
 lib/odp-util.c |   47 ++++++++++++++++++++++++++---------------------
 1 file changed, 26 insertions(+), 21 deletions(-)

diff --git a/lib/odp-util.c b/lib/odp-util.c
index 5966c15..a6002db 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -1506,7 +1506,8 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow,
                        uint32_t odp_in_port)
 {
     struct ovs_key_ethernet *eth_key;
-    size_t encap;
+    size_t encap_vlan = 0, encap_mpls = 0;
+    ovs_be16 dl_type = flow_innermost_dl_type(flow);
 
     if (flow->skb_priority) {
         nl_msg_put_u32(buf, OVS_KEY_ATTR_PRIORITY, flow->skb_priority);
@@ -1534,12 +1535,10 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow,
     if (flow->vlan_tci != htons(0) || flow->dl_type == htons(ETH_TYPE_VLAN)) {
         nl_msg_put_be16(buf, OVS_KEY_ATTR_ETHERTYPE, htons(ETH_TYPE_VLAN));
         nl_msg_put_be16(buf, OVS_KEY_ATTR_VLAN, flow->vlan_tci);
-        encap = nl_msg_start_nested(buf, OVS_KEY_ATTR_ENCAP);
+        encap_vlan = nl_msg_start_nested(buf, OVS_KEY_ATTR_ENCAP);
         if (flow->vlan_tci == htons(0)) {
             goto unencap;
         }
-    } else {
-        encap = 0;
     }
 
     if (ntohs(flow->dl_type) < ETH_TYPE_MIN) {
@@ -1548,7 +1547,18 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow,
 
     nl_msg_put_be16(buf, OVS_KEY_ATTR_ETHERTYPE, flow->dl_type);
 
-    if (flow->dl_type == htons(ETH_TYPE_IP)) {
+    if (flow->mpls_depth) {
+        struct ovs_key_mpls *mpls_key;
+
+        mpls_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_MPLS,
+                                            sizeof *mpls_key);
+        mpls_key->mpls_top_lse = flow->mpls_lse;
+        if (flow->encap_dl_type) {
+            encap_mpls = nl_msg_start_nested(buf, OVS_KEY_ATTR_ENCAP);
+        }
+    }
+
+    if (dl_type == htons(ETH_TYPE_IP)) {
         struct ovs_key_ipv4 *ipv4_key;
 
         ipv4_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_IPV4,
@@ -1559,7 +1569,7 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow,
         ipv4_key->ipv4_tos = flow->nw_tos;
         ipv4_key->ipv4_ttl = flow->nw_ttl;
         ipv4_key->ipv4_frag = ovs_to_odp_frag(flow->nw_frag);
-    } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
+    } else if (dl_type == htons(ETH_TYPE_IPV6)) {
         struct ovs_key_ipv6 *ipv6_key;
 
         ipv6_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_IPV6,
@@ -1571,8 +1581,8 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow,
         ipv6_key->ipv6_tclass = flow->nw_tos;
         ipv6_key->ipv6_hlimit = flow->nw_ttl;
         ipv6_key->ipv6_frag = ovs_to_odp_frag(flow->nw_frag);
-    } else if (flow->dl_type == htons(ETH_TYPE_ARP) ||
-               flow->dl_type == htons(ETH_TYPE_RARP)) {
+    } else if (dl_type == htons(ETH_TYPE_ARP) ||
+               dl_type == htons(ETH_TYPE_RARP)) {
         struct ovs_key_arp *arp_key;
 
         arp_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ARP,
@@ -1585,15 +1595,7 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow,
         memcpy(arp_key->arp_tha, flow->arp_tha, ETH_ADDR_LEN);
     }
 
-    if (flow->mpls_depth) {
-        struct ovs_key_mpls *mpls_key;
-
-        mpls_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_MPLS,
-                                            sizeof *mpls_key);
-        mpls_key->mpls_top_lse = flow->mpls_lse;
-    }
-
-    if (is_ip_any(flow) && !(flow->nw_frag & FLOW_NW_FRAG_LATER)) {
+    if (dl_type_is_ip_any(dl_type) && !(flow->nw_frag & FLOW_NW_FRAG_LATER)) {
         if (flow->nw_proto == IPPROTO_TCP) {
             struct ovs_key_tcp *tcp_key;
 
@@ -1608,7 +1610,7 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow,
                                                sizeof *udp_key);
             udp_key->udp_src = flow->tp_src;
             udp_key->udp_dst = flow->tp_dst;
-        } else if (flow->dl_type == htons(ETH_TYPE_IP)
+        } else if (dl_type == htons(ETH_TYPE_IP)
                 && flow->nw_proto == IPPROTO_ICMP) {
             struct ovs_key_icmp *icmp_key;
 
@@ -1616,7 +1618,7 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow,
                                                 sizeof *icmp_key);
             icmp_key->icmp_type = ntohs(flow->tp_src);
             icmp_key->icmp_code = ntohs(flow->tp_dst);
-        } else if (flow->dl_type == htons(ETH_TYPE_IPV6)
+        } else if (dl_type == htons(ETH_TYPE_IPV6)
                 && flow->nw_proto == IPPROTO_ICMPV6) {
             struct ovs_key_icmpv6 *icmpv6_key;
 
@@ -1640,8 +1642,11 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow,
     }
 
 unencap:
-    if (encap) {
-        nl_msg_end_nested(buf, encap);
+    if (encap_mpls) {
+        nl_msg_end_nested(buf, encap_mpls);
+    }
+    if (encap_vlan) {
+        nl_msg_end_nested(buf, encap_vlan);
     }
 }
 
-- 
1.7.10.4




More information about the dev mailing list