[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