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