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

Lorand Jakab lojakab at cisco.com
Fri Nov 14 13:51:48 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.

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

diff --git a/lib/flow.c b/lib/flow.c
index b46a483..d69e2f7 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..a4326a2 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,7 @@ 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;
 
     return md;
 }
diff --git a/lib/odp-util.c b/lib/odp-util.c
index a0ad73e..291f3b4 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -3065,6 +3065,8 @@ odp_flow_key_from_mask(struct ofpbuf *buf, const struct flow *mask,
 void
 odp_key_from_pkt_metadata(struct ofpbuf *buf, const struct pkt_metadata *md)
 {
+    struct ovs_key_ethernet *eth_key;
+
     nl_msg_put_u32(buf, OVS_KEY_ATTR_PRIORITY, md->skb_priority);
 
     if (md->tunnel.ip_dst) {
@@ -3078,6 +3080,12 @@ 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);
     }
+
+    /* Add unintialized OVS_KEY_ATTR_ETHERNET for layer 2 packets; lack of
+     * this key attribute signals layer 3 packet */
+    if (md->base_layer == LAYER_2) {
+        nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ETHERNET, sizeof *eth_key);
+    }
 }
 
 /* Generate packet metadata from the given ODP flow key. */
@@ -3089,10 +3097,12 @@ 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;
 
     *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,8 @@ 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;
         default:
             break;
         }
diff --git a/lib/packets.h b/lib/packets.h
index 1435af5..406ae60 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -62,6 +62,7 @@ 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 */
 };
 
 #define PKT_METADATA_INITIALIZER(PORT) \
-- 
1.9.3 (Apple Git-50)




More information about the dev mailing list