From: David Ahern <dsahern@gmail.com>
To: netdev@vger.kernel.org, stephen@networkplumber.org
Cc: David Ahern <dsahern@gmail.com>
Subject: [PATCH iproute2] ip: add support for more MPLS labels
Date: Sat, 13 May 2017 19:27:02 -0600 [thread overview]
Message-ID: <20170514012702.1083-1-dsahern@gmail.com> (raw)
Kernel now supports up to 30 labels but not defined as part of the uapi.
iproute2 handles up to 8 labels but in a non-consistent way. Update ip
to handle more labels, but in a more programmatic way.
For the MPLS address family, the data field in inet_prefix is used for
labels. Increase that field to 64 u32's -- 64 as nothing more than a
convenient power of 2 number.
Update mpls_pton to take the length of the address field, convert that
length to number of labels and add better error handling to the parsing
of the user supplied string.
Signed-off-by: David Ahern <dsahern@gmail.com>
---
include/utils.h | 7 ++-----
lib/mpls_pton.c | 11 +++++++----
lib/utils.c | 7 +++++--
3 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/include/utils.h b/include/utils.h
index 8c12e1e2a60c..bfbc9e6dff55 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -61,7 +61,7 @@ typedef struct
__s16 bitlen;
/* These next two fields match rtvia */
__u16 family;
- __u32 data[8];
+ __u32 data[64];
} inet_prefix;
#define PREFIXLEN_SPECIFIED 1
@@ -88,9 +88,6 @@ struct ipx_addr {
# define AF_MPLS 28
#endif
-/* Maximum number of labels the mpls helpers support */
-#define MPLS_MAX_LABELS 8
-
__u32 get_addr32(const char *name);
int get_addr_1(inet_prefix *dst, const char *arg, int family);
int get_prefix_1(inet_prefix *dst, char *arg, int family);
@@ -155,7 +152,7 @@ const char *ipx_ntop(int af, const void *addr, char *str, size_t len);
int ipx_pton(int af, const char *src, void *addr);
const char *mpls_ntop(int af, const void *addr, char *str, size_t len);
-int mpls_pton(int af, const char *src, void *addr);
+int mpls_pton(int af, const char *src, void *addr, size_t alen);
extern int __iproute2_hz_internal;
int __get_hz(void);
diff --git a/lib/mpls_pton.c b/lib/mpls_pton.c
index bd448cfcf14a..6d2e6a69436a 100644
--- a/lib/mpls_pton.c
+++ b/lib/mpls_pton.c
@@ -7,12 +7,13 @@
#include "utils.h"
-static int mpls_pton1(const char *name, struct mpls_label *addr)
+static int mpls_pton1(const char *name, struct mpls_label *addr,
+ unsigned int maxlabels)
{
char *endp;
unsigned count;
- for (count = 0; count < MPLS_MAX_LABELS; count++) {
+ for (count = 0; count < maxlabels; count++) {
unsigned long label;
label = strtoul(name, &endp, 0);
@@ -37,17 +38,19 @@ static int mpls_pton1(const char *name, struct mpls_label *addr)
addr += 1;
}
/* The address was too long */
+ fprintf(stderr, "Error: too many labels.\n");
return 0;
}
-int mpls_pton(int af, const char *src, void *addr)
+int mpls_pton(int af, const char *src, void *addr, size_t alen)
{
+ unsigned int maxlabels = alen / sizeof(struct mpls_label);
int err;
switch(af) {
case AF_MPLS:
errno = 0;
- err = mpls_pton1(src, (struct mpls_label *)addr);
+ err = mpls_pton1(src, (struct mpls_label *)addr, maxlabels);
break;
default:
errno = EAFNOSUPPORT;
diff --git a/lib/utils.c b/lib/utils.c
index 6d5642f4f1f3..e77bd302530b 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -518,15 +518,18 @@ int get_addr_1(inet_prefix *addr, const char *name, int family)
}
if (family == AF_MPLS) {
+ unsigned int maxlabels;
int i;
addr->family = AF_MPLS;
- if (mpls_pton(AF_MPLS, name, addr->data) <= 0)
+ if (mpls_pton(AF_MPLS, name, addr->data,
+ sizeof(addr->data)) <= 0)
return -1;
addr->bytelen = 4;
addr->bitlen = 20;
/* How many bytes do I need? */
- for (i = 0; i < 8; i++) {
+ maxlabels = sizeof(addr->data) / sizeof(struct mpls_label);
+ for (i = 0; i < maxlabels; i++) {
if (ntohl(addr->data[i]) & MPLS_LS_S_MASK) {
addr->bytelen = (i + 1)*4;
break;
--
2.11.0 (Apple Git-81)
next reply other threads:[~2017-05-14 1:28 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-14 1:27 David Ahern [this message]
2017-05-16 8:32 ` [PATCH iproute2] ip: add support for more MPLS labels Simon Horman
2017-05-16 15:21 ` David Ahern
2017-05-22 18:04 ` Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170514012702.1083-1-dsahern@gmail.com \
--to=dsahern@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=stephen@networkplumber.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.