]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_label.c
bgpd: Fix continue/break change from old commit
[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"
14454c9f 41#include "bgpd/bgp_errors.h"
cd1964ff
DS
42
43extern struct zclient *zclient;
44
d62a17ae 45int bgp_parse_fec_update(void)
cd1964ff 46{
d62a17ae 47 struct stream *s;
9bcb3eef 48 struct bgp_dest *dest;
d62a17ae 49 struct bgp *bgp;
50 struct bgp_table *table;
51 struct prefix p;
d7c0a89a 52 uint32_t label;
d62a17ae 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);
a85297a7 61 stream_get(p.u.val, s, PSIZE(p.prefixlen));
d62a17ae 62 label = stream_getl(s);
63
64 /* hack for the bgp instance & SAFI = have to send/receive it */
65 afi = family2afi(p.family);
66 safi = SAFI_UNICAST;
67 bgp = bgp_get_default();
68 if (!bgp) {
69 zlog_debug("no default bgp instance");
70 return -1;
71 }
72
73 table = bgp->rib[afi][safi];
74 if (!table) {
75 zlog_debug("no %u unicast table", p.family);
76 return -1;
77 }
9bcb3eef
DS
78 dest = bgp_node_lookup(table, &p);
79 if (!dest) {
d62a17ae 80 zlog_debug("no node for the prefix");
81 return -1;
82 }
83
84 /* treat it as implicit withdraw - the label is invalid */
85 if (label == MPLS_INVALID_LABEL)
9bcb3eef 86 bgp_unset_valid_label(&dest->local_label);
d62a17ae 87 else {
9bcb3eef
DS
88 label_ntop(label, 1, &dest->local_label);
89 bgp_set_valid_label(&dest->local_label);
d62a17ae 90 }
9bcb3eef 91 SET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
9bcb3eef 92 bgp_process(bgp, dest, afi, safi);
e71ad4b6 93 bgp_dest_unlock_node(dest);
d62a17ae 94 return 1;
cd1964ff
DS
95}
96
9bcb3eef 97mpls_label_t bgp_adv_label(struct bgp_dest *dest, struct bgp_path_info *pi,
d62a17ae 98 struct peer *to, afi_t afi, safi_t safi)
cd1964ff 99{
d62a17ae 100 struct peer *from;
101 mpls_label_t remote_label;
102 int reflect;
cd1964ff 103
9bcb3eef 104 if (!dest || !pi || !to)
d62a17ae 105 return MPLS_INVALID_LABEL;
cd1964ff 106
40381db7
DS
107 remote_label = pi->extra ? pi->extra->label[0] : MPLS_INVALID_LABEL;
108 from = pi->peer;
d62a17ae 109 reflect =
110 ((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP));
cd1964ff 111
d62a17ae 112 if (reflect
113 && !CHECK_FLAG(to->af_flags[afi][safi],
114 PEER_FLAG_FORCE_NEXTHOP_SELF))
115 return remote_label;
cd1964ff 116
d62a17ae 117 if (CHECK_FLAG(to->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED))
118 return remote_label;
cd1964ff 119
9bcb3eef 120 return dest->local_label;
cd1964ff
DS
121}
122
992dd67e
PR
123static void bgp_send_fec_register_label_msg(struct bgp_dest *dest, bool reg,
124 uint32_t label_index)
125{
126 struct stream *s;
127 int command;
128 const struct prefix *p;
129 uint16_t flags = 0;
130 size_t flags_pos = 0;
131 mpls_label_t *local_label = &(dest->local_label);
132 bool have_label_to_reg =
133 bgp_is_valid_label(local_label)
134 && label_pton(local_label) != MPLS_LABEL_IMPLICIT_NULL;
135
136 p = bgp_dest_get_prefix(dest);
137
138 /* Check socket. */
139 if (!zclient || zclient->sock < 0)
140 return;
141
142 if (BGP_DEBUG(labelpool, LABELPOOL))
143 zlog_debug("%s: FEC %sregister %pRN label_index=%u label=%u",
144 __func__, reg ? "" : "un", bgp_dest_to_rnode(dest),
145 label_index, label_pton(local_label));
146 /* If the route node has a local_label assigned or the
147 * path node has an MPLS SR label index allowing zebra to
148 * derive the label, proceed with registration. */
149 s = zclient->obuf;
150 stream_reset(s);
151 command = (reg) ? ZEBRA_FEC_REGISTER : ZEBRA_FEC_UNREGISTER;
152 zclient_create_header(s, command, VRF_DEFAULT);
153 flags_pos = stream_get_endp(s); /* save position of 'flags' */
154 stream_putw(s, flags); /* initial flags */
155 stream_putw(s, PREFIX_FAMILY(p));
156 stream_put_prefix(s, p);
157 if (reg) {
158 /* label index takes precedence over auto-assigned label. */
159 if (label_index != 0) {
160 flags |= ZEBRA_FEC_REGISTER_LABEL_INDEX;
161 stream_putl(s, label_index);
162 } else if (have_label_to_reg) {
163 flags |= ZEBRA_FEC_REGISTER_LABEL;
164 stream_putl(s, label_pton(local_label));
165 }
166 SET_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL);
167 } else
168 UNSET_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL);
169
170 /* Set length and flags */
171 stream_putw_at(s, 0, stream_get_endp(s));
172
173 /*
174 * We only need to write new flags if this is a register
175 */
176 if (reg)
177 stream_putw_at(s, flags_pos, flags);
178
179 zclient_send_message(zclient);
180}
181
57592a53
AD
182/**
183 * This is passed as the callback function to bgp_labelpool.c:bgp_lp_get()
184 * by bgp_reg_dereg_for_label() when a label needs to be obtained from
185 * label pool.
186 * Note that it will reject the allocated label if a label index is found,
187 * because the label index supposes predictable labels
188 */
189int bgp_reg_for_label_callback(mpls_label_t new_label, void *labelid,
190 bool allocated)
191{
9bcb3eef 192 struct bgp_dest *dest;
57592a53 193
992dd67e
PR
194 dest = labelid;
195
196 /*
197 * if the route had been removed or the request has gone then reject
198 * the allocated label. The requesting code will have done what is
199 * required to allocate the correct label
200 */
201 if (!CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
202 bgp_dest_unlock_node(dest);
ea63ff6b
EDP
203 return -1;
204 }
205
992dd67e 206 bgp_dest_unlock_node(dest);
57592a53
AD
207
208 if (BGP_DEBUG(labelpool, LABELPOOL))
9bcb3eef
DS
209 zlog_debug("%s: FEC %pRN label=%u, allocated=%d", __func__,
210 bgp_dest_to_rnode(dest), new_label, allocated);
57592a53
AD
211
212 if (!allocated) {
213 /*
992dd67e
PR
214 * previously-allocated label is now invalid, set to implicit
215 * null until new label arrives
57592a53 216 */
992dd67e
PR
217 if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)) {
218 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED);
57592a53 219 label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1,
9bcb3eef
DS
220 &dest->local_label);
221 bgp_set_valid_label(&dest->local_label);
57592a53 222 }
57592a53
AD
223 }
224
9bcb3eef
DS
225 label_ntop(new_label, 1, &dest->local_label);
226 bgp_set_valid_label(&dest->local_label);
57592a53
AD
227
228 /*
229 * Get back to registering the FEC
230 */
992dd67e 231 bgp_send_fec_register_label_msg(dest, true, 0);
57592a53
AD
232
233 return 0;
234}
235
9bcb3eef 236void bgp_reg_dereg_for_label(struct bgp_dest *dest, struct bgp_path_info *pi,
57592a53 237 bool reg)
cd1964ff 238{
57592a53 239 bool with_label_index = false;
b54892e0 240 const struct prefix *p;
992dd67e
PR
241 bool have_label_to_reg =
242 bgp_is_valid_label(&dest->local_label)
243 && label_pton(&dest->local_label) != MPLS_LABEL_IMPLICIT_NULL;
57592a53 244
9bcb3eef 245 p = bgp_dest_get_prefix(dest);
57592a53 246
bb2ca692
MS
247 if (BGP_DEBUG(labelpool, LABELPOOL))
248 zlog_debug("%s: %pFX: %s ", __func__, p,
249 (reg ? "reg" : "dereg"));
250
57592a53
AD
251 if (reg) {
252 assert(pi);
253 /*
254 * Determine if we will let zebra should derive label from
255 * label index instead of bgpd requesting from label pool
256 */
257 if (CHECK_FLAG(pi->attr->flag,
258 ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID))
259 && pi->attr->label_index != BGP_INVALID_LABEL_INDEX) {
260 with_label_index = true;
992dd67e 261 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED);
57592a53
AD
262 } else {
263 /*
992dd67e 264 * If no label has been registered -- assume any label
57592a53
AD
265 * from label pool will do. This means that label index
266 * always takes precedence over auto-assigned labels.
267 */
268 if (!have_label_to_reg) {
992dd67e 269 SET_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED);
2dbe669b
DA
270 if (BGP_DEBUG(labelpool, LABELPOOL))
271 zlog_debug(
272 "%s: Requesting label from LP for %pFX",
273 __func__, p);
992dd67e
PR
274 /* bgp_reg_for_label_callback() will deal with
275 * fec registration when it gets a label from
276 * the pool. This means we'll never register
277 * FECs withoutvalid labels.
57592a53 278 */
992dd67e
PR
279 bgp_lp_get(LP_TYPE_BGP_LU, dest,
280 bgp_reg_for_label_callback);
57592a53
AD
281 return;
282 }
283 }
78b351dd 284 } else {
992dd67e 285 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED);
78b351dd
PR
286 bgp_lp_release(LP_TYPE_BGP_LU, dest,
287 label_pton(&dest->local_label));
288 }
d62a17ae 289
992dd67e
PR
290 bgp_send_fec_register_label_msg(
291 dest, reg, with_label_index ? pi->attr->label_index : 0);
cd1964ff
DS
292}
293
d7c0a89a 294static int bgp_nlri_get_labels(struct peer *peer, uint8_t *pnt, uint8_t plen,
d62a17ae 295 mpls_label_t *label)
cd1964ff 296{
d7c0a89a
QY
297 uint8_t *data = pnt;
298 uint8_t *lim = pnt + plen;
299 uint8_t llen = 0;
300 uint8_t label_depth = 0;
d62a17ae 301
302 for (; data < lim; data += BGP_LABEL_BYTES) {
303 memcpy(label, data, BGP_LABEL_BYTES);
304 llen += BGP_LABEL_BYTES;
305
306 bgp_set_valid_label(label);
307 label_depth += 1;
308
309 if (bgp_is_withdraw_label(label) || label_bos(label))
310 break;
311 }
312
313 /* If we RX multiple labels we will end up keeping only the last
314 * one. We do not yet support a label stack greater than 1. */
315 if (label_depth > 1)
01c4f23c 316 zlog_info("%s rcvd UPDATE with label stack %d deep", peer->host,
d62a17ae 317 label_depth);
318
319 if (!(bgp_is_withdraw_label(label) || label_bos(label)))
01c4f23c 320 flog_warn(
e50f7cfd 321 EC_BGP_INVALID_LABEL_STACK,
d62a17ae 322 "%s rcvd UPDATE with invalid label stack - no bottom of stack",
323 peer->host);
324
325 return llen;
cd1964ff
DS
326}
327
d62a17ae 328int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
329 struct bgp_nlri *packet)
cd1964ff 330{
d7c0a89a
QY
331 uint8_t *pnt;
332 uint8_t *lim;
d62a17ae 333 struct prefix p;
334 int psize = 0;
335 int prefixlen;
336 afi_t afi;
337 safi_t safi;
be92fc9f 338 bool addpath_capable;
d7c0a89a 339 uint32_t addpath_id;
d62a17ae 340 mpls_label_t label = MPLS_INVALID_LABEL;
d7c0a89a 341 uint8_t llen;
d62a17ae 342
d62a17ae 343 pnt = packet->nlri;
344 lim = pnt + packet->length;
345 afi = packet->afi;
346 safi = packet->safi;
347 addpath_id = 0;
348
be92fc9f 349 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
d62a17ae 350
351 for (; pnt < lim; pnt += psize) {
352 /* Clear prefix structure. */
353 memset(&p, 0, sizeof(struct prefix));
d62a17ae 354
be92fc9f 355 if (addpath_capable) {
d62a17ae 356
357 /* When packet overflow occurs return immediately. */
358 if (pnt + BGP_ADDPATH_ID_LEN > lim)
513386b5 359 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
d62a17ae 360
a3a850a1
S
361 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
362 addpath_id = ntohl(addpath_id);
d62a17ae 363 pnt += BGP_ADDPATH_ID_LEN;
364 }
365
366 /* Fetch prefix length. */
367 prefixlen = *pnt++;
368 p.family = afi2family(packet->afi);
369 psize = PSIZE(prefixlen);
370
371 /* sanity check against packet data */
372 if ((pnt + psize) > lim) {
af4c2728 373 flog_err(
e50f7cfd 374 EC_BGP_UPDATE_RCV,
d62a17ae 375 "%s [Error] Update packet error / L-U (prefix length %d exceeds packet size %u)",
376 peer->host, prefixlen, (uint)(lim - pnt));
513386b5 377 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
d62a17ae 378 }
379
380 /* Fill in the labels */
381 llen = bgp_nlri_get_labels(peer, pnt, psize, &label);
382 p.prefixlen = prefixlen - BSIZE(llen);
383
384 /* There needs to be at least one label */
385 if (prefixlen < 24) {
e50f7cfd 386 flog_err(EC_BGP_UPDATE_RCV,
3efd0893 387 "%s [Error] Update packet error (wrong label length %d)",
1c50c1c0 388 peer->host, prefixlen);
d62a17ae 389 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
390 BGP_NOTIFY_UPDATE_INVAL_NETWORK);
513386b5 391 return BGP_NLRI_PARSE_ERROR_LABEL_LENGTH;
d62a17ae 392 }
393
12256b84 394 if ((afi == AFI_IP && p.prefixlen > IPV4_MAX_BITLEN)
13ccce6e 395 || (afi == AFI_IP6 && p.prefixlen > IPV6_MAX_BITLEN))
513386b5 396 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
d62a17ae 397
398 /* Fetch prefix from NLRI packet */
399 memcpy(&p.u.prefix, pnt + llen, psize - llen);
400
401 /* Check address. */
402 if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST) {
403 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
404 /* From RFC4271 Section 6.3:
405 *
406 * If a prefix in the NLRI field is semantically
407 * incorrect
408 * (e.g., an unexpected multicast IP address),
409 * an error SHOULD
410 * be logged locally, and the prefix SHOULD be
411 * ignored.
9d303b37 412 */
af4c2728 413 flog_err(
e50f7cfd 414 EC_BGP_UPDATE_RCV,
23d0a753
DA
415 "%s: IPv4 labeled-unicast NLRI is multicast address %pI4, ignoring",
416 peer->host, &p.u.prefix4);
d62a17ae 417 continue;
418 }
419 }
420
421 /* Check address. */
422 if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST) {
423 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
af4c2728 424 flog_err(
e50f7cfd 425 EC_BGP_UPDATE_RCV,
c0d72166
DS
426 "%s: IPv6 labeled-unicast NLRI is link-local address %pI6, ignoring",
427 peer->host, &p.u.prefix6);
d62a17ae 428
429 continue;
430 }
431
432 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
af4c2728 433 flog_err(
e50f7cfd 434 EC_BGP_UPDATE_RCV,
c0d72166
DS
435 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
436 peer->host, &p.u.prefix6);
d62a17ae 437
438 continue;
439 }
440 }
441
442 if (attr) {
443 bgp_update(peer, &p, addpath_id, attr, packet->afi,
907707db
MS
444 safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
445 NULL, &label, 1, 0, NULL);
d62a17ae 446 } else {
447 bgp_withdraw(peer, &p, addpath_id, attr, packet->afi,
448 SAFI_UNICAST, ZEBRA_ROUTE_BGP,
b57ba6d2 449 BGP_ROUTE_NORMAL, NULL, &label, 1, NULL);
d62a17ae 450 }
451 }
452
453 /* Packet length consistency check. */
454 if (pnt != lim) {
af4c2728 455 flog_err(
e50f7cfd 456 EC_BGP_UPDATE_RCV,
566bdaf6 457 "%s [Error] Update packet error / L-U (%td data remaining after parsing)",
d62a17ae 458 peer->host, lim - pnt);
513386b5 459 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
d62a17ae 460 }
461
513386b5 462 return BGP_NLRI_PARSE_OK;
cd1964ff 463}