]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_label.c
*: add indent control files
[mirror_frr.git] / bgpd / bgp_label.c
CommitLineData
cd1964ff
DS
1/* BGP carrying label information
2 * Copyright (C) 2013 Cumulus Networks, Inc.
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
896014f4
DL
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
cd1964ff
DS
19 */
20
21#include <zebra.h>
22
23#include "command.h"
24#include "thread.h"
25#include "prefix.h"
26#include "zclient.h"
27#include "stream.h"
28#include "network.h"
29#include "log.h"
30#include "memory.h"
31#include "nexthop.h"
32#include "mpls.h"
33
34#include "bgpd/bgpd.h"
35#include "bgpd/bgp_table.h"
36#include "bgpd/bgp_route.h"
37#include "bgpd/bgp_attr.h"
38#include "bgpd/bgp_label.h"
39#include "bgpd/bgp_packet.h"
40#include "bgpd/bgp_debug.h"
41
42extern struct zclient *zclient;
43
44int
45bgp_parse_fec_update (void)
46{
47 struct stream *s;
48 struct bgp_node *rn;
49 struct bgp *bgp;
50 struct bgp_table *table;
51 struct prefix p;
52 u_int32_t label;
53 afi_t afi;
54 safi_t safi;
55
56 s = zclient->ibuf;
57
58 memset(&p, 0, sizeof(struct prefix));
59 p.family = stream_getw(s);
60 p.prefixlen = stream_getc(s);
61 stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
62 label = stream_getl(s);
63
64 /* hack for the bgp instance & SAFI = have to send/receive it */
65 afi = family2afi(p.family);
9bedbb1e 66 safi = SAFI_UNICAST;
cd1964ff
DS
67 bgp = bgp_get_default();
68 if (!bgp)
69 {
70 zlog_debug("no default bgp instance");
71 return -1;
72 }
73
74 table = bgp->rib[afi][safi];
75 if (!table)
76 {
9bedbb1e 77 zlog_debug("no %u unicast table", p.family);
cd1964ff
DS
78 return -1;
79 }
80 rn = bgp_node_lookup(table, &p);
81 if (!rn)
82 {
83 zlog_debug("no node for the prefix");
84 return -1;
85 }
86
87 /* treat it as implicit withdraw - the label is invalid */
88 if (label == MPLS_INVALID_LABEL)
9bedbb1e 89 bgp_unset_valid_label(&rn->local_label);
cd1964ff
DS
90 else
91 {
9bedbb1e
DW
92 label_ntop(label, 1, &rn->local_label);
93 bgp_set_valid_label(&rn->local_label);
cd1964ff
DS
94 }
95 SET_FLAG(rn->flags, BGP_NODE_LABEL_CHANGED);
96 bgp_unlock_node (rn);
97 bgp_process (bgp, rn, afi, safi);
98 return 1;
99}
100
9bedbb1e 101mpls_label_t
cd1964ff
DS
102bgp_adv_label (struct bgp_node *rn, struct bgp_info *ri, struct peer *to,
103 afi_t afi, safi_t safi)
104{
105 struct peer *from;
9bedbb1e 106 mpls_label_t remote_label;
cd1964ff
DS
107 int reflect;
108
109 if (!rn || !ri || !to)
9bedbb1e 110 return MPLS_INVALID_LABEL;
cd1964ff 111
9bedbb1e 112 remote_label = ri->extra ? ri->extra->label : MPLS_INVALID_LABEL;
cd1964ff
DS
113 from = ri->peer;
114 reflect = ((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP));
115
116 if (reflect && !CHECK_FLAG(to->af_flags[afi][safi],
117 PEER_FLAG_FORCE_NEXTHOP_SELF))
118 return remote_label;
119
120 if (CHECK_FLAG(to->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED))
121 return remote_label;
122
123 return rn->local_label;
124}
125
126void
28d58fd7
VV
127bgp_reg_dereg_for_label (struct bgp_node *rn, struct bgp_info *ri,
128 int reg)
cd1964ff
DS
129{
130 struct stream *s;
131 struct prefix *p;
132 int command;
28d58fd7
VV
133 u_int16_t flags = 0;
134 size_t flags_pos = 0;
cd1964ff
DS
135
136 /* Check socket. */
137 if (!zclient || zclient->sock < 0)
138 return;
139
140 p = &(rn->p);
141 s = zclient->obuf;
142 stream_reset (s);
143 command = (reg) ? ZEBRA_FEC_REGISTER : ZEBRA_FEC_UNREGISTER;
144 zclient_create_header (s, command, VRF_DEFAULT);
28d58fd7
VV
145 flags_pos = stream_get_endp (s); /* save position of 'flags' */
146 stream_putw(s, flags); /* initial flags */
cd1964ff
DS
147 stream_putw(s, PREFIX_FAMILY(p));
148 stream_put_prefix(s, p);
6cf48acc 149 if (reg)
28d58fd7
VV
150 {
151 assert (ri);
c5a543b4 152 if (ri->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID))
28d58fd7 153 {
aadc0905 154 if (ri->attr->label_index != BGP_INVALID_LABEL_INDEX)
c5a543b4
DW
155 {
156 flags |= ZEBRA_FEC_REGISTER_LABEL_INDEX;
aadc0905 157 stream_putl (s, ri->attr->label_index);
c5a543b4 158 }
28d58fd7
VV
159 }
160 SET_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
161 }
6cf48acc
VV
162 else
163 UNSET_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
cd1964ff 164
28d58fd7
VV
165 /* Set length and flags */
166 stream_putw_at (s, 0, stream_get_endp (s));
167 stream_putw_at (s, flags_pos, flags);
168
169 zclient_send_message(zclient);
cd1964ff
DS
170}
171
172static int
9bedbb1e 173bgp_nlri_get_labels (struct peer *peer, u_char *pnt, u_char plen, mpls_label_t *label)
cd1964ff
DS
174{
175 u_char *data = pnt;
176 u_char *lim = pnt + plen;
177 u_char llen = 0;
bf468c3c 178 u_char label_depth = 0;
cd1964ff
DS
179
180 for (; data < lim; data += BGP_LABEL_BYTES)
181 {
182 memcpy(label, data, BGP_LABEL_BYTES);
9bedbb1e
DW
183 llen += BGP_LABEL_BYTES;
184
185 bgp_set_valid_label(label);
bf468c3c 186 label_depth += 1;
9bedbb1e 187
cd1964ff
DS
188 if (bgp_is_withdraw_label(label) || label_bos(label))
189 break;
190 }
9bedbb1e
DW
191
192 /* If we RX multiple labels we will end up keeping only the last
193 * one. We do not yet support a label stack greater than 1. */
bf468c3c 194 if (label_depth > 1)
9bedbb1e 195 zlog_warn("%s rcvd UPDATE with label stack %d deep",
bf468c3c 196 peer->host, label_depth);
9bedbb1e 197
cd1964ff 198 if (!(bgp_is_withdraw_label(label) || label_bos(label)))
9bedbb1e 199 zlog_warn("%s rcvd UPDATE with invalid label stack - no bottom of stack",
cd1964ff
DS
200 peer->host);
201
202 return llen;
203}
204
205int
206bgp_nlri_parse_label (struct peer *peer, struct attr *attr,
207 struct bgp_nlri *packet)
208{
209 u_char *pnt;
210 u_char *lim;
211 struct prefix p;
212 int psize = 0;
213 int prefixlen;
214 afi_t afi;
215 safi_t safi;
216 int addpath_encoded;
217 u_int32_t addpath_id;
9bedbb1e 218 mpls_label_t label = MPLS_INVALID_LABEL;
cd1964ff
DS
219 u_char llen;
220
221 /* Check peer status. */
222 if (peer->status != Established)
223 return 0;
224
225 pnt = packet->nlri;
226 lim = pnt + packet->length;
227 afi = packet->afi;
228 safi = packet->safi;
229 addpath_id = 0;
230
231 addpath_encoded = (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) &&
232 CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV));
233
234 for (; pnt < lim; pnt += psize)
235 {
236 /* Clear prefix structure. */
237 memset (&p, 0, sizeof (struct prefix));
238 llen = 0;
239
240 if (addpath_encoded)
241 {
242
243 /* When packet overflow occurs return immediately. */
244 if (pnt + BGP_ADDPATH_ID_LEN > lim)
245 return -1;
246
247 addpath_id = ntohl(*((uint32_t*) pnt));
248 pnt += BGP_ADDPATH_ID_LEN;
249 }
250
251 /* Fetch prefix length. */
252 prefixlen = *pnt++;
253 p.family = afi2family (packet->afi);
254 psize = PSIZE (prefixlen);
255
256 /* sanity check against packet data */
257 if ((pnt + psize) > lim)
258 {
259 zlog_err ("%s [Error] Update packet error / L-U (prefix length %d exceeds packet size %u)",
260 peer->host,
261 prefixlen, (uint)(lim-pnt));
262 return -1;
263 }
264
265 /* Fill in the labels */
9bedbb1e 266 llen = bgp_nlri_get_labels(peer, pnt, psize, &label);
aab1814c 267 p.prefixlen = prefixlen - BSIZE(llen);
cd1964ff
DS
268
269 /* There needs to be at least one label */
270 if (prefixlen < 24)
271 {
272 zlog_err ("%s [Error] Update packet error"
273 " (wrong label length %d)",
274 peer->host, prefixlen);
275 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
276 BGP_NOTIFY_UPDATE_INVAL_NETWORK);
277 return -1;
278 }
279
280 if ((afi == AFI_IP && p.prefixlen > 32)
281 || (afi == AFI_IP6 && p.prefixlen > 128))
282 return -1;
283
284 /* Fetch prefix from NLRI packet */
285 memcpy (&p.u.prefix, pnt + llen, psize - llen);
286
287 /* Check address. */
288 if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST)
289 {
290 if (IN_CLASSD (ntohl (p.u.prefix4.s_addr)))
291 {
292 /* From RFC4271 Section 6.3:
293 *
294 * If a prefix in the NLRI field is semantically incorrect
295 * (e.g., an unexpected multicast IP address), an error SHOULD
296 * be logged locally, and the prefix SHOULD be ignored.
297 */
298 zlog_err ("%s: IPv4 labeled-unicast NLRI is multicast address %s, ignoring",
299 peer->host, inet_ntoa (p.u.prefix4));
300 continue;
301 }
302 }
303
304 /* Check address. */
305 if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST)
306 {
307 if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
308 {
309 char buf[BUFSIZ];
310
311 zlog_err ("%s: IPv6 labeled-unicast NLRI is link-local address %s, ignoring",
312 peer->host, inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
313
314 continue;
315 }
316
317 if (IN6_IS_ADDR_MULTICAST (&p.u.prefix6))
318 {
319 char buf[BUFSIZ];
320
321 zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
322 peer->host, inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
323
324 continue;
325 }
326 }
327
328 if (attr)
329 {
9bedbb1e
DW
330 bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_UNICAST,
331 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, &label, 0, NULL);
cd1964ff
DS
332 }
333 else
334 {
9bedbb1e
DW
335 bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_UNICAST,
336 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, &label, NULL);
cd1964ff
DS
337 }
338 }
339
340 /* Packet length consistency check. */
341 if (pnt != lim)
342 {
343 zlog_err ("%s [Error] Update packet error / L-U (%zu data remaining after parsing)",
344 peer->host, lim - pnt);
345 return -1;
346 }
347
348 return 0;
349}