net: mpls: Increase max number of labels for lwt encap
authorDavid Ahern <dsa@cumulusnetworks.com>
Fri, 31 Mar 2017 14:14:04 +0000 (07:14 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sun, 2 Apr 2017 03:21:44 +0000 (20:21 -0700)
Alow users to push down more labels per MPLS encap. Similar to LSR case,
move label array to the end of mpls_iptunnel_encap and allocate based on
the number of labels for the route.

For consistency with the LSR case, re-use the same maximum number of
labels.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/mpls_iptunnel.h
net/mpls/af_mpls.c
net/mpls/internal.h
net/mpls/mpls_iptunnel.c

index a18af6a16eb5280db623f6c83ddb478235e2a4d1..9d22bf67ac86623eaaea2c49fbe1140747ce67e8 100644 (file)
 #ifndef _NET_MPLS_IPTUNNEL_H
 #define _NET_MPLS_IPTUNNEL_H 1
 
-#define MAX_NEW_LABELS 2
-
 struct mpls_iptunnel_encap {
-       u32     label[MAX_NEW_LABELS];
        u8      labels;
        u8      ttl_propagate;
        u8      default_ttl;
+       u8      reserved1;
+       u32     label[0];
 };
 
 static inline struct mpls_iptunnel_encap *mpls_lwtunnel_encap(struct lwtunnel_state *lwtstate)
index 10daefd7f9388ebb439571dbb1e52fdf28cfe94c..5928d22ba9c86813a13621fec6ebdcc62fd7aeba 100644 (file)
 #include <net/nexthop.h>
 #include "internal.h"
 
-/* put a reasonable limit on the number of labels
- * we will accept from userspace
- */
-#define MAX_NEW_LABELS 30
-
 /* max memory we will use for mpls_route */
 #define MAX_MPLS_ROUTE_MEM     4096
 
index c5d2f5bc37ec54bf6b1d20a287a100edf6aca757..4db6a59713220dcefac8be970ab06b1ae25bcd5c 100644 (file)
@@ -2,6 +2,11 @@
 #define MPLS_INTERNAL_H
 #include <net/mpls.h>
 
+/* put a reasonable limit on the number of labels
+ * we will accept from userspace
+ */
+#define MAX_NEW_LABELS 30
+
 struct mpls_entry_decoded {
        u32 label;
        u8 ttl;
index 22f71fce0bfb85a6a9f1f30d171dd141609653ab..fe00e98667cf603c5f01150fb4899f98c86c8496 100644 (file)
@@ -164,6 +164,7 @@ static int mpls_build_state(struct nlattr *nla,
        struct mpls_iptunnel_encap *tun_encap_info;
        struct nlattr *tb[MPLS_IPTUNNEL_MAX + 1];
        struct lwtunnel_state *newts;
+       u8 n_labels;
        int ret;
 
        ret = nla_parse_nested(tb, MPLS_IPTUNNEL_MAX, nla,
@@ -175,12 +176,18 @@ static int mpls_build_state(struct nlattr *nla,
                return -EINVAL;
 
 
-       newts = lwtunnel_state_alloc(sizeof(*tun_encap_info));
+       /* determine number of labels */
+       if (nla_get_labels(tb[MPLS_IPTUNNEL_DST],
+                          MAX_NEW_LABELS, &n_labels, NULL))
+               return -EINVAL;
+
+       newts = lwtunnel_state_alloc(sizeof(*tun_encap_info) +
+                                    n_labels * sizeof(u32));
        if (!newts)
                return -ENOMEM;
 
        tun_encap_info = mpls_lwtunnel_encap(newts);
-       ret = nla_get_labels(tb[MPLS_IPTUNNEL_DST], MAX_NEW_LABELS,
+       ret = nla_get_labels(tb[MPLS_IPTUNNEL_DST], n_labels,
                             &tun_encap_info->labels, tun_encap_info->label);
        if (ret)
                goto errout;
@@ -257,7 +264,7 @@ static int mpls_encap_cmp(struct lwtunnel_state *a, struct lwtunnel_state *b)
            a_hdr->default_ttl != b_hdr->default_ttl)
                return 1;
 
-       for (l = 0; l < MAX_NEW_LABELS; l++)
+       for (l = 0; l < a_hdr->labels; l++)
                if (a_hdr->label[l] != b_hdr->label[l])
                        return 1;
        return 0;