[ovs-dev] [PATCH v8 4/5] userspace: add layer 3 support to packet metadata

Lorand Jakab lojakab at cisco.com
Mon Nov 17 17:24:12 UTC 2014


This is needed for sending a packet back to the datapath after a miss upcall
was processed.  The presence of a layer 2 packet is signaled by adding
OVS_KEY_ATTR_ETHERNET to the packet metadata sent with the ovs_packet netlink
message.  Layer 3 packets need to be accompanied by OVS_KEY_ATTR_ETHERTYPE to
indicate network protocol.

Signed-off-by: Lorand Jakab <lojakab at cisco.com>
---
 lib/flow.c     |  1 +
 lib/flow.h     |  3 +++
 lib/odp-util.c | 20 +++++++++++++++++++-
 lib/packets.h  |  2 ++
 4 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/lib/flow.c b/lib/flow.c
index 29c5f9e..b8322ec 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -727,6 +727,7 @@ flow_get_metadata(const struct flow *flow, struct flow_metadata *fmd)
     memcpy(fmd->regs, flow->regs, sizeof fmd->regs);
     fmd->pkt_mark = flow->pkt_mark;
     fmd->in_port = flow->in_port.ofp_port;
+    fmd->base_layer = flow->base_layer;
 }
 
 char *
diff --git a/lib/flow.h b/lib/flow.h
index 637f847..0b43603 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -201,6 +201,7 @@ struct flow_metadata {
     uint32_t regs[FLOW_N_REGS];      /* Registers. */
     uint32_t pkt_mark;               /* Packet mark. */
     ofp_port_t in_port;              /* OpenFlow port or zero. */
+    uint32_t base_layer;             /* Fields start at this layer */
 };
 
 void flow_extract(struct ofpbuf *, const struct pkt_metadata *md,
@@ -718,6 +719,8 @@ pkt_metadata_from_flow(const struct flow *flow)
     md.skb_priority = flow->skb_priority;
     md.pkt_mark = flow->pkt_mark;
     md.in_port = flow->in_port;
+    md.base_layer = flow->base_layer;
+    md.protocol = flow->dl_type;
 
     return md;
 }
diff --git a/lib/odp-util.c b/lib/odp-util.c
index a0ad73e..c3936c5 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -3078,6 +3078,13 @@ odp_key_from_pkt_metadata(struct ofpbuf *buf, const struct pkt_metadata *md)
     if (md->in_port.odp_port != ODPP_NONE) {
         nl_msg_put_odp_port(buf, OVS_KEY_ATTR_IN_PORT, md->in_port.odp_port);
     }
+
+    if (md->base_layer == LAYER_2) {
+        nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ETHERNET,
+                                 sizeof(struct ovs_key_ethernet));
+    } else {
+        nl_msg_put_be16(buf, OVS_KEY_ATTR_ETHERTYPE, md->protocol);
+    }
 }
 
 /* Generate packet metadata from the given ODP flow key. */
@@ -3089,10 +3096,13 @@ odp_key_to_pkt_metadata(const struct nlattr *key, size_t key_len,
     size_t left;
     uint32_t wanted_attrs = 1u << OVS_KEY_ATTR_PRIORITY |
         1u << OVS_KEY_ATTR_SKB_MARK | 1u << OVS_KEY_ATTR_TUNNEL |
-        1u << OVS_KEY_ATTR_IN_PORT;
+        1u << OVS_KEY_ATTR_IN_PORT | 1u << OVS_KEY_ATTR_ETHERNET |
+        1u << OVS_KEY_ATTR_ETHERTYPE;
 
     *md = PKT_METADATA_INITIALIZER(ODPP_NONE);
 
+    md->base_layer = LAYER_3;
+
     NL_ATTR_FOR_EACH (nla, left, key, key_len) {
         uint16_t type = nl_attr_type(nla);
         size_t len = nl_attr_get_size(nla);
@@ -3134,6 +3144,14 @@ odp_key_to_pkt_metadata(const struct nlattr *key, size_t key_len,
             md->in_port.odp_port = nl_attr_get_odp_port(nla);
             wanted_attrs &= ~(1u << OVS_KEY_ATTR_IN_PORT);
             break;
+        case OVS_KEY_ATTR_ETHERNET:
+            md->base_layer = LAYER_2;
+            wanted_attrs &= ~(1u << OVS_KEY_ATTR_ETHERNET);
+            break;
+        case OVS_KEY_ATTR_ETHERTYPE:
+            md->protocol = nl_attr_get_be16(nla);
+            wanted_attrs &= ~(1u << OVS_KEY_ATTR_ETHERTYPE);
+            break;
         default:
             break;
         }
diff --git a/lib/packets.h b/lib/packets.h
index 1435af5..14cc230 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -62,6 +62,8 @@ struct pkt_metadata {
     uint32_t skb_priority;      /* Packet priority for QoS. */
     uint32_t pkt_mark;          /* Packet mark. */
     union flow_in_port in_port; /* Input port. */
+    uint32_t base_layer;        /* Packet starts at this layer */
+    ovs_be16 protocol;          /* Protocol for L3 packets */
 };
 
 #define PKT_METADATA_INITIALIZER(PORT) \
-- 
1.9.3 (Apple Git-50)




More information about the dev mailing list