Annotation of embedaddon/quagga/bgpd/bgp_zebra.c, revision 1.1.1.1
1.1 misho 1: /* zebra client
2: Copyright (C) 1997, 98, 99 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
18: Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19: Boston, MA 02111-1307, USA. */
20:
21: #include <zebra.h>
22:
23: #include "command.h"
24: #include "stream.h"
25: #include "network.h"
26: #include "prefix.h"
27: #include "log.h"
28: #include "sockunion.h"
29: #include "zclient.h"
30: #include "routemap.h"
31: #include "thread.h"
32:
33: #include "bgpd/bgpd.h"
34: #include "bgpd/bgp_route.h"
35: #include "bgpd/bgp_attr.h"
36: #include "bgpd/bgp_nexthop.h"
37: #include "bgpd/bgp_zebra.h"
38: #include "bgpd/bgp_fsm.h"
39: #include "bgpd/bgp_debug.h"
40:
41: /* All information about zebra. */
42: struct zclient *zclient = NULL;
43: struct in_addr router_id_zebra;
44:
45: /* Router-id update message from zebra. */
46: static int
47: bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length)
48: {
49: struct prefix router_id;
50: struct listnode *node, *nnode;
51: struct bgp *bgp;
52:
53: zebra_router_id_update_read(zclient->ibuf,&router_id);
54:
55: if (BGP_DEBUG(zebra, ZEBRA))
56: {
57: char buf[128];
58: prefix2str(&router_id, buf, sizeof(buf));
59: zlog_debug("Zebra rcvd: router id update %s", buf);
60: }
61:
62: router_id_zebra = router_id.u.prefix4;
63:
64: for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
65: {
66: if (!bgp->router_id_static.s_addr)
67: bgp_router_id_set (bgp, &router_id.u.prefix4);
68: }
69:
70: return 0;
71: }
72:
73: /* Inteface addition message from zebra. */
74: static int
75: bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length)
76: {
77: struct interface *ifp;
78:
79: ifp = zebra_interface_add_read (zclient->ibuf);
80:
81: if (BGP_DEBUG(zebra, ZEBRA) && ifp)
82: zlog_debug("Zebra rcvd: interface add %s", ifp->name);
83:
84: return 0;
85: }
86:
87: static int
88: bgp_interface_delete (int command, struct zclient *zclient,
89: zebra_size_t length)
90: {
91: struct stream *s;
92: struct interface *ifp;
93:
94: s = zclient->ibuf;
95: ifp = zebra_interface_state_read (s);
96: ifp->ifindex = IFINDEX_INTERNAL;
97:
98: if (BGP_DEBUG(zebra, ZEBRA))
99: zlog_debug("Zebra rcvd: interface delete %s", ifp->name);
100:
101: return 0;
102: }
103:
104: static int
105: bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length)
106: {
107: struct stream *s;
108: struct interface *ifp;
109: struct connected *c;
110: struct listnode *node, *nnode;
111:
112: s = zclient->ibuf;
113: ifp = zebra_interface_state_read (s);
114:
115: if (! ifp)
116: return 0;
117:
118: if (BGP_DEBUG(zebra, ZEBRA))
119: zlog_debug("Zebra rcvd: interface %s up", ifp->name);
120:
121: for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
122: bgp_connected_add (c);
123:
124: return 0;
125: }
126:
127: static int
128: bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length)
129: {
130: struct stream *s;
131: struct interface *ifp;
132: struct connected *c;
133: struct listnode *node, *nnode;
134:
135: s = zclient->ibuf;
136: ifp = zebra_interface_state_read (s);
137: if (! ifp)
138: return 0;
139:
140: if (BGP_DEBUG(zebra, ZEBRA))
141: zlog_debug("Zebra rcvd: interface %s down", ifp->name);
142:
143: for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
144: bgp_connected_delete (c);
145:
146: /* Fast external-failover (Currently IPv4 only) */
147: {
148: struct listnode *mnode;
149: struct bgp *bgp;
150: struct peer *peer;
151: struct interface *peer_if;
152:
153: for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
154: {
155: if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
156: continue;
157:
158: for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
159: {
160: if (peer->ttl != 1)
161: continue;
162:
163: if (peer->su.sa.sa_family == AF_INET)
164: peer_if = if_lookup_by_ipv4 (&peer->su.sin.sin_addr);
165: else
166: continue;
167:
168: if (ifp == peer_if)
169: BGP_EVENT_ADD (peer, BGP_Stop);
170: }
171: }
172: }
173:
174: return 0;
175: }
176:
177: static int
178: bgp_interface_address_add (int command, struct zclient *zclient,
179: zebra_size_t length)
180: {
181: struct connected *ifc;
182:
183: ifc = zebra_interface_address_read (command, zclient->ibuf);
184:
185: if (ifc == NULL)
186: return 0;
187:
188: if (BGP_DEBUG(zebra, ZEBRA))
189: {
190: char buf[128];
191: prefix2str(ifc->address, buf, sizeof(buf));
192: zlog_debug("Zebra rcvd: interface %s address add %s",
193: ifc->ifp->name, buf);
194: }
195:
196: if (if_is_operative (ifc->ifp))
197: bgp_connected_add (ifc);
198:
199: return 0;
200: }
201:
202: static int
203: bgp_interface_address_delete (int command, struct zclient *zclient,
204: zebra_size_t length)
205: {
206: struct connected *ifc;
207:
208: ifc = zebra_interface_address_read (command, zclient->ibuf);
209:
210: if (ifc == NULL)
211: return 0;
212:
213: if (BGP_DEBUG(zebra, ZEBRA))
214: {
215: char buf[128];
216: prefix2str(ifc->address, buf, sizeof(buf));
217: zlog_debug("Zebra rcvd: interface %s address delete %s",
218: ifc->ifp->name, buf);
219: }
220:
221: if (if_is_operative (ifc->ifp))
222: bgp_connected_delete (ifc);
223:
224: connected_free (ifc);
225:
226: return 0;
227: }
228:
229: /* Zebra route add and delete treatment. */
230: static int
231: zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
232: {
233: struct stream *s;
234: struct zapi_ipv4 api;
235: unsigned long ifindex;
236: struct in_addr nexthop;
237: struct prefix_ipv4 p;
238:
239: s = zclient->ibuf;
240: ifindex = 0;
241: nexthop.s_addr = 0;
242:
243: /* Type, flags, message. */
244: api.type = stream_getc (s);
245: api.flags = stream_getc (s);
246: api.message = stream_getc (s);
247:
248: /* IPv4 prefix. */
249: memset (&p, 0, sizeof (struct prefix_ipv4));
250: p.family = AF_INET;
251: p.prefixlen = stream_getc (s);
252: stream_get (&p.prefix, s, PSIZE (p.prefixlen));
253:
254: /* Nexthop, ifindex, distance, metric. */
255: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
256: {
257: api.nexthop_num = stream_getc (s);
258: nexthop.s_addr = stream_get_ipv4 (s);
259: }
260: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
261: {
262: api.ifindex_num = stream_getc (s);
263: ifindex = stream_getl (s);
264: }
265: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
266: api.distance = stream_getc (s);
267: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
268: api.metric = stream_getl (s);
269: else
270: api.metric = 0;
271:
272: if (command == ZEBRA_IPV4_ROUTE_ADD)
273: {
274: if (BGP_DEBUG(zebra, ZEBRA))
275: {
276: char buf[2][INET_ADDRSTRLEN];
277: zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
278: zebra_route_string(api.type),
279: inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
280: p.prefixlen,
281: inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
282: api.metric);
283: }
284: bgp_redistribute_add((struct prefix *)&p, &nexthop, api.metric, api.type);
285: }
286: else
287: {
288: if (BGP_DEBUG(zebra, ZEBRA))
289: {
290: char buf[2][INET_ADDRSTRLEN];
291: zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
292: "nexthop %s metric %u",
293: zebra_route_string(api.type),
294: inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
295: p.prefixlen,
296: inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
297: api.metric);
298: }
299: bgp_redistribute_delete((struct prefix *)&p, api.type);
300: }
301:
302: return 0;
303: }
304:
305: #ifdef HAVE_IPV6
306: /* Zebra route add and delete treatment. */
307: static int
308: zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
309: {
310: struct stream *s;
311: struct zapi_ipv6 api;
312: unsigned long ifindex;
313: struct in6_addr nexthop;
314: struct prefix_ipv6 p;
315:
316: s = zclient->ibuf;
317: ifindex = 0;
318: memset (&nexthop, 0, sizeof (struct in6_addr));
319:
320: /* Type, flags, message. */
321: api.type = stream_getc (s);
322: api.flags = stream_getc (s);
323: api.message = stream_getc (s);
324:
325: /* IPv6 prefix. */
326: memset (&p, 0, sizeof (struct prefix_ipv6));
327: p.family = AF_INET6;
328: p.prefixlen = stream_getc (s);
329: stream_get (&p.prefix, s, PSIZE (p.prefixlen));
330:
331: /* Nexthop, ifindex, distance, metric. */
332: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
333: {
334: api.nexthop_num = stream_getc (s);
335: stream_get (&nexthop, s, 16);
336: }
337: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
338: {
339: api.ifindex_num = stream_getc (s);
340: ifindex = stream_getl (s);
341: }
342: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
343: api.distance = stream_getc (s);
344: else
345: api.distance = 0;
346: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
347: api.metric = stream_getl (s);
348: else
349: api.metric = 0;
350:
351: /* Simply ignore link-local address. */
352: if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
353: return 0;
354:
355: if (command == ZEBRA_IPV6_ROUTE_ADD)
356: {
357: if (BGP_DEBUG(zebra, ZEBRA))
358: {
359: char buf[INET6_ADDRSTRLEN];
360: zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d metric %u",
361: zebra_route_string(api.type),
362: inet_ntop(AF_INET6, &p.prefix, buf, sizeof(buf)),
363: p.prefixlen, api.metric);
364: }
365: bgp_redistribute_add ((struct prefix *)&p, NULL, api.metric, api.type);
366: }
367: else
368: {
369: if (BGP_DEBUG(zebra, ZEBRA))
370: {
371: char buf[INET6_ADDRSTRLEN];
372: zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d metric %u",
373: zebra_route_string(api.type),
374: inet_ntop(AF_INET6, &p.prefix, buf, sizeof(buf)),
375: p.prefixlen, api.metric);
376: }
377: bgp_redistribute_delete ((struct prefix *) &p, api.type);
378: }
379:
380: return 0;
381: }
382: #endif /* HAVE_IPV6 */
383:
384: struct interface *
385: if_lookup_by_ipv4 (struct in_addr *addr)
386: {
387: struct listnode *ifnode;
388: struct listnode *cnode;
389: struct interface *ifp;
390: struct connected *connected;
391: struct prefix_ipv4 p;
392: struct prefix *cp;
393:
394: p.family = AF_INET;
395: p.prefix = *addr;
396: p.prefixlen = IPV4_MAX_BITLEN;
397:
398: for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
399: {
400: for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
401: {
402: cp = connected->address;
403:
404: if (cp->family == AF_INET)
405: if (prefix_match (cp, (struct prefix *)&p))
406: return ifp;
407: }
408: }
409: return NULL;
410: }
411:
412: struct interface *
413: if_lookup_by_ipv4_exact (struct in_addr *addr)
414: {
415: struct listnode *ifnode;
416: struct listnode *cnode;
417: struct interface *ifp;
418: struct connected *connected;
419: struct prefix *cp;
420:
421: for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
422: {
423: for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
424: {
425: cp = connected->address;
426:
427: if (cp->family == AF_INET)
428: if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
429: return ifp;
430: }
431: }
432: return NULL;
433: }
434:
435: #ifdef HAVE_IPV6
436: struct interface *
437: if_lookup_by_ipv6 (struct in6_addr *addr)
438: {
439: struct listnode *ifnode;
440: struct listnode *cnode;
441: struct interface *ifp;
442: struct connected *connected;
443: struct prefix_ipv6 p;
444: struct prefix *cp;
445:
446: p.family = AF_INET6;
447: p.prefix = *addr;
448: p.prefixlen = IPV6_MAX_BITLEN;
449:
450: for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
451: {
452: for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
453: {
454: cp = connected->address;
455:
456: if (cp->family == AF_INET6)
457: if (prefix_match (cp, (struct prefix *)&p))
458: return ifp;
459: }
460: }
461: return NULL;
462: }
463:
464: struct interface *
465: if_lookup_by_ipv6_exact (struct in6_addr *addr)
466: {
467: struct listnode *ifnode;
468: struct listnode *cnode;
469: struct interface *ifp;
470: struct connected *connected;
471: struct prefix *cp;
472:
473: for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
474: {
475: for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
476: {
477: cp = connected->address;
478:
479: if (cp->family == AF_INET6)
480: if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
481: return ifp;
482: }
483: }
484: return NULL;
485: }
486:
487: static int
488: if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
489: {
490: struct listnode *cnode;
491: struct connected *connected;
492: struct prefix *cp;
493:
494: for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
495: {
496: cp = connected->address;
497:
498: if (cp->family == AF_INET6)
499: if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
500: {
501: memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
502: return 1;
503: }
504: }
505: return 0;
506: }
507:
508: static int
509: if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
510: {
511: struct listnode *cnode;
512: struct connected *connected;
513: struct prefix *cp;
514:
515: for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
516: {
517: cp = connected->address;
518:
519: if (cp->family == AF_INET6)
520: if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
521: {
522: memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
523: return 1;
524: }
525: }
526: return 0;
527: }
528: #endif /* HAVE_IPV6 */
529:
530: int
531: bgp_nexthop_set (union sockunion *local, union sockunion *remote,
532: struct bgp_nexthop *nexthop, struct peer *peer)
533: {
534: int ret = 0;
535: struct interface *ifp = NULL;
536:
537: memset (nexthop, 0, sizeof (struct bgp_nexthop));
538:
539: if (!local)
540: return -1;
541: if (!remote)
542: return -1;
543:
544: if (local->sa.sa_family == AF_INET)
545: {
546: nexthop->v4 = local->sin.sin_addr;
547: ifp = if_lookup_by_ipv4 (&local->sin.sin_addr);
548: }
549: #ifdef HAVE_IPV6
550: if (local->sa.sa_family == AF_INET6)
551: {
552: if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
553: {
554: if (peer->ifname)
555: ifp = if_lookup_by_index (if_nametoindex (peer->ifname));
556: }
557: else
558: ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr);
559: }
560: #endif /* HAVE_IPV6 */
561:
562: if (!ifp)
563: return -1;
564:
565: nexthop->ifp = ifp;
566:
567: /* IPv4 connection. */
568: if (local->sa.sa_family == AF_INET)
569: {
570: #ifdef HAVE_IPV6
571: /* IPv6 nexthop*/
572: ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
573:
574: /* There is no global nexthop. */
575: if (!ret)
576: if_get_ipv6_local (ifp, &nexthop->v6_global);
577: else
578: if_get_ipv6_local (ifp, &nexthop->v6_local);
579: #endif /* HAVE_IPV6 */
580: }
581:
582: #ifdef HAVE_IPV6
583: /* IPv6 connection. */
584: if (local->sa.sa_family == AF_INET6)
585: {
586: struct interface *direct = NULL;
587:
588: /* IPv4 nexthop. I don't care about it. */
589: if (peer->local_id.s_addr)
590: nexthop->v4 = peer->local_id;
591:
592: /* Global address*/
593: if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
594: {
595: memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
596: IPV6_MAX_BYTELEN);
597:
598: /* If directory connected set link-local address. */
599: direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
600: if (direct)
601: if_get_ipv6_local (ifp, &nexthop->v6_local);
602: }
603: else
604: /* Link-local address. */
605: {
606: ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
607:
608: /* If there is no global address. Set link-local address as
609: global. I know this break RFC specification... */
610: if (!ret)
611: memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
612: IPV6_MAX_BYTELEN);
613: else
614: memcpy (&nexthop->v6_local, &local->sin6.sin6_addr,
615: IPV6_MAX_BYTELEN);
616: }
617: }
618:
619: if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
620: if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
621: peer->shared_network = 1;
622: else
623: peer->shared_network = 0;
624:
625: /* KAME stack specific treatment. */
626: #ifdef KAME
627: if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
628: && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
629: {
630: SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
631: }
632: if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
633: && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
634: {
635: SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
636: }
637: #endif /* KAME */
638: #endif /* HAVE_IPV6 */
639: return ret;
640: }
641:
642: void
643: bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp)
644: {
645: int flags;
646: u_char distance;
647: struct peer *peer;
648:
649: if (zclient->sock < 0)
650: return;
651:
652: if (! zclient->redist[ZEBRA_ROUTE_BGP])
653: return;
654:
655: flags = 0;
656: peer = info->peer;
657:
658: if (peer_sort (peer) == BGP_PEER_IBGP || peer_sort (peer) == BGP_PEER_CONFED)
659: {
660: SET_FLAG (flags, ZEBRA_FLAG_IBGP);
661: SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
662: }
663:
664: if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
665: || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
666: SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
667:
668: if (p->family == AF_INET)
669: {
670: struct zapi_ipv4 api;
671: struct in_addr *nexthop;
672:
673: api.flags = flags;
674: nexthop = &info->attr->nexthop;
675:
676: api.type = ZEBRA_ROUTE_BGP;
677: api.message = 0;
678: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
679: api.nexthop_num = 1;
680: api.nexthop = &nexthop;
681: api.ifindex_num = 0;
682: SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
683: api.metric = info->attr->med;
684:
685: distance = bgp_distance_apply (p, info, bgp);
686:
687: if (distance)
688: {
689: SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
690: api.distance = distance;
691: }
692:
693: if (BGP_DEBUG(zebra, ZEBRA))
694: {
695: char buf[2][INET_ADDRSTRLEN];
696: zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u",
697: inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
698: p->prefixlen,
699: inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])),
700: api.metric);
701: }
702:
703: zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient,
704: (struct prefix_ipv4 *) p, &api);
705: }
706: #ifdef HAVE_IPV6
707: /* We have to think about a IPv6 link-local address curse. */
708: if (p->family == AF_INET6)
709: {
710: unsigned int ifindex;
711: struct in6_addr *nexthop;
712: struct zapi_ipv6 api;
713:
714: ifindex = 0;
715: nexthop = NULL;
716:
717: assert (info->attr->extra);
718:
719: /* Only global address nexthop exists. */
720: if (info->attr->extra->mp_nexthop_len == 16)
721: nexthop = &info->attr->extra->mp_nexthop_global;
722:
723: /* If both global and link-local address present. */
724: if (info->attr->extra->mp_nexthop_len == 32)
725: {
726: /* Workaround for Cisco's nexthop bug. */
727: if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
728: && peer->su_remote->sa.sa_family == AF_INET6)
729: nexthop = &peer->su_remote->sin6.sin6_addr;
730: else
731: nexthop = &info->attr->extra->mp_nexthop_local;
732:
733: if (info->peer->nexthop.ifp)
734: ifindex = info->peer->nexthop.ifp->ifindex;
735: }
736:
737: if (nexthop == NULL)
738: return;
739:
740: if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
741: {
742: if (info->peer->ifname)
743: ifindex = if_nametoindex (info->peer->ifname);
744: else if (info->peer->nexthop.ifp)
745: ifindex = info->peer->nexthop.ifp->ifindex;
746: }
747:
748: /* Make Zebra API structure. */
749: api.flags = flags;
750: api.type = ZEBRA_ROUTE_BGP;
751: api.message = 0;
752: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
753: api.nexthop_num = 1;
754: api.nexthop = &nexthop;
755: SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
756: api.ifindex_num = 1;
757: api.ifindex = &ifindex;
758: SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
759: api.metric = info->attr->med;
760:
761: if (BGP_DEBUG(zebra, ZEBRA))
762: {
763: char buf[2][INET6_ADDRSTRLEN];
764: zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
765: inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
766: p->prefixlen,
767: inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
768: api.metric);
769: }
770:
771: zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient,
772: (struct prefix_ipv6 *) p, &api);
773: }
774: #endif /* HAVE_IPV6 */
775: }
776:
777: void
778: bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info)
779: {
780: int flags;
781: struct peer *peer;
782:
783: if (zclient->sock < 0)
784: return;
785:
786: if (! zclient->redist[ZEBRA_ROUTE_BGP])
787: return;
788:
789: peer = info->peer;
790: flags = 0;
791:
792: if (peer_sort (peer) == BGP_PEER_IBGP)
793: {
794: SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
795: SET_FLAG (flags, ZEBRA_FLAG_IBGP);
796: }
797:
798: if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
799: || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
800: SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
801:
802: if (p->family == AF_INET)
803: {
804: struct zapi_ipv4 api;
805: struct in_addr *nexthop;
806:
807: api.flags = flags;
808: nexthop = &info->attr->nexthop;
809:
810: api.type = ZEBRA_ROUTE_BGP;
811: api.message = 0;
812: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
813: api.nexthop_num = 1;
814: api.nexthop = &nexthop;
815: api.ifindex_num = 0;
816: SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
817: api.metric = info->attr->med;
818:
819: if (BGP_DEBUG(zebra, ZEBRA))
820: {
821: char buf[2][INET_ADDRSTRLEN];
822: zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u",
823: inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
824: p->prefixlen,
825: inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])),
826: api.metric);
827: }
828:
829: zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
830: (struct prefix_ipv4 *) p, &api);
831: }
832: #ifdef HAVE_IPV6
833: /* We have to think about a IPv6 link-local address curse. */
834: if (p->family == AF_INET6)
835: {
836: struct zapi_ipv6 api;
837: unsigned int ifindex;
838: struct in6_addr *nexthop;
839:
840: assert (info->attr->extra);
841:
842: ifindex = 0;
843: nexthop = NULL;
844:
845: /* Only global address nexthop exists. */
846: if (info->attr->extra->mp_nexthop_len == 16)
847: nexthop = &info->attr->extra->mp_nexthop_global;
848:
849: /* If both global and link-local address present. */
850: if (info->attr->extra->mp_nexthop_len == 32)
851: {
852: nexthop = &info->attr->extra->mp_nexthop_local;
853: if (info->peer->nexthop.ifp)
854: ifindex = info->peer->nexthop.ifp->ifindex;
855: }
856:
857: if (nexthop == NULL)
858: return;
859:
860: if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
861: if (info->peer->ifname)
862: ifindex = if_nametoindex (info->peer->ifname);
863:
864: api.flags = flags;
865: api.type = ZEBRA_ROUTE_BGP;
866: api.message = 0;
867: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
868: api.nexthop_num = 1;
869: api.nexthop = &nexthop;
870: SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
871: api.ifindex_num = 1;
872: api.ifindex = &ifindex;
873: SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
874: api.metric = info->attr->med;
875:
876: if (BGP_DEBUG(zebra, ZEBRA))
877: {
878: char buf[2][INET6_ADDRSTRLEN];
879: zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u",
880: inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
881: p->prefixlen,
882: inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
883: api.metric);
884: }
885:
886: zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
887: (struct prefix_ipv6 *) p, &api);
888: }
889: #endif /* HAVE_IPV6 */
890: }
891:
892: /* Other routes redistribution into BGP. */
893: int
894: bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
895: {
896: /* Set flag to BGP instance. */
897: bgp->redist[afi][type] = 1;
898:
899: /* Return if already redistribute flag is set. */
900: if (zclient->redist[type])
901: return CMD_WARNING;
902:
903: zclient->redist[type] = 1;
904:
905: /* Return if zebra connection is not established. */
906: if (zclient->sock < 0)
907: return CMD_WARNING;
908:
909: if (BGP_DEBUG(zebra, ZEBRA))
910: zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
911:
912: /* Send distribute add message to zebra. */
913: zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
914:
915: return CMD_SUCCESS;
916: }
917:
918: /* Redistribute with route-map specification. */
919: int
920: bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type,
921: const char *name)
922: {
923: if (bgp->rmap[afi][type].name
924: && (strcmp (bgp->rmap[afi][type].name, name) == 0))
925: return 0;
926:
927: if (bgp->rmap[afi][type].name)
928: free (bgp->rmap[afi][type].name);
929: bgp->rmap[afi][type].name = strdup (name);
930: bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
931:
932: return 1;
933: }
934:
935: /* Redistribute with metric specification. */
936: int
937: bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
938: u_int32_t metric)
939: {
940: if (bgp->redist_metric_flag[afi][type]
941: && bgp->redist_metric[afi][type] == metric)
942: return 0;
943:
944: bgp->redist_metric_flag[afi][type] = 1;
945: bgp->redist_metric[afi][type] = metric;
946:
947: return 1;
948: }
949:
950: /* Unset redistribution. */
951: int
952: bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
953: {
954: /* Unset flag from BGP instance. */
955: bgp->redist[afi][type] = 0;
956:
957: /* Unset route-map. */
958: if (bgp->rmap[afi][type].name)
959: free (bgp->rmap[afi][type].name);
960: bgp->rmap[afi][type].name = NULL;
961: bgp->rmap[afi][type].map = NULL;
962:
963: /* Unset metric. */
964: bgp->redist_metric_flag[afi][type] = 0;
965: bgp->redist_metric[afi][type] = 0;
966:
967: /* Return if zebra connection is disabled. */
968: if (! zclient->redist[type])
969: return CMD_WARNING;
970: zclient->redist[type] = 0;
971:
972: if (bgp->redist[AFI_IP][type] == 0
973: && bgp->redist[AFI_IP6][type] == 0
974: && zclient->sock >= 0)
975: {
976: /* Send distribute delete message to zebra. */
977: if (BGP_DEBUG(zebra, ZEBRA))
978: zlog_debug("Zebra send: redistribute delete %s",
979: zebra_route_string(type));
980: zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
981: }
982:
983: /* Withdraw redistributed routes from current BGP's routing table. */
984: bgp_redistribute_withdraw (bgp, afi, type);
985:
986: return CMD_SUCCESS;
987: }
988:
989: /* Unset redistribution route-map configuration. */
990: int
991: bgp_redistribute_routemap_unset (struct bgp *bgp, afi_t afi, int type)
992: {
993: if (! bgp->rmap[afi][type].name)
994: return 0;
995:
996: /* Unset route-map. */
997: free (bgp->rmap[afi][type].name);
998: bgp->rmap[afi][type].name = NULL;
999: bgp->rmap[afi][type].map = NULL;
1000:
1001: return 1;
1002: }
1003:
1004: /* Unset redistribution metric configuration. */
1005: int
1006: bgp_redistribute_metric_unset (struct bgp *bgp, afi_t afi, int type)
1007: {
1008: if (! bgp->redist_metric_flag[afi][type])
1009: return 0;
1010:
1011: /* Unset metric. */
1012: bgp->redist_metric_flag[afi][type] = 0;
1013: bgp->redist_metric[afi][type] = 0;
1014:
1015: return 1;
1016: }
1017:
1018: void
1019: bgp_zclient_reset (void)
1020: {
1021: zclient_reset (zclient);
1022: }
1023:
1024: void
1025: bgp_zebra_init (void)
1026: {
1027: /* Set default values. */
1028: zclient = zclient_new ();
1029: zclient_init (zclient, ZEBRA_ROUTE_BGP);
1030: zclient->router_id_update = bgp_router_id_update;
1031: zclient->interface_add = bgp_interface_add;
1032: zclient->interface_delete = bgp_interface_delete;
1033: zclient->interface_address_add = bgp_interface_address_add;
1034: zclient->interface_address_delete = bgp_interface_address_delete;
1035: zclient->ipv4_route_add = zebra_read_ipv4;
1036: zclient->ipv4_route_delete = zebra_read_ipv4;
1037: zclient->interface_up = bgp_interface_up;
1038: zclient->interface_down = bgp_interface_down;
1039: #ifdef HAVE_IPV6
1040: zclient->ipv6_route_add = zebra_read_ipv6;
1041: zclient->ipv6_route_delete = zebra_read_ipv6;
1042: #endif /* HAVE_IPV6 */
1043:
1044: /* Interface related init. */
1045: if_init ();
1046: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>