mirror of
https://git.kernel.org/pub/scm/network/iproute2/iproute2.git
synced 2024-11-16 22:45:17 +08:00
dacc5d4197
- Pull in the uapi mpls.h - Update rtnetlink.h to include the mpls rtnetlink notification multicast group. - Define AF_MPLS in utils.h if it is not defined from elsewhere as is done with AF_DECnet The address syntax for multiple mpls labels is a complete invention. When I looked there seemed to be no wide spread convention for talking about an mpls label stack in text for. Sometimes people did: "{ Label1, Label2, Label3 }", sometimes people would do: "[ label3, label2, label1 ]", and most of the time label stacks were not explicitly shown at all. The syntax I wound up using, so it would not have spaces and so it would visually distinct from other kinds of addresses is. label1/label2/label3 Where label1 is the label at the top of the label stack and label3 is the label at the bottom on the label stack. When there is a single label this matches what seems to be convention with other tools. Just print out the numeric value of the mpls label. The netlink protocol for labels uses the on the wire format for a label stack. The ttl and traffic class are expected to be 0. Using the on the wire format is common and what happens with other address types. BGP when passing label stacks also uses this technique with the exception that the ttl byte is not included making each label in a BGP label stack 3 bytes instead of 4. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
49 lines
936 B
C
49 lines
936 B
C
#include <errno.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <netinet/in.h>
|
|
#include <linux/mpls.h>
|
|
|
|
#include "utils.h"
|
|
|
|
static const char *mpls_ntop1(const struct mpls_label *addr, char *buf, size_t buflen)
|
|
{
|
|
size_t destlen = buflen;
|
|
char *dest = buf;
|
|
int count;
|
|
|
|
for (count = 0; count < MPLS_MAX_LABELS; count++) {
|
|
uint32_t entry = ntohl(addr[count].entry);
|
|
uint32_t label = (entry & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT;
|
|
int len = snprintf(dest, destlen, "%u", label);
|
|
|
|
/* Is this the end? */
|
|
if (entry & MPLS_LS_S_MASK)
|
|
return buf;
|
|
|
|
|
|
dest += len;
|
|
destlen -= len;
|
|
if (destlen) {
|
|
*dest = '/';
|
|
dest++;
|
|
destlen--;
|
|
}
|
|
}
|
|
errno = -E2BIG;
|
|
return NULL;
|
|
}
|
|
|
|
const char *mpls_ntop(int af, const void *addr, char *buf, size_t buflen)
|
|
{
|
|
switch(af) {
|
|
case AF_MPLS:
|
|
errno = 0;
|
|
return mpls_ntop1((struct mpls_label *)addr, buf, buflen);
|
|
default:
|
|
errno = EAFNOSUPPORT;
|
|
}
|
|
|
|
return NULL;
|
|
}
|