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