[ovs-dev] [PATCH 8/8] ofproto-dpif: Do not add more MPLS labels to mask than the datapath can handle
Simon Horman
horms at verge.net.au
Wed Jan 15 07:13:25 UTC 2014
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 <horms at 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
More information about the dev
mailing list