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