1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
/*
* MPLS definitions
* Copyright 2015 Cumulus Networks, Inc.
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2, or (at your
* option) any later version.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _QUAGGA_MPLS_H
#define _QUAGGA_MPLS_H
#include <arpa/inet.h>
/* Well-known MPLS label values (RFC 3032 etc). */
#define MPLS_V4_EXP_NULL_LABEL 0
#define MPLS_RA_LABEL 1
#define MPLS_V6_EXP_NULL_LABEL 2
#define MPLS_IMP_NULL_LABEL 3
#define MPLS_ENTROPY_LABEL_INDICATOR 7
#define MPLS_GAL_LABEL 13
#define MPLS_OAM_ALERT_LABEL 14
#define MPLS_EXTENSION_LABEL 15
/* Minimum and maximum label values */
#define MPLS_MIN_RESERVED_LABEL 0
#define MPLS_MAX_RESERVED_LABEL 15
#define MPLS_MIN_UNRESERVED_LABEL 16
#define MPLS_MAX_UNRESERVED_LABEL 1048575
/* Default min and max SRGB label range */
#define MPLS_DEFAULT_MIN_SRGB_LABEL 16000
#define MPLS_DEFAULT_MAX_SRGB_LABEL 23999
/* Maximum # labels that can be pushed. */
#define MPLS_MAX_LABELS 16
#define IS_MPLS_RESERVED_LABEL(label) \
(label >= MPLS_MIN_RESERVED_LABEL && label <= MPLS_MAX_RESERVED_LABEL)
#define IS_MPLS_UNRESERVED_LABEL(label) \
(label >= MPLS_MIN_UNRESERVED_LABEL \
&& label <= MPLS_MAX_UNRESERVED_LABEL)
/* Definitions for a MPLS label stack entry (RFC 3032). This encodes the
* label, EXP, BOS and TTL fields.
*/
typedef unsigned int mpls_lse_t;
#define MPLS_LS_LABEL_MASK 0xFFFFF000
#define MPLS_LS_LABEL_SHIFT 12
#define MPLS_LS_EXP_MASK 0x00000E00
#define MPLS_LS_EXP_SHIFT 9
#define MPLS_LS_S_MASK 0x00000100
#define MPLS_LS_S_SHIFT 8
#define MPLS_LS_TTL_MASK 0x000000FF
#define MPLS_LS_TTL_SHIFT 0
#define MPLS_LABEL_VALUE(lse) \
((lse & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT)
#define MPLS_LABEL_EXP(lse) ((lse & MPLS_LS_EXP_MASK) >> MPLS_LS_EXP_SHIFT)
#define MPLS_LABEL_BOS(lse) ((lse & MPLS_LS_S_MASK) >> MPLS_LS_S_SHIFT)
#define MPLS_LABEL_TTL(lse) ((lse & MPLS_LS_TTL_MASK) >> MPLS_LS_TTL_SHIFT)
#define IS_MPLS_LABEL_BOS(ls) (MPLS_LABEL_BOS(ls) == 1)
#define MPLS_LABEL_LEN_BITS 20
/* MPLS label value as a 32-bit (mostly we only care about the label value). */
typedef unsigned int mpls_label_t;
/* The MPLS explicit-null label is 0 which means when you memset a mpls_label_t
* to zero you have set that variable to explicit-null which was probably not
* your intent. The work-around is to use one bit to indicate if the
* mpls_label_t has been set by the user. MPLS_INVALID_LABEL has this bit clear
* so that we can use MPLS_INVALID_LABEL to initialize mpls_label_t variables.
*/
#define MPLS_INVALID_LABEL 0xFFFDFFFF
/* LSP types. */
enum lsp_types_t {
ZEBRA_LSP_NONE = 0, /* No LSP. */
ZEBRA_LSP_STATIC = 1, /* Static LSP. */
ZEBRA_LSP_LDP = 2, /* LDP LSP. */
ZEBRA_LSP_BGP = 3 /* BGP LSP. */
};
/* Functions for basic label operations. */
/* Encode a label stack entry from fields; convert to network byte-order as
* the Netlink interface expects MPLS labels to be in this format.
*/
static inline mpls_lse_t mpls_lse_encode(mpls_label_t label, u_int32_t ttl,
u_int32_t exp, u_int32_t bos)
{
mpls_lse_t lse;
lse = htonl((label << MPLS_LS_LABEL_SHIFT) | (exp << MPLS_LS_EXP_SHIFT)
| (bos ? (1 << MPLS_LS_S_SHIFT) : 0)
| (ttl << MPLS_LS_TTL_SHIFT));
return lse;
}
/* Extract the fields from a label stack entry after converting to host-byte
* order. This is expected to be called only for messages received over the
* Netlink interface.
*/
static inline void mpls_lse_decode(mpls_lse_t lse, mpls_label_t *label,
u_int32_t *ttl, u_int32_t *exp,
u_int32_t *bos)
{
mpls_lse_t local_lse;
local_lse = ntohl(lse);
*label = MPLS_LABEL_VALUE(local_lse);
*exp = MPLS_LABEL_EXP(local_lse);
*bos = MPLS_LABEL_BOS(local_lse);
*ttl = MPLS_LABEL_TTL(local_lse);
}
/* Invalid label index value (when used with BGP Prefix-SID). Should
* match the BGP definition.
*/
#define MPLS_INVALID_LABEL_INDEX 0xFFFFFFFF
/* Printable string for labels (with consideration for reserved values). */
static inline char *label2str(mpls_label_t label, char *buf, size_t len)
{
switch (label) {
case MPLS_V4_EXP_NULL_LABEL:
strlcpy(buf, "IPv4 Explicit Null", len);
return (buf);
case MPLS_RA_LABEL:
strlcpy(buf, "Router Alert", len);
return (buf);
case MPLS_V6_EXP_NULL_LABEL:
strlcpy(buf, "IPv6 Explict Null", len);
return (buf);
case MPLS_IMP_NULL_LABEL:
strlcpy(buf, "implicit-null", len);
return (buf);
case MPLS_ENTROPY_LABEL_INDICATOR:
strlcpy(buf, "Entropy Label Indicator", len);
return (buf);
case MPLS_GAL_LABEL:
strlcpy(buf, "Generic Associated Channel", len);
return (buf);
case MPLS_OAM_ALERT_LABEL:
strlcpy(buf, "OAM Alert", len);
return (buf);
case MPLS_EXTENSION_LABEL:
strlcpy(buf, "Extension", len);
return (buf);
default:
if (label < 16)
snprintf(buf, len, "Reserved (%u)", label);
else
snprintf(buf, len, "%u", label);
return (buf);
}
}
/* constants used by ldpd */
#define MPLS_LABEL_IPV4NULL 0 /* IPv4 Explicit NULL Label */
#define MPLS_LABEL_RTALERT 1 /* Router Alert Label */
#define MPLS_LABEL_IPV6NULL 2 /* IPv6 Explicit NULL Label */
#define MPLS_LABEL_IMPLNULL 3 /* Implicit NULL Label */
/* MPLS_LABEL_RESERVED 4-15 */ /* Values 4-15 are reserved */
#define MPLS_LABEL_RESERVED_MAX 15
#define MPLS_LABEL_MAX ((1 << 20) - 1)
#endif
|