]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_label.c
Merge pull request #4597 from FRRouting/revert-3775-ospf_missing_interface_handling_2
[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;
48 struct bgp_node *rn;
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 }
78 rn = bgp_node_lookup(table, &p);
79 if (!rn) {
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)
86 bgp_unset_valid_label(&rn->local_label);
87 else {
88 label_ntop(label, 1, &rn->local_label);
89 bgp_set_valid_label(&rn->local_label);
90 }
91 SET_FLAG(rn->flags, BGP_NODE_LABEL_CHANGED);
92 bgp_unlock_node(rn);
93 bgp_process(bgp, rn, afi, safi);
94 return 1;
cd1964ff
DS
95}
96
40381db7 97mpls_label_t bgp_adv_label(struct bgp_node *rn, 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
40381db7 104 if (!rn || !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
d62a17ae 120 return rn->local_label;
cd1964ff
DS
121}
122
57592a53
AD
123/**
124 * This is passed as the callback function to bgp_labelpool.c:bgp_lp_get()
125 * by bgp_reg_dereg_for_label() when a label needs to be obtained from
126 * label pool.
127 * Note that it will reject the allocated label if a label index is found,
128 * because the label index supposes predictable labels
129 */
130int bgp_reg_for_label_callback(mpls_label_t new_label, void *labelid,
131 bool allocated)
132{
133 struct bgp_path_info *pi = (struct bgp_path_info *)labelid;
134 struct bgp_node *rn = (struct bgp_node *)pi->net;
135 char addr[PREFIX_STRLEN];
136
137 prefix2str(&rn->p, addr, PREFIX_STRLEN);
138
139 if (BGP_DEBUG(labelpool, LABELPOOL))
140 zlog_debug("%s: FEC %s label=%u, allocated=%d", __func__, addr,
141 new_label, allocated);
142
143 if (!allocated) {
144 /*
145 * previously-allocated label is now invalid
146 */
147 if (pi->attr->label_index == MPLS_INVALID_LABEL_INDEX
148 && pi->attr->label != MPLS_LABEL_NONE
149 && CHECK_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) {
150 bgp_unregister_for_label(rn);
151 label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1,
152 &rn->local_label);
153 bgp_set_valid_label(&rn->local_label);
154 }
155 return 0;
156 }
157
158 /*
159 * label index is assigned, this should be handled by SR-related code,
160 * so retry FEC registration and then reject label allocation for
161 * it to be released to label pool
162 */
163 if (pi->attr->label_index != MPLS_INVALID_LABEL_INDEX) {
164 flog_err(
165 EC_BGP_LABEL,
166 "%s: FEC %s Rejecting allocated label %u as Label Index is %u",
167 __func__, addr, new_label, pi->attr->label_index);
168
169 bgp_register_for_label(pi->net, pi);
170
171 return -1;
172 }
173
174 if (pi->attr->label != MPLS_INVALID_LABEL) {
175 if (new_label == pi->attr->label) {
176 /* already have same label, accept but do nothing */
177 return 0;
178 }
179 /* Shouldn't happen: different label allocation */
180 flog_err(EC_BGP_LABEL,
181 "%s: %s had label %u but got new assignment %u",
182 __func__, addr, pi->attr->label, new_label);
183 /* continue means use new one */
184 }
185
186 label_ntop(new_label, 1, &rn->local_label);
187 bgp_set_valid_label(&rn->local_label);
188
189 /*
190 * Get back to registering the FEC
191 */
192 bgp_register_for_label(pi->net, pi);
193
194 return 0;
195}
196
40381db7 197void bgp_reg_dereg_for_label(struct bgp_node *rn, struct bgp_path_info *pi,
57592a53 198 bool reg)
cd1964ff 199{
57592a53 200 bool with_label_index = false;
d62a17ae 201 struct stream *s;
202 struct prefix *p;
57592a53 203 mpls_label_t *local_label;
d62a17ae 204 int command;
d7c0a89a 205 uint16_t flags = 0;
d62a17ae 206 size_t flags_pos = 0;
57592a53
AD
207 char addr[PREFIX_STRLEN];
208
209 p = &(rn->p);
210 local_label = &(rn->local_label);
211 /* this prevents the loop when we're called by
212 * bgp_reg_for_label_callback()
213 */
214 bool have_label_to_reg = bgp_is_valid_label(local_label)
215 && label_pton(local_label) != MPLS_LABEL_IMPLICIT_NULL;
216
217 if (reg) {
218 assert(pi);
219 /*
220 * Determine if we will let zebra should derive label from
221 * label index instead of bgpd requesting from label pool
222 */
223 if (CHECK_FLAG(pi->attr->flag,
224 ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID))
225 && pi->attr->label_index != BGP_INVALID_LABEL_INDEX) {
226 with_label_index = true;
227 } else {
228 /*
229 * If no label index was provided -- assume any label
230 * from label pool will do. This means that label index
231 * always takes precedence over auto-assigned labels.
232 */
233 if (!have_label_to_reg) {
234 if (BGP_DEBUG(labelpool, LABELPOOL)) {
235 prefix2str(p, addr, PREFIX_STRLEN);
236 zlog_debug("%s: Requesting label from LP for %s",
237 __func__, addr);
238 }
239 /* bgp_reg_for_label_callback() will call back
240 * __func__ when it gets a label from the pool.
241 * This means we'll never register FECs without
242 * valid labels.
243 */
244 bgp_lp_get(LP_TYPE_BGP_LU, pi,
245 bgp_reg_for_label_callback);
246 return;
247 }
248 }
249 }
d62a17ae 250
251 /* Check socket. */
252 if (!zclient || zclient->sock < 0)
253 return;
254
57592a53
AD
255 /* If the route node has a local_label assigned or the
256 * path node has an MPLS SR label index allowing zebra to
257 * derive the label, proceed with registration. */
d62a17ae 258 s = zclient->obuf;
259 stream_reset(s);
260 command = (reg) ? ZEBRA_FEC_REGISTER : ZEBRA_FEC_UNREGISTER;
261 zclient_create_header(s, command, VRF_DEFAULT);
262 flags_pos = stream_get_endp(s); /* save position of 'flags' */
263 stream_putw(s, flags); /* initial flags */
264 stream_putw(s, PREFIX_FAMILY(p));
265 stream_put_prefix(s, p);
266 if (reg) {
57592a53
AD
267 if (have_label_to_reg) {
268 flags |= ZEBRA_FEC_REGISTER_LABEL;
269 stream_putl(s, label_pton(local_label));
270 } else if (with_label_index) {
271 flags |= ZEBRA_FEC_REGISTER_LABEL_INDEX;
272 stream_putl(s, pi->attr->label_index);
d62a17ae 273 }
274 SET_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
275 } else
276 UNSET_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL);
277
278 /* Set length and flags */
279 stream_putw_at(s, 0, stream_get_endp(s));
e0b84ba1
DS
280
281 /*
282 * We only need to write new flags if this is a register
283 */
284 if (reg)
285 stream_putw_at(s, flags_pos, flags);
d62a17ae 286
287 zclient_send_message(zclient);
cd1964ff
DS
288}
289
d7c0a89a 290static int bgp_nlri_get_labels(struct peer *peer, uint8_t *pnt, uint8_t plen,
d62a17ae 291 mpls_label_t *label)
cd1964ff 292{
d7c0a89a
QY
293 uint8_t *data = pnt;
294 uint8_t *lim = pnt + plen;
295 uint8_t llen = 0;
296 uint8_t label_depth = 0;
d62a17ae 297
298 for (; data < lim; data += BGP_LABEL_BYTES) {
299 memcpy(label, data, BGP_LABEL_BYTES);
300 llen += BGP_LABEL_BYTES;
301
302 bgp_set_valid_label(label);
303 label_depth += 1;
304
305 if (bgp_is_withdraw_label(label) || label_bos(label))
306 break;
307 }
308
309 /* If we RX multiple labels we will end up keeping only the last
310 * one. We do not yet support a label stack greater than 1. */
311 if (label_depth > 1)
01c4f23c 312 zlog_info("%s rcvd UPDATE with label stack %d deep", peer->host,
d62a17ae 313 label_depth);
314
315 if (!(bgp_is_withdraw_label(label) || label_bos(label)))
01c4f23c 316 flog_warn(
e50f7cfd 317 EC_BGP_INVALID_LABEL_STACK,
d62a17ae 318 "%s rcvd UPDATE with invalid label stack - no bottom of stack",
319 peer->host);
320
321 return llen;
cd1964ff
DS
322}
323
d62a17ae 324int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
325 struct bgp_nlri *packet)
cd1964ff 326{
d7c0a89a
QY
327 uint8_t *pnt;
328 uint8_t *lim;
d62a17ae 329 struct prefix p;
330 int psize = 0;
331 int prefixlen;
332 afi_t afi;
333 safi_t safi;
334 int addpath_encoded;
d7c0a89a 335 uint32_t addpath_id;
d62a17ae 336 mpls_label_t label = MPLS_INVALID_LABEL;
d7c0a89a 337 uint8_t llen;
d62a17ae 338
d62a17ae 339 pnt = packet->nlri;
340 lim = pnt + packet->length;
341 afi = packet->afi;
342 safi = packet->safi;
343 addpath_id = 0;
344
345 addpath_encoded =
346 (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
347 && CHECK_FLAG(peer->af_cap[afi][safi],
348 PEER_CAP_ADDPATH_AF_TX_RCV));
349
350 for (; pnt < lim; pnt += psize) {
351 /* Clear prefix structure. */
352 memset(&p, 0, sizeof(struct prefix));
d62a17ae 353
354 if (addpath_encoded) {
355
356 /* When packet overflow occurs return immediately. */
357 if (pnt + BGP_ADDPATH_ID_LEN > lim)
513386b5 358 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
d62a17ae 359
360 addpath_id = ntohl(*((uint32_t *)pnt));
361 pnt += BGP_ADDPATH_ID_LEN;
362 }
363
364 /* Fetch prefix length. */
365 prefixlen = *pnt++;
366 p.family = afi2family(packet->afi);
367 psize = PSIZE(prefixlen);
368
369 /* sanity check against packet data */
370 if ((pnt + psize) > lim) {
af4c2728 371 flog_err(
e50f7cfd 372 EC_BGP_UPDATE_RCV,
d62a17ae 373 "%s [Error] Update packet error / L-U (prefix length %d exceeds packet size %u)",
374 peer->host, prefixlen, (uint)(lim - pnt));
513386b5 375 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
d62a17ae 376 }
377
378 /* Fill in the labels */
379 llen = bgp_nlri_get_labels(peer, pnt, psize, &label);
380 p.prefixlen = prefixlen - BSIZE(llen);
381
382 /* There needs to be at least one label */
383 if (prefixlen < 24) {
e50f7cfd 384 flog_err(EC_BGP_UPDATE_RCV,
1c50c1c0
QY
385 "%s [Error] Update packet error"
386 " (wrong label length %d)",
387 peer->host, prefixlen);
d62a17ae 388 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
389 BGP_NOTIFY_UPDATE_INVAL_NETWORK);
513386b5 390 return BGP_NLRI_PARSE_ERROR_LABEL_LENGTH;
d62a17ae 391 }
392
393 if ((afi == AFI_IP && p.prefixlen > 32)
394 || (afi == AFI_IP6 && p.prefixlen > 128))
513386b5 395 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
d62a17ae 396
397 /* Fetch prefix from NLRI packet */
398 memcpy(&p.u.prefix, pnt + llen, psize - llen);
399
400 /* Check address. */
401 if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST) {
402 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
403 /* From RFC4271 Section 6.3:
404 *
405 * If a prefix in the NLRI field is semantically
406 * incorrect
407 * (e.g., an unexpected multicast IP address),
408 * an error SHOULD
409 * be logged locally, and the prefix SHOULD be
410 * ignored.
9d303b37 411 */
af4c2728 412 flog_err(
e50f7cfd 413 EC_BGP_UPDATE_RCV,
d62a17ae 414 "%s: IPv4 labeled-unicast NLRI is multicast address %s, ignoring",
415 peer->host, inet_ntoa(p.u.prefix4));
416 continue;
417 }
418 }
419
420 /* Check address. */
421 if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST) {
422 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
423 char buf[BUFSIZ];
424
af4c2728 425 flog_err(
e50f7cfd 426 EC_BGP_UPDATE_RCV,
d62a17ae 427 "%s: IPv6 labeled-unicast NLRI is link-local address %s, ignoring",
428 peer->host,
429 inet_ntop(AF_INET6, &p.u.prefix6, buf,
430 BUFSIZ));
431
432 continue;
433 }
434
435 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
436 char buf[BUFSIZ];
437
af4c2728 438 flog_err(
e50f7cfd 439 EC_BGP_UPDATE_RCV,
d62a17ae 440 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
441 peer->host,
442 inet_ntop(AF_INET6, &p.u.prefix6, buf,
443 BUFSIZ));
444
445 continue;
446 }
447 }
448
449 if (attr) {
450 bgp_update(peer, &p, addpath_id, attr, packet->afi,
451 SAFI_UNICAST, ZEBRA_ROUTE_BGP,
b57ba6d2 452 BGP_ROUTE_NORMAL, NULL, &label, 1, 0, NULL);
d62a17ae 453 } else {
454 bgp_withdraw(peer, &p, addpath_id, attr, packet->afi,
455 SAFI_UNICAST, ZEBRA_ROUTE_BGP,
b57ba6d2 456 BGP_ROUTE_NORMAL, NULL, &label, 1, NULL);
d62a17ae 457 }
458 }
459
460 /* Packet length consistency check. */
461 if (pnt != lim) {
af4c2728 462 flog_err(
e50f7cfd 463 EC_BGP_UPDATE_RCV,
d62a17ae 464 "%s [Error] Update packet error / L-U (%zu data remaining after parsing)",
465 peer->host, lim - pnt);
513386b5 466 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
d62a17ae 467 }
468
513386b5 469 return BGP_NLRI_PARSE_OK;
cd1964ff 470}