[ovs-dev] [PATCH 14/16] datapath: ovs_flow_to_nlattrs: use encap_eth_type

Simon Horman horms at verge.net.au
Wed Feb 6 09:04:41 UTC 2013


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 at verge.net.au>

---

v2.17
* Rebase

v2.12 - v2.16
* No change

v2.11
* First post
---
 datapath/datapath.c |    4 ++--
 datapath/flow.c     |   49 +++++++++++++++++++++++++++----------------------
 datapath/flow.h     |    3 ++-
 3 files changed, 31 insertions(+), 25 deletions(-)

diff --git a/datapath/datapath.c b/datapath/datapath.c
index 0284bea..02a0f16 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -449,7 +449,7 @@ static int queue_userspace_packet(struct net *net, int dp_ifindex,
 	upcall->dp_ifindex = dp_ifindex;
 
 	nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY);
-	ovs_flow_to_nlattrs(upcall_info->key, user_skb);
+	ovs_flow_to_nlattrs(upcall_info->key, user_skb, htons(0));
 	nla_nest_end(user_skb, nla);
 
 	if (upcall_info->userdata)
@@ -1152,7 +1152,7 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
 	nla = nla_nest_start(skb, OVS_FLOW_ATTR_KEY);
 	if (!nla)
 		goto nla_put_failure;
-	err = ovs_flow_to_nlattrs(&flow->key, skb);
+	err = ovs_flow_to_nlattrs(&flow->key, skb, htons(0));
 	if (err)
 		goto error;
 	nla_nest_end(skb, nla);
diff --git a/datapath/flow.c b/datapath/flow.c
index b59e818..973c871 100644
--- a/datapath/flow.c
+++ b/datapath/flow.c
@@ -1477,10 +1477,12 @@ int ovs_flow_metadata_from_nlattrs(struct sw_flow *flow, int key_len, const stru
 	return 0;
 }
 
-int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
+int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb,
+			__be16 encap_eth_type)
 {
 	struct ovs_key_ethernet *eth_key;
 	struct nlattr *nla, *encap;
+	__be16 eth_type;
 
 	if (swkey->phy.priority &&
 	    nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, swkey->phy.priority))
@@ -1526,7 +1528,20 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
 	if (nla_put_be16(skb, OVS_KEY_ATTR_ETHERTYPE, swkey->eth.type))
 		goto nla_put_failure;
 
-	if (swkey->eth.type == htons(ETH_P_IP)) {
+	eth_type = swkey->eth.type;
+	if (eth_p_mpls(eth_type)) {
+		struct ovs_key_mpls *mpls_key;
+
+		nla = nla_reserve(skb, OVS_KEY_ATTR_MPLS, sizeof(*mpls_key));
+		if (!nla)
+			goto nla_put_failure;
+		mpls_key = nla_data(nla);
+		memset(mpls_key, 0, sizeof(struct ovs_key_mpls));
+		mpls_key->mpls_top_lse = swkey->mpls.top_lse;
+		eth_type = encap_eth_type;
+	}
+
+	if (eth_type == htons(ETH_P_IP)) {
 		struct ovs_key_ipv4 *ipv4_key;
 
 		nla = nla_reserve(skb, OVS_KEY_ATTR_IPV4, sizeof(*ipv4_key));
@@ -1539,7 +1554,7 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
 		ipv4_key->ipv4_tos = swkey->ip.tos;
 		ipv4_key->ipv4_ttl = swkey->ip.ttl;
 		ipv4_key->ipv4_frag = swkey->ip.frag;
-	} else if (swkey->eth.type == htons(ETH_P_IPV6)) {
+	} else if (eth_type == htons(ETH_P_IPV6)) {
 		struct ovs_key_ipv6 *ipv6_key;
 
 		nla = nla_reserve(skb, OVS_KEY_ATTR_IPV6, sizeof(*ipv6_key));
@@ -1555,8 +1570,8 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
 		ipv6_key->ipv6_tclass = swkey->ip.tos;
 		ipv6_key->ipv6_hlimit = swkey->ip.ttl;
 		ipv6_key->ipv6_frag = swkey->ip.frag;
-	} else if (swkey->eth.type == htons(ETH_P_ARP) ||
-		   swkey->eth.type == htons(ETH_P_RARP)) {
+	} else if (eth_type == htons(ETH_P_ARP) ||
+		   eth_type == htons(ETH_P_RARP)) {
 		struct ovs_key_arp *arp_key;
 
 		nla = nla_reserve(skb, OVS_KEY_ATTR_ARP, sizeof(*arp_key));
@@ -1569,19 +1584,9 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
 		arp_key->arp_op = htons(swkey->ip.proto);
 		memcpy(arp_key->arp_sha, swkey->ipv4.arp.sha, ETH_ALEN);
 		memcpy(arp_key->arp_tha, swkey->ipv4.arp.tha, ETH_ALEN);
-	} else if (eth_p_mpls(swkey->eth.type)) {
-		struct ovs_key_mpls *mpls_key;
-
-		nla = nla_reserve(skb, OVS_KEY_ATTR_MPLS, sizeof(*mpls_key));
-		if (!nla)
-			goto nla_put_failure;
-		mpls_key = nla_data(nla);
-		memset(mpls_key, 0, sizeof(struct ovs_key_mpls));
-		mpls_key->mpls_top_lse = swkey->mpls.top_lse;
 	}
 
-	if ((swkey->eth.type == htons(ETH_P_IP) ||
-	     swkey->eth.type == htons(ETH_P_IPV6)) &&
+	if ((eth_type == htons(ETH_P_IP) || eth_type == htons(ETH_P_IPV6)) &&
 	     swkey->ip.frag != OVS_FRAG_TYPE_LATER) {
 
 		if (swkey->ip.proto == IPPROTO_TCP) {
@@ -1591,10 +1596,10 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
 			if (!nla)
 				goto nla_put_failure;
 			tcp_key = nla_data(nla);
-			if (swkey->eth.type == htons(ETH_P_IP)) {
+			if (eth_type == htons(ETH_P_IP)) {
 				tcp_key->tcp_src = swkey->ipv4.tp.src;
 				tcp_key->tcp_dst = swkey->ipv4.tp.dst;
-			} else if (swkey->eth.type == htons(ETH_P_IPV6)) {
+			} else if (eth_type == htons(ETH_P_IPV6)) {
 				tcp_key->tcp_src = swkey->ipv6.tp.src;
 				tcp_key->tcp_dst = swkey->ipv6.tp.dst;
 			}
@@ -1605,14 +1610,14 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
 			if (!nla)
 				goto nla_put_failure;
 			udp_key = nla_data(nla);
-			if (swkey->eth.type == htons(ETH_P_IP)) {
+			if (eth_type == htons(ETH_P_IP)) {
 				udp_key->udp_src = swkey->ipv4.tp.src;
 				udp_key->udp_dst = swkey->ipv4.tp.dst;
-			} else if (swkey->eth.type == htons(ETH_P_IPV6)) {
+			} else if (eth_type == htons(ETH_P_IPV6)) {
 				udp_key->udp_src = swkey->ipv6.tp.src;
 				udp_key->udp_dst = swkey->ipv6.tp.dst;
 			}
-		} else if (swkey->eth.type == htons(ETH_P_IP) &&
+		} else if (eth_type == htons(ETH_P_IP) &&
 			   swkey->ip.proto == IPPROTO_ICMP) {
 			struct ovs_key_icmp *icmp_key;
 
@@ -1622,7 +1627,7 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
 			icmp_key = nla_data(nla);
 			icmp_key->icmp_type = ntohs(swkey->ipv4.tp.src);
 			icmp_key->icmp_code = ntohs(swkey->ipv4.tp.dst);
-		} else if (swkey->eth.type == htons(ETH_P_IPV6) &&
+		} else if (eth_type == htons(ETH_P_IPV6) &&
 			   swkey->ip.proto == IPPROTO_ICMPV6) {
 			struct ovs_key_icmpv6 *icmpv6_key;
 
diff --git a/datapath/flow.h b/datapath/flow.h
index d162302..e29c4e7 100644
--- a/datapath/flow.h
+++ b/datapath/flow.h
@@ -232,7 +232,8 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies);
  */
 #define FLOW_BUFSIZE 220
 
-int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *);
+int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *,
+			__be16 encap_eth_type);
 int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
 		      const struct nlattr *);
 int ovs_flow_metadata_from_nlattrs(struct sw_flow *flow, int key_len,
-- 
1.7.10.4




More information about the dev mailing list