]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
bgpd: inline bgp_lock()/bgp_unlock()
[mirror_frr.git] / bgpd / bgp_route.c
1 /* BGP routing information
2 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
3 * Copyright (C) 2016 Job Snijders <job@instituut.net>
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <zebra.h>
23
24 #include "prefix.h"
25 #include "linklist.h"
26 #include "memory.h"
27 #include "command.h"
28 #include "stream.h"
29 #include "filter.h"
30 #include "log.h"
31 #include "routemap.h"
32 #include "buffer.h"
33 #include "sockunion.h"
34 #include "plist.h"
35 #include "thread.h"
36 #include "workqueue.h"
37 #include "queue.h"
38 #include "memory.h"
39 #include "lib/json.h"
40
41 #include "bgpd/bgpd.h"
42 #include "bgpd/bgp_table.h"
43 #include "bgpd/bgp_route.h"
44 #include "bgpd/bgp_attr.h"
45 #include "bgpd/bgp_debug.h"
46 #include "bgpd/bgp_aspath.h"
47 #include "bgpd/bgp_regex.h"
48 #include "bgpd/bgp_community.h"
49 #include "bgpd/bgp_ecommunity.h"
50 #include "bgpd/bgp_lcommunity.h"
51 #include "bgpd/bgp_clist.h"
52 #include "bgpd/bgp_packet.h"
53 #include "bgpd/bgp_filter.h"
54 #include "bgpd/bgp_fsm.h"
55 #include "bgpd/bgp_mplsvpn.h"
56 #include "bgpd/bgp_nexthop.h"
57 #include "bgpd/bgp_damp.h"
58 #include "bgpd/bgp_advertise.h"
59 #include "bgpd/bgp_zebra.h"
60 #include "bgpd/bgp_vty.h"
61 #include "bgpd/bgp_mpath.h"
62 #include "bgpd/bgp_nht.h"
63 #include "bgpd/bgp_updgrp.h"
64 #include "bgpd/bgp_label.h"
65
66 #if ENABLE_BGP_VNC
67 #include "bgpd/rfapi/rfapi_backend.h"
68 #include "bgpd/rfapi/vnc_import_bgp.h"
69 #include "bgpd/rfapi/vnc_export_bgp.h"
70 #endif
71 #include "bgpd/bgp_encap_types.h"
72 #include "bgpd/bgp_encap_tlv.h"
73 #include "bgpd/bgp_evpn.h"
74 #include "bgpd/bgp_evpn_vty.h"
75
76
77 /* Extern from bgp_dump.c */
78 extern const char *bgp_origin_str[];
79 extern const char *bgp_origin_long_str[];
80
81 struct bgp_node *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
82 safi_t safi, struct prefix *p,
83 struct prefix_rd *prd)
84 {
85 struct bgp_node *rn;
86 struct bgp_node *prn = NULL;
87
88 assert(table);
89 if (!table)
90 return NULL;
91
92 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
93 || (safi == SAFI_EVPN)) {
94 prn = bgp_node_get(table, (struct prefix *)prd);
95
96 if (prn->info == NULL)
97 prn->info = bgp_table_init(afi, safi);
98 else
99 bgp_unlock_node(prn);
100 table = prn->info;
101 }
102
103 rn = bgp_node_get(table, p);
104
105 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
106 || (safi == SAFI_EVPN))
107 rn->prn = prn;
108
109 return rn;
110 }
111
112 struct bgp_node *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
113 safi_t safi, struct prefix *p,
114 struct prefix_rd *prd)
115 {
116 struct bgp_node *rn;
117 struct bgp_node *prn = NULL;
118
119 if (!table)
120 return NULL;
121
122 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
123 || (safi == SAFI_EVPN)) {
124 prn = bgp_node_lookup(table, (struct prefix *)prd);
125 if (!prn)
126 return NULL;
127
128 if (prn->info == NULL) {
129 bgp_unlock_node(prn);
130 return NULL;
131 }
132
133 table = prn->info;
134 }
135
136 rn = bgp_node_lookup(table, p);
137
138 return rn;
139 }
140
141 /* Allocate bgp_info_extra */
142 static struct bgp_info_extra *bgp_info_extra_new(void)
143 {
144 struct bgp_info_extra *new;
145 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA, sizeof(struct bgp_info_extra));
146 new->label = MPLS_INVALID_LABEL;
147 return new;
148 }
149
150 static void bgp_info_extra_free(struct bgp_info_extra **extra)
151 {
152 if (extra && *extra) {
153 if ((*extra)->damp_info)
154 bgp_damp_info_free((*extra)->damp_info, 0);
155
156 (*extra)->damp_info = NULL;
157
158 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
159
160 *extra = NULL;
161 }
162 }
163
164 /* Get bgp_info extra information for the given bgp_info, lazy allocated
165 * if required.
166 */
167 struct bgp_info_extra *bgp_info_extra_get(struct bgp_info *ri)
168 {
169 if (!ri->extra)
170 ri->extra = bgp_info_extra_new();
171 return ri->extra;
172 }
173
174 /* Allocate new bgp info structure. */
175 struct bgp_info *bgp_info_new(void)
176 {
177 return XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_info));
178 }
179
180 /* Free bgp route information. */
181 static void bgp_info_free(struct bgp_info *binfo)
182 {
183 if (binfo->attr)
184 bgp_attr_unintern(&binfo->attr);
185
186 bgp_unlink_nexthop(binfo);
187 bgp_info_extra_free(&binfo->extra);
188 bgp_info_mpath_free(&binfo->mpath);
189
190 peer_unlock(binfo->peer); /* bgp_info peer reference */
191
192 XFREE(MTYPE_BGP_ROUTE, binfo);
193 }
194
195 struct bgp_info *bgp_info_lock(struct bgp_info *binfo)
196 {
197 binfo->lock++;
198 return binfo;
199 }
200
201 struct bgp_info *bgp_info_unlock(struct bgp_info *binfo)
202 {
203 assert(binfo && binfo->lock > 0);
204 binfo->lock--;
205
206 if (binfo->lock == 0) {
207 #if 0
208 zlog_debug ("%s: unlocked and freeing", __func__);
209 zlog_backtrace (LOG_DEBUG);
210 #endif
211 bgp_info_free(binfo);
212 return NULL;
213 }
214
215 #if 0
216 if (binfo->lock == 1)
217 {
218 zlog_debug ("%s: unlocked to 1", __func__);
219 zlog_backtrace (LOG_DEBUG);
220 }
221 #endif
222
223 return binfo;
224 }
225
226 void bgp_info_add(struct bgp_node *rn, struct bgp_info *ri)
227 {
228 struct bgp_info *top;
229
230 top = rn->info;
231
232 ri->next = rn->info;
233 ri->prev = NULL;
234 if (top)
235 top->prev = ri;
236 rn->info = ri;
237
238 bgp_info_lock(ri);
239 bgp_lock_node(rn);
240 peer_lock(ri->peer); /* bgp_info peer reference */
241 }
242
243 /* Do the actual removal of info from RIB, for use by bgp_process
244 completion callback *only* */
245 void bgp_info_reap(struct bgp_node *rn, struct bgp_info *ri)
246 {
247 if (ri->next)
248 ri->next->prev = ri->prev;
249 if (ri->prev)
250 ri->prev->next = ri->next;
251 else
252 rn->info = ri->next;
253
254 bgp_info_mpath_dequeue(ri);
255 bgp_info_unlock(ri);
256 bgp_unlock_node(rn);
257 }
258
259 void bgp_info_delete(struct bgp_node *rn, struct bgp_info *ri)
260 {
261 bgp_info_set_flag(rn, ri, BGP_INFO_REMOVED);
262 /* set of previous already took care of pcount */
263 UNSET_FLAG(ri->flags, BGP_INFO_VALID);
264 }
265
266 /* undo the effects of a previous call to bgp_info_delete; typically
267 called when a route is deleted and then quickly re-added before the
268 deletion has been processed */
269 void bgp_info_restore(struct bgp_node *rn, struct bgp_info *ri)
270 {
271 bgp_info_unset_flag(rn, ri, BGP_INFO_REMOVED);
272 /* unset of previous already took care of pcount */
273 SET_FLAG(ri->flags, BGP_INFO_VALID);
274 }
275
276 /* Adjust pcount as required */
277 static void bgp_pcount_adjust(struct bgp_node *rn, struct bgp_info *ri)
278 {
279 struct bgp_table *table;
280
281 assert(rn && bgp_node_table(rn));
282 assert(ri && ri->peer && ri->peer->bgp);
283
284 table = bgp_node_table(rn);
285
286 if (ri->peer == ri->peer->bgp->peer_self)
287 return;
288
289 if (!BGP_INFO_COUNTABLE(ri)
290 && CHECK_FLAG(ri->flags, BGP_INFO_COUNTED)) {
291
292 UNSET_FLAG(ri->flags, BGP_INFO_COUNTED);
293
294 /* slight hack, but more robust against errors. */
295 if (ri->peer->pcount[table->afi][table->safi])
296 ri->peer->pcount[table->afi][table->safi]--;
297 else {
298 zlog_warn(
299 "%s: Asked to decrement 0 prefix count for peer %s",
300 __func__, ri->peer->host);
301 zlog_backtrace(LOG_WARNING);
302 zlog_warn("%s: Please report to Quagga bugzilla",
303 __func__);
304 }
305 } else if (BGP_INFO_COUNTABLE(ri)
306 && !CHECK_FLAG(ri->flags, BGP_INFO_COUNTED)) {
307 SET_FLAG(ri->flags, BGP_INFO_COUNTED);
308 ri->peer->pcount[table->afi][table->safi]++;
309 }
310 }
311
312 static int bgp_label_index_differs(struct bgp_info *ri1, struct bgp_info *ri2)
313 {
314 return (!(ri1->attr->label_index == ri2->attr->label_index));
315 }
316
317 /* Set/unset bgp_info flags, adjusting any other state as needed.
318 * This is here primarily to keep prefix-count in check.
319 */
320 void bgp_info_set_flag(struct bgp_node *rn, struct bgp_info *ri, u_int32_t flag)
321 {
322 SET_FLAG(ri->flags, flag);
323
324 /* early bath if we know it's not a flag that changes countability state
325 */
326 if (!CHECK_FLAG(flag,
327 BGP_INFO_VALID | BGP_INFO_HISTORY | BGP_INFO_REMOVED))
328 return;
329
330 bgp_pcount_adjust(rn, ri);
331 }
332
333 void bgp_info_unset_flag(struct bgp_node *rn, struct bgp_info *ri,
334 u_int32_t flag)
335 {
336 UNSET_FLAG(ri->flags, flag);
337
338 /* early bath if we know it's not a flag that changes countability state
339 */
340 if (!CHECK_FLAG(flag,
341 BGP_INFO_VALID | BGP_INFO_HISTORY | BGP_INFO_REMOVED))
342 return;
343
344 bgp_pcount_adjust(rn, ri);
345 }
346
347 /* Get MED value. If MED value is missing and "bgp bestpath
348 missing-as-worst" is specified, treat it as the worst value. */
349 static u_int32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
350 {
351 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
352 return attr->med;
353 else {
354 if (bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST))
355 return BGP_MED_MAX;
356 else
357 return 0;
358 }
359 }
360
361 void bgp_info_path_with_addpath_rx_str(struct bgp_info *ri, char *buf)
362 {
363 if (ri->addpath_rx_id)
364 sprintf(buf, "path %s (addpath rxid %d)", ri->peer->host,
365 ri->addpath_rx_id);
366 else
367 sprintf(buf, "path %s", ri->peer->host);
368 }
369
370 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
371 */
372 static int bgp_info_cmp(struct bgp *bgp, struct bgp_info *new,
373 struct bgp_info *exist, int *paths_eq,
374 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
375 char *pfx_buf, afi_t afi, safi_t safi)
376 {
377 struct attr *newattr, *existattr;
378 bgp_peer_sort_t new_sort;
379 bgp_peer_sort_t exist_sort;
380 u_int32_t new_pref;
381 u_int32_t exist_pref;
382 u_int32_t new_med;
383 u_int32_t exist_med;
384 u_int32_t new_weight;
385 u_int32_t exist_weight;
386 uint32_t newm, existm;
387 struct in_addr new_id;
388 struct in_addr exist_id;
389 int new_cluster;
390 int exist_cluster;
391 int internal_as_route;
392 int confed_as_route;
393 int ret;
394 char new_buf[PATH_ADDPATH_STR_BUFFER];
395 char exist_buf[PATH_ADDPATH_STR_BUFFER];
396 u_int32_t new_mm_seq;
397 u_int32_t exist_mm_seq;
398
399 *paths_eq = 0;
400
401 /* 0. Null check. */
402 if (new == NULL) {
403 if (debug)
404 zlog_debug("%s: new is NULL", pfx_buf);
405 return 0;
406 }
407
408 if (debug)
409 bgp_info_path_with_addpath_rx_str(new, new_buf);
410
411 if (exist == NULL) {
412 if (debug)
413 zlog_debug("%s: %s is the initial bestpath", pfx_buf,
414 new_buf);
415 return 1;
416 }
417
418 if (debug) {
419 bgp_info_path_with_addpath_rx_str(exist, exist_buf);
420 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
421 pfx_buf, new_buf, new->flags, exist_buf,
422 exist->flags);
423 }
424
425 newattr = new->attr;
426 existattr = exist->attr;
427
428 /* For EVPN routes, we cannot just go by local vs remote, we have to
429 * look at the MAC mobility sequence number, if present.
430 */
431 if (safi == SAFI_EVPN) {
432 /* This is an error condition described in RFC 7432 Section
433 * 15.2. The RFC
434 * states that in this scenario "the PE MUST alert the operator"
435 * but it
436 * does not state what other action to take. In order to provide
437 * some
438 * consistency in this scenario we are going to prefer the path
439 * with the
440 * sticky flag.
441 */
442 if (newattr->sticky != existattr->sticky) {
443 if (!debug) {
444 prefix2str(&new->net->p, pfx_buf,
445 sizeof(*pfx_buf)
446 * PREFIX2STR_BUFFER);
447 bgp_info_path_with_addpath_rx_str(new, new_buf);
448 bgp_info_path_with_addpath_rx_str(exist,
449 exist_buf);
450 }
451
452 if (newattr->sticky && !existattr->sticky) {
453 zlog_warn(
454 "%s: %s wins over %s due to sticky MAC flag",
455 pfx_buf, new_buf, exist_buf);
456 return 1;
457 }
458
459 if (!newattr->sticky && existattr->sticky) {
460 zlog_warn(
461 "%s: %s loses to %s due to sticky MAC flag",
462 pfx_buf, new_buf, exist_buf);
463 return 0;
464 }
465 }
466
467 new_mm_seq = mac_mobility_seqnum(newattr);
468 exist_mm_seq = mac_mobility_seqnum(existattr);
469
470 if (new_mm_seq > exist_mm_seq) {
471 if (debug)
472 zlog_debug(
473 "%s: %s wins over %s due to MM seq %u > %u",
474 pfx_buf, new_buf, exist_buf, new_mm_seq,
475 exist_mm_seq);
476 return 1;
477 }
478
479 if (new_mm_seq < exist_mm_seq) {
480 if (debug)
481 zlog_debug(
482 "%s: %s loses to %s due to MM seq %u < %u",
483 pfx_buf, new_buf, exist_buf, new_mm_seq,
484 exist_mm_seq);
485 return 0;
486 }
487 }
488
489 /* 1. Weight check. */
490 new_weight = exist_weight = 0;
491
492 new_weight = newattr->weight;
493 exist_weight = existattr->weight;
494
495 if (new_weight > exist_weight) {
496 if (debug)
497 zlog_debug("%s: %s wins over %s due to weight %d > %d",
498 pfx_buf, new_buf, exist_buf, new_weight,
499 exist_weight);
500 return 1;
501 }
502
503 if (new_weight < exist_weight) {
504 if (debug)
505 zlog_debug("%s: %s loses to %s due to weight %d < %d",
506 pfx_buf, new_buf, exist_buf, new_weight,
507 exist_weight);
508 return 0;
509 }
510
511 /* 2. Local preference check. */
512 new_pref = exist_pref = bgp->default_local_pref;
513
514 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
515 new_pref = newattr->local_pref;
516 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
517 exist_pref = existattr->local_pref;
518
519 if (new_pref > exist_pref) {
520 if (debug)
521 zlog_debug(
522 "%s: %s wins over %s due to localpref %d > %d",
523 pfx_buf, new_buf, exist_buf, new_pref,
524 exist_pref);
525 return 1;
526 }
527
528 if (new_pref < exist_pref) {
529 if (debug)
530 zlog_debug(
531 "%s: %s loses to %s due to localpref %d < %d",
532 pfx_buf, new_buf, exist_buf, new_pref,
533 exist_pref);
534 return 0;
535 }
536
537 /* 3. Local route check. We prefer:
538 * - BGP_ROUTE_STATIC
539 * - BGP_ROUTE_AGGREGATE
540 * - BGP_ROUTE_REDISTRIBUTE
541 */
542 if (!(new->sub_type == BGP_ROUTE_NORMAL)) {
543 if (debug)
544 zlog_debug(
545 "%s: %s wins over %s due to preferred BGP_ROUTE type",
546 pfx_buf, new_buf, exist_buf);
547 return 1;
548 }
549
550 if (!(exist->sub_type == BGP_ROUTE_NORMAL)) {
551 if (debug)
552 zlog_debug(
553 "%s: %s loses to %s due to preferred BGP_ROUTE type",
554 pfx_buf, new_buf, exist_buf);
555 return 0;
556 }
557
558 /* 4. AS path length check. */
559 if (!bgp_flag_check(bgp, BGP_FLAG_ASPATH_IGNORE)) {
560 int exist_hops = aspath_count_hops(existattr->aspath);
561 int exist_confeds = aspath_count_confeds(existattr->aspath);
562
563 if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_CONFED)) {
564 int aspath_hops;
565
566 aspath_hops = aspath_count_hops(newattr->aspath);
567 aspath_hops += aspath_count_confeds(newattr->aspath);
568
569 if (aspath_hops < (exist_hops + exist_confeds)) {
570 if (debug)
571 zlog_debug(
572 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
573 pfx_buf, new_buf, exist_buf,
574 aspath_hops,
575 (exist_hops + exist_confeds));
576 return 1;
577 }
578
579 if (aspath_hops > (exist_hops + exist_confeds)) {
580 if (debug)
581 zlog_debug(
582 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
583 pfx_buf, new_buf, exist_buf,
584 aspath_hops,
585 (exist_hops + exist_confeds));
586 return 0;
587 }
588 } else {
589 int newhops = aspath_count_hops(newattr->aspath);
590
591 if (newhops < exist_hops) {
592 if (debug)
593 zlog_debug(
594 "%s: %s wins over %s due to aspath hopcount %d < %d",
595 pfx_buf, new_buf, exist_buf,
596 newhops, exist_hops);
597 return 1;
598 }
599
600 if (newhops > exist_hops) {
601 if (debug)
602 zlog_debug(
603 "%s: %s loses to %s due to aspath hopcount %d > %d",
604 pfx_buf, new_buf, exist_buf,
605 newhops, exist_hops);
606 return 0;
607 }
608 }
609 }
610
611 /* 5. Origin check. */
612 if (newattr->origin < existattr->origin) {
613 if (debug)
614 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
615 pfx_buf, new_buf, exist_buf,
616 bgp_origin_long_str[newattr->origin],
617 bgp_origin_long_str[existattr->origin]);
618 return 1;
619 }
620
621 if (newattr->origin > existattr->origin) {
622 if (debug)
623 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
624 pfx_buf, new_buf, exist_buf,
625 bgp_origin_long_str[newattr->origin],
626 bgp_origin_long_str[existattr->origin]);
627 return 0;
628 }
629
630 /* 6. MED check. */
631 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
632 && aspath_count_hops(existattr->aspath) == 0);
633 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
634 && aspath_count_confeds(existattr->aspath) > 0
635 && aspath_count_hops(newattr->aspath) == 0
636 && aspath_count_hops(existattr->aspath) == 0);
637
638 if (bgp_flag_check(bgp, BGP_FLAG_ALWAYS_COMPARE_MED)
639 || (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED) && confed_as_route)
640 || aspath_cmp_left(newattr->aspath, existattr->aspath)
641 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
642 || internal_as_route) {
643 new_med = bgp_med_value(new->attr, bgp);
644 exist_med = bgp_med_value(exist->attr, bgp);
645
646 if (new_med < exist_med) {
647 if (debug)
648 zlog_debug(
649 "%s: %s wins over %s due to MED %d < %d",
650 pfx_buf, new_buf, exist_buf, new_med,
651 exist_med);
652 return 1;
653 }
654
655 if (new_med > exist_med) {
656 if (debug)
657 zlog_debug(
658 "%s: %s loses to %s due to MED %d > %d",
659 pfx_buf, new_buf, exist_buf, new_med,
660 exist_med);
661 return 0;
662 }
663 }
664
665 /* 7. Peer type check. */
666 new_sort = new->peer->sort;
667 exist_sort = exist->peer->sort;
668
669 if (new_sort == BGP_PEER_EBGP
670 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
671 if (debug)
672 zlog_debug(
673 "%s: %s wins over %s due to eBGP peer > iBGP peer",
674 pfx_buf, new_buf, exist_buf);
675 return 1;
676 }
677
678 if (exist_sort == BGP_PEER_EBGP
679 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
680 if (debug)
681 zlog_debug(
682 "%s: %s loses to %s due to iBGP peer < eBGP peer",
683 pfx_buf, new_buf, exist_buf);
684 return 0;
685 }
686
687 /* 8. IGP metric check. */
688 newm = existm = 0;
689
690 if (new->extra)
691 newm = new->extra->igpmetric;
692 if (exist->extra)
693 existm = exist->extra->igpmetric;
694
695 if (newm < existm) {
696 if (debug)
697 zlog_debug(
698 "%s: %s wins over %s due to IGP metric %d < %d",
699 pfx_buf, new_buf, exist_buf, newm, existm);
700 ret = 1;
701 }
702
703 if (newm > existm) {
704 if (debug)
705 zlog_debug(
706 "%s: %s loses to %s due to IGP metric %d > %d",
707 pfx_buf, new_buf, exist_buf, newm, existm);
708 ret = 0;
709 }
710
711 /* 9. Same IGP metric. Compare the cluster list length as
712 representative of IGP hops metric. Rewrite the metric value
713 pair (newm, existm) with the cluster list length. Prefer the
714 path with smaller cluster list length. */
715 if (newm == existm) {
716 if (peer_sort(new->peer) == BGP_PEER_IBGP
717 && peer_sort(exist->peer) == BGP_PEER_IBGP
718 && (mpath_cfg == NULL
719 || CHECK_FLAG(
720 mpath_cfg->ibgp_flags,
721 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN))) {
722 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
723 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
724
725 if (newm < existm) {
726 if (debug)
727 zlog_debug(
728 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
729 pfx_buf, new_buf, exist_buf,
730 newm, existm);
731 ret = 1;
732 }
733
734 if (newm > existm) {
735 if (debug)
736 zlog_debug(
737 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
738 pfx_buf, new_buf, exist_buf,
739 newm, existm);
740 ret = 0;
741 }
742 }
743 }
744
745 /* 10. confed-external vs. confed-internal */
746 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
747 if (new_sort == BGP_PEER_CONFED
748 && exist_sort == BGP_PEER_IBGP) {
749 if (debug)
750 zlog_debug(
751 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
752 pfx_buf, new_buf, exist_buf);
753 return 1;
754 }
755
756 if (exist_sort == BGP_PEER_CONFED
757 && new_sort == BGP_PEER_IBGP) {
758 if (debug)
759 zlog_debug(
760 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
761 pfx_buf, new_buf, exist_buf);
762 return 0;
763 }
764 }
765
766 /* 11. Maximum path check. */
767 if (newm == existm) {
768 /* If one path has a label but the other does not, do not treat
769 * them as equals for multipath
770 */
771 if ((new->extra &&bgp_is_valid_label(&new->extra->label))
772 != (exist->extra
773 && bgp_is_valid_label(&exist->extra->label))) {
774 if (debug)
775 zlog_debug(
776 "%s: %s and %s cannot be multipath, one has a label while the other does not",
777 pfx_buf, new_buf, exist_buf);
778 } else if (bgp_flag_check(bgp,
779 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
780
781 /*
782 * For the two paths, all comparison steps till IGP
783 * metric
784 * have succeeded - including AS_PATH hop count. Since
785 * 'bgp
786 * bestpath as-path multipath-relax' knob is on, we
787 * don't need
788 * an exact match of AS_PATH. Thus, mark the paths are
789 * equal.
790 * That will trigger both these paths to get into the
791 * multipath
792 * array.
793 */
794 *paths_eq = 1;
795
796 if (debug)
797 zlog_debug(
798 "%s: %s and %s are equal via multipath-relax",
799 pfx_buf, new_buf, exist_buf);
800 } else if (new->peer->sort == BGP_PEER_IBGP) {
801 if (aspath_cmp(new->attr->aspath,
802 exist->attr->aspath)) {
803 *paths_eq = 1;
804
805 if (debug)
806 zlog_debug(
807 "%s: %s and %s are equal via matching aspaths",
808 pfx_buf, new_buf, exist_buf);
809 }
810 } else if (new->peer->as == exist->peer->as) {
811 *paths_eq = 1;
812
813 if (debug)
814 zlog_debug(
815 "%s: %s and %s are equal via same remote-as",
816 pfx_buf, new_buf, exist_buf);
817 }
818 } else {
819 /*
820 * TODO: If unequal cost ibgp multipath is enabled we can
821 * mark the paths as equal here instead of returning
822 */
823 if (debug) {
824 if (ret == 1)
825 zlog_debug(
826 "%s: %s wins over %s after IGP metric comparison",
827 pfx_buf, new_buf, exist_buf);
828 else
829 zlog_debug(
830 "%s: %s loses to %s after IGP metric comparison",
831 pfx_buf, new_buf, exist_buf);
832 }
833 return ret;
834 }
835
836 /* 12. If both paths are external, prefer the path that was received
837 first (the oldest one). This step minimizes route-flap, since a
838 newer path won't displace an older one, even if it was the
839 preferred route based on the additional decision criteria below. */
840 if (!bgp_flag_check(bgp, BGP_FLAG_COMPARE_ROUTER_ID)
841 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
842 if (CHECK_FLAG(new->flags, BGP_INFO_SELECTED)) {
843 if (debug)
844 zlog_debug(
845 "%s: %s wins over %s due to oldest external",
846 pfx_buf, new_buf, exist_buf);
847 return 1;
848 }
849
850 if (CHECK_FLAG(exist->flags, BGP_INFO_SELECTED)) {
851 if (debug)
852 zlog_debug(
853 "%s: %s loses to %s due to oldest external",
854 pfx_buf, new_buf, exist_buf);
855 return 0;
856 }
857 }
858
859 /* 13. Router-ID comparision. */
860 /* If one of the paths is "stale", the corresponding peer router-id will
861 * be 0 and would always win over the other path. If originator id is
862 * used for the comparision, it will decide which path is better.
863 */
864 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
865 new_id.s_addr = newattr->originator_id.s_addr;
866 else
867 new_id.s_addr = new->peer->remote_id.s_addr;
868 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
869 exist_id.s_addr = existattr->originator_id.s_addr;
870 else
871 exist_id.s_addr = exist->peer->remote_id.s_addr;
872
873 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
874 if (debug)
875 zlog_debug(
876 "%s: %s wins over %s due to Router-ID comparison",
877 pfx_buf, new_buf, exist_buf);
878 return 1;
879 }
880
881 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
882 if (debug)
883 zlog_debug(
884 "%s: %s loses to %s due to Router-ID comparison",
885 pfx_buf, new_buf, exist_buf);
886 return 0;
887 }
888
889 /* 14. Cluster length comparision. */
890 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
891 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
892
893 if (new_cluster < exist_cluster) {
894 if (debug)
895 zlog_debug(
896 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
897 pfx_buf, new_buf, exist_buf, new_cluster,
898 exist_cluster);
899 return 1;
900 }
901
902 if (new_cluster > exist_cluster) {
903 if (debug)
904 zlog_debug(
905 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
906 pfx_buf, new_buf, exist_buf, new_cluster,
907 exist_cluster);
908 return 0;
909 }
910
911 /* 15. Neighbor address comparision. */
912 /* Do this only if neither path is "stale" as stale paths do not have
913 * valid peer information (as the connection may or may not be up).
914 */
915 if (CHECK_FLAG(exist->flags, BGP_INFO_STALE)) {
916 if (debug)
917 zlog_debug(
918 "%s: %s wins over %s due to latter path being STALE",
919 pfx_buf, new_buf, exist_buf);
920 return 1;
921 }
922
923 if (CHECK_FLAG(new->flags, BGP_INFO_STALE)) {
924 if (debug)
925 zlog_debug(
926 "%s: %s loses to %s due to former path being STALE",
927 pfx_buf, new_buf, exist_buf);
928 return 0;
929 }
930
931 /* locally configured routes to advertise do not have su_remote */
932 if (new->peer->su_remote == NULL)
933 return 0;
934 if (exist->peer->su_remote == NULL)
935 return 1;
936
937 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
938
939 if (ret == 1) {
940 if (debug)
941 zlog_debug(
942 "%s: %s loses to %s due to Neighor IP comparison",
943 pfx_buf, new_buf, exist_buf);
944 return 0;
945 }
946
947 if (ret == -1) {
948 if (debug)
949 zlog_debug(
950 "%s: %s wins over %s due to Neighor IP comparison",
951 pfx_buf, new_buf, exist_buf);
952 return 1;
953 }
954
955 if (debug)
956 zlog_debug("%s: %s wins over %s due to nothing left to compare",
957 pfx_buf, new_buf, exist_buf);
958
959 return 1;
960 }
961
962 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
963 * is preferred, or 0 if they are the same (usually will only occur if
964 * multipath is enabled
965 * This version is compatible with */
966 int bgp_info_cmp_compatible(struct bgp *bgp, struct bgp_info *new,
967 struct bgp_info *exist, char *pfx_buf, afi_t afi,
968 safi_t safi)
969 {
970 int paths_eq;
971 int ret;
972 ret = bgp_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf, afi,
973 safi);
974
975 if (paths_eq)
976 ret = 0;
977 else {
978 if (ret == 1)
979 ret = -1;
980 else
981 ret = 1;
982 }
983 return ret;
984 }
985
986 static enum filter_type bgp_input_filter(struct peer *peer, struct prefix *p,
987 struct attr *attr, afi_t afi,
988 safi_t safi)
989 {
990 struct bgp_filter *filter;
991
992 filter = &peer->filter[afi][safi];
993
994 #define FILTER_EXIST_WARN(F, f, filter) \
995 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
996 zlog_warn("%s: Could not find configured input %s-list %s!", \
997 peer->host, #f, F##_IN_NAME(filter));
998
999 if (DISTRIBUTE_IN_NAME(filter)) {
1000 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1001
1002 if (access_list_apply(DISTRIBUTE_IN(filter), p) == FILTER_DENY)
1003 return FILTER_DENY;
1004 }
1005
1006 if (PREFIX_LIST_IN_NAME(filter)) {
1007 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1008
1009 if (prefix_list_apply(PREFIX_LIST_IN(filter), p) == PREFIX_DENY)
1010 return FILTER_DENY;
1011 }
1012
1013 if (FILTER_LIST_IN_NAME(filter)) {
1014 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1015
1016 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1017 == AS_FILTER_DENY)
1018 return FILTER_DENY;
1019 }
1020
1021 return FILTER_PERMIT;
1022 #undef FILTER_EXIST_WARN
1023 }
1024
1025 static enum filter_type bgp_output_filter(struct peer *peer, struct prefix *p,
1026 struct attr *attr, afi_t afi,
1027 safi_t safi)
1028 {
1029 struct bgp_filter *filter;
1030
1031 filter = &peer->filter[afi][safi];
1032
1033 #define FILTER_EXIST_WARN(F, f, filter) \
1034 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1035 zlog_warn("%s: Could not find configured output %s-list %s!", \
1036 peer->host, #f, F##_OUT_NAME(filter));
1037
1038 if (DISTRIBUTE_OUT_NAME(filter)) {
1039 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1040
1041 if (access_list_apply(DISTRIBUTE_OUT(filter), p) == FILTER_DENY)
1042 return FILTER_DENY;
1043 }
1044
1045 if (PREFIX_LIST_OUT_NAME(filter)) {
1046 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1047
1048 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1049 == PREFIX_DENY)
1050 return FILTER_DENY;
1051 }
1052
1053 if (FILTER_LIST_OUT_NAME(filter)) {
1054 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1055
1056 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1057 == AS_FILTER_DENY)
1058 return FILTER_DENY;
1059 }
1060
1061 return FILTER_PERMIT;
1062 #undef FILTER_EXIST_WARN
1063 }
1064
1065 /* If community attribute includes no_export then return 1. */
1066 static int bgp_community_filter(struct peer *peer, struct attr *attr)
1067 {
1068 if (attr->community) {
1069 /* NO_ADVERTISE check. */
1070 if (community_include(attr->community, COMMUNITY_NO_ADVERTISE))
1071 return 1;
1072
1073 /* NO_EXPORT check. */
1074 if (peer->sort == BGP_PEER_EBGP
1075 && community_include(attr->community, COMMUNITY_NO_EXPORT))
1076 return 1;
1077
1078 /* NO_EXPORT_SUBCONFED check. */
1079 if (peer->sort == BGP_PEER_EBGP
1080 || peer->sort == BGP_PEER_CONFED)
1081 if (community_include(attr->community,
1082 COMMUNITY_NO_EXPORT_SUBCONFED))
1083 return 1;
1084 }
1085 return 0;
1086 }
1087
1088 /* Route reflection loop check. */
1089 static int bgp_cluster_filter(struct peer *peer, struct attr *attr)
1090 {
1091 struct in_addr cluster_id;
1092
1093 if (attr->cluster) {
1094 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1095 cluster_id = peer->bgp->cluster_id;
1096 else
1097 cluster_id = peer->bgp->router_id;
1098
1099 if (cluster_loop_check(attr->cluster, cluster_id))
1100 return 1;
1101 }
1102 return 0;
1103 }
1104
1105 static int bgp_input_modifier(struct peer *peer, struct prefix *p,
1106 struct attr *attr, afi_t afi, safi_t safi,
1107 const char *rmap_name)
1108 {
1109 struct bgp_filter *filter;
1110 struct bgp_info info;
1111 route_map_result_t ret;
1112 struct route_map *rmap = NULL;
1113
1114 filter = &peer->filter[afi][safi];
1115
1116 /* Apply default weight value. */
1117 if (peer->weight[afi][safi])
1118 attr->weight = peer->weight[afi][safi];
1119
1120 if (rmap_name) {
1121 rmap = route_map_lookup_by_name(rmap_name);
1122
1123 if (rmap == NULL)
1124 return RMAP_DENY;
1125 } else {
1126 if (ROUTE_MAP_IN_NAME(filter)) {
1127 rmap = ROUTE_MAP_IN(filter);
1128
1129 if (rmap == NULL)
1130 return RMAP_DENY;
1131 }
1132 }
1133
1134 /* Route map apply. */
1135 if (rmap) {
1136 /* Duplicate current value to new strucutre for modification. */
1137 info.peer = peer;
1138 info.attr = attr;
1139
1140 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1141
1142 /* Apply BGP route map to the attribute. */
1143 ret = route_map_apply(rmap, p, RMAP_BGP, &info);
1144
1145 peer->rmap_type = 0;
1146
1147 if (ret == RMAP_DENYMATCH) {
1148 /* Free newly generated AS path and community by
1149 * route-map. */
1150 bgp_attr_flush(attr);
1151 return RMAP_DENY;
1152 }
1153 }
1154 return RMAP_PERMIT;
1155 }
1156
1157 static int bgp_output_modifier(struct peer *peer, struct prefix *p,
1158 struct attr *attr, afi_t afi, safi_t safi,
1159 const char *rmap_name)
1160 {
1161 struct bgp_filter *filter;
1162 struct bgp_info info;
1163 route_map_result_t ret;
1164 struct route_map *rmap = NULL;
1165
1166 filter = &peer->filter[afi][safi];
1167
1168 /* Apply default weight value. */
1169 if (peer->weight[afi][safi])
1170 attr->weight = peer->weight[afi][safi];
1171
1172 if (rmap_name) {
1173 rmap = route_map_lookup_by_name(rmap_name);
1174
1175 if (rmap == NULL)
1176 return RMAP_DENY;
1177 } else {
1178 if (ROUTE_MAP_OUT_NAME(filter)) {
1179 rmap = ROUTE_MAP_OUT(filter);
1180
1181 if (rmap == NULL)
1182 return RMAP_DENY;
1183 }
1184 }
1185
1186 /* Route map apply. */
1187 if (rmap) {
1188 /* Duplicate current value to new strucutre for modification. */
1189 info.peer = peer;
1190 info.attr = attr;
1191
1192 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1193
1194 /* Apply BGP route map to the attribute. */
1195 ret = route_map_apply(rmap, p, RMAP_BGP, &info);
1196
1197 peer->rmap_type = 0;
1198
1199 if (ret == RMAP_DENYMATCH)
1200 /* caller has multiple error paths with bgp_attr_flush()
1201 */
1202 return RMAP_DENY;
1203 }
1204 return RMAP_PERMIT;
1205 }
1206
1207 /* If this is an EBGP peer with remove-private-AS */
1208 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1209 struct peer *peer, struct attr *attr)
1210 {
1211 if (peer->sort == BGP_PEER_EBGP
1212 && (peer_af_flag_check(peer, afi, safi,
1213 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1214 || peer_af_flag_check(peer, afi, safi,
1215 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1216 || peer_af_flag_check(peer, afi, safi,
1217 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1218 || peer_af_flag_check(peer, afi, safi,
1219 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1220 // Take action on the entire aspath
1221 if (peer_af_flag_check(peer, afi, safi,
1222 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1223 || peer_af_flag_check(peer, afi, safi,
1224 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1225 if (peer_af_flag_check(
1226 peer, afi, safi,
1227 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1228 attr->aspath = aspath_replace_private_asns(
1229 attr->aspath, bgp->as);
1230
1231 // The entire aspath consists of private ASNs so create
1232 // an empty aspath
1233 else if (aspath_private_as_check(attr->aspath))
1234 attr->aspath = aspath_empty_get();
1235
1236 // There are some public and some private ASNs, remove
1237 // the private ASNs
1238 else
1239 attr->aspath = aspath_remove_private_asns(
1240 attr->aspath);
1241 }
1242
1243 // 'all' was not specified so the entire aspath must be private
1244 // ASNs
1245 // for us to do anything
1246 else if (aspath_private_as_check(attr->aspath)) {
1247 if (peer_af_flag_check(
1248 peer, afi, safi,
1249 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1250 attr->aspath = aspath_replace_private_asns(
1251 attr->aspath, bgp->as);
1252 else
1253 attr->aspath = aspath_empty_get();
1254 }
1255 }
1256 }
1257
1258 /* If this is an EBGP peer with as-override */
1259 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1260 struct peer *peer, struct attr *attr)
1261 {
1262 if (peer->sort == BGP_PEER_EBGP
1263 && peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1264 if (aspath_single_asn_check(attr->aspath, peer->as))
1265 attr->aspath = aspath_replace_specific_asn(
1266 attr->aspath, peer->as, bgp->as);
1267 }
1268 }
1269
1270 static void subgroup_announce_reset_nhop(u_char family, struct attr *attr)
1271 {
1272 if (family == AF_INET)
1273 attr->nexthop.s_addr = 0;
1274 if (family == AF_INET6)
1275 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1276 }
1277
1278 int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri,
1279 struct update_subgroup *subgrp, struct prefix *p,
1280 struct attr *attr)
1281 {
1282 struct bgp_filter *filter;
1283 struct peer *from;
1284 struct peer *peer;
1285 struct peer *onlypeer;
1286 struct bgp *bgp;
1287 struct attr *riattr;
1288 struct peer_af *paf;
1289 char buf[PREFIX_STRLEN];
1290 int ret;
1291 int transparent;
1292 int reflect;
1293 afi_t afi;
1294 safi_t safi;
1295 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1296
1297 if (DISABLE_BGP_ANNOUNCE)
1298 return 0;
1299
1300 afi = SUBGRP_AFI(subgrp);
1301 safi = SUBGRP_SAFI(subgrp);
1302 peer = SUBGRP_PEER(subgrp);
1303 onlypeer = NULL;
1304 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
1305 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1306
1307 from = ri->peer;
1308 filter = &peer->filter[afi][safi];
1309 bgp = SUBGRP_INST(subgrp);
1310 riattr = bgp_info_mpath_count(ri) ? bgp_info_mpath_attr(ri) : ri->attr;
1311
1312 #if ENABLE_BGP_VNC
1313 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
1314 && ((ri->type == ZEBRA_ROUTE_BGP_DIRECT)
1315 || (ri->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
1316
1317 /*
1318 * direct and direct_ext type routes originate internally even
1319 * though they can have peer pointers that reference other
1320 * systems
1321 */
1322 prefix2str(p, buf, PREFIX_STRLEN);
1323 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe",
1324 __func__, buf);
1325 samepeer_safe = 1;
1326 }
1327 #endif
1328
1329 /* With addpath we may be asked to TX all kinds of paths so make sure
1330 * ri is valid */
1331 if (!CHECK_FLAG(ri->flags, BGP_INFO_VALID)
1332 || CHECK_FLAG(ri->flags, BGP_INFO_HISTORY)
1333 || CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
1334 return 0;
1335 }
1336
1337 /* If this is not the bestpath then check to see if there is an enabled
1338 * addpath
1339 * feature that requires us to advertise it */
1340 if (!CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) {
1341 if (!bgp_addpath_tx_path(peer, afi, safi, ri)) {
1342 return 0;
1343 }
1344 }
1345
1346 /* Aggregate-address suppress check. */
1347 if (ri->extra && ri->extra->suppress)
1348 if (!UNSUPPRESS_MAP_NAME(filter)) {
1349 return 0;
1350 }
1351
1352 /* If it's labeled safi, make sure the route has a valid label. */
1353 if (safi == SAFI_LABELED_UNICAST) {
1354 mpls_label_t label = bgp_adv_label(rn, ri, peer, afi, safi);
1355 if (!bgp_is_valid_label(&label)) {
1356 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1357 zlog_debug("u%" PRIu64 ":s%" PRIu64
1358 " %s/%d is filtered - no label (%p)",
1359 subgrp->update_group->id, subgrp->id,
1360 inet_ntop(p->family, &p->u.prefix,
1361 buf, SU_ADDRSTRLEN),
1362 p->prefixlen, &label);
1363 return 0;
1364 }
1365 }
1366
1367 /* Do not send back route to sender. */
1368 if (onlypeer && from == onlypeer) {
1369 return 0;
1370 }
1371
1372 /* Do not send the default route in the BGP table if the neighbor is
1373 * configured for default-originate */
1374 if (CHECK_FLAG(peer->af_flags[afi][safi],
1375 PEER_FLAG_DEFAULT_ORIGINATE)) {
1376 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
1377 return 0;
1378 else if (p->family == AF_INET6 && p->prefixlen == 0)
1379 return 0;
1380 }
1381
1382 /* Transparency check. */
1383 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
1384 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1385 transparent = 1;
1386 else
1387 transparent = 0;
1388
1389 /* If community is not disabled check the no-export and local. */
1390 if (!transparent && bgp_community_filter(peer, riattr)) {
1391 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1392 zlog_debug(
1393 "subgrpannouncecheck: community filter check fail");
1394 return 0;
1395 }
1396
1397 /* If the attribute has originator-id and it is same as remote
1398 peer's id. */
1399 if (onlypeer && riattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
1400 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &riattr->originator_id))) {
1401 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1402 zlog_debug(
1403 "%s [Update:SEND] %s originator-id is same as "
1404 "remote router-id",
1405 onlypeer->host,
1406 prefix2str(p, buf, sizeof(buf)));
1407 return 0;
1408 }
1409
1410 /* ORF prefix-list filter check */
1411 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
1412 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
1413 || CHECK_FLAG(peer->af_cap[afi][safi],
1414 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
1415 if (peer->orf_plist[afi][safi]) {
1416 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
1417 == PREFIX_DENY) {
1418 if (bgp_debug_update(NULL, p,
1419 subgrp->update_group, 0))
1420 zlog_debug(
1421 "%s [Update:SEND] %s is filtered via ORF",
1422 peer->host,
1423 prefix2str(p, buf,
1424 sizeof(buf)));
1425 return 0;
1426 }
1427 }
1428
1429 /* Output filter check. */
1430 if (bgp_output_filter(peer, p, riattr, afi, safi) == FILTER_DENY) {
1431 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1432 zlog_debug("%s [Update:SEND] %s is filtered",
1433 peer->host, prefix2str(p, buf, sizeof(buf)));
1434 return 0;
1435 }
1436
1437 #ifdef BGP_SEND_ASPATH_CHECK
1438 /* AS path loop check. */
1439 if (onlypeer && aspath_loop_check(riattr->aspath, onlypeer->as)) {
1440 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1441 zlog_debug(
1442 "%s [Update:SEND] suppress announcement to peer AS %u "
1443 "that is part of AS path.",
1444 onlypeer->host, onlypeer->as);
1445 return 0;
1446 }
1447 #endif /* BGP_SEND_ASPATH_CHECK */
1448
1449 /* If we're a CONFED we need to loop check the CONFED ID too */
1450 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1451 if (aspath_loop_check(riattr->aspath, bgp->confed_id)) {
1452 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1453 zlog_debug(
1454 "%s [Update:SEND] suppress announcement to peer AS %u"
1455 " is AS path.",
1456 peer->host, bgp->confed_id);
1457 return 0;
1458 }
1459 }
1460
1461 /* Route-Reflect check. */
1462 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
1463 reflect = 1;
1464 else
1465 reflect = 0;
1466
1467 /* IBGP reflection check. */
1468 if (reflect && !samepeer_safe) {
1469 /* A route from a Client peer. */
1470 if (CHECK_FLAG(from->af_flags[afi][safi],
1471 PEER_FLAG_REFLECTOR_CLIENT)) {
1472 /* Reflect to all the Non-Client peers and also to the
1473 Client peers other than the originator. Originator
1474 check
1475 is already done. So there is noting to do. */
1476 /* no bgp client-to-client reflection check. */
1477 if (bgp_flag_check(bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
1478 if (CHECK_FLAG(peer->af_flags[afi][safi],
1479 PEER_FLAG_REFLECTOR_CLIENT))
1480 return 0;
1481 } else {
1482 /* A route from a Non-client peer. Reflect to all other
1483 clients. */
1484 if (!CHECK_FLAG(peer->af_flags[afi][safi],
1485 PEER_FLAG_REFLECTOR_CLIENT))
1486 return 0;
1487 }
1488 }
1489
1490 /* For modify attribute, copy it to temporary structure. */
1491 bgp_attr_dup(attr, riattr);
1492
1493 /* If local-preference is not set. */
1494 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
1495 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
1496 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1497 attr->local_pref = bgp->default_local_pref;
1498 }
1499
1500 /* If originator-id is not set and the route is to be reflected,
1501 set the originator id */
1502 if (reflect
1503 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
1504 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
1505 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
1506 }
1507
1508 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
1509 */
1510 if (peer->sort == BGP_PEER_EBGP
1511 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
1512 if (from != bgp->peer_self && !transparent
1513 && !CHECK_FLAG(peer->af_flags[afi][safi],
1514 PEER_FLAG_MED_UNCHANGED))
1515 attr->flag &=
1516 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
1517 }
1518
1519 /* Since the nexthop attribute can vary per peer, it is not explicitly
1520 * set
1521 * in announce check, only certain flags and length (or number of
1522 * nexthops
1523 * -- for IPv6/MP_REACH) are set here in order to guide the update
1524 * formation
1525 * code in setting the nexthop(s) on a per peer basis in
1526 * reformat_peer().
1527 * Typically, the source nexthop in the attribute is preserved but in
1528 * the
1529 * scenarios where we know it will always be overwritten, we reset the
1530 * nexthop to "0" in an attempt to achieve better Update packing. An
1531 * example of this is when a prefix from each of 2 IBGP peers needs to
1532 * be
1533 * announced to an EBGP peer (and they have the same attributes barring
1534 * their nexthop).
1535 */
1536 if (reflect)
1537 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
1538
1539 #define NEXTHOP_IS_V6 \
1540 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
1541 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
1542 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
1543 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1544
1545 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
1546 * if
1547 * the peer (group) is configured to receive link-local nexthop
1548 * unchanged
1549 * and it is available in the prefix OR we're not reflecting the route
1550 * and
1551 * the peer (group) to whom we're going to announce is on a shared
1552 * network
1553 * and this is either a self-originated route or the peer is EBGP.
1554 */
1555 if (NEXTHOP_IS_V6) {
1556 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
1557 if ((CHECK_FLAG(peer->af_flags[afi][safi],
1558 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
1559 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
1560 || (!reflect && peer->shared_network
1561 && (from == bgp->peer_self
1562 || peer->sort == BGP_PEER_EBGP))) {
1563 attr->mp_nexthop_len =
1564 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
1565 }
1566
1567 /* Clear off link-local nexthop in source, whenever it is not
1568 * needed to
1569 * ensure more prefixes share the same attribute for
1570 * announcement.
1571 */
1572 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
1573 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
1574 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
1575 }
1576
1577 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
1578 bgp_peer_as_override(bgp, afi, safi, peer, attr);
1579
1580 /* Route map & unsuppress-map apply. */
1581 if (ROUTE_MAP_OUT_NAME(filter) || (ri->extra && ri->extra->suppress)) {
1582 struct bgp_info info;
1583 struct bgp_info_extra dummy_info_extra;
1584 struct attr dummy_attr;
1585
1586 info.peer = peer;
1587 info.attr = attr;
1588
1589 if (ri->extra) {
1590 memcpy(&dummy_info_extra, ri->extra,
1591 sizeof(struct bgp_info_extra));
1592 info.extra = &dummy_info_extra;
1593 }
1594
1595 /* don't confuse inbound and outbound setting */
1596 RESET_FLAG(attr->rmap_change_flags);
1597
1598 /*
1599 * The route reflector is not allowed to modify the attributes
1600 * of the reflected IBGP routes unless explicitly allowed.
1601 */
1602 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
1603 && !bgp_flag_check(bgp,
1604 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
1605 bgp_attr_dup(&dummy_attr, attr);
1606 info.attr = &dummy_attr;
1607 }
1608
1609 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1610
1611 if (ri->extra && ri->extra->suppress)
1612 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
1613 RMAP_BGP, &info);
1614 else
1615 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
1616 RMAP_BGP, &info);
1617
1618 peer->rmap_type = 0;
1619
1620 if (ret == RMAP_DENYMATCH) {
1621 bgp_attr_flush(attr);
1622 return 0;
1623 }
1624 }
1625
1626 /* After route-map has been applied, we check to see if the nexthop to
1627 * be carried in the attribute (that is used for the announcement) can
1628 * be cleared off or not. We do this in all cases where we would be
1629 * setting the nexthop to "ourselves". For IPv6, we only need to
1630 * consider
1631 * the global nexthop here; the link-local nexthop would have been
1632 * cleared
1633 * already, and if not, it is required by the update formation code.
1634 * Also see earlier comments in this function.
1635 */
1636 /*
1637 * If route-map has performed some operation on the nexthop or the peer
1638 * configuration says to pass it unchanged, we cannot reset the nexthop
1639 * here, so only attempt to do it if these aren't true. Note that the
1640 * route-map handler itself might have cleared the nexthop, if for
1641 * example,
1642 * it is configured as 'peer-address'.
1643 */
1644 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
1645 riattr->rmap_change_flags)
1646 && !transparent
1647 && !CHECK_FLAG(peer->af_flags[afi][safi],
1648 PEER_FLAG_NEXTHOP_UNCHANGED)) {
1649 /* We can reset the nexthop, if setting (or forcing) it to
1650 * 'self' */
1651 if (CHECK_FLAG(peer->af_flags[afi][safi],
1652 PEER_FLAG_NEXTHOP_SELF)
1653 || CHECK_FLAG(peer->af_flags[afi][safi],
1654 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
1655 if (!reflect
1656 || CHECK_FLAG(peer->af_flags[afi][safi],
1657 PEER_FLAG_FORCE_NEXTHOP_SELF))
1658 subgroup_announce_reset_nhop(
1659 (peer_cap_enhe(peer, afi, safi)
1660 ? AF_INET6
1661 : p->family),
1662 attr);
1663 } else if (peer->sort == BGP_PEER_EBGP) {
1664 /* Can also reset the nexthop if announcing to EBGP, but
1665 * only if
1666 * no peer in the subgroup is on a shared subnet.
1667 * Note: 3rd party nexthop currently implemented for
1668 * IPv4 only.
1669 */
1670 SUBGRP_FOREACH_PEER(subgrp, paf)
1671 {
1672 if (bgp_multiaccess_check_v4(riattr->nexthop,
1673 paf->peer))
1674 break;
1675 }
1676 if (!paf)
1677 subgroup_announce_reset_nhop(
1678 (peer_cap_enhe(peer, afi, safi)
1679 ? AF_INET6
1680 : p->family),
1681 attr);
1682 }
1683 /* If IPv6/MP and nexthop does not have any override and happens
1684 * to
1685 * be a link-local address, reset it so that we don't pass along
1686 * the
1687 * source's link-local IPv6 address to recipients who may not be
1688 * on
1689 * the same interface.
1690 */
1691 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
1692 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global))
1693 subgroup_announce_reset_nhop(AF_INET6, attr);
1694 }
1695 }
1696
1697 return 1;
1698 }
1699
1700 void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
1701 struct bgp_maxpaths_cfg *mpath_cfg,
1702 struct bgp_info_pair *result, afi_t afi, safi_t safi)
1703 {
1704 struct bgp_info *new_select;
1705 struct bgp_info *old_select;
1706 struct bgp_info *ri;
1707 struct bgp_info *ri1;
1708 struct bgp_info *ri2;
1709 struct bgp_info *nextri = NULL;
1710 int paths_eq, do_mpath, debug;
1711 struct list mp_list;
1712 char pfx_buf[PREFIX2STR_BUFFER];
1713 char path_buf[PATH_ADDPATH_STR_BUFFER];
1714
1715 bgp_mp_list_init(&mp_list);
1716 do_mpath =
1717 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
1718
1719 debug = bgp_debug_bestpath(&rn->p);
1720
1721 if (debug)
1722 prefix2str(&rn->p, pfx_buf, sizeof(pfx_buf));
1723
1724 /* bgp deterministic-med */
1725 new_select = NULL;
1726 if (bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)) {
1727
1728 /* Clear BGP_INFO_DMED_SELECTED for all paths */
1729 for (ri1 = rn->info; ri1; ri1 = ri1->next)
1730 bgp_info_unset_flag(rn, ri1, BGP_INFO_DMED_SELECTED);
1731
1732 for (ri1 = rn->info; ri1; ri1 = ri1->next) {
1733 if (CHECK_FLAG(ri1->flags, BGP_INFO_DMED_CHECK))
1734 continue;
1735 if (BGP_INFO_HOLDDOWN(ri1))
1736 continue;
1737 if (ri1->peer && ri1->peer != bgp->peer_self)
1738 if (ri1->peer->status != Established)
1739 continue;
1740
1741 new_select = ri1;
1742 if (ri1->next) {
1743 for (ri2 = ri1->next; ri2; ri2 = ri2->next) {
1744 if (CHECK_FLAG(ri2->flags,
1745 BGP_INFO_DMED_CHECK))
1746 continue;
1747 if (BGP_INFO_HOLDDOWN(ri2))
1748 continue;
1749 if (ri2->peer
1750 && ri2->peer != bgp->peer_self
1751 && !CHECK_FLAG(
1752 ri2->peer->sflags,
1753 PEER_STATUS_NSF_WAIT))
1754 if (ri2->peer->status
1755 != Established)
1756 continue;
1757
1758 if (aspath_cmp_left(ri1->attr->aspath,
1759 ri2->attr->aspath)
1760 || aspath_cmp_left_confed(
1761 ri1->attr->aspath,
1762 ri2->attr->aspath)) {
1763 if (bgp_info_cmp(bgp, ri2,
1764 new_select,
1765 &paths_eq,
1766 mpath_cfg,
1767 debug, pfx_buf,
1768 afi, safi)) {
1769 bgp_info_unset_flag(
1770 rn, new_select,
1771 BGP_INFO_DMED_SELECTED);
1772 new_select = ri2;
1773 }
1774
1775 bgp_info_set_flag(
1776 rn, ri2,
1777 BGP_INFO_DMED_CHECK);
1778 }
1779 }
1780 }
1781 bgp_info_set_flag(rn, new_select, BGP_INFO_DMED_CHECK);
1782 bgp_info_set_flag(rn, new_select,
1783 BGP_INFO_DMED_SELECTED);
1784
1785 if (debug) {
1786 bgp_info_path_with_addpath_rx_str(new_select,
1787 path_buf);
1788 zlog_debug("%s: %s is the bestpath from AS %d",
1789 pfx_buf, path_buf,
1790 aspath_get_first_as(
1791 new_select->attr->aspath));
1792 }
1793 }
1794 }
1795
1796 /* Check old selected route and new selected route. */
1797 old_select = NULL;
1798 new_select = NULL;
1799 for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1);
1800 ri = nextri) {
1801 if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED))
1802 old_select = ri;
1803
1804 if (BGP_INFO_HOLDDOWN(ri)) {
1805 /* reap REMOVED routes, if needs be
1806 * selected route must stay for a while longer though
1807 */
1808 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)
1809 && (ri != old_select))
1810 bgp_info_reap(rn, ri);
1811
1812 continue;
1813 }
1814
1815 if (ri->peer && ri->peer != bgp->peer_self
1816 && !CHECK_FLAG(ri->peer->sflags, PEER_STATUS_NSF_WAIT))
1817 if (ri->peer->status != Established)
1818 continue;
1819
1820 if (bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)
1821 && (!CHECK_FLAG(ri->flags, BGP_INFO_DMED_SELECTED))) {
1822 bgp_info_unset_flag(rn, ri, BGP_INFO_DMED_CHECK);
1823 continue;
1824 }
1825
1826 bgp_info_unset_flag(rn, ri, BGP_INFO_DMED_CHECK);
1827
1828 if (bgp_info_cmp(bgp, ri, new_select, &paths_eq, mpath_cfg,
1829 debug, pfx_buf, afi, safi)) {
1830 new_select = ri;
1831 }
1832 }
1833
1834 /* Now that we know which path is the bestpath see if any of the other
1835 * paths
1836 * qualify as multipaths
1837 */
1838 if (debug) {
1839 if (new_select)
1840 bgp_info_path_with_addpath_rx_str(new_select, path_buf);
1841 else
1842 sprintf(path_buf, "NONE");
1843 zlog_debug(
1844 "%s: After path selection, newbest is %s oldbest was %s",
1845 pfx_buf, path_buf,
1846 old_select ? old_select->peer->host : "NONE");
1847 }
1848
1849 if (do_mpath && new_select) {
1850 for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1);
1851 ri = nextri) {
1852
1853 if (debug)
1854 bgp_info_path_with_addpath_rx_str(ri, path_buf);
1855
1856 if (ri == new_select) {
1857 if (debug)
1858 zlog_debug(
1859 "%s: %s is the bestpath, add to the multipath list",
1860 pfx_buf, path_buf);
1861 bgp_mp_list_add(&mp_list, ri);
1862 continue;
1863 }
1864
1865 if (BGP_INFO_HOLDDOWN(ri))
1866 continue;
1867
1868 if (ri->peer && ri->peer != bgp->peer_self
1869 && !CHECK_FLAG(ri->peer->sflags,
1870 PEER_STATUS_NSF_WAIT))
1871 if (ri->peer->status != Established)
1872 continue;
1873
1874 if (!bgp_info_nexthop_cmp(ri, new_select)) {
1875 if (debug)
1876 zlog_debug(
1877 "%s: %s has the same nexthop as the bestpath, skip it",
1878 pfx_buf, path_buf);
1879 continue;
1880 }
1881
1882 bgp_info_cmp(bgp, ri, new_select, &paths_eq, mpath_cfg,
1883 debug, pfx_buf, afi, safi);
1884
1885 if (paths_eq) {
1886 if (debug)
1887 zlog_debug(
1888 "%s: %s is equivalent to the bestpath, add to the multipath list",
1889 pfx_buf, path_buf);
1890 bgp_mp_list_add(&mp_list, ri);
1891 }
1892 }
1893 }
1894
1895 bgp_info_mpath_update(rn, new_select, old_select, &mp_list, mpath_cfg);
1896 bgp_info_mpath_aggregate_update(new_select, old_select);
1897 bgp_mp_list_clear(&mp_list);
1898
1899 result->old = old_select;
1900 result->new = new_select;
1901
1902 return;
1903 }
1904
1905 /*
1906 * A new route/change in bestpath of an existing route. Evaluate the path
1907 * for advertisement to the subgroup.
1908 */
1909 int subgroup_process_announce_selected(struct update_subgroup *subgrp,
1910 struct bgp_info *selected,
1911 struct bgp_node *rn,
1912 u_int32_t addpath_tx_id)
1913 {
1914 struct prefix *p;
1915 struct peer *onlypeer;
1916 struct attr attr;
1917 afi_t afi;
1918 safi_t safi;
1919
1920 p = &rn->p;
1921 afi = SUBGRP_AFI(subgrp);
1922 safi = SUBGRP_SAFI(subgrp);
1923 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
1924 : NULL);
1925
1926 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1927 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
1928 PEER_STATUS_ORF_WAIT_REFRESH))
1929 return 0;
1930
1931 memset(&attr, 0, sizeof(struct attr));
1932 /* It's initialized in bgp_announce_check() */
1933
1934 /* Announcement to the subgroup. If the route is filtered withdraw it.
1935 */
1936 if (selected) {
1937 if (subgroup_announce_check(rn, selected, subgrp, p, &attr))
1938 bgp_adj_out_set_subgroup(rn, subgrp, &attr, selected);
1939 else
1940 bgp_adj_out_unset_subgroup(rn, subgrp, 1,
1941 selected->addpath_tx_id);
1942 }
1943
1944 /* If selected is NULL we must withdraw the path using addpath_tx_id */
1945 else {
1946 bgp_adj_out_unset_subgroup(rn, subgrp, 1, addpath_tx_id);
1947 }
1948
1949 return 0;
1950 }
1951
1952 /*
1953 * Clear IGP changed flag and attribute changed flag for a route (all paths).
1954 * This is called at the end of route processing.
1955 */
1956 void bgp_zebra_clear_route_change_flags(struct bgp_node *rn)
1957 {
1958 struct bgp_info *ri;
1959
1960 for (ri = rn->info; ri; ri = ri->next) {
1961 if (BGP_INFO_HOLDDOWN(ri))
1962 continue;
1963 UNSET_FLAG(ri->flags, BGP_INFO_IGP_CHANGED);
1964 UNSET_FLAG(ri->flags, BGP_INFO_ATTR_CHANGED);
1965 }
1966 }
1967
1968 /*
1969 * Has the route changed from the RIB's perspective? This is invoked only
1970 * if the route selection returns the same best route as earlier - to
1971 * determine if we need to update zebra or not.
1972 */
1973 int bgp_zebra_has_route_changed(struct bgp_node *rn, struct bgp_info *selected)
1974 {
1975 struct bgp_info *mpinfo;
1976
1977 /* If this is multipath, check all selected paths for any nexthop change
1978 * or
1979 * attribute change. Some attribute changes (e.g., community) aren't of
1980 * relevance to the RIB, but we'll update zebra to ensure we handle the
1981 * case of BGP nexthop change. This is the behavior when the best path
1982 * has
1983 * an attribute change anyway.
1984 */
1985 if (CHECK_FLAG(selected->flags, BGP_INFO_IGP_CHANGED)
1986 || CHECK_FLAG(selected->flags, BGP_INFO_MULTIPATH_CHG))
1987 return 1;
1988
1989 /* If this is multipath, check all selected paths for any nexthop change
1990 */
1991 for (mpinfo = bgp_info_mpath_first(selected); mpinfo;
1992 mpinfo = bgp_info_mpath_next(mpinfo)) {
1993 if (CHECK_FLAG(mpinfo->flags, BGP_INFO_IGP_CHANGED)
1994 || CHECK_FLAG(mpinfo->flags, BGP_INFO_ATTR_CHANGED))
1995 return 1;
1996 }
1997
1998 /* Nothing has changed from the RIB's perspective. */
1999 return 0;
2000 }
2001
2002 struct bgp_process_queue {
2003 struct bgp *bgp;
2004 struct bgp_node *rn;
2005 afi_t afi;
2006 safi_t safi;
2007 };
2008
2009 static wq_item_status bgp_process_main(struct work_queue *wq, void *data)
2010 {
2011 struct bgp_process_queue *pq = data;
2012 struct bgp *bgp = pq->bgp;
2013 struct bgp_node *rn = pq->rn;
2014 afi_t afi = pq->afi;
2015 safi_t safi = pq->safi;
2016 struct prefix *p = &rn->p;
2017 struct bgp_info *new_select;
2018 struct bgp_info *old_select;
2019 struct bgp_info_pair old_and_new;
2020
2021 /* Is it end of initial update? (after startup) */
2022 if (!rn) {
2023 quagga_timestamp(3, bgp->update_delay_zebra_resume_time,
2024 sizeof(bgp->update_delay_zebra_resume_time));
2025
2026 bgp->main_zebra_update_hold = 0;
2027 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2028 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
2029 if (bgp_fibupd_safi(safi))
2030 bgp_zebra_announce_table(bgp, afi,
2031 safi);
2032 }
2033 bgp->main_peers_update_hold = 0;
2034
2035 bgp_start_routeadv(bgp);
2036 return WQ_SUCCESS;
2037 }
2038
2039 /* Best path selection. */
2040 bgp_best_selection(bgp, rn, &bgp->maxpaths[afi][safi], &old_and_new,
2041 afi, safi);
2042 old_select = old_and_new.old;
2043 new_select = old_and_new.new;
2044
2045 /* Do we need to allocate or free labels?
2046 * Right now, since we only deal with per-prefix labels, it is not
2047 * necessary
2048 * to do this upon changes to best path except of the label index
2049 * changes.
2050 */
2051 if (safi == SAFI_UNICAST) {
2052 if (new_select) {
2053 if (!old_select
2054 || bgp_label_index_differs(new_select, old_select)
2055 || new_select->sub_type != old_select->sub_type) {
2056 if (new_select->sub_type == BGP_ROUTE_STATIC
2057 && new_select->attr->flag
2058 & ATTR_FLAG_BIT(
2059 BGP_ATTR_PREFIX_SID)
2060 && new_select->attr->label_index
2061 != BGP_INVALID_LABEL_INDEX) {
2062 if (CHECK_FLAG(
2063 rn->flags,
2064 BGP_NODE_REGISTERED_FOR_LABEL))
2065 bgp_unregister_for_label(rn);
2066 label_ntop(MPLS_IMP_NULL_LABEL, 1,
2067 &rn->local_label);
2068 bgp_set_valid_label(&rn->local_label);
2069 } else
2070 bgp_register_for_label(rn, new_select);
2071 }
2072 } else if (CHECK_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
2073 bgp_unregister_for_label(rn);
2074 }
2075
2076 /* If best route remains the same and this is not due to user-initiated
2077 * clear, see exactly what needs to be done.
2078 */
2079
2080 if (old_select && old_select == new_select
2081 && !CHECK_FLAG(rn->flags, BGP_NODE_USER_CLEAR)
2082 && !CHECK_FLAG(old_select->flags, BGP_INFO_ATTR_CHANGED)
2083 && !bgp->addpath_tx_used[afi][safi]) {
2084 if (bgp_zebra_has_route_changed(rn, old_select)) {
2085 #if ENABLE_BGP_VNC
2086 vnc_import_bgp_add_route(bgp, p, old_select);
2087 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
2088 #endif
2089 if (bgp_fibupd_safi(safi)
2090 && !bgp_option_check(BGP_OPT_NO_FIB)
2091 && new_select->type == ZEBRA_ROUTE_BGP
2092 && new_select->sub_type == BGP_ROUTE_NORMAL)
2093 bgp_zebra_announce(rn, p, old_select, bgp, afi,
2094 safi);
2095 }
2096 UNSET_FLAG(old_select->flags, BGP_INFO_MULTIPATH_CHG);
2097 bgp_zebra_clear_route_change_flags(rn);
2098
2099 /* If there is a change of interest to peers, reannounce the
2100 * route. */
2101 if (CHECK_FLAG(old_select->flags, BGP_INFO_ATTR_CHANGED)
2102 || CHECK_FLAG(rn->flags, BGP_NODE_LABEL_CHANGED)) {
2103 group_announce_route(bgp, afi, safi, rn, new_select);
2104
2105 /* unicast routes must also be annouced to
2106 * labeled-unicast update-groups */
2107 if (safi == SAFI_UNICAST)
2108 group_announce_route(bgp, afi,
2109 SAFI_LABELED_UNICAST, rn,
2110 new_select);
2111
2112 UNSET_FLAG(old_select->flags, BGP_INFO_ATTR_CHANGED);
2113 UNSET_FLAG(rn->flags, BGP_NODE_LABEL_CHANGED);
2114 }
2115
2116 UNSET_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED);
2117 return WQ_SUCCESS;
2118 }
2119
2120 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
2121 */
2122 UNSET_FLAG(rn->flags, BGP_NODE_USER_CLEAR);
2123
2124 /* bestpath has changed; bump version */
2125 if (old_select || new_select) {
2126 bgp_bump_version(rn);
2127
2128 if (!bgp->t_rmap_def_originate_eval) {
2129 bgp_lock(bgp);
2130 thread_add_timer(
2131 bm->master,
2132 update_group_refresh_default_originate_route_map,
2133 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
2134 &bgp->t_rmap_def_originate_eval);
2135 }
2136 }
2137
2138 if (old_select)
2139 bgp_info_unset_flag(rn, old_select, BGP_INFO_SELECTED);
2140 if (new_select) {
2141 bgp_info_set_flag(rn, new_select, BGP_INFO_SELECTED);
2142 bgp_info_unset_flag(rn, new_select, BGP_INFO_ATTR_CHANGED);
2143 UNSET_FLAG(new_select->flags, BGP_INFO_MULTIPATH_CHG);
2144 }
2145
2146 #if ENABLE_BGP_VNC
2147 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
2148 if (old_select != new_select) {
2149 if (old_select) {
2150 vnc_import_bgp_exterior_del_route(bgp, p,
2151 old_select);
2152 vnc_import_bgp_del_route(bgp, p, old_select);
2153 }
2154 if (new_select) {
2155 vnc_import_bgp_exterior_add_route(bgp, p,
2156 new_select);
2157 vnc_import_bgp_add_route(bgp, p, new_select);
2158 }
2159 }
2160 }
2161 #endif
2162
2163 group_announce_route(bgp, afi, safi, rn, new_select);
2164
2165 /* unicast routes must also be annouced to labeled-unicast update-groups
2166 */
2167 if (safi == SAFI_UNICAST)
2168 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, rn,
2169 new_select);
2170
2171 /* FIB update. */
2172 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
2173 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2174 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
2175 && (new_select->sub_type == BGP_ROUTE_NORMAL
2176 || new_select->sub_type == BGP_ROUTE_AGGREGATE))
2177 bgp_zebra_announce(rn, p, new_select, bgp, afi, safi);
2178 else {
2179 /* Withdraw the route from the kernel. */
2180 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
2181 && (old_select->sub_type == BGP_ROUTE_NORMAL
2182 || old_select->sub_type == BGP_ROUTE_AGGREGATE))
2183 bgp_zebra_withdraw(p, old_select, safi);
2184 }
2185 }
2186
2187 /* Clear any route change flags. */
2188 bgp_zebra_clear_route_change_flags(rn);
2189
2190 /* Reap old select bgp_info, if it has been removed */
2191 if (old_select && CHECK_FLAG(old_select->flags, BGP_INFO_REMOVED))
2192 bgp_info_reap(rn, old_select);
2193
2194 UNSET_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED);
2195 return WQ_SUCCESS;
2196 }
2197
2198 static void bgp_processq_del(struct work_queue *wq, void *data)
2199 {
2200 struct bgp_process_queue *pq = data;
2201 struct bgp_table *table;
2202
2203 bgp_unlock(pq->bgp);
2204 if (pq->rn) {
2205 table = bgp_node_table(pq->rn);
2206 bgp_unlock_node(pq->rn);
2207 bgp_table_unlock(table);
2208 }
2209 XFREE(MTYPE_BGP_PROCESS_QUEUE, pq);
2210 }
2211
2212 void bgp_process_queue_init(void)
2213 {
2214 if (!bm->process_main_queue) {
2215 bm->process_main_queue =
2216 work_queue_new(bm->master, "process_main_queue");
2217
2218 if (!bm->process_main_queue) {
2219 zlog_err("%s: Failed to allocate work queue", __func__);
2220 exit(1);
2221 }
2222 }
2223
2224 bm->process_main_queue->spec.workfunc = &bgp_process_main;
2225 bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
2226 bm->process_main_queue->spec.max_retries = 0;
2227 bm->process_main_queue->spec.hold = 50;
2228 /* Use a higher yield value of 50ms for main queue processing */
2229 bm->process_main_queue->spec.yield = 50 * 1000L;
2230 }
2231
2232 void bgp_process(struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi)
2233 {
2234 struct bgp_process_queue *pqnode;
2235
2236 /* already scheduled for processing? */
2237 if (CHECK_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED))
2238 return;
2239
2240 if (bm->process_main_queue == NULL)
2241 return;
2242
2243 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
2244 sizeof(struct bgp_process_queue));
2245 if (!pqnode)
2246 return;
2247
2248 /* all unlocked in bgp_processq_del */
2249 bgp_table_lock(bgp_node_table(rn));
2250 pqnode->rn = bgp_lock_node(rn);
2251 pqnode->bgp = bgp_lock(bgp);
2252 pqnode->afi = afi;
2253 pqnode->safi = safi;
2254 work_queue_add(bm->process_main_queue, pqnode);
2255 SET_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED);
2256 return;
2257 }
2258
2259 void bgp_add_eoiu_mark(struct bgp *bgp)
2260 {
2261 struct bgp_process_queue *pqnode;
2262
2263 if (bm->process_main_queue == NULL)
2264 return;
2265
2266 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
2267 sizeof(struct bgp_process_queue));
2268 if (!pqnode)
2269 return;
2270
2271 pqnode->rn = NULL;
2272 pqnode->bgp = bgp;
2273 bgp_lock(bgp);
2274 work_queue_add(bm->process_main_queue, pqnode);
2275 }
2276
2277 static int bgp_maximum_prefix_restart_timer(struct thread *thread)
2278 {
2279 struct peer *peer;
2280
2281 peer = THREAD_ARG(thread);
2282 peer->t_pmax_restart = NULL;
2283
2284 if (bgp_debug_neighbor_events(peer))
2285 zlog_debug(
2286 "%s Maximum-prefix restart timer expired, restore peering",
2287 peer->host);
2288
2289 peer_clear(peer, NULL);
2290
2291 return 0;
2292 }
2293
2294 int bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
2295 int always)
2296 {
2297 iana_afi_t pkt_afi;
2298 iana_safi_t pkt_safi;
2299
2300 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
2301 return 0;
2302
2303 if (peer->pcount[afi][safi] > peer->pmax[afi][safi]) {
2304 if (CHECK_FLAG(peer->af_sflags[afi][safi],
2305 PEER_STATUS_PREFIX_LIMIT)
2306 && !always)
2307 return 0;
2308
2309 zlog_info(
2310 "%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2311 "limit %ld",
2312 afi_safi_print(afi, safi), peer->host,
2313 peer->pcount[afi][safi], peer->pmax[afi][safi]);
2314 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
2315
2316 if (CHECK_FLAG(peer->af_flags[afi][safi],
2317 PEER_FLAG_MAX_PREFIX_WARNING))
2318 return 0;
2319
2320 /* Convert AFI, SAFI to values for packet. */
2321 pkt_afi = afi_int2iana(afi);
2322 pkt_safi = safi_int2iana(safi);
2323 {
2324 u_int8_t ndata[7];
2325
2326 ndata[0] = (pkt_afi >> 8);
2327 ndata[1] = pkt_afi;
2328 ndata[2] = pkt_safi;
2329 ndata[3] = (peer->pmax[afi][safi] >> 24);
2330 ndata[4] = (peer->pmax[afi][safi] >> 16);
2331 ndata[5] = (peer->pmax[afi][safi] >> 8);
2332 ndata[6] = (peer->pmax[afi][safi]);
2333
2334 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
2335 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
2336 BGP_NOTIFY_CEASE_MAX_PREFIX,
2337 ndata, 7);
2338 }
2339
2340 /* Dynamic peers will just close their connection. */
2341 if (peer_dynamic_neighbor(peer))
2342 return 1;
2343
2344 /* restart timer start */
2345 if (peer->pmax_restart[afi][safi]) {
2346 peer->v_pmax_restart =
2347 peer->pmax_restart[afi][safi] * 60;
2348
2349 if (bgp_debug_neighbor_events(peer))
2350 zlog_debug(
2351 "%s Maximum-prefix restart timer started for %d secs",
2352 peer->host, peer->v_pmax_restart);
2353
2354 BGP_TIMER_ON(peer->t_pmax_restart,
2355 bgp_maximum_prefix_restart_timer,
2356 peer->v_pmax_restart);
2357 }
2358
2359 return 1;
2360 } else
2361 UNSET_FLAG(peer->af_sflags[afi][safi],
2362 PEER_STATUS_PREFIX_LIMIT);
2363
2364 if (peer->pcount[afi][safi]
2365 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
2366 if (CHECK_FLAG(peer->af_sflags[afi][safi],
2367 PEER_STATUS_PREFIX_THRESHOLD)
2368 && !always)
2369 return 0;
2370
2371 zlog_info(
2372 "%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2373 afi_safi_print(afi, safi), peer->host,
2374 peer->pcount[afi][safi], peer->pmax[afi][safi]);
2375 SET_FLAG(peer->af_sflags[afi][safi],
2376 PEER_STATUS_PREFIX_THRESHOLD);
2377 } else
2378 UNSET_FLAG(peer->af_sflags[afi][safi],
2379 PEER_STATUS_PREFIX_THRESHOLD);
2380 return 0;
2381 }
2382
2383 /* Unconditionally remove the route from the RIB, without taking
2384 * damping into consideration (eg, because the session went down)
2385 */
2386 static void bgp_rib_remove(struct bgp_node *rn, struct bgp_info *ri,
2387 struct peer *peer, afi_t afi, safi_t safi)
2388 {
2389 bgp_aggregate_decrement(peer->bgp, &rn->p, ri, afi, safi);
2390
2391 if (!CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
2392 bgp_info_delete(rn, ri); /* keep historical info */
2393
2394 bgp_process(peer->bgp, rn, afi, safi);
2395 }
2396
2397 static void bgp_rib_withdraw(struct bgp_node *rn, struct bgp_info *ri,
2398 struct peer *peer, afi_t afi, safi_t safi,
2399 struct prefix_rd *prd)
2400 {
2401 int status = BGP_DAMP_NONE;
2402
2403 /* apply dampening, if result is suppressed, we'll be retaining
2404 * the bgp_info in the RIB for historical reference.
2405 */
2406 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
2407 && peer->sort == BGP_PEER_EBGP)
2408 if ((status = bgp_damp_withdraw(ri, rn, afi, safi, 0))
2409 == BGP_DAMP_SUPPRESSED) {
2410 bgp_aggregate_decrement(peer->bgp, &rn->p, ri, afi,
2411 safi);
2412 return;
2413 }
2414
2415 #if ENABLE_BGP_VNC
2416 if (safi == SAFI_MPLS_VPN) {
2417 struct bgp_node *prn = NULL;
2418 struct bgp_table *table = NULL;
2419
2420 prn = bgp_node_get(peer->bgp->rib[afi][safi],
2421 (struct prefix *)prd);
2422 if (prn->info) {
2423 table = (struct bgp_table *)(prn->info);
2424
2425 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2426 peer->bgp, prd, table, &rn->p, ri);
2427 }
2428 bgp_unlock_node(prn);
2429 }
2430 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
2431 if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) {
2432
2433 vnc_import_bgp_del_route(peer->bgp, &rn->p, ri);
2434 vnc_import_bgp_exterior_del_route(peer->bgp, &rn->p,
2435 ri);
2436 }
2437 }
2438 #endif
2439
2440 /* If this is an EVPN route, process for un-import. */
2441 if (safi == SAFI_EVPN)
2442 bgp_evpn_unimport_route(peer->bgp, afi, safi, &rn->p, ri);
2443
2444 bgp_rib_remove(rn, ri, peer, afi, safi);
2445 }
2446
2447 struct bgp_info *info_make(int type, int sub_type, u_short instance,
2448 struct peer *peer, struct attr *attr,
2449 struct bgp_node *rn)
2450 {
2451 struct bgp_info *new;
2452
2453 /* Make new BGP info. */
2454 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_info));
2455 new->type = type;
2456 new->instance = instance;
2457 new->sub_type = sub_type;
2458 new->peer = peer;
2459 new->attr = attr;
2460 new->uptime = bgp_clock();
2461 new->net = rn;
2462 new->addpath_tx_id = ++peer->bgp->addpath_tx_id;
2463 return new;
2464 }
2465
2466 static void overlay_index_update(struct attr *attr,
2467 struct eth_segment_id *eth_s_id,
2468 union gw_addr *gw_ip)
2469 {
2470 if (!attr)
2471 return;
2472
2473 if (eth_s_id == NULL) {
2474 memset(&(attr->evpn_overlay.eth_s_id), 0,
2475 sizeof(struct eth_segment_id));
2476 } else {
2477 memcpy(&(attr->evpn_overlay.eth_s_id), eth_s_id,
2478 sizeof(struct eth_segment_id));
2479 }
2480 if (gw_ip == NULL) {
2481 memset(&(attr->evpn_overlay.gw_ip), 0, sizeof(union gw_addr));
2482 } else {
2483 memcpy(&(attr->evpn_overlay.gw_ip), gw_ip,
2484 sizeof(union gw_addr));
2485 }
2486 }
2487
2488 static bool overlay_index_equal(afi_t afi, struct bgp_info *info,
2489 struct eth_segment_id *eth_s_id,
2490 union gw_addr *gw_ip)
2491 {
2492 struct eth_segment_id *info_eth_s_id, *info_eth_s_id_remote;
2493 union gw_addr *info_gw_ip, *info_gw_ip_remote;
2494 char temp[16];
2495
2496 if (afi != AFI_L2VPN)
2497 return true;
2498 if (!info->attr) {
2499 memset(&temp, 0, 16);
2500 info_eth_s_id = (struct eth_segment_id *)&temp;
2501 info_gw_ip = (union gw_addr *)&temp;
2502 if (eth_s_id == NULL && gw_ip == NULL)
2503 return true;
2504 } else {
2505 info_eth_s_id = &(info->attr->evpn_overlay.eth_s_id);
2506 info_gw_ip = &(info->attr->evpn_overlay.gw_ip);
2507 }
2508 if (gw_ip == NULL)
2509 info_gw_ip_remote = (union gw_addr *)&temp;
2510 else
2511 info_gw_ip_remote = gw_ip;
2512 if (eth_s_id == NULL)
2513 info_eth_s_id_remote = (struct eth_segment_id *)&temp;
2514 else
2515 info_eth_s_id_remote = eth_s_id;
2516 if (!memcmp(info_gw_ip, info_gw_ip_remote, sizeof(union gw_addr)))
2517 return false;
2518 return !memcmp(info_eth_s_id, info_eth_s_id_remote,
2519 sizeof(struct eth_segment_id));
2520 }
2521
2522 /* Check if received nexthop is valid or not. */
2523 static int bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
2524 struct attr *attr)
2525 {
2526 int ret = 0;
2527
2528 /* Only validated for unicast and multicast currently. */
2529 /* Also valid for EVPN where the nexthop is an IP address. */
2530 if (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN)
2531 return 0;
2532
2533 /* If NEXT_HOP is present, validate it. */
2534 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
2535 if (attr->nexthop.s_addr == 0
2536 || IPV4_CLASS_DE(ntohl(attr->nexthop.s_addr))
2537 || bgp_nexthop_self(bgp, attr->nexthop))
2538 return 1;
2539 }
2540
2541 /* If MP_NEXTHOP is present, validate it. */
2542 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2543 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2544 * it is not an IPv6 link-local address.
2545 */
2546 if (attr->mp_nexthop_len) {
2547 switch (attr->mp_nexthop_len) {
2548 case BGP_ATTR_NHLEN_IPV4:
2549 case BGP_ATTR_NHLEN_VPNV4:
2550 ret = (attr->mp_nexthop_global_in.s_addr == 0
2551 || IPV4_CLASS_DE(ntohl(
2552 attr->mp_nexthop_global_in.s_addr))
2553 || bgp_nexthop_self(bgp,
2554 attr->mp_nexthop_global_in));
2555 break;
2556
2557 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
2558 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
2559 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
2560 ret = (IN6_IS_ADDR_UNSPECIFIED(&attr->mp_nexthop_global)
2561 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
2562 || IN6_IS_ADDR_MULTICAST(
2563 &attr->mp_nexthop_global));
2564 break;
2565
2566 default:
2567 ret = 1;
2568 break;
2569 }
2570 }
2571
2572 return ret;
2573 }
2574
2575 int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
2576 struct attr *attr, afi_t afi, safi_t safi, int type,
2577 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
2578 int soft_reconfig, struct bgp_route_evpn *evpn)
2579 {
2580 int ret;
2581 int aspath_loop_count = 0;
2582 struct bgp_node *rn;
2583 struct bgp *bgp;
2584 struct attr new_attr;
2585 struct attr *attr_new;
2586 struct bgp_info *ri;
2587 struct bgp_info *new;
2588 const char *reason;
2589 char pfx_buf[BGP_PRD_PATH_STRLEN];
2590 char label_buf[20];
2591 int connected = 0;
2592 int do_loop_check = 1;
2593 int has_valid_label = 0;
2594 #if ENABLE_BGP_VNC
2595 int vnc_implicit_withdraw = 0;
2596 #endif
2597 int same_attr = 0;
2598
2599 memset(&new_attr, 0, sizeof(struct attr));
2600 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
2601 new_attr.label = MPLS_INVALID_LABEL;
2602
2603 bgp = peer->bgp;
2604 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
2605 has_valid_label = bgp_is_valid_label(label);
2606
2607 if (has_valid_label)
2608 sprintf(label_buf, "label %u", label_pton(label));
2609
2610 /* When peer's soft reconfiguration enabled. Record input packet in
2611 Adj-RIBs-In. */
2612 if (!soft_reconfig
2613 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
2614 && peer != bgp->peer_self)
2615 bgp_adj_in_set(rn, peer, attr, addpath_id);
2616
2617 /* Check previously received route. */
2618 for (ri = rn->info; ri; ri = ri->next)
2619 if (ri->peer == peer && ri->type == type
2620 && ri->sub_type == sub_type
2621 && ri->addpath_rx_id == addpath_id)
2622 break;
2623
2624 /* AS path local-as loop check. */
2625 if (peer->change_local_as) {
2626 if (!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND))
2627 aspath_loop_count = 1;
2628
2629 if (aspath_loop_check(attr->aspath, peer->change_local_as)
2630 > aspath_loop_count) {
2631 reason = "as-path contains our own AS;";
2632 goto filtered;
2633 }
2634 }
2635
2636 /* If the peer is configured for "allowas-in origin" and the last ASN in
2637 * the
2638 * as-path is our ASN then we do not need to call aspath_loop_check
2639 */
2640 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
2641 if (aspath_get_last_as(attr->aspath) == bgp->as)
2642 do_loop_check = 0;
2643
2644 /* AS path loop check. */
2645 if (do_loop_check) {
2646 if (aspath_loop_check(attr->aspath, bgp->as)
2647 > peer->allowas_in[afi][safi]
2648 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
2649 && aspath_loop_check(attr->aspath, bgp->confed_id)
2650 > peer->allowas_in[afi][safi])) {
2651 reason = "as-path contains our own AS;";
2652 goto filtered;
2653 }
2654 }
2655
2656 /* Route reflector originator ID check. */
2657 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
2658 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
2659 reason = "originator is us;";
2660 goto filtered;
2661 }
2662
2663 /* Route reflector cluster ID check. */
2664 if (bgp_cluster_filter(peer, attr)) {
2665 reason = "reflected from the same cluster;";
2666 goto filtered;
2667 }
2668
2669 /* Apply incoming filter. */
2670 if (bgp_input_filter(peer, p, attr, afi, safi) == FILTER_DENY) {
2671 reason = "filter;";
2672 goto filtered;
2673 }
2674
2675 bgp_attr_dup(&new_attr, attr);
2676
2677 /* Apply incoming route-map.
2678 * NB: new_attr may now contain newly allocated values from route-map
2679 * "set"
2680 * commands, so we need bgp_attr_flush in the error paths, until we
2681 * intern
2682 * the attr (which takes over the memory references) */
2683 if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL)
2684 == RMAP_DENY) {
2685 reason = "route-map;";
2686 bgp_attr_flush(&new_attr);
2687 goto filtered;
2688 }
2689
2690 /* next hop check. */
2691 if (bgp_update_martian_nexthop(bgp, afi, safi, &new_attr)) {
2692 reason = "martian or self next-hop;";
2693 bgp_attr_flush(&new_attr);
2694 goto filtered;
2695 }
2696
2697 attr_new = bgp_attr_intern(&new_attr);
2698
2699 /* If the update is implicit withdraw. */
2700 if (ri) {
2701 ri->uptime = bgp_clock();
2702 same_attr = attrhash_cmp(ri->attr, attr_new);
2703
2704 /* Same attribute comes in. */
2705 if (!CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)
2706 && attrhash_cmp(ri->attr, attr_new)
2707 && (!has_valid_label
2708 || memcmp(&(bgp_info_extra_get(ri))->label, label,
2709 BGP_LABEL_BYTES)
2710 == 0)
2711 && (overlay_index_equal(
2712 afi, ri, evpn == NULL ? NULL : &evpn->eth_s_id,
2713 evpn == NULL ? NULL : &evpn->gw_ip))) {
2714 if (CHECK_FLAG(bgp->af_flags[afi][safi],
2715 BGP_CONFIG_DAMPENING)
2716 && peer->sort == BGP_PEER_EBGP
2717 && CHECK_FLAG(ri->flags, BGP_INFO_HISTORY)) {
2718 if (bgp_debug_update(peer, p, NULL, 1)) {
2719 bgp_debug_rdpfxpath2str(
2720 afi, safi, prd, p, label,
2721 addpath_id ? 1 : 0, addpath_id,
2722 pfx_buf, sizeof(pfx_buf));
2723 zlog_debug("%s rcvd %s", peer->host,
2724 pfx_buf);
2725 }
2726
2727 if (bgp_damp_update(ri, rn, afi, safi)
2728 != BGP_DAMP_SUPPRESSED) {
2729 bgp_aggregate_increment(bgp, p, ri, afi,
2730 safi);
2731 bgp_process(bgp, rn, afi, safi);
2732 }
2733 } else /* Duplicate - odd */
2734 {
2735 if (bgp_debug_update(peer, p, NULL, 1)) {
2736 if (!peer->rcvd_attr_printed) {
2737 zlog_debug(
2738 "%s rcvd UPDATE w/ attr: %s",
2739 peer->host,
2740 peer->rcvd_attr_str);
2741 peer->rcvd_attr_printed = 1;
2742 }
2743
2744 bgp_debug_rdpfxpath2str(
2745 afi, safi, prd, p, label,
2746 addpath_id ? 1 : 0, addpath_id,
2747 pfx_buf, sizeof(pfx_buf));
2748 zlog_debug(
2749 "%s rcvd %s...duplicate ignored",
2750 peer->host, pfx_buf);
2751 }
2752
2753 /* graceful restart STALE flag unset. */
2754 if (CHECK_FLAG(ri->flags, BGP_INFO_STALE)) {
2755 bgp_info_unset_flag(rn, ri,
2756 BGP_INFO_STALE);
2757 bgp_process(bgp, rn, afi, safi);
2758 }
2759 }
2760
2761 bgp_unlock_node(rn);
2762 bgp_attr_unintern(&attr_new);
2763
2764 return 0;
2765 }
2766
2767 /* Withdraw/Announce before we fully processed the withdraw */
2768 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
2769 if (bgp_debug_update(peer, p, NULL, 1)) {
2770 bgp_debug_rdpfxpath2str(
2771 afi, safi, prd, p, label,
2772 addpath_id ? 1 : 0, addpath_id, pfx_buf,
2773 sizeof(pfx_buf));
2774 zlog_debug(
2775 "%s rcvd %s, flapped quicker than processing",
2776 peer->host, pfx_buf);
2777 }
2778
2779 bgp_info_restore(rn, ri);
2780 }
2781
2782 /* Received Logging. */
2783 if (bgp_debug_update(peer, p, NULL, 1)) {
2784 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
2785 addpath_id ? 1 : 0, addpath_id,
2786 pfx_buf, sizeof(pfx_buf));
2787 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
2788 }
2789
2790 /* graceful restart STALE flag unset. */
2791 if (CHECK_FLAG(ri->flags, BGP_INFO_STALE))
2792 bgp_info_unset_flag(rn, ri, BGP_INFO_STALE);
2793
2794 /* The attribute is changed. */
2795 bgp_info_set_flag(rn, ri, BGP_INFO_ATTR_CHANGED);
2796
2797 /* implicit withdraw, decrement aggregate and pcount here.
2798 * only if update is accepted, they'll increment below.
2799 */
2800 bgp_aggregate_decrement(bgp, p, ri, afi, safi);
2801
2802 /* Update bgp route dampening information. */
2803 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
2804 && peer->sort == BGP_PEER_EBGP) {
2805 /* This is implicit withdraw so we should update
2806 dampening
2807 information. */
2808 if (!CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
2809 bgp_damp_withdraw(ri, rn, afi, safi, 1);
2810 }
2811 #if ENABLE_BGP_VNC
2812 if (safi == SAFI_MPLS_VPN) {
2813 struct bgp_node *prn = NULL;
2814 struct bgp_table *table = NULL;
2815
2816 prn = bgp_node_get(bgp->rib[afi][safi],
2817 (struct prefix *)prd);
2818 if (prn->info) {
2819 table = (struct bgp_table *)(prn->info);
2820
2821 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2822 bgp, prd, table, p, ri);
2823 }
2824 bgp_unlock_node(prn);
2825 }
2826 if ((afi == AFI_IP || afi == AFI_IP6)
2827 && (safi == SAFI_UNICAST)) {
2828 if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) {
2829 /*
2830 * Implicit withdraw case.
2831 */
2832 ++vnc_implicit_withdraw;
2833 vnc_import_bgp_del_route(bgp, p, ri);
2834 vnc_import_bgp_exterior_del_route(bgp, p, ri);
2835 }
2836 }
2837 #endif
2838
2839 /* Special handling for EVPN update of an existing route. If the
2840 * extended community attribute has changed, we need to
2841 * un-import
2842 * the route using its existing extended community. It will be
2843 * subsequently processed for import with the new extended
2844 * community.
2845 */
2846 if (safi == SAFI_EVPN && !same_attr) {
2847 if ((ri->attr->flag
2848 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
2849 && (attr_new->flag
2850 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
2851 int cmp;
2852
2853 cmp = ecommunity_cmp(ri->attr->ecommunity,
2854 attr_new->ecommunity);
2855 if (!cmp) {
2856 if (bgp_debug_update(peer, p, NULL, 1))
2857 zlog_debug(
2858 "Change in EXT-COMM, existing %s new %s",
2859 ecommunity_str(
2860 ri->attr->ecommunity),
2861 ecommunity_str(
2862 attr_new->ecommunity));
2863 bgp_evpn_unimport_route(bgp, afi, safi,
2864 p, ri);
2865 }
2866 }
2867 }
2868
2869 /* Update to new attribute. */
2870 bgp_attr_unintern(&ri->attr);
2871 ri->attr = attr_new;
2872
2873 /* Update MPLS label */
2874 if (has_valid_label) {
2875 memcpy(&(bgp_info_extra_get(ri))->label, label,
2876 BGP_LABEL_BYTES);
2877 bgp_set_valid_label(&(bgp_info_extra_get(ri))->label);
2878 }
2879
2880 #if ENABLE_BGP_VNC
2881 if ((afi == AFI_IP || afi == AFI_IP6)
2882 && (safi == SAFI_UNICAST)) {
2883 if (vnc_implicit_withdraw) {
2884 /*
2885 * Add back the route with its new attributes
2886 * (e.g., nexthop).
2887 * The route is still selected, until the route
2888 * selection
2889 * queued by bgp_process actually runs. We have
2890 * to make this
2891 * update to the VNC side immediately to avoid
2892 * racing against
2893 * configuration changes (e.g., route-map
2894 * changes) which
2895 * trigger re-importation of the entire RIB.
2896 */
2897 vnc_import_bgp_add_route(bgp, p, ri);
2898 vnc_import_bgp_exterior_add_route(bgp, p, ri);
2899 }
2900 }
2901 #endif
2902 /* Update Overlay Index */
2903 if (afi == AFI_L2VPN) {
2904 overlay_index_update(
2905 ri->attr, evpn == NULL ? NULL : &evpn->eth_s_id,
2906 evpn == NULL ? NULL : &evpn->gw_ip);
2907 }
2908
2909 /* Update bgp route dampening information. */
2910 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
2911 && peer->sort == BGP_PEER_EBGP) {
2912 /* Now we do normal update dampening. */
2913 ret = bgp_damp_update(ri, rn, afi, safi);
2914 if (ret == BGP_DAMP_SUPPRESSED) {
2915 bgp_unlock_node(rn);
2916 return 0;
2917 }
2918 }
2919
2920 /* Nexthop reachability check - for unicast and
2921 * labeled-unicast.. */
2922 if ((afi == AFI_IP || afi == AFI_IP6)
2923 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
2924 if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1
2925 && !CHECK_FLAG(peer->flags,
2926 PEER_FLAG_DISABLE_CONNECTED_CHECK)
2927 && !bgp_flag_check(
2928 bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
2929 connected = 1;
2930 else
2931 connected = 0;
2932
2933 if (bgp_find_or_add_nexthop(bgp, afi, ri, NULL,
2934 connected))
2935 bgp_info_set_flag(rn, ri, BGP_INFO_VALID);
2936 else {
2937 if (BGP_DEBUG(nht, NHT)) {
2938 char buf1[INET6_ADDRSTRLEN];
2939 inet_ntop(AF_INET,
2940 (const void *)&attr_new
2941 ->nexthop,
2942 buf1, INET6_ADDRSTRLEN);
2943 zlog_debug("%s(%s): NH unresolved",
2944 __FUNCTION__, buf1);
2945 }
2946 bgp_info_unset_flag(rn, ri, BGP_INFO_VALID);
2947 }
2948 } else
2949 bgp_info_set_flag(rn, ri, BGP_INFO_VALID);
2950
2951 #if ENABLE_BGP_VNC
2952 if (safi == SAFI_MPLS_VPN) {
2953 struct bgp_node *prn = NULL;
2954 struct bgp_table *table = NULL;
2955
2956 prn = bgp_node_get(bgp->rib[afi][safi],
2957 (struct prefix *)prd);
2958 if (prn->info) {
2959 table = (struct bgp_table *)(prn->info);
2960
2961 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2962 bgp, prd, table, p, ri);
2963 }
2964 bgp_unlock_node(prn);
2965 }
2966 #endif
2967
2968 /* If this is an EVPN route and some attribute has changed,
2969 * process
2970 * route for import. If the extended community has changed, we
2971 * would
2972 * have done the un-import earlier and the import would result
2973 * in the
2974 * route getting injected into appropriate L2 VNIs. If it is
2975 * just
2976 * some other attribute change, the import will result in
2977 * updating
2978 * the attributes for the route in the VNI(s).
2979 */
2980 if (safi == SAFI_EVPN && !same_attr)
2981 bgp_evpn_import_route(bgp, afi, safi, p, ri);
2982
2983 /* Process change. */
2984 bgp_aggregate_increment(bgp, p, ri, afi, safi);
2985
2986 bgp_process(bgp, rn, afi, safi);
2987 bgp_unlock_node(rn);
2988
2989 #if ENABLE_BGP_VNC
2990 if (SAFI_MPLS_VPN == safi) {
2991 mpls_label_t label_decoded = decode_label(label);
2992
2993 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
2994 type, sub_type, &label_decoded);
2995 }
2996 if (SAFI_ENCAP == safi) {
2997 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
2998 type, sub_type, NULL);
2999 }
3000 #endif
3001
3002 return 0;
3003 } // End of implicit withdraw
3004
3005 /* Received Logging. */
3006 if (bgp_debug_update(peer, p, NULL, 1)) {
3007 if (!peer->rcvd_attr_printed) {
3008 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
3009 peer->rcvd_attr_str);
3010 peer->rcvd_attr_printed = 1;
3011 }
3012
3013 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
3014 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3015 sizeof(pfx_buf));
3016 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
3017 }
3018
3019 /* Make new BGP info. */
3020 new = info_make(type, sub_type, 0, peer, attr_new, rn);
3021
3022 /* Update MPLS label */
3023 if (has_valid_label) {
3024 memcpy(&(bgp_info_extra_get(new))->label, label,
3025 BGP_LABEL_BYTES);
3026 bgp_set_valid_label(&(bgp_info_extra_get(new))->label);
3027 }
3028
3029 /* Update Overlay Index */
3030 if (afi == AFI_L2VPN) {
3031 overlay_index_update(new->attr,
3032 evpn == NULL ? NULL : &evpn->eth_s_id,
3033 evpn == NULL ? NULL : &evpn->gw_ip);
3034 }
3035 /* Nexthop reachability check. */
3036 if ((afi == AFI_IP || afi == AFI_IP6)
3037 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
3038 if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1
3039 && !CHECK_FLAG(peer->flags,
3040 PEER_FLAG_DISABLE_CONNECTED_CHECK)
3041 && !bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
3042 connected = 1;
3043 else
3044 connected = 0;
3045
3046 if (bgp_find_or_add_nexthop(bgp, afi, new, NULL, connected))
3047 bgp_info_set_flag(rn, new, BGP_INFO_VALID);
3048 else {
3049 if (BGP_DEBUG(nht, NHT)) {
3050 char buf1[INET6_ADDRSTRLEN];
3051 inet_ntop(AF_INET,
3052 (const void *)&attr_new->nexthop,
3053 buf1, INET6_ADDRSTRLEN);
3054 zlog_debug("%s(%s): NH unresolved",
3055 __FUNCTION__, buf1);
3056 }
3057 bgp_info_unset_flag(rn, new, BGP_INFO_VALID);
3058 }
3059 } else
3060 bgp_info_set_flag(rn, new, BGP_INFO_VALID);
3061
3062 /* Addpath ID */
3063 new->addpath_rx_id = addpath_id;
3064
3065 /* Increment prefix */
3066 bgp_aggregate_increment(bgp, p, new, afi, safi);
3067
3068 /* Register new BGP information. */
3069 bgp_info_add(rn, new);
3070
3071 /* route_node_get lock */
3072 bgp_unlock_node(rn);
3073
3074 #if ENABLE_BGP_VNC
3075 if (safi == SAFI_MPLS_VPN) {
3076 struct bgp_node *prn = NULL;
3077 struct bgp_table *table = NULL;
3078
3079 prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
3080 if (prn->info) {
3081 table = (struct bgp_table *)(prn->info);
3082
3083 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3084 bgp, prd, table, p, new);
3085 }
3086 bgp_unlock_node(prn);
3087 }
3088 #endif
3089
3090 /* If maximum prefix count is configured and current prefix
3091 count exeed it. */
3092 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0))
3093 return -1;
3094
3095 /* If this is an EVPN route, process for import. */
3096 if (safi == SAFI_EVPN)
3097 bgp_evpn_import_route(bgp, afi, safi, p, new);
3098
3099 /* Process change. */
3100 bgp_process(bgp, rn, afi, safi);
3101
3102 #if ENABLE_BGP_VNC
3103 if (SAFI_MPLS_VPN == safi) {
3104 mpls_label_t label_decoded = decode_label(label);
3105
3106 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
3107 sub_type, &label_decoded);
3108 }
3109 if (SAFI_ENCAP == safi) {
3110 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
3111 sub_type, NULL);
3112 }
3113 #endif
3114
3115 return 0;
3116
3117 /* This BGP update is filtered. Log the reason then update BGP
3118 entry. */
3119 filtered:
3120 if (bgp_debug_update(peer, p, NULL, 1)) {
3121 if (!peer->rcvd_attr_printed) {
3122 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
3123 peer->rcvd_attr_str);
3124 peer->rcvd_attr_printed = 1;
3125 }
3126
3127 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
3128 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3129 sizeof(pfx_buf));
3130 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
3131 peer->host, pfx_buf, reason);
3132 }
3133
3134 if (ri) {
3135 /* If this is an EVPN route, un-import it as it is now filtered.
3136 */
3137 if (safi == SAFI_EVPN)
3138 bgp_evpn_unimport_route(bgp, afi, safi, p, ri);
3139
3140 bgp_rib_remove(rn, ri, peer, afi, safi);
3141 }
3142
3143 bgp_unlock_node(rn);
3144
3145 #if ENABLE_BGP_VNC
3146 /*
3147 * Filtered update is treated as an implicit withdrawal (see
3148 * bgp_rib_remove()
3149 * a few lines above)
3150 */
3151 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
3152 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
3153 0);
3154 }
3155 #endif
3156
3157 return 0;
3158 }
3159
3160 int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
3161 struct attr *attr, afi_t afi, safi_t safi, int type,
3162 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3163 struct bgp_route_evpn *evpn)
3164 {
3165 struct bgp *bgp;
3166 char pfx_buf[BGP_PRD_PATH_STRLEN];
3167 struct bgp_node *rn;
3168 struct bgp_info *ri;
3169
3170 #if ENABLE_BGP_VNC
3171 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
3172 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
3173 0);
3174 }
3175 #endif
3176
3177 bgp = peer->bgp;
3178
3179 /* Lookup node. */
3180 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
3181
3182 /* If peer is soft reconfiguration enabled. Record input packet for
3183 * further calculation.
3184 *
3185 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
3186 * routes that are filtered. This tanks out Quagga RS pretty badly due
3187 * to
3188 * the iteration over all RS clients.
3189 * Since we need to remove the entry from adj_in anyway, do that first
3190 * and
3191 * if there was no entry, we don't need to do anything more.
3192 */
3193 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3194 && peer != bgp->peer_self)
3195 if (!bgp_adj_in_unset(rn, peer, addpath_id)) {
3196 if (bgp_debug_update(peer, p, NULL, 1)) {
3197 bgp_debug_rdpfxpath2str(
3198 afi, safi, prd, p, label,
3199 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3200 sizeof(pfx_buf));
3201 zlog_debug(
3202 "%s withdrawing route %s not in adj-in",
3203 peer->host, pfx_buf);
3204 }
3205 bgp_unlock_node(rn);
3206 return 0;
3207 }
3208
3209 /* Lookup withdrawn route. */
3210 for (ri = rn->info; ri; ri = ri->next)
3211 if (ri->peer == peer && ri->type == type
3212 && ri->sub_type == sub_type
3213 && ri->addpath_rx_id == addpath_id)
3214 break;
3215
3216 /* Logging. */
3217 if (bgp_debug_update(peer, p, NULL, 1)) {
3218 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
3219 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3220 sizeof(pfx_buf));
3221 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host,
3222 pfx_buf);
3223 }
3224
3225 /* Withdraw specified route from routing table. */
3226 if (ri && !CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
3227 bgp_rib_withdraw(rn, ri, peer, afi, safi, prd);
3228 else if (bgp_debug_update(peer, p, NULL, 1)) {
3229 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
3230 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3231 sizeof(pfx_buf));
3232 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
3233 }
3234
3235 /* Unlock bgp_node_get() lock. */
3236 bgp_unlock_node(rn);
3237
3238 return 0;
3239 }
3240
3241 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
3242 int withdraw)
3243 {
3244 struct update_subgroup *subgrp;
3245 subgrp = peer_subgroup(peer, afi, safi);
3246 subgroup_default_originate(subgrp, withdraw);
3247 }
3248
3249
3250 /*
3251 * bgp_stop_announce_route_timer
3252 */
3253 void bgp_stop_announce_route_timer(struct peer_af *paf)
3254 {
3255 if (!paf->t_announce_route)
3256 return;
3257
3258 THREAD_TIMER_OFF(paf->t_announce_route);
3259 }
3260
3261 /*
3262 * bgp_announce_route_timer_expired
3263 *
3264 * Callback that is invoked when the route announcement timer for a
3265 * peer_af expires.
3266 */
3267 static int bgp_announce_route_timer_expired(struct thread *t)
3268 {
3269 struct peer_af *paf;
3270 struct peer *peer;
3271
3272 paf = THREAD_ARG(t);
3273 peer = paf->peer;
3274
3275 if (peer->status != Established)
3276 return 0;
3277
3278 if (!peer->afc_nego[paf->afi][paf->safi])
3279 return 0;
3280
3281 peer_af_announce_route(paf, 1);
3282 return 0;
3283 }
3284
3285 /*
3286 * bgp_announce_route
3287 *
3288 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3289 */
3290 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi)
3291 {
3292 struct peer_af *paf;
3293 struct update_subgroup *subgrp;
3294
3295 paf = peer_af_find(peer, afi, safi);
3296 if (!paf)
3297 return;
3298 subgrp = PAF_SUBGRP(paf);
3299
3300 /*
3301 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3302 * or a refresh has already been triggered.
3303 */
3304 if (!subgrp || paf->t_announce_route)
3305 return;
3306
3307 /*
3308 * Start a timer to stagger/delay the announce. This serves
3309 * two purposes - announcement can potentially be combined for
3310 * multiple peers and the announcement doesn't happen in the
3311 * vty context.
3312 */
3313 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
3314 (subgrp->peer_count == 1)
3315 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
3316 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
3317 &paf->t_announce_route);
3318 }
3319
3320 /*
3321 * Announce routes from all AF tables to a peer.
3322 *
3323 * This should ONLY be called when there is a need to refresh the
3324 * routes to the peer based on a policy change for this peer alone
3325 * or a route refresh request received from the peer.
3326 * The operation will result in splitting the peer from its existing
3327 * subgroups and putting it in new subgroups.
3328 */
3329 void bgp_announce_route_all(struct peer *peer)
3330 {
3331 afi_t afi;
3332 safi_t safi;
3333
3334 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3335 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3336 bgp_announce_route(peer, afi, safi);
3337 }
3338
3339 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
3340 struct bgp_table *table,
3341 struct prefix_rd *prd)
3342 {
3343 int ret;
3344 struct bgp_node *rn;
3345 struct bgp_adj_in *ain;
3346
3347 if (!table)
3348 table = peer->bgp->rib[afi][safi];
3349
3350 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
3351 for (ain = rn->adj_in; ain; ain = ain->next) {
3352 if (ain->peer == peer) {
3353 struct bgp_info *ri = rn->info;
3354 mpls_label_t label =
3355 (ri && ri->extra) ? ri->extra->label
3356 : MPLS_INVALID_LABEL;
3357
3358 ret = bgp_update(
3359 peer, &rn->p, ain->addpath_rx_id,
3360 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
3361 BGP_ROUTE_NORMAL, prd, &label, 1, NULL);
3362
3363 if (ret < 0) {
3364 bgp_unlock_node(rn);
3365 return;
3366 }
3367 }
3368 }
3369 }
3370
3371 void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
3372 {
3373 struct bgp_node *rn;
3374 struct bgp_table *table;
3375
3376 if (peer->status != Established)
3377 return;
3378
3379 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
3380 && (safi != SAFI_EVPN))
3381 bgp_soft_reconfig_table(peer, afi, safi, NULL, NULL);
3382 else
3383 for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
3384 rn = bgp_route_next(rn))
3385 if ((table = rn->info) != NULL) {
3386 struct prefix_rd prd;
3387 prd.family = AF_UNSPEC;
3388 prd.prefixlen = 64;
3389 memcpy(&prd.val, rn->p.u.val, 8);
3390
3391 bgp_soft_reconfig_table(peer, afi, safi, table,
3392 &prd);
3393 }
3394 }
3395
3396
3397 struct bgp_clear_node_queue {
3398 struct bgp_node *rn;
3399 };
3400
3401 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
3402 {
3403 struct bgp_clear_node_queue *cnq = data;
3404 struct bgp_node *rn = cnq->rn;
3405 struct peer *peer = wq->spec.data;
3406 struct bgp_info *ri;
3407 afi_t afi = bgp_node_table(rn)->afi;
3408 safi_t safi = bgp_node_table(rn)->safi;
3409
3410 assert(rn && peer);
3411
3412 /* It is possible that we have multiple paths for a prefix from a peer
3413 * if that peer is using AddPath.
3414 */
3415 for (ri = rn->info; ri; ri = ri->next)
3416 if (ri->peer == peer) {
3417 /* graceful restart STALE flag set. */
3418 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
3419 && peer->nsf[afi][safi]
3420 && !CHECK_FLAG(ri->flags, BGP_INFO_STALE)
3421 && !CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
3422 bgp_info_set_flag(rn, ri, BGP_INFO_STALE);
3423 else {
3424 /* If this is an EVPN route, process for
3425 * un-import. */
3426 if (safi == SAFI_EVPN)
3427 bgp_evpn_unimport_route(peer->bgp, afi,
3428 safi, &rn->p,
3429 ri);
3430 bgp_rib_remove(rn, ri, peer, afi, safi);
3431 }
3432 }
3433 return WQ_SUCCESS;
3434 }
3435
3436 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
3437 {
3438 struct bgp_clear_node_queue *cnq = data;
3439 struct bgp_node *rn = cnq->rn;
3440 struct bgp_table *table = bgp_node_table(rn);
3441
3442 bgp_unlock_node(rn);
3443 bgp_table_unlock(table);
3444 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
3445 }
3446
3447 static void bgp_clear_node_complete(struct work_queue *wq)
3448 {
3449 struct peer *peer = wq->spec.data;
3450
3451 /* Tickle FSM to start moving again */
3452 BGP_EVENT_ADD(peer, Clearing_Completed);
3453
3454 peer_unlock(peer); /* bgp_clear_route */
3455 }
3456
3457 static void bgp_clear_node_queue_init(struct peer *peer)
3458 {
3459 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3460
3461 snprintf(wname, sizeof(wname), "clear %s", peer->host);
3462 #undef CLEAR_QUEUE_NAME_LEN
3463
3464 if ((peer->clear_node_queue = work_queue_new(bm->master, wname))
3465 == NULL) {
3466 zlog_err("%s: Failed to allocate work queue", __func__);
3467 exit(1);
3468 }
3469 peer->clear_node_queue->spec.hold = 10;
3470 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
3471 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
3472 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
3473 peer->clear_node_queue->spec.max_retries = 0;
3474
3475 /* we only 'lock' this peer reference when the queue is actually active
3476 */
3477 peer->clear_node_queue->spec.data = peer;
3478 }
3479
3480 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
3481 struct bgp_table *table)
3482 {
3483 struct bgp_node *rn;
3484 int force = bm->process_main_queue ? 0 : 1;
3485
3486 if (!table)
3487 table = peer->bgp->rib[afi][safi];
3488
3489 /* If still no table => afi/safi isn't configured at all or smth. */
3490 if (!table)
3491 return;
3492
3493 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
3494 struct bgp_info *ri, *next;
3495 struct bgp_adj_in *ain;
3496 struct bgp_adj_in *ain_next;
3497
3498 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3499 * queued for every clearing peer, regardless of whether it is
3500 * relevant to the peer at hand.
3501 *
3502 * Overview: There are 3 different indices which need to be
3503 * scrubbed, potentially, when a peer is removed:
3504 *
3505 * 1 peer's routes visible via the RIB (ie accepted routes)
3506 * 2 peer's routes visible by the (optional) peer's adj-in index
3507 * 3 other routes visible by the peer's adj-out index
3508 *
3509 * 3 there is no hurry in scrubbing, once the struct peer is
3510 * removed from bgp->peer, we could just GC such deleted peer's
3511 * adj-outs at our leisure.
3512 *
3513 * 1 and 2 must be 'scrubbed' in some way, at least made
3514 * invisible via RIB index before peer session is allowed to be
3515 * brought back up. So one needs to know when such a 'search' is
3516 * complete.
3517 *
3518 * Ideally:
3519 *
3520 * - there'd be a single global queue or a single RIB walker
3521 * - rather than tracking which route_nodes still need to be
3522 * examined on a peer basis, we'd track which peers still
3523 * aren't cleared
3524 *
3525 * Given that our per-peer prefix-counts now should be reliable,
3526 * this may actually be achievable. It doesn't seem to be a huge
3527 * problem at this time,
3528 *
3529 * It is possible that we have multiple paths for a prefix from
3530 * a peer
3531 * if that peer is using AddPath.
3532 */
3533 ain = rn->adj_in;
3534 while (ain) {
3535 ain_next = ain->next;
3536
3537 if (ain->peer == peer) {
3538 bgp_adj_in_remove(rn, ain);
3539 bgp_unlock_node(rn);
3540 }
3541
3542 ain = ain_next;
3543 }
3544
3545 for (ri = rn->info; ri; ri = next) {
3546 next = ri->next;
3547 if (ri->peer != peer)
3548 continue;
3549
3550 if (force)
3551 bgp_info_reap(rn, ri);
3552 else {
3553 struct bgp_clear_node_queue *cnq;
3554
3555 /* both unlocked in bgp_clear_node_queue_del */
3556 bgp_table_lock(bgp_node_table(rn));
3557 bgp_lock_node(rn);
3558 cnq = XCALLOC(
3559 MTYPE_BGP_CLEAR_NODE_QUEUE,
3560 sizeof(struct bgp_clear_node_queue));
3561 cnq->rn = rn;
3562 work_queue_add(peer->clear_node_queue, cnq);
3563 break;
3564 }
3565 }
3566 }
3567 return;
3568 }
3569
3570 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
3571 {
3572 struct bgp_node *rn;
3573 struct bgp_table *table;
3574
3575 if (peer->clear_node_queue == NULL)
3576 bgp_clear_node_queue_init(peer);
3577
3578 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3579 * Idle until it receives a Clearing_Completed event. This protects
3580 * against peers which flap faster than we can we clear, which could
3581 * lead to:
3582 *
3583 * a) race with routes from the new session being installed before
3584 * clear_route_node visits the node (to delete the route of that
3585 * peer)
3586 * b) resource exhaustion, clear_route_node likely leads to an entry
3587 * on the process_main queue. Fast-flapping could cause that queue
3588 * to grow and grow.
3589 */
3590
3591 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3592 * the unlock will happen upon work-queue completion; other wise, the
3593 * unlock happens at the end of this function.
3594 */
3595 if (!peer->clear_node_queue->thread)
3596 peer_lock(peer);
3597
3598 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
3599 bgp_clear_route_table(peer, afi, safi, NULL);
3600 else
3601 for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
3602 rn = bgp_route_next(rn))
3603 if ((table = rn->info) != NULL)
3604 bgp_clear_route_table(peer, afi, safi, table);
3605
3606 /* unlock if no nodes got added to the clear-node-queue. */
3607 if (!peer->clear_node_queue->thread)
3608 peer_unlock(peer);
3609 }
3610
3611 void bgp_clear_route_all(struct peer *peer)
3612 {
3613 afi_t afi;
3614 safi_t safi;
3615
3616 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3617 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3618 bgp_clear_route(peer, afi, safi);
3619
3620 #if ENABLE_BGP_VNC
3621 rfapiProcessPeerDown(peer);
3622 #endif
3623 }
3624
3625 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
3626 {
3627 struct bgp_table *table;
3628 struct bgp_node *rn;
3629 struct bgp_adj_in *ain;
3630 struct bgp_adj_in *ain_next;
3631
3632 table = peer->bgp->rib[afi][safi];
3633
3634 /* It is possible that we have multiple paths for a prefix from a peer
3635 * if that peer is using AddPath.
3636 */
3637 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
3638 ain = rn->adj_in;
3639
3640 while (ain) {
3641 ain_next = ain->next;
3642
3643 if (ain->peer == peer) {
3644 bgp_adj_in_remove(rn, ain);
3645 bgp_unlock_node(rn);
3646 }
3647
3648 ain = ain_next;
3649 }
3650 }
3651 }
3652
3653 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
3654 {
3655 struct bgp_node *rn;
3656 struct bgp_info *ri;
3657 struct bgp_table *table;
3658
3659 if (safi == SAFI_MPLS_VPN) {
3660 for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
3661 rn = bgp_route_next(rn)) {
3662 struct bgp_node *rm;
3663 struct bgp_info *ri;
3664
3665 /* look for neighbor in tables */
3666 if ((table = rn->info) != NULL) {
3667 for (rm = bgp_table_top(table); rm;
3668 rm = bgp_route_next(rm))
3669 for (ri = rm->info; ri; ri = ri->next)
3670 if (ri->peer == peer) {
3671 if (CHECK_FLAG(
3672 ri->flags,
3673 BGP_INFO_STALE))
3674 bgp_rib_remove(
3675 rm, ri,
3676 peer,
3677 afi,
3678 safi);
3679 break;
3680 }
3681 }
3682 }
3683 } else {
3684 for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
3685 rn = bgp_route_next(rn))
3686 for (ri = rn->info; ri; ri = ri->next)
3687 if (ri->peer == peer) {
3688 if (CHECK_FLAG(ri->flags,
3689 BGP_INFO_STALE))
3690 bgp_rib_remove(rn, ri, peer,
3691 afi, safi);
3692 break;
3693 }
3694 }
3695 }
3696
3697 static void bgp_cleanup_table(struct bgp_table *table, safi_t safi)
3698 {
3699 struct bgp_node *rn;
3700 struct bgp_info *ri;
3701 struct bgp_info *next;
3702
3703 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
3704 for (ri = rn->info; ri; ri = next) {
3705 next = ri->next;
3706 if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)
3707 && ri->type == ZEBRA_ROUTE_BGP
3708 && (ri->sub_type == BGP_ROUTE_NORMAL
3709 || ri->sub_type == BGP_ROUTE_AGGREGATE)) {
3710 if (bgp_fibupd_safi(safi))
3711 bgp_zebra_withdraw(&rn->p, ri, safi);
3712 bgp_info_reap(rn, ri);
3713 }
3714 }
3715 }
3716
3717 /* Delete all kernel routes. */
3718 void bgp_cleanup_routes(struct bgp *bgp)
3719 {
3720 afi_t afi;
3721 struct bgp_node *rn;
3722
3723 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
3724 if (afi == AFI_L2VPN)
3725 continue;
3726 bgp_cleanup_table(bgp->rib[afi][SAFI_UNICAST], SAFI_UNICAST);
3727 /*
3728 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
3729 */
3730 if (afi != AFI_L2VPN) {
3731 safi_t safi;
3732 safi = SAFI_MPLS_VPN;
3733 for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
3734 rn = bgp_route_next(rn)) {
3735 if (rn->info) {
3736 bgp_cleanup_table(
3737 (struct bgp_table *)(rn->info),
3738 safi);
3739 bgp_table_finish((struct bgp_table **)&(
3740 rn->info));
3741 rn->info = NULL;
3742 bgp_unlock_node(rn);
3743 }
3744 }
3745 safi = SAFI_ENCAP;
3746 for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
3747 rn = bgp_route_next(rn)) {
3748 if (rn->info) {
3749 bgp_cleanup_table(
3750 (struct bgp_table *)(rn->info),
3751 safi);
3752 bgp_table_finish((struct bgp_table **)&(
3753 rn->info));
3754 rn->info = NULL;
3755 bgp_unlock_node(rn);
3756 }
3757 }
3758 }
3759 }
3760 for (rn = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); rn;
3761 rn = bgp_route_next(rn)) {
3762 if (rn->info) {
3763 bgp_cleanup_table((struct bgp_table *)(rn->info),
3764 SAFI_EVPN);
3765 bgp_table_finish((struct bgp_table **)&(rn->info));
3766 rn->info = NULL;
3767 bgp_unlock_node(rn);
3768 }
3769 }
3770 }
3771
3772 void bgp_reset(void)
3773 {
3774 vty_reset();
3775 bgp_zclient_reset();
3776 access_list_reset();
3777 prefix_list_reset();
3778 }
3779
3780 static int bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
3781 {
3782 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
3783 && CHECK_FLAG(peer->af_cap[afi][safi],
3784 PEER_CAP_ADDPATH_AF_TX_RCV));
3785 }
3786
3787 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
3788 value. */
3789 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
3790 struct bgp_nlri *packet)
3791 {
3792 u_char *pnt;
3793 u_char *lim;
3794 struct prefix p;
3795 int psize;
3796 int ret;
3797 afi_t afi;
3798 safi_t safi;
3799 int addpath_encoded;
3800 u_int32_t addpath_id;
3801
3802 /* Check peer status. */
3803 if (peer->status != Established)
3804 return 0;
3805
3806 pnt = packet->nlri;
3807 lim = pnt + packet->length;
3808 afi = packet->afi;
3809 safi = packet->safi;
3810 addpath_id = 0;
3811 addpath_encoded = bgp_addpath_encode_rx(peer, afi, safi);
3812
3813 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
3814 syntactic validity. If the field is syntactically incorrect,
3815 then the Error Subcode is set to Invalid Network Field. */
3816 for (; pnt < lim; pnt += psize) {
3817 /* Clear prefix structure. */
3818 memset(&p, 0, sizeof(struct prefix));
3819
3820 if (addpath_encoded) {
3821
3822 /* When packet overflow occurs return immediately. */
3823 if (pnt + BGP_ADDPATH_ID_LEN > lim)
3824 return -1;
3825
3826 addpath_id = ntohl(*((uint32_t *)pnt));
3827 pnt += BGP_ADDPATH_ID_LEN;
3828 }
3829
3830 /* Fetch prefix length. */
3831 p.prefixlen = *pnt++;
3832 /* afi/safi validity already verified by caller,
3833 * bgp_update_receive */
3834 p.family = afi2family(afi);
3835
3836 /* Prefix length check. */
3837 if (p.prefixlen > prefix_blen(&p) * 8) {
3838 zlog_err(
3839 "%s [Error] Update packet error (wrong perfix length %d for afi %u)",
3840 peer->host, p.prefixlen, packet->afi);
3841 return -1;
3842 }
3843
3844 /* Packet size overflow check. */
3845 psize = PSIZE(p.prefixlen);
3846
3847 /* When packet overflow occur return immediately. */
3848 if (pnt + psize > lim) {
3849 zlog_err(
3850 "%s [Error] Update packet error (prefix length %d overflows packet)",
3851 peer->host, p.prefixlen);
3852 return -1;
3853 }
3854
3855 /* Defensive coding, double-check the psize fits in a struct
3856 * prefix */
3857 if (psize > (ssize_t)sizeof(p.u)) {
3858 zlog_err(
3859 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
3860 peer->host, p.prefixlen, sizeof(p.u));
3861 return -1;
3862 }
3863
3864 /* Fetch prefix from NLRI packet. */
3865 memcpy(&p.u.prefix, pnt, psize);
3866
3867 /* Check address. */
3868 if (afi == AFI_IP && safi == SAFI_UNICAST) {
3869 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
3870 /* From RFC4271 Section 6.3:
3871 *
3872 * If a prefix in the NLRI field is semantically
3873 * incorrect
3874 * (e.g., an unexpected multicast IP address),
3875 * an error SHOULD
3876 * be logged locally, and the prefix SHOULD be
3877 * ignored.
3878 */
3879 zlog_err(
3880 "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
3881 peer->host, inet_ntoa(p.u.prefix4));
3882 continue;
3883 }
3884 }
3885
3886 /* Check address. */
3887 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
3888 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
3889 char buf[BUFSIZ];
3890
3891 zlog_err(
3892 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
3893 peer->host,
3894 inet_ntop(AF_INET6, &p.u.prefix6, buf,
3895 BUFSIZ));
3896
3897 continue;
3898 }
3899 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
3900 char buf[BUFSIZ];
3901
3902 zlog_err(
3903 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
3904 peer->host,
3905 inet_ntop(AF_INET6, &p.u.prefix6, buf,
3906 BUFSIZ));
3907
3908 continue;
3909 }
3910 }
3911
3912 /* Normal process. */
3913 if (attr)
3914 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
3915 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
3916 NULL, NULL, 0, NULL);
3917 else
3918 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
3919 safi, ZEBRA_ROUTE_BGP,
3920 BGP_ROUTE_NORMAL, NULL, NULL, NULL);
3921
3922 /* Address family configuration mismatch or maximum-prefix count
3923 overflow. */
3924 if (ret < 0)
3925 return -1;
3926 }
3927
3928 /* Packet length consistency check. */
3929 if (pnt != lim) {
3930 zlog_err(
3931 "%s [Error] Update packet error (prefix length mismatch with total length)",
3932 peer->host);
3933 return -1;
3934 }
3935
3936 return 0;
3937 }
3938
3939 static struct bgp_static *bgp_static_new(void)
3940 {
3941 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
3942 }
3943
3944 static void bgp_static_free(struct bgp_static *bgp_static)
3945 {
3946 if (bgp_static->rmap.name)
3947 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
3948 if (bgp_static->eth_s_id)
3949 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
3950 XFREE(MTYPE_BGP_STATIC, bgp_static);
3951 }
3952
3953 void bgp_static_update(struct bgp *bgp, struct prefix *p,
3954 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
3955 {
3956 struct bgp_node *rn;
3957 struct bgp_info *ri;
3958 struct bgp_info *new;
3959 struct bgp_info info;
3960 struct attr attr;
3961 struct attr *attr_new;
3962 int ret;
3963 #if ENABLE_BGP_VNC
3964 int vnc_implicit_withdraw = 0;
3965 #endif
3966
3967 assert(bgp_static);
3968 if (!bgp_static)
3969 return;
3970
3971 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
3972
3973 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
3974
3975 attr.nexthop = bgp_static->igpnexthop;
3976 attr.med = bgp_static->igpmetric;
3977 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
3978
3979 if (bgp_static->atomic)
3980 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
3981
3982 /* Store label index, if required. */
3983 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
3984 attr.label_index = bgp_static->label_index;
3985 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
3986 }
3987
3988 /* Apply route-map. */
3989 if (bgp_static->rmap.name) {
3990 struct attr attr_tmp = attr;
3991 info.peer = bgp->peer_self;
3992 info.attr = &attr_tmp;
3993
3994 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
3995
3996 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP, &info);
3997
3998 bgp->peer_self->rmap_type = 0;
3999
4000 if (ret == RMAP_DENYMATCH) {
4001 /* Free uninterned attribute. */
4002 bgp_attr_flush(&attr_tmp);
4003
4004 /* Unintern original. */
4005 aspath_unintern(&attr.aspath);
4006 bgp_static_withdraw(bgp, p, afi, safi);
4007 return;
4008 }
4009 attr_new = bgp_attr_intern(&attr_tmp);
4010 } else
4011 attr_new = bgp_attr_intern(&attr);
4012
4013 for (ri = rn->info; ri; ri = ri->next)
4014 if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
4015 && ri->sub_type == BGP_ROUTE_STATIC)
4016 break;
4017
4018 if (ri) {
4019 if (attrhash_cmp(ri->attr, attr_new)
4020 && !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)
4021 && !bgp_flag_check(bgp, BGP_FLAG_FORCE_STATIC_PROCESS)) {
4022 bgp_unlock_node(rn);
4023 bgp_attr_unintern(&attr_new);
4024 aspath_unintern(&attr.aspath);
4025 return;
4026 } else {
4027 /* The attribute is changed. */
4028 bgp_info_set_flag(rn, ri, BGP_INFO_ATTR_CHANGED);
4029
4030 /* Rewrite BGP route information. */
4031 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
4032 bgp_info_restore(rn, ri);
4033 else
4034 bgp_aggregate_decrement(bgp, p, ri, afi, safi);
4035 #if ENABLE_BGP_VNC
4036 if ((afi == AFI_IP || afi == AFI_IP6)
4037 && (safi == SAFI_UNICAST)) {
4038 if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) {
4039 /*
4040 * Implicit withdraw case.
4041 * We have to do this before ri is
4042 * changed
4043 */
4044 ++vnc_implicit_withdraw;
4045 vnc_import_bgp_del_route(bgp, p, ri);
4046 vnc_import_bgp_exterior_del_route(
4047 bgp, p, ri);
4048 }
4049 }
4050 #endif
4051 bgp_attr_unintern(&ri->attr);
4052 ri->attr = attr_new;
4053 ri->uptime = bgp_clock();
4054 #if ENABLE_BGP_VNC
4055 if ((afi == AFI_IP || afi == AFI_IP6)
4056 && (safi == SAFI_UNICAST)) {
4057 if (vnc_implicit_withdraw) {
4058 vnc_import_bgp_add_route(bgp, p, ri);
4059 vnc_import_bgp_exterior_add_route(
4060 bgp, p, ri);
4061 }
4062 }
4063 #endif
4064
4065 /* Nexthop reachability check. */
4066 if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
4067 && (safi == SAFI_UNICAST
4068 || safi == SAFI_LABELED_UNICAST)) {
4069 if (bgp_find_or_add_nexthop(bgp, afi, ri, NULL,
4070 0))
4071 bgp_info_set_flag(rn, ri,
4072 BGP_INFO_VALID);
4073 else {
4074 if (BGP_DEBUG(nht, NHT)) {
4075 char buf1[INET6_ADDRSTRLEN];
4076 inet_ntop(p->family,
4077 &p->u.prefix, buf1,
4078 INET6_ADDRSTRLEN);
4079 zlog_debug(
4080 "%s(%s): Route not in table, not advertising",
4081 __FUNCTION__, buf1);
4082 }
4083 bgp_info_unset_flag(rn, ri,
4084 BGP_INFO_VALID);
4085 }
4086 } else {
4087 /* Delete the NHT structure if any, if we're
4088 * toggling between
4089 * enabling/disabling import check. We
4090 * deregister the route
4091 * from NHT to avoid overloading NHT and the
4092 * process interaction
4093 */
4094 bgp_unlink_nexthop(ri);
4095 bgp_info_set_flag(rn, ri, BGP_INFO_VALID);
4096 }
4097 /* Process change. */
4098 bgp_aggregate_increment(bgp, p, ri, afi, safi);
4099 bgp_process(bgp, rn, afi, safi);
4100 bgp_unlock_node(rn);
4101 aspath_unintern(&attr.aspath);
4102 return;
4103 }
4104 }
4105
4106 /* Make new BGP info. */
4107 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
4108 attr_new, rn);
4109 /* Nexthop reachability check. */
4110 if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
4111 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
4112 if (bgp_find_or_add_nexthop(bgp, afi, new, NULL, 0))
4113 bgp_info_set_flag(rn, new, BGP_INFO_VALID);
4114 else {
4115 if (BGP_DEBUG(nht, NHT)) {
4116 char buf1[INET6_ADDRSTRLEN];
4117 inet_ntop(p->family, &p->u.prefix, buf1,
4118 INET6_ADDRSTRLEN);
4119 zlog_debug(
4120 "%s(%s): Route not in table, not advertising",
4121 __FUNCTION__, buf1);
4122 }
4123 bgp_info_unset_flag(rn, new, BGP_INFO_VALID);
4124 }
4125 } else {
4126 /* Delete the NHT structure if any, if we're toggling between
4127 * enabling/disabling import check. We deregister the route
4128 * from NHT to avoid overloading NHT and the process interaction
4129 */
4130 bgp_unlink_nexthop(new);
4131
4132 bgp_info_set_flag(rn, new, BGP_INFO_VALID);
4133 }
4134
4135 /* Aggregate address increment. */
4136 bgp_aggregate_increment(bgp, p, new, afi, safi);
4137
4138 /* Register new BGP information. */
4139 bgp_info_add(rn, new);
4140
4141 /* route_node_get lock */
4142 bgp_unlock_node(rn);
4143
4144 /* Process change. */
4145 bgp_process(bgp, rn, afi, safi);
4146
4147 /* Unintern original. */
4148 aspath_unintern(&attr.aspath);
4149 }
4150
4151 void bgp_static_withdraw(struct bgp *bgp, struct prefix *p, afi_t afi,
4152 safi_t safi)
4153 {
4154 struct bgp_node *rn;
4155 struct bgp_info *ri;
4156
4157 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
4158
4159 /* Check selected route and self inserted route. */
4160 for (ri = rn->info; ri; ri = ri->next)
4161 if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
4162 && ri->sub_type == BGP_ROUTE_STATIC)
4163 break;
4164
4165 /* Withdraw static BGP route from routing table. */
4166 if (ri) {
4167 bgp_aggregate_decrement(bgp, p, ri, afi, safi);
4168 bgp_unlink_nexthop(ri);
4169 bgp_info_delete(rn, ri);
4170 bgp_process(bgp, rn, afi, safi);
4171 }
4172
4173 /* Unlock bgp_node_lookup. */
4174 bgp_unlock_node(rn);
4175 }
4176
4177 /*
4178 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4179 */
4180 static void bgp_static_withdraw_safi(struct bgp *bgp, struct prefix *p,
4181 afi_t afi, safi_t safi,
4182 struct prefix_rd *prd)
4183 {
4184 struct bgp_node *rn;
4185 struct bgp_info *ri;
4186
4187 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4188
4189 /* Check selected route and self inserted route. */
4190 for (ri = rn->info; ri; ri = ri->next)
4191 if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
4192 && ri->sub_type == BGP_ROUTE_STATIC)
4193 break;
4194
4195 /* Withdraw static BGP route from routing table. */
4196 if (ri) {
4197 #if ENABLE_BGP_VNC
4198 rfapiProcessWithdraw(
4199 ri->peer, NULL, p, prd, ri->attr, afi, safi, ri->type,
4200 1); /* Kill, since it is an administrative change */
4201 #endif
4202 bgp_aggregate_decrement(bgp, p, ri, afi, safi);
4203 bgp_info_delete(rn, ri);
4204 bgp_process(bgp, rn, afi, safi);
4205 }
4206
4207 /* Unlock bgp_node_lookup. */
4208 bgp_unlock_node(rn);
4209 }
4210
4211 static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p,
4212 struct bgp_static *bgp_static, afi_t afi,
4213 safi_t safi)
4214 {
4215 struct bgp_node *rn;
4216 struct bgp_info *new;
4217 struct attr *attr_new;
4218 struct attr attr = {0};
4219 struct bgp_info *ri;
4220 #if ENABLE_BGP_VNC
4221 mpls_label_t label = 0;
4222 #endif
4223 union gw_addr add;
4224
4225 assert(bgp_static);
4226
4227 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
4228 &bgp_static->prd);
4229
4230 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
4231
4232 attr.nexthop = bgp_static->igpnexthop;
4233 attr.med = bgp_static->igpmetric;
4234 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
4235
4236 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
4237 || (safi == SAFI_ENCAP)) {
4238 if (afi == AFI_IP) {
4239 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
4240 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
4241 }
4242 }
4243 if (afi == AFI_L2VPN) {
4244 if (bgp_static->gatewayIp.family == AF_INET)
4245 add.ipv4.s_addr =
4246 bgp_static->gatewayIp.u.prefix4.s_addr;
4247 else if (bgp_static->gatewayIp.family == AF_INET6)
4248 memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6),
4249 sizeof(struct in6_addr));
4250 overlay_index_update(&attr, bgp_static->eth_s_id, &add);
4251 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
4252 struct bgp_encap_type_vxlan bet;
4253 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
4254 bet.vnid = p->u.prefix_evpn.eth_tag;
4255 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
4256 }
4257 if (bgp_static->router_mac) {
4258 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
4259 }
4260 }
4261 /* Apply route-map. */
4262 if (bgp_static->rmap.name) {
4263 struct attr attr_tmp = attr;
4264 struct bgp_info info;
4265 int ret;
4266
4267 info.peer = bgp->peer_self;
4268 info.attr = &attr_tmp;
4269
4270 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
4271
4272 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP, &info);
4273
4274 bgp->peer_self->rmap_type = 0;
4275
4276 if (ret == RMAP_DENYMATCH) {
4277 /* Free uninterned attribute. */
4278 bgp_attr_flush(&attr_tmp);
4279
4280 /* Unintern original. */
4281 aspath_unintern(&attr.aspath);
4282 bgp_static_withdraw_safi(bgp, p, afi, safi,
4283 &bgp_static->prd);
4284 return;
4285 }
4286
4287 attr_new = bgp_attr_intern(&attr_tmp);
4288 } else {
4289 attr_new = bgp_attr_intern(&attr);
4290 }
4291
4292 for (ri = rn->info; ri; ri = ri->next)
4293 if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
4294 && ri->sub_type == BGP_ROUTE_STATIC)
4295 break;
4296
4297 if (ri) {
4298 union gw_addr add;
4299 memset(&add, 0, sizeof(union gw_addr));
4300 if (attrhash_cmp(ri->attr, attr_new)
4301 && overlay_index_equal(afi, ri, bgp_static->eth_s_id, &add)
4302 && !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
4303 bgp_unlock_node(rn);
4304 bgp_attr_unintern(&attr_new);
4305 aspath_unintern(&attr.aspath);
4306 return;
4307 } else {
4308 /* The attribute is changed. */
4309 bgp_info_set_flag(rn, ri, BGP_INFO_ATTR_CHANGED);
4310
4311 /* Rewrite BGP route information. */
4312 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
4313 bgp_info_restore(rn, ri);
4314 else
4315 bgp_aggregate_decrement(bgp, p, ri, afi, safi);
4316 bgp_attr_unintern(&ri->attr);
4317 ri->attr = attr_new;
4318 ri->uptime = bgp_clock();
4319 #if ENABLE_BGP_VNC
4320 if (ri->extra)
4321 label = decode_label(&ri->extra->label);
4322 #endif
4323
4324 /* Process change. */
4325 bgp_aggregate_increment(bgp, p, ri, afi, safi);
4326 bgp_process(bgp, rn, afi, safi);
4327 #if ENABLE_BGP_VNC
4328 rfapiProcessUpdate(ri->peer, NULL, p, &bgp_static->prd,
4329 ri->attr, afi, safi, ri->type,
4330 ri->sub_type, &label);
4331 #endif
4332 bgp_unlock_node(rn);
4333 aspath_unintern(&attr.aspath);
4334 return;
4335 }
4336 }
4337
4338
4339 /* Make new BGP info. */
4340 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
4341 attr_new, rn);
4342 SET_FLAG(new->flags, BGP_INFO_VALID);
4343 new->extra = bgp_info_extra_new();
4344 new->extra->label = bgp_static->label;
4345 #if ENABLE_BGP_VNC
4346 label = decode_label(&bgp_static->label);
4347 #endif
4348
4349 /* Aggregate address increment. */
4350 bgp_aggregate_increment(bgp, p, new, afi, safi);
4351
4352 /* Register new BGP information. */
4353 bgp_info_add(rn, new);
4354 /* route_node_get lock */
4355 bgp_unlock_node(rn);
4356
4357 /* Process change. */
4358 bgp_process(bgp, rn, afi, safi);
4359
4360 #if ENABLE_BGP_VNC
4361 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
4362 safi, new->type, new->sub_type, &label);
4363 #endif
4364
4365 /* Unintern original. */
4366 aspath_unintern(&attr.aspath);
4367 }
4368
4369 /* Configure static BGP network. When user don't run zebra, static
4370 route should be installed as valid. */
4371 static int bgp_static_set(struct vty *vty, const char *ip_str, afi_t afi,
4372 safi_t safi, const char *rmap, int backdoor,
4373 u_int32_t label_index)
4374 {
4375 VTY_DECLVAR_CONTEXT(bgp, bgp);
4376 int ret;
4377 struct prefix p;
4378 struct bgp_static *bgp_static;
4379 struct bgp_node *rn;
4380 u_char need_update = 0;
4381
4382 /* Convert IP prefix string to struct prefix. */
4383 ret = str2prefix(ip_str, &p);
4384 if (!ret) {
4385 vty_out(vty, "%% Malformed prefix\n");
4386 return CMD_WARNING_CONFIG_FAILED;
4387 }
4388 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
4389 vty_out(vty, "%% Malformed prefix (link-local address)\n");
4390 return CMD_WARNING_CONFIG_FAILED;
4391 }
4392
4393 apply_mask(&p);
4394
4395 /* Set BGP static route configuration. */
4396 rn = bgp_node_get(bgp->route[afi][safi], &p);
4397
4398 if (rn->info) {
4399 /* Configuration change. */
4400 bgp_static = rn->info;
4401
4402 /* Label index cannot be changed. */
4403 if (bgp_static->label_index != label_index) {
4404 vty_out(vty, "%% Label index cannot be changed\n");
4405 return CMD_WARNING_CONFIG_FAILED;
4406 }
4407
4408 /* Check previous routes are installed into BGP. */
4409 if (bgp_static->valid && bgp_static->backdoor != backdoor)
4410 need_update = 1;
4411
4412 bgp_static->backdoor = backdoor;
4413
4414 if (rmap) {
4415 if (bgp_static->rmap.name)
4416 XFREE(MTYPE_ROUTE_MAP_NAME,
4417 bgp_static->rmap.name);
4418 bgp_static->rmap.name =
4419 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
4420 bgp_static->rmap.map = route_map_lookup_by_name(rmap);
4421 } else {
4422 if (bgp_static->rmap.name)
4423 XFREE(MTYPE_ROUTE_MAP_NAME,
4424 bgp_static->rmap.name);
4425 bgp_static->rmap.name = NULL;
4426 bgp_static->rmap.map = NULL;
4427 bgp_static->valid = 0;
4428 }
4429 bgp_unlock_node(rn);
4430 } else {
4431 /* New configuration. */
4432 bgp_static = bgp_static_new();
4433 bgp_static->backdoor = backdoor;
4434 bgp_static->valid = 0;
4435 bgp_static->igpmetric = 0;
4436 bgp_static->igpnexthop.s_addr = 0;
4437 bgp_static->label_index = label_index;
4438
4439 if (rmap) {
4440 if (bgp_static->rmap.name)
4441 XFREE(MTYPE_ROUTE_MAP_NAME,
4442 bgp_static->rmap.name);
4443 bgp_static->rmap.name =
4444 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
4445 bgp_static->rmap.map = route_map_lookup_by_name(rmap);
4446 }
4447 rn->info = bgp_static;
4448 }
4449
4450 bgp_static->valid = 1;
4451 if (need_update)
4452 bgp_static_withdraw(bgp, &p, afi, safi);
4453
4454 if (!bgp_static->backdoor)
4455 bgp_static_update(bgp, &p, bgp_static, afi, safi);
4456
4457 return CMD_SUCCESS;
4458 }
4459
4460 /* Configure static BGP network. */
4461 static int bgp_static_unset(struct vty *vty, const char *ip_str, afi_t afi,
4462 safi_t safi)
4463 {
4464 VTY_DECLVAR_CONTEXT(bgp, bgp);
4465 int ret;
4466 struct prefix p;
4467 struct bgp_static *bgp_static;
4468 struct bgp_node *rn;
4469
4470 /* Convert IP prefix string to struct prefix. */
4471 ret = str2prefix(ip_str, &p);
4472 if (!ret) {
4473 vty_out(vty, "%% Malformed prefix\n");
4474 return CMD_WARNING_CONFIG_FAILED;
4475 }
4476 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
4477 vty_out(vty, "%% Malformed prefix (link-local address)\n");
4478 return CMD_WARNING_CONFIG_FAILED;
4479 }
4480
4481 apply_mask(&p);
4482
4483 rn = bgp_node_lookup(bgp->route[afi][safi], &p);
4484 if (!rn) {
4485 vty_out(vty,
4486 "%% Can't find specified static route configuration.\n");
4487 return CMD_WARNING_CONFIG_FAILED;
4488 }
4489
4490 bgp_static = rn->info;
4491
4492 /* Update BGP RIB. */
4493 if (!bgp_static->backdoor)
4494 bgp_static_withdraw(bgp, &p, afi, safi);
4495
4496 /* Clear configuration. */
4497 bgp_static_free(bgp_static);
4498 rn->info = NULL;
4499 bgp_unlock_node(rn);
4500 bgp_unlock_node(rn);
4501
4502 return CMD_SUCCESS;
4503 }
4504
4505 void bgp_static_add(struct bgp *bgp)
4506 {
4507 afi_t afi;
4508 safi_t safi;
4509 struct bgp_node *rn;
4510 struct bgp_node *rm;
4511 struct bgp_table *table;
4512 struct bgp_static *bgp_static;
4513
4514 for (afi = AFI_IP; afi < AFI_MAX; afi++)
4515 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
4516 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
4517 rn = bgp_route_next(rn))
4518 if (rn->info != NULL) {
4519 if ((safi == SAFI_MPLS_VPN)
4520 || (safi == SAFI_ENCAP)
4521 || (safi == SAFI_EVPN)) {
4522 table = rn->info;
4523
4524 for (rm = bgp_table_top(table);
4525 rm;
4526 rm = bgp_route_next(rm)) {
4527 bgp_static = rm->info;
4528 bgp_static_update_safi(
4529 bgp, &rm->p,
4530 bgp_static, afi,
4531 safi);
4532 }
4533 } else {
4534 bgp_static_update(bgp, &rn->p,
4535 rn->info, afi,
4536 safi);
4537 }
4538 }
4539 }
4540
4541 /* Called from bgp_delete(). Delete all static routes from the BGP
4542 instance. */
4543 void bgp_static_delete(struct bgp *bgp)
4544 {
4545 afi_t afi;
4546 safi_t safi;
4547 struct bgp_node *rn;
4548 struct bgp_node *rm;
4549 struct bgp_table *table;
4550 struct bgp_static *bgp_static;
4551
4552 for (afi = AFI_IP; afi < AFI_MAX; afi++)
4553 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
4554 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
4555 rn = bgp_route_next(rn))
4556 if (rn->info != NULL) {
4557 if ((safi == SAFI_MPLS_VPN)
4558 || (safi == SAFI_ENCAP)
4559 || (safi == SAFI_EVPN)) {
4560 table = rn->info;
4561
4562 for (rm = bgp_table_top(table);
4563 rm;
4564 rm = bgp_route_next(rm)) {
4565 bgp_static = rm->info;
4566 bgp_static_withdraw_safi(
4567 bgp, &rm->p,
4568 AFI_IP, safi,
4569 (struct
4570 prefix_rd *)&rn
4571 ->p);
4572 bgp_static_free(
4573 bgp_static);
4574 rn->info = NULL;
4575 bgp_unlock_node(rn);
4576 }
4577 } else {
4578 bgp_static = rn->info;
4579 bgp_static_withdraw(bgp, &rn->p,
4580 afi, safi);
4581 bgp_static_free(bgp_static);
4582 rn->info = NULL;
4583 bgp_unlock_node(rn);
4584 }
4585 }
4586 }
4587
4588 void bgp_static_redo_import_check(struct bgp *bgp)
4589 {
4590 afi_t afi;
4591 safi_t safi;
4592 struct bgp_node *rn;
4593 struct bgp_node *rm;
4594 struct bgp_table *table;
4595 struct bgp_static *bgp_static;
4596
4597 /* Use this flag to force reprocessing of the route */
4598 bgp_flag_set(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
4599 for (afi = AFI_IP; afi < AFI_MAX; afi++)
4600 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
4601 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
4602 rn = bgp_route_next(rn))
4603 if (rn->info != NULL) {
4604 if ((safi == SAFI_MPLS_VPN)
4605 || (safi == SAFI_ENCAP)
4606 || (safi == SAFI_EVPN)) {
4607 table = rn->info;
4608
4609 for (rm = bgp_table_top(table);
4610 rm;
4611 rm = bgp_route_next(rm)) {
4612 bgp_static = rm->info;
4613 bgp_static_update_safi(
4614 bgp, &rm->p,
4615 bgp_static, afi,
4616 safi);
4617 }
4618 } else {
4619 bgp_static = rn->info;
4620 bgp_static_update(bgp, &rn->p,
4621 bgp_static,
4622 afi, safi);
4623 }
4624 }
4625 bgp_flag_unset(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
4626 }
4627
4628 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
4629 safi_t safi)
4630 {
4631 struct bgp_table *table;
4632 struct bgp_node *rn;
4633 struct bgp_info *ri;
4634
4635 table = bgp->rib[afi][safi];
4636 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
4637 for (ri = rn->info; ri; ri = ri->next) {
4638 if (ri->peer == bgp->peer_self
4639 && ((ri->type == ZEBRA_ROUTE_BGP
4640 && ri->sub_type == BGP_ROUTE_STATIC)
4641 || (ri->type != ZEBRA_ROUTE_BGP
4642 && ri->sub_type
4643 == BGP_ROUTE_REDISTRIBUTE))) {
4644 bgp_aggregate_decrement(bgp, &rn->p, ri, afi,
4645 safi);
4646 bgp_unlink_nexthop(ri);
4647 bgp_info_delete(rn, ri);
4648 bgp_process(bgp, rn, afi, safi);
4649 }
4650 }
4651 }
4652 }
4653
4654 /*
4655 * Purge all networks and redistributed routes from routing table.
4656 * Invoked upon the instance going down.
4657 */
4658 void bgp_purge_static_redist_routes(struct bgp *bgp)
4659 {
4660 afi_t afi;
4661 safi_t safi;
4662
4663 for (afi = AFI_IP; afi < AFI_MAX; afi++)
4664 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
4665 bgp_purge_af_static_redist_routes(bgp, afi, safi);
4666 }
4667
4668 /*
4669 * gpz 110624
4670 * Currently this is used to set static routes for VPN and ENCAP.
4671 * I think it can probably be factored with bgp_static_set.
4672 */
4673 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
4674 const char *ip_str, const char *rd_str,
4675 const char *label_str, const char *rmap_str,
4676 int evpn_type, const char *esi, const char *gwip,
4677 const char *ethtag, const char *routermac)
4678 {
4679 VTY_DECLVAR_CONTEXT(bgp, bgp);
4680 int ret;
4681 struct prefix p;
4682 struct prefix_rd prd;
4683 struct bgp_node *prn;
4684 struct bgp_node *rn;
4685 struct bgp_table *table;
4686 struct bgp_static *bgp_static;
4687 mpls_label_t label = MPLS_INVALID_LABEL;
4688 struct prefix gw_ip;
4689
4690 /* validate ip prefix */
4691 ret = str2prefix(ip_str, &p);
4692 if (!ret) {
4693 vty_out(vty, "%% Malformed prefix\n");
4694 return CMD_WARNING_CONFIG_FAILED;
4695 }
4696 apply_mask(&p);
4697 if ((afi == AFI_L2VPN)
4698 && (bgp_build_evpn_prefix(evpn_type,
4699 ethtag != NULL ? atol(ethtag) : 0, &p))) {
4700 vty_out(vty, "%% L2VPN prefix could not be forged\n");
4701 return CMD_WARNING_CONFIG_FAILED;
4702 }
4703
4704 ret = str2prefix_rd(rd_str, &prd);
4705 if (!ret) {
4706 vty_out(vty, "%% Malformed rd\n");
4707 return CMD_WARNING_CONFIG_FAILED;
4708 }
4709
4710 if (label_str) {
4711 unsigned long label_val;
4712 label_val = strtoul(label_str, NULL, 10);
4713 encode_label(label_val, &label);
4714 }
4715
4716 if (safi == SAFI_EVPN) {
4717 if (esi && str2esi(esi, NULL) == 0) {
4718 vty_out(vty, "%% Malformed ESI\n");
4719 return CMD_WARNING_CONFIG_FAILED;
4720 }
4721 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
4722 vty_out(vty, "%% Malformed Router MAC\n");
4723 return CMD_WARNING_CONFIG_FAILED;
4724 }
4725 if (gwip) {
4726 memset(&gw_ip, 0, sizeof(struct prefix));
4727 ret = str2prefix(gwip, &gw_ip);
4728 if (!ret) {
4729 vty_out(vty, "%% Malformed GatewayIp\n");
4730 return CMD_WARNING_CONFIG_FAILED;
4731 }
4732 if ((gw_ip.family == AF_INET
4733 && IS_EVPN_PREFIX_IPADDR_V6(
4734 (struct prefix_evpn *)&p))
4735 || (gw_ip.family == AF_INET6
4736 && IS_EVPN_PREFIX_IPADDR_V4(
4737 (struct prefix_evpn *)&p))) {
4738 vty_out(vty,
4739 "%% GatewayIp family differs with IP prefix\n");
4740 return CMD_WARNING_CONFIG_FAILED;
4741 }
4742 }
4743 }
4744 prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
4745 if (prn->info == NULL)
4746 prn->info = bgp_table_init(afi, safi);
4747 else
4748 bgp_unlock_node(prn);
4749 table = prn->info;
4750
4751 rn = bgp_node_get(table, &p);
4752
4753 if (rn->info) {
4754 vty_out(vty, "%% Same network configuration exists\n");
4755 bgp_unlock_node(rn);
4756 } else {
4757 /* New configuration. */
4758 bgp_static = bgp_static_new();
4759 bgp_static->backdoor = 0;
4760 bgp_static->valid = 0;
4761 bgp_static->igpmetric = 0;
4762 bgp_static->igpnexthop.s_addr = 0;
4763 bgp_static->label = label;
4764 bgp_static->prd = prd;
4765
4766 if (rmap_str) {
4767 if (bgp_static->rmap.name)
4768 XFREE(MTYPE_ROUTE_MAP_NAME,
4769 bgp_static->rmap.name);
4770 bgp_static->rmap.name =
4771 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
4772 bgp_static->rmap.map =
4773 route_map_lookup_by_name(rmap_str);
4774 }
4775
4776 if (safi == SAFI_EVPN) {
4777 if (esi) {
4778 bgp_static->eth_s_id =
4779 XCALLOC(MTYPE_ATTR,
4780 sizeof(struct eth_segment_id));
4781 str2esi(esi, bgp_static->eth_s_id);
4782 }
4783 if (routermac) {
4784 bgp_static->router_mac =
4785 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
4786 prefix_str2mac(routermac,
4787 bgp_static->router_mac);
4788 }
4789 if (gwip)
4790 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
4791 }
4792 rn->info = bgp_static;
4793
4794 bgp_static->valid = 1;
4795 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
4796 }
4797
4798 return CMD_SUCCESS;
4799 }
4800
4801 /* Configure static BGP network. */
4802 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
4803 const char *ip_str, const char *rd_str,
4804 const char *label_str, int evpn_type, const char *esi,
4805 const char *gwip, const char *ethtag)
4806 {
4807 VTY_DECLVAR_CONTEXT(bgp, bgp);
4808 int ret;
4809 struct prefix p;
4810 struct prefix_rd prd;
4811 struct bgp_node *prn;
4812 struct bgp_node *rn;
4813 struct bgp_table *table;
4814 struct bgp_static *bgp_static;
4815 mpls_label_t label = MPLS_INVALID_LABEL;
4816
4817 /* Convert IP prefix string to struct prefix. */
4818 ret = str2prefix(ip_str, &p);
4819 if (!ret) {
4820 vty_out(vty, "%% Malformed prefix\n");
4821 return CMD_WARNING_CONFIG_FAILED;
4822 }
4823 apply_mask(&p);
4824 if ((afi == AFI_L2VPN)
4825 && (bgp_build_evpn_prefix(evpn_type,
4826 ethtag != NULL ? atol(ethtag) : 0, &p))) {
4827 vty_out(vty, "%% L2VPN prefix could not be forged\n");
4828 return CMD_WARNING_CONFIG_FAILED;
4829 }
4830 ret = str2prefix_rd(rd_str, &prd);
4831 if (!ret) {
4832 vty_out(vty, "%% Malformed rd\n");
4833 return CMD_WARNING_CONFIG_FAILED;
4834 }
4835
4836 if (label_str) {
4837 unsigned long label_val;
4838 label_val = strtoul(label_str, NULL, 10);
4839 encode_label(label_val, &label);
4840 }
4841
4842 prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
4843 if (prn->info == NULL)
4844 prn->info = bgp_table_init(afi, safi);
4845 else
4846 bgp_unlock_node(prn);
4847 table = prn->info;
4848
4849 rn = bgp_node_lookup(table, &p);
4850
4851 if (rn) {
4852 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
4853
4854 bgp_static = rn->info;
4855 bgp_static_free(bgp_static);
4856 rn->info = NULL;
4857 bgp_unlock_node(rn);
4858 bgp_unlock_node(rn);
4859 } else
4860 vty_out(vty, "%% Can't find the route\n");
4861
4862 return CMD_SUCCESS;
4863 }
4864
4865 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
4866 const char *rmap_name)
4867 {
4868 VTY_DECLVAR_CONTEXT(bgp, bgp);
4869 struct bgp_rmap *rmap;
4870
4871 rmap = &bgp->table_map[afi][safi];
4872 if (rmap_name) {
4873 if (rmap->name)
4874 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
4875 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
4876 rmap->map = route_map_lookup_by_name(rmap_name);
4877 } else {
4878 if (rmap->name)
4879 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
4880 rmap->name = NULL;
4881 rmap->map = NULL;
4882 }
4883
4884 if (bgp_fibupd_safi(safi))
4885 bgp_zebra_announce_table(bgp, afi, safi);
4886
4887 return CMD_SUCCESS;
4888 }
4889
4890 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
4891 const char *rmap_name)
4892 {
4893 VTY_DECLVAR_CONTEXT(bgp, bgp);
4894 struct bgp_rmap *rmap;
4895
4896 rmap = &bgp->table_map[afi][safi];
4897 if (rmap->name)
4898 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
4899 rmap->name = NULL;
4900 rmap->map = NULL;
4901
4902 if (bgp_fibupd_safi(safi))
4903 bgp_zebra_announce_table(bgp, afi, safi);
4904
4905 return CMD_SUCCESS;
4906 }
4907
4908 int bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
4909 safi_t safi, int *write)
4910 {
4911 if (bgp->table_map[afi][safi].name) {
4912 bgp_config_write_family_header(vty, afi, safi, write);
4913 vty_out(vty, " table-map %s\n",
4914 bgp->table_map[afi][safi].name);
4915 }
4916
4917 return 0;
4918 }
4919
4920 DEFUN (bgp_table_map,
4921 bgp_table_map_cmd,
4922 "table-map WORD",
4923 "BGP table to RIB route download filter\n"
4924 "Name of the route map\n")
4925 {
4926 int idx_word = 1;
4927 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
4928 argv[idx_word]->arg);
4929 }
4930 DEFUN (no_bgp_table_map,
4931 no_bgp_table_map_cmd,
4932 "no table-map WORD",
4933 NO_STR
4934 "BGP table to RIB route download filter\n"
4935 "Name of the route map\n")
4936 {
4937 int idx_word = 2;
4938 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
4939 argv[idx_word]->arg);
4940 }
4941
4942 DEFUN (bgp_network,
4943 bgp_network_cmd,
4944 "network A.B.C.D/M",
4945 "Specify a network to announce via BGP\n"
4946 "IPv4 prefix\n")
4947 {
4948 int idx_ipv4_prefixlen = 1;
4949 return bgp_static_set(vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP,
4950 bgp_node_safi(vty), NULL, 0,
4951 BGP_INVALID_LABEL_INDEX);
4952 }
4953
4954 DEFUN (bgp_network_route_map,
4955 bgp_network_route_map_cmd,
4956 "network A.B.C.D/M route-map WORD",
4957 "Specify a network to announce via BGP\n"
4958 "IPv4 prefix\n"
4959 "Route-map to modify the attributes\n"
4960 "Name of the route map\n")
4961 {
4962 int idx_ipv4_prefixlen = 1;
4963 int idx_word = 3;
4964 return bgp_static_set(vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP,
4965 bgp_node_safi(vty), argv[idx_word]->arg, 0,
4966 BGP_INVALID_LABEL_INDEX);
4967 }
4968
4969 DEFUN (bgp_network_backdoor,
4970 bgp_network_backdoor_cmd,
4971 "network A.B.C.D/M backdoor",
4972 "Specify a network to announce via BGP\n"
4973 "IPv4 prefix\n"
4974 "Specify a BGP backdoor route\n")
4975 {
4976 int idx_ipv4_prefixlen = 1;
4977 return bgp_static_set(vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP,
4978 SAFI_UNICAST, NULL, 1, BGP_INVALID_LABEL_INDEX);
4979 }
4980
4981 DEFUN (bgp_network_mask,
4982 bgp_network_mask_cmd,
4983 "network A.B.C.D mask A.B.C.D",
4984 "Specify a network to announce via BGP\n"
4985 "Network number\n"
4986 "Network mask\n"
4987 "Network mask\n")
4988 {
4989 int idx_ipv4 = 1;
4990 int idx_ipv4_2 = 3;
4991 int ret;
4992 char prefix_str[BUFSIZ];
4993
4994 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
4995 prefix_str);
4996 if (!ret) {
4997 vty_out(vty, "%% Inconsistent address and mask\n");
4998 return CMD_WARNING_CONFIG_FAILED;
4999 }
5000
5001 return bgp_static_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty), NULL,
5002 0, BGP_INVALID_LABEL_INDEX);
5003 }
5004
5005 DEFUN (bgp_network_mask_route_map,
5006 bgp_network_mask_route_map_cmd,
5007 "network A.B.C.D mask A.B.C.D route-map WORD",
5008 "Specify a network to announce via BGP\n"
5009 "Network number\n"
5010 "Network mask\n"
5011 "Network mask\n"
5012 "Route-map to modify the attributes\n"
5013 "Name of the route map\n")
5014 {
5015 int idx_ipv4 = 1;
5016 int idx_ipv4_2 = 3;
5017 int idx_word = 5;
5018 int ret;
5019 char prefix_str[BUFSIZ];
5020
5021 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
5022 prefix_str);
5023 if (!ret) {
5024 vty_out(vty, "%% Inconsistent address and mask\n");
5025 return CMD_WARNING_CONFIG_FAILED;
5026 }
5027
5028 return bgp_static_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty),
5029 argv[idx_word]->arg, 0, BGP_INVALID_LABEL_INDEX);
5030 }
5031
5032 DEFUN (bgp_network_mask_backdoor,
5033 bgp_network_mask_backdoor_cmd,
5034 "network A.B.C.D mask A.B.C.D backdoor",
5035 "Specify a network to announce via BGP\n"
5036 "Network number\n"
5037 "Network mask\n"
5038 "Network mask\n"
5039 "Specify a BGP backdoor route\n")
5040 {
5041 int idx_ipv4 = 1;
5042 int idx_ipv4_2 = 3;
5043 int ret;
5044 char prefix_str[BUFSIZ];
5045
5046 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
5047 prefix_str);
5048 if (!ret) {
5049 vty_out(vty, "%% Inconsistent address and mask\n");
5050 return CMD_WARNING_CONFIG_FAILED;
5051 }
5052
5053 return bgp_static_set(vty, prefix_str, AFI_IP, SAFI_UNICAST, NULL, 1,
5054 BGP_INVALID_LABEL_INDEX);
5055 }
5056
5057 DEFUN (bgp_network_mask_natural,
5058 bgp_network_mask_natural_cmd,
5059 "network A.B.C.D",
5060 "Specify a network to announce via BGP\n"
5061 "Network number\n")
5062 {
5063 int idx_ipv4 = 1;
5064 int ret;
5065 char prefix_str[BUFSIZ];
5066
5067 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, NULL, prefix_str);
5068 if (!ret) {
5069 vty_out(vty, "%% Inconsistent address and mask\n");
5070 return CMD_WARNING_CONFIG_FAILED;
5071 }
5072
5073 return bgp_static_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty), NULL,
5074 0, BGP_INVALID_LABEL_INDEX);
5075 }
5076
5077 DEFUN (bgp_network_mask_natural_route_map,
5078 bgp_network_mask_natural_route_map_cmd,
5079 "network A.B.C.D route-map WORD",
5080 "Specify a network to announce via BGP\n"
5081 "Network number\n"
5082 "Route-map to modify the attributes\n"
5083 "Name of the route map\n")
5084 {
5085 int idx_ipv4 = 1;
5086 int idx_word = 3;
5087 int ret;
5088 char prefix_str[BUFSIZ];
5089
5090 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, NULL, prefix_str);
5091 if (!ret) {
5092 vty_out(vty, "%% Inconsistent address and mask\n");
5093 return CMD_WARNING_CONFIG_FAILED;
5094 }
5095
5096 return bgp_static_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty),
5097 argv[idx_word]->arg, 0, BGP_INVALID_LABEL_INDEX);
5098 }
5099
5100 DEFUN (bgp_network_mask_natural_backdoor,
5101 bgp_network_mask_natural_backdoor_cmd,
5102 "network A.B.C.D backdoor",
5103 "Specify a network to announce via BGP\n"
5104 "Network number\n"
5105 "Specify a BGP backdoor route\n")
5106 {
5107 int idx_ipv4 = 1;
5108 int ret;
5109 char prefix_str[BUFSIZ];
5110
5111 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, NULL, prefix_str);
5112 if (!ret) {
5113 vty_out(vty, "%% Inconsistent address and mask\n");
5114 return CMD_WARNING_CONFIG_FAILED;
5115 }
5116
5117 return bgp_static_set(vty, prefix_str, AFI_IP, SAFI_UNICAST, NULL, 1,
5118 BGP_INVALID_LABEL_INDEX);
5119 }
5120
5121 DEFUN (bgp_network_label_index,
5122 bgp_network_label_index_cmd,
5123 "network A.B.C.D/M label-index (0-1048560)",
5124 "Specify a network to announce via BGP\n"
5125 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5126 "Label index to associate with the prefix\n"
5127 "Label index value\n")
5128 {
5129 u_int32_t label_index;
5130
5131 label_index = strtoul(argv[3]->arg, NULL, 10);
5132 return bgp_static_set(vty, argv[1]->arg, AFI_IP, bgp_node_safi(vty),
5133 NULL, 0, label_index);
5134 }
5135
5136 DEFUN (bgp_network_label_index_route_map,
5137 bgp_network_label_index_route_map_cmd,
5138 "network A.B.C.D/M label-index (0-1048560) route-map WORD",
5139 "Specify a network to announce via BGP\n"
5140 "IP prefix\n"
5141 "Label index to associate with the prefix\n"
5142 "Label index value\n"
5143 "Route-map to modify the attributes\n"
5144 "Name of the route map\n")
5145 {
5146 u_int32_t label_index;
5147
5148 label_index = strtoul(argv[3]->arg, NULL, 10);
5149 return bgp_static_set(vty, argv[1]->arg, AFI_IP, bgp_node_safi(vty),
5150 argv[5]->arg, 0, label_index);
5151 }
5152
5153 DEFUN (no_bgp_network,
5154 no_bgp_network_cmd,
5155 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
5156 NO_STR
5157 "Specify a network to announce via BGP\n"
5158 "IPv4 prefix\n"
5159 "Specify a BGP backdoor route\n"
5160 "Route-map to modify the attributes\n"
5161 "Name of the route map\n")
5162 {
5163 int idx_ipv4_prefixlen = 2;
5164 return bgp_static_unset(vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP,
5165 bgp_node_safi(vty));
5166 }
5167
5168 DEFUN (no_bgp_network_mask,
5169 no_bgp_network_mask_cmd,
5170 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
5171 NO_STR
5172 "Specify a network to announce via BGP\n"
5173 "Network number\n"
5174 "Network mask\n"
5175 "Network mask\n"
5176 "Specify a BGP backdoor route\n"
5177 "Route-map to modify the attributes\n"
5178 "Name of the route map\n")
5179 {
5180 int idx_ipv4 = 2;
5181 int idx_ipv4_2 = 4;
5182 int ret;
5183 char prefix_str[BUFSIZ];
5184
5185 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
5186 prefix_str);
5187 if (!ret) {
5188 vty_out(vty, "%% Inconsistent address and mask\n");
5189 return CMD_WARNING_CONFIG_FAILED;
5190 }
5191
5192 return bgp_static_unset(vty, prefix_str, AFI_IP, bgp_node_safi(vty));
5193 }
5194
5195 DEFUN (no_bgp_network_mask_natural,
5196 no_bgp_network_mask_natural_cmd,
5197 "no network A.B.C.D [<backdoor|route-map WORD>]",
5198 NO_STR
5199 "Specify a network to announce via BGP\n"
5200 "Network number\n"
5201 "Specify a BGP backdoor route\n"
5202 "Route-map to modify the attributes\n"
5203 "Name of the route map\n")
5204 {
5205 int idx_ipv4 = 2;
5206 int ret;
5207 char prefix_str[BUFSIZ];
5208
5209 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, NULL, prefix_str);
5210 if (!ret) {
5211 vty_out(vty, "%% Inconsistent address and mask\n");
5212 return CMD_WARNING_CONFIG_FAILED;
5213 }
5214
5215 return bgp_static_unset(vty, prefix_str, AFI_IP, bgp_node_safi(vty));
5216 }
5217
5218 ALIAS(no_bgp_network, no_bgp_network_label_index_cmd,
5219 "no network A.B.C.D/M label-index (0-1048560)", NO_STR
5220 "Specify a network to announce via BGP\n"
5221 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5222 "Label index to associate with the prefix\n"
5223 "Label index value\n")
5224
5225 ALIAS(no_bgp_network, no_bgp_network_label_index_route_map_cmd,
5226 "no network A.B.C.D/M label-index (0-1048560) route-map WORD", NO_STR
5227 "Specify a network to announce via BGP\n"
5228 "IP prefix\n"
5229 "Label index to associate with the prefix\n"
5230 "Label index value\n"
5231 "Route-map to modify the attributes\n"
5232 "Name of the route map\n")
5233
5234 DEFUN (ipv6_bgp_network,
5235 ipv6_bgp_network_cmd,
5236 "network X:X::X:X/M",
5237 "Specify a network to announce via BGP\n"
5238 "IPv6 prefix\n")
5239 {
5240 int idx_ipv6_prefixlen = 1;
5241 return bgp_static_set(vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6,
5242 bgp_node_safi(vty), NULL, 0,
5243 BGP_INVALID_LABEL_INDEX);
5244 }
5245
5246 DEFUN (ipv6_bgp_network_route_map,
5247 ipv6_bgp_network_route_map_cmd,
5248 "network X:X::X:X/M route-map WORD",
5249 "Specify a network to announce via BGP\n"
5250 "IPv6 prefix\n"
5251 "Route-map to modify the attributes\n"
5252 "Name of the route map\n")
5253 {
5254 int idx_ipv6_prefixlen = 1;
5255 int idx_word = 3;
5256 return bgp_static_set(vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6,
5257 bgp_node_safi(vty), argv[idx_word]->arg, 0,
5258 BGP_INVALID_LABEL_INDEX);
5259 }
5260
5261 DEFUN (ipv6_bgp_network_label_index,
5262 ipv6_bgp_network_label_index_cmd,
5263 "network X:X::X:X/M label-index (0-1048560)",
5264 "Specify a network to announce via BGP\n"
5265 "IPv6 prefix <network>/<length>\n"
5266 "Label index to associate with the prefix\n"
5267 "Label index value\n")
5268 {
5269 u_int32_t label_index;
5270
5271 label_index = strtoul(argv[3]->arg, NULL, 10);
5272 return bgp_static_set(vty, argv[1]->arg, AFI_IP6, bgp_node_safi(vty),
5273 NULL, 0, label_index);
5274 }
5275
5276 DEFUN (ipv6_bgp_network_label_index_route_map,
5277 ipv6_bgp_network_label_index_route_map_cmd,
5278 "network X:X::X:X/M label-index (0-1048560) route-map WORD",
5279 "Specify a network to announce via BGP\n"
5280 "IPv6 prefix\n"
5281 "Label index to associate with the prefix\n"
5282 "Label index value\n"
5283 "Route-map to modify the attributes\n"
5284 "Name of the route map\n")
5285 {
5286 u_int32_t label_index;
5287
5288 label_index = strtoul(argv[3]->arg, NULL, 10);
5289 return bgp_static_set(vty, argv[1]->arg, AFI_IP6, bgp_node_safi(vty),
5290 argv[5]->arg, 0, label_index);
5291 }
5292
5293 DEFUN (no_ipv6_bgp_network,
5294 no_ipv6_bgp_network_cmd,
5295 "no network X:X::X:X/M [route-map WORD]",
5296 NO_STR
5297 "Specify a network to announce via BGP\n"
5298 "IPv6 prefix\n"
5299 "Route-map to modify the attributes\n"
5300 "Name of the route map\n")
5301 {
5302 int idx_ipv6_prefixlen = 2;
5303 return bgp_static_unset(vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6,
5304 bgp_node_safi(vty));
5305 }
5306
5307 ALIAS(no_ipv6_bgp_network, no_ipv6_bgp_network_label_index_cmd,
5308 "no network X:X::X:X/M label-index (0-1048560)", NO_STR
5309 "Specify a network to announce via BGP\n"
5310 "IPv6 prefix <network>/<length>\n"
5311 "Label index to associate with the prefix\n"
5312 "Label index value\n")
5313
5314 ALIAS(no_ipv6_bgp_network, no_ipv6_bgp_network_label_index_route_map_cmd,
5315 "no network X:X::X:X/M label-index (0-1048560) route-map WORD", NO_STR
5316 "Specify a network to announce via BGP\n"
5317 "IPv6 prefix\n"
5318 "Label index to associate with the prefix\n"
5319 "Label index value\n"
5320 "Route-map to modify the attributes\n"
5321 "Name of the route map\n")
5322
5323 /* Aggreagete address:
5324
5325 advertise-map Set condition to advertise attribute
5326 as-set Generate AS set path information
5327 attribute-map Set attributes of aggregate
5328 route-map Set parameters of aggregate
5329 summary-only Filter more specific routes from updates
5330 suppress-map Conditionally filter more specific routes from updates
5331 <cr>
5332 */
5333 struct bgp_aggregate {
5334 /* Summary-only flag. */
5335 u_char summary_only;
5336
5337 /* AS set generation. */
5338 u_char as_set;
5339
5340 /* Route-map for aggregated route. */
5341 struct route_map *map;
5342
5343 /* Suppress-count. */
5344 unsigned long count;
5345
5346 /* SAFI configuration. */
5347 safi_t safi;
5348 };
5349
5350 static struct bgp_aggregate *bgp_aggregate_new(void)
5351 {
5352 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
5353 }
5354
5355 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
5356 {
5357 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
5358 }
5359
5360 /* Update an aggregate as routes are added/removed from the BGP table */
5361 static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
5362 struct bgp_info *rinew, afi_t afi, safi_t safi,
5363 struct bgp_info *del,
5364 struct bgp_aggregate *aggregate)
5365 {
5366 struct bgp_table *table;
5367 struct bgp_node *top;
5368 struct bgp_node *rn;
5369 u_char origin;
5370 struct aspath *aspath = NULL;
5371 struct aspath *asmerge = NULL;
5372 struct community *community = NULL;
5373 struct community *commerge = NULL;
5374 #if defined(AGGREGATE_NEXTHOP_CHECK)
5375 struct in_addr nexthop;
5376 u_int32_t med = 0;
5377 #endif
5378 struct bgp_info *ri;
5379 struct bgp_info *new;
5380 int first = 1;
5381 unsigned long match = 0;
5382 u_char atomic_aggregate = 0;
5383
5384 /* Record adding route's nexthop and med. */
5385 if (rinew) {
5386 #if defined(AGGREGATE_NEXTHOP_CHECK)
5387 nexthop = rinew->attr->nexthop;
5388 med = rinew->attr->med;
5389 #endif
5390 }
5391
5392 /* ORIGIN attribute: If at least one route among routes that are
5393 aggregated has ORIGIN with the value INCOMPLETE, then the
5394 aggregated route must have the ORIGIN attribute with the value
5395 INCOMPLETE. Otherwise, if at least one route among routes that
5396 are aggregated has ORIGIN with the value EGP, then the aggregated
5397 route must have the origin attribute with the value EGP. In all
5398 other case the value of the ORIGIN attribute of the aggregated
5399 route is INTERNAL. */
5400 origin = BGP_ORIGIN_IGP;
5401
5402 table = bgp->rib[afi][safi];
5403
5404 top = bgp_node_get(table, p);
5405 for (rn = bgp_node_get(table, p); rn;
5406 rn = bgp_route_next_until(rn, top))
5407 if (rn->p.prefixlen > p->prefixlen) {
5408 match = 0;
5409
5410 for (ri = rn->info; ri; ri = ri->next) {
5411 if (BGP_INFO_HOLDDOWN(ri))
5412 continue;
5413
5414 if (del && ri == del)
5415 continue;
5416
5417 if (!rinew && first) {
5418 #if defined(AGGREGATE_NEXTHOP_CHECK)
5419 nexthop = ri->attr->nexthop;
5420 med = ri->attr->med;
5421 #endif
5422 first = 0;
5423 }
5424
5425 #ifdef AGGREGATE_NEXTHOP_CHECK
5426 if (!IPV4_ADDR_SAME(&ri->attr->nexthop,
5427 &nexthop)
5428 || ri->attr->med != med) {
5429 if (aspath)
5430 aspath_free(aspath);
5431 if (community)
5432 community_free(community);
5433 bgp_unlock_node(rn);
5434 bgp_unlock_node(top);
5435 return;
5436 }
5437 #endif /* AGGREGATE_NEXTHOP_CHECK */
5438
5439 if (ri->attr->flag
5440 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
5441 atomic_aggregate = 1;
5442
5443 if (ri->sub_type != BGP_ROUTE_AGGREGATE) {
5444 if (aggregate->summary_only) {
5445 (bgp_info_extra_get(ri))
5446 ->suppress++;
5447 bgp_info_set_flag(
5448 rn, ri,
5449 BGP_INFO_ATTR_CHANGED);
5450 match++;
5451 }
5452
5453 aggregate->count++;
5454
5455 if (origin < ri->attr->origin)
5456 origin = ri->attr->origin;
5457
5458 if (aggregate->as_set) {
5459 if (aspath) {
5460 asmerge = aspath_aggregate(
5461 aspath,
5462 ri->attr->aspath);
5463 aspath_free(aspath);
5464 aspath = asmerge;
5465 } else
5466 aspath = aspath_dup(
5467 ri->attr->aspath);
5468
5469 if (ri->attr->community) {
5470 if (community) {
5471 commerge = community_merge(
5472 community,
5473 ri->attr->community);
5474 community = community_uniq_sort(
5475 commerge);
5476 community_free(
5477 commerge);
5478 } else
5479 community = community_dup(
5480 ri->attr->community);
5481 }
5482 }
5483 }
5484 }
5485 if (match)
5486 bgp_process(bgp, rn, afi, safi);
5487 }
5488 bgp_unlock_node(top);
5489
5490 if (rinew) {
5491 aggregate->count++;
5492
5493 if (aggregate->summary_only)
5494 (bgp_info_extra_get(rinew))->suppress++;
5495
5496 if (origin < rinew->attr->origin)
5497 origin = rinew->attr->origin;
5498
5499 if (aggregate->as_set) {
5500 if (aspath) {
5501 asmerge = aspath_aggregate(aspath,
5502 rinew->attr->aspath);
5503 aspath_free(aspath);
5504 aspath = asmerge;
5505 } else
5506 aspath = aspath_dup(rinew->attr->aspath);
5507
5508 if (rinew->attr->community) {
5509 if (community) {
5510 commerge = community_merge(
5511 community,
5512 rinew->attr->community);
5513 community =
5514 community_uniq_sort(commerge);
5515 community_free(commerge);
5516 } else
5517 community = community_dup(
5518 rinew->attr->community);
5519 }
5520 }
5521 }
5522
5523 if (aggregate->count > 0) {
5524 rn = bgp_node_get(table, p);
5525 new = info_make(
5526 ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self,
5527 bgp_attr_aggregate_intern(bgp, origin, aspath,
5528 community, aggregate->as_set,
5529 atomic_aggregate),
5530 rn);
5531 SET_FLAG(new->flags, BGP_INFO_VALID);
5532
5533 bgp_info_add(rn, new);
5534 bgp_unlock_node(rn);
5535 bgp_process(bgp, rn, afi, safi);
5536 } else {
5537 if (aspath)
5538 aspath_free(aspath);
5539 if (community)
5540 community_free(community);
5541 }
5542 }
5543
5544 void bgp_aggregate_delete(struct bgp *, struct prefix *, afi_t, safi_t,
5545 struct bgp_aggregate *);
5546
5547 void bgp_aggregate_increment(struct bgp *bgp, struct prefix *p,
5548 struct bgp_info *ri, afi_t afi, safi_t safi)
5549 {
5550 struct bgp_node *child;
5551 struct bgp_node *rn;
5552 struct bgp_aggregate *aggregate;
5553 struct bgp_table *table;
5554
5555 /* MPLS-VPN aggregation is not yet supported. */
5556 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5557 || (safi == SAFI_EVPN))
5558 return;
5559
5560 table = bgp->aggregate[afi][safi];
5561
5562 /* No aggregates configured. */
5563 if (bgp_table_top_nolock(table) == NULL)
5564 return;
5565
5566 if (p->prefixlen == 0)
5567 return;
5568
5569 if (BGP_INFO_HOLDDOWN(ri))
5570 return;
5571
5572 child = bgp_node_get(table, p);
5573
5574 /* Aggregate address configuration check. */
5575 for (rn = child; rn; rn = bgp_node_parent_nolock(rn))
5576 if ((aggregate = rn->info) != NULL
5577 && rn->p.prefixlen < p->prefixlen) {
5578 bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
5579 bgp_aggregate_route(bgp, &rn->p, ri, afi, safi, NULL,
5580 aggregate);
5581 }
5582 bgp_unlock_node(child);
5583 }
5584
5585 void bgp_aggregate_decrement(struct bgp *bgp, struct prefix *p,
5586 struct bgp_info *del, afi_t afi, safi_t safi)
5587 {
5588 struct bgp_node *child;
5589 struct bgp_node *rn;
5590 struct bgp_aggregate *aggregate;
5591 struct bgp_table *table;
5592
5593 /* MPLS-VPN aggregation is not yet supported. */
5594 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5595 || (safi == SAFI_EVPN))
5596 return;
5597
5598 table = bgp->aggregate[afi][safi];
5599
5600 /* No aggregates configured. */
5601 if (bgp_table_top_nolock(table) == NULL)
5602 return;
5603
5604 if (p->prefixlen == 0)
5605 return;
5606
5607 child = bgp_node_get(table, p);
5608
5609 /* Aggregate address configuration check. */
5610 for (rn = child; rn; rn = bgp_node_parent_nolock(rn))
5611 if ((aggregate = rn->info) != NULL
5612 && rn->p.prefixlen < p->prefixlen) {
5613 bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
5614 bgp_aggregate_route(bgp, &rn->p, NULL, afi, safi, del,
5615 aggregate);
5616 }
5617 bgp_unlock_node(child);
5618 }
5619
5620 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5621 static void bgp_aggregate_add(struct bgp *bgp, struct prefix *p, afi_t afi,
5622 safi_t safi, struct bgp_aggregate *aggregate)
5623 {
5624 struct bgp_table *table;
5625 struct bgp_node *top;
5626 struct bgp_node *rn;
5627 struct bgp_info *new;
5628 struct bgp_info *ri;
5629 unsigned long match;
5630 u_char origin = BGP_ORIGIN_IGP;
5631 struct aspath *aspath = NULL;
5632 struct aspath *asmerge = NULL;
5633 struct community *community = NULL;
5634 struct community *commerge = NULL;
5635 u_char atomic_aggregate = 0;
5636
5637 table = bgp->rib[afi][safi];
5638
5639 /* Sanity check. */
5640 if (afi == AFI_IP && p->prefixlen == IPV4_MAX_BITLEN)
5641 return;
5642 if (afi == AFI_IP6 && p->prefixlen == IPV6_MAX_BITLEN)
5643 return;
5644
5645 /* If routes exists below this node, generate aggregate routes. */
5646 top = bgp_node_get(table, p);
5647 for (rn = bgp_node_get(table, p); rn;
5648 rn = bgp_route_next_until(rn, top))
5649 if (rn->p.prefixlen > p->prefixlen) {
5650 match = 0;
5651
5652 for (ri = rn->info; ri; ri = ri->next) {
5653 if (BGP_INFO_HOLDDOWN(ri))
5654 continue;
5655
5656 if (ri->attr->flag
5657 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
5658 atomic_aggregate = 1;
5659
5660 if (ri->sub_type != BGP_ROUTE_AGGREGATE) {
5661 /* summary-only aggregate route suppress
5662 aggregated
5663 route announcement. */
5664 if (aggregate->summary_only) {
5665 (bgp_info_extra_get(ri))
5666 ->suppress++;
5667 bgp_info_set_flag(
5668 rn, ri,
5669 BGP_INFO_ATTR_CHANGED);
5670 match++;
5671 }
5672
5673 /* If at least one route among routes
5674 * that are aggregated has
5675 * ORIGIN with the value INCOMPLETE,
5676 * then the aggregated route
5677 * MUST have the ORIGIN attribute with
5678 * the value INCOMPLETE.
5679 * Otherwise, if at least one route
5680 * among routes that are
5681 * aggregated has ORIGIN with the value
5682 * EGP, then the aggregated
5683 * route MUST have the ORIGIN attribute
5684 * with the value EGP.
5685 */
5686 if (origin < ri->attr->origin)
5687 origin = ri->attr->origin;
5688
5689 /* as-set aggregate route generate
5690 origin, as path,
5691 community aggregation. */
5692 if (aggregate->as_set) {
5693 if (aspath) {
5694 asmerge = aspath_aggregate(
5695 aspath,
5696 ri->attr->aspath);
5697 aspath_free(aspath);
5698 aspath = asmerge;
5699 } else
5700 aspath = aspath_dup(
5701 ri->attr->aspath);
5702
5703 if (ri->attr->community) {
5704 if (community) {
5705 commerge = community_merge(
5706 community,
5707 ri->attr->community);
5708 community = community_uniq_sort(
5709 commerge);
5710 community_free(
5711 commerge);
5712 } else
5713 community = community_dup(
5714 ri->attr->community);
5715 }
5716 }
5717 aggregate->count++;
5718 }
5719 }
5720
5721 /* If this node is suppressed, process the change. */
5722 if (match)
5723 bgp_process(bgp, rn, afi, safi);
5724 }
5725 bgp_unlock_node(top);
5726
5727 /* Add aggregate route to BGP table. */
5728 if (aggregate->count) {
5729 rn = bgp_node_get(table, p);
5730 new = info_make(
5731 ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self,
5732 bgp_attr_aggregate_intern(bgp, origin, aspath,
5733 community, aggregate->as_set,
5734 atomic_aggregate),
5735 rn);
5736 SET_FLAG(new->flags, BGP_INFO_VALID);
5737
5738 bgp_info_add(rn, new);
5739 bgp_unlock_node(rn);
5740
5741 /* Process change. */
5742 bgp_process(bgp, rn, afi, safi);
5743 } else {
5744 if (aspath)
5745 aspath_free(aspath);
5746 if (community)
5747 community_free(community);
5748 }
5749 }
5750
5751 void bgp_aggregate_delete(struct bgp *bgp, struct prefix *p, afi_t afi,
5752 safi_t safi, struct bgp_aggregate *aggregate)
5753 {
5754 struct bgp_table *table;
5755 struct bgp_node *top;
5756 struct bgp_node *rn;
5757 struct bgp_info *ri;
5758 unsigned long match;
5759
5760 table = bgp->rib[afi][safi];
5761
5762 if (afi == AFI_IP && p->prefixlen == IPV4_MAX_BITLEN)
5763 return;
5764 if (afi == AFI_IP6 && p->prefixlen == IPV6_MAX_BITLEN)
5765 return;
5766
5767 /* If routes exists below this node, generate aggregate routes. */
5768 top = bgp_node_get(table, p);
5769 for (rn = bgp_node_get(table, p); rn;
5770 rn = bgp_route_next_until(rn, top))
5771 if (rn->p.prefixlen > p->prefixlen) {
5772 match = 0;
5773
5774 for (ri = rn->info; ri; ri = ri->next) {
5775 if (BGP_INFO_HOLDDOWN(ri))
5776 continue;
5777
5778 if (ri->sub_type != BGP_ROUTE_AGGREGATE) {
5779 if (aggregate->summary_only
5780 && ri->extra) {
5781 ri->extra->suppress--;
5782
5783 if (ri->extra->suppress == 0) {
5784 bgp_info_set_flag(
5785 rn, ri,
5786 BGP_INFO_ATTR_CHANGED);
5787 match++;
5788 }
5789 }
5790 aggregate->count--;
5791 }
5792 }
5793
5794 /* If this node was suppressed, process the change. */
5795 if (match)
5796 bgp_process(bgp, rn, afi, safi);
5797 }
5798 bgp_unlock_node(top);
5799
5800 /* Delete aggregate route from BGP table. */
5801 rn = bgp_node_get(table, p);
5802
5803 for (ri = rn->info; ri; ri = ri->next)
5804 if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
5805 && ri->sub_type == BGP_ROUTE_AGGREGATE)
5806 break;
5807
5808 /* Withdraw static BGP route from routing table. */
5809 if (ri) {
5810 bgp_info_delete(rn, ri);
5811 bgp_process(bgp, rn, afi, safi);
5812 }
5813
5814 /* Unlock bgp_node_lookup. */
5815 bgp_unlock_node(rn);
5816 }
5817
5818 /* Aggregate route attribute. */
5819 #define AGGREGATE_SUMMARY_ONLY 1
5820 #define AGGREGATE_AS_SET 1
5821
5822 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
5823 afi_t afi, safi_t safi)
5824 {
5825 VTY_DECLVAR_CONTEXT(bgp, bgp);
5826 int ret;
5827 struct prefix p;
5828 struct bgp_node *rn;
5829 struct bgp_aggregate *aggregate;
5830
5831 /* Convert string to prefix structure. */
5832 ret = str2prefix(prefix_str, &p);
5833 if (!ret) {
5834 vty_out(vty, "Malformed prefix\n");
5835 return CMD_WARNING_CONFIG_FAILED;
5836 }
5837 apply_mask(&p);
5838
5839 /* Old configuration check. */
5840 rn = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
5841 if (!rn) {
5842 vty_out(vty,
5843 "%% There is no aggregate-address configuration.\n");
5844 return CMD_WARNING_CONFIG_FAILED;
5845 }
5846
5847 aggregate = rn->info;
5848 if (aggregate->safi == SAFI_UNICAST)
5849 bgp_aggregate_delete(bgp, &p, afi, SAFI_UNICAST, aggregate);
5850 if (aggregate->safi == SAFI_LABELED_UNICAST)
5851 bgp_aggregate_delete(bgp, &p, afi, SAFI_LABELED_UNICAST,
5852 aggregate);
5853 if (aggregate->safi == SAFI_MULTICAST)
5854 bgp_aggregate_delete(bgp, &p, afi, SAFI_MULTICAST, aggregate);
5855
5856 /* Unlock aggregate address configuration. */
5857 rn->info = NULL;
5858 bgp_aggregate_free(aggregate);
5859 bgp_unlock_node(rn);
5860 bgp_unlock_node(rn);
5861
5862 return CMD_SUCCESS;
5863 }
5864
5865 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
5866 safi_t safi, u_char summary_only, u_char as_set)
5867 {
5868 VTY_DECLVAR_CONTEXT(bgp, bgp);
5869 int ret;
5870 struct prefix p;
5871 struct bgp_node *rn;
5872 struct bgp_aggregate *aggregate;
5873
5874 /* Convert string to prefix structure. */
5875 ret = str2prefix(prefix_str, &p);
5876 if (!ret) {
5877 vty_out(vty, "Malformed prefix\n");
5878 return CMD_WARNING_CONFIG_FAILED;
5879 }
5880 apply_mask(&p);
5881
5882 /* Old configuration check. */
5883 rn = bgp_node_get(bgp->aggregate[afi][safi], &p);
5884
5885 if (rn->info) {
5886 vty_out(vty, "There is already same aggregate network.\n");
5887 /* try to remove the old entry */
5888 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
5889 if (ret) {
5890 vty_out(vty, "Error deleting aggregate.\n");
5891 bgp_unlock_node(rn);
5892 return CMD_WARNING_CONFIG_FAILED;
5893 }
5894 }
5895
5896 /* Make aggregate address structure. */
5897 aggregate = bgp_aggregate_new();
5898 aggregate->summary_only = summary_only;
5899 aggregate->as_set = as_set;
5900 aggregate->safi = safi;
5901 rn->info = aggregate;
5902
5903 /* Aggregate address insert into BGP routing table. */
5904 if (safi == SAFI_UNICAST)
5905 bgp_aggregate_add(bgp, &p, afi, SAFI_UNICAST, aggregate);
5906 if (safi == SAFI_LABELED_UNICAST)
5907 bgp_aggregate_add(bgp, &p, afi, SAFI_LABELED_UNICAST,
5908 aggregate);
5909 if (safi == SAFI_MULTICAST)
5910 bgp_aggregate_add(bgp, &p, afi, SAFI_MULTICAST, aggregate);
5911
5912 return CMD_SUCCESS;
5913 }
5914
5915 DEFUN (aggregate_address,
5916 aggregate_address_cmd,
5917 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5918 "Configure BGP aggregate entries\n"
5919 "Aggregate prefix\n"
5920 "Generate AS set path information\n"
5921 "Filter more specific routes from updates\n"
5922 "Filter more specific routes from updates\n"
5923 "Generate AS set path information\n")
5924 {
5925 int idx = 0;
5926 argv_find(argv, argc, "A.B.C.D/M", &idx);
5927 char *prefix = argv[idx]->arg;
5928 int as_set =
5929 argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
5930 idx = 0;
5931 int summary_only = argv_find(argv, argc, "summary-only", &idx)
5932 ? AGGREGATE_SUMMARY_ONLY
5933 : 0;
5934
5935 return bgp_aggregate_set(vty, prefix, AFI_IP, bgp_node_safi(vty),
5936 summary_only, as_set);
5937 }
5938
5939 DEFUN (aggregate_address_mask,
5940 aggregate_address_mask_cmd,
5941 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5942 "Configure BGP aggregate entries\n"
5943 "Aggregate address\n"
5944 "Aggregate mask\n"
5945 "Generate AS set path information\n"
5946 "Filter more specific routes from updates\n"
5947 "Filter more specific routes from updates\n"
5948 "Generate AS set path information\n")
5949 {
5950 int idx = 0;
5951 argv_find(argv, argc, "A.B.C.D", &idx);
5952 char *prefix = argv[idx]->arg;
5953 char *mask = argv[idx + 1]->arg;
5954 int as_set =
5955 argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
5956 idx = 0;
5957 int summary_only = argv_find(argv, argc, "summary-only", &idx)
5958 ? AGGREGATE_SUMMARY_ONLY
5959 : 0;
5960
5961 char prefix_str[BUFSIZ];
5962 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
5963
5964 if (!ret) {
5965 vty_out(vty, "%% Inconsistent address and mask\n");
5966 return CMD_WARNING_CONFIG_FAILED;
5967 }
5968
5969 return bgp_aggregate_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty),
5970 summary_only, as_set);
5971 }
5972
5973 DEFUN (no_aggregate_address,
5974 no_aggregate_address_cmd,
5975 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5976 NO_STR
5977 "Configure BGP aggregate entries\n"
5978 "Aggregate prefix\n"
5979 "Generate AS set path information\n"
5980 "Filter more specific routes from updates\n"
5981 "Filter more specific routes from updates\n"
5982 "Generate AS set path information\n")
5983 {
5984 int idx = 0;
5985 argv_find(argv, argc, "A.B.C.D/M", &idx);
5986 char *prefix = argv[idx]->arg;
5987 return bgp_aggregate_unset(vty, prefix, AFI_IP, bgp_node_safi(vty));
5988 }
5989
5990 DEFUN (no_aggregate_address_mask,
5991 no_aggregate_address_mask_cmd,
5992 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5993 NO_STR
5994 "Configure BGP aggregate entries\n"
5995 "Aggregate address\n"
5996 "Aggregate mask\n"
5997 "Generate AS set path information\n"
5998 "Filter more specific routes from updates\n"
5999 "Filter more specific routes from updates\n"
6000 "Generate AS set path information\n")
6001 {
6002 int idx = 0;
6003 argv_find(argv, argc, "A.B.C.D", &idx);
6004 char *prefix = argv[idx]->arg;
6005 char *mask = argv[idx + 1]->arg;
6006
6007 char prefix_str[BUFSIZ];
6008 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
6009
6010 if (!ret) {
6011 vty_out(vty, "%% Inconsistent address and mask\n");
6012 return CMD_WARNING_CONFIG_FAILED;
6013 }
6014
6015 return bgp_aggregate_unset(vty, prefix_str, AFI_IP, bgp_node_safi(vty));
6016 }
6017
6018 DEFUN (ipv6_aggregate_address,
6019 ipv6_aggregate_address_cmd,
6020 "aggregate-address X:X::X:X/M [summary-only]",
6021 "Configure BGP aggregate entries\n"
6022 "Aggregate prefix\n"
6023 "Filter more specific routes from updates\n")
6024 {
6025 int idx = 0;
6026 argv_find(argv, argc, "X:X::X:X/M", &idx);
6027 char *prefix = argv[idx]->arg;
6028 int sum_only = argv_find(argv, argc, "summary-only", &idx)
6029 ? AGGREGATE_SUMMARY_ONLY
6030 : 0;
6031 return bgp_aggregate_set(vty, prefix, AFI_IP6, SAFI_UNICAST, sum_only,
6032 0);
6033 }
6034
6035 DEFUN (no_ipv6_aggregate_address,
6036 no_ipv6_aggregate_address_cmd,
6037 "no aggregate-address X:X::X:X/M [summary-only]",
6038 NO_STR
6039 "Configure BGP aggregate entries\n"
6040 "Aggregate prefix\n"
6041 "Filter more specific routes from updates\n")
6042 {
6043 int idx = 0;
6044 argv_find(argv, argc, "X:X::X:X/M", &idx);
6045 char *prefix = argv[idx]->arg;
6046 return bgp_aggregate_unset(vty, prefix, AFI_IP6, SAFI_UNICAST);
6047 }
6048
6049 /* Redistribute route treatment. */
6050 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
6051 const struct in_addr *nexthop,
6052 const struct in6_addr *nexthop6, unsigned int ifindex,
6053 u_int32_t metric, u_char type, u_short instance,
6054 route_tag_t tag)
6055 {
6056 struct bgp_info *new;
6057 struct bgp_info *bi;
6058 struct bgp_info info;
6059 struct bgp_node *bn;
6060 struct attr attr;
6061 struct attr *new_attr;
6062 afi_t afi;
6063 int ret;
6064 struct bgp_redist *red;
6065
6066 /* Make default attribute. */
6067 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
6068 if (nexthop)
6069 attr.nexthop = *nexthop;
6070 attr.nh_ifindex = ifindex;
6071
6072 if (nexthop6) {
6073 attr.mp_nexthop_global = *nexthop6;
6074 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
6075 }
6076
6077 attr.med = metric;
6078 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6079 attr.tag = tag;
6080
6081 afi = family2afi(p->family);
6082
6083 red = bgp_redist_lookup(bgp, afi, type, instance);
6084 if (red) {
6085 struct attr attr_new;
6086
6087 /* Copy attribute for modification. */
6088 bgp_attr_dup(&attr_new, &attr);
6089
6090 if (red->redist_metric_flag)
6091 attr_new.med = red->redist_metric;
6092
6093 /* Apply route-map. */
6094 if (red->rmap.name) {
6095 info.peer = bgp->peer_self;
6096 info.attr = &attr_new;
6097
6098 SET_FLAG(bgp->peer_self->rmap_type,
6099 PEER_RMAP_TYPE_REDISTRIBUTE);
6100
6101 ret = route_map_apply(red->rmap.map, p, RMAP_BGP,
6102 &info);
6103
6104 bgp->peer_self->rmap_type = 0;
6105
6106 if (ret == RMAP_DENYMATCH) {
6107 /* Free uninterned attribute. */
6108 bgp_attr_flush(&attr_new);
6109
6110 /* Unintern original. */
6111 aspath_unintern(&attr.aspath);
6112 bgp_redistribute_delete(bgp, p, type, instance);
6113 return;
6114 }
6115 }
6116
6117 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
6118 SAFI_UNICAST, p, NULL);
6119
6120 new_attr = bgp_attr_intern(&attr_new);
6121
6122 for (bi = bn->info; bi; bi = bi->next)
6123 if (bi->peer == bgp->peer_self
6124 && bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
6125 break;
6126
6127 if (bi) {
6128 /* Ensure the (source route) type is updated. */
6129 bi->type = type;
6130 if (attrhash_cmp(bi->attr, new_attr)
6131 && !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {
6132 bgp_attr_unintern(&new_attr);
6133 aspath_unintern(&attr.aspath);
6134 bgp_unlock_node(bn);
6135 return;
6136 } else {
6137 /* The attribute is changed. */
6138 bgp_info_set_flag(bn, bi,
6139 BGP_INFO_ATTR_CHANGED);
6140
6141 /* Rewrite BGP route information. */
6142 if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
6143 bgp_info_restore(bn, bi);
6144 else
6145 bgp_aggregate_decrement(bgp, p, bi, afi,
6146 SAFI_UNICAST);
6147 bgp_attr_unintern(&bi->attr);
6148 bi->attr = new_attr;
6149 bi->uptime = bgp_clock();
6150
6151 /* Process change. */
6152 bgp_aggregate_increment(bgp, p, bi, afi,
6153 SAFI_UNICAST);
6154 bgp_process(bgp, bn, afi, SAFI_UNICAST);
6155 bgp_unlock_node(bn);
6156 aspath_unintern(&attr.aspath);
6157 return;
6158 }
6159 }
6160
6161 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
6162 bgp->peer_self, new_attr, bn);
6163 SET_FLAG(new->flags, BGP_INFO_VALID);
6164
6165 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
6166 bgp_info_add(bn, new);
6167 bgp_unlock_node(bn);
6168 bgp_process(bgp, bn, afi, SAFI_UNICAST);
6169 }
6170
6171 /* Unintern original. */
6172 aspath_unintern(&attr.aspath);
6173 }
6174
6175 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, u_char type,
6176 u_short instance)
6177 {
6178 afi_t afi;
6179 struct bgp_node *rn;
6180 struct bgp_info *ri;
6181 struct bgp_redist *red;
6182
6183 afi = family2afi(p->family);
6184
6185 red = bgp_redist_lookup(bgp, afi, type, instance);
6186 if (red) {
6187 rn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
6188 SAFI_UNICAST, p, NULL);
6189
6190 for (ri = rn->info; ri; ri = ri->next)
6191 if (ri->peer == bgp->peer_self && ri->type == type)
6192 break;
6193
6194 if (ri) {
6195 bgp_aggregate_decrement(bgp, p, ri, afi, SAFI_UNICAST);
6196 bgp_info_delete(rn, ri);
6197 bgp_process(bgp, rn, afi, SAFI_UNICAST);
6198 }
6199 bgp_unlock_node(rn);
6200 }
6201 }
6202
6203 /* Withdraw specified route type's route. */
6204 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
6205 u_short instance)
6206 {
6207 struct bgp_node *rn;
6208 struct bgp_info *ri;
6209 struct bgp_table *table;
6210
6211 table = bgp->rib[afi][SAFI_UNICAST];
6212
6213 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
6214 for (ri = rn->info; ri; ri = ri->next)
6215 if (ri->peer == bgp->peer_self && ri->type == type
6216 && ri->instance == instance)
6217 break;
6218
6219 if (ri) {
6220 bgp_aggregate_decrement(bgp, &rn->p, ri, afi,
6221 SAFI_UNICAST);
6222 bgp_info_delete(rn, ri);
6223 bgp_process(bgp, rn, afi, SAFI_UNICAST);
6224 }
6225 }
6226 }
6227
6228 /* Static function to display route. */
6229 static void route_vty_out_route(struct prefix *p, struct vty *vty)
6230 {
6231 int len;
6232 u_int32_t destination;
6233 char buf[BUFSIZ];
6234
6235 if (p->family == AF_INET) {
6236 len = vty_out(vty, "%s",
6237 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ));
6238 destination = ntohl(p->u.prefix4.s_addr);
6239
6240 if ((IN_CLASSC(destination) && p->prefixlen == 24)
6241 || (IN_CLASSB(destination) && p->prefixlen == 16)
6242 || (IN_CLASSA(destination) && p->prefixlen == 8)
6243 || p->u.prefix4.s_addr == 0) {
6244 /* When mask is natural, mask is not displayed. */
6245 } else
6246 len += vty_out(vty, "/%d", p->prefixlen);
6247 } else if (p->family == AF_ETHERNET) {
6248 prefix2str(p, buf, PREFIX_STRLEN);
6249 len = vty_out(vty, "%s", buf);
6250 } else if (p->family == AF_EVPN) {
6251 #if defined(HAVE_CUMULUS)
6252 len = vty_out(vty, "%s",
6253 bgp_evpn_route2str((struct prefix_evpn *)p, buf,
6254 BUFSIZ));
6255 #else
6256 prefix2str(p, buf, PREFIX_STRLEN);
6257 len = vty_out(vty, "%s", buf);
6258 #endif
6259 } else
6260 len = vty_out(vty, "%s/%d",
6261 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
6262 p->prefixlen);
6263
6264 len = 17 - len;
6265 if (len < 1)
6266 vty_out(vty, "\n%*s", 20, " ");
6267 else
6268 vty_out(vty, "%*s", len, " ");
6269 }
6270
6271 enum bgp_display_type {
6272 normal_list,
6273 };
6274
6275 /* Print the short form route status for a bgp_info */
6276 static void route_vty_short_status_out(struct vty *vty, struct bgp_info *binfo,
6277 json_object *json_path)
6278 {
6279 if (json_path) {
6280
6281 /* Route status display. */
6282 if (CHECK_FLAG(binfo->flags, BGP_INFO_REMOVED))
6283 json_object_boolean_true_add(json_path, "removed");
6284
6285 if (CHECK_FLAG(binfo->flags, BGP_INFO_STALE))
6286 json_object_boolean_true_add(json_path, "stale");
6287
6288 if (binfo->extra && binfo->extra->suppress)
6289 json_object_boolean_true_add(json_path, "suppressed");
6290
6291 if (CHECK_FLAG(binfo->flags, BGP_INFO_VALID)
6292 && !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
6293 json_object_boolean_true_add(json_path, "valid");
6294
6295 /* Selected */
6296 if (CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
6297 json_object_boolean_true_add(json_path, "history");
6298
6299 if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED))
6300 json_object_boolean_true_add(json_path, "damped");
6301
6302 if (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED))
6303 json_object_boolean_true_add(json_path, "bestpath");
6304
6305 if (CHECK_FLAG(binfo->flags, BGP_INFO_MULTIPATH))
6306 json_object_boolean_true_add(json_path, "multipath");
6307
6308 /* Internal route. */
6309 if ((binfo->peer->as)
6310 && (binfo->peer->as == binfo->peer->local_as))
6311 json_object_string_add(json_path, "pathFrom",
6312 "internal");
6313 else
6314 json_object_string_add(json_path, "pathFrom",
6315 "external");
6316
6317 return;
6318 }
6319
6320 /* Route status display. */
6321 if (CHECK_FLAG(binfo->flags, BGP_INFO_REMOVED))
6322 vty_out(vty, "R");
6323 else if (CHECK_FLAG(binfo->flags, BGP_INFO_STALE))
6324 vty_out(vty, "S");
6325 else if (binfo->extra && binfo->extra->suppress)
6326 vty_out(vty, "s");
6327 else if (CHECK_FLAG(binfo->flags, BGP_INFO_VALID)
6328 && !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
6329 vty_out(vty, "*");
6330 else
6331 vty_out(vty, " ");
6332
6333 /* Selected */
6334 if (CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
6335 vty_out(vty, "h");
6336 else if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED))
6337 vty_out(vty, "d");
6338 else if (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED))
6339 vty_out(vty, ">");
6340 else if (CHECK_FLAG(binfo->flags, BGP_INFO_MULTIPATH))
6341 vty_out(vty, "=");
6342 else
6343 vty_out(vty, " ");
6344
6345 /* Internal route. */
6346 if (binfo->peer && (binfo->peer->as)
6347 && (binfo->peer->as == binfo->peer->local_as))
6348 vty_out(vty, "i");
6349 else
6350 vty_out(vty, " ");
6351 }
6352
6353 /* called from terminal list command */
6354 void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
6355 int display, safi_t safi, json_object *json_paths)
6356 {
6357 struct attr *attr;
6358 json_object *json_path = NULL;
6359 json_object *json_nexthops = NULL;
6360 json_object *json_nexthop_global = NULL;
6361 json_object *json_nexthop_ll = NULL;
6362
6363 if (json_paths)
6364 json_path = json_object_new_object();
6365
6366 /* short status lead text */
6367 route_vty_short_status_out(vty, binfo, json_path);
6368
6369 if (!json_paths) {
6370 /* print prefix and mask */
6371 if (!display)
6372 route_vty_out_route(p, vty);
6373 else
6374 vty_out(vty, "%*s", 17, " ");
6375 }
6376
6377 /* Print attribute */
6378 attr = binfo->attr;
6379 if (attr) {
6380 /*
6381 * For ENCAP and EVPN routes, nexthop address family is not
6382 * neccessarily the same as the prefix address family.
6383 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6384 * EVPN routes are also exchanged with a MP nexthop. Currently,
6385 * this
6386 * is only IPv4, the value will be present in either
6387 * attr->nexthop or
6388 * attr->mp_nexthop_global_in
6389 */
6390 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
6391 char buf[BUFSIZ];
6392 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
6393
6394 switch (af) {
6395 case AF_INET:
6396 vty_out(vty, "%s",
6397 inet_ntop(af,
6398 &attr->mp_nexthop_global_in,
6399 buf, BUFSIZ));
6400 break;
6401 case AF_INET6:
6402 vty_out(vty, "%s",
6403 inet_ntop(af, &attr->mp_nexthop_global,
6404 buf, BUFSIZ));
6405 break;
6406 default:
6407 vty_out(vty, "?");
6408 break;
6409 }
6410 } else if (safi == SAFI_EVPN) {
6411 if (json_paths) {
6412 json_nexthop_global = json_object_new_object();
6413
6414 json_object_string_add(
6415 json_nexthop_global, "ip",
6416 inet_ntoa(attr->nexthop));
6417 json_object_string_add(json_nexthop_global,
6418 "afi", "ipv4");
6419 json_object_boolean_true_add(
6420 json_nexthop_global, "used");
6421 } else
6422 vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
6423 }
6424 /* IPv4 Next Hop */
6425 else if (p->family == AF_INET
6426 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
6427 if (json_paths) {
6428 json_nexthop_global = json_object_new_object();
6429
6430 if ((safi == SAFI_MPLS_VPN)
6431 || (safi == SAFI_EVPN))
6432 json_object_string_add(
6433 json_nexthop_global, "ip",
6434 inet_ntoa(
6435 attr->mp_nexthop_global_in));
6436 else
6437 json_object_string_add(
6438 json_nexthop_global, "ip",
6439 inet_ntoa(attr->nexthop));
6440
6441 json_object_string_add(json_nexthop_global,
6442 "afi", "ipv4");
6443 json_object_boolean_true_add(
6444 json_nexthop_global, "used");
6445 } else {
6446 if ((safi == SAFI_MPLS_VPN)
6447 || (safi == SAFI_EVPN))
6448 vty_out(vty, "%-16s",
6449 inet_ntoa(
6450 attr->mp_nexthop_global_in));
6451 else
6452 vty_out(vty, "%-16s",
6453 inet_ntoa(attr->nexthop));
6454 }
6455 }
6456
6457 /* IPv6 Next Hop */
6458 else if (p->family == AF_INET6
6459 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
6460 int len;
6461 char buf[BUFSIZ];
6462
6463 if (json_paths) {
6464 json_nexthop_global = json_object_new_object();
6465 json_object_string_add(
6466 json_nexthop_global, "ip",
6467 inet_ntop(AF_INET6,
6468 &attr->mp_nexthop_global, buf,
6469 BUFSIZ));
6470 json_object_string_add(json_nexthop_global,
6471 "afi", "ipv6");
6472 json_object_string_add(json_nexthop_global,
6473 "scope", "global");
6474
6475 /* We display both LL & GL if both have been
6476 * received */
6477 if ((attr->mp_nexthop_len == 32)
6478 || (binfo->peer->conf_if)) {
6479 json_nexthop_ll =
6480 json_object_new_object();
6481 json_object_string_add(
6482 json_nexthop_ll, "ip",
6483 inet_ntop(
6484 AF_INET6,
6485 &attr->mp_nexthop_local,
6486 buf, BUFSIZ));
6487 json_object_string_add(json_nexthop_ll,
6488 "afi", "ipv6");
6489 json_object_string_add(json_nexthop_ll,
6490 "scope",
6491 "link-local");
6492
6493 if ((IPV6_ADDR_CMP(
6494 &attr->mp_nexthop_global,
6495 &attr->mp_nexthop_local)
6496 != 0)
6497 && !attr->mp_nexthop_prefer_global)
6498 json_object_boolean_true_add(
6499 json_nexthop_ll,
6500 "used");
6501 else
6502 json_object_boolean_true_add(
6503 json_nexthop_global,
6504 "used");
6505 } else
6506 json_object_boolean_true_add(
6507 json_nexthop_global, "used");
6508 } else {
6509 /* Display LL if LL/Global both in table unless
6510 * prefer-global is set */
6511 if (((attr->mp_nexthop_len == 32)
6512 && !attr->mp_nexthop_prefer_global)
6513 || (binfo->peer->conf_if)) {
6514 if (binfo->peer->conf_if) {
6515 len = vty_out(
6516 vty, "%s",
6517 binfo->peer->conf_if);
6518 len = 16 - len; /* len of IPv6
6519 addr + max
6520 len of def
6521 ifname */
6522
6523 if (len < 1)
6524 vty_out(vty, "\n%*s",
6525 36, " ");
6526 else
6527 vty_out(vty, "%*s", len,
6528 " ");
6529 } else {
6530 len = vty_out(
6531 vty, "%s",
6532 inet_ntop(
6533 AF_INET6,
6534 &attr->mp_nexthop_local,
6535 buf, BUFSIZ));
6536 len = 16 - len;
6537
6538 if (len < 1)
6539 vty_out(vty, "\n%*s",
6540 36, " ");
6541 else
6542 vty_out(vty, "%*s", len,
6543 " ");
6544 }
6545 } else {
6546 len = vty_out(
6547 vty, "%s",
6548 inet_ntop(
6549 AF_INET6,
6550 &attr->mp_nexthop_global,
6551 buf, BUFSIZ));
6552 len = 16 - len;
6553
6554 if (len < 1)
6555 vty_out(vty, "\n%*s", 36, " ");
6556 else
6557 vty_out(vty, "%*s", len, " ");
6558 }
6559 }
6560 }
6561
6562 /* MED/Metric */
6563 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
6564 if (json_paths)
6565 json_object_int_add(json_path, "med",
6566 attr->med);
6567 else
6568 vty_out(vty, "%10u", attr->med);
6569 else if (!json_paths)
6570 vty_out(vty, " ");
6571
6572 /* Local Pref */
6573 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
6574 if (json_paths)
6575 json_object_int_add(json_path, "localpref",
6576 attr->local_pref);
6577 else
6578 vty_out(vty, "%7u", attr->local_pref);
6579 else if (!json_paths)
6580 vty_out(vty, " ");
6581
6582 if (json_paths)
6583 json_object_int_add(json_path, "weight", attr->weight);
6584 else
6585 vty_out(vty, "%7u ", attr->weight);
6586
6587 if (json_paths) {
6588 char buf[BUFSIZ];
6589 json_object_string_add(json_path, "peerId",
6590 sockunion2str(&binfo->peer->su,
6591 buf,
6592 SU_ADDRSTRLEN));
6593 }
6594
6595 /* Print aspath */
6596 if (attr->aspath) {
6597 if (json_paths)
6598 json_object_string_add(json_path, "aspath",
6599 attr->aspath->str);
6600 else
6601 aspath_print_vty(vty, "%s", attr->aspath, " ");
6602 }
6603
6604 /* Print origin */
6605 if (json_paths)
6606 json_object_string_add(
6607 json_path, "origin",
6608 bgp_origin_long_str[attr->origin]);
6609 else
6610 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
6611 } else {
6612 if (json_paths)
6613 json_object_string_add(json_path, "alert",
6614 "No attributes");
6615 else
6616 vty_out(vty, "No attributes to print\n");
6617 }
6618
6619 if (json_paths) {
6620 if (json_nexthop_global || json_nexthop_ll) {
6621 json_nexthops = json_object_new_array();
6622
6623 if (json_nexthop_global)
6624 json_object_array_add(json_nexthops,
6625 json_nexthop_global);
6626
6627 if (json_nexthop_ll)
6628 json_object_array_add(json_nexthops,
6629 json_nexthop_ll);
6630
6631 json_object_object_add(json_path, "nexthops",
6632 json_nexthops);
6633 }
6634
6635 json_object_array_add(json_paths, json_path);
6636 } else {
6637 vty_out(vty, "\n");
6638 #if ENABLE_BGP_VNC
6639 /* prints an additional line, indented, with VNC info, if
6640 * present */
6641 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
6642 rfapi_vty_out_vncinfo(vty, p, binfo, safi);
6643 #endif
6644 }
6645 }
6646
6647 /* called from terminal list command */
6648 void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
6649 safi_t safi, u_char use_json, json_object *json_ar)
6650 {
6651 json_object *json_status = NULL;
6652 json_object *json_net = NULL;
6653 char buff[BUFSIZ];
6654 /* Route status display. */
6655 if (use_json) {
6656 json_status = json_object_new_object();
6657 json_net = json_object_new_object();
6658 } else {
6659 vty_out(vty, "*");
6660 vty_out(vty, ">");
6661 vty_out(vty, " ");
6662 }
6663
6664 /* print prefix and mask */
6665 if (use_json)
6666 json_object_string_add(
6667 json_net, "addrPrefix",
6668 inet_ntop(p->family, &p->u.prefix, buff, BUFSIZ));
6669 else
6670 route_vty_out_route(p, vty);
6671
6672 /* Print attribute */
6673 if (attr) {
6674 if (use_json) {
6675 if (p->family == AF_INET
6676 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
6677 || safi == SAFI_EVPN
6678 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
6679 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
6680 || safi == SAFI_EVPN)
6681 json_object_string_add(
6682 json_net, "nextHop",
6683 inet_ntoa(
6684 attr->mp_nexthop_global_in));
6685 else
6686 json_object_string_add(
6687 json_net, "nextHop",
6688 inet_ntoa(attr->nexthop));
6689 } else if (p->family == AF_INET6
6690 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
6691 char buf[BUFSIZ];
6692
6693 json_object_string_add(
6694 json_net, "netHopGloabal",
6695 inet_ntop(AF_INET6,
6696 &attr->mp_nexthop_global, buf,
6697 BUFSIZ));
6698 }
6699
6700 if (attr->flag
6701 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
6702 json_object_int_add(json_net, "metric",
6703 attr->med);
6704
6705 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
6706 json_object_int_add(json_net, "localPref",
6707 attr->local_pref);
6708
6709 json_object_int_add(json_net, "weight", attr->weight);
6710
6711 /* Print aspath */
6712 if (attr->aspath)
6713 json_object_string_add(json_net, "asPath",
6714 attr->aspath->str);
6715
6716 /* Print origin */
6717 json_object_string_add(json_net, "bgpOriginCode",
6718 bgp_origin_str[attr->origin]);
6719 } else {
6720 if (p->family == AF_INET
6721 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
6722 || safi == SAFI_EVPN
6723 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
6724 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
6725 || safi == SAFI_EVPN)
6726 vty_out(vty, "%-16s",
6727 inet_ntoa(
6728 attr->mp_nexthop_global_in));
6729 else
6730 vty_out(vty, "%-16s",
6731 inet_ntoa(attr->nexthop));
6732 } else if (p->family == AF_INET6
6733 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
6734 int len;
6735 char buf[BUFSIZ];
6736
6737 len = vty_out(
6738 vty, "%s",
6739 inet_ntop(AF_INET6,
6740 &attr->mp_nexthop_global, buf,
6741 BUFSIZ));
6742 len = 16 - len;
6743 if (len < 1)
6744 vty_out(vty, "\n%*s", 36, " ");
6745 else
6746 vty_out(vty, "%*s", len, " ");
6747 }
6748 if (attr->flag
6749 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
6750 vty_out(vty, "%10u", attr->med);
6751 else
6752 vty_out(vty, " ");
6753
6754 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
6755 vty_out(vty, "%7u", attr->local_pref);
6756 else
6757 vty_out(vty, " ");
6758
6759 vty_out(vty, "%7u ", attr->weight);
6760
6761 /* Print aspath */
6762 if (attr->aspath)
6763 aspath_print_vty(vty, "%s", attr->aspath, " ");
6764
6765 /* Print origin */
6766 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
6767 }
6768 }
6769 if (use_json) {
6770 json_object_boolean_true_add(json_status, "*");
6771 json_object_boolean_true_add(json_status, ">");
6772 json_object_object_add(json_net, "appliedStatusSymbols",
6773 json_status);
6774 char buf_cut[BUFSIZ];
6775 json_object_object_add(
6776 json_ar,
6777 inet_ntop(p->family, &p->u.prefix, buf_cut, BUFSIZ),
6778 json_net);
6779 } else
6780 vty_out(vty, "\n");
6781 }
6782
6783 void route_vty_out_tag(struct vty *vty, struct prefix *p,
6784 struct bgp_info *binfo, int display, safi_t safi,
6785 json_object *json)
6786 {
6787 json_object *json_out = NULL;
6788 struct attr *attr;
6789 mpls_label_t label = MPLS_INVALID_LABEL;
6790
6791 if (!binfo->extra)
6792 return;
6793
6794 if (json)
6795 json_out = json_object_new_object();
6796
6797 /* short status lead text */
6798 route_vty_short_status_out(vty, binfo, json_out);
6799
6800 /* print prefix and mask */
6801 if (json == NULL) {
6802 if (!display)
6803 route_vty_out_route(p, vty);
6804 else
6805 vty_out(vty, "%*s", 17, " ");
6806 }
6807
6808 /* Print attribute */
6809 attr = binfo->attr;
6810 if (attr) {
6811 if (((p->family == AF_INET)
6812 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
6813 || (safi == SAFI_EVPN
6814 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6815 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
6816 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
6817 || safi == SAFI_EVPN) {
6818 if (json)
6819 json_object_string_add(
6820 json_out, "mpNexthopGlobalIn",
6821 inet_ntoa(
6822 attr->mp_nexthop_global_in));
6823 else
6824 vty_out(vty, "%-16s",
6825 inet_ntoa(
6826 attr->mp_nexthop_global_in));
6827 } else {
6828 if (json)
6829 json_object_string_add(
6830 json_out, "nexthop",
6831 inet_ntoa(attr->nexthop));
6832 else
6833 vty_out(vty, "%-16s",
6834 inet_ntoa(attr->nexthop));
6835 }
6836 } else if (((p->family == AF_INET6)
6837 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
6838 || (safi == SAFI_EVPN
6839 && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6840 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
6841 char buf_a[BUFSIZ];
6842 char buf_b[BUFSIZ];
6843 char buf_c[BUFSIZ];
6844 if (attr->mp_nexthop_len
6845 == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
6846 if (json)
6847 json_object_string_add(
6848 json_out, "mpNexthopGlobalIn",
6849 inet_ntop(
6850 AF_INET6,
6851 &attr->mp_nexthop_global,
6852 buf_a, BUFSIZ));
6853 else
6854 vty_out(vty, "%s",
6855 inet_ntop(
6856 AF_INET6,
6857 &attr->mp_nexthop_global,
6858 buf_a, BUFSIZ));
6859 } else if (attr->mp_nexthop_len
6860 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
6861 if (json) {
6862 inet_ntop(AF_INET6,
6863 &attr->mp_nexthop_global,
6864 buf_a, BUFSIZ);
6865 inet_ntop(AF_INET6,
6866 &attr->mp_nexthop_local,
6867 buf_b, BUFSIZ);
6868 sprintf(buf_c, "%s(%s)", buf_a, buf_b);
6869 json_object_string_add(
6870 json_out,
6871 "mpNexthopGlobalLocal", buf_c);
6872 } else
6873 vty_out(vty, "%s(%s)",
6874 inet_ntop(
6875 AF_INET6,
6876 &attr->mp_nexthop_global,
6877 buf_a, BUFSIZ),
6878 inet_ntop(
6879 AF_INET6,
6880 &attr->mp_nexthop_local,
6881 buf_b, BUFSIZ));
6882 }
6883 }
6884 }
6885
6886 label = decode_label(&binfo->extra->label);
6887
6888 if (bgp_is_valid_label(&label)) {
6889 if (json) {
6890 json_object_int_add(json_out, "notag", label);
6891 json_object_array_add(json, json_out);
6892 } else {
6893 vty_out(vty, "notag/%d", label);
6894 vty_out(vty, "\n");
6895 }
6896 }
6897 }
6898
6899 void route_vty_out_overlay(struct vty *vty, struct prefix *p,
6900 struct bgp_info *binfo, int display,
6901 json_object *json_paths)
6902 {
6903 struct attr *attr;
6904 char buf[BUFSIZ];
6905 json_object *json_path = NULL;
6906
6907 if (json_paths)
6908 json_path = json_object_new_object();
6909
6910 if (!binfo->extra)
6911 return;
6912
6913 /* short status lead text */
6914 route_vty_short_status_out(vty, binfo, json_path);
6915
6916 /* print prefix and mask */
6917 if (!display)
6918 route_vty_out_route(p, vty);
6919 else
6920 vty_out(vty, "%*s", 17, " ");
6921
6922 /* Print attribute */
6923 attr = binfo->attr;
6924 if (attr) {
6925 char buf1[BUFSIZ];
6926 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
6927
6928 switch (af) {
6929 case AF_INET:
6930 vty_out(vty, "%-16s",
6931 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
6932 BUFSIZ));
6933 break;
6934 case AF_INET6:
6935 vty_out(vty, "%s(%s)",
6936 inet_ntop(af, &attr->mp_nexthop_global, buf,
6937 BUFSIZ),
6938 inet_ntop(af, &attr->mp_nexthop_local, buf1,
6939 BUFSIZ));
6940 break;
6941 default:
6942 vty_out(vty, "?");
6943 }
6944 }
6945
6946 struct eth_segment_id *id = &(attr->evpn_overlay.eth_s_id);
6947 char *str = esi2str(id);
6948 vty_out(vty, "%s", str);
6949 XFREE(MTYPE_TMP, str);
6950 if (IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p)) {
6951 vty_out(vty, "/%s", inet_ntoa(attr->evpn_overlay.gw_ip.ipv4));
6952 } else if (IS_EVPN_PREFIX_IPADDR_V6((struct prefix_evpn *)p)) {
6953 vty_out(vty, "/%s",
6954 inet_ntop(AF_INET6, &(attr->evpn_overlay.gw_ip.ipv6),
6955 buf, BUFSIZ));
6956 }
6957 if (attr->ecommunity) {
6958 char *mac = NULL;
6959 struct ecommunity_val *routermac = ecommunity_lookup(
6960 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
6961 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
6962 if (routermac)
6963 mac = ecom_mac2str((char *)routermac->val);
6964 if (mac) {
6965 vty_out(vty, "/%s", (char *)mac);
6966 XFREE(MTYPE_TMP, mac);
6967 }
6968 }
6969 vty_out(vty, "\n");
6970 }
6971
6972 /* dampening route */
6973 static void damp_route_vty_out(struct vty *vty, struct prefix *p,
6974 struct bgp_info *binfo, int display, safi_t safi,
6975 u_char use_json, json_object *json)
6976 {
6977 struct attr *attr;
6978 int len;
6979 char timebuf[BGP_UPTIME_LEN];
6980
6981 /* short status lead text */
6982 route_vty_short_status_out(vty, binfo, json);
6983
6984 /* print prefix and mask */
6985 if (!use_json) {
6986 if (!display)
6987 route_vty_out_route(p, vty);
6988 else
6989 vty_out(vty, "%*s", 17, " ");
6990 }
6991
6992 len = vty_out(vty, "%s", binfo->peer->host);
6993 len = 17 - len;
6994 if (len < 1) {
6995 if (!use_json)
6996 vty_out(vty, "\n%*s", 34, " ");
6997 } else {
6998 if (use_json)
6999 json_object_int_add(json, "peerHost", len);
7000 else
7001 vty_out(vty, "%*s", len, " ");
7002 }
7003
7004 if (use_json)
7005 bgp_damp_reuse_time_vty(vty, binfo, timebuf, BGP_UPTIME_LEN,
7006 use_json, json);
7007 else
7008 vty_out(vty, "%s ", bgp_damp_reuse_time_vty(vty, binfo, timebuf,
7009 BGP_UPTIME_LEN,
7010 use_json, json));
7011
7012 /* Print attribute */
7013 attr = binfo->attr;
7014 if (attr) {
7015 /* Print aspath */
7016 if (attr->aspath) {
7017 if (use_json)
7018 json_object_string_add(json, "asPath",
7019 attr->aspath->str);
7020 else
7021 aspath_print_vty(vty, "%s", attr->aspath, " ");
7022 }
7023
7024 /* Print origin */
7025 if (use_json)
7026 json_object_string_add(json, "origin",
7027 bgp_origin_str[attr->origin]);
7028 else
7029 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7030 }
7031 if (!use_json)
7032 vty_out(vty, "\n");
7033 }
7034
7035 /* flap route */
7036 static void flap_route_vty_out(struct vty *vty, struct prefix *p,
7037 struct bgp_info *binfo, int display, safi_t safi,
7038 u_char use_json, json_object *json)
7039 {
7040 struct attr *attr;
7041 struct bgp_damp_info *bdi;
7042 char timebuf[BGP_UPTIME_LEN];
7043 int len;
7044
7045 if (!binfo->extra)
7046 return;
7047
7048 bdi = binfo->extra->damp_info;
7049
7050 /* short status lead text */
7051 route_vty_short_status_out(vty, binfo, json);
7052
7053 /* print prefix and mask */
7054 if (!use_json) {
7055 if (!display)
7056 route_vty_out_route(p, vty);
7057 else
7058 vty_out(vty, "%*s", 17, " ");
7059 }
7060
7061 len = vty_out(vty, "%s", binfo->peer->host);
7062 len = 16 - len;
7063 if (len < 1) {
7064 if (!use_json)
7065 vty_out(vty, "\n%*s", 33, " ");
7066 } else {
7067 if (use_json)
7068 json_object_int_add(json, "peerHost", len);
7069 else
7070 vty_out(vty, "%*s", len, " ");
7071 }
7072
7073 len = vty_out(vty, "%d", bdi->flap);
7074 len = 5 - len;
7075 if (len < 1) {
7076 if (!use_json)
7077 vty_out(vty, " ");
7078 } else {
7079 if (use_json)
7080 json_object_int_add(json, "bdiFlap", len);
7081 else
7082 vty_out(vty, "%*s", len, " ");
7083 }
7084
7085 if (use_json)
7086 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
7087 json);
7088 else
7089 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
7090 BGP_UPTIME_LEN, 0, NULL));
7091
7092 if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)
7093 && !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) {
7094 if (use_json)
7095 bgp_damp_reuse_time_vty(vty, binfo, timebuf,
7096 BGP_UPTIME_LEN, use_json, json);
7097 else
7098 vty_out(vty, "%s ",
7099 bgp_damp_reuse_time_vty(vty, binfo, timebuf,
7100 BGP_UPTIME_LEN,
7101 use_json, json));
7102 } else {
7103 if (!use_json)
7104 vty_out(vty, "%*s ", 8, " ");
7105 }
7106
7107 /* Print attribute */
7108 attr = binfo->attr;
7109 if (attr) {
7110 /* Print aspath */
7111 if (attr->aspath) {
7112 if (use_json)
7113 json_object_string_add(json, "asPath",
7114 attr->aspath->str);
7115 else
7116 aspath_print_vty(vty, "%s", attr->aspath, " ");
7117 }
7118
7119 /* Print origin */
7120 if (use_json)
7121 json_object_string_add(json, "origin",
7122 bgp_origin_str[attr->origin]);
7123 else
7124 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7125 }
7126 if (!use_json)
7127 vty_out(vty, "\n");
7128 }
7129
7130 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
7131 int *first, const char *header,
7132 json_object *json_adv_to)
7133 {
7134 char buf1[INET6_ADDRSTRLEN];
7135 json_object *json_peer = NULL;
7136
7137 if (json_adv_to) {
7138 /* 'advertised-to' is a dictionary of peers we have advertised
7139 * this
7140 * prefix too. The key is the peer's IP or swpX, the value is
7141 * the
7142 * hostname if we know it and "" if not.
7143 */
7144 json_peer = json_object_new_object();
7145
7146 if (peer->hostname)
7147 json_object_string_add(json_peer, "hostname",
7148 peer->hostname);
7149
7150 if (peer->conf_if)
7151 json_object_object_add(json_adv_to, peer->conf_if,
7152 json_peer);
7153 else
7154 json_object_object_add(
7155 json_adv_to,
7156 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
7157 json_peer);
7158 } else {
7159 if (*first) {
7160 vty_out(vty, "%s", header);
7161 *first = 0;
7162 }
7163
7164 if (peer->hostname
7165 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
7166 if (peer->conf_if)
7167 vty_out(vty, " %s(%s)", peer->hostname,
7168 peer->conf_if);
7169 else
7170 vty_out(vty, " %s(%s)", peer->hostname,
7171 sockunion2str(&peer->su, buf1,
7172 SU_ADDRSTRLEN));
7173 } else {
7174 if (peer->conf_if)
7175 vty_out(vty, " %s", peer->conf_if);
7176 else
7177 vty_out(vty, " %s",
7178 sockunion2str(&peer->su, buf1,
7179 SU_ADDRSTRLEN));
7180 }
7181 }
7182 }
7183
7184 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
7185 struct bgp_info *binfo, afi_t afi, safi_t safi,
7186 json_object *json_paths)
7187 {
7188 char buf[INET6_ADDRSTRLEN];
7189 char buf1[BUFSIZ];
7190 #if defined(HAVE_CUMULUS)
7191 char buf2[EVPN_ROUTE_STRLEN];
7192 #endif
7193 struct attr *attr;
7194 int sockunion_vty_out(struct vty *, union sockunion *);
7195 time_t tbuf;
7196 json_object *json_bestpath = NULL;
7197 json_object *json_cluster_list = NULL;
7198 json_object *json_cluster_list_list = NULL;
7199 json_object *json_ext_community = NULL;
7200 json_object *json_last_update = NULL;
7201 json_object *json_nexthop_global = NULL;
7202 json_object *json_nexthop_ll = NULL;
7203 json_object *json_nexthops = NULL;
7204 json_object *json_path = NULL;
7205 json_object *json_peer = NULL;
7206 json_object *json_string = NULL;
7207 json_object *json_adv_to = NULL;
7208 int first = 0;
7209 struct listnode *node, *nnode;
7210 struct peer *peer;
7211 int addpath_capable;
7212 int has_adj;
7213 unsigned int first_as;
7214
7215 if (json_paths) {
7216 json_path = json_object_new_object();
7217 json_peer = json_object_new_object();
7218 json_nexthop_global = json_object_new_object();
7219 }
7220
7221 #if defined(HAVE_CUMULUS)
7222 if (!json_paths && safi == SAFI_EVPN) {
7223 char tag_buf[20];
7224
7225 bgp_evpn_route2str((struct prefix_evpn *)p, buf2, sizeof(buf2));
7226 vty_out(vty, " Route %s", buf2);
7227 tag_buf[0] = '\0';
7228 if (binfo->extra) {
7229 bgp_evpn_label2str(&binfo->extra->label, tag_buf,
7230 sizeof(tag_buf));
7231 vty_out(vty, " VNI %s", tag_buf);
7232 }
7233 vty_out(vty, "\n");
7234 if (binfo->extra && binfo->extra->parent) {
7235 struct bgp_info *parent_ri;
7236 struct bgp_node *rn, *prn;
7237
7238 parent_ri = (struct bgp_info *)binfo->extra->parent;
7239 rn = parent_ri->net;
7240 if (rn && rn->prn) {
7241 prn = rn->prn;
7242 vty_out(vty, " Imported from %s:%s\n",
7243 prefix_rd2str(
7244 (struct prefix_rd *)&prn->p,
7245 buf1, RD_ADDRSTRLEN),
7246 buf2);
7247 }
7248 }
7249 }
7250 #endif
7251
7252 attr = binfo->attr;
7253
7254 if (attr) {
7255 /* Line1 display AS-path, Aggregator */
7256 if (attr->aspath) {
7257 if (json_paths) {
7258 json_object_lock(attr->aspath->json);
7259 json_object_object_add(json_path, "aspath",
7260 attr->aspath->json);
7261 } else {
7262 if (attr->aspath->segments)
7263 aspath_print_vty(vty, " %s",
7264 attr->aspath, "");
7265 else
7266 vty_out(vty, " Local");
7267 }
7268 }
7269
7270 if (CHECK_FLAG(binfo->flags, BGP_INFO_REMOVED)) {
7271 if (json_paths)
7272 json_object_boolean_true_add(json_path,
7273 "removed");
7274 else
7275 vty_out(vty, ", (removed)");
7276 }
7277
7278 if (CHECK_FLAG(binfo->flags, BGP_INFO_STALE)) {
7279 if (json_paths)
7280 json_object_boolean_true_add(json_path,
7281 "stale");
7282 else
7283 vty_out(vty, ", (stale)");
7284 }
7285
7286 if (CHECK_FLAG(attr->flag,
7287 ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
7288 if (json_paths) {
7289 json_object_int_add(json_path, "aggregatorAs",
7290 attr->aggregator_as);
7291 json_object_string_add(
7292 json_path, "aggregatorId",
7293 inet_ntoa(attr->aggregator_addr));
7294 } else {
7295 vty_out(vty, ", (aggregated by %u %s)",
7296 attr->aggregator_as,
7297 inet_ntoa(attr->aggregator_addr));
7298 }
7299 }
7300
7301 if (CHECK_FLAG(binfo->peer->af_flags[afi][safi],
7302 PEER_FLAG_REFLECTOR_CLIENT)) {
7303 if (json_paths)
7304 json_object_boolean_true_add(
7305 json_path, "rxedFromRrClient");
7306 else
7307 vty_out(vty, ", (Received from a RR-client)");
7308 }
7309
7310 if (CHECK_FLAG(binfo->peer->af_flags[afi][safi],
7311 PEER_FLAG_RSERVER_CLIENT)) {
7312 if (json_paths)
7313 json_object_boolean_true_add(
7314 json_path, "rxedFromRsClient");
7315 else
7316 vty_out(vty, ", (Received from a RS-client)");
7317 }
7318
7319 if (CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) {
7320 if (json_paths)
7321 json_object_boolean_true_add(
7322 json_path, "dampeningHistoryEntry");
7323 else
7324 vty_out(vty, ", (history entry)");
7325 } else if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)) {
7326 if (json_paths)
7327 json_object_boolean_true_add(
7328 json_path, "dampeningSuppressed");
7329 else
7330 vty_out(vty, ", (suppressed due to dampening)");
7331 }
7332
7333 if (!json_paths)
7334 vty_out(vty, "\n");
7335
7336 /* Line2 display Next-hop, Neighbor, Router-id */
7337 /* Display the nexthop */
7338 if ((p->family == AF_INET || p->family == AF_ETHERNET ||
7339 p->family == AF_EVPN)
7340 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7341 || safi == SAFI_EVPN
7342 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7343 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7344 || safi == SAFI_EVPN) {
7345 if (json_paths)
7346 json_object_string_add(
7347 json_nexthop_global, "ip",
7348 inet_ntoa(
7349 attr->mp_nexthop_global_in));
7350 else
7351 vty_out(vty, " %s",
7352 inet_ntoa(
7353 attr->mp_nexthop_global_in));
7354 } else {
7355 if (json_paths)
7356 json_object_string_add(
7357 json_nexthop_global, "ip",
7358 inet_ntoa(attr->nexthop));
7359 else
7360 vty_out(vty, " %s",
7361 inet_ntoa(attr->nexthop));
7362 }
7363
7364 if (json_paths)
7365 json_object_string_add(json_nexthop_global,
7366 "afi", "ipv4");
7367 } else {
7368 if (json_paths) {
7369 json_object_string_add(
7370 json_nexthop_global, "ip",
7371 inet_ntop(AF_INET6,
7372 &attr->mp_nexthop_global, buf,
7373 INET6_ADDRSTRLEN));
7374 json_object_string_add(json_nexthop_global,
7375 "afi", "ipv6");
7376 json_object_string_add(json_nexthop_global,
7377 "scope", "global");
7378 } else {
7379 vty_out(vty, " %s",
7380 inet_ntop(AF_INET6,
7381 &attr->mp_nexthop_global, buf,
7382 INET6_ADDRSTRLEN));
7383 }
7384 }
7385
7386 /* Display the IGP cost or 'inaccessible' */
7387 if (!CHECK_FLAG(binfo->flags, BGP_INFO_VALID)) {
7388 if (json_paths)
7389 json_object_boolean_false_add(
7390 json_nexthop_global, "accessible");
7391 else
7392 vty_out(vty, " (inaccessible)");
7393 } else {
7394 if (binfo->extra && binfo->extra->igpmetric) {
7395 if (json_paths)
7396 json_object_int_add(
7397 json_nexthop_global, "metric",
7398 binfo->extra->igpmetric);
7399 else
7400 vty_out(vty, " (metric %u)",
7401 binfo->extra->igpmetric);
7402 }
7403
7404 /* IGP cost is 0, display this only for json */
7405 else {
7406 if (json_paths)
7407 json_object_int_add(json_nexthop_global,
7408 "metric", 0);
7409 }
7410
7411 if (json_paths)
7412 json_object_boolean_true_add(
7413 json_nexthop_global, "accessible");
7414 }
7415
7416 /* Display peer "from" output */
7417 /* This path was originated locally */
7418 if (binfo->peer == bgp->peer_self) {
7419
7420 if (safi == SAFI_EVPN
7421 || (p->family == AF_INET
7422 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7423 if (json_paths)
7424 json_object_string_add(
7425 json_peer, "peerId", "0.0.0.0");
7426 else
7427 vty_out(vty, " from 0.0.0.0 ");
7428 } else {
7429 if (json_paths)
7430 json_object_string_add(json_peer,
7431 "peerId", "::");
7432 else
7433 vty_out(vty, " from :: ");
7434 }
7435
7436 if (json_paths)
7437 json_object_string_add(
7438 json_peer, "routerId",
7439 inet_ntoa(bgp->router_id));
7440 else
7441 vty_out(vty, "(%s)", inet_ntoa(bgp->router_id));
7442 }
7443
7444 /* We RXed this path from one of our peers */
7445 else {
7446
7447 if (json_paths) {
7448 json_object_string_add(
7449 json_peer, "peerId",
7450 sockunion2str(&binfo->peer->su, buf,
7451 SU_ADDRSTRLEN));
7452 json_object_string_add(
7453 json_peer, "routerId",
7454 inet_ntop(AF_INET,
7455 &binfo->peer->remote_id, buf1,
7456 BUFSIZ));
7457
7458 if (binfo->peer->hostname)
7459 json_object_string_add(
7460 json_peer, "hostname",
7461 binfo->peer->hostname);
7462
7463 if (binfo->peer->domainname)
7464 json_object_string_add(
7465 json_peer, "domainname",
7466 binfo->peer->domainname);
7467
7468 if (binfo->peer->conf_if)
7469 json_object_string_add(
7470 json_peer, "interface",
7471 binfo->peer->conf_if);
7472 } else {
7473 if (binfo->peer->conf_if) {
7474 if (binfo->peer->hostname
7475 && bgp_flag_check(
7476 binfo->peer->bgp,
7477 BGP_FLAG_SHOW_HOSTNAME))
7478 vty_out(vty, " from %s(%s)",
7479 binfo->peer->hostname,
7480 binfo->peer->conf_if);
7481 else
7482 vty_out(vty, " from %s",
7483 binfo->peer->conf_if);
7484 } else {
7485 if (binfo->peer->hostname
7486 && bgp_flag_check(
7487 binfo->peer->bgp,
7488 BGP_FLAG_SHOW_HOSTNAME))
7489 vty_out(vty, " from %s(%s)",
7490 binfo->peer->hostname,
7491 binfo->peer->host);
7492 else
7493 vty_out(vty, " from %s",
7494 sockunion2str(
7495 &binfo->peer
7496 ->su,
7497 buf,
7498 SU_ADDRSTRLEN));
7499 }
7500
7501 if (attr->flag
7502 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
7503 vty_out(vty, " (%s)",
7504 inet_ntoa(attr->originator_id));
7505 else
7506 vty_out(vty, " (%s)",
7507 inet_ntop(
7508 AF_INET,
7509 &binfo->peer->remote_id,
7510 buf1, BUFSIZ));
7511 }
7512 }
7513
7514 if (!json_paths)
7515 vty_out(vty, "\n");
7516
7517 /* display the link-local nexthop */
7518 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
7519 if (json_paths) {
7520 json_nexthop_ll = json_object_new_object();
7521 json_object_string_add(
7522 json_nexthop_ll, "ip",
7523 inet_ntop(AF_INET6,
7524 &attr->mp_nexthop_local, buf,
7525 INET6_ADDRSTRLEN));
7526 json_object_string_add(json_nexthop_ll, "afi",
7527 "ipv6");
7528 json_object_string_add(json_nexthop_ll, "scope",
7529 "link-local");
7530
7531 json_object_boolean_true_add(json_nexthop_ll,
7532 "accessible");
7533
7534 if (!attr->mp_nexthop_prefer_global)
7535 json_object_boolean_true_add(
7536 json_nexthop_ll, "used");
7537 else
7538 json_object_boolean_true_add(
7539 json_nexthop_global, "used");
7540 } else {
7541 vty_out(vty, " (%s) %s\n",
7542 inet_ntop(AF_INET6,
7543 &attr->mp_nexthop_local, buf,
7544 INET6_ADDRSTRLEN),
7545 attr->mp_nexthop_prefer_global
7546 ? "(prefer-global)"
7547 : "(used)");
7548 }
7549 }
7550 /* If we do not have a link-local nexthop then we must flag the
7551 global as "used" */
7552 else {
7553 if (json_paths)
7554 json_object_boolean_true_add(
7555 json_nexthop_global, "used");
7556 }
7557
7558 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
7559 * Int/Ext/Local, Atomic, best */
7560 if (json_paths)
7561 json_object_string_add(
7562 json_path, "origin",
7563 bgp_origin_long_str[attr->origin]);
7564 else
7565 vty_out(vty, " Origin %s",
7566 bgp_origin_long_str[attr->origin]);
7567
7568 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
7569 if (json_paths)
7570 json_object_int_add(json_path, "med",
7571 attr->med);
7572 else
7573 vty_out(vty, ", metric %u", attr->med);
7574 }
7575
7576 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
7577 if (json_paths)
7578 json_object_int_add(json_path, "localpref",
7579 attr->local_pref);
7580 else
7581 vty_out(vty, ", localpref %u",
7582 attr->local_pref);
7583 } else {
7584 if (json_paths)
7585 json_object_int_add(json_path, "localpref",
7586 bgp->default_local_pref);
7587 else
7588 vty_out(vty, ", localpref %u",
7589 bgp->default_local_pref);
7590 }
7591
7592 if (attr->weight != 0) {
7593 if (json_paths)
7594 json_object_int_add(json_path, "weight",
7595 attr->weight);
7596 else
7597 vty_out(vty, ", weight %u", attr->weight);
7598 }
7599
7600 if (attr->tag != 0) {
7601 if (json_paths)
7602 json_object_int_add(json_path, "tag",
7603 attr->tag);
7604 else
7605 vty_out(vty, ", tag %" ROUTE_TAG_PRI,
7606 attr->tag);
7607 }
7608
7609 if (!CHECK_FLAG(binfo->flags, BGP_INFO_VALID)) {
7610 if (json_paths)
7611 json_object_boolean_false_add(json_path,
7612 "valid");
7613 else
7614 vty_out(vty, ", invalid");
7615 } else if (!CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) {
7616 if (json_paths)
7617 json_object_boolean_true_add(json_path,
7618 "valid");
7619 else
7620 vty_out(vty, ", valid");
7621 }
7622
7623 if (binfo->peer != bgp->peer_self) {
7624 if (binfo->peer->as == binfo->peer->local_as) {
7625 if (CHECK_FLAG(bgp->config,
7626 BGP_CONFIG_CONFEDERATION)) {
7627 if (json_paths)
7628 json_object_string_add(
7629 json_peer, "type",
7630 "confed-internal");
7631 else
7632 vty_out(vty,
7633 ", confed-internal");
7634 } else {
7635 if (json_paths)
7636 json_object_string_add(
7637 json_peer, "type",
7638 "internal");
7639 else
7640 vty_out(vty, ", internal");
7641 }
7642 } else {
7643 if (bgp_confederation_peers_check(
7644 bgp, binfo->peer->as)) {
7645 if (json_paths)
7646 json_object_string_add(
7647 json_peer, "type",
7648 "confed-external");
7649 else
7650 vty_out(vty,
7651 ", confed-external");
7652 } else {
7653 if (json_paths)
7654 json_object_string_add(
7655 json_peer, "type",
7656 "external");
7657 else
7658 vty_out(vty, ", external");
7659 }
7660 }
7661 } else if (binfo->sub_type == BGP_ROUTE_AGGREGATE) {
7662 if (json_paths) {
7663 json_object_boolean_true_add(json_path,
7664 "aggregated");
7665 json_object_boolean_true_add(json_path,
7666 "local");
7667 } else {
7668 vty_out(vty, ", aggregated, local");
7669 }
7670 } else if (binfo->type != ZEBRA_ROUTE_BGP) {
7671 if (json_paths)
7672 json_object_boolean_true_add(json_path,
7673 "sourced");
7674 else
7675 vty_out(vty, ", sourced");
7676 } else {
7677 if (json_paths) {
7678 json_object_boolean_true_add(json_path,
7679 "sourced");
7680 json_object_boolean_true_add(json_path,
7681 "local");
7682 } else {
7683 vty_out(vty, ", sourced, local");
7684 }
7685 }
7686
7687 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
7688 if (json_paths)
7689 json_object_boolean_true_add(json_path,
7690 "atomicAggregate");
7691 else
7692 vty_out(vty, ", atomic-aggregate");
7693 }
7694
7695 if (CHECK_FLAG(binfo->flags, BGP_INFO_MULTIPATH)
7696 || (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED)
7697 && bgp_info_mpath_count(binfo))) {
7698 if (json_paths)
7699 json_object_boolean_true_add(json_path,
7700 "multipath");
7701 else
7702 vty_out(vty, ", multipath");
7703 }
7704
7705 // Mark the bestpath(s)
7706 if (CHECK_FLAG(binfo->flags, BGP_INFO_DMED_SELECTED)) {
7707 first_as = aspath_get_first_as(attr->aspath);
7708
7709 if (json_paths) {
7710 if (!json_bestpath)
7711 json_bestpath =
7712 json_object_new_object();
7713 json_object_int_add(json_bestpath,
7714 "bestpathFromAs", first_as);
7715 } else {
7716 if (first_as)
7717 vty_out(vty, ", bestpath-from-AS %d",
7718 first_as);
7719 else
7720 vty_out(vty,
7721 ", bestpath-from-AS Local");
7722 }
7723 }
7724
7725 if (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED)) {
7726 if (json_paths) {
7727 if (!json_bestpath)
7728 json_bestpath =
7729 json_object_new_object();
7730 json_object_boolean_true_add(json_bestpath,
7731 "overall");
7732 } else
7733 vty_out(vty, ", best");
7734 }
7735
7736 if (json_bestpath)
7737 json_object_object_add(json_path, "bestpath",
7738 json_bestpath);
7739
7740 if (!json_paths)
7741 vty_out(vty, "\n");
7742
7743 /* Line 4 display Community */
7744 if (attr->community) {
7745 if (json_paths) {
7746 json_object_lock(attr->community->json);
7747 json_object_object_add(json_path, "community",
7748 attr->community->json);
7749 } else {
7750 vty_out(vty, " Community: %s\n",
7751 attr->community->str);
7752 }
7753 }
7754
7755 /* Line 5 display Extended-community */
7756 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
7757 if (json_paths) {
7758 json_ext_community = json_object_new_object();
7759 json_object_string_add(json_ext_community,
7760 "string",
7761 attr->ecommunity->str);
7762 json_object_object_add(json_path,
7763 "extendedCommunity",
7764 json_ext_community);
7765 } else {
7766 vty_out(vty, " Extended Community: %s\n",
7767 attr->ecommunity->str);
7768 }
7769 }
7770
7771 /* Line 6 display Large community */
7772 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))
7773 vty_out(vty, " Large Community: %s\n",
7774 attr->lcommunity->str);
7775
7776 /* Line 7 display Originator, Cluster-id */
7777 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
7778 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
7779 if (attr->flag
7780 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
7781 if (json_paths)
7782 json_object_string_add(
7783 json_path, "originatorId",
7784 inet_ntoa(attr->originator_id));
7785 else
7786 vty_out(vty, " Originator: %s",
7787 inet_ntoa(attr->originator_id));
7788 }
7789
7790 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
7791 int i;
7792
7793 if (json_paths) {
7794 json_cluster_list =
7795 json_object_new_object();
7796 json_cluster_list_list =
7797 json_object_new_array();
7798
7799 for (i = 0;
7800 i < attr->cluster->length / 4;
7801 i++) {
7802 json_string = json_object_new_string(
7803 inet_ntoa(
7804 attr->cluster->list
7805 [i]));
7806 json_object_array_add(
7807 json_cluster_list_list,
7808 json_string);
7809 }
7810
7811 /* struct cluster_list does not have
7812 "str" variable like
7813 * aspath and community do. Add this
7814 someday if someone
7815 * asks for it.
7816 json_object_string_add(json_cluster_list,
7817 "string", attr->cluster->str);
7818 */
7819 json_object_object_add(
7820 json_cluster_list, "list",
7821 json_cluster_list_list);
7822 json_object_object_add(
7823 json_path, "clusterList",
7824 json_cluster_list);
7825 } else {
7826 vty_out(vty, ", Cluster list: ");
7827
7828 for (i = 0;
7829 i < attr->cluster->length / 4;
7830 i++) {
7831 vty_out(vty, "%s ",
7832 inet_ntoa(
7833 attr->cluster->list
7834 [i]));
7835 }
7836 }
7837 }
7838
7839 if (!json_paths)
7840 vty_out(vty, "\n");
7841 }
7842
7843 if (binfo->extra && binfo->extra->damp_info)
7844 bgp_damp_info_vty(vty, binfo, json_path);
7845
7846 /* Remote Label */
7847 #if defined(HAVE_CUMULUS)
7848 if (binfo->extra && bgp_is_valid_label(&binfo->extra->label)
7849 && safi != SAFI_EVPN)
7850 #else
7851 if (binfo->extra && bgp_is_valid_label(&binfo->extra->label))
7852 #endif
7853 {
7854 mpls_label_t label = label_pton(&binfo->extra->label);
7855 if (json_paths)
7856 json_object_int_add(json_path, "remoteLabel",
7857 label);
7858 else
7859 vty_out(vty, " Remote label: %d\n", label);
7860 }
7861
7862 /* Label Index */
7863 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
7864 if (json_paths)
7865 json_object_int_add(json_path, "labelIndex",
7866 attr->label_index);
7867 else
7868 vty_out(vty, " Label Index: %d\n",
7869 attr->label_index);
7870 }
7871
7872 /* Line 8 display Addpath IDs */
7873 if (binfo->addpath_rx_id || binfo->addpath_tx_id) {
7874 if (json_paths) {
7875 json_object_int_add(json_path, "addpathRxId",
7876 binfo->addpath_rx_id);
7877 json_object_int_add(json_path, "addpathTxId",
7878 binfo->addpath_tx_id);
7879 } else {
7880 vty_out(vty, " AddPath ID: RX %u, TX %u\n",
7881 binfo->addpath_rx_id,
7882 binfo->addpath_tx_id);
7883 }
7884 }
7885
7886 /* If we used addpath to TX a non-bestpath we need to display
7887 * "Advertised to" on a path-by-path basis */
7888 if (bgp->addpath_tx_used[afi][safi]) {
7889 first = 1;
7890
7891 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
7892 addpath_capable =
7893 bgp_addpath_encode_tx(peer, afi, safi);
7894 has_adj = bgp_adj_out_lookup(
7895 peer, binfo->net, binfo->addpath_tx_id);
7896
7897 if ((addpath_capable && has_adj)
7898 || (!addpath_capable && has_adj
7899 && CHECK_FLAG(binfo->flags,
7900 BGP_INFO_SELECTED))) {
7901 if (json_path && !json_adv_to)
7902 json_adv_to =
7903 json_object_new_object();
7904
7905 route_vty_out_advertised_to(
7906 vty, peer, &first,
7907 " Advertised to:",
7908 json_adv_to);
7909 }
7910 }
7911
7912 if (json_path) {
7913 if (json_adv_to) {
7914 json_object_object_add(json_path,
7915 "advertisedTo",
7916 json_adv_to);
7917 }
7918 } else {
7919 if (!first) {
7920 vty_out(vty, "\n");
7921 }
7922 }
7923 }
7924
7925 /* Line 9 display Uptime */
7926 tbuf = time(NULL) - (bgp_clock() - binfo->uptime);
7927 if (json_paths) {
7928 json_last_update = json_object_new_object();
7929 json_object_int_add(json_last_update, "epoch", tbuf);
7930 json_object_string_add(json_last_update, "string",
7931 ctime(&tbuf));
7932 json_object_object_add(json_path, "lastUpdate",
7933 json_last_update);
7934 } else
7935 vty_out(vty, " Last update: %s", ctime(&tbuf));
7936 }
7937
7938 /* We've constructed the json object for this path, add it to the json
7939 * array of paths
7940 */
7941 if (json_paths) {
7942 if (json_nexthop_global || json_nexthop_ll) {
7943 json_nexthops = json_object_new_array();
7944
7945 if (json_nexthop_global)
7946 json_object_array_add(json_nexthops,
7947 json_nexthop_global);
7948
7949 if (json_nexthop_ll)
7950 json_object_array_add(json_nexthops,
7951 json_nexthop_ll);
7952
7953 json_object_object_add(json_path, "nexthops",
7954 json_nexthops);
7955 }
7956
7957 json_object_object_add(json_path, "peer", json_peer);
7958 json_object_array_add(json_paths, json_path);
7959 } else
7960 vty_out(vty, "\n");
7961 }
7962
7963 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
7964 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
7965 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
7966
7967 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
7968 const char *prefix_list_str, afi_t afi,
7969 safi_t safi, enum bgp_show_type type);
7970 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
7971 const char *filter, afi_t afi, safi_t safi,
7972 enum bgp_show_type type);
7973 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
7974 const char *rmap_str, afi_t afi, safi_t safi,
7975 enum bgp_show_type type);
7976 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
7977 const char *com, int exact, afi_t afi,
7978 safi_t safi);
7979 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
7980 const char *prefix, afi_t afi, safi_t safi,
7981 enum bgp_show_type type);
7982 static int bgp_show_regexp(struct vty *vty, const char *regstr, afi_t afi,
7983 safi_t safi, enum bgp_show_type type);
7984 static int bgp_show_community(struct vty *vty, struct bgp *bgp, int argc,
7985 struct cmd_token **argv, int exact, afi_t afi,
7986 safi_t safi);
7987
7988 static int bgp_show_table(struct vty *vty, struct bgp *bgp,
7989 struct bgp_table *table, enum bgp_show_type type,
7990 void *output_arg, u_char use_json)
7991 {
7992 struct bgp_info *ri;
7993 struct bgp_node *rn;
7994 int header = 1;
7995 int display;
7996 unsigned long output_count;
7997 unsigned long total_count;
7998 struct prefix *p;
7999 char buf[BUFSIZ];
8000 char buf2[BUFSIZ];
8001 json_object *json_paths = NULL;
8002 int first = 1;
8003
8004 if (use_json) {
8005 vty_out(vty,
8006 "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
8007 ", \"routerId\": \"%s\", \"routes\": { ",
8008 bgp->vrf_id == VRF_UNKNOWN ? -1 : bgp->vrf_id,
8009 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default"
8010 : bgp->name,
8011 table->version, inet_ntoa(bgp->router_id));
8012 json_paths = json_object_new_object();
8013 }
8014
8015 /* This is first entry point, so reset total line. */
8016 output_count = 0;
8017 total_count = 0;
8018
8019 /* Start processing of routes. */
8020 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
8021 if (rn->info != NULL) {
8022 display = 0;
8023 if (!first && use_json) {
8024 vty_out(vty, ",");
8025 }
8026 if (use_json)
8027 json_paths = json_object_new_array();
8028 else
8029 json_paths = NULL;
8030
8031 for (ri = rn->info; ri; ri = ri->next) {
8032 total_count++;
8033 if (type == bgp_show_type_flap_statistics
8034 || type == bgp_show_type_flap_neighbor
8035 || type == bgp_show_type_dampend_paths
8036 || type == bgp_show_type_damp_neighbor) {
8037 if (!(ri->extra
8038 && ri->extra->damp_info))
8039 continue;
8040 }
8041 if (type == bgp_show_type_regexp) {
8042 regex_t *regex = output_arg;
8043
8044 if (bgp_regexec(regex, ri->attr->aspath)
8045 == REG_NOMATCH)
8046 continue;
8047 }
8048 if (type == bgp_show_type_prefix_list) {
8049 struct prefix_list *plist = output_arg;
8050
8051 if (prefix_list_apply(plist, &rn->p)
8052 != PREFIX_PERMIT)
8053 continue;
8054 }
8055 if (type == bgp_show_type_filter_list) {
8056 struct as_list *as_list = output_arg;
8057
8058 if (as_list_apply(as_list,
8059 ri->attr->aspath)
8060 != AS_FILTER_PERMIT)
8061 continue;
8062 }
8063 if (type == bgp_show_type_route_map) {
8064 struct route_map *rmap = output_arg;
8065 struct bgp_info binfo;
8066 struct attr dummy_attr;
8067 int ret;
8068
8069 bgp_attr_dup(&dummy_attr, ri->attr);
8070
8071 binfo.peer = ri->peer;
8072 binfo.attr = &dummy_attr;
8073
8074 ret = route_map_apply(rmap, &rn->p,
8075 RMAP_BGP, &binfo);
8076 if (ret == RMAP_DENYMATCH)
8077 continue;
8078 }
8079 if (type == bgp_show_type_neighbor
8080 || type == bgp_show_type_flap_neighbor
8081 || type == bgp_show_type_damp_neighbor) {
8082 union sockunion *su = output_arg;
8083
8084 if (ri->peer == NULL
8085 || ri->peer->su_remote == NULL
8086 || !sockunion_same(
8087 ri->peer->su_remote, su))
8088 continue;
8089 }
8090 if (type == bgp_show_type_cidr_only) {
8091 u_int32_t destination;
8092
8093 destination =
8094 ntohl(rn->p.u.prefix4.s_addr);
8095 if (IN_CLASSC(destination)
8096 && rn->p.prefixlen == 24)
8097 continue;
8098 if (IN_CLASSB(destination)
8099 && rn->p.prefixlen == 16)
8100 continue;
8101 if (IN_CLASSA(destination)
8102 && rn->p.prefixlen == 8)
8103 continue;
8104 }
8105 if (type == bgp_show_type_prefix_longer) {
8106 struct prefix *p = output_arg;
8107
8108 if (!prefix_match(p, &rn->p))
8109 continue;
8110 }
8111 if (type == bgp_show_type_community_all) {
8112 if (!ri->attr->community)
8113 continue;
8114 }
8115 if (type == bgp_show_type_community) {
8116 struct community *com = output_arg;
8117
8118 if (!ri->attr->community
8119 || !community_match(
8120 ri->attr->community,
8121 com))
8122 continue;
8123 }
8124 if (type == bgp_show_type_community_exact) {
8125 struct community *com = output_arg;
8126
8127 if (!ri->attr->community
8128 || !community_cmp(
8129 ri->attr->community,
8130 com))
8131 continue;
8132 }
8133 if (type == bgp_show_type_community_list) {
8134 struct community_list *list =
8135 output_arg;
8136
8137 if (!community_list_match(
8138 ri->attr->community, list))
8139 continue;
8140 }
8141 if (type
8142 == bgp_show_type_community_list_exact) {
8143 struct community_list *list =
8144 output_arg;
8145
8146 if (!community_list_exact_match(
8147 ri->attr->community, list))
8148 continue;
8149 }
8150 if (type == bgp_show_type_lcommunity) {
8151 struct lcommunity *lcom = output_arg;
8152
8153 if (!ri->attr->lcommunity
8154 || !lcommunity_match(
8155 ri->attr->lcommunity,
8156 lcom))
8157 continue;
8158 }
8159 if (type == bgp_show_type_lcommunity_list) {
8160 struct community_list *list =
8161 output_arg;
8162
8163 if (!lcommunity_list_match(
8164 ri->attr->lcommunity, list))
8165 continue;
8166 }
8167 if (type == bgp_show_type_lcommunity_all) {
8168 if (!ri->attr->lcommunity)
8169 continue;
8170 }
8171 if (type == bgp_show_type_dampend_paths
8172 || type == bgp_show_type_damp_neighbor) {
8173 if (!CHECK_FLAG(ri->flags,
8174 BGP_INFO_DAMPED)
8175 || CHECK_FLAG(ri->flags,
8176 BGP_INFO_HISTORY))
8177 continue;
8178 }
8179
8180 if (!use_json && header) {
8181 vty_out(vty,
8182 "BGP table version is %" PRIu64
8183 ", local router ID is %s\n",
8184 table->version,
8185 inet_ntoa(bgp->router_id));
8186 vty_out(vty, BGP_SHOW_SCODE_HEADER);
8187 vty_out(vty, BGP_SHOW_OCODE_HEADER);
8188 if (type == bgp_show_type_dampend_paths
8189 || type == bgp_show_type_damp_neighbor)
8190 vty_out(vty,
8191 BGP_SHOW_DAMP_HEADER);
8192 else if (
8193 type == bgp_show_type_flap_statistics
8194 || type == bgp_show_type_flap_neighbor)
8195 vty_out(vty,
8196 BGP_SHOW_FLAP_HEADER);
8197 else
8198 vty_out(vty, BGP_SHOW_HEADER);
8199 header = 0;
8200 }
8201
8202 if (type == bgp_show_type_dampend_paths
8203 || type == bgp_show_type_damp_neighbor)
8204 damp_route_vty_out(
8205 vty, &rn->p, ri, display,
8206 SAFI_UNICAST, use_json,
8207 json_paths);
8208 else if (type == bgp_show_type_flap_statistics
8209 || type == bgp_show_type_flap_neighbor)
8210 flap_route_vty_out(
8211 vty, &rn->p, ri, display,
8212 SAFI_UNICAST, use_json,
8213 json_paths);
8214 else
8215 route_vty_out(vty, &rn->p, ri, display,
8216 SAFI_UNICAST, json_paths);
8217 display++;
8218 }
8219
8220 if (display) {
8221 output_count++;
8222 if (use_json) {
8223 p = &rn->p;
8224 sprintf(buf2, "%s/%d",
8225 inet_ntop(p->family,
8226 &p->u.prefix, buf,
8227 BUFSIZ),
8228 p->prefixlen);
8229 vty_out(vty, "\"%s\": ", buf2);
8230 vty_out(vty, "%s",
8231 json_object_to_json_string(
8232 json_paths));
8233 json_object_free(json_paths);
8234 first = 0;
8235 }
8236 }
8237 }
8238
8239 if (use_json) {
8240 json_object_free(json_paths);
8241 vty_out(vty, " } }\n");
8242 } else {
8243 /* No route is displayed */
8244 if (output_count == 0) {
8245 if (type == bgp_show_type_normal)
8246 vty_out(vty,
8247 "No BGP prefixes displayed, %ld exist\n",
8248 total_count);
8249 } else
8250 vty_out(vty,
8251 "\nDisplayed %ld routes and %ld total paths\n",
8252 output_count, total_count);
8253 }
8254
8255 return CMD_SUCCESS;
8256 }
8257
8258 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
8259 enum bgp_show_type type, void *output_arg, u_char use_json)
8260 {
8261 struct bgp_table *table;
8262
8263 if (bgp == NULL) {
8264 bgp = bgp_get_default();
8265 }
8266
8267 if (bgp == NULL) {
8268 if (!use_json)
8269 vty_out(vty, "No BGP process is configured\n");
8270 else
8271 vty_out(vty, "{}\n");
8272 return CMD_WARNING;
8273 }
8274
8275 /* use MPLS and ENCAP specific shows until they are merged */
8276 if (safi == SAFI_MPLS_VPN) {
8277 return bgp_show_mpls_vpn(vty, afi, NULL, type, output_arg, 0,
8278 use_json);
8279 }
8280 /* labeled-unicast routes live in the unicast table */
8281 else if (safi == SAFI_LABELED_UNICAST)
8282 safi = SAFI_UNICAST;
8283
8284 table = bgp->rib[afi][safi];
8285
8286 return bgp_show_table(vty, bgp, table, type, output_arg, use_json);
8287 }
8288
8289 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
8290 safi_t safi, u_char use_json)
8291 {
8292 struct listnode *node, *nnode;
8293 struct bgp *bgp;
8294 int is_first = 1;
8295
8296 if (use_json)
8297 vty_out(vty, "{\n");
8298
8299 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
8300 if (use_json) {
8301 if (!is_first)
8302 vty_out(vty, ",\n");
8303 else
8304 is_first = 0;
8305
8306 vty_out(vty, "\"%s\":",
8307 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
8308 ? "Default"
8309 : bgp->name);
8310 } else {
8311 vty_out(vty, "\nInstance %s:\n",
8312 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
8313 ? "Default"
8314 : bgp->name);
8315 }
8316 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
8317 use_json);
8318 }
8319
8320 if (use_json)
8321 vty_out(vty, "}\n");
8322 }
8323
8324 /* Header of detailed BGP route information */
8325 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
8326 struct bgp_node *rn, struct prefix_rd *prd,
8327 afi_t afi, safi_t safi, json_object *json)
8328 {
8329 struct bgp_info *ri;
8330 struct prefix *p;
8331 struct peer *peer;
8332 struct listnode *node, *nnode;
8333 char buf1[INET6_ADDRSTRLEN];
8334 char buf2[INET6_ADDRSTRLEN];
8335 #if defined(HAVE_CUMULUS)
8336 char buf3[EVPN_ROUTE_STRLEN];
8337 #endif
8338 int count = 0;
8339 int best = 0;
8340 int suppress = 0;
8341 int no_export = 0;
8342 int no_advertise = 0;
8343 int local_as = 0;
8344 int first = 1;
8345 int has_valid_label = 0;
8346 mpls_label_t label = 0;
8347 json_object *json_adv_to = NULL;
8348
8349 p = &rn->p;
8350 has_valid_label = bgp_is_valid_label(&rn->local_label);
8351
8352 if (has_valid_label)
8353 label = label_pton(&rn->local_label);
8354
8355 if (json) {
8356 if (has_valid_label)
8357 json_object_int_add(json, "localLabel", label);
8358
8359 json_object_string_add(json, "prefix",
8360 inet_ntop(p->family, &p->u.prefix, buf2,
8361 INET6_ADDRSTRLEN));
8362 json_object_int_add(json, "prefixlen", p->prefixlen);
8363 } else {
8364 #if defined(HAVE_CUMULUS)
8365 if (safi == SAFI_EVPN)
8366 vty_out(vty, "BGP routing table entry for %s%s%s\n",
8367 prd ? prefix_rd2str(prd, buf1, RD_ADDRSTRLEN)
8368 : "",
8369 prd ? ":" : "",
8370 bgp_evpn_route2str((struct prefix_evpn *)p,
8371 buf3, sizeof(buf3)));
8372 else
8373 vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
8374 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
8375 ? prefix_rd2str(prd, buf1,
8376 RD_ADDRSTRLEN)
8377 : ""),
8378 safi == SAFI_MPLS_VPN ? ":" : "",
8379 inet_ntop(p->family, &p->u.prefix, buf2,
8380 INET6_ADDRSTRLEN),
8381 p->prefixlen);
8382 #else
8383 if (p->family == AF_ETHERNET)
8384 prefix2str(p, buf2, INET6_ADDRSTRLEN);
8385 else
8386 inet_ntop(p->family, &p->u.prefix, buf2,
8387 INET6_ADDRSTRLEN);
8388 vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
8389 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8390 || safi == SAFI_EVPN)
8391 ? prefix_rd2str(prd, buf1, RD_ADDRSTRLEN)
8392 : ""),
8393 ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN)) ? ":"
8394 : "",
8395 buf2, p->prefixlen);
8396 #endif
8397
8398 if (has_valid_label)
8399 vty_out(vty, "Local label: %d\n", label);
8400 #if defined(HAVE_CUMULUS)
8401 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
8402 #else
8403 if (bgp_labeled_safi(safi))
8404 #endif
8405 vty_out(vty, "not allocated\n");
8406 }
8407
8408 for (ri = rn->info; ri; ri = ri->next) {
8409 count++;
8410 if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) {
8411 best = count;
8412 if (ri->extra && ri->extra->suppress)
8413 suppress = 1;
8414 if (ri->attr->community != NULL) {
8415 if (community_include(ri->attr->community,
8416 COMMUNITY_NO_ADVERTISE))
8417 no_advertise = 1;
8418 if (community_include(ri->attr->community,
8419 COMMUNITY_NO_EXPORT))
8420 no_export = 1;
8421 if (community_include(ri->attr->community,
8422 COMMUNITY_LOCAL_AS))
8423 local_as = 1;
8424 }
8425 }
8426 }
8427
8428 if (!json) {
8429 vty_out(vty, "Paths: (%d available", count);
8430 if (best) {
8431 vty_out(vty, ", best #%d", best);
8432 if (safi == SAFI_UNICAST)
8433 vty_out(vty, ", table %s",
8434 (bgp->inst_type
8435 == BGP_INSTANCE_TYPE_DEFAULT)
8436 ? "Default-IP-Routing-Table"
8437 : bgp->name);
8438 } else
8439 vty_out(vty, ", no best path");
8440
8441 if (no_advertise)
8442 vty_out(vty, ", not advertised to any peer");
8443 else if (no_export)
8444 vty_out(vty, ", not advertised to EBGP peer");
8445 else if (local_as)
8446 vty_out(vty, ", not advertised outside local AS");
8447
8448 if (suppress)
8449 vty_out(vty,
8450 ", Advertisements suppressed by an aggregate.");
8451 vty_out(vty, ")\n");
8452 }
8453
8454 /* If we are not using addpath then we can display Advertised to and
8455 * that will
8456 * show what peers we advertised the bestpath to. If we are using
8457 * addpath
8458 * though then we must display Advertised to on a path-by-path basis. */
8459 if (!bgp->addpath_tx_used[afi][safi]) {
8460 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
8461 if (bgp_adj_out_lookup(peer, rn, 0)) {
8462 if (json && !json_adv_to)
8463 json_adv_to = json_object_new_object();
8464
8465 route_vty_out_advertised_to(
8466 vty, peer, &first,
8467 " Advertised to non peer-group peers:\n ",
8468 json_adv_to);
8469 }
8470 }
8471
8472 if (json) {
8473 if (json_adv_to) {
8474 json_object_object_add(json, "advertisedTo",
8475 json_adv_to);
8476 }
8477 } else {
8478 if (first)
8479 vty_out(vty, " Not advertised to any peer");
8480 vty_out(vty, "\n");
8481 }
8482 }
8483 }
8484
8485 /* Display specified route of BGP table. */
8486 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
8487 struct bgp_table *rib, const char *ip_str,
8488 afi_t afi, safi_t safi,
8489 struct prefix_rd *prd, int prefix_check,
8490 enum bgp_path_type pathtype, u_char use_json)
8491 {
8492 int ret;
8493 int header;
8494 int display = 0;
8495 struct prefix match;
8496 struct bgp_node *rn;
8497 struct bgp_node *rm;
8498 struct bgp_info *ri;
8499 struct bgp_table *table;
8500 json_object *json = NULL;
8501 json_object *json_paths = NULL;
8502
8503 /* Check IP address argument. */
8504 ret = str2prefix(ip_str, &match);
8505 if (!ret) {
8506 vty_out(vty, "address is malformed\n");
8507 return CMD_WARNING;
8508 }
8509
8510 match.family = afi2family(afi);
8511
8512 if (use_json) {
8513 json = json_object_new_object();
8514 json_paths = json_object_new_array();
8515 }
8516
8517 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
8518 for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
8519 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
8520 continue;
8521
8522 if ((table = rn->info) != NULL) {
8523 header = 1;
8524
8525 if ((rm = bgp_node_match(table, &match))
8526 != NULL) {
8527 if (prefix_check
8528 && rm->p.prefixlen
8529 != match.prefixlen) {
8530 bgp_unlock_node(rm);
8531 continue;
8532 }
8533
8534 for (ri = rm->info; ri; ri = ri->next) {
8535 if (header) {
8536 route_vty_out_detail_header(
8537 vty, bgp, rm,
8538 (struct
8539 prefix_rd *)&rn
8540 ->p,
8541 AFI_IP, safi,
8542 json);
8543 header = 0;
8544 }
8545 display++;
8546
8547 if (pathtype == BGP_PATH_ALL
8548 || (pathtype
8549 == BGP_PATH_BESTPATH
8550 && CHECK_FLAG(
8551 ri->flags,
8552 BGP_INFO_SELECTED))
8553 || (pathtype
8554 == BGP_PATH_MULTIPATH
8555 && (CHECK_FLAG(
8556 ri->flags,
8557 BGP_INFO_MULTIPATH)
8558 || CHECK_FLAG(
8559 ri->flags,
8560 BGP_INFO_SELECTED))))
8561 route_vty_out_detail(
8562 vty, bgp,
8563 &rm->p, ri,
8564 AFI_IP, safi,
8565 json_paths);
8566 }
8567
8568 bgp_unlock_node(rm);
8569 }
8570 }
8571 }
8572 } else {
8573 header = 1;
8574
8575 if ((rn = bgp_node_match(rib, &match)) != NULL) {
8576 if (!prefix_check
8577 || rn->p.prefixlen == match.prefixlen) {
8578 for (ri = rn->info; ri; ri = ri->next) {
8579 if (header) {
8580 route_vty_out_detail_header(
8581 vty, bgp, rn, NULL, afi,
8582 safi, json);
8583 header = 0;
8584 }
8585 display++;
8586
8587 if (pathtype == BGP_PATH_ALL
8588 || (pathtype == BGP_PATH_BESTPATH
8589 && CHECK_FLAG(
8590 ri->flags,
8591 BGP_INFO_SELECTED))
8592 || (pathtype == BGP_PATH_MULTIPATH
8593 && (CHECK_FLAG(
8594 ri->flags,
8595 BGP_INFO_MULTIPATH)
8596 || CHECK_FLAG(
8597 ri->flags,
8598 BGP_INFO_SELECTED))))
8599 route_vty_out_detail(
8600 vty, bgp, &rn->p, ri,
8601 afi, safi, json_paths);
8602 }
8603 }
8604
8605 bgp_unlock_node(rn);
8606 }
8607 }
8608
8609 if (use_json) {
8610 if (display)
8611 json_object_object_add(json, "paths", json_paths);
8612
8613 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8614 json, JSON_C_TO_STRING_PRETTY));
8615 json_object_free(json);
8616 } else {
8617 if (!display) {
8618 vty_out(vty, "%% Network not in table\n");
8619 return CMD_WARNING;
8620 }
8621 }
8622
8623 return CMD_SUCCESS;
8624 }
8625
8626 /* Display specified route of Main RIB */
8627 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
8628 afi_t afi, safi_t safi, struct prefix_rd *prd,
8629 int prefix_check, enum bgp_path_type pathtype,
8630 u_char use_json)
8631 {
8632 if (!bgp) {
8633 bgp = bgp_get_default();
8634 if (!bgp) {
8635 if (!use_json)
8636 vty_out(vty, "No BGP process is configured\n");
8637 else
8638 vty_out(vty, "{}\n");
8639 return CMD_WARNING;
8640 }
8641 }
8642
8643 /* labeled-unicast routes live in the unicast table */
8644 if (safi == SAFI_LABELED_UNICAST)
8645 safi = SAFI_UNICAST;
8646
8647 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
8648 afi, safi, prd, prefix_check, pathtype,
8649 use_json);
8650 }
8651
8652 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
8653 struct cmd_token **argv, afi_t afi, safi_t safi,
8654 u_char uj)
8655 {
8656 struct lcommunity *lcom;
8657 struct buffer *b;
8658 int i;
8659 char *str;
8660 int first = 0;
8661
8662 b = buffer_new(1024);
8663 for (i = 0; i < argc; i++) {
8664 if (first)
8665 buffer_putc(b, ' ');
8666 else {
8667 if (strmatch(argv[i]->text, "AA:BB:CC")) {
8668 first = 1;
8669 buffer_putstr(b, argv[i]->arg);
8670 }
8671 }
8672 }
8673 buffer_putc(b, '\0');
8674
8675 str = buffer_getstr(b);
8676 buffer_free(b);
8677
8678 lcom = lcommunity_str2com(str);
8679 XFREE(MTYPE_TMP, str);
8680 if (!lcom) {
8681 vty_out(vty, "%% Large-community malformed\n");
8682 return CMD_WARNING;
8683 }
8684
8685 return bgp_show(vty, bgp, afi, safi, bgp_show_type_lcommunity, lcom,
8686 uj);
8687 }
8688
8689 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
8690 const char *lcom, afi_t afi, safi_t safi,
8691 u_char uj)
8692 {
8693 struct community_list *list;
8694
8695 list = community_list_lookup(bgp_clist, lcom,
8696 LARGE_COMMUNITY_LIST_MASTER);
8697 if (list == NULL) {
8698 vty_out(vty, "%% %s is not a valid large-community-list name\n",
8699 lcom);
8700 return CMD_WARNING;
8701 }
8702
8703 return bgp_show(vty, bgp, afi, safi, bgp_show_type_lcommunity_list,
8704 list, uj);
8705 }
8706
8707 DEFUN (show_ip_bgp_large_community_list,
8708 show_ip_bgp_large_community_list_cmd,
8709 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community-list <(1-500)|WORD> [json]",
8710 SHOW_STR
8711 IP_STR
8712 BGP_STR
8713 BGP_INSTANCE_HELP_STR
8714 BGP_AFI_HELP_STR
8715 BGP_SAFI_WITH_LABEL_HELP_STR
8716 "Display routes matching the large-community-list\n"
8717 "large-community-list number\n"
8718 "large-community-list name\n"
8719 JSON_STR)
8720 {
8721 char *vrf = NULL;
8722 afi_t afi = AFI_IP6;
8723 safi_t safi = SAFI_UNICAST;
8724 int idx = 0;
8725
8726 if (argv_find(argv, argc, "ip", &idx))
8727 afi = AFI_IP;
8728 if (argv_find(argv, argc, "view", &idx)
8729 || argv_find(argv, argc, "vrf", &idx))
8730 vrf = argv[++idx]->arg;
8731 if (argv_find(argv, argc, "ipv4", &idx)
8732 || argv_find(argv, argc, "ipv6", &idx)) {
8733 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
8734 if (argv_find(argv, argc, "unicast", &idx)
8735 || argv_find(argv, argc, "multicast", &idx))
8736 safi = bgp_vty_safi_from_str(argv[idx]->text);
8737 }
8738
8739 int uj = use_json(argc, argv);
8740
8741 struct bgp *bgp = bgp_lookup_by_name(vrf);
8742 if (bgp == NULL) {
8743 vty_out(vty, "Can't find BGP instance %s\n", vrf);
8744 return CMD_WARNING;
8745 }
8746
8747 argv_find(argv, argc, "large-community-list", &idx);
8748 return bgp_show_lcommunity_list(vty, bgp, argv[idx + 1]->arg, afi, safi,
8749 uj);
8750 }
8751 DEFUN (show_ip_bgp_large_community,
8752 show_ip_bgp_large_community_cmd,
8753 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [AA:BB:CC] [json]",
8754 SHOW_STR
8755 IP_STR
8756 BGP_STR
8757 BGP_INSTANCE_HELP_STR
8758 BGP_AFI_HELP_STR
8759 BGP_SAFI_WITH_LABEL_HELP_STR
8760 "Display routes matching the large-communities\n"
8761 "List of large-community numbers\n"
8762 JSON_STR)
8763 {
8764 char *vrf = NULL;
8765 afi_t afi = AFI_IP6;
8766 safi_t safi = SAFI_UNICAST;
8767 int idx = 0;
8768
8769 if (argv_find(argv, argc, "ip", &idx))
8770 afi = AFI_IP;
8771 if (argv_find(argv, argc, "view", &idx)
8772 || argv_find(argv, argc, "vrf", &idx))
8773 vrf = argv[++idx]->arg;
8774 if (argv_find(argv, argc, "ipv4", &idx)
8775 || argv_find(argv, argc, "ipv6", &idx)) {
8776 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
8777 if (argv_find(argv, argc, "unicast", &idx)
8778 || argv_find(argv, argc, "multicast", &idx))
8779 safi = bgp_vty_safi_from_str(argv[idx]->text);
8780 }
8781
8782 int uj = use_json(argc, argv);
8783
8784 struct bgp *bgp = bgp_lookup_by_name(vrf);
8785 if (bgp == NULL) {
8786 vty_out(vty, "Can't find BGP instance %s\n", vrf);
8787 return CMD_WARNING;
8788 }
8789
8790 if (argv_find(argv, argc, "AA:BB:CC", &idx))
8791 return bgp_show_lcommunity(vty, bgp, argc, argv, afi, safi, uj);
8792 else
8793 return bgp_show(vty, bgp, afi, safi,
8794 bgp_show_type_lcommunity_all, NULL, uj);
8795 }
8796
8797 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
8798 safi_t safi);
8799
8800 /* BGP route print out function. */
8801 DEFUN (show_ip_bgp,
8802 show_ip_bgp_cmd,
8803 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
8804 [<\
8805 cidr-only\
8806 |dampening <flap-statistics|dampened-paths|parameters>\
8807 |route-map WORD\
8808 |prefix-list WORD\
8809 |filter-list WORD\
8810 |statistics\
8811 |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
8812 |community-list <(1-500)|WORD> [exact-match]\
8813 |A.B.C.D/M longer-prefixes\
8814 |X:X::X:X/M longer-prefixes>\
8815 ] [json]",
8816 SHOW_STR
8817 IP_STR
8818 BGP_STR
8819 BGP_INSTANCE_HELP_STR
8820 BGP_AFI_HELP_STR
8821 BGP_SAFI_WITH_LABEL_HELP_STR
8822 "Display only routes with non-natural netmasks\n"
8823 "Display detailed information about dampening\n"
8824 "Display flap statistics of routes\n"
8825 "Display paths suppressed due to dampening\n"
8826 "Display detail of configured dampening parameters\n"
8827 "Display routes matching the route-map\n"
8828 "A route-map to match on\n"
8829 "Display routes conforming to the prefix-list\n"
8830 "Prefix-list name\n"
8831 "Display routes conforming to the filter-list\n"
8832 "Regular expression access list name\n"
8833 "BGP RIB advertisement statistics\n"
8834 "Display routes matching the communities\n"
8835 COMMUNITY_AANN_STR
8836 "Do not send outside local AS (well-known community)\n"
8837 "Do not advertise to any peer (well-known community)\n"
8838 "Do not export to next AS (well-known community)\n"
8839 "Exact match of the communities\n"
8840 "Display routes matching the community-list\n"
8841 "community-list number\n"
8842 "community-list name\n"
8843 "Exact match of the communities\n"
8844 "IPv4 prefix\n"
8845 "Display route and more specific routes\n"
8846 "IPv6 prefix\n"
8847 "Display route and more specific routes\n"
8848 JSON_STR)
8849 {
8850 afi_t afi = AFI_IP6;
8851 safi_t safi = SAFI_UNICAST;
8852 int exact_match = 0;
8853 enum bgp_show_type sh_type = bgp_show_type_normal;
8854 struct bgp *bgp = NULL;
8855 int idx = 0;
8856
8857 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
8858 &bgp);
8859 if (!idx)
8860 return CMD_WARNING;
8861
8862 int uj = use_json(argc, argv);
8863 if (uj)
8864 argc--;
8865
8866 if (argv_find(argv, argc, "cidr-only", &idx))
8867 return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only,
8868 NULL, uj);
8869
8870 if (argv_find(argv, argc, "dampening", &idx)) {
8871 if (argv_find(argv, argc, "dampened-paths", &idx))
8872 return bgp_show(vty, bgp, afi, safi,
8873 bgp_show_type_dampend_paths, NULL, uj);
8874 else if (argv_find(argv, argc, "flap-statistics", &idx))
8875 return bgp_show(vty, bgp, afi, safi,
8876 bgp_show_type_flap_statistics, NULL,
8877 uj);
8878 else if (argv_find(argv, argc, "parameters", &idx))
8879 return bgp_show_dampening_parameters(vty, afi, safi);
8880 }
8881
8882 if (argv_find(argv, argc, "prefix-list", &idx))
8883 return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
8884 safi, bgp_show_type_prefix_list);
8885
8886 if (argv_find(argv, argc, "filter-list", &idx))
8887 return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
8888 safi, bgp_show_type_filter_list);
8889
8890 if (argv_find(argv, argc, "statistics", &idx))
8891 return bgp_table_stats(vty, bgp, afi, safi);
8892
8893 if (argv_find(argv, argc, "route-map", &idx))
8894 return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
8895 safi, bgp_show_type_route_map);
8896
8897 if (argv_find(argv, argc, "community", &idx)) {
8898 /* show a specific community */
8899 if (argv_find(argv, argc, "local-AS", &idx)
8900 || argv_find(argv, argc, "no-advertise", &idx)
8901 || argv_find(argv, argc, "no-export", &idx)) {
8902 if (argv_find(argv, argc, "exact_match", &idx))
8903 exact_match = 1;
8904 return bgp_show_community(vty, bgp, argc, argv,
8905 exact_match, afi, safi);
8906 }
8907 /* show all communities */
8908 else
8909 return bgp_show(vty, bgp, afi, safi,
8910 bgp_show_type_community_all, NULL, uj);
8911 }
8912
8913 if (argv_find(argv, argc, "community-list", &idx)) {
8914 const char *clist_number_or_name = argv[++idx]->arg;
8915 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
8916 exact_match = 1;
8917 return bgp_show_community_list(vty, bgp, clist_number_or_name,
8918 exact_match, afi, safi);
8919 }
8920 /* prefix-longer */
8921 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
8922 || argv_find(argv, argc, "X:X::X:X/M", &idx))
8923 return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
8924 safi,
8925 bgp_show_type_prefix_longer);
8926
8927 if (safi == SAFI_MPLS_VPN)
8928 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
8929 NULL, 0, uj);
8930 else
8931 return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj);
8932 }
8933
8934 DEFUN (show_ip_bgp_route,
8935 show_ip_bgp_route_cmd,
8936 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]"
8937 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
8938 SHOW_STR
8939 IP_STR
8940 BGP_STR
8941 BGP_INSTANCE_HELP_STR
8942 BGP_AFI_HELP_STR
8943 BGP_SAFI_WITH_LABEL_HELP_STR
8944 "Network in the BGP routing table to display\n"
8945 "IPv4 prefix\n"
8946 "Network in the BGP routing table to display\n"
8947 "IPv6 prefix\n"
8948 "Display only the bestpath\n"
8949 "Display only multipaths\n"
8950 JSON_STR)
8951 {
8952 int prefix_check = 0;
8953
8954 afi_t afi = AFI_IP6;
8955 safi_t safi = SAFI_UNICAST;
8956 char *prefix = NULL;
8957 struct bgp *bgp = NULL;
8958 enum bgp_path_type path_type;
8959 u_char uj = use_json(argc, argv);
8960
8961 int idx = 0;
8962
8963 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
8964 &bgp);
8965 if (!idx)
8966 return CMD_WARNING;
8967
8968 if (!bgp) {
8969 vty_out(vty,
8970 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
8971 return CMD_WARNING;
8972 }
8973
8974 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
8975 if (argv_find(argv, argc, "A.B.C.D", &idx)
8976 || argv_find(argv, argc, "X:X::X:X", &idx))
8977 prefix_check = 0;
8978 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
8979 || argv_find(argv, argc, "X:X::X:X/M", &idx))
8980 prefix_check = 1;
8981
8982 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
8983 && afi != AFI_IP6) {
8984 vty_out(vty,
8985 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
8986 return CMD_WARNING;
8987 }
8988 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
8989 && afi != AFI_IP) {
8990 vty_out(vty,
8991 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
8992 return CMD_WARNING;
8993 }
8994
8995 prefix = argv[idx]->arg;
8996
8997 /* [<bestpath|multipath>] */
8998 if (argv_find(argv, argc, "bestpath", &idx))
8999 path_type = BGP_PATH_BESTPATH;
9000 else if (argv_find(argv, argc, "multipath", &idx))
9001 path_type = BGP_PATH_MULTIPATH;
9002 else
9003 path_type = BGP_PATH_ALL;
9004
9005 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
9006 path_type, uj);
9007 }
9008
9009 DEFUN (show_ip_bgp_regexp,
9010 show_ip_bgp_regexp_cmd,
9011 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX...",
9012 SHOW_STR
9013 IP_STR
9014 BGP_STR
9015 BGP_INSTANCE_HELP_STR
9016 BGP_AFI_HELP_STR
9017 BGP_SAFI_WITH_LABEL_HELP_STR
9018 "Display routes matching the AS path regular expression\n"
9019 "A regular-expression to match the BGP AS paths\n")
9020 {
9021 afi_t afi = AFI_IP6;
9022 safi_t safi = SAFI_UNICAST;
9023 struct bgp *bgp = NULL;
9024
9025 int idx = 0;
9026 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9027 &bgp);
9028 if (!idx)
9029 return CMD_WARNING;
9030
9031 // get index of regex
9032 argv_find(argv, argc, "regexp", &idx);
9033 idx++;
9034
9035 char *regstr = argv_concat(argv, argc, idx);
9036 int rc = bgp_show_regexp(vty, (const char *)regstr, afi, safi,
9037 bgp_show_type_regexp);
9038 XFREE(MTYPE_TMP, regstr);
9039 return rc;
9040 }
9041
9042 DEFUN (show_ip_bgp_instance_all,
9043 show_ip_bgp_instance_all_cmd,
9044 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json]",
9045 SHOW_STR
9046 IP_STR
9047 BGP_STR
9048 BGP_INSTANCE_ALL_HELP_STR
9049 BGP_AFI_HELP_STR
9050 BGP_SAFI_WITH_LABEL_HELP_STR
9051 JSON_STR)
9052 {
9053 afi_t afi = AFI_IP;
9054 safi_t safi = SAFI_UNICAST;
9055 struct bgp *bgp = NULL;
9056
9057 int idx = 0;
9058 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9059 &bgp);
9060 if (!idx)
9061 return CMD_WARNING;
9062
9063 int uj = use_json(argc, argv);
9064 if (uj)
9065 argc--;
9066
9067 bgp_show_all_instances_routes_vty(vty, afi, safi, uj);
9068 return CMD_SUCCESS;
9069 }
9070
9071 static int bgp_show_regexp(struct vty *vty, const char *regstr, afi_t afi,
9072 safi_t safi, enum bgp_show_type type)
9073 {
9074 regex_t *regex;
9075 int rc;
9076
9077 regex = bgp_regcomp(regstr);
9078 if (!regex) {
9079 vty_out(vty, "Can't compile regexp %s\n", regstr);
9080 return CMD_WARNING;
9081 }
9082
9083 rc = bgp_show(vty, NULL, afi, safi, type, regex, 0);
9084 bgp_regex_free(regex);
9085 return rc;
9086 }
9087
9088 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
9089 const char *prefix_list_str, afi_t afi,
9090 safi_t safi, enum bgp_show_type type)
9091 {
9092 struct prefix_list *plist;
9093
9094 plist = prefix_list_lookup(afi, prefix_list_str);
9095 if (plist == NULL) {
9096 vty_out(vty, "%% %s is not a valid prefix-list name\n",
9097 prefix_list_str);
9098 return CMD_WARNING;
9099 }
9100
9101 return bgp_show(vty, bgp, afi, safi, type, plist, 0);
9102 }
9103
9104 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
9105 const char *filter, afi_t afi, safi_t safi,
9106 enum bgp_show_type type)
9107 {
9108 struct as_list *as_list;
9109
9110 as_list = as_list_lookup(filter);
9111 if (as_list == NULL) {
9112 vty_out(vty, "%% %s is not a valid AS-path access-list name\n",
9113 filter);
9114 return CMD_WARNING;
9115 }
9116
9117 return bgp_show(vty, bgp, afi, safi, type, as_list, 0);
9118 }
9119
9120 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
9121 const char *rmap_str, afi_t afi, safi_t safi,
9122 enum bgp_show_type type)
9123 {
9124 struct route_map *rmap;
9125
9126 rmap = route_map_lookup_by_name(rmap_str);
9127 if (!rmap) {
9128 vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str);
9129 return CMD_WARNING;
9130 }
9131
9132 return bgp_show(vty, bgp, afi, safi, type, rmap, 0);
9133 }
9134
9135 static int bgp_show_community(struct vty *vty, struct bgp *bgp, int argc,
9136 struct cmd_token **argv, int exact, afi_t afi,
9137 safi_t safi)
9138 {
9139 struct community *com;
9140 struct buffer *b;
9141 int i;
9142 char *str;
9143 int first = 0;
9144 int ret = 0;
9145
9146 b = buffer_new(1024);
9147 for (i = 0; i < argc; i++) {
9148 if (first)
9149 buffer_putc(b, ' ');
9150 else {
9151 if (strmatch(argv[i]->text, "unicast")
9152 || strmatch(argv[i]->text, "multicast"))
9153 continue;
9154 first = 1;
9155 }
9156
9157 buffer_putstr(b, argv[i]->arg);
9158 }
9159 buffer_putc(b, '\0');
9160
9161 str = buffer_getstr(b);
9162 buffer_free(b);
9163
9164 com = community_str2com(str);
9165 XFREE(MTYPE_TMP, str);
9166 if (!com) {
9167 vty_out(vty, "%% Community malformed: \n");
9168 return CMD_WARNING;
9169 }
9170
9171 ret = bgp_show(vty, bgp, afi, safi,
9172 (exact ? bgp_show_type_community_exact
9173 : bgp_show_type_community),
9174 com, 0);
9175 community_free(com);
9176
9177 return ret;
9178 }
9179
9180 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
9181 const char *com, int exact, afi_t afi,
9182 safi_t safi)
9183 {
9184 struct community_list *list;
9185
9186 list = community_list_lookup(bgp_clist, com, COMMUNITY_LIST_MASTER);
9187 if (list == NULL) {
9188 vty_out(vty, "%% %s is not a valid community-list name\n", com);
9189 return CMD_WARNING;
9190 }
9191
9192 return bgp_show(vty, bgp, afi, safi,
9193 (exact ? bgp_show_type_community_list_exact
9194 : bgp_show_type_community_list),
9195 list, 0);
9196 }
9197
9198 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
9199 const char *prefix, afi_t afi, safi_t safi,
9200 enum bgp_show_type type)
9201 {
9202 int ret;
9203 struct prefix *p;
9204
9205 p = prefix_new();
9206
9207 ret = str2prefix(prefix, p);
9208 if (!ret) {
9209 vty_out(vty, "%% Malformed Prefix\n");
9210 return CMD_WARNING;
9211 }
9212
9213 ret = bgp_show(vty, bgp, afi, safi, type, p, 0);
9214 prefix_free(p);
9215 return ret;
9216 }
9217
9218 static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
9219 const char *ip_str, u_char use_json)
9220 {
9221 int ret;
9222 struct peer *peer;
9223 union sockunion su;
9224
9225 /* Get peer sockunion. */
9226 ret = str2sockunion(ip_str, &su);
9227 if (ret < 0) {
9228 peer = peer_lookup_by_conf_if(bgp, ip_str);
9229 if (!peer) {
9230 peer = peer_lookup_by_hostname(bgp, ip_str);
9231
9232 if (!peer) {
9233 if (use_json) {
9234 json_object *json_no = NULL;
9235 json_no = json_object_new_object();
9236 json_object_string_add(
9237 json_no,
9238 "malformedAddressOrName",
9239 ip_str);
9240 vty_out(vty, "%s\n",
9241 json_object_to_json_string(
9242 json_no));
9243 json_object_free(json_no);
9244 } else
9245 vty_out(vty,
9246 "%% Malformed address or name: %s\n",
9247 ip_str);
9248 return NULL;
9249 }
9250 }
9251 return peer;
9252 }
9253
9254 /* Peer structure lookup. */
9255 peer = peer_lookup(bgp, &su);
9256 if (!peer) {
9257 if (use_json) {
9258 json_object *json_no = NULL;
9259 json_no = json_object_new_object();
9260 json_object_string_add(json_no, "warning",
9261 "No such neighbor");
9262 vty_out(vty, "%s\n",
9263 json_object_to_json_string(json_no));
9264 json_object_free(json_no);
9265 } else
9266 vty_out(vty, "No such neighbor\n");
9267 return NULL;
9268 }
9269
9270 return peer;
9271 }
9272
9273 enum bgp_stats {
9274 BGP_STATS_MAXBITLEN = 0,
9275 BGP_STATS_RIB,
9276 BGP_STATS_PREFIXES,
9277 BGP_STATS_TOTPLEN,
9278 BGP_STATS_UNAGGREGATEABLE,
9279 BGP_STATS_MAX_AGGREGATEABLE,
9280 BGP_STATS_AGGREGATES,
9281 BGP_STATS_SPACE,
9282 BGP_STATS_ASPATH_COUNT,
9283 BGP_STATS_ASPATH_MAXHOPS,
9284 BGP_STATS_ASPATH_TOTHOPS,
9285 BGP_STATS_ASPATH_MAXSIZE,
9286 BGP_STATS_ASPATH_TOTSIZE,
9287 BGP_STATS_ASN_HIGHEST,
9288 BGP_STATS_MAX,
9289 };
9290
9291 static const char *table_stats_strs[] = {
9292 [BGP_STATS_PREFIXES] = "Total Prefixes",
9293 [BGP_STATS_TOTPLEN] = "Average prefix length",
9294 [BGP_STATS_RIB] = "Total Advertisements",
9295 [BGP_STATS_UNAGGREGATEABLE] = "Unaggregateable prefixes",
9296 [BGP_STATS_MAX_AGGREGATEABLE] =
9297 "Maximum aggregateable prefixes",
9298 [BGP_STATS_AGGREGATES] = "BGP Aggregate advertisements",
9299 [BGP_STATS_SPACE] = "Address space advertised",
9300 [BGP_STATS_ASPATH_COUNT] = "Advertisements with paths",
9301 [BGP_STATS_ASPATH_MAXHOPS] = "Longest AS-Path (hops)",
9302 [BGP_STATS_ASPATH_MAXSIZE] = "Largest AS-Path (bytes)",
9303 [BGP_STATS_ASPATH_TOTHOPS] = "Average AS-Path length (hops)",
9304 [BGP_STATS_ASPATH_TOTSIZE] = "Average AS-Path size (bytes)",
9305 [BGP_STATS_ASN_HIGHEST] = "Highest public ASN",
9306 [BGP_STATS_MAX] = NULL,
9307 };
9308
9309 struct bgp_table_stats {
9310 struct bgp_table *table;
9311 unsigned long long counts[BGP_STATS_MAX];
9312 };
9313
9314 #if 0
9315 #define TALLY_SIGFIG 100000
9316 static unsigned long
9317 ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
9318 {
9319 unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
9320 unsigned long res = (newtot * TALLY_SIGFIG) / count;
9321 unsigned long ret = newtot / count;
9322
9323 if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
9324 return ret + 1;
9325 else
9326 return ret;
9327 }
9328 #endif
9329
9330 static int bgp_table_stats_walker(struct thread *t)
9331 {
9332 struct bgp_node *rn;
9333 struct bgp_node *top;
9334 struct bgp_table_stats *ts = THREAD_ARG(t);
9335 unsigned int space = 0;
9336
9337 if (!(top = bgp_table_top(ts->table)))
9338 return 0;
9339
9340 switch (top->p.family) {
9341 case AF_INET:
9342 space = IPV4_MAX_BITLEN;
9343 break;
9344 case AF_INET6:
9345 space = IPV6_MAX_BITLEN;
9346 break;
9347 }
9348
9349 ts->counts[BGP_STATS_MAXBITLEN] = space;
9350
9351 for (rn = top; rn; rn = bgp_route_next(rn)) {
9352 struct bgp_info *ri;
9353 struct bgp_node *prn = bgp_node_parent_nolock(rn);
9354 unsigned int rinum = 0;
9355
9356 if (rn == top)
9357 continue;
9358
9359 if (!rn->info)
9360 continue;
9361
9362 ts->counts[BGP_STATS_PREFIXES]++;
9363 ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
9364
9365 #if 0
9366 ts->counts[BGP_STATS_AVGPLEN]
9367 = ravg_tally (ts->counts[BGP_STATS_PREFIXES],
9368 ts->counts[BGP_STATS_AVGPLEN],
9369 rn->p.prefixlen);
9370 #endif
9371
9372 /* check if the prefix is included by any other announcements */
9373 while (prn && !prn->info)
9374 prn = bgp_node_parent_nolock(prn);
9375
9376 if (prn == NULL || prn == top) {
9377 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
9378 /* announced address space */
9379 if (space)
9380 ts->counts[BGP_STATS_SPACE] +=
9381 1 << (space - rn->p.prefixlen);
9382 } else if (prn->info)
9383 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
9384
9385 for (ri = rn->info; ri; ri = ri->next) {
9386 rinum++;
9387 ts->counts[BGP_STATS_RIB]++;
9388
9389 if (ri->attr
9390 && (CHECK_FLAG(ri->attr->flag,
9391 ATTR_FLAG_BIT(
9392 BGP_ATTR_ATOMIC_AGGREGATE))))
9393 ts->counts[BGP_STATS_AGGREGATES]++;
9394
9395 /* as-path stats */
9396 if (ri->attr && ri->attr->aspath) {
9397 unsigned int hops =
9398 aspath_count_hops(ri->attr->aspath);
9399 unsigned int size =
9400 aspath_size(ri->attr->aspath);
9401 as_t highest = aspath_highest(ri->attr->aspath);
9402
9403 ts->counts[BGP_STATS_ASPATH_COUNT]++;
9404
9405 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
9406 ts->counts[BGP_STATS_ASPATH_MAXHOPS] =
9407 hops;
9408
9409 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
9410 ts->counts[BGP_STATS_ASPATH_MAXSIZE] =
9411 size;
9412
9413 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
9414 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
9415 #if 0
9416 ts->counts[BGP_STATS_ASPATH_AVGHOPS]
9417 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
9418 ts->counts[BGP_STATS_ASPATH_AVGHOPS],
9419 hops);
9420 ts->counts[BGP_STATS_ASPATH_AVGSIZE]
9421 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
9422 ts->counts[BGP_STATS_ASPATH_AVGSIZE],
9423 size);
9424 #endif
9425 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
9426 ts->counts[BGP_STATS_ASN_HIGHEST] =
9427 highest;
9428 }
9429 }
9430 }
9431 return 0;
9432 }
9433
9434 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
9435 safi_t safi)
9436 {
9437 struct bgp_table_stats ts;
9438 unsigned int i;
9439
9440 if (!bgp->rib[afi][safi]) {
9441 vty_out(vty, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
9442 afi, safi);
9443 return CMD_WARNING;
9444 }
9445
9446 vty_out(vty, "BGP %s RIB statistics\n", afi_safi_print(afi, safi));
9447
9448 /* labeled-unicast routes live in the unicast table */
9449 if (safi == SAFI_LABELED_UNICAST)
9450 safi = SAFI_UNICAST;
9451
9452 memset(&ts, 0, sizeof(ts));
9453 ts.table = bgp->rib[afi][safi];
9454 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
9455
9456 for (i = 0; i < BGP_STATS_MAX; i++) {
9457 if (!table_stats_strs[i])
9458 continue;
9459
9460 switch (i) {
9461 #if 0
9462 case BGP_STATS_ASPATH_AVGHOPS:
9463 case BGP_STATS_ASPATH_AVGSIZE:
9464 case BGP_STATS_AVGPLEN:
9465 vty_out (vty, "%-30s: ", table_stats_strs[i]);
9466 vty_out (vty, "%12.2f",
9467 (float)ts.counts[i] / (float)TALLY_SIGFIG);
9468 break;
9469 #endif
9470 case BGP_STATS_ASPATH_TOTHOPS:
9471 case BGP_STATS_ASPATH_TOTSIZE:
9472 vty_out(vty, "%-30s: ", table_stats_strs[i]);
9473 vty_out(vty, "%12.2f",
9474 ts.counts[i]
9475 ? (float)ts.counts[i]
9476 / (float)ts.counts
9477 [BGP_STATS_ASPATH_COUNT]
9478 : 0);
9479 break;
9480 case BGP_STATS_TOTPLEN:
9481 vty_out(vty, "%-30s: ", table_stats_strs[i]);
9482 vty_out(vty, "%12.2f",
9483 ts.counts[i]
9484 ? (float)ts.counts[i]
9485 / (float)ts.counts
9486 [BGP_STATS_PREFIXES]
9487 : 0);
9488 break;
9489 case BGP_STATS_SPACE:
9490 vty_out(vty, "%-30s: ", table_stats_strs[i]);
9491 vty_out(vty, "%12llu\n", ts.counts[i]);
9492 if (ts.counts[BGP_STATS_MAXBITLEN] < 9)
9493 break;
9494 vty_out(vty, "%30s: ", "%% announced ");
9495 vty_out(vty, "%12.2f\n",
9496 100 * (float)ts.counts[BGP_STATS_SPACE]
9497 / (float)((uint64_t)1UL
9498 << ts.counts
9499 [BGP_STATS_MAXBITLEN]));
9500 vty_out(vty, "%30s: ", "/8 equivalent ");
9501 vty_out(vty, "%12.2f\n",
9502 (float)ts.counts[BGP_STATS_SPACE]
9503 / (float)(1UL
9504 << (ts.counts
9505 [BGP_STATS_MAXBITLEN]
9506 - 8)));
9507 if (ts.counts[BGP_STATS_MAXBITLEN] < 25)
9508 break;
9509 vty_out(vty, "%30s: ", "/24 equivalent ");
9510 vty_out(vty, "%12.2f",
9511 (float)ts.counts[BGP_STATS_SPACE]
9512 / (float)(1UL
9513 << (ts.counts
9514 [BGP_STATS_MAXBITLEN]
9515 - 24)));
9516 break;
9517 default:
9518 vty_out(vty, "%-30s: ", table_stats_strs[i]);
9519 vty_out(vty, "%12llu", ts.counts[i]);
9520 }
9521
9522 vty_out(vty, "\n");
9523 }
9524 return CMD_SUCCESS;
9525 }
9526
9527 enum bgp_pcounts {
9528 PCOUNT_ADJ_IN = 0,
9529 PCOUNT_DAMPED,
9530 PCOUNT_REMOVED,
9531 PCOUNT_HISTORY,
9532 PCOUNT_STALE,
9533 PCOUNT_VALID,
9534 PCOUNT_ALL,
9535 PCOUNT_COUNTED,
9536 PCOUNT_PFCNT, /* the figure we display to users */
9537 PCOUNT_MAX,
9538 };
9539
9540 static const char *pcount_strs[] = {
9541 [PCOUNT_ADJ_IN] = "Adj-in",
9542 [PCOUNT_DAMPED] = "Damped",
9543 [PCOUNT_REMOVED] = "Removed",
9544 [PCOUNT_HISTORY] = "History",
9545 [PCOUNT_STALE] = "Stale",
9546 [PCOUNT_VALID] = "Valid",
9547 [PCOUNT_ALL] = "All RIB",
9548 [PCOUNT_COUNTED] = "PfxCt counted",
9549 [PCOUNT_PFCNT] = "Useable",
9550 [PCOUNT_MAX] = NULL,
9551 };
9552
9553 struct peer_pcounts {
9554 unsigned int count[PCOUNT_MAX];
9555 const struct peer *peer;
9556 const struct bgp_table *table;
9557 };
9558
9559 static int bgp_peer_count_walker(struct thread *t)
9560 {
9561 struct bgp_node *rn;
9562 struct peer_pcounts *pc = THREAD_ARG(t);
9563 const struct peer *peer = pc->peer;
9564
9565 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn)) {
9566 struct bgp_adj_in *ain;
9567 struct bgp_info *ri;
9568
9569 for (ain = rn->adj_in; ain; ain = ain->next)
9570 if (ain->peer == peer)
9571 pc->count[PCOUNT_ADJ_IN]++;
9572
9573 for (ri = rn->info; ri; ri = ri->next) {
9574 char buf[SU_ADDRSTRLEN];
9575
9576 if (ri->peer != peer)
9577 continue;
9578
9579 pc->count[PCOUNT_ALL]++;
9580
9581 if (CHECK_FLAG(ri->flags, BGP_INFO_DAMPED))
9582 pc->count[PCOUNT_DAMPED]++;
9583 if (CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
9584 pc->count[PCOUNT_HISTORY]++;
9585 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
9586 pc->count[PCOUNT_REMOVED]++;
9587 if (CHECK_FLAG(ri->flags, BGP_INFO_STALE))
9588 pc->count[PCOUNT_STALE]++;
9589 if (CHECK_FLAG(ri->flags, BGP_INFO_VALID))
9590 pc->count[PCOUNT_VALID]++;
9591 if (!CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
9592 pc->count[PCOUNT_PFCNT]++;
9593
9594 if (CHECK_FLAG(ri->flags, BGP_INFO_COUNTED)) {
9595 pc->count[PCOUNT_COUNTED]++;
9596 if (CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
9597 zlog_warn(
9598 "%s [pcount] %s/%d is counted but flags 0x%x",
9599 peer->host,
9600 inet_ntop(rn->p.family,
9601 &rn->p.u.prefix, buf,
9602 SU_ADDRSTRLEN),
9603 rn->p.prefixlen, ri->flags);
9604 } else {
9605 if (!CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
9606 zlog_warn(
9607 "%s [pcount] %s/%d not counted but flags 0x%x",
9608 peer->host,
9609 inet_ntop(rn->p.family,
9610 &rn->p.u.prefix, buf,
9611 SU_ADDRSTRLEN),
9612 rn->p.prefixlen, ri->flags);
9613 }
9614 }
9615 }
9616 return 0;
9617 }
9618
9619 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
9620 safi_t safi, u_char use_json)
9621 {
9622 struct peer_pcounts pcounts = {.peer = peer};
9623 unsigned int i;
9624 json_object *json = NULL;
9625 json_object *json_loop = NULL;
9626
9627 if (use_json) {
9628 json = json_object_new_object();
9629 json_loop = json_object_new_object();
9630 }
9631
9632 if (!peer || !peer->bgp || !peer->afc[afi][safi]
9633 || !peer->bgp->rib[afi][safi]) {
9634 if (use_json) {
9635 json_object_string_add(
9636 json, "warning",
9637 "No such neighbor or address family");
9638 vty_out(vty, "%s\n", json_object_to_json_string(json));
9639 json_object_free(json);
9640 } else
9641 vty_out(vty, "%% No such neighbor or address family\n");
9642
9643 return CMD_WARNING;
9644 }
9645
9646 memset(&pcounts, 0, sizeof(pcounts));
9647 pcounts.peer = peer;
9648 pcounts.table = peer->bgp->rib[afi][safi];
9649
9650 /* in-place call via thread subsystem so as to record execution time
9651 * * stats for the thread-walk (i.e. ensure this can't be blamed on
9652 * * on just vty_read()).
9653 * */
9654 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
9655
9656 if (use_json) {
9657 json_object_string_add(json, "prefixCountsFor", peer->host);
9658 json_object_string_add(json, "multiProtocol",
9659 afi_safi_print(afi, safi));
9660 json_object_int_add(json, "pfxCounter",
9661 peer->pcount[afi][safi]);
9662
9663 for (i = 0; i < PCOUNT_MAX; i++)
9664 json_object_int_add(json_loop, pcount_strs[i],
9665 pcounts.count[i]);
9666
9667 json_object_object_add(json, "ribTableWalkCounters", json_loop);
9668
9669 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
9670 json_object_string_add(json, "pfxctDriftFor",
9671 peer->host);
9672 json_object_string_add(
9673 json, "recommended",
9674 "Please report this bug, with the above command output");
9675 }
9676 vty_out(vty, "%s\n", json_object_to_json_string(json));
9677 json_object_free(json);
9678 } else {
9679
9680 if (peer->hostname
9681 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
9682 vty_out(vty, "Prefix counts for %s/%s, %s\n",
9683 peer->hostname, peer->host,
9684 afi_safi_print(afi, safi));
9685 } else {
9686 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
9687 afi_safi_print(afi, safi));
9688 }
9689
9690 vty_out(vty, "PfxCt: %ld\n", peer->pcount[afi][safi]);
9691 vty_out(vty, "\nCounts from RIB table walk:\n\n");
9692
9693 for (i = 0; i < PCOUNT_MAX; i++)
9694 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
9695 pcounts.count[i]);
9696
9697 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
9698 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
9699 vty_out(vty,
9700 "Please report this bug, with the above command output\n");
9701 }
9702 }
9703
9704 return CMD_SUCCESS;
9705 }
9706
9707 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
9708 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
9709 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] "
9710 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9711 SHOW_STR
9712 IP_STR
9713 BGP_STR
9714 BGP_INSTANCE_HELP_STR
9715 BGP_AFI_HELP_STR
9716 BGP_SAFI_HELP_STR
9717 "Detailed information on TCP and BGP neighbor connections\n"
9718 "Neighbor to display information about\n"
9719 "Neighbor to display information about\n"
9720 "Neighbor on BGP configured interface\n"
9721 "Display detailed prefix count information\n"
9722 JSON_STR)
9723 {
9724 afi_t afi = AFI_IP6;
9725 safi_t safi = SAFI_UNICAST;
9726 struct peer *peer;
9727 int idx = 0;
9728 struct bgp *bgp = NULL;
9729
9730 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9731 &bgp);
9732 if (!idx)
9733 return CMD_WARNING;
9734
9735 int uj = use_json(argc, argv);
9736 if (uj)
9737 argc--;
9738
9739 argv_find(argv, argc, "neighbors", &idx);
9740 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
9741 if (!peer)
9742 return CMD_WARNING;
9743
9744 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_UNICAST, uj);
9745 }
9746
9747 #ifdef KEEP_OLD_VPN_COMMANDS
9748 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
9749 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
9750 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9751 SHOW_STR
9752 IP_STR
9753 BGP_STR
9754 BGP_VPNVX_HELP_STR
9755 "Display information about all VPNv4 NLRIs\n"
9756 "Detailed information on TCP and BGP neighbor connections\n"
9757 "Neighbor to display information about\n"
9758 "Neighbor to display information about\n"
9759 "Neighbor on BGP configured interface\n"
9760 "Display detailed prefix count information\n"
9761 JSON_STR)
9762 {
9763 int idx_peer = 6;
9764 struct peer *peer;
9765 u_char uj = use_json(argc, argv);
9766
9767 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
9768 if (!peer)
9769 return CMD_WARNING;
9770
9771 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
9772 }
9773
9774 DEFUN (show_ip_bgp_vpn_all_route_prefix,
9775 show_ip_bgp_vpn_all_route_prefix_cmd,
9776 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9777 SHOW_STR
9778 IP_STR
9779 BGP_STR
9780 BGP_VPNVX_HELP_STR
9781 "Display information about all VPNv4 NLRIs\n"
9782 "Network in the BGP routing table to display\n"
9783 "Network in the BGP routing table to display\n"
9784 JSON_STR)
9785 {
9786 int idx = 0;
9787 char *network = NULL;
9788 struct bgp *bgp = bgp_get_default();
9789 if (!bgp) {
9790 vty_out(vty, "Can't find default instance\n");
9791 return CMD_WARNING;
9792 }
9793
9794 if (argv_find(argv, argc, "A.B.C.D", &idx))
9795 network = argv[idx]->arg;
9796 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
9797 network = argv[idx]->arg;
9798 else {
9799 vty_out(vty, "Unable to figure out Network\n");
9800 return CMD_WARNING;
9801 }
9802
9803 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
9804 BGP_PATH_ALL, use_json(argc, argv));
9805 }
9806 #endif /* KEEP_OLD_VPN_COMMANDS */
9807
9808 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix,
9809 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd,
9810 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
9811 SHOW_STR
9812 IP_STR
9813 BGP_STR
9814 L2VPN_HELP_STR
9815 EVPN_HELP_STR
9816 "Display information about all EVPN NLRIs\n"
9817 "Network in the BGP routing table to display\n"
9818 "Network in the BGP routing table to display\n"
9819 JSON_STR)
9820 {
9821 int idx = 0;
9822 char *network = NULL;
9823
9824 if (argv_find(argv, argc, "A.B.C.D", &idx))
9825 network = argv[idx]->arg;
9826 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
9827 network = argv[idx]->arg;
9828 else {
9829 vty_out(vty, "Unable to figure out Network\n");
9830 return CMD_WARNING;
9831 }
9832 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL, 0,
9833 BGP_PATH_ALL, use_json(argc, argv));
9834 }
9835
9836 static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
9837 safi_t safi, int in, const char *rmap_name,
9838 u_char use_json, json_object *json)
9839 {
9840 struct bgp_table *table;
9841 struct bgp_adj_in *ain;
9842 struct bgp_adj_out *adj;
9843 unsigned long output_count;
9844 unsigned long filtered_count;
9845 struct bgp_node *rn;
9846 int header1 = 1;
9847 struct bgp *bgp;
9848 int header2 = 1;
9849 struct attr attr;
9850 int ret;
9851 struct update_subgroup *subgrp;
9852 json_object *json_scode = NULL;
9853 json_object *json_ocode = NULL;
9854 json_object *json_ar = NULL;
9855 struct peer_af *paf;
9856
9857 if (use_json) {
9858 json_scode = json_object_new_object();
9859 json_ocode = json_object_new_object();
9860 json_ar = json_object_new_object();
9861
9862 json_object_string_add(json_scode, "suppressed", "s");
9863 json_object_string_add(json_scode, "damped", "d");
9864 json_object_string_add(json_scode, "history", "h");
9865 json_object_string_add(json_scode, "valid", "*");
9866 json_object_string_add(json_scode, "best", ">");
9867 json_object_string_add(json_scode, "multipath", "=");
9868 json_object_string_add(json_scode, "internal", "i");
9869 json_object_string_add(json_scode, "ribFailure", "r");
9870 json_object_string_add(json_scode, "stale", "S");
9871 json_object_string_add(json_scode, "removed", "R");
9872
9873 json_object_string_add(json_ocode, "igp", "i");
9874 json_object_string_add(json_ocode, "egp", "e");
9875 json_object_string_add(json_ocode, "incomplete", "?");
9876 }
9877
9878 bgp = peer->bgp;
9879
9880 if (!bgp) {
9881 if (use_json) {
9882 json_object_string_add(json, "alert", "no BGP");
9883 vty_out(vty, "%s\n", json_object_to_json_string(json));
9884 json_object_free(json);
9885 } else
9886 vty_out(vty, "%% No bgp\n");
9887 return;
9888 }
9889
9890 table = bgp->rib[afi][safi];
9891
9892 output_count = filtered_count = 0;
9893 subgrp = peer_subgroup(peer, afi, safi);
9894
9895 if (!in && subgrp
9896 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
9897 if (use_json) {
9898 json_object_int_add(json, "bgpTableVersion",
9899 table->version);
9900 json_object_string_add(json, "bgpLocalRouterId",
9901 inet_ntoa(bgp->router_id));
9902 json_object_object_add(json, "bgpStatusCodes",
9903 json_scode);
9904 json_object_object_add(json, "bgpOriginCodes",
9905 json_ocode);
9906 json_object_string_add(json,
9907 "bgpOriginatingDefaultNetwork",
9908 "0.0.0.0");
9909 } else {
9910 vty_out(vty, "BGP table version is %" PRIu64
9911 ", local router ID is %s\n",
9912 table->version, inet_ntoa(bgp->router_id));
9913 vty_out(vty, BGP_SHOW_SCODE_HEADER);
9914 vty_out(vty, BGP_SHOW_OCODE_HEADER);
9915
9916 vty_out(vty, "Originating default network 0.0.0.0\n\n");
9917 }
9918 header1 = 0;
9919 }
9920
9921 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
9922 if (in) {
9923 for (ain = rn->adj_in; ain; ain = ain->next) {
9924 if (ain->peer == peer) {
9925 if (header1) {
9926 if (use_json) {
9927 json_object_int_add(
9928 json,
9929 "bgpTableVersion",
9930 0);
9931 json_object_string_add(
9932 json,
9933 "bgpLocalRouterId",
9934 inet_ntoa(
9935 bgp->router_id));
9936 json_object_object_add(
9937 json,
9938 "bgpStatusCodes",
9939 json_scode);
9940 json_object_object_add(
9941 json,
9942 "bgpOriginCodes",
9943 json_ocode);
9944 } else {
9945 vty_out(vty,
9946 "BGP table version is 0, local router ID is %s\n",
9947 inet_ntoa(
9948 bgp->router_id));
9949 vty_out(vty,
9950 BGP_SHOW_SCODE_HEADER);
9951 vty_out(vty,
9952 BGP_SHOW_OCODE_HEADER);
9953 }
9954 header1 = 0;
9955 }
9956 if (header2) {
9957 if (!use_json)
9958 vty_out(vty,
9959 BGP_SHOW_HEADER);
9960 header2 = 0;
9961 }
9962 if (ain->attr) {
9963 bgp_attr_dup(&attr, ain->attr);
9964 if (bgp_input_modifier(
9965 peer, &rn->p, &attr,
9966 afi, safi,
9967 rmap_name)
9968 != RMAP_DENY) {
9969 route_vty_out_tmp(
9970 vty, &rn->p,
9971 &attr, safi,
9972 use_json,
9973 json_ar);
9974 output_count++;
9975 } else
9976 filtered_count++;
9977 }
9978 }
9979 }
9980 } else {
9981 for (adj = rn->adj_out; adj; adj = adj->next)
9982 SUBGRP_FOREACH_PEER(adj->subgroup, paf)
9983 if (paf->peer == peer) {
9984 if (header1) {
9985 if (use_json) {
9986 json_object_int_add(
9987 json, "bgpTableVersion",
9988 table->version);
9989 json_object_string_add(
9990 json,
9991 "bgpLocalRouterId",
9992 inet_ntoa(
9993 bgp->router_id));
9994 json_object_object_add(
9995 json, "bgpStatusCodes",
9996 json_scode);
9997 json_object_object_add(
9998 json, "bgpOriginCodes",
9999 json_ocode);
10000 } else {
10001 vty_out(vty,
10002 "BGP table version is %" PRIu64
10003 ", local router ID is %s\n",
10004 table->version,
10005 inet_ntoa(
10006 bgp->router_id));
10007 vty_out(vty,
10008 BGP_SHOW_SCODE_HEADER);
10009 vty_out(vty,
10010 BGP_SHOW_OCODE_HEADER);
10011 }
10012 header1 = 0;
10013 }
10014
10015 if (header2) {
10016 if (!use_json)
10017 vty_out(vty, BGP_SHOW_HEADER);
10018 header2 = 0;
10019 }
10020
10021 if (adj->attr) {
10022 bgp_attr_dup(&attr, adj->attr);
10023 ret = bgp_output_modifier(
10024 peer, &rn->p, &attr, afi, safi,
10025 rmap_name);
10026 if (ret != RMAP_DENY) {
10027 route_vty_out_tmp(vty, &rn->p,
10028 &attr, safi,
10029 use_json,
10030 json_ar);
10031 output_count++;
10032 } else
10033 filtered_count++;
10034 }
10035 }
10036 }
10037 }
10038 if (use_json)
10039 json_object_object_add(json, "advertisedRoutes", json_ar);
10040
10041 if (output_count != 0) {
10042 if (use_json)
10043 json_object_int_add(json, "totalPrefixCounter",
10044 output_count);
10045 else
10046 vty_out(vty, "\nTotal number of prefixes %ld\n",
10047 output_count);
10048 }
10049 if (use_json) {
10050 vty_out(vty, "%s\n", json_object_to_json_string(json));
10051 json_object_free(json);
10052 }
10053 }
10054
10055 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
10056 safi_t safi, int in, const char *rmap_name,
10057 u_char use_json)
10058 {
10059 json_object *json = NULL;
10060
10061 if (use_json)
10062 json = json_object_new_object();
10063
10064 /* labeled-unicast routes live in the unicast table */
10065 if (safi == SAFI_LABELED_UNICAST)
10066 safi = SAFI_UNICAST;
10067
10068 if (!peer || !peer->afc[afi][safi]) {
10069 if (use_json) {
10070 json_object_string_add(
10071 json, "warning",
10072 "No such neighbor or address family");
10073 vty_out(vty, "%s\n", json_object_to_json_string(json));
10074 json_object_free(json);
10075 } else
10076 vty_out(vty, "%% No such neighbor or address family\n");
10077
10078 return CMD_WARNING;
10079 }
10080
10081 if (in
10082 && !CHECK_FLAG(peer->af_flags[afi][safi],
10083 PEER_FLAG_SOFT_RECONFIG)) {
10084 if (use_json) {
10085 json_object_string_add(
10086 json, "warning",
10087 "Inbound soft reconfiguration not enabled");
10088 vty_out(vty, "%s\n", json_object_to_json_string(json));
10089 json_object_free(json);
10090 } else
10091 vty_out(vty,
10092 "%% Inbound soft reconfiguration not enabled\n");
10093
10094 return CMD_WARNING;
10095 }
10096
10097 show_adj_route(vty, peer, afi, safi, in, rmap_name, use_json, json);
10098
10099 return CMD_SUCCESS;
10100 }
10101
10102 DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
10103 show_ip_bgp_instance_neighbor_advertised_route_cmd,
10104 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
10105 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
10106 SHOW_STR
10107 IP_STR
10108 BGP_STR
10109 BGP_INSTANCE_HELP_STR
10110 BGP_AFI_HELP_STR
10111 BGP_SAFI_WITH_LABEL_HELP_STR
10112 "Detailed information on TCP and BGP neighbor connections\n"
10113 "Neighbor to display information about\n"
10114 "Neighbor to display information about\n"
10115 "Neighbor on BGP configured interface\n"
10116 "Display the received routes from neighbor\n"
10117 "Display the routes advertised to a BGP neighbor\n"
10118 "Route-map to modify the attributes\n"
10119 "Name of the route map\n"
10120 JSON_STR)
10121 {
10122 afi_t afi = AFI_IP6;
10123 safi_t safi = SAFI_UNICAST;
10124 char *rmap_name = NULL;
10125 char *peerstr = NULL;
10126 int rcvd = 0;
10127 struct bgp *bgp = NULL;
10128 struct peer *peer;
10129
10130 int idx = 0;
10131
10132 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10133 &bgp);
10134 if (!idx)
10135 return CMD_WARNING;
10136
10137 int uj = use_json(argc, argv);
10138 if (uj)
10139 argc--;
10140
10141 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10142 argv_find(argv, argc, "neighbors", &idx);
10143 peerstr = argv[++idx]->arg;
10144
10145 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
10146 if (!peer)
10147 return CMD_WARNING;
10148
10149 if (argv_find(argv, argc, "received-routes", &idx))
10150 rcvd = 1;
10151 if (argv_find(argv, argc, "advertised-routes", &idx))
10152 rcvd = 0;
10153 if (argv_find(argv, argc, "route-map", &idx))
10154 rmap_name = argv[++idx]->arg;
10155
10156 return peer_adj_routes(vty, peer, afi, safi, rcvd, rmap_name, uj);
10157 }
10158
10159 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
10160 show_ip_bgp_neighbor_received_prefix_filter_cmd,
10161 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
10162 SHOW_STR
10163 IP_STR
10164 BGP_STR
10165 "Address Family\n"
10166 "Address Family\n"
10167 "Address Family modifier\n"
10168 "Detailed information on TCP and BGP neighbor connections\n"
10169 "Neighbor to display information about\n"
10170 "Neighbor to display information about\n"
10171 "Neighbor on BGP configured interface\n"
10172 "Display information received from a BGP neighbor\n"
10173 "Display the prefixlist filter\n"
10174 JSON_STR)
10175 {
10176 afi_t afi = AFI_IP6;
10177 safi_t safi = SAFI_UNICAST;
10178 char *peerstr = NULL;
10179
10180 char name[BUFSIZ];
10181 union sockunion su;
10182 struct peer *peer;
10183 int count, ret;
10184
10185 int idx = 0;
10186
10187 /* show [ip] bgp */
10188 if (argv_find(argv, argc, "ip", &idx))
10189 afi = AFI_IP;
10190 /* [<ipv4|ipv6> [unicast]] */
10191 if (argv_find(argv, argc, "ipv4", &idx))
10192 afi = AFI_IP;
10193 if (argv_find(argv, argc, "ipv6", &idx))
10194 afi = AFI_IP6;
10195 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10196 argv_find(argv, argc, "neighbors", &idx);
10197 peerstr = argv[++idx]->arg;
10198
10199 u_char uj = use_json(argc, argv);
10200
10201 ret = str2sockunion(peerstr, &su);
10202 if (ret < 0) {
10203 peer = peer_lookup_by_conf_if(NULL, peerstr);
10204 if (!peer) {
10205 if (uj)
10206 vty_out(vty, "{}\n");
10207 else
10208 vty_out(vty,
10209 "%% Malformed address or name: %s\n",
10210 peerstr);
10211 return CMD_WARNING;
10212 }
10213 } else {
10214 peer = peer_lookup(NULL, &su);
10215 if (!peer) {
10216 if (uj)
10217 vty_out(vty, "{}\n");
10218 else
10219 vty_out(vty, "No peer\n");
10220 return CMD_WARNING;
10221 }
10222 }
10223
10224 sprintf(name, "%s.%d.%d", peer->host, afi, safi);
10225 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
10226 if (count) {
10227 if (!uj)
10228 vty_out(vty, "Address Family: %s\n",
10229 afi_safi_print(afi, safi));
10230 prefix_bgp_show_prefix_list(vty, afi, name, uj);
10231 } else {
10232 if (uj)
10233 vty_out(vty, "{}\n");
10234 else
10235 vty_out(vty, "No functional output\n");
10236 }
10237
10238 return CMD_SUCCESS;
10239 }
10240
10241 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
10242 afi_t afi, safi_t safi,
10243 enum bgp_show_type type, u_char use_json)
10244 {
10245 /* labeled-unicast routes live in the unicast table */
10246 if (safi == SAFI_LABELED_UNICAST)
10247 safi = SAFI_UNICAST;
10248
10249 if (!peer || !peer->afc[afi][safi]) {
10250 if (use_json) {
10251 json_object *json_no = NULL;
10252 json_no = json_object_new_object();
10253 json_object_string_add(
10254 json_no, "warning",
10255 "No such neighbor or address family");
10256 vty_out(vty, "%s\n",
10257 json_object_to_json_string(json_no));
10258 json_object_free(json_no);
10259 } else
10260 vty_out(vty, "%% No such neighbor or address family\n");
10261 return CMD_WARNING;
10262 }
10263
10264 /* labeled-unicast routes live in the unicast table */
10265 if (safi == SAFI_LABELED_UNICAST)
10266 safi = SAFI_UNICAST;
10267
10268 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, use_json);
10269 }
10270
10271 DEFUN (show_ip_bgp_neighbor_routes,
10272 show_ip_bgp_neighbor_routes_cmd,
10273 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
10274 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
10275 SHOW_STR
10276 IP_STR
10277 BGP_STR
10278 BGP_INSTANCE_HELP_STR
10279 BGP_AFI_HELP_STR
10280 BGP_SAFI_WITH_LABEL_HELP_STR
10281 "Detailed information on TCP and BGP neighbor connections\n"
10282 "Neighbor to display information about\n"
10283 "Neighbor to display information about\n"
10284 "Neighbor on BGP configured interface\n"
10285 "Display flap statistics of the routes learned from neighbor\n"
10286 "Display the dampened routes received from neighbor\n"
10287 "Display routes learned from neighbor\n"
10288 JSON_STR)
10289 {
10290 char *peerstr = NULL;
10291 struct bgp *bgp = NULL;
10292 afi_t afi = AFI_IP6;
10293 safi_t safi = SAFI_UNICAST;
10294 struct peer *peer;
10295 enum bgp_show_type sh_type = bgp_show_type_neighbor;
10296
10297 int idx = 0;
10298
10299 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10300 &bgp);
10301 if (!idx)
10302 return CMD_WARNING;
10303
10304 int uj = use_json(argc, argv);
10305 if (uj)
10306 argc--;
10307
10308 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10309 argv_find(argv, argc, "neighbors", &idx);
10310 peerstr = argv[++idx]->arg;
10311
10312 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
10313 if (!peer) {
10314 vty_out(vty, "No such neighbor\n");
10315 return CMD_WARNING;
10316 }
10317
10318 if (argv_find(argv, argc, "flap-statistics", &idx))
10319 sh_type = bgp_show_type_flap_neighbor;
10320 else if (argv_find(argv, argc, "dampened-routes", &idx))
10321 sh_type = bgp_show_type_damp_neighbor;
10322 else if (argv_find(argv, argc, "routes", &idx))
10323 sh_type = bgp_show_type_neighbor;
10324
10325 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
10326 }
10327
10328 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
10329
10330 struct bgp_distance {
10331 /* Distance value for the IP source prefix. */
10332 u_char distance;
10333
10334 /* Name of the access-list to be matched. */
10335 char *access_list;
10336 };
10337
10338 DEFUN (show_bgp_afi_vpn_rd_route,
10339 show_bgp_afi_vpn_rd_route_cmd,
10340 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:nn_or_IP-address:nn <A.B.C.D/M|X:X::X:X/M> [json]",
10341 SHOW_STR
10342 BGP_STR
10343 BGP_AFI_HELP_STR
10344 "Address Family modifier\n"
10345 "Display information for a route distinguisher\n"
10346 "Route Distinguisher\n"
10347 "Network in the BGP routing table to display\n"
10348 "Network in the BGP routing table to display\n"
10349 JSON_STR)
10350 {
10351 int ret;
10352 struct prefix_rd prd;
10353 afi_t afi = AFI_MAX;
10354 int idx = 0;
10355
10356 argv_find_and_parse_afi(argv, argc, &idx, &afi);
10357 ret = str2prefix_rd(argv[5]->arg, &prd);
10358 if (!ret) {
10359 vty_out(vty, "%% Malformed Route Distinguisher\n");
10360 return CMD_WARNING;
10361 }
10362 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
10363 0, BGP_PATH_ALL, use_json(argc, argv));
10364 }
10365
10366 static struct bgp_distance *bgp_distance_new(void)
10367 {
10368 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
10369 }
10370
10371 static void bgp_distance_free(struct bgp_distance *bdistance)
10372 {
10373 XFREE(MTYPE_BGP_DISTANCE, bdistance);
10374 }
10375
10376 static int bgp_distance_set(struct vty *vty, const char *distance_str,
10377 const char *ip_str, const char *access_list_str)
10378 {
10379 int ret;
10380 afi_t afi;
10381 safi_t safi;
10382 struct prefix p;
10383 u_char distance;
10384 struct bgp_node *rn;
10385 struct bgp_distance *bdistance;
10386
10387 afi = bgp_node_afi(vty);
10388 safi = bgp_node_safi(vty);
10389
10390 ret = str2prefix(ip_str, &p);
10391 if (ret == 0) {
10392 vty_out(vty, "Malformed prefix\n");
10393 return CMD_WARNING_CONFIG_FAILED;
10394 }
10395
10396 distance = atoi(distance_str);
10397
10398 /* Get BGP distance node. */
10399 rn = bgp_node_get(bgp_distance_table[afi][safi], (struct prefix *)&p);
10400 if (rn->info) {
10401 bdistance = rn->info;
10402 bgp_unlock_node(rn);
10403 } else {
10404 bdistance = bgp_distance_new();
10405 rn->info = bdistance;
10406 }
10407
10408 /* Set distance value. */
10409 bdistance->distance = distance;
10410
10411 /* Reset access-list configuration. */
10412 if (bdistance->access_list) {
10413 XFREE(MTYPE_AS_LIST, bdistance->access_list);
10414 bdistance->access_list = NULL;
10415 }
10416 if (access_list_str)
10417 bdistance->access_list =
10418 XSTRDUP(MTYPE_AS_LIST, access_list_str);
10419
10420 return CMD_SUCCESS;
10421 }
10422
10423 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
10424 const char *ip_str, const char *access_list_str)
10425 {
10426 int ret;
10427 afi_t afi;
10428 safi_t safi;
10429 struct prefix p;
10430 int distance;
10431 struct bgp_node *rn;
10432 struct bgp_distance *bdistance;
10433
10434 afi = bgp_node_afi(vty);
10435 safi = bgp_node_safi(vty);
10436
10437 ret = str2prefix(ip_str, &p);
10438 if (ret == 0) {
10439 vty_out(vty, "Malformed prefix\n");
10440 return CMD_WARNING_CONFIG_FAILED;
10441 }
10442
10443 rn = bgp_node_lookup(bgp_distance_table[afi][safi],
10444 (struct prefix *)&p);
10445 if (!rn) {
10446 vty_out(vty, "Can't find specified prefix\n");
10447 return CMD_WARNING_CONFIG_FAILED;
10448 }
10449
10450 bdistance = rn->info;
10451 distance = atoi(distance_str);
10452
10453 if (bdistance->distance != distance) {
10454 vty_out(vty, "Distance does not match configured\n");
10455 return CMD_WARNING_CONFIG_FAILED;
10456 }
10457
10458 if (bdistance->access_list)
10459 XFREE(MTYPE_AS_LIST, bdistance->access_list);
10460 bgp_distance_free(bdistance);
10461
10462 rn->info = NULL;
10463 bgp_unlock_node(rn);
10464 bgp_unlock_node(rn);
10465
10466 return CMD_SUCCESS;
10467 }
10468
10469 /* Apply BGP information to distance method. */
10470 u_char bgp_distance_apply(struct prefix *p, struct bgp_info *rinfo, afi_t afi,
10471 safi_t safi, struct bgp *bgp)
10472 {
10473 struct bgp_node *rn;
10474 struct prefix q;
10475 struct peer *peer;
10476 struct bgp_distance *bdistance;
10477 struct access_list *alist;
10478 struct bgp_static *bgp_static;
10479
10480 if (!bgp)
10481 return 0;
10482
10483 peer = rinfo->peer;
10484
10485 /* Check source address. */
10486 sockunion2hostprefix(&peer->su, &q);
10487 rn = bgp_node_match(bgp_distance_table[afi][safi], &q);
10488 if (rn) {
10489 bdistance = rn->info;
10490 bgp_unlock_node(rn);
10491
10492 if (bdistance->access_list) {
10493 alist = access_list_lookup(afi, bdistance->access_list);
10494 if (alist
10495 && access_list_apply(alist, p) == FILTER_PERMIT)
10496 return bdistance->distance;
10497 } else
10498 return bdistance->distance;
10499 }
10500
10501 /* Backdoor check. */
10502 rn = bgp_node_lookup(bgp->route[afi][safi], p);
10503 if (rn) {
10504 bgp_static = rn->info;
10505 bgp_unlock_node(rn);
10506
10507 if (bgp_static->backdoor) {
10508 if (bgp->distance_local[afi][safi])
10509 return bgp->distance_local[afi][safi];
10510 else
10511 return ZEBRA_IBGP_DISTANCE_DEFAULT;
10512 }
10513 }
10514
10515 if (peer->sort == BGP_PEER_EBGP) {
10516 if (bgp->distance_ebgp[afi][safi])
10517 return bgp->distance_ebgp[afi][safi];
10518 return ZEBRA_EBGP_DISTANCE_DEFAULT;
10519 } else {
10520 if (bgp->distance_ibgp[afi][safi])
10521 return bgp->distance_ibgp[afi][safi];
10522 return ZEBRA_IBGP_DISTANCE_DEFAULT;
10523 }
10524 }
10525
10526 DEFUN (bgp_distance,
10527 bgp_distance_cmd,
10528 "distance bgp (1-255) (1-255) (1-255)",
10529 "Define an administrative distance\n"
10530 "BGP distance\n"
10531 "Distance for routes external to the AS\n"
10532 "Distance for routes internal to the AS\n"
10533 "Distance for local routes\n")
10534 {
10535 VTY_DECLVAR_CONTEXT(bgp, bgp);
10536 int idx_number = 2;
10537 int idx_number_2 = 3;
10538 int idx_number_3 = 4;
10539 afi_t afi;
10540 safi_t safi;
10541
10542 afi = bgp_node_afi(vty);
10543 safi = bgp_node_safi(vty);
10544
10545 bgp->distance_ebgp[afi][safi] = atoi(argv[idx_number]->arg);
10546 bgp->distance_ibgp[afi][safi] = atoi(argv[idx_number_2]->arg);
10547 bgp->distance_local[afi][safi] = atoi(argv[idx_number_3]->arg);
10548 return CMD_SUCCESS;
10549 }
10550
10551 DEFUN (no_bgp_distance,
10552 no_bgp_distance_cmd,
10553 "no distance bgp [(1-255) (1-255) (1-255)]",
10554 NO_STR
10555 "Define an administrative distance\n"
10556 "BGP distance\n"
10557 "Distance for routes external to the AS\n"
10558 "Distance for routes internal to the AS\n"
10559 "Distance for local routes\n")
10560 {
10561 VTY_DECLVAR_CONTEXT(bgp, bgp);
10562 afi_t afi;
10563 safi_t safi;
10564
10565 afi = bgp_node_afi(vty);
10566 safi = bgp_node_safi(vty);
10567
10568 bgp->distance_ebgp[afi][safi] = 0;
10569 bgp->distance_ibgp[afi][safi] = 0;
10570 bgp->distance_local[afi][safi] = 0;
10571 return CMD_SUCCESS;
10572 }
10573
10574
10575 DEFUN (bgp_distance_source,
10576 bgp_distance_source_cmd,
10577 "distance (1-255) A.B.C.D/M",
10578 "Define an administrative distance\n"
10579 "Administrative distance\n"
10580 "IP source prefix\n")
10581 {
10582 int idx_number = 1;
10583 int idx_ipv4_prefixlen = 2;
10584 bgp_distance_set(vty, argv[idx_number]->arg,
10585 argv[idx_ipv4_prefixlen]->arg, NULL);
10586 return CMD_SUCCESS;
10587 }
10588
10589 DEFUN (no_bgp_distance_source,
10590 no_bgp_distance_source_cmd,
10591 "no distance (1-255) A.B.C.D/M",
10592 NO_STR
10593 "Define an administrative distance\n"
10594 "Administrative distance\n"
10595 "IP source prefix\n")
10596 {
10597 int idx_number = 2;
10598 int idx_ipv4_prefixlen = 3;
10599 bgp_distance_unset(vty, argv[idx_number]->arg,
10600 argv[idx_ipv4_prefixlen]->arg, NULL);
10601 return CMD_SUCCESS;
10602 }
10603
10604 DEFUN (bgp_distance_source_access_list,
10605 bgp_distance_source_access_list_cmd,
10606 "distance (1-255) A.B.C.D/M WORD",
10607 "Define an administrative distance\n"
10608 "Administrative distance\n"
10609 "IP source prefix\n"
10610 "Access list name\n")
10611 {
10612 int idx_number = 1;
10613 int idx_ipv4_prefixlen = 2;
10614 int idx_word = 3;
10615 bgp_distance_set(vty, argv[idx_number]->arg,
10616 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
10617 return CMD_SUCCESS;
10618 }
10619
10620 DEFUN (no_bgp_distance_source_access_list,
10621 no_bgp_distance_source_access_list_cmd,
10622 "no distance (1-255) A.B.C.D/M WORD",
10623 NO_STR
10624 "Define an administrative distance\n"
10625 "Administrative distance\n"
10626 "IP source prefix\n"
10627 "Access list name\n")
10628 {
10629 int idx_number = 2;
10630 int idx_ipv4_prefixlen = 3;
10631 int idx_word = 4;
10632 bgp_distance_unset(vty, argv[idx_number]->arg,
10633 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
10634 return CMD_SUCCESS;
10635 }
10636
10637 DEFUN (ipv6_bgp_distance_source,
10638 ipv6_bgp_distance_source_cmd,
10639 "distance (1-255) X:X::X:X/M",
10640 "Define an administrative distance\n"
10641 "Administrative distance\n"
10642 "IP source prefix\n")
10643 {
10644 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
10645 return CMD_SUCCESS;
10646 }
10647
10648 DEFUN (no_ipv6_bgp_distance_source,
10649 no_ipv6_bgp_distance_source_cmd,
10650 "no distance (1-255) X:X::X:X/M",
10651 NO_STR
10652 "Define an administrative distance\n"
10653 "Administrative distance\n"
10654 "IP source prefix\n")
10655 {
10656 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
10657 return CMD_SUCCESS;
10658 }
10659
10660 DEFUN (ipv6_bgp_distance_source_access_list,
10661 ipv6_bgp_distance_source_access_list_cmd,
10662 "distance (1-255) X:X::X:X/M WORD",
10663 "Define an administrative distance\n"
10664 "Administrative distance\n"
10665 "IP source prefix\n"
10666 "Access list name\n")
10667 {
10668 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
10669 return CMD_SUCCESS;
10670 }
10671
10672 DEFUN (no_ipv6_bgp_distance_source_access_list,
10673 no_ipv6_bgp_distance_source_access_list_cmd,
10674 "no distance (1-255) X:X::X:X/M WORD",
10675 NO_STR
10676 "Define an administrative distance\n"
10677 "Administrative distance\n"
10678 "IP source prefix\n"
10679 "Access list name\n")
10680 {
10681 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
10682 return CMD_SUCCESS;
10683 }
10684
10685 DEFUN (bgp_damp_set,
10686 bgp_damp_set_cmd,
10687 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10688 "BGP Specific commands\n"
10689 "Enable route-flap dampening\n"
10690 "Half-life time for the penalty\n"
10691 "Value to start reusing a route\n"
10692 "Value to start suppressing a route\n"
10693 "Maximum duration to suppress a stable route\n")
10694 {
10695 VTY_DECLVAR_CONTEXT(bgp, bgp);
10696 int idx_half_life = 2;
10697 int idx_reuse = 3;
10698 int idx_suppress = 4;
10699 int idx_max_suppress = 5;
10700 int half = DEFAULT_HALF_LIFE * 60;
10701 int reuse = DEFAULT_REUSE;
10702 int suppress = DEFAULT_SUPPRESS;
10703 int max = 4 * half;
10704
10705 if (argc == 6) {
10706 half = atoi(argv[idx_half_life]->arg) * 60;
10707 reuse = atoi(argv[idx_reuse]->arg);
10708 suppress = atoi(argv[idx_suppress]->arg);
10709 max = atoi(argv[idx_max_suppress]->arg) * 60;
10710 } else if (argc == 3) {
10711 half = atoi(argv[idx_half_life]->arg) * 60;
10712 max = 4 * half;
10713 }
10714
10715 if (suppress < reuse) {
10716 vty_out(vty,
10717 "Suppress value cannot be less than reuse value \n");
10718 return 0;
10719 }
10720
10721 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
10722 reuse, suppress, max);
10723 }
10724
10725 DEFUN (bgp_damp_unset,
10726 bgp_damp_unset_cmd,
10727 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10728 NO_STR
10729 "BGP Specific commands\n"
10730 "Enable route-flap dampening\n"
10731 "Half-life time for the penalty\n"
10732 "Value to start reusing a route\n"
10733 "Value to start suppressing a route\n"
10734 "Maximum duration to suppress a stable route\n")
10735 {
10736 VTY_DECLVAR_CONTEXT(bgp, bgp);
10737 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
10738 }
10739
10740 /* Display specified route of BGP table. */
10741 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
10742 const char *ip_str, afi_t afi, safi_t safi,
10743 struct prefix_rd *prd, int prefix_check)
10744 {
10745 int ret;
10746 struct prefix match;
10747 struct bgp_node *rn;
10748 struct bgp_node *rm;
10749 struct bgp_info *ri;
10750 struct bgp_info *ri_temp;
10751 struct bgp *bgp;
10752 struct bgp_table *table;
10753
10754 /* BGP structure lookup. */
10755 if (view_name) {
10756 bgp = bgp_lookup_by_name(view_name);
10757 if (bgp == NULL) {
10758 vty_out(vty, "%% Can't find BGP instance %s\n",
10759 view_name);
10760 return CMD_WARNING;
10761 }
10762 } else {
10763 bgp = bgp_get_default();
10764 if (bgp == NULL) {
10765 vty_out(vty, "%% No BGP process is configured\n");
10766 return CMD_WARNING;
10767 }
10768 }
10769
10770 /* Check IP address argument. */
10771 ret = str2prefix(ip_str, &match);
10772 if (!ret) {
10773 vty_out(vty, "%% address is malformed\n");
10774 return CMD_WARNING;
10775 }
10776
10777 match.family = afi2family(afi);
10778
10779 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
10780 || (safi == SAFI_EVPN)) {
10781 for (rn = bgp_table_top(bgp->rib[AFI_IP][safi]); rn;
10782 rn = bgp_route_next(rn)) {
10783 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
10784 continue;
10785
10786 if ((table = rn->info) != NULL)
10787 if ((rm = bgp_node_match(table, &match))
10788 != NULL) {
10789 if (!prefix_check
10790 || rm->p.prefixlen
10791 == match.prefixlen) {
10792 ri = rm->info;
10793 while (ri) {
10794 if (ri->extra
10795 && ri->extra
10796 ->damp_info) {
10797 ri_temp =
10798 ri->next;
10799 bgp_damp_info_free(
10800 ri->extra
10801 ->damp_info,
10802 1);
10803 ri = ri_temp;
10804 } else
10805 ri = ri->next;
10806 }
10807 }
10808
10809 bgp_unlock_node(rm);
10810 }
10811 }
10812 } else {
10813 if ((rn = bgp_node_match(bgp->rib[afi][safi], &match))
10814 != NULL) {
10815 if (!prefix_check
10816 || rn->p.prefixlen == match.prefixlen) {
10817 ri = rn->info;
10818 while (ri) {
10819 if (ri->extra && ri->extra->damp_info) {
10820 ri_temp = ri->next;
10821 bgp_damp_info_free(
10822 ri->extra->damp_info,
10823 1);
10824 ri = ri_temp;
10825 } else
10826 ri = ri->next;
10827 }
10828 }
10829
10830 bgp_unlock_node(rn);
10831 }
10832 }
10833
10834 return CMD_SUCCESS;
10835 }
10836
10837 DEFUN (clear_ip_bgp_dampening,
10838 clear_ip_bgp_dampening_cmd,
10839 "clear ip bgp dampening",
10840 CLEAR_STR
10841 IP_STR
10842 BGP_STR
10843 "Clear route flap dampening information\n")
10844 {
10845 bgp_damp_info_clean();
10846 return CMD_SUCCESS;
10847 }
10848
10849 DEFUN (clear_ip_bgp_dampening_prefix,
10850 clear_ip_bgp_dampening_prefix_cmd,
10851 "clear ip bgp dampening A.B.C.D/M",
10852 CLEAR_STR
10853 IP_STR
10854 BGP_STR
10855 "Clear route flap dampening information\n"
10856 "IPv4 prefix\n")
10857 {
10858 int idx_ipv4_prefixlen = 4;
10859 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
10860 AFI_IP, SAFI_UNICAST, NULL, 1);
10861 }
10862
10863 DEFUN (clear_ip_bgp_dampening_address,
10864 clear_ip_bgp_dampening_address_cmd,
10865 "clear ip bgp dampening A.B.C.D",
10866 CLEAR_STR
10867 IP_STR
10868 BGP_STR
10869 "Clear route flap dampening information\n"
10870 "Network to clear damping information\n")
10871 {
10872 int idx_ipv4 = 4;
10873 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
10874 SAFI_UNICAST, NULL, 0);
10875 }
10876
10877 DEFUN (clear_ip_bgp_dampening_address_mask,
10878 clear_ip_bgp_dampening_address_mask_cmd,
10879 "clear ip bgp dampening A.B.C.D A.B.C.D",
10880 CLEAR_STR
10881 IP_STR
10882 BGP_STR
10883 "Clear route flap dampening information\n"
10884 "Network to clear damping information\n"
10885 "Network mask\n")
10886 {
10887 int idx_ipv4 = 4;
10888 int idx_ipv4_2 = 5;
10889 int ret;
10890 char prefix_str[BUFSIZ];
10891
10892 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
10893 prefix_str);
10894 if (!ret) {
10895 vty_out(vty, "%% Inconsistent address and mask\n");
10896 return CMD_WARNING;
10897 }
10898
10899 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
10900 NULL, 0);
10901 }
10902
10903 /* also used for encap safi */
10904 static int bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
10905 afi_t afi, safi_t safi, int *write)
10906 {
10907 struct bgp_node *prn;
10908 struct bgp_node *rn;
10909 struct bgp_table *table;
10910 struct prefix *p;
10911 struct prefix_rd *prd;
10912 struct bgp_static *bgp_static;
10913 mpls_label_t label;
10914 char buf[SU_ADDRSTRLEN];
10915 char rdbuf[RD_ADDRSTRLEN];
10916
10917 /* Network configuration. */
10918 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
10919 prn = bgp_route_next(prn))
10920 if ((table = prn->info) != NULL)
10921 for (rn = bgp_table_top(table); rn;
10922 rn = bgp_route_next(rn))
10923 if ((bgp_static = rn->info) != NULL) {
10924 p = &rn->p;
10925 prd = (struct prefix_rd *)&prn->p;
10926
10927 /* "address-family" display. */
10928 bgp_config_write_family_header(
10929 vty, afi, safi, write);
10930
10931 /* "network" configuration display. */
10932 prefix_rd2str(prd, rdbuf,
10933 RD_ADDRSTRLEN);
10934 label = decode_label(
10935 &bgp_static->label);
10936
10937 vty_out(vty, " network %s/%d rd %s",
10938 inet_ntop(p->family,
10939 &p->u.prefix, buf,
10940 SU_ADDRSTRLEN),
10941 p->prefixlen, rdbuf);
10942 if (safi == SAFI_MPLS_VPN)
10943 vty_out(vty, " label %u",
10944 label);
10945
10946 if (bgp_static->rmap.name)
10947 vty_out(vty, " route-map %s",
10948 bgp_static->rmap.name);
10949 else {
10950 if (bgp_static->backdoor)
10951 vty_out(vty,
10952 " backdoor");
10953 }
10954 vty_out(vty, "\n");
10955 }
10956 return 0;
10957 }
10958
10959 static int bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
10960 afi_t afi, safi_t safi, int *write)
10961 {
10962 struct bgp_node *prn;
10963 struct bgp_node *rn;
10964 struct bgp_table *table;
10965 struct prefix *p;
10966 struct prefix_rd *prd;
10967 struct bgp_static *bgp_static;
10968 char buf[PREFIX_STRLEN];
10969 char buf2[SU_ADDRSTRLEN];
10970 char rdbuf[RD_ADDRSTRLEN];
10971
10972 /* Network configuration. */
10973 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
10974 prn = bgp_route_next(prn))
10975 if ((table = prn->info) != NULL)
10976 for (rn = bgp_table_top(table); rn;
10977 rn = bgp_route_next(rn))
10978 if ((bgp_static = rn->info) != NULL) {
10979 char *macrouter = NULL;
10980 char *esi = NULL;
10981
10982 if (bgp_static->router_mac)
10983 macrouter = prefix_mac2str(
10984 bgp_static->router_mac,
10985 NULL, 0);
10986 if (bgp_static->eth_s_id)
10987 esi = esi2str(
10988 bgp_static->eth_s_id);
10989 p = &rn->p;
10990 prd = (struct prefix_rd *)&prn->p;
10991
10992 /* "address-family" display. */
10993 bgp_config_write_family_header(
10994 vty, afi, safi, write);
10995
10996 /* "network" configuration display. */
10997 prefix_rd2str(prd, rdbuf,
10998 RD_ADDRSTRLEN);
10999
11000 inet_ntop(AF_INET,
11001 &bgp_static->igpnexthop, buf2,
11002 SU_ADDRSTRLEN);
11003
11004 prefix2str(p, buf, sizeof(buf)),
11005 vty_out(vty,
11006 " network %s rd %s ethtag %u tag %u esi %s gwip %s routermac %s",
11007 buf, rdbuf,
11008 p->u.prefix_evpn
11009 .eth_tag,
11010 decode_label(
11011 &bgp_static
11012 ->label),
11013 esi, buf2, macrouter);
11014 vty_out(vty, "\n");
11015 if (macrouter)
11016 XFREE(MTYPE_TMP, macrouter);
11017 if (esi)
11018 XFREE(MTYPE_TMP, esi);
11019 }
11020 return 0;
11021 }
11022
11023 /* Configuration of static route announcement and aggregate
11024 information. */
11025 int bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
11026 safi_t safi, int *write)
11027 {
11028 struct bgp_node *rn;
11029 struct prefix *p;
11030 struct bgp_static *bgp_static;
11031 struct bgp_aggregate *bgp_aggregate;
11032 char buf[SU_ADDRSTRLEN];
11033
11034 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
11035 return bgp_config_write_network_vpn(vty, bgp, afi, safi, write);
11036
11037 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
11038 return bgp_config_write_network_evpn(vty, bgp, afi, safi,
11039 write);
11040
11041 /* Network configuration. */
11042 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
11043 rn = bgp_route_next(rn))
11044 if ((bgp_static = rn->info) != NULL) {
11045 p = &rn->p;
11046
11047 /* "address-family" display. */
11048 bgp_config_write_family_header(vty, afi, safi, write);
11049
11050 /* "network" configuration display. */
11051 if (bgp_option_check(BGP_OPT_CONFIG_CISCO)
11052 && afi == AFI_IP) {
11053 u_int32_t destination;
11054 struct in_addr netmask;
11055
11056 destination = ntohl(p->u.prefix4.s_addr);
11057 masklen2ip(p->prefixlen, &netmask);
11058 vty_out(vty, " network %s",
11059 inet_ntop(p->family, &p->u.prefix, buf,
11060 SU_ADDRSTRLEN));
11061
11062 if ((IN_CLASSC(destination)
11063 && p->prefixlen == 24)
11064 || (IN_CLASSB(destination)
11065 && p->prefixlen == 16)
11066 || (IN_CLASSA(destination)
11067 && p->prefixlen == 8)
11068 || p->u.prefix4.s_addr == 0) {
11069 /* Natural mask is not display. */
11070 } else
11071 vty_out(vty, " mask %s",
11072 inet_ntoa(netmask));
11073 } else {
11074 vty_out(vty, " network %s/%d",
11075 inet_ntop(p->family, &p->u.prefix, buf,
11076 SU_ADDRSTRLEN),
11077 p->prefixlen);
11078 }
11079
11080 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
11081 vty_out(vty, " label-index %u",
11082 bgp_static->label_index);
11083
11084 if (bgp_static->rmap.name)
11085 vty_out(vty, " route-map %s",
11086 bgp_static->rmap.name);
11087 else {
11088 if (bgp_static->backdoor)
11089 vty_out(vty, " backdoor");
11090 }
11091
11092 vty_out(vty, "\n");
11093 }
11094
11095 /* Aggregate-address configuration. */
11096 for (rn = bgp_table_top(bgp->aggregate[afi][safi]); rn;
11097 rn = bgp_route_next(rn))
11098 if ((bgp_aggregate = rn->info) != NULL) {
11099 p = &rn->p;
11100
11101 /* "address-family" display. */
11102 bgp_config_write_family_header(vty, afi, safi, write);
11103
11104 if (bgp_option_check(BGP_OPT_CONFIG_CISCO)
11105 && afi == AFI_IP) {
11106 struct in_addr netmask;
11107
11108 masklen2ip(p->prefixlen, &netmask);
11109 vty_out(vty, " aggregate-address %s %s",
11110 inet_ntop(p->family, &p->u.prefix, buf,
11111 SU_ADDRSTRLEN),
11112 inet_ntoa(netmask));
11113 } else {
11114 vty_out(vty, " aggregate-address %s/%d",
11115 inet_ntop(p->family, &p->u.prefix, buf,
11116 SU_ADDRSTRLEN),
11117 p->prefixlen);
11118 }
11119
11120 if (bgp_aggregate->as_set)
11121 vty_out(vty, " as-set");
11122
11123 if (bgp_aggregate->summary_only)
11124 vty_out(vty, " summary-only");
11125
11126 vty_out(vty, "\n");
11127 }
11128
11129 return 0;
11130 }
11131
11132 int bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
11133 safi_t safi, int *write)
11134 {
11135 struct bgp_node *rn;
11136 struct bgp_distance *bdistance;
11137
11138 /* Distance configuration. */
11139 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
11140 && bgp->distance_local[afi][safi]
11141 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
11142 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
11143 || bgp->distance_local[afi][safi]
11144 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
11145 bgp_config_write_family_header(vty, afi, safi, write);
11146 vty_out(vty, " distance bgp %d %d %d\n",
11147 bgp->distance_ebgp[afi][safi],
11148 bgp->distance_ibgp[afi][safi],
11149 bgp->distance_local[afi][safi]);
11150 }
11151
11152 for (rn = bgp_table_top(bgp_distance_table[afi][safi]); rn;
11153 rn = bgp_route_next(rn))
11154 if ((bdistance = rn->info) != NULL) {
11155 char buf[PREFIX_STRLEN];
11156
11157 bgp_config_write_family_header(vty, afi, safi, write);
11158 vty_out(vty, " distance %d %s %s\n",
11159 bdistance->distance,
11160 prefix2str(&rn->p, buf, sizeof(buf)),
11161 bdistance->access_list ? bdistance->access_list
11162 : "");
11163 }
11164
11165 return *write;
11166 }
11167
11168 /* Allocate routing table structure and install commands. */
11169 void bgp_route_init(void)
11170 {
11171 afi_t afi;
11172 safi_t safi;
11173
11174 /* Init BGP distance table. */
11175 for (afi = AFI_IP; afi < AFI_MAX; afi++)
11176 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
11177 bgp_distance_table[afi][safi] =
11178 bgp_table_init(afi, safi);
11179
11180 /* IPv4 BGP commands. */
11181 install_element(BGP_NODE, &bgp_table_map_cmd);
11182 install_element(BGP_NODE, &bgp_network_cmd);
11183 install_element(BGP_NODE, &bgp_network_mask_cmd);
11184 install_element(BGP_NODE, &bgp_network_mask_natural_cmd);
11185 install_element(BGP_NODE, &bgp_network_route_map_cmd);
11186 install_element(BGP_NODE, &bgp_network_mask_route_map_cmd);
11187 install_element(BGP_NODE, &bgp_network_mask_natural_route_map_cmd);
11188 install_element(BGP_NODE, &bgp_network_backdoor_cmd);
11189 install_element(BGP_NODE, &bgp_network_mask_backdoor_cmd);
11190 install_element(BGP_NODE, &bgp_network_mask_natural_backdoor_cmd);
11191 install_element(BGP_NODE, &no_bgp_table_map_cmd);
11192 install_element(BGP_NODE, &no_bgp_network_cmd);
11193 install_element(BGP_NODE, &no_bgp_network_mask_cmd);
11194 install_element(BGP_NODE, &no_bgp_network_mask_natural_cmd);
11195
11196 install_element(BGP_NODE, &aggregate_address_cmd);
11197 install_element(BGP_NODE, &aggregate_address_mask_cmd);
11198 install_element(BGP_NODE, &no_aggregate_address_cmd);
11199 install_element(BGP_NODE, &no_aggregate_address_mask_cmd);
11200
11201 /* IPv4 unicast configuration. */
11202 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
11203 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
11204 install_element(BGP_IPV4_NODE, &bgp_network_mask_cmd);
11205 install_element(BGP_IPV4_NODE, &bgp_network_mask_natural_cmd);
11206 install_element(BGP_IPV4_NODE, &bgp_network_route_map_cmd);
11207 install_element(BGP_IPV4_NODE, &bgp_network_mask_route_map_cmd);
11208 install_element(BGP_IPV4_NODE, &bgp_network_mask_natural_route_map_cmd);
11209 install_element(BGP_IPV4_NODE, &bgp_network_label_index_cmd);
11210 install_element(BGP_IPV4_NODE, &bgp_network_label_index_route_map_cmd);
11211 install_element(BGP_IPV4_NODE, &no_bgp_network_label_index_cmd);
11212 install_element(BGP_IPV4_NODE,
11213 &no_bgp_network_label_index_route_map_cmd);
11214 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
11215 install_element(BGP_IPV4_NODE, &no_bgp_network_cmd);
11216 install_element(BGP_IPV4_NODE, &no_bgp_network_mask_cmd);
11217 install_element(BGP_IPV4_NODE, &no_bgp_network_mask_natural_cmd);
11218
11219 install_element(BGP_IPV4_NODE, &aggregate_address_cmd);
11220 install_element(BGP_IPV4_NODE, &aggregate_address_mask_cmd);
11221 install_element(BGP_IPV4_NODE, &no_aggregate_address_cmd);
11222 install_element(BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
11223
11224 /* IPv4 multicast configuration. */
11225 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
11226 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
11227 install_element(BGP_IPV4M_NODE, &bgp_network_mask_cmd);
11228 install_element(BGP_IPV4M_NODE, &bgp_network_mask_natural_cmd);
11229 install_element(BGP_IPV4M_NODE, &bgp_network_route_map_cmd);
11230 install_element(BGP_IPV4M_NODE, &bgp_network_mask_route_map_cmd);
11231 install_element(BGP_IPV4M_NODE,
11232 &bgp_network_mask_natural_route_map_cmd);
11233 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
11234 install_element(BGP_IPV4M_NODE, &no_bgp_network_cmd);
11235 install_element(BGP_IPV4M_NODE, &no_bgp_network_mask_cmd);
11236 install_element(BGP_IPV4M_NODE, &no_bgp_network_mask_natural_cmd);
11237 install_element(BGP_IPV4M_NODE, &aggregate_address_cmd);
11238 install_element(BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
11239 install_element(BGP_IPV4M_NODE, &no_aggregate_address_cmd);
11240 install_element(BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
11241
11242 /* IPv4 labeled-unicast configuration. */
11243 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
11244 install_element(VIEW_NODE, &show_ip_bgp_cmd);
11245 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
11246 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
11247
11248 install_element(VIEW_NODE,
11249 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
11250 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
11251 install_element(VIEW_NODE,
11252 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
11253 #ifdef KEEP_OLD_VPN_COMMANDS
11254 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
11255 #endif /* KEEP_OLD_VPN_COMMANDS */
11256 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
11257 install_element(VIEW_NODE,
11258 &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd);
11259
11260 /* BGP dampening clear commands */
11261 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
11262 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
11263
11264 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
11265 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
11266
11267 /* prefix count */
11268 install_element(ENABLE_NODE,
11269 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
11270 #ifdef KEEP_OLD_VPN_COMMANDS
11271 install_element(ENABLE_NODE,
11272 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
11273 #endif /* KEEP_OLD_VPN_COMMANDS */
11274
11275 /* New config IPv6 BGP commands. */
11276 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
11277 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
11278 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_route_map_cmd);
11279 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
11280 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_network_cmd);
11281 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_label_index_cmd);
11282 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_network_label_index_cmd);
11283 install_element(BGP_IPV6_NODE,
11284 &ipv6_bgp_network_label_index_route_map_cmd);
11285 install_element(BGP_IPV6_NODE,
11286 &no_ipv6_bgp_network_label_index_route_map_cmd);
11287
11288 install_element(BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
11289 install_element(BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
11290
11291 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
11292 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_network_cmd);
11293
11294 install_element(BGP_IPV6L_NODE, &bgp_table_map_cmd);
11295 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
11296 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_route_map_cmd);
11297 install_element(BGP_IPV6L_NODE, &no_bgp_table_map_cmd);
11298 install_element(BGP_IPV6L_NODE, &no_ipv6_bgp_network_cmd);
11299
11300 install_element(BGP_NODE, &bgp_distance_cmd);
11301 install_element(BGP_NODE, &no_bgp_distance_cmd);
11302 install_element(BGP_NODE, &bgp_distance_source_cmd);
11303 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
11304 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
11305 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
11306 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
11307 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
11308 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
11309 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
11310 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
11311 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
11312 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
11313 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
11314 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
11315 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
11316 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
11317 install_element(BGP_IPV4M_NODE,
11318 &no_bgp_distance_source_access_list_cmd);
11319 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
11320 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
11321 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
11322 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
11323 install_element(BGP_IPV6_NODE,
11324 &ipv6_bgp_distance_source_access_list_cmd);
11325 install_element(BGP_IPV6_NODE,
11326 &no_ipv6_bgp_distance_source_access_list_cmd);
11327 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
11328 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
11329 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
11330 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
11331 install_element(BGP_IPV6M_NODE,
11332 &ipv6_bgp_distance_source_access_list_cmd);
11333 install_element(BGP_IPV6M_NODE,
11334 &no_ipv6_bgp_distance_source_access_list_cmd);
11335
11336 install_element(BGP_NODE, &bgp_damp_set_cmd);
11337 install_element(BGP_NODE, &bgp_damp_unset_cmd);
11338 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
11339 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
11340
11341 /* IPv4 Multicast Mode */
11342 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
11343 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
11344
11345 /* Large Communities */
11346 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
11347 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
11348 }
11349
11350 void bgp_route_finish(void)
11351 {
11352 afi_t afi;
11353 safi_t safi;
11354
11355 for (afi = AFI_IP; afi < AFI_MAX; afi++)
11356 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
11357 bgp_table_unlock(bgp_distance_table[afi][safi]);
11358 bgp_distance_table[afi][safi] = NULL;
11359 }
11360 }