Packet metadata for layer 3 packets is expected to contain
OVS_KEY_ATTR_ETHERTYPE to indicate the network protocol.

Signed-off-by: Lorand Jakab <loja...@cisco.com>
---
 datapath/datapath.c     | 14 +-------------
 datapath/flow.c         |  1 -
 datapath/flow_netlink.c | 12 ++++++++++++
 3 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/datapath/datapath.c b/datapath/datapath.c
index 3607170..a0f92dc 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -527,7 +527,6 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, 
struct genl_info *info)
        struct sw_flow *flow;
        struct sw_flow_actions *sf_acts;
        struct datapath *dp;
-       struct ethhdr *eth;
        struct vport *input_vport;
        int len;
        int err;
@@ -547,18 +546,6 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, 
struct genl_info *info)
 
        nla_memcpy(__skb_put(packet, len), a[OVS_PACKET_ATTR_PACKET], len);
 
-       skb_reset_mac_header(packet);
-       eth = eth_hdr(packet);
-
-       /* Normally, setting the skb 'protocol' field would be handled by a
-        * call to eth_type_trans(), but it assumes there's a sending
-        * device, which we may not have.
-        */
-       if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN)
-               packet->protocol = eth->h_proto;
-       else
-               packet->protocol = htons(ETH_P_802_2);
-
        /* Build an sw_flow for sending this packet. */
        flow = ovs_flow_alloc();
        err = PTR_ERR(flow);
@@ -579,6 +566,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, 
struct genl_info *info)
        OVS_CB(packet)->egress_tun_info = NULL;
        packet->priority = flow->key.phy.priority;
        packet->mark = flow->key.phy.skb_mark;
+       packet->protocol = flow->key.eth.type;
 
        rcu_read_lock();
        dp = get_dp_rcu(sock_net(skb->sk), ovs_header->dp_ifindex);
diff --git a/datapath/flow.c b/datapath/flow.c
index b01f7bd..3caa364 100644
--- a/datapath/flow.c
+++ b/datapath/flow.c
@@ -462,7 +462,6 @@ static int key_extract(struct sk_buff *skb, struct 
sw_flow_key *key)
        /* Link layer. */
        if (key->phy.is_layer3) {
                key->eth.tci = 0;
-               key->eth.type = skb->protocol;
        } else {
                eth = eth_hdr(skb);
                ether_addr_copy(key->eth.src, eth->h_source);
diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c
index 54510c8..8ca3469 100644
--- a/datapath/flow_netlink.c
+++ b/datapath/flow_netlink.c
@@ -692,6 +692,18 @@ static int metadata_from_nlattrs(struct sw_flow_match 
*match,  u64 *attrs,
                else
                        SW_FLOW_KEY_PUT(match, phy.is_layer3, true, is_mask);
        }
+       /* Layer 3 packets from user space have the EtherType as metadata */
+       if (*attrs & (1ULL << OVS_KEY_ATTR_ETHERTYPE)) {
+               __be16 eth_type;
+
+               if (is_mask)
+                       /* Always exact match EtherType. */
+                       eth_type = htons(0xffff);
+               else
+                       eth_type = nla_get_be16(a[OVS_KEY_ATTR_ETHERTYPE]);
+
+               SW_FLOW_KEY_PUT(match, eth.type, eth_type, is_mask);
+       }
        return 0;
 }
 
-- 
1.9.3 (Apple Git-50)

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to