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