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