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