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
|
/* BGP carrying Label information
* Copyright (C) 2013 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 _BGP_LABEL_H
#define _BGP_LABEL_H
#define BGP_LABEL_BYTES 3
#define BGP_LABEL_BITS 24
#define BGP_WITHDRAW_LABEL 0x800000
struct bgp_node;
struct bgp_info;
struct peer;
extern void bgp_reg_dereg_for_label (struct bgp_node *rn, struct bgp_info *ri,
int reg);
extern int bgp_parse_fec_update(void);
extern mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri,
struct peer *to, afi_t afi, safi_t safi);
extern int bgp_nlri_parse_label (struct peer *peer, struct attr *attr,
struct bgp_nlri *packet);
static inline int
bgp_labeled_safi (safi_t safi)
{
/* NOTE: This API really says a label (tag) MAY be present. Not all EVPN
* routes will have a label.
*/
if ((safi == SAFI_LABELED_UNICAST) || (safi == SAFI_MPLS_VPN) ||
(safi == SAFI_EVPN))
return 1;
return 0;
}
static inline int
bgp_is_withdraw_label (mpls_label_t *label)
{
u_char *pkt = (u_char *) label;
/* The check on pkt[2] for 0x00 or 0x02 is in case bgp_set_valid_label()
* was called on the withdraw label */
if ((pkt[0] == 0x80) && (pkt[1] == 0x00) && ((pkt[2] == 0x00) || (pkt[2] == 0x02)))
return 1;
return 0;
}
static inline int
bgp_is_valid_label (mpls_label_t *label)
{
u_char *t= (u_char *) label;
if (!t)
return 0;
return (t[2] & 0x02);
}
static inline void
bgp_set_valid_label (mpls_label_t *label)
{
u_char *t= (u_char *) label;
if (t)
t[2] |= 0x02;
}
static inline void
bgp_unset_valid_label (mpls_label_t *label)
{
u_char *t= (u_char *) label;
if (t)
t[2] &= ~0x02;
}
static inline void
bgp_register_for_label (struct bgp_node *rn, struct bgp_info *ri)
{
bgp_reg_dereg_for_label (rn, ri, 1);
}
static inline void
bgp_unregister_for_label (struct bgp_node *rn)
{
bgp_reg_dereg_for_label (rn, NULL, 0);
}
/* Label stream to value */
static inline u_int32_t
label_pton (mpls_label_t *label)
{
u_char *t= (u_char *) label;
return ((((unsigned int) t[0]) << 12) | (((unsigned int) t[1]) << 4) |
((unsigned int) ((t[2] & 0xF0) >> 4)));
}
/* Encode label values */
static inline void
label_ntop (u_int32_t l, int bos, mpls_label_t *label)
{
u_char *t= (u_char *) label;
t[0] = ((l & 0x000FF000) >> 12);
t[1] = ((l & 0x00000FF0) >> 4);
t[2] = ((l & 0x0000000F) << 4);
if (bos)
t[2] |= 0x01;
}
/* Return BOS value of label stream */
static inline u_char
label_bos (mpls_label_t *label)
{
u_char *t= (u_char *) label;
return (t[2] & 0x01);
};
#endif /* _BGP_LABEL_H */
|