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