1 /* BGP-4, BGP-4+ daemon program
2 Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
3
4 This file is part of GNU Zebra.
5
6 GNU Zebra is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 GNU Zebra is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
20
21 #include <zebra.h>
22
23 #include "prefix.h"
24 #include "thread.h"
25 #include "buffer.h"
26 #include "stream.h"
27 #include "command.h"
28 #include "sockunion.h"
29 #include "sockopt.h"
30 #include "network.h"
31 #include "memory.h"
32 #include "filter.h"
33 #include "routemap.h"
34 #include "str.h"
35 #include "log.h"
36 #include "plist.h"
37 #include "linklist.h"
38 #include "workqueue.h"
39 #include "table.h"
40
41 #include "bgpd/bgpd.h"
42 #include "bgpd/bgp_table.h"
43 #include "bgpd/bgp_aspath.h"
44 #include "bgpd/bgp_route.h"
45 #include "bgpd/bgp_dump.h"
46 #include "bgpd/bgp_debug.h"
47 #include "bgpd/bgp_community.h"
48 #include "bgpd/bgp_attr.h"
49 #include "bgpd/bgp_regex.h"
50 #include "bgpd/bgp_clist.h"
51 #include "bgpd/bgp_fsm.h"
52 #include "bgpd/bgp_packet.h"
53 #include "bgpd/bgp_zebra.h"
54 #include "bgpd/bgp_open.h"
55 #include "bgpd/bgp_filter.h"
56 #include "bgpd/bgp_nexthop.h"
57 #include "bgpd/bgp_damp.h"
58 #include "bgpd/bgp_mplsvpn.h"
59 #include "bgpd/bgp_encap.h"
60 #include "bgpd/bgp_advertise.h"
61 #include "bgpd/bgp_network.h"
62 #include "bgpd/bgp_vty.h"
63 #include "bgpd/bgp_mpath.h"
64 #include "bgpd/bgp_nht.h"
65 #ifdef HAVE_SNMP
66 #include "bgpd/bgp_snmp.h"
67 #endif /* HAVE_SNMP */
68
69 /* BGP process wide configuration. */
70 static struct bgp_master bgp_master;
71
72 extern struct in_addr router_id_zebra;
73
74 /* BGP process wide configuration pointer to export. */
75 struct bgp_master *bm;
76
77 /* BGP community-list. */
78 struct community_list_handler *bgp_clist;
79
80 /* BGP global flag manipulation. */
81 int
bgp_option_set(int flag)82 bgp_option_set (int flag)
83 {
84 switch (flag)
85 {
86 case BGP_OPT_NO_FIB:
87 case BGP_OPT_MULTIPLE_INSTANCE:
88 case BGP_OPT_CONFIG_CISCO:
89 case BGP_OPT_NO_LISTEN:
90 SET_FLAG (bm->options, flag);
91 break;
92 default:
93 return BGP_ERR_INVALID_FLAG;
94 }
95 return 0;
96 }
97
98 int
bgp_option_unset(int flag)99 bgp_option_unset (int flag)
100 {
101 switch (flag)
102 {
103 case BGP_OPT_MULTIPLE_INSTANCE:
104 if (listcount (bm->bgp) > 1)
105 return BGP_ERR_MULTIPLE_INSTANCE_USED;
106 /* Fall through. */
107 case BGP_OPT_NO_FIB:
108 case BGP_OPT_CONFIG_CISCO:
109 UNSET_FLAG (bm->options, flag);
110 break;
111 default:
112 return BGP_ERR_INVALID_FLAG;
113 }
114 return 0;
115 }
116
117 int
bgp_option_check(int flag)118 bgp_option_check (int flag)
119 {
120 return CHECK_FLAG (bm->options, flag);
121 }
122
123 /* BGP flag manipulation. */
124 int
bgp_flag_set(struct bgp * bgp,int flag)125 bgp_flag_set (struct bgp *bgp, int flag)
126 {
127 SET_FLAG (bgp->flags, flag);
128 return 0;
129 }
130
131 int
bgp_flag_unset(struct bgp * bgp,int flag)132 bgp_flag_unset (struct bgp *bgp, int flag)
133 {
134 UNSET_FLAG (bgp->flags, flag);
135 return 0;
136 }
137
138 int
bgp_flag_check(struct bgp * bgp,int flag)139 bgp_flag_check (struct bgp *bgp, int flag)
140 {
141 return CHECK_FLAG (bgp->flags, flag);
142 }
143
144 /* Internal function to set BGP structure configureation flag. */
145 static void
bgp_config_set(struct bgp * bgp,int config)146 bgp_config_set (struct bgp *bgp, int config)
147 {
148 SET_FLAG (bgp->config, config);
149 }
150
151 static void
bgp_config_unset(struct bgp * bgp,int config)152 bgp_config_unset (struct bgp *bgp, int config)
153 {
154 UNSET_FLAG (bgp->config, config);
155 }
156
157 static int
bgp_config_check(struct bgp * bgp,int config)158 bgp_config_check (struct bgp *bgp, int config)
159 {
160 return CHECK_FLAG (bgp->config, config);
161 }
162
163 /* Set BGP router identifier. */
164 static int
bgp_router_id_set(struct bgp * bgp,struct in_addr * id)165 bgp_router_id_set (struct bgp *bgp, struct in_addr *id)
166 {
167 struct peer *peer;
168 struct listnode *node, *nnode;
169
170 if (bgp_config_check (bgp, BGP_CONFIG_ROUTER_ID)
171 && IPV4_ADDR_SAME (&bgp->router_id, id))
172 return 0;
173
174 IPV4_ADDR_COPY (&bgp->router_id, id);
175 bgp_config_set (bgp, BGP_CONFIG_ROUTER_ID);
176
177 /* Set all peer's local identifier with this value. */
178 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
179 {
180 IPV4_ADDR_COPY (&peer->local_id, id);
181
182 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
183 {
184 peer->last_reset = PEER_DOWN_RID_CHANGE;
185 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
186 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
187 }
188 }
189 return 0;
190 }
191
192 void
bgp_router_id_zebra_bump(void)193 bgp_router_id_zebra_bump (void)
194 {
195 struct listnode *node, *nnode;
196 struct bgp *bgp;
197
198 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
199 {
200 if (!bgp->router_id_static.s_addr)
201 bgp_router_id_set (bgp, &router_id_zebra);
202 }
203 }
204
205 int
bgp_router_id_static_set(struct bgp * bgp,struct in_addr id)206 bgp_router_id_static_set (struct bgp *bgp, struct in_addr id)
207 {
208 bgp->router_id_static = id;
209 bgp_router_id_set (bgp, id.s_addr ? &id : &router_id_zebra);
210 return 0;
211 }
212
213 /* BGP's cluster-id control. */
214 int
bgp_cluster_id_set(struct bgp * bgp,struct in_addr * cluster_id)215 bgp_cluster_id_set (struct bgp *bgp, struct in_addr *cluster_id)
216 {
217 struct peer *peer;
218 struct listnode *node, *nnode;
219
220 if (bgp_config_check (bgp, BGP_CONFIG_CLUSTER_ID)
221 && IPV4_ADDR_SAME (&bgp->cluster_id, cluster_id))
222 return 0;
223
224 IPV4_ADDR_COPY (&bgp->cluster_id, cluster_id);
225 bgp_config_set (bgp, BGP_CONFIG_CLUSTER_ID);
226
227 /* Clear all IBGP peer. */
228 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
229 {
230 if (peer->sort != BGP_PEER_IBGP)
231 continue;
232
233 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
234 {
235 peer->last_reset = PEER_DOWN_CLID_CHANGE;
236 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
237 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
238 }
239 }
240 return 0;
241 }
242
243 int
bgp_cluster_id_unset(struct bgp * bgp)244 bgp_cluster_id_unset (struct bgp *bgp)
245 {
246 struct peer *peer;
247 struct listnode *node, *nnode;
248
249 if (! bgp_config_check (bgp, BGP_CONFIG_CLUSTER_ID))
250 return 0;
251
252 bgp->cluster_id.s_addr = 0;
253 bgp_config_unset (bgp, BGP_CONFIG_CLUSTER_ID);
254
255 /* Clear all IBGP peer. */
256 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
257 {
258 if (peer->sort != BGP_PEER_IBGP)
259 continue;
260
261 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
262 {
263 peer->last_reset = PEER_DOWN_CLID_CHANGE;
264 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
265 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
266 }
267 }
268 return 0;
269 }
270
271 /* time_t value that is monotonicly increasing
272 * and uneffected by adjustments to system clock
273 */
bgp_clock(void)274 time_t bgp_clock (void)
275 {
276 struct timeval tv;
277
278 quagga_gettime(QUAGGA_CLK_MONOTONIC, &tv);
279 return tv.tv_sec;
280 }
281
282 /* BGP timer configuration. */
283 int
bgp_timers_set(struct bgp * bgp,u_int32_t keepalive,u_int32_t holdtime)284 bgp_timers_set (struct bgp *bgp, u_int32_t keepalive, u_int32_t holdtime)
285 {
286 bgp->default_keepalive = (keepalive < holdtime / 3
287 ? keepalive : holdtime / 3);
288 bgp->default_holdtime = holdtime;
289
290 return 0;
291 }
292
293 int
bgp_timers_unset(struct bgp * bgp)294 bgp_timers_unset (struct bgp *bgp)
295 {
296 bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
297 bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
298
299 return 0;
300 }
301
302 /* BGP confederation configuration. */
303 int
bgp_confederation_id_set(struct bgp * bgp,as_t as)304 bgp_confederation_id_set (struct bgp *bgp, as_t as)
305 {
306 struct peer *peer;
307 struct listnode *node, *nnode;
308 int already_confed;
309
310 if (as == 0)
311 return BGP_ERR_INVALID_AS;
312
313 /* Remember - were we doing confederation before? */
314 already_confed = bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION);
315 bgp->confed_id = as;
316 bgp_config_set (bgp, BGP_CONFIG_CONFEDERATION);
317
318 /* If we were doing confederation already, this is just an external
319 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
320 were not doing confederation before, reset all EBGP sessions. */
321 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
322 {
323 /* We're looking for peers who's AS is not local or part of our
324 confederation. */
325 if (already_confed)
326 {
327 if (peer_sort (peer) == BGP_PEER_EBGP)
328 {
329 peer->local_as = as;
330 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
331 {
332 peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
333 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
334 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
335 }
336
337 else
338 BGP_EVENT_ADD (peer, BGP_Stop);
339 }
340 }
341 else
342 {
343 /* Not doign confederation before, so reset every non-local
344 session */
345 if (peer_sort (peer) != BGP_PEER_IBGP)
346 {
347 /* Reset the local_as to be our EBGP one */
348 if (peer_sort (peer) == BGP_PEER_EBGP)
349 peer->local_as = as;
350 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
351 {
352 peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
353 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
354 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
355 }
356 else
357 BGP_EVENT_ADD (peer, BGP_Stop);
358 }
359 }
360 }
361 return 0;
362 }
363
364 int
bgp_confederation_id_unset(struct bgp * bgp)365 bgp_confederation_id_unset (struct bgp *bgp)
366 {
367 struct peer *peer;
368 struct listnode *node, *nnode;
369
370 bgp->confed_id = 0;
371 bgp_config_unset (bgp, BGP_CONFIG_CONFEDERATION);
372
373 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
374 {
375 /* We're looking for peers who's AS is not local */
376 if (peer_sort (peer) != BGP_PEER_IBGP)
377 {
378 peer->local_as = bgp->as;
379 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
380 {
381 peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
382 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
383 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
384 }
385
386 else
387 BGP_EVENT_ADD (peer, BGP_Stop);
388 }
389 }
390 return 0;
391 }
392
393 /* Is an AS part of the confed or not? */
394 int
bgp_confederation_peers_check(struct bgp * bgp,as_t as)395 bgp_confederation_peers_check (struct bgp *bgp, as_t as)
396 {
397 int i;
398
399 if (! bgp)
400 return 0;
401
402 for (i = 0; i < bgp->confed_peers_cnt; i++)
403 if (bgp->confed_peers[i] == as)
404 return 1;
405
406 return 0;
407 }
408
409 /* Add an AS to the confederation set. */
410 int
bgp_confederation_peers_add(struct bgp * bgp,as_t as)411 bgp_confederation_peers_add (struct bgp *bgp, as_t as)
412 {
413 struct peer *peer;
414 struct listnode *node, *nnode;
415
416 if (! bgp)
417 return BGP_ERR_INVALID_BGP;
418
419 if (bgp->as == as)
420 return BGP_ERR_INVALID_AS;
421
422 if (bgp_confederation_peers_check (bgp, as))
423 return -1;
424
425 if (bgp->confed_peers)
426 bgp->confed_peers = XREALLOC (MTYPE_BGP_CONFED_LIST,
427 bgp->confed_peers,
428 (bgp->confed_peers_cnt + 1) * sizeof (as_t));
429 else
430 bgp->confed_peers = XMALLOC (MTYPE_BGP_CONFED_LIST,
431 (bgp->confed_peers_cnt + 1) * sizeof (as_t));
432
433 bgp->confed_peers[bgp->confed_peers_cnt] = as;
434 bgp->confed_peers_cnt++;
435
436 if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION))
437 {
438 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
439 {
440 if (peer->as == as)
441 {
442 peer->local_as = bgp->as;
443 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
444 {
445 peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;
446 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
447 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
448 }
449 else
450 BGP_EVENT_ADD (peer, BGP_Stop);
451 }
452 }
453 }
454 return 0;
455 }
456
457 /* Delete an AS from the confederation set. */
458 int
bgp_confederation_peers_remove(struct bgp * bgp,as_t as)459 bgp_confederation_peers_remove (struct bgp *bgp, as_t as)
460 {
461 int i;
462 int j;
463 struct peer *peer;
464 struct listnode *node, *nnode;
465
466 if (! bgp)
467 return -1;
468
469 if (! bgp_confederation_peers_check (bgp, as))
470 return -1;
471
472 for (i = 0; i < bgp->confed_peers_cnt; i++)
473 if (bgp->confed_peers[i] == as)
474 for(j = i + 1; j < bgp->confed_peers_cnt; j++)
475 bgp->confed_peers[j - 1] = bgp->confed_peers[j];
476
477 bgp->confed_peers_cnt--;
478
479 if (bgp->confed_peers_cnt == 0)
480 {
481 if (bgp->confed_peers)
482 XFREE (MTYPE_BGP_CONFED_LIST, bgp->confed_peers);
483 bgp->confed_peers = NULL;
484 }
485 else
486 bgp->confed_peers = XREALLOC (MTYPE_BGP_CONFED_LIST,
487 bgp->confed_peers,
488 bgp->confed_peers_cnt * sizeof (as_t));
489
490 /* Now reset any peer who's remote AS has just been removed from the
491 CONFED */
492 if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION))
493 {
494 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
495 {
496 if (peer->as == as)
497 {
498 peer->local_as = bgp->confed_id;
499 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
500 {
501 peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;
502 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
503 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
504 }
505 else
506 BGP_EVENT_ADD (peer, BGP_Stop);
507 }
508 }
509 }
510
511 return 0;
512 }
513
514 /* Local preference configuration. */
515 int
bgp_default_local_preference_set(struct bgp * bgp,u_int32_t local_pref)516 bgp_default_local_preference_set (struct bgp *bgp, u_int32_t local_pref)
517 {
518 if (! bgp)
519 return -1;
520
521 bgp->default_local_pref = local_pref;
522
523 return 0;
524 }
525
526 int
bgp_default_local_preference_unset(struct bgp * bgp)527 bgp_default_local_preference_unset (struct bgp *bgp)
528 {
529 if (! bgp)
530 return -1;
531
532 bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
533
534 return 0;
535 }
536
537 /* If peer is RSERVER_CLIENT in at least one address family and is not member
538 of a peer_group for that family, return 1.
539 Used to check wether the peer is included in list bgp->rsclient. */
540 int
peer_rsclient_active(struct peer * peer)541 peer_rsclient_active (struct peer *peer)
542 {
543 int i;
544 int j;
545
546 for (i=AFI_IP; i < AFI_MAX; i++)
547 for (j=SAFI_UNICAST; j < SAFI_MAX; j++)
548 if (CHECK_FLAG(peer->af_flags[i][j], PEER_FLAG_RSERVER_CLIENT)
549 && ! peer->af_group[i][j])
550 return 1;
551 return 0;
552 }
553
554 /* Peer comparison function for sorting. */
555 static int
peer_cmp(struct peer * p1,struct peer * p2)556 peer_cmp (struct peer *p1, struct peer *p2)
557 {
558 return sockunion_cmp (&p1->su, &p2->su);
559 }
560
561 int
peer_af_flag_check(struct peer * peer,afi_t afi,safi_t safi,u_int32_t flag)562 peer_af_flag_check (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
563 {
564 return CHECK_FLAG (peer->af_flags[afi][safi], flag);
565 }
566
567 /* Reset all address family specific configuration. */
568 static void
peer_af_flag_reset(struct peer * peer,afi_t afi,safi_t safi)569 peer_af_flag_reset (struct peer *peer, afi_t afi, safi_t safi)
570 {
571 int i;
572 struct bgp_filter *filter;
573 char orf_name[BUFSIZ];
574
575 filter = &peer->filter[afi][safi];
576
577 /* Clear neighbor filter and route-map */
578 for (i = FILTER_IN; i < FILTER_MAX; i++)
579 {
580 if (filter->dlist[i].name)
581 {
582 free (filter->dlist[i].name);
583 filter->dlist[i].name = NULL;
584 }
585 if (filter->plist[i].name)
586 {
587 free (filter->plist[i].name);
588 filter->plist[i].name = NULL;
589 }
590 if (filter->aslist[i].name)
591 {
592 free (filter->aslist[i].name);
593 filter->aslist[i].name = NULL;
594 }
595 }
596 for (i = RMAP_IN; i < RMAP_MAX; i++)
597 {
598 if (filter->map[i].name)
599 {
600 free (filter->map[i].name);
601 filter->map[i].name = NULL;
602 }
603 }
604
605 /* Clear unsuppress map. */
606 if (filter->usmap.name)
607 free (filter->usmap.name);
608 filter->usmap.name = NULL;
609 filter->usmap.map = NULL;
610
611 /* Clear neighbor's all address family flags. */
612 peer->af_flags[afi][safi] = 0;
613
614 /* Clear neighbor's all address family sflags. */
615 peer->af_sflags[afi][safi] = 0;
616
617 /* Clear neighbor's all address family capabilities. */
618 peer->af_cap[afi][safi] = 0;
619
620 /* Clear ORF info */
621 peer->orf_plist[afi][safi] = NULL;
622 sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi);
623 prefix_bgp_orf_remove_all (afi, orf_name);
624
625 /* Set default neighbor send-community. */
626 if (! bgp_option_check (BGP_OPT_CONFIG_CISCO))
627 {
628 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY);
629 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY);
630 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_LARGE_COMMUNITY);
631 }
632
633 /* Clear neighbor default_originate_rmap */
634 if (peer->default_rmap[afi][safi].name)
635 free (peer->default_rmap[afi][safi].name);
636 peer->default_rmap[afi][safi].name = NULL;
637 peer->default_rmap[afi][safi].map = NULL;
638
639 /* Clear neighbor maximum-prefix */
640 peer->pmax[afi][safi] = 0;
641 peer->pmax_threshold[afi][safi] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT;
642 }
643
644 /* peer global config reset */
645 static void
peer_global_config_reset(struct peer * peer)646 peer_global_config_reset (struct peer *peer)
647 {
648 peer->weight = 0;
649 peer->change_local_as = 0;
650 peer->ttl = 0;
651 peer->gtsm_hops = 0;
652 if (peer->update_source)
653 {
654 sockunion_free (peer->update_source);
655 peer->update_source = NULL;
656 }
657 if (peer->update_if)
658 {
659 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
660 peer->update_if = NULL;
661 }
662
663 if (peer_sort (peer) == BGP_PEER_IBGP)
664 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
665 else
666 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
667
668 peer->flags = 0;
669 peer->config = 0;
670 peer->holdtime = 0;
671 peer->keepalive = 0;
672 peer->connect = 0;
673 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
674 }
675
676 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
677 static bgp_peer_sort_t
peer_calc_sort(struct peer * peer)678 peer_calc_sort (struct peer *peer)
679 {
680 struct bgp *bgp;
681
682 bgp = peer->bgp;
683
684 /* Peer-group */
685 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
686 {
687 if (peer->as)
688 return (bgp->as == peer->as ? BGP_PEER_IBGP : BGP_PEER_EBGP);
689 else
690 {
691 struct peer *peer1;
692 peer1 = listnode_head (peer->group->peer);
693 if (peer1)
694 return (peer1->local_as == peer1->as
695 ? BGP_PEER_IBGP : BGP_PEER_EBGP);
696 }
697 return BGP_PEER_INTERNAL;
698 }
699
700 /* Normal peer */
701 if (bgp && CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
702 {
703 if (peer->local_as == 0)
704 return BGP_PEER_INTERNAL;
705
706 if (peer->local_as == peer->as)
707 {
708 if (peer->local_as == bgp->confed_id)
709 return BGP_PEER_EBGP;
710 else
711 return BGP_PEER_IBGP;
712 }
713
714 if (bgp_confederation_peers_check (bgp, peer->as))
715 return BGP_PEER_CONFED;
716
717 return BGP_PEER_EBGP;
718 }
719 else
720 {
721 return (peer->local_as == 0
722 ? BGP_PEER_INTERNAL : peer->local_as == peer->as
723 ? BGP_PEER_IBGP : BGP_PEER_EBGP);
724 }
725 }
726
727 /* Calculate and cache the peer "sort" */
728 bgp_peer_sort_t
peer_sort(struct peer * peer)729 peer_sort (struct peer *peer)
730 {
731 peer->sort = peer_calc_sort (peer);
732 return peer->sort;
733 }
734
735 static void
peer_free(struct peer * peer)736 peer_free (struct peer *peer)
737 {
738 assert (peer->status == Deleted);
739
740 /* this /ought/ to have been done already through bgp_stop earlier,
741 * but just to be sure..
742 */
743 bgp_timer_set (peer);
744 BGP_READ_OFF (peer->t_read);
745 BGP_WRITE_OFF (peer->t_write);
746 BGP_EVENT_FLUSH (peer);
747
748 if (peer->desc)
749 {
750 XFREE (MTYPE_PEER_DESC, peer->desc);
751 peer->desc = NULL;
752 }
753
754 /* Free allocated host character. */
755 if (peer->host)
756 {
757 XFREE (MTYPE_BGP_PEER_HOST, peer->host);
758 peer->host = NULL;
759 }
760
761 /* Update source configuration. */
762 if (peer->update_source)
763 {
764 sockunion_free (peer->update_source);
765 peer->update_source = NULL;
766 }
767
768 if (peer->update_if)
769 {
770 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
771 peer->update_if = NULL;
772 }
773
774 if (peer->clear_node_queue)
775 {
776 work_queue_free(peer->clear_node_queue);
777 peer->clear_node_queue = NULL;
778 }
779
780 if (peer->notify.data)
781 XFREE(MTYPE_TMP, peer->notify.data);
782
783 bgp_sync_delete (peer);
784
785 bgp_unlock(peer->bgp);
786
787 memset (peer, 0, sizeof (struct peer));
788
789 XFREE (MTYPE_BGP_PEER, peer);
790 }
791
792 /* increase reference count on a struct peer */
793 struct peer *
peer_lock_with_caller(const char * name,struct peer * peer)794 peer_lock_with_caller (const char *name, struct peer *peer)
795 {
796 assert (peer && (peer->lock >= 0));
797
798 #if 0
799 zlog_debug("%s peer_lock %p %d", name, peer, peer->lock);
800 #endif
801
802 peer->lock++;
803
804 return peer;
805 }
806
807 /* decrease reference count on a struct peer
808 * struct peer is freed and NULL returned if last reference
809 */
810 struct peer *
peer_unlock_with_caller(const char * name,struct peer * peer)811 peer_unlock_with_caller (const char *name, struct peer *peer)
812 {
813 assert (peer && (peer->lock > 0));
814
815 #if 0
816 zlog_debug("%s peer_unlock %p %d", name, peer, peer->lock);
817 #endif
818
819 peer->lock--;
820
821 if (peer->lock == 0)
822 {
823 peer_free (peer);
824 return NULL;
825 }
826
827 return peer;
828 }
829
830 /* Allocate new peer object, implicitely locked. */
831 static struct peer *
peer_new(struct bgp * bgp)832 peer_new (struct bgp *bgp)
833 {
834 afi_t afi;
835 safi_t safi;
836 struct peer *peer;
837 struct servent *sp;
838
839 /* bgp argument is absolutely required */
840 assert (bgp);
841 if (!bgp)
842 return NULL;
843
844 /* Allocate new peer. */
845 peer = XCALLOC (MTYPE_BGP_PEER, sizeof (struct peer));
846
847 /* Set default value. */
848 peer->fd = -1;
849 peer->v_start = BGP_INIT_START_TIMER;
850 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
851 peer->status = Idle;
852 peer->ostatus = Idle;
853 peer->weight = 0;
854 peer->password = NULL;
855 peer->bgp = bgp;
856 peer = peer_lock (peer); /* initial reference */
857 bgp_lock (bgp);
858
859 /* Set default flags. */
860 for (afi = AFI_IP; afi < AFI_MAX; afi++)
861 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
862 {
863 if (! bgp_option_check (BGP_OPT_CONFIG_CISCO))
864 {
865 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY);
866 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY);
867 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_LARGE_COMMUNITY);
868 }
869 peer->orf_plist[afi][safi] = NULL;
870 }
871 SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
872
873 /* Create buffers. */
874 peer->ibuf = stream_new (BGP_MAX_PACKET_SIZE);
875 peer->obuf = stream_fifo_new ();
876
877 /* We use a larger buffer for peer->work in the event that:
878 * - We RX a BGP_UPDATE where the attributes alone are just
879 * under BGP_MAX_PACKET_SIZE
880 * - The user configures an outbound route-map that does many as-path
881 * prepends or adds many communities. At most they can have CMD_ARGC_MAX
882 * args in a route-map so there is a finite limit on how large they can
883 * make the attributes.
884 *
885 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid bounds
886 * checking for every single attribute as we construct an UPDATE.
887 */
888 peer->work = stream_new (BGP_MAX_PACKET_SIZE + BGP_MAX_PACKET_SIZE_OVERFLOW);
889 peer->scratch = stream_new (BGP_MAX_PACKET_SIZE);
890
891 bgp_sync_init (peer);
892
893 /* Get service port number. */
894 sp = getservbyname ("bgp", "tcp");
895 peer->port = (sp == NULL) ? BGP_PORT_DEFAULT : ntohs (sp->s_port);
896
897 return peer;
898 }
899
900 /* Create new BGP peer. */
901 static struct peer *
peer_create(union sockunion * su,struct bgp * bgp,as_t local_as,as_t remote_as,afi_t afi,safi_t safi)902 peer_create (union sockunion *su, struct bgp *bgp, as_t local_as,
903 as_t remote_as, afi_t afi, safi_t safi)
904 {
905 int active;
906 struct peer *peer;
907 char buf[SU_ADDRSTRLEN];
908
909 peer = peer_new (bgp);
910 peer->su = *su;
911 peer->local_as = local_as;
912 peer->as = remote_as;
913 peer->local_id = bgp->router_id;
914 peer->v_holdtime = bgp->default_holdtime;
915 peer->v_keepalive = bgp->default_keepalive;
916 if (peer_sort (peer) == BGP_PEER_IBGP)
917 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
918 else
919 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
920
921 peer = peer_lock (peer); /* bgp peer list reference */
922 listnode_add_sort (bgp->peer, peer);
923
924 active = peer_active (peer);
925
926 if (afi && safi)
927 peer->afc[afi][safi] = 1;
928
929 /* Last read and reset time set */
930 peer->readtime = peer->resettime = bgp_clock ();
931
932 /* Make peer's address string. */
933 sockunion2str (su, buf, SU_ADDRSTRLEN);
934 peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, buf);
935
936 /* Set up peer's events and timers. */
937 if (! active && peer_active (peer))
938 bgp_timer_set (peer);
939
940 return peer;
941 }
942
943 /* Make accept BGP peer. Called from bgp_accept (). */
944 struct peer *
peer_create_accept(struct bgp * bgp)945 peer_create_accept (struct bgp *bgp)
946 {
947 struct peer *peer;
948
949 peer = peer_new (bgp);
950
951 peer = peer_lock (peer); /* bgp peer list reference */
952 listnode_add_sort (bgp->peer, peer);
953
954 return peer;
955 }
956
957 /* Change peer's AS number. */
958 static void
peer_as_change(struct peer * peer,as_t as)959 peer_as_change (struct peer *peer, as_t as)
960 {
961 struct peer *conf;
962
963 /* Stop peer. */
964 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
965 {
966 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
967 {
968 peer->last_reset = PEER_DOWN_REMOTE_AS_CHANGE;
969 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
970 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
971 }
972 else
973 BGP_EVENT_ADD (peer, BGP_Stop);
974 }
975 peer->as = as;
976
977 if (bgp_config_check (peer->bgp, BGP_CONFIG_CONFEDERATION)
978 && ! bgp_confederation_peers_check (peer->bgp, as)
979 && peer->bgp->as != as)
980 peer->local_as = peer->bgp->confed_id;
981 else
982 peer->local_as = peer->bgp->as;
983
984 /* Advertisement-interval reset */
985 conf = NULL;
986 if (peer->group)
987 conf = peer->group->conf;
988
989 if (conf && CHECK_FLAG (conf->config, PEER_CONFIG_ROUTEADV))
990 peer->v_routeadv = conf->routeadv;
991 else
992 if (peer_sort (peer) == BGP_PEER_IBGP)
993 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
994 else
995 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
996
997 /* reflector-client reset */
998 if (peer_sort (peer) != BGP_PEER_IBGP)
999 {
1000 UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST],
1001 PEER_FLAG_REFLECTOR_CLIENT);
1002 UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MULTICAST],
1003 PEER_FLAG_REFLECTOR_CLIENT);
1004 UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MPLS_VPN],
1005 PEER_FLAG_REFLECTOR_CLIENT);
1006 UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_ENCAP],
1007 PEER_FLAG_REFLECTOR_CLIENT);
1008 UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_UNICAST],
1009 PEER_FLAG_REFLECTOR_CLIENT);
1010 UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MULTICAST],
1011 PEER_FLAG_REFLECTOR_CLIENT);
1012 UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MPLS_VPN],
1013 PEER_FLAG_REFLECTOR_CLIENT);
1014 UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_ENCAP],
1015 PEER_FLAG_REFLECTOR_CLIENT);
1016 }
1017
1018 /* local-as reset */
1019 if (peer_sort (peer) != BGP_PEER_EBGP)
1020 {
1021 peer->change_local_as = 0;
1022 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
1023 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
1024 }
1025 }
1026
1027 /* If peer does not exist, create new one. If peer already exists,
1028 set AS number to the peer. */
1029 int
peer_remote_as(struct bgp * bgp,union sockunion * su,as_t * as,afi_t afi,safi_t safi)1030 peer_remote_as (struct bgp *bgp, union sockunion *su, as_t *as,
1031 afi_t afi, safi_t safi)
1032 {
1033 struct peer *peer;
1034 as_t local_as;
1035
1036 peer = peer_lookup (bgp, su);
1037
1038 if (peer)
1039 {
1040 /* When this peer is a member of peer-group. */
1041 if (peer->group)
1042 {
1043 if (peer->group->conf->as)
1044 {
1045 /* Return peer group's AS number. */
1046 *as = peer->group->conf->as;
1047 return BGP_ERR_PEER_GROUP_MEMBER;
1048 }
1049 if (peer_sort (peer->group->conf) == BGP_PEER_IBGP)
1050 {
1051 if (bgp->as != *as)
1052 {
1053 *as = peer->as;
1054 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
1055 }
1056 }
1057 else
1058 {
1059 if (bgp->as == *as)
1060 {
1061 *as = peer->as;
1062 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
1063 }
1064 }
1065 }
1066
1067 /* Existing peer's AS number change. */
1068 if (peer->as != *as)
1069 peer_as_change (peer, *as);
1070 }
1071 else
1072 {
1073
1074 /* If the peer is not part of our confederation, and its not an
1075 iBGP peer then spoof the source AS */
1076 if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION)
1077 && ! bgp_confederation_peers_check (bgp, *as)
1078 && bgp->as != *as)
1079 local_as = bgp->confed_id;
1080 else
1081 local_as = bgp->as;
1082
1083 /* If this is IPv4 unicast configuration and "no bgp default
1084 ipv4-unicast" is specified. */
1085
1086 if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)
1087 && afi == AFI_IP && safi == SAFI_UNICAST)
1088 peer_create (su, bgp, local_as, *as, 0, 0);
1089 else
1090 peer_create (su, bgp, local_as, *as, afi, safi);
1091 }
1092
1093 return 0;
1094 }
1095
1096 /* Activate the peer or peer group for specified AFI and SAFI. */
1097 int
peer_activate(struct peer * peer,afi_t afi,safi_t safi)1098 peer_activate (struct peer *peer, afi_t afi, safi_t safi)
1099 {
1100 int active;
1101
1102 if (peer->afc[afi][safi])
1103 return 0;
1104
1105 /* Activate the address family configuration. */
1106 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1107 peer->afc[afi][safi] = 1;
1108 else
1109 {
1110 active = peer_active (peer);
1111
1112 peer->afc[afi][safi] = 1;
1113
1114 if (! active && peer_active (peer))
1115 bgp_timer_set (peer);
1116 else
1117 {
1118 if (peer->status == Established)
1119 {
1120 if (CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV))
1121 {
1122 peer->afc_adv[afi][safi] = 1;
1123 bgp_capability_send (peer, afi, safi,
1124 CAPABILITY_CODE_MP,
1125 CAPABILITY_ACTION_SET);
1126 if (peer->afc_recv[afi][safi])
1127 {
1128 peer->afc_nego[afi][safi] = 1;
1129 bgp_announce_route (peer, afi, safi);
1130 }
1131 }
1132 else
1133 {
1134 peer->last_reset = PEER_DOWN_AF_ACTIVATE;
1135 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1136 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1137 }
1138 }
1139 }
1140 }
1141 return 0;
1142 }
1143
1144 int
peer_deactivate(struct peer * peer,afi_t afi,safi_t safi)1145 peer_deactivate (struct peer *peer, afi_t afi, safi_t safi)
1146 {
1147 struct peer_group *group;
1148 struct peer *peer1;
1149 struct listnode *node, *nnode;
1150
1151 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1152 {
1153 group = peer->group;
1154
1155 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
1156 {
1157 if (peer1->af_group[afi][safi])
1158 return BGP_ERR_PEER_GROUP_MEMBER_EXISTS;
1159 }
1160 }
1161 else
1162 {
1163 if (peer->af_group[afi][safi])
1164 return BGP_ERR_PEER_BELONGS_TO_GROUP;
1165 }
1166
1167 if (! peer->afc[afi][safi])
1168 return 0;
1169
1170 /* De-activate the address family configuration. */
1171 peer->afc[afi][safi] = 0;
1172 peer_af_flag_reset (peer, afi, safi);
1173
1174 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1175 {
1176 if (peer->status == Established)
1177 {
1178 if (CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV))
1179 {
1180 peer->afc_adv[afi][safi] = 0;
1181 peer->afc_nego[afi][safi] = 0;
1182
1183 if (peer_active_nego (peer))
1184 {
1185 bgp_capability_send (peer, afi, safi,
1186 CAPABILITY_CODE_MP,
1187 CAPABILITY_ACTION_UNSET);
1188 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
1189 peer->pcount[afi][safi] = 0;
1190 }
1191 else
1192 {
1193 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
1194 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1195 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1196 }
1197 }
1198 else
1199 {
1200 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
1201 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1202 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1203 }
1204 }
1205 }
1206 return 0;
1207 }
1208
1209 int
peer_afc_set(struct peer * peer,afi_t afi,safi_t safi,int enable)1210 peer_afc_set (struct peer *peer, afi_t afi, safi_t safi, int enable)
1211 {
1212 if (enable)
1213 return peer_activate (peer, afi, safi);
1214 else
1215 return peer_deactivate (peer, afi, safi);
1216 }
1217
1218 static void
peer_nsf_stop(struct peer * peer)1219 peer_nsf_stop (struct peer *peer)
1220 {
1221 afi_t afi;
1222 safi_t safi;
1223
1224 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
1225 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
1226
1227 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1228 for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
1229 peer->nsf[afi][safi] = 0;
1230
1231 if (peer->t_gr_restart)
1232 {
1233 BGP_TIMER_OFF (peer->t_gr_restart);
1234 if (BGP_DEBUG (events, EVENTS))
1235 zlog_debug ("%s graceful restart timer stopped", peer->host);
1236 }
1237 if (peer->t_gr_stale)
1238 {
1239 BGP_TIMER_OFF (peer->t_gr_stale);
1240 if (BGP_DEBUG (events, EVENTS))
1241 zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
1242 }
1243 bgp_clear_route_all (peer);
1244 }
1245
1246 /* Delete peer from confguration.
1247 *
1248 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
1249 * it to "cool off" and refcounts to hit 0, at which state it is freed.
1250 *
1251 * This function /should/ take care to be idempotent, to guard against
1252 * it being called multiple times through stray events that come in
1253 * that happen to result in this function being called again. That
1254 * said, getting here for a "Deleted" peer is a bug in the neighbour
1255 * FSM.
1256 */
1257 int
peer_delete(struct peer * peer)1258 peer_delete (struct peer *peer)
1259 {
1260 int i;
1261 afi_t afi;
1262 safi_t safi;
1263 struct bgp *bgp;
1264 struct bgp_filter *filter;
1265 struct listnode *pn;
1266
1267 assert (peer->status != Deleted);
1268
1269 bgp = peer->bgp;
1270
1271 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
1272 peer_nsf_stop (peer);
1273
1274 /* If this peer belongs to peer group, clear up the
1275 relationship. */
1276 if (peer->group)
1277 {
1278 if ((pn = listnode_lookup (peer->group->peer, peer)))
1279 {
1280 peer = peer_unlock (peer); /* group->peer list reference */
1281 list_delete_node (peer->group->peer, pn);
1282 }
1283 peer->group = NULL;
1284 }
1285
1286 /* Withdraw all information from routing table. We can not use
1287 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
1288 * executed after peer structure is deleted.
1289 */
1290 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
1291 bgp_stop (peer);
1292 bgp_fsm_change_status (peer, Deleted);
1293
1294 /* Remove from NHT */
1295 bgp_unlink_nexthop_by_peer (peer);
1296
1297 /* Password configuration */
1298 if (peer->password)
1299 {
1300 XFREE (MTYPE_PEER_PASSWORD, peer->password);
1301 peer->password = NULL;
1302
1303 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1304 bgp_md5_set (peer);
1305 }
1306
1307 bgp_timer_set (peer); /* stops all timers for Deleted */
1308
1309 /* Delete from all peer list. */
1310 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
1311 && (pn = listnode_lookup (bgp->peer, peer)))
1312 {
1313 peer_unlock (peer); /* bgp peer list reference */
1314 list_delete_node (bgp->peer, pn);
1315 }
1316
1317 if (peer_rsclient_active (peer)
1318 && (pn = listnode_lookup (bgp->rsclient, peer)))
1319 {
1320 peer_unlock (peer); /* rsclient list reference */
1321 list_delete_node (bgp->rsclient, pn);
1322
1323 /* Clear our own rsclient ribs. */
1324 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1325 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1326 if (CHECK_FLAG(peer->af_flags[afi][safi],
1327 PEER_FLAG_RSERVER_CLIENT))
1328 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_MY_RSCLIENT);
1329 }
1330
1331 /* Free RIB for any family in which peer is RSERVER_CLIENT, and is not
1332 member of a peer_group. */
1333 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1334 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1335 if (peer->rib[afi][safi] && ! peer->af_group[afi][safi])
1336 bgp_table_finish (&peer->rib[afi][safi]);
1337
1338 /* Buffers. */
1339 if (peer->ibuf)
1340 {
1341 stream_free (peer->ibuf);
1342 peer->ibuf = NULL;
1343 }
1344
1345 if (peer->obuf)
1346 {
1347 stream_fifo_free (peer->obuf);
1348 peer->obuf = NULL;
1349 }
1350
1351 if (peer->work)
1352 {
1353 stream_free (peer->work);
1354 peer->work = NULL;
1355 }
1356
1357 if (peer->scratch)
1358 {
1359 stream_free(peer->scratch);
1360 peer->scratch = NULL;
1361 }
1362
1363 /* Local and remote addresses. */
1364 if (peer->su_local)
1365 {
1366 sockunion_free (peer->su_local);
1367 peer->su_local = NULL;
1368 }
1369
1370 if (peer->su_remote)
1371 {
1372 sockunion_free (peer->su_remote);
1373 peer->su_remote = NULL;
1374 }
1375
1376 /* Free filter related memory. */
1377 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1378 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1379 {
1380 filter = &peer->filter[afi][safi];
1381
1382 for (i = FILTER_IN; i < FILTER_MAX; i++)
1383 {
1384 if (filter->dlist[i].name)
1385 {
1386 free(filter->dlist[i].name);
1387 filter->dlist[i].name = NULL;
1388 }
1389
1390 if (filter->plist[i].name)
1391 {
1392 free(filter->plist[i].name);
1393 filter->plist[i].name = NULL;
1394 }
1395
1396 if (filter->aslist[i].name)
1397 {
1398 free(filter->aslist[i].name);
1399 filter->aslist[i].name = NULL;
1400 }
1401 }
1402
1403 for (i = RMAP_IN; i < RMAP_MAX; i++)
1404 {
1405 if (filter->map[i].name)
1406 {
1407 free (filter->map[i].name);
1408 filter->map[i].name = NULL;
1409 }
1410 }
1411
1412 if (filter->usmap.name)
1413 {
1414 free (filter->usmap.name);
1415 filter->usmap.name = NULL;
1416 }
1417
1418 if (peer->default_rmap[afi][safi].name)
1419 {
1420 free (peer->default_rmap[afi][safi].name);
1421 peer->default_rmap[afi][safi].name = NULL;
1422 }
1423 }
1424
1425 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETING))
1426 bgp_peer_clear_node_queue_drain_immediate(peer);
1427
1428 peer_unlock (peer); /* initial reference */
1429
1430 return 0;
1431 }
1432
1433 static int
peer_group_cmp(struct peer_group * g1,struct peer_group * g2)1434 peer_group_cmp (struct peer_group *g1, struct peer_group *g2)
1435 {
1436 return strcmp (g1->name, g2->name);
1437 }
1438
1439 /* If peer is configured at least one address family return 1. */
1440 static int
peer_group_active(struct peer * peer)1441 peer_group_active (struct peer *peer)
1442 {
1443 if (peer->af_group[AFI_IP][SAFI_UNICAST]
1444 || peer->af_group[AFI_IP][SAFI_MULTICAST]
1445 || peer->af_group[AFI_IP][SAFI_MPLS_VPN]
1446 || peer->af_group[AFI_IP][SAFI_ENCAP]
1447 || peer->af_group[AFI_IP6][SAFI_UNICAST]
1448 || peer->af_group[AFI_IP6][SAFI_MULTICAST]
1449 || peer->af_group[AFI_IP6][SAFI_MPLS_VPN]
1450 || peer->af_group[AFI_IP6][SAFI_ENCAP])
1451 return 1;
1452 return 0;
1453 }
1454
1455 /* Peer group cofiguration. */
1456 static struct peer_group *
peer_group_new(void)1457 peer_group_new (void)
1458 {
1459 return (struct peer_group *) XCALLOC (MTYPE_PEER_GROUP,
1460 sizeof (struct peer_group));
1461 }
1462
1463 static void
peer_group_free(struct peer_group * group)1464 peer_group_free (struct peer_group *group)
1465 {
1466 XFREE (MTYPE_PEER_GROUP, group);
1467 }
1468
1469 struct peer_group *
peer_group_lookup(struct bgp * bgp,const char * name)1470 peer_group_lookup (struct bgp *bgp, const char *name)
1471 {
1472 struct peer_group *group;
1473 struct listnode *node, *nnode;
1474
1475 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
1476 {
1477 if (strcmp (group->name, name) == 0)
1478 return group;
1479 }
1480 return NULL;
1481 }
1482
1483 struct peer_group *
peer_group_get(struct bgp * bgp,const char * name)1484 peer_group_get (struct bgp *bgp, const char *name)
1485 {
1486 struct peer_group *group;
1487
1488 group = peer_group_lookup (bgp, name);
1489 if (group)
1490 return group;
1491
1492 group = peer_group_new ();
1493 group->bgp = bgp;
1494 group->name = strdup (name);
1495 group->peer = list_new ();
1496 group->conf = peer_new (bgp);
1497 if (! bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
1498 group->conf->afc[AFI_IP][SAFI_UNICAST] = 1;
1499 group->conf->host = XSTRDUP (MTYPE_BGP_PEER_HOST, name);
1500 group->conf->group = group;
1501 group->conf->as = 0;
1502 group->conf->ttl = 0;
1503 group->conf->gtsm_hops = 0;
1504 group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
1505 UNSET_FLAG (group->conf->config, PEER_CONFIG_TIMER);
1506 UNSET_FLAG (group->conf->config, PEER_CONFIG_CONNECT);
1507 group->conf->keepalive = 0;
1508 group->conf->holdtime = 0;
1509 group->conf->connect = 0;
1510 SET_FLAG (group->conf->sflags, PEER_STATUS_GROUP);
1511 listnode_add_sort (bgp->group, group);
1512
1513 return 0;
1514 }
1515
1516 static void
peer_group2peer_config_copy(struct peer_group * group,struct peer * peer,afi_t afi,safi_t safi)1517 peer_group2peer_config_copy (struct peer_group *group, struct peer *peer,
1518 afi_t afi, safi_t safi)
1519 {
1520 int in = FILTER_IN;
1521 int out = FILTER_OUT;
1522 struct peer *conf;
1523 struct bgp_filter *pfilter;
1524 struct bgp_filter *gfilter;
1525
1526 conf = group->conf;
1527 pfilter = &peer->filter[afi][safi];
1528 gfilter = &conf->filter[afi][safi];
1529
1530 /* remote-as */
1531 if (conf->as)
1532 peer->as = conf->as;
1533
1534 /* remote-as */
1535 if (conf->change_local_as)
1536 peer->change_local_as = conf->change_local_as;
1537
1538 /* TTL */
1539 peer->ttl = conf->ttl;
1540
1541 /* GTSM hops */
1542 peer->gtsm_hops = conf->gtsm_hops;
1543
1544 /* Weight */
1545 peer->weight = conf->weight;
1546
1547 /* peer flags apply */
1548 peer->flags = conf->flags;
1549 /* peer af_flags apply */
1550 peer->af_flags[afi][safi] = conf->af_flags[afi][safi];
1551 /* peer config apply */
1552 peer->config = conf->config;
1553
1554 /* peer timers apply */
1555 peer->holdtime = conf->holdtime;
1556 peer->keepalive = conf->keepalive;
1557 peer->connect = conf->connect;
1558 if (CHECK_FLAG (conf->config, PEER_CONFIG_CONNECT))
1559 peer->v_connect = conf->connect;
1560 else
1561 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
1562
1563 /* advertisement-interval reset */
1564 if (CHECK_FLAG (conf->config, PEER_CONFIG_ROUTEADV))
1565 peer->v_routeadv = conf->routeadv;
1566 else
1567 if (peer_sort (peer) == BGP_PEER_IBGP)
1568 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
1569 else
1570 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
1571
1572 /* password apply */
1573 if (conf->password && !peer->password)
1574 peer->password = XSTRDUP (MTYPE_PEER_PASSWORD, conf->password);
1575
1576 bgp_md5_set (peer);
1577
1578 /* maximum-prefix */
1579 peer->pmax[afi][safi] = conf->pmax[afi][safi];
1580 peer->pmax_threshold[afi][safi] = conf->pmax_threshold[afi][safi];
1581 peer->pmax_restart[afi][safi] = conf->pmax_restart[afi][safi];
1582
1583 /* allowas-in */
1584 peer->allowas_in[afi][safi] = conf->allowas_in[afi][safi];
1585
1586 /* route-server-client */
1587 if (CHECK_FLAG(conf->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1588 {
1589 /* Make peer's RIB point to group's RIB. */
1590 peer->rib[afi][safi] = group->conf->rib[afi][safi];
1591
1592 /* Import policy. */
1593 if (pfilter->map[RMAP_IMPORT].name)
1594 free (pfilter->map[RMAP_IMPORT].name);
1595 if (gfilter->map[RMAP_IMPORT].name)
1596 {
1597 pfilter->map[RMAP_IMPORT].name = strdup (gfilter->map[RMAP_IMPORT].name);
1598 pfilter->map[RMAP_IMPORT].map = gfilter->map[RMAP_IMPORT].map;
1599 }
1600 else
1601 {
1602 pfilter->map[RMAP_IMPORT].name = NULL;
1603 pfilter->map[RMAP_IMPORT].map = NULL;
1604 }
1605
1606 /* Export policy. */
1607 if (gfilter->map[RMAP_EXPORT].name && ! pfilter->map[RMAP_EXPORT].name)
1608 {
1609 pfilter->map[RMAP_EXPORT].name = strdup (gfilter->map[RMAP_EXPORT].name);
1610 pfilter->map[RMAP_EXPORT].map = gfilter->map[RMAP_EXPORT].map;
1611 }
1612 }
1613
1614 /* default-originate route-map */
1615 if (conf->default_rmap[afi][safi].name)
1616 {
1617 if (peer->default_rmap[afi][safi].name)
1618 free (peer->default_rmap[afi][safi].name);
1619 peer->default_rmap[afi][safi].name = strdup (conf->default_rmap[afi][safi].name);
1620 peer->default_rmap[afi][safi].map = conf->default_rmap[afi][safi].map;
1621 }
1622
1623 /* update-source apply */
1624 if (conf->update_source)
1625 {
1626 if (peer->update_source)
1627 sockunion_free (peer->update_source);
1628 if (peer->update_if)
1629 {
1630 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
1631 peer->update_if = NULL;
1632 }
1633 peer->update_source = sockunion_dup (conf->update_source);
1634 }
1635 else if (conf->update_if)
1636 {
1637 if (peer->update_if)
1638 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
1639 if (peer->update_source)
1640 {
1641 sockunion_free (peer->update_source);
1642 peer->update_source = NULL;
1643 }
1644 peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, conf->update_if);
1645 }
1646
1647 /* inbound filter apply */
1648 if (gfilter->dlist[in].name && ! pfilter->dlist[in].name)
1649 {
1650 if (pfilter->dlist[in].name)
1651 free (pfilter->dlist[in].name);
1652 pfilter->dlist[in].name = strdup (gfilter->dlist[in].name);
1653 pfilter->dlist[in].alist = gfilter->dlist[in].alist;
1654 }
1655 if (gfilter->plist[in].name && ! pfilter->plist[in].name)
1656 {
1657 if (pfilter->plist[in].name)
1658 free (pfilter->plist[in].name);
1659 pfilter->plist[in].name = strdup (gfilter->plist[in].name);
1660 pfilter->plist[in].plist = gfilter->plist[in].plist;
1661 }
1662 if (gfilter->aslist[in].name && ! pfilter->aslist[in].name)
1663 {
1664 if (pfilter->aslist[in].name)
1665 free (pfilter->aslist[in].name);
1666 pfilter->aslist[in].name = strdup (gfilter->aslist[in].name);
1667 pfilter->aslist[in].aslist = gfilter->aslist[in].aslist;
1668 }
1669 if (gfilter->map[RMAP_IN].name && ! pfilter->map[RMAP_IN].name)
1670 {
1671 if (pfilter->map[RMAP_IN].name)
1672 free (pfilter->map[RMAP_IN].name);
1673 pfilter->map[RMAP_IN].name = strdup (gfilter->map[RMAP_IN].name);
1674 pfilter->map[RMAP_IN].map = gfilter->map[RMAP_IN].map;
1675 }
1676
1677 /* outbound filter apply */
1678 if (gfilter->dlist[out].name)
1679 {
1680 if (pfilter->dlist[out].name)
1681 free (pfilter->dlist[out].name);
1682 pfilter->dlist[out].name = strdup (gfilter->dlist[out].name);
1683 pfilter->dlist[out].alist = gfilter->dlist[out].alist;
1684 }
1685 else
1686 {
1687 if (pfilter->dlist[out].name)
1688 free (pfilter->dlist[out].name);
1689 pfilter->dlist[out].name = NULL;
1690 pfilter->dlist[out].alist = NULL;
1691 }
1692 if (gfilter->plist[out].name)
1693 {
1694 if (pfilter->plist[out].name)
1695 free (pfilter->plist[out].name);
1696 pfilter->plist[out].name = strdup (gfilter->plist[out].name);
1697 pfilter->plist[out].plist = gfilter->plist[out].plist;
1698 }
1699 else
1700 {
1701 if (pfilter->plist[out].name)
1702 free (pfilter->plist[out].name);
1703 pfilter->plist[out].name = NULL;
1704 pfilter->plist[out].plist = NULL;
1705 }
1706 if (gfilter->aslist[out].name)
1707 {
1708 if (pfilter->aslist[out].name)
1709 free (pfilter->aslist[out].name);
1710 pfilter->aslist[out].name = strdup (gfilter->aslist[out].name);
1711 pfilter->aslist[out].aslist = gfilter->aslist[out].aslist;
1712 }
1713 else
1714 {
1715 if (pfilter->aslist[out].name)
1716 free (pfilter->aslist[out].name);
1717 pfilter->aslist[out].name = NULL;
1718 pfilter->aslist[out].aslist = NULL;
1719 }
1720 if (gfilter->map[RMAP_OUT].name)
1721 {
1722 if (pfilter->map[RMAP_OUT].name)
1723 free (pfilter->map[RMAP_OUT].name);
1724 pfilter->map[RMAP_OUT].name = strdup (gfilter->map[RMAP_OUT].name);
1725 pfilter->map[RMAP_OUT].map = gfilter->map[RMAP_OUT].map;
1726 }
1727 else
1728 {
1729 if (pfilter->map[RMAP_OUT].name)
1730 free (pfilter->map[RMAP_OUT].name);
1731 pfilter->map[RMAP_OUT].name = NULL;
1732 pfilter->map[RMAP_OUT].map = NULL;
1733 }
1734
1735 /* RS-client's import/export route-maps. */
1736 if (gfilter->map[RMAP_IMPORT].name)
1737 {
1738 if (pfilter->map[RMAP_IMPORT].name)
1739 free (pfilter->map[RMAP_IMPORT].name);
1740 pfilter->map[RMAP_IMPORT].name = strdup (gfilter->map[RMAP_IMPORT].name);
1741 pfilter->map[RMAP_IMPORT].map = gfilter->map[RMAP_IMPORT].map;
1742 }
1743 else
1744 {
1745 if (pfilter->map[RMAP_IMPORT].name)
1746 free (pfilter->map[RMAP_IMPORT].name);
1747 pfilter->map[RMAP_IMPORT].name = NULL;
1748 pfilter->map[RMAP_IMPORT].map = NULL;
1749 }
1750 if (gfilter->map[RMAP_EXPORT].name && ! pfilter->map[RMAP_EXPORT].name)
1751 {
1752 if (pfilter->map[RMAP_EXPORT].name)
1753 free (pfilter->map[RMAP_EXPORT].name);
1754 pfilter->map[RMAP_EXPORT].name = strdup (gfilter->map[RMAP_EXPORT].name);
1755 pfilter->map[RMAP_EXPORT].map = gfilter->map[RMAP_EXPORT].map;
1756 }
1757
1758 if (gfilter->usmap.name)
1759 {
1760 if (pfilter->usmap.name)
1761 free (pfilter->usmap.name);
1762 pfilter->usmap.name = strdup (gfilter->usmap.name);
1763 pfilter->usmap.map = gfilter->usmap.map;
1764 }
1765 else
1766 {
1767 if (pfilter->usmap.name)
1768 free (pfilter->usmap.name);
1769 pfilter->usmap.name = NULL;
1770 pfilter->usmap.map = NULL;
1771 }
1772 }
1773
1774 /* Peer group's remote AS configuration. */
1775 int
peer_group_remote_as(struct bgp * bgp,const char * group_name,as_t * as)1776 peer_group_remote_as (struct bgp *bgp, const char *group_name, as_t *as)
1777 {
1778 struct peer_group *group;
1779 struct peer *peer;
1780 struct listnode *node, *nnode;
1781
1782 group = peer_group_lookup (bgp, group_name);
1783 if (! group)
1784 return -1;
1785
1786 if (group->conf->as == *as)
1787 return 0;
1788
1789 /* When we setup peer-group AS number all peer group member's AS
1790 number must be updated to same number. */
1791 peer_as_change (group->conf, *as);
1792
1793 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
1794 {
1795 if (peer->as != *as)
1796 peer_as_change (peer, *as);
1797 }
1798
1799 return 0;
1800 }
1801
1802 int
peer_ttl(struct peer * peer)1803 peer_ttl (struct peer *peer)
1804 {
1805 if (peer->ttl)
1806 return peer->ttl;
1807 if (peer->gtsm_hops || peer->sort == BGP_PEER_IBGP)
1808 return 255;
1809 return 1;
1810 }
1811
1812 int
peer_group_delete(struct peer_group * group)1813 peer_group_delete (struct peer_group *group)
1814 {
1815 struct bgp *bgp;
1816 struct peer *peer;
1817 struct listnode *node, *nnode;
1818
1819 bgp = group->bgp;
1820
1821 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
1822 {
1823 peer_delete (peer);
1824 }
1825 list_delete (group->peer);
1826
1827 free (group->name);
1828 group->name = NULL;
1829
1830 group->conf->group = NULL;
1831 peer_delete (group->conf);
1832
1833 /* Delete from all peer_group list. */
1834 listnode_delete (bgp->group, group);
1835
1836 peer_group_free (group);
1837
1838 return 0;
1839 }
1840
1841 int
peer_group_remote_as_delete(struct peer_group * group)1842 peer_group_remote_as_delete (struct peer_group *group)
1843 {
1844 struct peer *peer;
1845 struct listnode *node, *nnode;
1846
1847 if (! group->conf->as)
1848 return 0;
1849
1850 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
1851 {
1852 peer_delete (peer);
1853 }
1854 list_delete_all_node (group->peer);
1855
1856 group->conf->as = 0;
1857
1858 return 0;
1859 }
1860
1861 /* Bind specified peer to peer group. */
1862 int
peer_group_bind(struct bgp * bgp,union sockunion * su,struct peer_group * group,afi_t afi,safi_t safi,as_t * as)1863 peer_group_bind (struct bgp *bgp, union sockunion *su,
1864 struct peer_group *group, afi_t afi, safi_t safi, as_t *as)
1865 {
1866 struct peer *peer;
1867 int first_member = 0;
1868
1869 /* Check peer group's address family. */
1870 if (! group->conf->afc[afi][safi])
1871 return BGP_ERR_PEER_GROUP_AF_UNCONFIGURED;
1872
1873 /* Lookup the peer. */
1874 peer = peer_lookup (bgp, su);
1875
1876 /* Create a new peer. */
1877 if (! peer)
1878 {
1879 if (! group->conf->as)
1880 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS;
1881
1882 peer = peer_create (su, bgp, bgp->as, group->conf->as, afi, safi);
1883 peer->group = group;
1884 peer->af_group[afi][safi] = 1;
1885
1886 peer = peer_lock (peer); /* group->peer list reference */
1887 listnode_add (group->peer, peer);
1888 peer_group2peer_config_copy (group, peer, afi, safi);
1889
1890 return 0;
1891 }
1892
1893 /* When the peer already belongs to peer group, check the consistency. */
1894 if (peer->af_group[afi][safi])
1895 {
1896 if (strcmp (peer->group->name, group->name) != 0)
1897 return BGP_ERR_PEER_GROUP_CANT_CHANGE;
1898
1899 return 0;
1900 }
1901
1902 /* Check current peer group configuration. */
1903 if (peer_group_active (peer)
1904 && strcmp (peer->group->name, group->name) != 0)
1905 return BGP_ERR_PEER_GROUP_MISMATCH;
1906
1907 if (! group->conf->as)
1908 {
1909 if (peer_sort (group->conf) != BGP_PEER_INTERNAL
1910 && peer_sort (group->conf) != peer_sort (peer))
1911 {
1912 if (as)
1913 *as = peer->as;
1914 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
1915 }
1916
1917 if (peer_sort (group->conf) == BGP_PEER_INTERNAL)
1918 first_member = 1;
1919 }
1920
1921 peer->af_group[afi][safi] = 1;
1922 peer->afc[afi][safi] = 1;
1923 if (! peer->group)
1924 {
1925 peer->group = group;
1926
1927 peer = peer_lock (peer); /* group->peer list reference */
1928 listnode_add (group->peer, peer);
1929 }
1930 else
1931 assert (group && peer->group == group);
1932
1933 if (first_member)
1934 {
1935 /* Advertisement-interval reset */
1936 if (! CHECK_FLAG (group->conf->config, PEER_CONFIG_ROUTEADV))
1937 {
1938 if (peer_sort (group->conf) == BGP_PEER_IBGP)
1939 group->conf->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
1940 else
1941 group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
1942 }
1943
1944 /* local-as reset */
1945 if (peer_sort (group->conf) != BGP_PEER_EBGP)
1946 {
1947 group->conf->change_local_as = 0;
1948 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
1949 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
1950 }
1951 }
1952
1953 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1954 {
1955 struct listnode *pn;
1956
1957 /* If it's not configured as RSERVER_CLIENT in any other address
1958 family, without being member of a peer_group, remove it from
1959 list bgp->rsclient.*/
1960 if (! peer_rsclient_active (peer)
1961 && (pn = listnode_lookup (bgp->rsclient, peer)))
1962 {
1963 peer_unlock (peer); /* peer rsclient reference */
1964 list_delete_node (bgp->rsclient, pn);
1965
1966 /* Clear our own rsclient rib for this afi/safi. */
1967 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_MY_RSCLIENT);
1968 }
1969
1970 bgp_table_finish (&peer->rib[afi][safi]);
1971
1972 /* Import policy. */
1973 if (peer->filter[afi][safi].map[RMAP_IMPORT].name)
1974 {
1975 free (peer->filter[afi][safi].map[RMAP_IMPORT].name);
1976 peer->filter[afi][safi].map[RMAP_IMPORT].name = NULL;
1977 peer->filter[afi][safi].map[RMAP_IMPORT].map = NULL;
1978 }
1979
1980 /* Export policy. */
1981 if (! CHECK_FLAG(group->conf->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
1982 && peer->filter[afi][safi].map[RMAP_EXPORT].name)
1983 {
1984 free (peer->filter[afi][safi].map[RMAP_EXPORT].name);
1985 peer->filter[afi][safi].map[RMAP_EXPORT].name = NULL;
1986 peer->filter[afi][safi].map[RMAP_EXPORT].map = NULL;
1987 }
1988 }
1989
1990 peer_group2peer_config_copy (group, peer, afi, safi);
1991
1992 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
1993 {
1994 peer->last_reset = PEER_DOWN_RMAP_BIND;
1995 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1996 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1997 }
1998 else
1999 BGP_EVENT_ADD (peer, BGP_Stop);
2000
2001 return 0;
2002 }
2003
2004 int
peer_group_unbind(struct bgp * bgp,struct peer * peer,struct peer_group * group,afi_t afi,safi_t safi)2005 peer_group_unbind (struct bgp *bgp, struct peer *peer,
2006 struct peer_group *group, afi_t afi, safi_t safi)
2007 {
2008 if (! peer->af_group[afi][safi])
2009 return 0;
2010
2011 if (group != peer->group)
2012 return BGP_ERR_PEER_GROUP_MISMATCH;
2013
2014 peer->af_group[afi][safi] = 0;
2015 peer->afc[afi][safi] = 0;
2016 peer_af_flag_reset (peer, afi, safi);
2017
2018 if (peer->rib[afi][safi])
2019 peer->rib[afi][safi] = NULL;
2020
2021 if (! peer_group_active (peer))
2022 {
2023 assert (listnode_lookup (group->peer, peer));
2024 peer_unlock (peer); /* peer group list reference */
2025 listnode_delete (group->peer, peer);
2026 peer->group = NULL;
2027 if (group->conf->as)
2028 {
2029 peer_delete (peer);
2030 return 0;
2031 }
2032 peer_global_config_reset (peer);
2033 }
2034
2035 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2036 {
2037 peer->last_reset = PEER_DOWN_RMAP_UNBIND;
2038 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2039 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2040 }
2041 else
2042 BGP_EVENT_ADD (peer, BGP_Stop);
2043
2044 return 0;
2045 }
2046
2047
2048 static int
bgp_startup_timer_expire(struct thread * thread)2049 bgp_startup_timer_expire (struct thread *thread)
2050 {
2051 struct bgp *bgp;
2052
2053 bgp = THREAD_ARG (thread);
2054 bgp->t_startup = NULL;
2055
2056 return 0;
2057 }
2058
2059 /* BGP instance creation by `router bgp' commands. */
2060 static struct bgp *
bgp_create(as_t * as,const char * name)2061 bgp_create (as_t *as, const char *name)
2062 {
2063 struct bgp *bgp;
2064 afi_t afi;
2065 safi_t safi;
2066
2067 if ( (bgp = XCALLOC (MTYPE_BGP, sizeof (struct bgp))) == NULL)
2068 return NULL;
2069
2070 bgp_lock (bgp);
2071 bgp->peer_self = peer_new (bgp);
2072 bgp->peer_self->host = XSTRDUP (MTYPE_BGP_PEER_HOST, "Static announcement");
2073
2074 bgp->peer = list_new ();
2075 bgp->peer->cmp = (int (*)(void *, void *)) peer_cmp;
2076
2077 bgp->group = list_new ();
2078 bgp->group->cmp = (int (*)(void *, void *)) peer_group_cmp;
2079
2080 bgp->rsclient = list_new ();
2081 bgp->rsclient->cmp = (int (*)(void*, void*)) peer_cmp;
2082
2083 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2084 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2085 {
2086 bgp->route[afi][safi] = bgp_table_init (afi, safi);
2087 bgp->aggregate[afi][safi] = bgp_table_init (afi, safi);
2088 bgp->rib[afi][safi] = bgp_table_init (afi, safi);
2089 bgp->maxpaths[afi][safi].maxpaths_ebgp = BGP_DEFAULT_MAXPATHS;
2090 bgp->maxpaths[afi][safi].maxpaths_ibgp = BGP_DEFAULT_MAXPATHS;
2091 }
2092
2093 bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
2094 bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
2095 bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
2096 bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
2097 bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
2098 bgp_flag_set (bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
2099
2100 bgp->as = *as;
2101
2102 if (name)
2103 bgp->name = strdup (name);
2104
2105 THREAD_TIMER_ON (bm->master, bgp->t_startup, bgp_startup_timer_expire,
2106 bgp, bgp->restart_time);
2107
2108 return bgp;
2109 }
2110
2111 /* Return first entry of BGP. */
2112 struct bgp *
bgp_get_default(void)2113 bgp_get_default (void)
2114 {
2115 if (bm && bm->bgp && bm->bgp->head)
2116 return (listgetdata (listhead (bm->bgp)));
2117 return NULL;
2118 }
2119
2120 /* Lookup BGP entry. */
2121 struct bgp *
bgp_lookup(as_t as,const char * name)2122 bgp_lookup (as_t as, const char *name)
2123 {
2124 struct bgp *bgp;
2125 struct listnode *node, *nnode;
2126
2127 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
2128 if (bgp->as == as
2129 && ((bgp->name == NULL && name == NULL)
2130 || (bgp->name && name && strcmp (bgp->name, name) == 0)))
2131 return bgp;
2132 return NULL;
2133 }
2134
2135 /* Lookup BGP structure by view name. */
2136 struct bgp *
bgp_lookup_by_name(const char * name)2137 bgp_lookup_by_name (const char *name)
2138 {
2139 struct bgp *bgp;
2140 struct listnode *node, *nnode;
2141
2142 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
2143 if ((bgp->name == NULL && name == NULL)
2144 || (bgp->name && name && strcmp (bgp->name, name) == 0))
2145 return bgp;
2146 return NULL;
2147 }
2148
2149 /* Called from VTY commands. */
2150 int
bgp_get(struct bgp ** bgp_val,as_t * as,const char * name)2151 bgp_get (struct bgp **bgp_val, as_t *as, const char *name)
2152 {
2153 struct bgp *bgp;
2154
2155 /* Multiple instance check. */
2156 if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
2157 {
2158 if (name)
2159 bgp = bgp_lookup_by_name (name);
2160 else
2161 bgp = bgp_get_default ();
2162
2163 /* Already exists. */
2164 if (bgp)
2165 {
2166 if (bgp->as != *as)
2167 {
2168 *as = bgp->as;
2169 return BGP_ERR_INSTANCE_MISMATCH;
2170 }
2171 *bgp_val = bgp;
2172 return 0;
2173 }
2174 }
2175 else
2176 {
2177 /* BGP instance name can not be specified for single instance. */
2178 if (name)
2179 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET;
2180
2181 /* Get default BGP structure if exists. */
2182 bgp = bgp_get_default ();
2183
2184 if (bgp)
2185 {
2186 if (bgp->as != *as)
2187 {
2188 *as = bgp->as;
2189 return BGP_ERR_AS_MISMATCH;
2190 }
2191 *bgp_val = bgp;
2192 return 0;
2193 }
2194 }
2195
2196 bgp = bgp_create (as, name);
2197 bgp_router_id_set(bgp, &router_id_zebra);
2198 *bgp_val = bgp;
2199
2200 /* Create BGP server socket, if first instance. */
2201 if (list_isempty(bm->bgp)
2202 && !bgp_option_check (BGP_OPT_NO_LISTEN))
2203 {
2204 if (bgp_socket (bm->port, bm->address) < 0)
2205 return BGP_ERR_INVALID_VALUE;
2206 }
2207
2208 listnode_add (bm->bgp, bgp);
2209
2210 return 0;
2211 }
2212
2213 /* Delete BGP instance. */
2214 int
bgp_delete(struct bgp * bgp)2215 bgp_delete (struct bgp *bgp)
2216 {
2217 struct peer *peer;
2218 struct peer_group *group;
2219 struct listnode *node, *pnode;
2220 struct listnode *next, *pnext;
2221 afi_t afi;
2222 int i;
2223
2224 SET_FLAG(bgp->flags, BGP_FLAG_DELETING);
2225
2226 THREAD_OFF (bgp->t_startup);
2227
2228 for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
2229 {
2230 if (peer->status == Established ||
2231 peer->status == OpenSent ||
2232 peer->status == OpenConfirm)
2233 {
2234 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2235 BGP_NOTIFY_CEASE_PEER_UNCONFIG);
2236 }
2237 }
2238
2239 /* Delete static route. */
2240 bgp_static_delete (bgp);
2241
2242 /* Unset redistribution. */
2243 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2244 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2245 if (i != ZEBRA_ROUTE_BGP)
2246 bgp_redistribute_unset (bgp, afi, i);
2247
2248 for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
2249 {
2250 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2251 {
2252 /* Send notify to remote peer. */
2253 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
2254 }
2255
2256 peer_delete (peer);
2257 }
2258
2259 for (ALL_LIST_ELEMENTS (bgp->group, node, next, group))
2260 {
2261 for (ALL_LIST_ELEMENTS (group->peer, pnode, pnext, peer))
2262 {
2263 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2264 {
2265 /* Send notify to remote peer. */
2266 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
2267 }
2268 }
2269 peer_group_delete (group);
2270 }
2271
2272 assert (listcount (bgp->rsclient) == 0);
2273
2274 if (bgp->peer_self) {
2275 peer_delete(bgp->peer_self);
2276 bgp->peer_self = NULL;
2277 }
2278
2279 /*
2280 * Free pending deleted routes. Unfortunately, it also has to process
2281 * all the pending activity for other instances of struct bgp.
2282 *
2283 * This call was added to achieve clean memory allocation at exit,
2284 * for the sake of valgrind.
2285 */
2286 bgp_process_queues_drain_immediate();
2287
2288 /* Remove visibility via the master list - there may however still be
2289 * routes to be processed still referencing the struct bgp.
2290 */
2291 listnode_delete (bm->bgp, bgp);
2292 if (list_isempty(bm->bgp))
2293 bgp_close ();
2294
2295 bgp_unlock(bgp); /* initial reference */
2296
2297 return 0;
2298 }
2299
2300 static void bgp_free (struct bgp *);
2301
2302 void
bgp_lock(struct bgp * bgp)2303 bgp_lock (struct bgp *bgp)
2304 {
2305 ++bgp->lock;
2306 }
2307
2308 void
bgp_unlock(struct bgp * bgp)2309 bgp_unlock(struct bgp *bgp)
2310 {
2311 assert(bgp->lock > 0);
2312 if (--bgp->lock == 0)
2313 bgp_free (bgp);
2314 }
2315
2316 static void
bgp_free(struct bgp * bgp)2317 bgp_free (struct bgp *bgp)
2318 {
2319 afi_t afi;
2320 safi_t safi;
2321
2322 list_delete (bgp->group);
2323 list_delete (bgp->peer);
2324 list_delete (bgp->rsclient);
2325
2326 if (bgp->name)
2327 free (bgp->name);
2328
2329 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2330 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2331 {
2332 if (bgp->route[afi][safi])
2333 bgp_table_finish (&bgp->route[afi][safi]);
2334 if (bgp->aggregate[afi][safi])
2335 bgp_table_finish (&bgp->aggregate[afi][safi]) ;
2336 if (bgp->rib[afi][safi])
2337 bgp_table_finish (&bgp->rib[afi][safi]);
2338 }
2339 XFREE (MTYPE_BGP, bgp);
2340 }
2341
2342 struct peer *
peer_lookup(struct bgp * bgp,union sockunion * su)2343 peer_lookup (struct bgp *bgp, union sockunion *su)
2344 {
2345 struct peer *peer;
2346 struct listnode *node, *nnode;
2347
2348 if (bgp != NULL)
2349 {
2350 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2351 if (sockunion_same (&peer->su, su)
2352 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2353 return peer;
2354 }
2355 else if (bm->bgp != NULL)
2356 {
2357 struct listnode *bgpnode, *nbgpnode;
2358
2359 for (ALL_LIST_ELEMENTS (bm->bgp, bgpnode, nbgpnode, bgp))
2360 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2361 if (sockunion_same (&peer->su, su)
2362 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2363 return peer;
2364 }
2365 return NULL;
2366 }
2367
2368 struct peer *
peer_lookup_with_open(union sockunion * su,as_t remote_as,struct in_addr * remote_id,int * as)2369 peer_lookup_with_open (union sockunion *su, as_t remote_as,
2370 struct in_addr *remote_id, int *as)
2371 {
2372 struct peer *peer;
2373 struct listnode *node;
2374 struct listnode *bgpnode;
2375 struct bgp *bgp;
2376
2377 if (! bm->bgp)
2378 return NULL;
2379
2380 for (ALL_LIST_ELEMENTS_RO (bm->bgp, bgpnode, bgp))
2381 {
2382 for (ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
2383 {
2384 if (sockunion_same (&peer->su, su)
2385 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2386 {
2387 if (peer->as == remote_as
2388 && peer->remote_id.s_addr == remote_id->s_addr)
2389 return peer;
2390 if (peer->as == remote_as)
2391 *as = 1;
2392 }
2393 }
2394
2395 for (ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
2396 {
2397 if (sockunion_same (&peer->su, su)
2398 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2399 {
2400 if (peer->as == remote_as
2401 && peer->remote_id.s_addr == 0)
2402 return peer;
2403 if (peer->as == remote_as)
2404 *as = 1;
2405 }
2406 }
2407 }
2408 return NULL;
2409 }
2410
2411 /* If peer is configured at least one address family return 1. */
2412 int
peer_active(struct peer * peer)2413 peer_active (struct peer *peer)
2414 {
2415 if (peer->afc[AFI_IP][SAFI_UNICAST]
2416 || peer->afc[AFI_IP][SAFI_MULTICAST]
2417 || peer->afc[AFI_IP][SAFI_MPLS_VPN]
2418 || peer->afc[AFI_IP][SAFI_ENCAP]
2419 || peer->afc[AFI_IP6][SAFI_UNICAST]
2420 || peer->afc[AFI_IP6][SAFI_MULTICAST]
2421 || peer->afc[AFI_IP6][SAFI_MPLS_VPN]
2422 || peer->afc[AFI_IP6][SAFI_ENCAP])
2423 return 1;
2424 return 0;
2425 }
2426
2427 /* If peer is negotiated at least one address family return 1. */
2428 int
peer_active_nego(struct peer * peer)2429 peer_active_nego (struct peer *peer)
2430 {
2431 if (peer->afc_nego[AFI_IP][SAFI_UNICAST]
2432 || peer->afc_nego[AFI_IP][SAFI_MULTICAST]
2433 || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
2434 || peer->afc_nego[AFI_IP][SAFI_ENCAP]
2435 || peer->afc_nego[AFI_IP6][SAFI_UNICAST]
2436 || peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
2437 || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
2438 || peer->afc_nego[AFI_IP6][SAFI_ENCAP])
2439 return 1;
2440 return 0;
2441 }
2442
2443 /* peer_flag_change_type. */
2444 enum peer_change_type
2445 {
2446 peer_change_none,
2447 peer_change_reset,
2448 peer_change_reset_in,
2449 peer_change_reset_out,
2450 };
2451
2452 static void
peer_change_action(struct peer * peer,afi_t afi,safi_t safi,enum peer_change_type type)2453 peer_change_action (struct peer *peer, afi_t afi, safi_t safi,
2454 enum peer_change_type type)
2455 {
2456 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2457 return;
2458
2459 if (peer->status != Established)
2460 return;
2461
2462 if (type == peer_change_reset)
2463 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2464 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2465 else if (type == peer_change_reset_in)
2466 {
2467 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
2468 || CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
2469 bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
2470 else
2471 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2472 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2473 }
2474 else if (type == peer_change_reset_out)
2475 bgp_announce_route (peer, afi, safi);
2476 }
2477
2478 struct peer_flag_action
2479 {
2480 /* Peer's flag. */
2481 u_int32_t flag;
2482
2483 /* This flag can be set for peer-group member. */
2484 u_char not_for_member;
2485
2486 /* Action when the flag is changed. */
2487 enum peer_change_type type;
2488
2489 /* Peer down cause */
2490 u_char peer_down;
2491 };
2492
2493 static const struct peer_flag_action peer_flag_action_list[] =
2494 {
2495 { PEER_FLAG_PASSIVE, 0, peer_change_reset },
2496 { PEER_FLAG_SHUTDOWN, 0, peer_change_reset },
2497 { PEER_FLAG_DONT_CAPABILITY, 0, peer_change_none },
2498 { PEER_FLAG_OVERRIDE_CAPABILITY, 0, peer_change_none },
2499 { PEER_FLAG_STRICT_CAP_MATCH, 0, peer_change_none },
2500 { PEER_FLAG_DYNAMIC_CAPABILITY, 0, peer_change_reset },
2501 { PEER_FLAG_DISABLE_CONNECTED_CHECK, 0, peer_change_reset },
2502 { 0, 0, 0 }
2503 };
2504
2505 static const struct peer_flag_action peer_af_flag_action_list[] =
2506 {
2507 { PEER_FLAG_NEXTHOP_SELF, 1, peer_change_reset_out },
2508 { PEER_FLAG_SEND_COMMUNITY, 1, peer_change_reset_out },
2509 { PEER_FLAG_SEND_EXT_COMMUNITY, 1, peer_change_reset_out },
2510 { PEER_FLAG_SEND_LARGE_COMMUNITY, 1, peer_change_reset_out },
2511 { PEER_FLAG_SOFT_RECONFIG, 0, peer_change_reset_in },
2512 { PEER_FLAG_REFLECTOR_CLIENT, 1, peer_change_reset },
2513 { PEER_FLAG_RSERVER_CLIENT, 1, peer_change_reset },
2514 { PEER_FLAG_AS_PATH_UNCHANGED, 1, peer_change_reset_out },
2515 { PEER_FLAG_NEXTHOP_UNCHANGED, 1, peer_change_reset_out },
2516 { PEER_FLAG_MED_UNCHANGED, 1, peer_change_reset_out },
2517 { PEER_FLAG_REMOVE_PRIVATE_AS, 1, peer_change_reset_out },
2518 { PEER_FLAG_ALLOWAS_IN, 0, peer_change_reset_in },
2519 { PEER_FLAG_ORF_PREFIX_SM, 1, peer_change_reset },
2520 { PEER_FLAG_ORF_PREFIX_RM, 1, peer_change_reset },
2521 { PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out },
2522 { PEER_FLAG_NEXTHOP_SELF_ALL, 1, peer_change_reset_out },
2523 { 0, 0, 0 }
2524 };
2525
2526 /* Proper action set. */
2527 static int
peer_flag_action_set(const struct peer_flag_action * action_list,int size,struct peer_flag_action * action,u_int32_t flag)2528 peer_flag_action_set (const struct peer_flag_action *action_list, int size,
2529 struct peer_flag_action *action, u_int32_t flag)
2530 {
2531 int i;
2532 int found = 0;
2533 int reset_in = 0;
2534 int reset_out = 0;
2535 const struct peer_flag_action *match = NULL;
2536
2537 /* Check peer's frag action. */
2538 for (i = 0; i < size; i++)
2539 {
2540 match = &action_list[i];
2541
2542 if (match->flag == 0)
2543 break;
2544
2545 if (match->flag & flag)
2546 {
2547 found = 1;
2548
2549 if (match->type == peer_change_reset_in)
2550 reset_in = 1;
2551 if (match->type == peer_change_reset_out)
2552 reset_out = 1;
2553 if (match->type == peer_change_reset)
2554 {
2555 reset_in = 1;
2556 reset_out = 1;
2557 }
2558 if (match->not_for_member)
2559 action->not_for_member = 1;
2560 }
2561 }
2562
2563 /* Set peer clear type. */
2564 if (reset_in && reset_out)
2565 action->type = peer_change_reset;
2566 else if (reset_in)
2567 action->type = peer_change_reset_in;
2568 else if (reset_out)
2569 action->type = peer_change_reset_out;
2570 else
2571 action->type = peer_change_none;
2572
2573 return found;
2574 }
2575
2576 static void
peer_flag_modify_action(struct peer * peer,u_int32_t flag)2577 peer_flag_modify_action (struct peer *peer, u_int32_t flag)
2578 {
2579 if (flag == PEER_FLAG_SHUTDOWN)
2580 {
2581 if (CHECK_FLAG (peer->flags, flag))
2582 {
2583 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
2584 peer_nsf_stop (peer);
2585
2586 UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
2587 if (peer->t_pmax_restart)
2588 {
2589 BGP_TIMER_OFF (peer->t_pmax_restart);
2590 if (BGP_DEBUG (events, EVENTS))
2591 zlog_debug ("%s Maximum-prefix restart timer canceled",
2592 peer->host);
2593 }
2594
2595 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
2596 peer_nsf_stop (peer);
2597
2598 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2599 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2600 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
2601 else
2602 BGP_EVENT_ADD (peer, BGP_Stop);
2603 }
2604 else
2605 {
2606 peer->v_start = BGP_INIT_START_TIMER;
2607 BGP_EVENT_ADD (peer, BGP_Stop);
2608 }
2609 }
2610 else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2611 {
2612 if (flag == PEER_FLAG_DYNAMIC_CAPABILITY)
2613 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2614 else if (flag == PEER_FLAG_PASSIVE)
2615 peer->last_reset = PEER_DOWN_PASSIVE_CHANGE;
2616 else if (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK)
2617 peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE;
2618
2619 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2620 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2621 }
2622 else
2623 BGP_EVENT_ADD (peer, BGP_Stop);
2624 }
2625
2626 /* Change specified peer flag. */
2627 static int
peer_flag_modify(struct peer * peer,u_int32_t flag,int set)2628 peer_flag_modify (struct peer *peer, u_int32_t flag, int set)
2629 {
2630 int found;
2631 int size;
2632 struct peer_group *group;
2633 struct listnode *node, *nnode;
2634 struct peer_flag_action action;
2635
2636 memset (&action, 0, sizeof (struct peer_flag_action));
2637 size = sizeof peer_flag_action_list / sizeof (struct peer_flag_action);
2638
2639 found = peer_flag_action_set (peer_flag_action_list, size, &action, flag);
2640
2641 /* No flag action is found. */
2642 if (! found)
2643 return BGP_ERR_INVALID_FLAG;
2644
2645 /* Not for peer-group member. */
2646 if (action.not_for_member && peer_group_active (peer))
2647 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
2648
2649 /* When unset the peer-group member's flag we have to check
2650 peer-group configuration. */
2651 if (! set && peer_group_active (peer))
2652 if (CHECK_FLAG (peer->group->conf->flags, flag))
2653 {
2654 if (flag == PEER_FLAG_SHUTDOWN)
2655 return BGP_ERR_PEER_GROUP_SHUTDOWN;
2656 else
2657 return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
2658 }
2659
2660 /* Flag conflict check. */
2661 if (set
2662 && CHECK_FLAG (peer->flags | flag, PEER_FLAG_STRICT_CAP_MATCH)
2663 && CHECK_FLAG (peer->flags | flag, PEER_FLAG_OVERRIDE_CAPABILITY))
2664 return BGP_ERR_PEER_FLAG_CONFLICT;
2665
2666 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2667 {
2668 if (set && CHECK_FLAG (peer->flags, flag) == flag)
2669 return 0;
2670 if (! set && ! CHECK_FLAG (peer->flags, flag))
2671 return 0;
2672 }
2673
2674 if (set)
2675 SET_FLAG (peer->flags, flag);
2676 else
2677 UNSET_FLAG (peer->flags, flag);
2678
2679 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2680 {
2681 if (action.type == peer_change_reset)
2682 peer_flag_modify_action (peer, flag);
2683
2684 return 0;
2685 }
2686
2687 /* peer-group member updates. */
2688 group = peer->group;
2689
2690 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2691 {
2692 if (set && CHECK_FLAG (peer->flags, flag) == flag)
2693 continue;
2694
2695 if (! set && ! CHECK_FLAG (peer->flags, flag))
2696 continue;
2697
2698 if (set)
2699 SET_FLAG (peer->flags, flag);
2700 else
2701 UNSET_FLAG (peer->flags, flag);
2702
2703 if (action.type == peer_change_reset)
2704 peer_flag_modify_action (peer, flag);
2705 }
2706 return 0;
2707 }
2708
2709 int
peer_flag_set(struct peer * peer,u_int32_t flag)2710 peer_flag_set (struct peer *peer, u_int32_t flag)
2711 {
2712 return peer_flag_modify (peer, flag, 1);
2713 }
2714
2715 int
peer_flag_unset(struct peer * peer,u_int32_t flag)2716 peer_flag_unset (struct peer *peer, u_int32_t flag)
2717 {
2718 return peer_flag_modify (peer, flag, 0);
2719 }
2720
2721 static int
peer_is_group_member(struct peer * peer,afi_t afi,safi_t safi)2722 peer_is_group_member (struct peer *peer, afi_t afi, safi_t safi)
2723 {
2724 if (peer->af_group[afi][safi])
2725 return 1;
2726 return 0;
2727 }
2728
2729 static int
peer_af_flag_modify(struct peer * peer,afi_t afi,safi_t safi,u_int32_t flag,int set)2730 peer_af_flag_modify (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag,
2731 int set)
2732 {
2733 int found;
2734 int size;
2735 struct listnode *node, *nnode;
2736 struct peer_group *group;
2737 struct peer_flag_action action;
2738
2739 memset (&action, 0, sizeof (struct peer_flag_action));
2740 size = sizeof peer_af_flag_action_list / sizeof (struct peer_flag_action);
2741
2742 found = peer_flag_action_set (peer_af_flag_action_list, size, &action, flag);
2743
2744 /* No flag action is found. */
2745 if (! found)
2746 return BGP_ERR_INVALID_FLAG;
2747
2748 /* Adress family must be activated. */
2749 if (! peer->afc[afi][safi])
2750 return BGP_ERR_PEER_INACTIVE;
2751
2752 /* Not for peer-group member. */
2753 if (action.not_for_member && peer_is_group_member (peer, afi, safi))
2754 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
2755
2756 /* Spcecial check for reflector client. */
2757 if (flag & PEER_FLAG_REFLECTOR_CLIENT
2758 && peer_sort (peer) != BGP_PEER_IBGP)
2759 return BGP_ERR_NOT_INTERNAL_PEER;
2760
2761 /* Spcecial check for remove-private-AS. */
2762 if (flag & PEER_FLAG_REMOVE_PRIVATE_AS
2763 && peer_sort (peer) == BGP_PEER_IBGP)
2764 return BGP_ERR_REMOVE_PRIVATE_AS;
2765
2766 /* When unset the peer-group member's flag we have to check
2767 peer-group configuration. */
2768 if (! set && peer->af_group[afi][safi])
2769 if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi], flag))
2770 return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
2771
2772 /* When current flag configuration is same as requested one. */
2773 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2774 {
2775 if (set && CHECK_FLAG (peer->af_flags[afi][safi], flag) == flag)
2776 return 0;
2777 if (! set && ! CHECK_FLAG (peer->af_flags[afi][safi], flag))
2778 return 0;
2779 }
2780
2781 if (set)
2782 SET_FLAG (peer->af_flags[afi][safi], flag);
2783 else
2784 UNSET_FLAG (peer->af_flags[afi][safi], flag);
2785
2786 /* Execute action when peer is established. */
2787 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
2788 && peer->status == Established)
2789 {
2790 if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
2791 bgp_clear_adj_in (peer, afi, safi);
2792 else
2793 {
2794 if (flag == PEER_FLAG_REFLECTOR_CLIENT)
2795 peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
2796 else if (flag == PEER_FLAG_RSERVER_CLIENT)
2797 peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
2798 else if (flag == PEER_FLAG_ORF_PREFIX_SM)
2799 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2800 else if (flag == PEER_FLAG_ORF_PREFIX_RM)
2801 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2802
2803 peer_change_action (peer, afi, safi, action.type);
2804 }
2805
2806 }
2807
2808 /* Peer group member updates. */
2809 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2810 {
2811 group = peer->group;
2812
2813 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2814 {
2815 if (! peer->af_group[afi][safi])
2816 continue;
2817
2818 if (set && CHECK_FLAG (peer->af_flags[afi][safi], flag) == flag)
2819 continue;
2820
2821 if (! set && ! CHECK_FLAG (peer->af_flags[afi][safi], flag))
2822 continue;
2823
2824 if (set)
2825 SET_FLAG (peer->af_flags[afi][safi], flag);
2826 else
2827 UNSET_FLAG (peer->af_flags[afi][safi], flag);
2828
2829 if (peer->status == Established)
2830 {
2831 if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
2832 bgp_clear_adj_in (peer, afi, safi);
2833 else
2834 {
2835 if (flag == PEER_FLAG_REFLECTOR_CLIENT)
2836 peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
2837 else if (flag == PEER_FLAG_RSERVER_CLIENT)
2838 peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
2839 else if (flag == PEER_FLAG_ORF_PREFIX_SM)
2840 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2841 else if (flag == PEER_FLAG_ORF_PREFIX_RM)
2842 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2843
2844 peer_change_action (peer, afi, safi, action.type);
2845 }
2846 }
2847 }
2848 }
2849 return 0;
2850 }
2851
2852 int
peer_af_flag_set(struct peer * peer,afi_t afi,safi_t safi,u_int32_t flag)2853 peer_af_flag_set (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
2854 {
2855 return peer_af_flag_modify (peer, afi, safi, flag, 1);
2856 }
2857
2858 int
peer_af_flag_unset(struct peer * peer,afi_t afi,safi_t safi,u_int32_t flag)2859 peer_af_flag_unset (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
2860 {
2861 return peer_af_flag_modify (peer, afi, safi, flag, 0);
2862 }
2863
2864 /* EBGP multihop configuration. */
2865 int
peer_ebgp_multihop_set(struct peer * peer,int ttl)2866 peer_ebgp_multihop_set (struct peer *peer, int ttl)
2867 {
2868 struct peer_group *group;
2869 struct listnode *node, *nnode;
2870 struct peer *peer1;
2871
2872 if (peer->sort == BGP_PEER_IBGP)
2873 return BGP_ERR_NO_IBGP_WITH_TTLHACK;
2874
2875 if (peer->gtsm_hops != 0)
2876 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
2877
2878 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2879 {
2880 group = peer->group;
2881 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
2882 {
2883 if (peer1->gtsm_hops != 0)
2884 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
2885 }
2886 }
2887
2888 peer->ttl = ttl;
2889
2890 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2891 {
2892 bgp_set_socket_ttl (peer, peer->fd);
2893 }
2894 else
2895 {
2896 group = peer->group;
2897 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2898 {
2899 peer->ttl = ttl;
2900 bgp_set_socket_ttl (peer, peer->fd);
2901 }
2902 }
2903
2904 return 0;
2905 }
2906
2907 /* Neighbor description. */
2908 int
peer_description_set(struct peer * peer,const char * desc)2909 peer_description_set (struct peer *peer, const char *desc)
2910 {
2911 if (peer->desc)
2912 XFREE (MTYPE_PEER_DESC, peer->desc);
2913
2914 peer->desc = XSTRDUP (MTYPE_PEER_DESC, desc);
2915
2916 return 0;
2917 }
2918
2919 int
peer_description_unset(struct peer * peer)2920 peer_description_unset (struct peer *peer)
2921 {
2922 if (peer->desc)
2923 XFREE (MTYPE_PEER_DESC, peer->desc);
2924
2925 peer->desc = NULL;
2926
2927 return 0;
2928 }
2929
2930 /* Neighbor update-source. */
2931 int
peer_update_source_if_set(struct peer * peer,const char * ifname)2932 peer_update_source_if_set (struct peer *peer, const char *ifname)
2933 {
2934 struct peer_group *group;
2935 struct listnode *node, *nnode;
2936
2937 if (peer->update_if)
2938 {
2939 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
2940 && strcmp (peer->update_if, ifname) == 0)
2941 return 0;
2942
2943 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2944 peer->update_if = NULL;
2945 }
2946
2947 if (peer->update_source)
2948 {
2949 sockunion_free (peer->update_source);
2950 peer->update_source = NULL;
2951 }
2952
2953 peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname);
2954
2955 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2956 {
2957 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2958 {
2959 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2960 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2961 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2962 }
2963 else
2964 BGP_EVENT_ADD (peer, BGP_Stop);
2965 return 0;
2966 }
2967
2968 /* peer-group member updates. */
2969 group = peer->group;
2970 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2971 {
2972 if (peer->update_if)
2973 {
2974 if (strcmp (peer->update_if, ifname) == 0)
2975 continue;
2976
2977 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2978 peer->update_if = NULL;
2979 }
2980
2981 if (peer->update_source)
2982 {
2983 sockunion_free (peer->update_source);
2984 peer->update_source = NULL;
2985 }
2986
2987 peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname);
2988
2989 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2990 {
2991 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2992 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2993 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2994 }
2995 else
2996 BGP_EVENT_ADD (peer, BGP_Stop);
2997 }
2998 return 0;
2999 }
3000
3001 int
peer_update_source_addr_set(struct peer * peer,const union sockunion * su)3002 peer_update_source_addr_set (struct peer *peer, const union sockunion *su)
3003 {
3004 struct peer_group *group;
3005 struct listnode *node, *nnode;
3006
3007 if (peer->update_source)
3008 {
3009 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
3010 && sockunion_cmp (peer->update_source, su) == 0)
3011 return 0;
3012 sockunion_free (peer->update_source);
3013 peer->update_source = NULL;
3014 }
3015
3016 if (peer->update_if)
3017 {
3018 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
3019 peer->update_if = NULL;
3020 }
3021
3022 peer->update_source = sockunion_dup (su);
3023
3024 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3025 {
3026 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3027 {
3028 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
3029 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3030 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3031 }
3032 else
3033 BGP_EVENT_ADD (peer, BGP_Stop);
3034 return 0;
3035 }
3036
3037 /* peer-group member updates. */
3038 group = peer->group;
3039 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3040 {
3041 if (peer->update_source)
3042 {
3043 if (sockunion_cmp (peer->update_source, su) == 0)
3044 continue;
3045 sockunion_free (peer->update_source);
3046 peer->update_source = NULL;
3047 }
3048
3049 if (peer->update_if)
3050 {
3051 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
3052 peer->update_if = NULL;
3053 }
3054
3055 peer->update_source = sockunion_dup (su);
3056
3057 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3058 {
3059 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
3060 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3061 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3062 }
3063 else
3064 BGP_EVENT_ADD (peer, BGP_Stop);
3065 }
3066 return 0;
3067 }
3068
3069 int
peer_update_source_unset(struct peer * peer)3070 peer_update_source_unset (struct peer *peer)
3071 {
3072 union sockunion *su;
3073 struct peer_group *group;
3074 struct listnode *node, *nnode;
3075
3076 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
3077 && ! peer->update_source
3078 && ! peer->update_if)
3079 return 0;
3080
3081 if (peer->update_source)
3082 {
3083 sockunion_free (peer->update_source);
3084 peer->update_source = NULL;
3085 }
3086 if (peer->update_if)
3087 {
3088 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
3089 peer->update_if = NULL;
3090 }
3091
3092 if (peer_group_active (peer))
3093 {
3094 group = peer->group;
3095
3096 if (group->conf->update_source)
3097 {
3098 su = sockunion_dup (group->conf->update_source);
3099 peer->update_source = su;
3100 }
3101 else if (group->conf->update_if)
3102 peer->update_if =
3103 XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, group->conf->update_if);
3104 }
3105
3106 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3107 {
3108 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3109 {
3110 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
3111 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3112 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3113 }
3114 else
3115 BGP_EVENT_ADD (peer, BGP_Stop);
3116 return 0;
3117 }
3118
3119 /* peer-group member updates. */
3120 group = peer->group;
3121 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3122 {
3123 if (! peer->update_source && ! peer->update_if)
3124 continue;
3125
3126 if (peer->update_source)
3127 {
3128 sockunion_free (peer->update_source);
3129 peer->update_source = NULL;
3130 }
3131
3132 if (peer->update_if)
3133 {
3134 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
3135 peer->update_if = NULL;
3136 }
3137
3138 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3139 {
3140 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
3141 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3142 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3143 }
3144 else
3145 BGP_EVENT_ADD (peer, BGP_Stop);
3146 }
3147 return 0;
3148 }
3149
3150 int
peer_default_originate_set(struct peer * peer,afi_t afi,safi_t safi,const char * rmap)3151 peer_default_originate_set (struct peer *peer, afi_t afi, safi_t safi,
3152 const char *rmap)
3153 {
3154 struct peer_group *group;
3155 struct listnode *node, *nnode;
3156
3157 /* Adress family must be activated. */
3158 if (! peer->afc[afi][safi])
3159 return BGP_ERR_PEER_INACTIVE;
3160
3161 /* Default originate can't be used for peer group memeber. */
3162 if (peer_is_group_member (peer, afi, safi))
3163 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3164
3165 if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)
3166 || (rmap && ! peer->default_rmap[afi][safi].name)
3167 || (rmap && strcmp (rmap, peer->default_rmap[afi][safi].name) != 0))
3168 {
3169 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
3170
3171 if (rmap)
3172 {
3173 if (peer->default_rmap[afi][safi].name)
3174 free (peer->default_rmap[afi][safi].name);
3175 peer->default_rmap[afi][safi].name = strdup (rmap);
3176 peer->default_rmap[afi][safi].map = route_map_lookup_by_name (rmap);
3177 }
3178 }
3179
3180 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3181 {
3182 if (peer->status == Established && peer->afc_nego[afi][safi])
3183 bgp_default_originate (peer, afi, safi, 0);
3184 return 0;
3185 }
3186
3187 /* peer-group member updates. */
3188 group = peer->group;
3189 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3190 {
3191 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
3192
3193 if (rmap)
3194 {
3195 if (peer->default_rmap[afi][safi].name)
3196 free (peer->default_rmap[afi][safi].name);
3197 peer->default_rmap[afi][safi].name = strdup (rmap);
3198 peer->default_rmap[afi][safi].map = route_map_lookup_by_name (rmap);
3199 }
3200
3201 if (peer->status == Established && peer->afc_nego[afi][safi])
3202 bgp_default_originate (peer, afi, safi, 0);
3203 }
3204 return 0;
3205 }
3206
3207 int
peer_default_originate_unset(struct peer * peer,afi_t afi,safi_t safi)3208 peer_default_originate_unset (struct peer *peer, afi_t afi, safi_t safi)
3209 {
3210 struct peer_group *group;
3211 struct listnode *node, *nnode;
3212
3213 /* Adress family must be activated. */
3214 if (! peer->afc[afi][safi])
3215 return BGP_ERR_PEER_INACTIVE;
3216
3217 /* Default originate can't be used for peer group memeber. */
3218 if (peer_is_group_member (peer, afi, safi))
3219 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3220
3221 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE))
3222 {
3223 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
3224
3225 if (peer->default_rmap[afi][safi].name)
3226 free (peer->default_rmap[afi][safi].name);
3227 peer->default_rmap[afi][safi].name = NULL;
3228 peer->default_rmap[afi][safi].map = NULL;
3229 }
3230
3231 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3232 {
3233 if (peer->status == Established && peer->afc_nego[afi][safi])
3234 bgp_default_originate (peer, afi, safi, 1);
3235 return 0;
3236 }
3237
3238 /* peer-group member updates. */
3239 group = peer->group;
3240 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3241 {
3242 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
3243
3244 if (peer->default_rmap[afi][safi].name)
3245 free (peer->default_rmap[afi][safi].name);
3246 peer->default_rmap[afi][safi].name = NULL;
3247 peer->default_rmap[afi][safi].map = NULL;
3248
3249 if (peer->status == Established && peer->afc_nego[afi][safi])
3250 bgp_default_originate (peer, afi, safi, 1);
3251 }
3252 return 0;
3253 }
3254
3255 int
peer_port_set(struct peer * peer,u_int16_t port)3256 peer_port_set (struct peer *peer, u_int16_t port)
3257 {
3258 peer->port = port;
3259 return 0;
3260 }
3261
3262 int
peer_port_unset(struct peer * peer)3263 peer_port_unset (struct peer *peer)
3264 {
3265 peer->port = BGP_PORT_DEFAULT;
3266 return 0;
3267 }
3268
3269 /* neighbor weight. */
3270 int
peer_weight_set(struct peer * peer,u_int16_t weight)3271 peer_weight_set (struct peer *peer, u_int16_t weight)
3272 {
3273 struct peer_group *group;
3274 struct listnode *node, *nnode;
3275
3276 SET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
3277 peer->weight = weight;
3278
3279 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3280 return 0;
3281
3282 /* peer-group member updates. */
3283 group = peer->group;
3284 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3285 {
3286 peer->weight = group->conf->weight;
3287 }
3288 return 0;
3289 }
3290
3291 int
peer_weight_unset(struct peer * peer)3292 peer_weight_unset (struct peer *peer)
3293 {
3294 struct peer_group *group;
3295 struct listnode *node, *nnode;
3296
3297 /* Set default weight. */
3298 if (peer_group_active (peer))
3299 peer->weight = peer->group->conf->weight;
3300 else
3301 peer->weight = 0;
3302
3303 UNSET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
3304
3305 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3306 return 0;
3307
3308 /* peer-group member updates. */
3309 group = peer->group;
3310 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3311 {
3312 peer->weight = 0;
3313 }
3314 return 0;
3315 }
3316
3317 int
peer_timers_set(struct peer * peer,u_int32_t keepalive,u_int32_t holdtime)3318 peer_timers_set (struct peer *peer, u_int32_t keepalive, u_int32_t holdtime)
3319 {
3320 struct peer_group *group;
3321 struct listnode *node, *nnode;
3322
3323 /* Not for peer group memeber. */
3324 if (peer_group_active (peer))
3325 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3326
3327 /* keepalive value check. */
3328 if (keepalive > 65535)
3329 return BGP_ERR_INVALID_VALUE;
3330
3331 /* Holdtime value check. */
3332 if (holdtime > 65535)
3333 return BGP_ERR_INVALID_VALUE;
3334
3335 /* Holdtime value must be either 0 or greater than 3. */
3336 if (holdtime < 3 && holdtime != 0)
3337 return BGP_ERR_INVALID_VALUE;
3338
3339 /* Set value to the configuration. */
3340 SET_FLAG (peer->config, PEER_CONFIG_TIMER);
3341 peer->holdtime = holdtime;
3342 peer->keepalive = (keepalive < holdtime / 3 ? keepalive : holdtime / 3);
3343
3344 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3345 return 0;
3346
3347 /* peer-group member updates. */
3348 group = peer->group;
3349 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3350 {
3351 SET_FLAG (peer->config, PEER_CONFIG_TIMER);
3352 peer->holdtime = group->conf->holdtime;
3353 peer->keepalive = group->conf->keepalive;
3354 }
3355 return 0;
3356 }
3357
3358 int
peer_timers_unset(struct peer * peer)3359 peer_timers_unset (struct peer *peer)
3360 {
3361 struct peer_group *group;
3362 struct listnode *node, *nnode;
3363
3364 if (peer_group_active (peer))
3365 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3366
3367 /* Clear configuration. */
3368 UNSET_FLAG (peer->config, PEER_CONFIG_TIMER);
3369 peer->keepalive = 0;
3370 peer->holdtime = 0;
3371
3372 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3373 return 0;
3374
3375 /* peer-group member updates. */
3376 group = peer->group;
3377 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3378 {
3379 UNSET_FLAG (peer->config, PEER_CONFIG_TIMER);
3380 peer->holdtime = 0;
3381 peer->keepalive = 0;
3382 }
3383
3384 return 0;
3385 }
3386
3387 int
peer_timers_connect_set(struct peer * peer,u_int32_t connect)3388 peer_timers_connect_set (struct peer *peer, u_int32_t connect)
3389 {
3390 struct peer_group *group;
3391 struct listnode *node, *nnode;
3392
3393 if (peer_group_active (peer))
3394 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3395
3396 if (connect > 65535)
3397 return BGP_ERR_INVALID_VALUE;
3398
3399 /* Set value to the configuration. */
3400 SET_FLAG (peer->config, PEER_CONFIG_CONNECT);
3401 peer->connect = connect;
3402
3403 /* Set value to timer setting. */
3404 peer->v_connect = connect;
3405
3406 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3407 return 0;
3408
3409 /* peer-group member updates. */
3410 group = peer->group;
3411 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3412 {
3413 SET_FLAG (peer->config, PEER_CONFIG_CONNECT);
3414 peer->connect = connect;
3415 peer->v_connect = connect;
3416 }
3417 return 0;
3418 }
3419
3420 int
peer_timers_connect_unset(struct peer * peer)3421 peer_timers_connect_unset (struct peer *peer)
3422 {
3423 struct peer_group *group;
3424 struct listnode *node, *nnode;
3425
3426 if (peer_group_active (peer))
3427 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3428
3429 /* Clear configuration. */
3430 UNSET_FLAG (peer->config, PEER_CONFIG_CONNECT);
3431 peer->connect = 0;
3432
3433 /* Set timer setting to default value. */
3434 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
3435
3436 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3437 return 0;
3438
3439 /* peer-group member updates. */
3440 group = peer->group;
3441 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3442 {
3443 UNSET_FLAG (peer->config, PEER_CONFIG_CONNECT);
3444 peer->connect = 0;
3445 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
3446 }
3447 return 0;
3448 }
3449
3450 int
peer_advertise_interval_set(struct peer * peer,u_int32_t routeadv)3451 peer_advertise_interval_set (struct peer *peer, u_int32_t routeadv)
3452 {
3453 struct peer_group *group;
3454 struct listnode *node, *nnode;
3455
3456 if (peer_group_active (peer))
3457 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3458
3459 if (routeadv > 600)
3460 return BGP_ERR_INVALID_VALUE;
3461
3462 SET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
3463 peer->routeadv = routeadv;
3464 peer->v_routeadv = routeadv;
3465
3466 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3467 return 0;
3468
3469 /* peer-group member updates. */
3470 group = peer->group;
3471 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3472 {
3473 SET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
3474 peer->routeadv = routeadv;
3475 peer->v_routeadv = routeadv;
3476 }
3477
3478 return 0;
3479 }
3480
3481 int
peer_advertise_interval_unset(struct peer * peer)3482 peer_advertise_interval_unset (struct peer *peer)
3483 {
3484 struct peer_group *group;
3485 struct listnode *node, *nnode;
3486
3487 if (peer_group_active (peer))
3488 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3489
3490 UNSET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
3491 peer->routeadv = 0;
3492
3493 if (peer->sort == BGP_PEER_IBGP)
3494 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
3495 else
3496 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
3497
3498 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3499 return 0;
3500
3501 /* peer-group member updates. */
3502 group = peer->group;
3503 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3504 {
3505 UNSET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
3506 peer->routeadv = 0;
3507
3508 if (peer->sort == BGP_PEER_IBGP)
3509 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
3510 else
3511 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
3512 }
3513
3514 return 0;
3515 }
3516
3517 /* neighbor interface */
3518 int
peer_interface_set(struct peer * peer,const char * str)3519 peer_interface_set (struct peer *peer, const char *str)
3520 {
3521 if (peer->ifname)
3522 free (peer->ifname);
3523 peer->ifname = strdup (str);
3524
3525 return 0;
3526 }
3527
3528 int
peer_interface_unset(struct peer * peer)3529 peer_interface_unset (struct peer *peer)
3530 {
3531 if (peer->ifname)
3532 free (peer->ifname);
3533 peer->ifname = NULL;
3534
3535 return 0;
3536 }
3537
3538 /* Allow-as in. */
3539 int
peer_allowas_in_set(struct peer * peer,afi_t afi,safi_t safi,int allow_num)3540 peer_allowas_in_set (struct peer *peer, afi_t afi, safi_t safi, int allow_num)
3541 {
3542 struct peer_group *group;
3543 struct listnode *node, *nnode;
3544
3545 if (allow_num < 1 || allow_num > 10)
3546 return BGP_ERR_INVALID_VALUE;
3547
3548 if (peer->allowas_in[afi][safi] != allow_num)
3549 {
3550 peer->allowas_in[afi][safi] = allow_num;
3551 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
3552 peer_change_action (peer, afi, safi, peer_change_reset_in);
3553 }
3554
3555 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3556 return 0;
3557
3558 group = peer->group;
3559 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3560 {
3561 if (peer->allowas_in[afi][safi] != allow_num)
3562 {
3563 peer->allowas_in[afi][safi] = allow_num;
3564 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
3565 peer_change_action (peer, afi, safi, peer_change_reset_in);
3566 }
3567
3568 }
3569 return 0;
3570 }
3571
3572 int
peer_allowas_in_unset(struct peer * peer,afi_t afi,safi_t safi)3573 peer_allowas_in_unset (struct peer *peer, afi_t afi, safi_t safi)
3574 {
3575 struct peer_group *group;
3576 struct listnode *node, *nnode;
3577
3578 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
3579 {
3580 peer->allowas_in[afi][safi] = 0;
3581 peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
3582 }
3583
3584 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3585 return 0;
3586
3587 group = peer->group;
3588 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3589 {
3590 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
3591 {
3592 peer->allowas_in[afi][safi] = 0;
3593 peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
3594 }
3595 }
3596 return 0;
3597 }
3598
3599 int
peer_local_as_set(struct peer * peer,as_t as,int no_prepend,int replace_as)3600 peer_local_as_set (struct peer *peer, as_t as, int no_prepend, int replace_as)
3601 {
3602 struct bgp *bgp = peer->bgp;
3603 struct peer_group *group;
3604 struct listnode *node, *nnode;
3605
3606 if (peer_sort (peer) != BGP_PEER_EBGP
3607 && peer_sort (peer) != BGP_PEER_INTERNAL)
3608 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP;
3609
3610 if (bgp->as == as)
3611 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS;
3612
3613 if (peer_group_active (peer))
3614 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3615
3616 if (peer->as == as)
3617 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS;
3618
3619 if (peer->change_local_as == as &&
3620 ((CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) && no_prepend)
3621 || (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) && ! no_prepend)) &&
3622 ((CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) && replace_as)
3623 || (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) && ! replace_as)))
3624 return 0;
3625
3626 peer->change_local_as = as;
3627 if (no_prepend)
3628 SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3629 else
3630 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3631
3632 if (replace_as)
3633 SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
3634 else
3635 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
3636
3637 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3638 {
3639 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3640 {
3641 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3642 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3643 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3644 }
3645 else
3646 BGP_EVENT_ADD (peer, BGP_Stop);
3647
3648 return 0;
3649 }
3650
3651 group = peer->group;
3652 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3653 {
3654 peer->change_local_as = as;
3655 if (no_prepend)
3656 SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3657 else
3658 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3659
3660 if (replace_as)
3661 SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
3662 else
3663 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
3664
3665 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3666 {
3667 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3668 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3669 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3670 }
3671 else
3672 BGP_EVENT_ADD (peer, BGP_Stop);
3673 }
3674
3675 return 0;
3676 }
3677
3678 int
peer_local_as_unset(struct peer * peer)3679 peer_local_as_unset (struct peer *peer)
3680 {
3681 struct peer_group *group;
3682 struct listnode *node, *nnode;
3683
3684 if (peer_group_active (peer))
3685 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3686
3687 if (! peer->change_local_as)
3688 return 0;
3689
3690 peer->change_local_as = 0;
3691 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3692 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
3693
3694 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3695 {
3696 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3697 {
3698 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3699 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3700 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3701 }
3702 else
3703 BGP_EVENT_ADD (peer, BGP_Stop);
3704
3705 return 0;
3706 }
3707
3708 group = peer->group;
3709 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3710 {
3711 peer->change_local_as = 0;
3712 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3713 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
3714
3715 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3716 {
3717 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3718 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3719 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3720 }
3721 else
3722 BGP_EVENT_ADD (peer, BGP_Stop);
3723 }
3724 return 0;
3725 }
3726
3727 /* Set password for authenticating with the peer. */
3728 int
peer_password_set(struct peer * peer,const char * password)3729 peer_password_set (struct peer *peer, const char *password)
3730 {
3731 struct listnode *nn, *nnode;
3732 int len = password ? strlen(password) : 0;
3733 int ret = BGP_SUCCESS;
3734
3735 if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
3736 return BGP_ERR_INVALID_VALUE;
3737
3738 if (peer->password && strcmp (peer->password, password) == 0
3739 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3740 return 0;
3741
3742 if (peer->password)
3743 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3744
3745 peer->password = XSTRDUP (MTYPE_PEER_PASSWORD, password);
3746
3747 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3748 {
3749 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3750 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3751 else
3752 BGP_EVENT_ADD (peer, BGP_Stop);
3753
3754 return (bgp_md5_set (peer) >= 0) ? BGP_SUCCESS : BGP_ERR_TCPSIG_FAILED;
3755 }
3756
3757 for (ALL_LIST_ELEMENTS (peer->group->peer, nn, nnode, peer))
3758 {
3759 if (peer->password && strcmp (peer->password, password) == 0)
3760 continue;
3761
3762 if (peer->password)
3763 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3764
3765 peer->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
3766
3767 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3768 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3769 else
3770 BGP_EVENT_ADD (peer, BGP_Stop);
3771
3772 if (bgp_md5_set (peer) < 0)
3773 ret = BGP_ERR_TCPSIG_FAILED;
3774 }
3775
3776 return ret;
3777 }
3778
3779 int
peer_password_unset(struct peer * peer)3780 peer_password_unset (struct peer *peer)
3781 {
3782 struct listnode *nn, *nnode;
3783
3784 if (!peer->password
3785 && !CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3786 return 0;
3787
3788 if (!CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3789 {
3790 if (peer_group_active (peer)
3791 && peer->group->conf->password
3792 && strcmp (peer->group->conf->password, peer->password) == 0)
3793 return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
3794
3795 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3796 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3797 else
3798 BGP_EVENT_ADD (peer, BGP_Stop);
3799
3800 if (peer->password)
3801 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3802
3803 peer->password = NULL;
3804
3805 bgp_md5_set (peer);
3806
3807 return 0;
3808 }
3809
3810 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3811 peer->password = NULL;
3812
3813 for (ALL_LIST_ELEMENTS (peer->group->peer, nn, nnode, peer))
3814 {
3815 if (!peer->password)
3816 continue;
3817
3818 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3819 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3820 else
3821 BGP_EVENT_ADD (peer, BGP_Stop);
3822
3823 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3824 peer->password = NULL;
3825
3826 bgp_md5_set (peer);
3827 }
3828
3829 return 0;
3830 }
3831
3832 /* Set distribute list to the peer. */
3833 int
peer_distribute_set(struct peer * peer,afi_t afi,safi_t safi,int direct,const char * name)3834 peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
3835 const char *name)
3836 {
3837 struct bgp_filter *filter;
3838 struct peer_group *group;
3839 struct listnode *node, *nnode;
3840
3841 if (! peer->afc[afi][safi])
3842 return BGP_ERR_PEER_INACTIVE;
3843
3844 if (direct != FILTER_IN && direct != FILTER_OUT)
3845 return BGP_ERR_INVALID_VALUE;
3846
3847 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3848 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3849
3850 filter = &peer->filter[afi][safi];
3851
3852 if (filter->plist[direct].name)
3853 return BGP_ERR_PEER_FILTER_CONFLICT;
3854
3855 if (filter->dlist[direct].name)
3856 free (filter->dlist[direct].name);
3857 filter->dlist[direct].name = strdup (name);
3858 filter->dlist[direct].alist = access_list_lookup (afi, name);
3859
3860 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3861 return 0;
3862
3863 group = peer->group;
3864 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3865 {
3866 filter = &peer->filter[afi][safi];
3867
3868 if (! peer->af_group[afi][safi])
3869 continue;
3870
3871 if (filter->dlist[direct].name)
3872 free (filter->dlist[direct].name);
3873 filter->dlist[direct].name = strdup (name);
3874 filter->dlist[direct].alist = access_list_lookup (afi, name);
3875 }
3876
3877 return 0;
3878 }
3879
3880 int
peer_distribute_unset(struct peer * peer,afi_t afi,safi_t safi,int direct)3881 peer_distribute_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
3882 {
3883 struct bgp_filter *filter;
3884 struct bgp_filter *gfilter;
3885 struct peer_group *group;
3886 struct listnode *node, *nnode;
3887
3888 if (! peer->afc[afi][safi])
3889 return BGP_ERR_PEER_INACTIVE;
3890
3891 if (direct != FILTER_IN && direct != FILTER_OUT)
3892 return BGP_ERR_INVALID_VALUE;
3893
3894 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3895 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3896
3897 filter = &peer->filter[afi][safi];
3898
3899 /* apply peer-group filter */
3900 if (peer->af_group[afi][safi])
3901 {
3902 gfilter = &peer->group->conf->filter[afi][safi];
3903
3904 if (gfilter->dlist[direct].name)
3905 {
3906 if (filter->dlist[direct].name)
3907 free (filter->dlist[direct].name);
3908 filter->dlist[direct].name = strdup (gfilter->dlist[direct].name);
3909 filter->dlist[direct].alist = gfilter->dlist[direct].alist;
3910 return 0;
3911 }
3912 }
3913
3914 if (filter->dlist[direct].name)
3915 free (filter->dlist[direct].name);
3916 filter->dlist[direct].name = NULL;
3917 filter->dlist[direct].alist = NULL;
3918
3919 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3920 return 0;
3921
3922 group = peer->group;
3923 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3924 {
3925 filter = &peer->filter[afi][safi];
3926
3927 if (! peer->af_group[afi][safi])
3928 continue;
3929
3930 if (filter->dlist[direct].name)
3931 free (filter->dlist[direct].name);
3932 filter->dlist[direct].name = NULL;
3933 filter->dlist[direct].alist = NULL;
3934 }
3935
3936 return 0;
3937 }
3938
3939 /* Update distribute list. */
3940 static void
peer_distribute_update(const char * name)3941 peer_distribute_update (const char *name)
3942 {
3943 afi_t afi;
3944 safi_t safi;
3945 int direct;
3946 struct listnode *mnode, *mnnode;
3947 struct listnode *node, *nnode;
3948 struct bgp *bgp;
3949 struct peer *peer;
3950 struct peer_group *group;
3951 struct bgp_filter *filter;
3952
3953 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
3954 {
3955 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
3956 {
3957 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3958 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3959 {
3960 filter = &peer->filter[afi][safi];
3961
3962 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
3963 {
3964 if (filter->dlist[direct].name)
3965 filter->dlist[direct].alist =
3966 access_list_lookup (afi, filter->dlist[direct].name);
3967 else
3968 filter->dlist[direct].alist = NULL;
3969 }
3970 }
3971 }
3972 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
3973 {
3974 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3975 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3976 {
3977 filter = &group->conf->filter[afi][safi];
3978
3979 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
3980 {
3981 if (filter->dlist[direct].name)
3982 filter->dlist[direct].alist =
3983 access_list_lookup (afi, filter->dlist[direct].name);
3984 else
3985 filter->dlist[direct].alist = NULL;
3986 }
3987 }
3988 }
3989 }
3990 }
3991
3992 /* Set prefix list to the peer. */
3993 int
peer_prefix_list_set(struct peer * peer,afi_t afi,safi_t safi,int direct,const char * name)3994 peer_prefix_list_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
3995 const char *name)
3996 {
3997 struct bgp_filter *filter;
3998 struct peer_group *group;
3999 struct listnode *node, *nnode;
4000
4001 if (! peer->afc[afi][safi])
4002 return BGP_ERR_PEER_INACTIVE;
4003
4004 if (direct != FILTER_IN && direct != FILTER_OUT)
4005 return BGP_ERR_INVALID_VALUE;
4006
4007 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
4008 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4009
4010 filter = &peer->filter[afi][safi];
4011
4012 if (filter->dlist[direct].name)
4013 return BGP_ERR_PEER_FILTER_CONFLICT;
4014
4015 if (filter->plist[direct].name)
4016 free (filter->plist[direct].name);
4017 filter->plist[direct].name = strdup (name);
4018 filter->plist[direct].plist = prefix_list_lookup (afi, name);
4019
4020 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4021 return 0;
4022
4023 group = peer->group;
4024 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4025 {
4026 filter = &peer->filter[afi][safi];
4027
4028 if (! peer->af_group[afi][safi])
4029 continue;
4030
4031 if (filter->plist[direct].name)
4032 free (filter->plist[direct].name);
4033 filter->plist[direct].name = strdup (name);
4034 filter->plist[direct].plist = prefix_list_lookup (afi, name);
4035 }
4036 return 0;
4037 }
4038
4039 int
peer_prefix_list_unset(struct peer * peer,afi_t afi,safi_t safi,int direct)4040 peer_prefix_list_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
4041 {
4042 struct bgp_filter *filter;
4043 struct bgp_filter *gfilter;
4044 struct peer_group *group;
4045 struct listnode *node, *nnode;
4046
4047 if (! peer->afc[afi][safi])
4048 return BGP_ERR_PEER_INACTIVE;
4049
4050 if (direct != FILTER_IN && direct != FILTER_OUT)
4051 return BGP_ERR_INVALID_VALUE;
4052
4053 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
4054 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4055
4056 filter = &peer->filter[afi][safi];
4057
4058 /* apply peer-group filter */
4059 if (peer->af_group[afi][safi])
4060 {
4061 gfilter = &peer->group->conf->filter[afi][safi];
4062
4063 if (gfilter->plist[direct].name)
4064 {
4065 if (filter->plist[direct].name)
4066 free (filter->plist[direct].name);
4067 filter->plist[direct].name = strdup (gfilter->plist[direct].name);
4068 filter->plist[direct].plist = gfilter->plist[direct].plist;
4069 return 0;
4070 }
4071 }
4072
4073 if (filter->plist[direct].name)
4074 free (filter->plist[direct].name);
4075 filter->plist[direct].name = NULL;
4076 filter->plist[direct].plist = NULL;
4077
4078 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4079 return 0;
4080
4081 group = peer->group;
4082 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4083 {
4084 filter = &peer->filter[afi][safi];
4085
4086 if (! peer->af_group[afi][safi])
4087 continue;
4088
4089 if (filter->plist[direct].name)
4090 free (filter->plist[direct].name);
4091 filter->plist[direct].name = NULL;
4092 filter->plist[direct].plist = NULL;
4093 }
4094
4095 return 0;
4096 }
4097
4098 /* Update prefix-list list. */
4099 static void
peer_prefix_list_update(struct prefix_list * plist)4100 peer_prefix_list_update (struct prefix_list *plist)
4101 {
4102 struct listnode *mnode, *mnnode;
4103 struct listnode *node, *nnode;
4104 struct bgp *bgp;
4105 struct peer *peer;
4106 struct peer_group *group;
4107 struct bgp_filter *filter;
4108 afi_t afi;
4109 safi_t safi;
4110 int direct;
4111
4112 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
4113 {
4114 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
4115 {
4116 for (afi = AFI_IP; afi < AFI_MAX; afi++)
4117 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
4118 {
4119 filter = &peer->filter[afi][safi];
4120
4121 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
4122 {
4123 if (filter->plist[direct].name)
4124 filter->plist[direct].plist =
4125 prefix_list_lookup (afi, filter->plist[direct].name);
4126 else
4127 filter->plist[direct].plist = NULL;
4128 }
4129 }
4130 }
4131 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
4132 {
4133 for (afi = AFI_IP; afi < AFI_MAX; afi++)
4134 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
4135 {
4136 filter = &group->conf->filter[afi][safi];
4137
4138 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
4139 {
4140 if (filter->plist[direct].name)
4141 filter->plist[direct].plist =
4142 prefix_list_lookup (afi, filter->plist[direct].name);
4143 else
4144 filter->plist[direct].plist = NULL;
4145 }
4146 }
4147 }
4148 }
4149 }
4150
4151 int
peer_aslist_set(struct peer * peer,afi_t afi,safi_t safi,int direct,const char * name)4152 peer_aslist_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
4153 const char *name)
4154 {
4155 struct bgp_filter *filter;
4156 struct peer_group *group;
4157 struct listnode *node, *nnode;
4158
4159 if (! peer->afc[afi][safi])
4160 return BGP_ERR_PEER_INACTIVE;
4161
4162 if (direct != FILTER_IN && direct != FILTER_OUT)
4163 return BGP_ERR_INVALID_VALUE;
4164
4165 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
4166 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4167
4168 filter = &peer->filter[afi][safi];
4169
4170 if (filter->aslist[direct].name)
4171 free (filter->aslist[direct].name);
4172 filter->aslist[direct].name = strdup (name);
4173 filter->aslist[direct].aslist = as_list_lookup (name);
4174
4175 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4176 return 0;
4177
4178 group = peer->group;
4179 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4180 {
4181 filter = &peer->filter[afi][safi];
4182
4183 if (! peer->af_group[afi][safi])
4184 continue;
4185
4186 if (filter->aslist[direct].name)
4187 free (filter->aslist[direct].name);
4188 filter->aslist[direct].name = strdup (name);
4189 filter->aslist[direct].aslist = as_list_lookup (name);
4190 }
4191 return 0;
4192 }
4193
4194 int
peer_aslist_unset(struct peer * peer,afi_t afi,safi_t safi,int direct)4195 peer_aslist_unset (struct peer *peer,afi_t afi, safi_t safi, int direct)
4196 {
4197 struct bgp_filter *filter;
4198 struct bgp_filter *gfilter;
4199 struct peer_group *group;
4200 struct listnode *node, *nnode;
4201
4202 if (! peer->afc[afi][safi])
4203 return BGP_ERR_PEER_INACTIVE;
4204
4205 if (direct != FILTER_IN && direct != FILTER_OUT)
4206 return BGP_ERR_INVALID_VALUE;
4207
4208 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
4209 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4210
4211 filter = &peer->filter[afi][safi];
4212
4213 /* apply peer-group filter */
4214 if (peer->af_group[afi][safi])
4215 {
4216 gfilter = &peer->group->conf->filter[afi][safi];
4217
4218 if (gfilter->aslist[direct].name)
4219 {
4220 if (filter->aslist[direct].name)
4221 free (filter->aslist[direct].name);
4222 filter->aslist[direct].name = strdup (gfilter->aslist[direct].name);
4223 filter->aslist[direct].aslist = gfilter->aslist[direct].aslist;
4224 return 0;
4225 }
4226 }
4227
4228 if (filter->aslist[direct].name)
4229 free (filter->aslist[direct].name);
4230 filter->aslist[direct].name = NULL;
4231 filter->aslist[direct].aslist = NULL;
4232
4233 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4234 return 0;
4235
4236 group = peer->group;
4237 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4238 {
4239 filter = &peer->filter[afi][safi];
4240
4241 if (! peer->af_group[afi][safi])
4242 continue;
4243
4244 if (filter->aslist[direct].name)
4245 free (filter->aslist[direct].name);
4246 filter->aslist[direct].name = NULL;
4247 filter->aslist[direct].aslist = NULL;
4248 }
4249
4250 return 0;
4251 }
4252
4253 static void
peer_aslist_update(void)4254 peer_aslist_update (void)
4255 {
4256 afi_t afi;
4257 safi_t safi;
4258 int direct;
4259 struct listnode *mnode, *mnnode;
4260 struct listnode *node, *nnode;
4261 struct bgp *bgp;
4262 struct peer *peer;
4263 struct peer_group *group;
4264 struct bgp_filter *filter;
4265
4266 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
4267 {
4268 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
4269 {
4270 for (afi = AFI_IP; afi < AFI_MAX; afi++)
4271 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
4272 {
4273 filter = &peer->filter[afi][safi];
4274
4275 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
4276 {
4277 if (filter->aslist[direct].name)
4278 filter->aslist[direct].aslist =
4279 as_list_lookup (filter->aslist[direct].name);
4280 else
4281 filter->aslist[direct].aslist = NULL;
4282 }
4283 }
4284 }
4285 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
4286 {
4287 for (afi = AFI_IP; afi < AFI_MAX; afi++)
4288 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
4289 {
4290 filter = &group->conf->filter[afi][safi];
4291
4292 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
4293 {
4294 if (filter->aslist[direct].name)
4295 filter->aslist[direct].aslist =
4296 as_list_lookup (filter->aslist[direct].name);
4297 else
4298 filter->aslist[direct].aslist = NULL;
4299 }
4300 }
4301 }
4302 }
4303 }
4304
4305 /* Set route-map to the peer. */
4306 int
peer_route_map_set(struct peer * peer,afi_t afi,safi_t safi,int direct,const char * name)4307 peer_route_map_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
4308 const char *name)
4309 {
4310 struct bgp_filter *filter;
4311 struct peer_group *group;
4312 struct listnode *node, *nnode;
4313
4314 if (! peer->afc[afi][safi])
4315 return BGP_ERR_PEER_INACTIVE;
4316
4317 if (direct != RMAP_IN && direct != RMAP_OUT &&
4318 direct != RMAP_IMPORT && direct != RMAP_EXPORT)
4319 return BGP_ERR_INVALID_VALUE;
4320
4321 if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
4322 && peer_is_group_member (peer, afi, safi))
4323 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4324
4325 filter = &peer->filter[afi][safi];
4326
4327 if (filter->map[direct].name)
4328 free (filter->map[direct].name);
4329
4330 filter->map[direct].name = strdup (name);
4331 filter->map[direct].map = route_map_lookup_by_name (name);
4332
4333 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4334 return 0;
4335
4336 group = peer->group;
4337 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4338 {
4339 filter = &peer->filter[afi][safi];
4340
4341 if (! peer->af_group[afi][safi])
4342 continue;
4343
4344 if (filter->map[direct].name)
4345 free (filter->map[direct].name);
4346 filter->map[direct].name = strdup (name);
4347 filter->map[direct].map = route_map_lookup_by_name (name);
4348 }
4349 return 0;
4350 }
4351
4352 /* Unset route-map from the peer. */
4353 int
peer_route_map_unset(struct peer * peer,afi_t afi,safi_t safi,int direct)4354 peer_route_map_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
4355 {
4356 struct bgp_filter *filter;
4357 struct bgp_filter *gfilter;
4358 struct peer_group *group;
4359 struct listnode *node, *nnode;
4360
4361 if (! peer->afc[afi][safi])
4362 return BGP_ERR_PEER_INACTIVE;
4363
4364 if (direct != RMAP_IN && direct != RMAP_OUT &&
4365 direct != RMAP_IMPORT && direct != RMAP_EXPORT)
4366 return BGP_ERR_INVALID_VALUE;
4367
4368 if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
4369 && peer_is_group_member (peer, afi, safi))
4370 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4371
4372 filter = &peer->filter[afi][safi];
4373
4374 /* apply peer-group filter */
4375 if (peer->af_group[afi][safi])
4376 {
4377 gfilter = &peer->group->conf->filter[afi][safi];
4378
4379 if (gfilter->map[direct].name)
4380 {
4381 if (filter->map[direct].name)
4382 free (filter->map[direct].name);
4383 filter->map[direct].name = strdup (gfilter->map[direct].name);
4384 filter->map[direct].map = gfilter->map[direct].map;
4385 return 0;
4386 }
4387 }
4388
4389 if (filter->map[direct].name)
4390 free (filter->map[direct].name);
4391 filter->map[direct].name = NULL;
4392 filter->map[direct].map = NULL;
4393
4394 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4395 return 0;
4396
4397 group = peer->group;
4398 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4399 {
4400 filter = &peer->filter[afi][safi];
4401
4402 if (! peer->af_group[afi][safi])
4403 continue;
4404
4405 if (filter->map[direct].name)
4406 free (filter->map[direct].name);
4407 filter->map[direct].name = NULL;
4408 filter->map[direct].map = NULL;
4409 }
4410 return 0;
4411 }
4412
4413 /* Set unsuppress-map to the peer. */
4414 int
peer_unsuppress_map_set(struct peer * peer,afi_t afi,safi_t safi,const char * name)4415 peer_unsuppress_map_set (struct peer *peer, afi_t afi, safi_t safi,
4416 const char *name)
4417 {
4418 struct bgp_filter *filter;
4419 struct peer_group *group;
4420 struct listnode *node, *nnode;
4421
4422 if (! peer->afc[afi][safi])
4423 return BGP_ERR_PEER_INACTIVE;
4424
4425 if (peer_is_group_member (peer, afi, safi))
4426 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4427
4428 filter = &peer->filter[afi][safi];
4429
4430 if (filter->usmap.name)
4431 free (filter->usmap.name);
4432
4433 filter->usmap.name = strdup (name);
4434 filter->usmap.map = route_map_lookup_by_name (name);
4435
4436 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4437 return 0;
4438
4439 group = peer->group;
4440 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4441 {
4442 filter = &peer->filter[afi][safi];
4443
4444 if (! peer->af_group[afi][safi])
4445 continue;
4446
4447 if (filter->usmap.name)
4448 free (filter->usmap.name);
4449 filter->usmap.name = strdup (name);
4450 filter->usmap.map = route_map_lookup_by_name (name);
4451 }
4452 return 0;
4453 }
4454
4455 /* Unset route-map from the peer. */
4456 int
peer_unsuppress_map_unset(struct peer * peer,afi_t afi,safi_t safi)4457 peer_unsuppress_map_unset (struct peer *peer, afi_t afi, safi_t safi)
4458 {
4459 struct bgp_filter *filter;
4460 struct peer_group *group;
4461 struct listnode *node, *nnode;
4462
4463 if (! peer->afc[afi][safi])
4464 return BGP_ERR_PEER_INACTIVE;
4465
4466 if (peer_is_group_member (peer, afi, safi))
4467 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4468
4469 filter = &peer->filter[afi][safi];
4470
4471 if (filter->usmap.name)
4472 free (filter->usmap.name);
4473 filter->usmap.name = NULL;
4474 filter->usmap.map = NULL;
4475
4476 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4477 return 0;
4478
4479 group = peer->group;
4480 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4481 {
4482 filter = &peer->filter[afi][safi];
4483
4484 if (! peer->af_group[afi][safi])
4485 continue;
4486
4487 if (filter->usmap.name)
4488 free (filter->usmap.name);
4489 filter->usmap.name = NULL;
4490 filter->usmap.map = NULL;
4491 }
4492 return 0;
4493 }
4494
4495 int
peer_maximum_prefix_set(struct peer * peer,afi_t afi,safi_t safi,u_int32_t max,u_char threshold,int warning,u_int16_t restart)4496 peer_maximum_prefix_set (struct peer *peer, afi_t afi, safi_t safi,
4497 u_int32_t max, u_char threshold,
4498 int warning, u_int16_t restart)
4499 {
4500 struct peer_group *group;
4501 struct listnode *node, *nnode;
4502
4503 if (! peer->afc[afi][safi])
4504 return BGP_ERR_PEER_INACTIVE;
4505
4506 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4507 peer->pmax[afi][safi] = max;
4508 peer->pmax_threshold[afi][safi] = threshold;
4509 peer->pmax_restart[afi][safi] = restart;
4510 if (warning)
4511 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4512 else
4513 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4514
4515 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4516 {
4517 group = peer->group;
4518 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4519 {
4520 if (! peer->af_group[afi][safi])
4521 continue;
4522
4523 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4524 peer->pmax[afi][safi] = max;
4525 peer->pmax_threshold[afi][safi] = threshold;
4526 peer->pmax_restart[afi][safi] = restart;
4527 if (warning)
4528 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4529 else
4530 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4531
4532 if ((peer->status == Established) && (peer->afc[afi][safi]))
4533 bgp_maximum_prefix_overflow (peer, afi, safi, 1);
4534 }
4535 }
4536 else
4537 {
4538 if ((peer->status == Established) && (peer->afc[afi][safi]))
4539 bgp_maximum_prefix_overflow (peer, afi, safi, 1);
4540 }
4541
4542 return 0;
4543 }
4544
4545 int
peer_maximum_prefix_unset(struct peer * peer,afi_t afi,safi_t safi)4546 peer_maximum_prefix_unset (struct peer *peer, afi_t afi, safi_t safi)
4547 {
4548 struct peer_group *group;
4549 struct listnode *node, *nnode;
4550
4551 if (! peer->afc[afi][safi])
4552 return BGP_ERR_PEER_INACTIVE;
4553
4554 /* apply peer-group config */
4555 if (peer->af_group[afi][safi])
4556 {
4557 if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi],
4558 PEER_FLAG_MAX_PREFIX))
4559 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4560 else
4561 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4562
4563 if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi],
4564 PEER_FLAG_MAX_PREFIX_WARNING))
4565 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4566 else
4567 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4568
4569 peer->pmax[afi][safi] = peer->group->conf->pmax[afi][safi];
4570 peer->pmax_threshold[afi][safi] = peer->group->conf->pmax_threshold[afi][safi];
4571 peer->pmax_restart[afi][safi] = peer->group->conf->pmax_restart[afi][safi];
4572 return 0;
4573 }
4574
4575 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4576 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4577 peer->pmax[afi][safi] = 0;
4578 peer->pmax_threshold[afi][safi] = 0;
4579 peer->pmax_restart[afi][safi] = 0;
4580
4581 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4582 return 0;
4583
4584 group = peer->group;
4585 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4586 {
4587 if (! peer->af_group[afi][safi])
4588 continue;
4589
4590 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4591 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4592 peer->pmax[afi][safi] = 0;
4593 peer->pmax_threshold[afi][safi] = 0;
4594 peer->pmax_restart[afi][safi] = 0;
4595 }
4596 return 0;
4597 }
4598
4599 /* Set # of hops between us and BGP peer. */
4600 int
peer_ttl_security_hops_set(struct peer * peer,int gtsm_hops)4601 peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops)
4602 {
4603 struct peer_group *group;
4604 struct listnode *node, *nnode;
4605 struct peer *peer1;
4606
4607 zlog_debug ("peer_ttl_security_hops_set: set gtsm_hops to %d for %s", gtsm_hops, peer->host);
4608
4609 if (peer->ttl != 0)
4610 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
4611
4612 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4613 {
4614 group = peer->group;
4615 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
4616 {
4617 if (peer1->ttl != 0)
4618 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
4619 }
4620 }
4621
4622 peer->gtsm_hops = gtsm_hops;
4623
4624 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4625 {
4626 bgp_set_socket_ttl (peer, peer->fd);
4627 }
4628 else
4629 {
4630 group = peer->group;
4631 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4632 {
4633 peer->gtsm_hops = gtsm_hops;
4634
4635 /* Change setting of existing peer
4636 * established then change value (may break connectivity)
4637 * not established yet (teardown session and restart)
4638 * no session then do nothing (will get handled by next connection)
4639 */
4640 if (peer->status == Established)
4641 {
4642 bgp_set_socket_ttl (peer, peer->fd);
4643 }
4644 else if (peer->status < Established)
4645 {
4646 if (BGP_DEBUG (events, EVENTS))
4647 zlog_debug ("%s Min-ttl changed", peer->host);
4648 BGP_EVENT_ADD (peer, BGP_Stop);
4649 }
4650 }
4651 }
4652
4653 return 0;
4654 }
4655
4656 int
peer_clear(struct peer * peer)4657 peer_clear (struct peer *peer)
4658 {
4659 if (! CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
4660 {
4661 if (CHECK_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
4662 {
4663 UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
4664 if (peer->t_pmax_restart)
4665 {
4666 BGP_TIMER_OFF (peer->t_pmax_restart);
4667 if (BGP_DEBUG (events, EVENTS))
4668 zlog_debug ("%s Maximum-prefix restart timer canceled",
4669 peer->host);
4670 }
4671 BGP_EVENT_ADD (peer, BGP_Start);
4672 return 0;
4673 }
4674
4675 peer->v_start = BGP_INIT_START_TIMER;
4676 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
4677 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
4678 BGP_NOTIFY_CEASE_ADMIN_RESET);
4679 else
4680 BGP_EVENT_ADD (peer, BGP_Stop);
4681 }
4682 return 0;
4683 }
4684
4685 int
peer_clear_soft(struct peer * peer,afi_t afi,safi_t safi,enum bgp_clear_type stype)4686 peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi,
4687 enum bgp_clear_type stype)
4688 {
4689 if (peer->status != Established)
4690 return 0;
4691
4692 if (! peer->afc[afi][safi])
4693 return BGP_ERR_AF_UNCONFIGURED;
4694
4695 peer->rtt = sockopt_tcp_rtt (peer->fd);
4696
4697 if (stype == BGP_CLEAR_SOFT_RSCLIENT)
4698 {
4699 if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
4700 return 0;
4701 bgp_check_local_routes_rsclient (peer, afi, safi);
4702 bgp_soft_reconfig_rsclient (peer, afi, safi);
4703 }
4704
4705 if (stype == BGP_CLEAR_SOFT_OUT || stype == BGP_CLEAR_SOFT_BOTH)
4706 bgp_announce_route (peer, afi, safi);
4707
4708 if (stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX)
4709 {
4710 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV)
4711 && (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV)
4712 || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV)))
4713 {
4714 struct bgp_filter *filter = &peer->filter[afi][safi];
4715 u_char prefix_type;
4716
4717 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV))
4718 prefix_type = ORF_TYPE_PREFIX;
4719 else
4720 prefix_type = ORF_TYPE_PREFIX_OLD;
4721
4722 if (filter->plist[FILTER_IN].plist)
4723 {
4724 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND))
4725 bgp_route_refresh_send (peer, afi, safi,
4726 prefix_type, REFRESH_DEFER, 1);
4727 bgp_route_refresh_send (peer, afi, safi, prefix_type,
4728 REFRESH_IMMEDIATE, 0);
4729 }
4730 else
4731 {
4732 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND))
4733 bgp_route_refresh_send (peer, afi, safi,
4734 prefix_type, REFRESH_IMMEDIATE, 1);
4735 else
4736 bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
4737 }
4738 return 0;
4739 }
4740 }
4741
4742 if (stype == BGP_CLEAR_SOFT_IN || stype == BGP_CLEAR_SOFT_BOTH
4743 || stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX)
4744 {
4745 /* If neighbor has soft reconfiguration inbound flag.
4746 Use Adj-RIB-In database. */
4747 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
4748 bgp_soft_reconfig_in (peer, afi, safi);
4749 else
4750 {
4751 /* If neighbor has route refresh capability, send route refresh
4752 message to the peer. */
4753 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
4754 || CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
4755 bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
4756 else
4757 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED;
4758 }
4759 }
4760 return 0;
4761 }
4762
4763 /* Display peer uptime.*/
4764 /* XXX: why does this function return char * when it takes buffer? */
4765 char *
peer_uptime(time_t uptime2,char * buf,size_t len)4766 peer_uptime (time_t uptime2, char *buf, size_t len)
4767 {
4768 time_t uptime1;
4769 struct tm *tm;
4770
4771 /* Check buffer length. */
4772 if (len < BGP_UPTIME_LEN)
4773 {
4774 zlog_warn ("peer_uptime (): buffer shortage %lu", (u_long)len);
4775 /* XXX: should return status instead of buf... */
4776 snprintf (buf, len, "<error> ");
4777 return buf;
4778 }
4779
4780 /* If there is no connection has been done before print `never'. */
4781 if (uptime2 == 0)
4782 {
4783 snprintf (buf, len, "never ");
4784 return buf;
4785 }
4786
4787 /* Get current time. */
4788 uptime1 = bgp_clock ();
4789 uptime1 -= uptime2;
4790 tm = gmtime (&uptime1);
4791
4792 /* Making formatted timer strings. */
4793 #define ONE_DAY_SECOND 60*60*24
4794 #define ONE_WEEK_SECOND ONE_DAY_SECOND*7
4795 #define ONE_YEAR_SECOND ONE_DAY_SECOND*365
4796
4797 if (uptime1 < ONE_DAY_SECOND)
4798 snprintf (buf, len, "%02d:%02d:%02d",
4799 tm->tm_hour, tm->tm_min, tm->tm_sec);
4800 else if (uptime1 < ONE_WEEK_SECOND)
4801 snprintf (buf, len, "%dd%02dh%02dm",
4802 tm->tm_yday, tm->tm_hour, tm->tm_min);
4803 else if (uptime1 < ONE_YEAR_SECOND)
4804 snprintf (buf, len, "%02dw%dd%02dh",
4805 tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
4806 else
4807 snprintf (buf, len, "%02dy%02dw%dd",
4808 tm->tm_year - 70, tm->tm_yday/7,
4809 tm->tm_yday - ((tm->tm_yday/7) * 7));
4810 return buf;
4811 }
4812
4813 static void
bgp_config_write_filter(struct vty * vty,struct peer * peer,afi_t afi,safi_t safi)4814 bgp_config_write_filter (struct vty *vty, struct peer *peer,
4815 afi_t afi, safi_t safi)
4816 {
4817 struct bgp_filter *filter;
4818 struct bgp_filter *gfilter = NULL;
4819 char *addr;
4820 int in = FILTER_IN;
4821 int out = FILTER_OUT;
4822
4823 addr = peer->host;
4824 filter = &peer->filter[afi][safi];
4825 if (peer->af_group[afi][safi])
4826 gfilter = &peer->group->conf->filter[afi][safi];
4827
4828 /* distribute-list. */
4829 if (filter->dlist[in].name)
4830 if (! gfilter || ! gfilter->dlist[in].name
4831 || strcmp (filter->dlist[in].name, gfilter->dlist[in].name) != 0)
4832 vty_out (vty, " neighbor %s distribute-list %s in%s", addr,
4833 filter->dlist[in].name, VTY_NEWLINE);
4834 if (filter->dlist[out].name && ! gfilter)
4835 vty_out (vty, " neighbor %s distribute-list %s out%s", addr,
4836 filter->dlist[out].name, VTY_NEWLINE);
4837
4838 /* prefix-list. */
4839 if (filter->plist[in].name)
4840 if (! gfilter || ! gfilter->plist[in].name
4841 || strcmp (filter->plist[in].name, gfilter->plist[in].name) != 0)
4842 vty_out (vty, " neighbor %s prefix-list %s in%s", addr,
4843 filter->plist[in].name, VTY_NEWLINE);
4844 if (filter->plist[out].name && ! gfilter)
4845 vty_out (vty, " neighbor %s prefix-list %s out%s", addr,
4846 filter->plist[out].name, VTY_NEWLINE);
4847
4848 /* route-map. */
4849 if (filter->map[RMAP_IN].name)
4850 if (! gfilter || ! gfilter->map[RMAP_IN].name
4851 || strcmp (filter->map[RMAP_IN].name, gfilter->map[RMAP_IN].name) != 0)
4852 vty_out (vty, " neighbor %s route-map %s in%s", addr,
4853 filter->map[RMAP_IN].name, VTY_NEWLINE);
4854 if (filter->map[RMAP_OUT].name && ! gfilter)
4855 vty_out (vty, " neighbor %s route-map %s out%s", addr,
4856 filter->map[RMAP_OUT].name, VTY_NEWLINE);
4857 if (filter->map[RMAP_IMPORT].name && ! gfilter)
4858 vty_out (vty, " neighbor %s route-map %s import%s", addr,
4859 filter->map[RMAP_IMPORT].name, VTY_NEWLINE);
4860 if (filter->map[RMAP_EXPORT].name)
4861 if (! gfilter || ! gfilter->map[RMAP_EXPORT].name
4862 || strcmp (filter->map[RMAP_EXPORT].name,
4863 gfilter->map[RMAP_EXPORT].name) != 0)
4864 vty_out (vty, " neighbor %s route-map %s export%s", addr,
4865 filter->map[RMAP_EXPORT].name, VTY_NEWLINE);
4866
4867 /* unsuppress-map */
4868 if (filter->usmap.name && ! gfilter)
4869 vty_out (vty, " neighbor %s unsuppress-map %s%s", addr,
4870 filter->usmap.name, VTY_NEWLINE);
4871
4872 /* filter-list. */
4873 if (filter->aslist[in].name)
4874 if (! gfilter || ! gfilter->aslist[in].name
4875 || strcmp (filter->aslist[in].name, gfilter->aslist[in].name) != 0)
4876 vty_out (vty, " neighbor %s filter-list %s in%s", addr,
4877 filter->aslist[in].name, VTY_NEWLINE);
4878 if (filter->aslist[out].name && ! gfilter)
4879 vty_out (vty, " neighbor %s filter-list %s out%s", addr,
4880 filter->aslist[out].name, VTY_NEWLINE);
4881 }
4882
4883 /* BGP peer configuration display function. */
4884 static void
bgp_config_write_peer(struct vty * vty,struct bgp * bgp,struct peer * peer,afi_t afi,safi_t safi)4885 bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
4886 struct peer *peer, afi_t afi, safi_t safi)
4887 {
4888 struct peer *g_peer = NULL;
4889 char buf[SU_ADDRSTRLEN];
4890 char *addr;
4891
4892 addr = peer->host;
4893 if (peer_group_active (peer))
4894 g_peer = peer->group->conf;
4895
4896 /************************************
4897 ****** Global to the neighbor ******
4898 ************************************/
4899 if (afi == AFI_IP && safi == SAFI_UNICAST)
4900 {
4901 /* remote-as. */
4902 if (! peer_group_active (peer))
4903 {
4904 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4905 vty_out (vty, " neighbor %s peer-group%s", addr,
4906 VTY_NEWLINE);
4907 if (peer->as)
4908 vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
4909 VTY_NEWLINE);
4910 }
4911 else
4912 {
4913 if (! g_peer->as)
4914 vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
4915 VTY_NEWLINE);
4916 if (peer->af_group[AFI_IP][SAFI_UNICAST])
4917 vty_out (vty, " neighbor %s peer-group %s%s", addr,
4918 peer->group->name, VTY_NEWLINE);
4919 }
4920
4921 /* local-as. */
4922 if (peer->change_local_as)
4923 if (! peer_group_active (peer))
4924 vty_out (vty, " neighbor %s local-as %u%s%s%s", addr,
4925 peer->change_local_as,
4926 CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) ?
4927 " no-prepend" : "",
4928 CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) ?
4929 " replace-as" : "", VTY_NEWLINE);
4930
4931 /* Description. */
4932 if (peer->desc)
4933 vty_out (vty, " neighbor %s description %s%s", addr, peer->desc,
4934 VTY_NEWLINE);
4935
4936 /* Shutdown. */
4937 if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
4938 if (! peer_group_active (peer) ||
4939 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_SHUTDOWN))
4940 vty_out (vty, " neighbor %s shutdown%s", addr, VTY_NEWLINE);
4941
4942 /* Password. */
4943 if (peer->password)
4944 if (!peer_group_active (peer)
4945 || ! g_peer->password
4946 || strcmp (peer->password, g_peer->password) != 0)
4947 vty_out (vty, " neighbor %s password %s%s", addr, peer->password,
4948 VTY_NEWLINE);
4949
4950 /* BGP port. */
4951 if (peer->port != BGP_PORT_DEFAULT)
4952 vty_out (vty, " neighbor %s port %d%s", addr, peer->port,
4953 VTY_NEWLINE);
4954
4955 /* Local interface name. */
4956 if (peer->ifname)
4957 vty_out (vty, " neighbor %s interface %s%s", addr, peer->ifname,
4958 VTY_NEWLINE);
4959
4960 /* Passive. */
4961 if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
4962 if (! peer_group_active (peer) ||
4963 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_PASSIVE))
4964 vty_out (vty, " neighbor %s passive%s", addr, VTY_NEWLINE);
4965
4966 /* TTL option */
4967 if (peer->gtsm_hops && ! peer_group_active (peer))
4968 vty_out (vty, " neighbor %s ttl-security hops %d%s", addr,
4969 peer->gtsm_hops, VTY_NEWLINE);
4970 else if (peer->ttl && ! peer_group_active (peer))
4971 vty_out (vty, " neighbor %s ebgp-multihop %d%s", addr, peer->ttl,
4972 VTY_NEWLINE);
4973
4974 /* disable-connected-check. */
4975 if (CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
4976 if (! peer_group_active (peer) ||
4977 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
4978 vty_out (vty, " neighbor %s disable-connected-check%s", addr, VTY_NEWLINE);
4979
4980 /* Update-source. */
4981 if (peer->update_if)
4982 if (! peer_group_active (peer) || ! g_peer->update_if
4983 || strcmp (g_peer->update_if, peer->update_if) != 0)
4984 vty_out (vty, " neighbor %s update-source %s%s", addr,
4985 peer->update_if, VTY_NEWLINE);
4986 if (peer->update_source)
4987 if (! peer_group_active (peer) || ! g_peer->update_source
4988 || sockunion_cmp (g_peer->update_source,
4989 peer->update_source) != 0)
4990 vty_out (vty, " neighbor %s update-source %s%s", addr,
4991 sockunion2str (peer->update_source, buf, SU_ADDRSTRLEN),
4992 VTY_NEWLINE);
4993
4994 /* advertisement-interval */
4995 if (CHECK_FLAG (peer->config, PEER_CONFIG_ROUTEADV) &&
4996 ! peer_group_active (peer))
4997 vty_out (vty, " neighbor %s advertisement-interval %d%s",
4998 addr, peer->v_routeadv, VTY_NEWLINE);
4999
5000 /* timers. */
5001 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER)
5002 && ! peer_group_active (peer))
5003 vty_out (vty, " neighbor %s timers %d %d%s", addr,
5004 peer->keepalive, peer->holdtime, VTY_NEWLINE);
5005
5006 if (CHECK_FLAG (peer->config, PEER_CONFIG_CONNECT) &&
5007 ! peer_group_active (peer))
5008 vty_out (vty, " neighbor %s timers connect %d%s", addr,
5009 peer->connect, VTY_NEWLINE);
5010
5011 /* Default weight. */
5012 if (CHECK_FLAG (peer->config, PEER_CONFIG_WEIGHT))
5013 if (! peer_group_active (peer) ||
5014 g_peer->weight != peer->weight)
5015 vty_out (vty, " neighbor %s weight %d%s", addr, peer->weight,
5016 VTY_NEWLINE);
5017
5018 /* Dynamic capability. */
5019 if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
5020 if (! peer_group_active (peer) ||
5021 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
5022 vty_out (vty, " neighbor %s capability dynamic%s", addr,
5023 VTY_NEWLINE);
5024
5025 /* dont capability negotiation. */
5026 if (CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
5027 if (! peer_group_active (peer) ||
5028 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DONT_CAPABILITY))
5029 vty_out (vty, " neighbor %s dont-capability-negotiate%s", addr,
5030 VTY_NEWLINE);
5031
5032 /* override capability negotiation. */
5033 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
5034 if (! peer_group_active (peer) ||
5035 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
5036 vty_out (vty, " neighbor %s override-capability%s", addr,
5037 VTY_NEWLINE);
5038
5039 /* strict capability negotiation. */
5040 if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
5041 if (! peer_group_active (peer) ||
5042 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
5043 vty_out (vty, " neighbor %s strict-capability-match%s", addr,
5044 VTY_NEWLINE);
5045
5046 if (! peer->af_group[AFI_IP][SAFI_UNICAST])
5047 {
5048 if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
5049 {
5050 if (peer->afc[AFI_IP][SAFI_UNICAST])
5051 vty_out (vty, " neighbor %s activate%s", addr, VTY_NEWLINE);
5052 }
5053 else
5054 {
5055 if (! peer->afc[AFI_IP][SAFI_UNICAST])
5056 vty_out (vty, " no neighbor %s activate%s", addr, VTY_NEWLINE);
5057 }
5058 }
5059 }
5060
5061
5062 /************************************
5063 ****** Per AF to the neighbor ******
5064 ************************************/
5065
5066 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
5067 {
5068 if (peer->af_group[afi][safi])
5069 vty_out (vty, " neighbor %s peer-group %s%s", addr,
5070 peer->group->name, VTY_NEWLINE);
5071 else
5072 vty_out (vty, " neighbor %s activate%s", addr, VTY_NEWLINE);
5073 }
5074
5075 /* ORF capability. */
5076 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
5077 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
5078 if (! peer->af_group[afi][safi])
5079 {
5080 vty_out (vty, " neighbor %s capability orf prefix-list", addr);
5081
5082 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
5083 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
5084 vty_out (vty, " both");
5085 else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
5086 vty_out (vty, " send");
5087 else
5088 vty_out (vty, " receive");
5089 vty_out (vty, "%s", VTY_NEWLINE);
5090 }
5091
5092 /* Route reflector client. */
5093 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REFLECTOR_CLIENT)
5094 && ! peer->af_group[afi][safi])
5095 vty_out (vty, " neighbor %s route-reflector-client%s", addr,
5096 VTY_NEWLINE);
5097
5098 /* Nexthop self. */
5099 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)
5100 && ! peer->af_group[afi][safi])
5101 vty_out (vty, " neighbor %s next-hop-self%s%s", addr,
5102 peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF_ALL) ?
5103 " all" : "", VTY_NEWLINE);
5104
5105 /* Remove private AS. */
5106 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
5107 && ! peer->af_group[afi][safi])
5108 vty_out (vty, " neighbor %s remove-private-AS%s",
5109 addr, VTY_NEWLINE);
5110
5111 /* send-community print. */
5112 if (! peer->af_group[afi][safi])
5113 {
5114 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
5115 {
5116 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)
5117 && peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY)
5118 && peer_af_flag_check(peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY))
5119 vty_out (vty, " neighbor %s send-community all%s", addr, VTY_NEWLINE);
5120 else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
5121 vty_out (vty, " neighbor %s send-community extended%s",
5122 addr, VTY_NEWLINE);
5123 else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY))
5124 vty_out (vty, " neighbor %s send-community large%s",
5125 addr, VTY_NEWLINE);
5126 else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
5127 vty_out (vty, " neighbor %s send-community%s", addr, VTY_NEWLINE);
5128 }
5129 else
5130 {
5131 if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)
5132 && ! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY)
5133 && ! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY))
5134 vty_out (vty, " no neighbor %s send-community all%s",
5135 addr, VTY_NEWLINE);
5136 else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
5137 vty_out (vty, " no neighbor %s send-community extended%s",
5138 addr, VTY_NEWLINE);
5139 else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY))
5140 vty_out (vty, " no neighbor %s send-community large%s",
5141 addr, VTY_NEWLINE);
5142 else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
5143 vty_out (vty, " no neighbor %s send-community%s",
5144 addr, VTY_NEWLINE);
5145 }
5146 }
5147
5148 /* Default information */
5149 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_DEFAULT_ORIGINATE)
5150 && ! peer->af_group[afi][safi])
5151 {
5152 vty_out (vty, " neighbor %s default-originate", addr);
5153 if (peer->default_rmap[afi][safi].name)
5154 vty_out (vty, " route-map %s", peer->default_rmap[afi][safi].name);
5155 vty_out (vty, "%s", VTY_NEWLINE);
5156 }
5157
5158 /* Soft reconfiguration inbound. */
5159 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5160 if (! peer->af_group[afi][safi] ||
5161 ! CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5162 vty_out (vty, " neighbor %s soft-reconfiguration inbound%s", addr,
5163 VTY_NEWLINE);
5164
5165 /* maximum-prefix. */
5166 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
5167 if (! peer->af_group[afi][safi]
5168 || g_peer->pmax[afi][safi] != peer->pmax[afi][safi]
5169 || g_peer->pmax_threshold[afi][safi] != peer->pmax_threshold[afi][safi]
5170 || CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING)
5171 != CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
5172 {
5173 vty_out (vty, " neighbor %s maximum-prefix %ld", addr, peer->pmax[afi][safi]);
5174 if (peer->pmax_threshold[afi][safi] != MAXIMUM_PREFIX_THRESHOLD_DEFAULT)
5175 vty_out (vty, " %d", peer->pmax_threshold[afi][safi]);
5176 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
5177 vty_out (vty, " warning-only");
5178 if (peer->pmax_restart[afi][safi])
5179 vty_out (vty, " restart %d", peer->pmax_restart[afi][safi]);
5180 vty_out (vty, "%s", VTY_NEWLINE);
5181 }
5182
5183 /* Route server client. */
5184 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
5185 && ! peer->af_group[afi][safi])
5186 vty_out (vty, " neighbor %s route-server-client%s", addr, VTY_NEWLINE);
5187
5188 /* Nexthop-local unchanged. */
5189 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
5190 && ! peer->af_group[afi][safi])
5191 vty_out (vty, " neighbor %s nexthop-local unchanged%s", addr, VTY_NEWLINE);
5192
5193 /* Allow AS in. */
5194 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_ALLOWAS_IN))
5195 if (! peer_group_active (peer)
5196 || ! peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_ALLOWAS_IN)
5197 || peer->allowas_in[afi][safi] != g_peer->allowas_in[afi][safi])
5198 {
5199 if (peer->allowas_in[afi][safi] == 3)
5200 vty_out (vty, " neighbor %s allowas-in%s", addr, VTY_NEWLINE);
5201 else
5202 vty_out (vty, " neighbor %s allowas-in %d%s", addr,
5203 peer->allowas_in[afi][safi], VTY_NEWLINE);
5204 }
5205
5206 /* Filter. */
5207 bgp_config_write_filter (vty, peer, afi, safi);
5208
5209 /* atribute-unchanged. */
5210 if ((CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
5211 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
5212 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
5213 && ! peer->af_group[afi][safi])
5214 {
5215 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
5216 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
5217 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
5218 vty_out (vty, " neighbor %s attribute-unchanged%s", addr, VTY_NEWLINE);
5219 else
5220 vty_out (vty, " neighbor %s attribute-unchanged%s%s%s%s", addr,
5221 (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)) ?
5222 " as-path" : "",
5223 (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)) ?
5224 " next-hop" : "",
5225 (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED)) ?
5226 " med" : "", VTY_NEWLINE);
5227 }
5228 }
5229
5230 /* Display "address-family" configuration header. */
5231 void
bgp_config_write_family_header(struct vty * vty,afi_t afi,safi_t safi,int * write)5232 bgp_config_write_family_header (struct vty *vty, afi_t afi, safi_t safi,
5233 int *write)
5234 {
5235 if (*write)
5236 return;
5237
5238 if (afi == AFI_IP && safi == SAFI_UNICAST)
5239 return;
5240
5241 vty_out (vty, "!%s address-family ", VTY_NEWLINE);
5242
5243 if (afi == AFI_IP)
5244 {
5245 if (safi == SAFI_MULTICAST)
5246 vty_out (vty, "ipv4 multicast");
5247 else if (safi == SAFI_MPLS_VPN)
5248 vty_out (vty, "vpnv4");
5249 else if (safi == SAFI_ENCAP)
5250 vty_out (vty, "encap");
5251 }
5252 else if (afi == AFI_IP6)
5253 {
5254 if (safi == SAFI_MPLS_VPN)
5255 vty_out (vty, "vpnv6");
5256 else if (safi == SAFI_ENCAP)
5257 vty_out (vty, "encapv6");
5258 else
5259 {
5260 vty_out (vty, "ipv6");
5261 if (safi == SAFI_MULTICAST)
5262 vty_out (vty, " multicast");
5263 }
5264 }
5265
5266 vty_out (vty, "%s", VTY_NEWLINE);
5267
5268 *write = 1;
5269 }
5270
5271 /* Address family based peer configuration display. */
5272 static int
bgp_config_write_family(struct vty * vty,struct bgp * bgp,afi_t afi,safi_t safi)5273 bgp_config_write_family (struct vty *vty, struct bgp *bgp, afi_t afi,
5274 safi_t safi)
5275 {
5276 int write = 0;
5277 struct peer *peer;
5278 struct peer_group *group;
5279 struct listnode *node, *nnode;
5280
5281 bgp_config_write_network (vty, bgp, afi, safi, &write);
5282
5283 bgp_config_write_redistribute (vty, bgp, afi, safi, &write);
5284
5285 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
5286 {
5287 if (group->conf->afc[afi][safi])
5288 {
5289 bgp_config_write_family_header (vty, afi, safi, &write);
5290 bgp_config_write_peer (vty, bgp, group->conf, afi, safi);
5291 }
5292 }
5293 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
5294 {
5295 if (peer->afc[afi][safi])
5296 {
5297 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
5298 {
5299 bgp_config_write_family_header (vty, afi, safi, &write);
5300 bgp_config_write_peer (vty, bgp, peer, afi, safi);
5301 }
5302 }
5303 }
5304
5305 bgp_config_write_maxpaths (vty, bgp, afi, safi, &write);
5306
5307 bgp_config_write_distance (vty, bgp, afi, safi, &write);
5308
5309 if (write)
5310 vty_out (vty, " exit-address-family%s", VTY_NEWLINE);
5311
5312 return write;
5313 }
5314
5315 int
bgp_config_write(struct vty * vty)5316 bgp_config_write (struct vty *vty)
5317 {
5318 int write = 0;
5319 struct bgp *bgp;
5320 struct peer_group *group;
5321 struct peer *peer;
5322 struct listnode *node, *nnode;
5323 struct listnode *mnode, *mnnode;
5324
5325 /* BGP Multiple instance. */
5326 if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
5327 {
5328 vty_out (vty, "bgp multiple-instance%s", VTY_NEWLINE);
5329 write++;
5330 }
5331
5332 /* BGP Config type. */
5333 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
5334 {
5335 vty_out (vty, "bgp config-type cisco%s", VTY_NEWLINE);
5336 write++;
5337 }
5338
5339 /* BGP configuration. */
5340 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
5341 {
5342 if (write)
5343 vty_out (vty, "!%s", VTY_NEWLINE);
5344
5345 /* Router bgp ASN */
5346 vty_out (vty, "router bgp %u", bgp->as);
5347
5348 if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
5349 {
5350 if (bgp->name)
5351 vty_out (vty, " view %s", bgp->name);
5352 }
5353 vty_out (vty, "%s", VTY_NEWLINE);
5354
5355 /* No Synchronization */
5356 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
5357 vty_out (vty, " no synchronization%s", VTY_NEWLINE);
5358
5359 /* BGP fast-external-failover. */
5360 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
5361 vty_out (vty, " no bgp fast-external-failover%s", VTY_NEWLINE);
5362
5363 /* BGP router ID. */
5364 if (CHECK_FLAG (bgp->config, BGP_CONFIG_ROUTER_ID))
5365 vty_out (vty, " bgp router-id %s%s", inet_ntoa (bgp->router_id),
5366 VTY_NEWLINE);
5367
5368 /* BGP log-neighbor-changes. */
5369 if (!bgp_flag_check (bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
5370 vty_out (vty, " no bgp log-neighbor-changes%s", VTY_NEWLINE);
5371
5372 /* BGP configuration. */
5373 if (bgp_flag_check (bgp, BGP_FLAG_ALWAYS_COMPARE_MED))
5374 vty_out (vty, " bgp always-compare-med%s", VTY_NEWLINE);
5375
5376 /* BGP default ipv4-unicast. */
5377 if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
5378 vty_out (vty, " no bgp default ipv4-unicast%s", VTY_NEWLINE);
5379
5380 /* BGP default local-preference. */
5381 if (bgp->default_local_pref != BGP_DEFAULT_LOCAL_PREF)
5382 vty_out (vty, " bgp default local-preference %d%s",
5383 bgp->default_local_pref, VTY_NEWLINE);
5384
5385 /* BGP client-to-client reflection. */
5386 if (bgp_flag_check (bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
5387 vty_out (vty, " no bgp client-to-client reflection%s", VTY_NEWLINE);
5388
5389 /* BGP cluster ID. */
5390 if (CHECK_FLAG (bgp->config, BGP_CONFIG_CLUSTER_ID))
5391 vty_out (vty, " bgp cluster-id %s%s", inet_ntoa (bgp->cluster_id),
5392 VTY_NEWLINE);
5393
5394 /* Confederation identifier*/
5395 if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
5396 vty_out (vty, " bgp confederation identifier %i%s", bgp->confed_id,
5397 VTY_NEWLINE);
5398
5399 /* Confederation peer */
5400 if (bgp->confed_peers_cnt > 0)
5401 {
5402 int i;
5403
5404 vty_out (vty, " bgp confederation peers");
5405
5406 for (i = 0; i < bgp->confed_peers_cnt; i++)
5407 vty_out(vty, " %u", bgp->confed_peers[i]);
5408
5409 vty_out (vty, "%s", VTY_NEWLINE);
5410 }
5411
5412 /* BGP enforce-first-as. */
5413 if (bgp_flag_check (bgp, BGP_FLAG_ENFORCE_FIRST_AS))
5414 vty_out (vty, " bgp enforce-first-as%s", VTY_NEWLINE);
5415
5416 /* BGP deterministic-med. */
5417 if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
5418 vty_out (vty, " bgp deterministic-med%s", VTY_NEWLINE);
5419
5420 /* BGP graceful-restart. */
5421 if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME)
5422 vty_out (vty, " bgp graceful-restart stalepath-time %d%s",
5423 bgp->stalepath_time, VTY_NEWLINE);
5424 if (bgp->restart_time != BGP_DEFAULT_RESTART_TIME)
5425 vty_out (vty, " bgp graceful-restart restart-time %d%s",
5426 bgp->restart_time, VTY_NEWLINE);
5427 if (bgp_flag_check (bgp, BGP_FLAG_GRACEFUL_RESTART))
5428 vty_out (vty, " bgp graceful-restart%s", VTY_NEWLINE);
5429
5430 /* BGP bestpath method. */
5431 if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_IGNORE))
5432 vty_out (vty, " bgp bestpath as-path ignore%s", VTY_NEWLINE);
5433 if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_CONFED))
5434 vty_out (vty, " bgp bestpath as-path confed%s", VTY_NEWLINE);
5435 if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
5436 vty_out (vty, " bgp bestpath as-path multipath-relax%s", VTY_NEWLINE);
5437 }
5438 if (bgp_flag_check (bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
5439 vty_out (vty, " bgp route-reflector allow-outbound-policy%s",
5440 VTY_NEWLINE);
5441 }
5442 if (bgp_flag_check (bgp, BGP_FLAG_COMPARE_ROUTER_ID))
5443 vty_out (vty, " bgp bestpath compare-routerid%s", VTY_NEWLINE);
5444 if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED)
5445 || bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
5446 {
5447 vty_out (vty, " bgp bestpath med");
5448 if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED))
5449 vty_out (vty, " confed");
5450 if (bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
5451 vty_out (vty, " missing-as-worst");
5452 vty_out (vty, "%s", VTY_NEWLINE);
5453 }
5454
5455 /* BGP network import check. */
5456 if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
5457 vty_out (vty, " bgp network import-check%s", VTY_NEWLINE);
5458
5459 /* BGP flag dampening. */
5460 if (CHECK_FLAG (bgp->af_flags[AFI_IP][SAFI_UNICAST],
5461 BGP_CONFIG_DAMPENING))
5462 bgp_config_write_damp (vty);
5463
5464 /* BGP static route configuration. */
5465 bgp_config_write_network (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
5466
5467 /* BGP redistribute configuration. */
5468 bgp_config_write_redistribute (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
5469
5470 /* BGP timers configuration. */
5471 if (bgp->default_keepalive != BGP_DEFAULT_KEEPALIVE
5472 && bgp->default_holdtime != BGP_DEFAULT_HOLDTIME)
5473 vty_out (vty, " timers bgp %d %d%s", bgp->default_keepalive,
5474 bgp->default_holdtime, VTY_NEWLINE);
5475
5476 /* peer-group */
5477 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
5478 {
5479 bgp_config_write_peer (vty, bgp, group->conf, AFI_IP, SAFI_UNICAST);
5480 }
5481
5482 /* Normal neighbor configuration. */
5483 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
5484 {
5485 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
5486 bgp_config_write_peer (vty, bgp, peer, AFI_IP, SAFI_UNICAST);
5487 }
5488
5489 /* maximum-paths */
5490 bgp_config_write_maxpaths (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
5491
5492 /* Distance configuration. */
5493 bgp_config_write_distance (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
5494
5495 /* No auto-summary */
5496 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
5497 vty_out (vty, " no auto-summary%s", VTY_NEWLINE);
5498
5499 /* IPv4 multicast configuration. */
5500 write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MULTICAST);
5501
5502 /* IPv4 VPN configuration. */
5503 write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MPLS_VPN);
5504
5505 /* ENCAPv4 configuration. */
5506 write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_ENCAP);
5507
5508 /* IPv6 unicast configuration. */
5509 write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_UNICAST);
5510
5511 /* IPv6 multicast configuration. */
5512 write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_MULTICAST);
5513
5514 /* IPv6 VPN configuration. */
5515 write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_MPLS_VPN);
5516
5517 /* ENCAPv6 configuration. */
5518 write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_ENCAP);
5519
5520 vty_out (vty, " exit%s", VTY_NEWLINE);
5521
5522 write++;
5523 }
5524 return write;
5525 }
5526
5527 void
bgp_master_init(void)5528 bgp_master_init (void)
5529 {
5530 memset (&bgp_master, 0, sizeof (struct bgp_master));
5531
5532 bm = &bgp_master;
5533 bm->bgp = list_new ();
5534 bm->listen_sockets = list_new ();
5535 bm->port = BGP_PORT_DEFAULT;
5536 bm->master = thread_master_create ();
5537 bm->start_time = bgp_clock ();
5538 }
5539
5540
5541 void
bgp_init(void)5542 bgp_init (void)
5543 {
5544
5545 /* allocates some vital data structures used by peer commands in vty_init */
5546 bgp_scan_init ();
5547
5548 /* Init zebra. */
5549 bgp_zebra_init (bm->master);
5550
5551 /* BGP VTY commands installation. */
5552 bgp_vty_init ();
5553
5554 /* BGP inits. */
5555 bgp_attr_init ();
5556 bgp_debug_init ();
5557 bgp_dump_init ();
5558 bgp_route_init ();
5559 bgp_route_map_init ();
5560 bgp_address_init ();
5561 bgp_scan_vty_init();
5562 bgp_mplsvpn_init ();
5563 bgp_encap_init ();
5564
5565 /* Access list initialize. */
5566 access_list_init ();
5567 access_list_add_hook (peer_distribute_update);
5568 access_list_delete_hook (peer_distribute_update);
5569
5570 /* Filter list initialize. */
5571 bgp_filter_init ();
5572 as_list_add_hook (peer_aslist_update);
5573 as_list_delete_hook (peer_aslist_update);
5574
5575 /* Prefix list initialize.*/
5576 prefix_list_init ();
5577 prefix_list_add_hook (peer_prefix_list_update);
5578 prefix_list_delete_hook (peer_prefix_list_update);
5579
5580 /* Community list initialize. */
5581 bgp_clist = community_list_init ();
5582
5583 #ifdef HAVE_SNMP
5584 bgp_snmp_init ();
5585 #endif /* HAVE_SNMP */
5586 }
5587
5588 void
bgp_terminate(void)5589 bgp_terminate (void)
5590 {
5591 struct bgp *bgp;
5592 struct peer *peer;
5593 struct listnode *node, *nnode;
5594 struct listnode *mnode, *mnnode;
5595
5596 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
5597 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
5598 if (peer->status == Established)
5599 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
5600 BGP_NOTIFY_CEASE_PEER_UNCONFIG);
5601
5602 bgp_cleanup_routes ();
5603
5604 if (bm->process_main_queue)
5605 {
5606 work_queue_free (bm->process_main_queue);
5607 bm->process_main_queue = NULL;
5608 }
5609 if (bm->process_rsclient_queue)
5610 {
5611 work_queue_free (bm->process_rsclient_queue);
5612 bm->process_rsclient_queue = NULL;
5613 }
5614 }
5615