[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