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