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