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