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 <loja...@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) _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev