The key is sourced from the datapath so should not have more labels than it can handle.
dpif-netdev supports as many LSEs as can fit in struct flow, so it is safe to pass SIZE_MAX as the limit there. This is an proposed enhancement to "Implement OpenFlow support for MPLS, for up to 3 labels." Signed-off-by: Simon Horman <ho...@verge.net.au> --- lib/dpif-netdev.c | 3 ++- lib/odp-util.c | 13 ++++++++----- lib/odp-util.h | 3 ++- ofproto/ofproto-dpif-upcall.c | 5 ++++- ofproto/ofproto-dpif.c | 6 ++++++ ofproto/ofproto-dpif.h | 2 ++ 6 files changed, 24 insertions(+), 8 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index fdea0a7..6186a11 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -1361,7 +1361,8 @@ dpif_netdev_flow_dump_next(const struct dpif *dpif, void *state_, ofpbuf_use_stack(&buf, &state->maskbuf, sizeof state->maskbuf); minimask_expand(&netdev_flow->cr.match.mask, &wc); odp_flow_key_from_mask(&buf, &wc.masks, &netdev_flow->flow, - odp_to_u32(wc.masks.in_port.odp_port)); + odp_to_u32(wc.masks.in_port.odp_port), + SIZE_MAX); *mask = buf.data; *mask_len = buf.size; diff --git a/lib/odp-util.c b/lib/odp-util.c index 520b314..a4039b9 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -2419,7 +2419,8 @@ ovs_to_odp_frag_mask(uint8_t nw_frag_mask) static void odp_flow_key_from_flow__(struct ofpbuf *buf, const struct flow *data, - const struct flow *flow, odp_port_t odp_in_port) + const struct flow *flow, odp_port_t odp_in_port, + size_t max_mpls_depth) { bool is_mask; struct ovs_key_ethernet *eth_key; @@ -2523,7 +2524,7 @@ odp_flow_key_from_flow__(struct ofpbuf *buf, const struct flow *data, struct ovs_key_mpls *mpls_key; int i, n; - n = flow_count_mpls_labels(flow, NULL); + n = MIN(flow_count_mpls_labels(flow, NULL), max_mpls_depth); mpls_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_MPLS, n * sizeof *mpls_key); for (i = 0; i < n; i++) { @@ -2610,7 +2611,7 @@ void odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow, odp_port_t odp_in_port) { - odp_flow_key_from_flow__(buf, flow, flow, odp_in_port); + odp_flow_key_from_flow__(buf, flow, flow, odp_in_port, SIZE_MAX); } /* Appends a representation of 'mask' as OVS_KEY_ATTR_* attributes to @@ -2623,9 +2624,11 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow, * capable of being expanded to allow for that much space. */ void odp_flow_key_from_mask(struct ofpbuf *buf, const struct flow *mask, - const struct flow *flow, uint32_t odp_in_port_mask) + const struct flow *flow, uint32_t odp_in_port_mask, + size_t max_mpls_depth) { - odp_flow_key_from_flow__(buf, mask, flow, u32_to_odp(odp_in_port_mask)); + odp_flow_key_from_flow__(buf, mask, flow, u32_to_odp(odp_in_port_mask), + max_mpls_depth); } /* Generate ODP flow key from the given packet metadata */ diff --git a/lib/odp-util.h b/lib/odp-util.h index abb8789..7bc64c7 100644 --- a/lib/odp-util.h +++ b/lib/odp-util.h @@ -146,7 +146,8 @@ int odp_flow_from_string(const char *s, void odp_flow_key_from_flow(struct ofpbuf *, const struct flow *, odp_port_t odp_in_port); void odp_flow_key_from_mask(struct ofpbuf *, const struct flow *mask, - const struct flow *flow, uint32_t odp_in_port); + const struct flow *flow, uint32_t odp_in_port, + size_t max_mpls_depth); uint32_t odp_flow_key_hash(const struct nlattr *, size_t); diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index dd24f5c..12d43f1 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -1114,8 +1114,11 @@ handle_upcalls(struct handler *handler, struct list *upcalls) atomic_read(&enable_megaflows, &megaflow); ofpbuf_use_stack(&mask, &miss->mask_buf, sizeof miss->mask_buf); if (megaflow) { + size_t max_mpls; + + max_mpls = ofproto_dpif_get_max_mpls_depth(miss->ofproto); odp_flow_key_from_mask(&mask, &miss->xout.wc.masks, - &miss->flow, UINT32_MAX); + &miss->flow, UINT32_MAX, max_mpls); } op = &ops[n_ops++]; diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index ee93db2..9cffa87 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -323,6 +323,12 @@ ofproto_dpif_cast(const struct ofproto *ofproto) return CONTAINER_OF(ofproto, struct ofproto_dpif, up); } +size_t +ofproto_dpif_get_max_mpls_depth(const struct ofproto_dpif *ofproto) +{ + return ofproto->backer->max_mpls_depth; +} + static struct ofport_dpif *get_ofp_port(const struct ofproto_dpif *ofproto, ofp_port_t ofp_port); static void ofproto_trace(struct ofproto_dpif *, const struct flow *, diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h index 51cb38f..a9e6924 100644 --- a/ofproto/ofproto-dpif.h +++ b/ofproto/ofproto-dpif.h @@ -62,6 +62,8 @@ struct OVS_LOCKABLE group_dpif; * Ofproto-dpif-xlate is responsible for translating translating OpenFlow * actions into datapath actions. */ +size_t ofproto_dpif_get_max_mpls_depth(const struct ofproto_dpif *); + void rule_dpif_lookup(struct ofproto_dpif *, const struct flow *, struct flow_wildcards *, struct rule_dpif **rule); -- 1.8.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev