]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_zebra.c
Merge branch 'cmaster' of ssh://stash.cumulusnetworks.com:7999/quag/quagga into cmaster
[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 #include "queue.h"
33 #include "memory.h"
34 #include "lib/json.h"
35
36 #include "bgpd/bgpd.h"
37 #include "bgpd/bgp_route.h"
38 #include "bgpd/bgp_attr.h"
39 #include "bgpd/bgp_nexthop.h"
40 #include "bgpd/bgp_zebra.h"
41 #include "bgpd/bgp_fsm.h"
42 #include "bgpd/bgp_debug.h"
43 #include "bgpd/bgp_mpath.h"
44 #include "bgpd/bgp_nexthop.h"
45 #include "bgpd/bgp_nht.h"
46 #include "bgpd/bgp_bfd.h"
47
48 /* All information about zebra. */
49 struct zclient *zclient = NULL;
50 struct in_addr router_id_zebra;
51
52 /* Growable buffer for nexthops sent to zebra */
53 struct stream *bgp_nexthop_buf = NULL;
54 struct stream *bgp_ifindices_buf = NULL;
55
56 /* These array buffers are used in making a copy of the attributes for
57 route-map apply. Arrays are being used here to minimize mallocs and
58 frees for the temporary copy of the attributes.
59 Given the zapi api expects the nexthop buffer to contain pointer to
60 pointers for nexthops, we couldnt have used a single nexthop variable
61 on the stack, hence we had two options:
62 1. maintain a linked-list and free it after zapi_*_route call
63 2. use an array to avoid number of mallocs.
64 Number of supported next-hops are finite, use of arrays should be ok. */
65 struct attr attr_cp[BGP_MAXIMUM_MAXPATHS];
66 struct attr_extra attr_extra_cp[BGP_MAXIMUM_MAXPATHS];
67 int attr_index = 0;
68
69 /* Once per address-family initialization of the attribute array */
70 #define BGP_INFO_ATTR_BUF_INIT()\
71 do {\
72 memset(attr_cp, 0, BGP_MAXIMUM_MAXPATHS * sizeof(struct attr));\
73 memset(attr_extra_cp, 0, BGP_MAXIMUM_MAXPATHS * sizeof(struct attr_extra));\
74 attr_index = 0;\
75 } while (0)
76
77 #define BGP_INFO_ATTR_BUF_COPY(info_src, info_dst)\
78 do { \
79 *info_dst = *info_src; \
80 assert(attr_index != BGP_MAXIMUM_MAXPATHS);\
81 attr_cp[attr_index].extra = &attr_extra_cp[attr_index]; \
82 bgp_attr_dup (&attr_cp[attr_index], info_src->attr); \
83 bgp_attr_deep_dup (&attr_cp[attr_index], info_src->attr); \
84 info_dst->attr = &attr_cp[attr_index]; \
85 attr_index++;\
86 } while (0)
87
88 #define BGP_INFO_ATTR_BUF_FREE(info) \
89 do { \
90 bgp_attr_deep_free(info->attr); \
91 } while (0)
92
93 /* Router-id update message from zebra. */
94 static int
95 bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length)
96 {
97 struct prefix router_id;
98 struct listnode *node, *nnode;
99 struct bgp *bgp;
100
101 zebra_router_id_update_read(zclient->ibuf,&router_id);
102
103 if (BGP_DEBUG (zebra, ZEBRA))
104 {
105 char buf[128];
106 prefix2str(&router_id, buf, sizeof(buf));
107 zlog_debug("Zebra rcvd: router id update %s", buf);
108 }
109
110 router_id_zebra = router_id.u.prefix4;
111
112 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
113 {
114 if (!bgp->router_id_static.s_addr)
115 bgp_router_id_set (bgp, &router_id.u.prefix4);
116 }
117
118 return 0;
119 }
120
121 /* Nexthop update message from zebra. */
122 static int
123 bgp_read_nexthop_update (int command, struct zclient *zclient,
124 zebra_size_t length)
125 {
126 bgp_parse_nexthop_update(command);
127 return 0;
128 }
129
130 static int
131 bgp_read_import_check_update(int command, struct zclient *zclient,
132 zebra_size_t length)
133 {
134 bgp_parse_nexthop_update(command);
135 return 0;
136 }
137
138 static void
139 bgp_start_interface_nbrs (struct interface *ifp)
140 {
141 struct listnode *node, *nnode, *mnode;
142 struct bgp *bgp;
143 struct peer *peer;
144
145 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
146 {
147 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
148 {
149 if (peer->conf_if &&
150 (strcmp (peer->conf_if, ifp->name) == 0) &&
151 peer->status != Established)
152 {
153 if (peer_active(peer))
154 BGP_EVENT_ADD (peer, BGP_Stop);
155 BGP_EVENT_ADD (peer, BGP_Start);
156 }
157 }
158 }
159 }
160
161 static void
162 bgp_nbr_connected_add (struct nbr_connected *ifc)
163 {
164 struct listnode *node;
165 struct connected *connected;
166 struct interface *ifp;
167 struct prefix *p;
168
169 /* Kick-off the FSM for any relevant peers only if there is a
170 * valid local address on the interface.
171 */
172 ifp = ifc->ifp;
173 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
174 {
175 p = connected->address;
176 if (p->family == AF_INET6 &&
177 IN6_IS_ADDR_LINKLOCAL (&p->u.prefix6))
178 break;
179 }
180 if (!connected)
181 return;
182
183 bgp_start_interface_nbrs (ifp);
184 }
185
186 static void
187 bgp_nbr_connected_delete (struct nbr_connected *ifc, int del)
188 {
189 struct listnode *node, *nnode, *mnode;
190 struct bgp *bgp;
191 struct peer *peer;
192 struct interface *ifp;
193
194 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
195 {
196 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
197 {
198 if (peer->conf_if && (strcmp (peer->conf_if, ifc->ifp->name) == 0))
199 {
200 BGP_EVENT_ADD (peer, BGP_Stop);
201 }
202 }
203 }
204 /* Free neighbor also, if we're asked to. */
205 if (del)
206 {
207 ifp = ifc->ifp;
208 listnode_delete (ifp->nbr_connected, ifc);
209 nbr_connected_free (ifc);
210 }
211 }
212
213 /* Inteface addition message from zebra. */
214 static int
215 bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length)
216 {
217 struct interface *ifp;
218
219 ifp = zebra_interface_add_read (zclient->ibuf);
220
221 if (BGP_DEBUG (zebra, ZEBRA) && ifp)
222 zlog_debug("Zebra rcvd: interface add %s", ifp->name);
223
224 return 0;
225 }
226
227 static int
228 bgp_interface_delete (int command, struct zclient *zclient,
229 zebra_size_t length)
230 {
231 struct stream *s;
232 struct interface *ifp;
233
234 s = zclient->ibuf;
235 ifp = zebra_interface_state_read (s);
236 ifp->ifindex = IFINDEX_INTERNAL;
237
238 if (BGP_DEBUG (zebra, ZEBRA))
239 zlog_debug("Zebra rcvd: interface delete %s", ifp->name);
240
241 return 0;
242 }
243
244 static int
245 bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length)
246 {
247 struct stream *s;
248 struct interface *ifp;
249 struct connected *c;
250 struct nbr_connected *nc;
251 struct listnode *node, *nnode;
252
253 s = zclient->ibuf;
254 ifp = zebra_interface_state_read (s);
255
256 if (! ifp)
257 return 0;
258
259 if (BGP_DEBUG (zebra, ZEBRA))
260 zlog_debug("Zebra rcvd: interface %s up", ifp->name);
261
262 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
263 bgp_connected_add (c);
264
265 for (ALL_LIST_ELEMENTS (ifp->nbr_connected, node, nnode, nc))
266 bgp_nbr_connected_add (nc);
267
268 return 0;
269 }
270
271 static int
272 bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length)
273 {
274 struct stream *s;
275 struct interface *ifp;
276 struct connected *c;
277 struct nbr_connected *nc;
278 struct listnode *node, *nnode;
279
280 s = zclient->ibuf;
281 ifp = zebra_interface_state_read (s);
282 if (! ifp)
283 return 0;
284
285 if (BGP_DEBUG (zebra, ZEBRA))
286 zlog_debug("Zebra rcvd: interface %s down", ifp->name);
287
288 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
289 bgp_connected_delete (c);
290
291 for (ALL_LIST_ELEMENTS (ifp->nbr_connected, node, nnode, nc))
292 bgp_nbr_connected_delete (nc, 1);
293
294 /* Fast external-failover */
295 {
296 struct listnode *mnode;
297 struct bgp *bgp;
298 struct peer *peer;
299
300 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
301 {
302 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
303 continue;
304
305 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
306 {
307 if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
308 continue;
309
310 if (ifp == peer->nexthop.ifp)
311 BGP_EVENT_ADD (peer, BGP_Stop);
312 }
313 }
314 }
315
316 return 0;
317 }
318
319 static int
320 bgp_interface_address_add (int command, struct zclient *zclient,
321 zebra_size_t length)
322 {
323 struct connected *ifc;
324
325 ifc = zebra_interface_address_read (command, zclient->ibuf);
326
327 if (ifc == NULL)
328 return 0;
329
330 if (bgp_debug_zebra(ifc->address))
331 {
332 char buf[128];
333 prefix2str(ifc->address, buf, sizeof(buf));
334 zlog_debug("Zebra rcvd: interface %s address add %s",
335 ifc->ifp->name, buf);
336 }
337
338 if (if_is_operative (ifc->ifp))
339 {
340 bgp_connected_add (ifc);
341 /* If we have learnt of any neighbors on this interface,
342 * check to kick off any BGP interface-based neighbors,
343 * but only if this is a link-local address.
344 */
345 if (IN6_IS_ADDR_LINKLOCAL(&ifc->address->u.prefix6) &&
346 !list_isempty(ifc->ifp->nbr_connected))
347 bgp_start_interface_nbrs (ifc->ifp);
348 }
349
350 return 0;
351 }
352
353 static int
354 bgp_interface_address_delete (int command, struct zclient *zclient,
355 zebra_size_t length)
356 {
357 struct connected *ifc;
358
359 ifc = zebra_interface_address_read (command, zclient->ibuf);
360
361 if (ifc == NULL)
362 return 0;
363
364 if (bgp_debug_zebra(ifc->address))
365 {
366 char buf[128];
367 prefix2str(ifc->address, buf, sizeof(buf));
368 zlog_debug("Zebra rcvd: interface %s address delete %s",
369 ifc->ifp->name, buf);
370 }
371
372 if (if_is_operative (ifc->ifp))
373 bgp_connected_delete (ifc);
374
375 connected_free (ifc);
376
377 return 0;
378 }
379
380 static int
381 bgp_interface_nbr_address_add (int command, struct zclient *zclient,
382 zebra_size_t length)
383 {
384 struct nbr_connected *ifc = NULL;
385
386 ifc = zebra_interface_nbr_address_read (command, zclient->ibuf);
387
388 if (ifc == NULL)
389 return 0;
390
391 if (bgp_debug_zebra(ifc->address))
392 {
393 char buf[128];
394 prefix2str(ifc->address, buf, sizeof(buf));
395 zlog_debug("Zebra rcvd: interface %s nbr address add %s",
396 ifc->ifp->name, buf);
397 }
398
399 if (if_is_operative (ifc->ifp))
400 bgp_nbr_connected_add (ifc);
401
402 return 0;
403 }
404
405 static int
406 bgp_interface_nbr_address_delete (int command, struct zclient *zclient,
407 zebra_size_t length)
408 {
409 struct nbr_connected *ifc = NULL;
410
411 ifc = zebra_interface_nbr_address_read (command, zclient->ibuf);
412
413 if (ifc == NULL)
414 return 0;
415
416 if (bgp_debug_zebra(ifc->address))
417 {
418 char buf[128];
419 prefix2str(ifc->address, buf, sizeof(buf));
420 zlog_debug("Zebra rcvd: interface %s nbr address delete %s",
421 ifc->ifp->name, buf);
422 }
423
424 if (if_is_operative (ifc->ifp))
425 bgp_nbr_connected_delete (ifc, 0);
426
427 nbr_connected_free (ifc);
428
429 return 0;
430 }
431
432 /* Zebra route add and delete treatment. */
433 static int
434 zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
435 {
436 struct stream *s;
437 struct zapi_ipv4 api;
438 struct in_addr nexthop;
439 struct prefix_ipv4 p;
440 unsigned int ifindex;
441
442 s = zclient->ibuf;
443 nexthop.s_addr = 0;
444
445 /* Type, flags, message. */
446 api.type = stream_getc (s);
447 api.instance = stream_getw (s);
448 api.flags = stream_getc (s);
449 api.message = stream_getc (s);
450
451 /* IPv4 prefix. */
452 memset (&p, 0, sizeof (struct prefix_ipv4));
453 p.family = AF_INET;
454 p.prefixlen = stream_getc (s);
455 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
456
457 /* Nexthop, ifindex, distance, metric. */
458 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
459 {
460 api.nexthop_num = stream_getc (s);
461 nexthop.s_addr = stream_get_ipv4 (s);
462 }
463
464 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
465 {
466 api.ifindex_num = stream_getc (s);
467 ifindex = stream_getl (s); /* ifindex, unused */
468 }
469 else
470 {
471 ifindex = 0;
472 }
473
474 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
475 api.distance = stream_getc (s);
476
477 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
478 api.metric = stream_getl (s);
479 else
480 api.metric = 0;
481
482 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
483 api.tag = stream_getw (s);
484 else
485 api.tag = 0;
486
487 if (command == ZEBRA_IPV4_ROUTE_ADD)
488 {
489 if (bgp_debug_zebra((struct prefix *)&p))
490 {
491 char buf[2][INET_ADDRSTRLEN];
492 zlog_debug("Zebra rcvd: IPv4 route add %s[%d] %s/%d nexthop %s metric %u tag %d",
493 zebra_route_string(api.type), api.instance,
494 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
495 p.prefixlen,
496 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
497 api.metric,
498 api.tag);
499 }
500 bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL, ifindex,
501 api.metric, api.type, api.instance, api.tag);
502 }
503 else
504 {
505 if (bgp_debug_zebra((struct prefix *)&p))
506 {
507 char buf[2][INET_ADDRSTRLEN];
508 zlog_debug("Zebra rcvd: IPv4 route delete %s[%d] %s/%d "
509 "nexthop %s metric %u tag %d",
510 zebra_route_string(api.type), api.instance,
511 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
512 p.prefixlen,
513 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
514 api.metric,
515 api.tag);
516 }
517 bgp_redistribute_delete((struct prefix *)&p, api.type, api.instance);
518 }
519
520 return 0;
521 }
522
523 #ifdef HAVE_IPV6
524 /* Zebra route add and delete treatment. */
525 static int
526 zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
527 {
528 struct stream *s;
529 struct zapi_ipv6 api;
530 struct in6_addr nexthop;
531 struct prefix_ipv6 p;
532 unsigned int ifindex;
533
534 s = zclient->ibuf;
535 memset (&nexthop, 0, sizeof (struct in6_addr));
536
537 /* Type, flags, message. */
538 api.type = stream_getc (s);
539 api.instance = stream_getw (s);
540 api.flags = stream_getc (s);
541 api.message = stream_getc (s);
542
543 /* IPv6 prefix. */
544 memset (&p, 0, sizeof (struct prefix_ipv6));
545 p.family = AF_INET6;
546 p.prefixlen = stream_getc (s);
547 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
548
549 /* Nexthop, ifindex, distance, metric. */
550 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
551 {
552 api.nexthop_num = stream_getc (s);
553 stream_get (&nexthop, s, 16);
554 }
555
556 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
557 {
558 api.ifindex_num = stream_getc (s);
559 ifindex = stream_getl (s); /* ifindex, unused */
560 }
561 else
562 {
563 ifindex = 0;
564 }
565
566 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
567 api.distance = stream_getc (s);
568 else
569 api.distance = 0;
570
571 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
572 api.metric = stream_getl (s);
573 else
574 api.metric = 0;
575
576 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
577 api.tag = stream_getw (s);
578 else
579 api.tag = 0;
580
581 /* Simply ignore link-local address. */
582 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
583 return 0;
584
585 if (command == ZEBRA_IPV6_ROUTE_ADD)
586 {
587 if (bgp_debug_zebra((struct prefix *)&p))
588 {
589 char buf[2][INET6_ADDRSTRLEN];
590 zlog_debug("Zebra rcvd: IPv6 route add %s[%d] %s/%d nexthop %s metric %u tag %d",
591 zebra_route_string(api.type), api.instance,
592 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
593 p.prefixlen,
594 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
595 api.metric,
596 api.tag);
597 }
598 bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop, ifindex,
599 api.metric, api.type, api.instance, api.tag);
600 }
601 else
602 {
603 if (bgp_debug_zebra((struct prefix *)&p))
604 {
605 char buf[2][INET6_ADDRSTRLEN];
606 zlog_debug("Zebra rcvd: IPv6 route delete %s[%d] %s/%d "
607 "nexthop %s metric %u tag %d",
608 zebra_route_string(api.type), api.instance,
609 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
610 p.prefixlen,
611 inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
612 api.metric,
613 api.tag);
614 }
615 bgp_redistribute_delete ((struct prefix *) &p, api.type, api.instance);
616 }
617
618 return 0;
619 }
620 #endif /* HAVE_IPV6 */
621
622 struct interface *
623 if_lookup_by_ipv4 (struct in_addr *addr)
624 {
625 struct listnode *ifnode;
626 struct listnode *cnode;
627 struct interface *ifp;
628 struct connected *connected;
629 struct prefix_ipv4 p;
630 struct prefix *cp;
631
632 p.family = AF_INET;
633 p.prefix = *addr;
634 p.prefixlen = IPV4_MAX_BITLEN;
635
636 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
637 {
638 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
639 {
640 cp = connected->address;
641
642 if (cp->family == AF_INET)
643 if (prefix_match (cp, (struct prefix *)&p))
644 return ifp;
645 }
646 }
647 return NULL;
648 }
649
650 struct interface *
651 if_lookup_by_ipv4_exact (struct in_addr *addr)
652 {
653 struct listnode *ifnode;
654 struct listnode *cnode;
655 struct interface *ifp;
656 struct connected *connected;
657 struct prefix *cp;
658
659 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
660 {
661 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
662 {
663 cp = connected->address;
664
665 if (cp->family == AF_INET)
666 if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
667 return ifp;
668 }
669 }
670 return NULL;
671 }
672
673 #ifdef HAVE_IPV6
674 struct interface *
675 if_lookup_by_ipv6 (struct in6_addr *addr, unsigned int ifindex)
676 {
677 struct listnode *ifnode;
678 struct listnode *cnode;
679 struct interface *ifp;
680 struct connected *connected;
681 struct prefix_ipv6 p;
682 struct prefix *cp;
683
684 p.family = AF_INET6;
685 p.prefix = *addr;
686 p.prefixlen = IPV6_MAX_BITLEN;
687
688 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
689 {
690 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
691 {
692 cp = connected->address;
693
694 if (cp->family == AF_INET6)
695 if (prefix_match (cp, (struct prefix *)&p))
696 {
697 if (IN6_IS_ADDR_LINKLOCAL(&cp->u.prefix6.s6_addr32[0]))
698 {
699 if (ifindex == ifp->ifindex)
700 return ifp;
701 }
702 else
703 return ifp;
704 }
705 }
706 }
707 return NULL;
708 }
709
710 struct interface *
711 if_lookup_by_ipv6_exact (struct in6_addr *addr, unsigned int ifindex)
712 {
713 struct listnode *ifnode;
714 struct listnode *cnode;
715 struct interface *ifp;
716 struct connected *connected;
717 struct prefix *cp;
718
719 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
720 {
721 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
722 {
723 cp = connected->address;
724
725 if (cp->family == AF_INET6)
726 if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
727 {
728 if (IN6_IS_ADDR_LINKLOCAL(&cp->u.prefix6))
729 {
730 if (ifindex == ifp->ifindex)
731 return ifp;
732 }
733 else
734 return ifp;
735 }
736 }
737 }
738 return NULL;
739 }
740
741 static int
742 if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
743 {
744 struct listnode *cnode;
745 struct connected *connected;
746 struct prefix *cp;
747
748 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
749 {
750 cp = connected->address;
751
752 if (cp->family == AF_INET6)
753 if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
754 {
755 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
756 return 1;
757 }
758 }
759 return 0;
760 }
761
762 static int
763 if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
764 {
765 struct listnode *cnode;
766 struct connected *connected;
767 struct prefix *cp;
768
769 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
770 {
771 cp = connected->address;
772
773 if (cp->family == AF_INET6)
774 if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
775 {
776 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
777 return 1;
778 }
779 }
780 return 0;
781 }
782 #endif /* HAVE_IPV6 */
783
784 static int
785 if_get_ipv4_address (struct interface *ifp, struct in_addr *addr)
786 {
787 struct listnode *cnode;
788 struct connected *connected;
789 struct prefix *cp;
790
791 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
792 {
793 cp = connected->address;
794 if ((cp->family == AF_INET) && !ipv4_martian(&(cp->u.prefix4)))
795 {
796 *addr = cp->u.prefix4;
797 return 1;
798 }
799 }
800 return 0;
801 }
802
803 int
804 bgp_nexthop_set (union sockunion *local, union sockunion *remote,
805 struct bgp_nexthop *nexthop, struct peer *peer)
806 {
807 int ret = 0;
808 struct interface *ifp = NULL;
809
810 memset (nexthop, 0, sizeof (struct bgp_nexthop));
811
812 if (!local)
813 return -1;
814 if (!remote)
815 return -1;
816
817 if (local->sa.sa_family == AF_INET)
818 {
819 nexthop->v4 = local->sin.sin_addr;
820 if (peer->update_if)
821 ifp = if_lookup_by_name (peer->update_if);
822 else
823 ifp = if_lookup_by_ipv4_exact (&local->sin.sin_addr);
824 }
825 #ifdef HAVE_IPV6
826 if (local->sa.sa_family == AF_INET6)
827 {
828 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
829 {
830 if (peer->conf_if || peer->ifname)
831 ifp = if_lookup_by_index (if_nametoindex (peer->conf_if ? peer->conf_if : peer->ifname));
832 }
833 else if (peer->update_if)
834 ifp = if_lookup_by_name (peer->update_if);
835 else
836 ifp = if_lookup_by_ipv6_exact (&local->sin6.sin6_addr,
837 local->sin6.sin6_scope_id);
838 }
839 #endif /* HAVE_IPV6 */
840
841 if (!ifp)
842 return -1;
843
844 nexthop->ifp = ifp;
845
846 /* IPv4 connection. */
847 if (local->sa.sa_family == AF_INET)
848 {
849 #ifdef HAVE_IPV6
850 /* IPv6 nexthop*/
851 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
852
853 /* There is no global nexthop. */
854 if (!ret)
855 if_get_ipv6_local (ifp, &nexthop->v6_global);
856 else
857 if_get_ipv6_local (ifp, &nexthop->v6_local);
858 #endif /* HAVE_IPV6 */
859 }
860
861 #ifdef HAVE_IPV6
862 /* IPv6 connection. */
863 if (local->sa.sa_family == AF_INET6)
864 {
865 struct interface *direct = NULL;
866
867 /* IPv4 nexthop. */
868 ret = if_get_ipv4_address(ifp, &nexthop->v4);
869 if (!ret && peer->local_id.s_addr)
870 nexthop->v4 = peer->local_id;
871
872 /* Global address*/
873 if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
874 {
875 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
876 IPV6_MAX_BYTELEN);
877
878 /* If directory connected set link-local address. */
879 direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr,
880 remote->sin6.sin6_scope_id);
881 if (direct)
882 if_get_ipv6_local (ifp, &nexthop->v6_local);
883 }
884 else
885 /* Link-local address. */
886 {
887 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
888
889 /* If there is no global address. Set link-local address as
890 global. I know this break RFC specification... */
891 /* In this scenario, the expectation for interop is that the
892 * network admin would use a route-map to specify the global
893 * IPv6 nexthop.
894 */
895 if (!ret)
896 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
897 IPV6_MAX_BYTELEN);
898 /* Always set the link-local address */
899 memcpy (&nexthop->v6_local, &local->sin6.sin6_addr,
900 IPV6_MAX_BYTELEN);
901 }
902 }
903
904 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
905 if_lookup_by_ipv6 (&remote->sin6.sin6_addr, remote->sin6.sin6_scope_id))
906 peer->shared_network = 1;
907 else
908 peer->shared_network = 0;
909
910 /* KAME stack specific treatment. */
911 #ifdef KAME
912 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
913 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
914 {
915 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
916 }
917 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
918 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
919 {
920 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
921 }
922 #endif /* KAME */
923 #endif /* HAVE_IPV6 */
924 return ret;
925 }
926
927 static struct in6_addr *
928 bgp_info_to_ipv6_nexthop (struct bgp_info *info)
929 {
930 struct in6_addr *nexthop = NULL;
931
932 /* Only global address nexthop exists. */
933 if (info->attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL)
934 nexthop = &info->attr->extra->mp_nexthop_global;
935
936 /* If both global and link-local address present. */
937 if (info->attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
938 {
939 /* Workaround for Cisco's nexthop bug. */
940 if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
941 && info->peer->su_remote->sa.sa_family == AF_INET6)
942 nexthop = &info->peer->su_remote->sin6.sin6_addr;
943 else
944 nexthop = &info->attr->extra->mp_nexthop_local;
945 }
946
947 return nexthop;
948 }
949
950 static int
951 bgp_table_map_apply (struct route_map *map, struct prefix *p,
952 struct bgp_info *info)
953 {
954 if (route_map_apply(map, p, RMAP_BGP, info) != RMAP_DENYMATCH)
955 return 1;
956
957 if (bgp_debug_zebra(p))
958 {
959 if (p->family == AF_INET)
960 {
961 char buf[2][INET_ADDRSTRLEN];
962 zlog_debug("Zebra rmap deny: IPv4 route %s/%d nexthop %s",
963 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
964 p->prefixlen,
965 inet_ntop(AF_INET, &info->attr->nexthop, buf[1],
966 sizeof(buf[1])));
967 }
968 if (p->family == AF_INET6)
969 {
970 char buf[2][INET6_ADDRSTRLEN];
971 zlog_debug("Zebra rmap deny: IPv6 route %s/%d nexthop %s",
972 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
973 p->prefixlen,
974 inet_ntop(AF_INET6, bgp_info_to_ipv6_nexthop(info), buf[1],
975 sizeof(buf[1])));
976 }
977 }
978 return 0;
979 }
980
981 void
982 bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
983 afi_t afi, safi_t safi)
984 {
985 int flags;
986 u_char distance;
987 struct peer *peer;
988 struct bgp_info *mpinfo;
989 size_t oldsize, newsize;
990 u_int32_t nhcount, metric;
991 struct bgp_info local_info;
992 struct bgp_info *info_cp = &local_info;
993 u_short tag;
994
995 if (zclient->sock < 0)
996 return;
997
998 if ((p->family == AF_INET && !zclient->redist[AFI_IP][ZEBRA_ROUTE_BGP].enabled)
999 || (p->family == AF_INET6 && !zclient->redist[AFI_IP6][ZEBRA_ROUTE_BGP].enabled))
1000 return;
1001
1002 if (bgp->main_zebra_update_hold)
1003 return;
1004
1005 flags = 0;
1006 peer = info->peer;
1007
1008 if ((info->attr->extra) && (info->attr->extra->tag != 0))
1009 tag = info->attr->extra->tag;
1010 else
1011 tag = 0;
1012
1013 /* When we create an aggregate route we must also install a Null0 route in
1014 * the RIB */
1015 if (info->sub_type == BGP_ROUTE_AGGREGATE)
1016 SET_FLAG (flags, ZEBRA_FLAG_BLACKHOLE);
1017
1018 if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED ||
1019 info->sub_type == BGP_ROUTE_AGGREGATE)
1020 {
1021 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
1022 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
1023 }
1024
1025 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
1026 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
1027 || bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
1028
1029 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
1030
1031 nhcount = 1 + bgp_info_mpath_count (info);
1032
1033 if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(info->attr))
1034 {
1035 struct zapi_ipv4 api;
1036 struct in_addr *nexthop;
1037 char buf[2][INET_ADDRSTRLEN];
1038 int valid_nh_count = 0;
1039
1040 /* resize nexthop buffer size if necessary */
1041 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
1042 (sizeof (struct in_addr *) * nhcount))
1043 {
1044 newsize = (sizeof (struct in_addr *) * nhcount);
1045 newsize = stream_resize (bgp_nexthop_buf, newsize);
1046 if (newsize == oldsize)
1047 {
1048 zlog_err ("can't resize nexthop buffer");
1049 return;
1050 }
1051 }
1052 stream_reset (bgp_nexthop_buf);
1053 nexthop = NULL;
1054
1055 /* Metric is currently based on the best-path only. */
1056 metric = info->attr->med;
1057
1058 if (bgp->table_map[afi][safi].name)
1059 {
1060 BGP_INFO_ATTR_BUF_INIT();
1061
1062 /* Copy info and attributes, so the route-map apply doesn't modify the
1063 BGP route info. */
1064 BGP_INFO_ATTR_BUF_COPY(info, info_cp);
1065 if (bgp_table_map_apply(bgp->table_map[afi][safi].map, p, info_cp))
1066 {
1067 metric = info_cp->attr->med;
1068 nexthop = &info_cp->attr->nexthop;
1069
1070 if (info_cp->attr->extra)
1071 tag = info_cp->attr->extra->tag;
1072 }
1073 BGP_INFO_ATTR_BUF_FREE(info_cp);
1074 }
1075 else
1076 {
1077 nexthop = &info->attr->nexthop;
1078 }
1079
1080 if (nexthop)
1081 {
1082 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
1083 valid_nh_count++;
1084 }
1085
1086 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
1087 mpinfo = bgp_info_mpath_next (mpinfo))
1088 {
1089 nexthop = NULL;
1090
1091 if (bgp->table_map[afi][safi].name)
1092 {
1093 /* Copy info and attributes, so the route-map apply doesn't modify the
1094 BGP route info. */
1095 BGP_INFO_ATTR_BUF_COPY(mpinfo, info_cp);
1096 if (bgp_table_map_apply(bgp->table_map[afi][safi].map, p, info_cp))
1097 nexthop = &info_cp->attr->nexthop;
1098 BGP_INFO_ATTR_BUF_FREE(info_cp);
1099 }
1100 else
1101 {
1102 nexthop = &mpinfo->attr->nexthop;
1103 }
1104
1105 if (nexthop == NULL)
1106 continue;
1107
1108 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
1109 valid_nh_count++;
1110 }
1111
1112 api.flags = flags;
1113 api.type = ZEBRA_ROUTE_BGP;
1114 api.instance = 0;
1115 api.message = 0;
1116 api.safi = safi;
1117 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
1118
1119 /* Note that this currently only applies to Null0 routes for aggregates.
1120 * ZEBRA_FLAG_BLACKHOLE signals zapi_ipv4_route to encode a special
1121 * BLACKHOLE nexthop. We want to set api.nexthop_num to zero since we
1122 * do not want to also encode the 0.0.0.0 nexthop for the aggregate route.
1123 */
1124 if (CHECK_FLAG(flags, ZEBRA_FLAG_BLACKHOLE))
1125 api.nexthop_num = 0;
1126 else
1127 api.nexthop_num = valid_nh_count;
1128
1129 api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
1130 api.ifindex_num = 0;
1131 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
1132 api.metric = metric;
1133
1134 if (tag)
1135 {
1136 SET_FLAG (api.message, ZAPI_MESSAGE_TAG);
1137 api.tag = tag;
1138 }
1139
1140 distance = bgp_distance_apply (p, info, bgp);
1141
1142 if (distance)
1143 {
1144 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
1145 api.distance = distance;
1146 }
1147
1148 if (bgp_debug_zebra(p))
1149 {
1150 int i;
1151 zlog_debug("Zebra send: IPv4 route %s %s/%d metric %u tag %d"
1152 " count %d", (valid_nh_count ? "add":"delete"),
1153 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
1154 p->prefixlen, api.metric, api.tag, api.nexthop_num);
1155 for (i = 0; i < api.nexthop_num; i++)
1156 zlog_debug(" IPv4 [nexthop %d] %s", i+1,
1157 inet_ntop(AF_INET, api.nexthop[i], buf[1], sizeof(buf[1])));
1158 }
1159
1160 zapi_ipv4_route (valid_nh_count ? ZEBRA_IPV4_ROUTE_ADD: ZEBRA_IPV4_ROUTE_DELETE,
1161 zclient, (struct prefix_ipv4 *) p, &api);
1162 }
1163 #ifdef HAVE_IPV6
1164
1165 /* We have to think about a IPv6 link-local address curse. */
1166 if (p->family == AF_INET6 ||
1167 (p->family == AF_INET && BGP_ATTR_NEXTHOP_AFI_IP6(info->attr)))
1168 {
1169 unsigned int ifindex;
1170 struct in6_addr *nexthop;
1171 struct zapi_ipv6 api;
1172 int valid_nh_count = 0;
1173 char buf[2][INET6_ADDRSTRLEN];
1174
1175 /* resize nexthop buffer size if necessary */
1176 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
1177 (sizeof (struct in6_addr *) * nhcount))
1178 {
1179 newsize = (sizeof (struct in6_addr *) * nhcount);
1180 newsize = stream_resize (bgp_nexthop_buf, newsize);
1181 if (newsize == oldsize)
1182 {
1183 zlog_err ("can't resize nexthop buffer");
1184 return;
1185 }
1186 }
1187 stream_reset (bgp_nexthop_buf);
1188
1189 /* resize ifindices buffer size if necessary */
1190 if ((oldsize = stream_get_size (bgp_ifindices_buf)) <
1191 (sizeof (unsigned int) * nhcount))
1192 {
1193 newsize = (sizeof (unsigned int) * nhcount);
1194 newsize = stream_resize (bgp_ifindices_buf, newsize);
1195 if (newsize == oldsize)
1196 {
1197 zlog_err ("can't resize nexthop buffer");
1198 return;
1199 }
1200 }
1201 stream_reset (bgp_ifindices_buf);
1202
1203 ifindex = 0;
1204 nexthop = NULL;
1205
1206 assert (info->attr->extra);
1207
1208 /* Metric is currently based on the best-path only. */
1209 metric = info->attr->med;
1210
1211 if (bgp->table_map[afi][safi].name)
1212 {
1213 BGP_INFO_ATTR_BUF_INIT();
1214
1215 /* Copy info and attributes, so the route-map apply doesn't modify the
1216 BGP route info. */
1217 BGP_INFO_ATTR_BUF_COPY(info, info_cp);
1218 if (bgp_table_map_apply(bgp->table_map[afi][safi].map, p, info_cp))
1219 {
1220 metric = info_cp->attr->med;
1221 nexthop = bgp_info_to_ipv6_nexthop(info_cp);
1222
1223 if (info_cp->attr->extra)
1224 tag = info_cp->attr->extra->tag;
1225 }
1226 BGP_INFO_ATTR_BUF_FREE(info_cp);
1227 }
1228 else
1229 {
1230 nexthop = bgp_info_to_ipv6_nexthop(info);
1231 }
1232
1233 if (nexthop)
1234 {
1235 if (info->attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
1236 if (info->peer->nexthop.ifp)
1237 ifindex = info->peer->nexthop.ifp->ifindex;
1238
1239 if (!ifindex)
1240 {
1241 if (info->peer->conf_if || info->peer->ifname)
1242 ifindex = if_nametoindex (info->peer->conf_if ? info->peer->conf_if : info->peer->ifname);
1243 else if (info->peer->nexthop.ifp)
1244 ifindex = info->peer->nexthop.ifp->ifindex;
1245 }
1246 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
1247 stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int));
1248 valid_nh_count++;
1249 }
1250
1251 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
1252 mpinfo = bgp_info_mpath_next (mpinfo))
1253 {
1254 ifindex = 0;
1255 nexthop = NULL;
1256
1257 if (bgp->table_map[afi][safi].name)
1258 {
1259 /* Copy info and attributes, so the route-map apply doesn't modify the
1260 BGP route info. */
1261 BGP_INFO_ATTR_BUF_COPY(mpinfo, info_cp);
1262 if (bgp_table_map_apply(bgp->table_map[afi][safi].map, p, info_cp))
1263 nexthop = bgp_info_to_ipv6_nexthop(info_cp);
1264 BGP_INFO_ATTR_BUF_FREE(info_cp);
1265 }
1266 else
1267 {
1268 nexthop = bgp_info_to_ipv6_nexthop(mpinfo);
1269 }
1270
1271 if (nexthop == NULL)
1272 continue;
1273
1274 if (mpinfo->attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
1275 if (mpinfo->peer->nexthop.ifp)
1276 ifindex = mpinfo->peer->nexthop.ifp->ifindex;
1277
1278 if (!ifindex)
1279 {
1280 if (mpinfo->peer->conf_if || mpinfo->peer->ifname)
1281 ifindex = if_nametoindex (mpinfo->peer->conf_if ? mpinfo->peer->conf_if : mpinfo->peer->ifname);
1282 else if (mpinfo->peer->nexthop.ifp)
1283 ifindex = mpinfo->peer->nexthop.ifp->ifindex;
1284 }
1285 if (ifindex == 0)
1286 continue;
1287
1288 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
1289 stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int));
1290 valid_nh_count++;
1291 }
1292
1293 /* Make Zebra API structure. */
1294 api.flags = flags;
1295 api.type = ZEBRA_ROUTE_BGP;
1296 api.instance = 0;
1297 api.message = 0;
1298 api.safi = safi;
1299 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
1300
1301 /* Note that this currently only applies to Null0 routes for aggregates.
1302 * ZEBRA_FLAG_BLACKHOLE signals zapi_ipv6_route to encode a special
1303 * BLACKHOLE nexthop. We want to set api.nexthop_num to zero since we
1304 * do not want to also encode the :: nexthop for the aggregate route.
1305 */
1306 if (CHECK_FLAG(flags, ZEBRA_FLAG_BLACKHOLE))
1307 api.nexthop_num = 0;
1308 else
1309 api.nexthop_num = valid_nh_count;
1310
1311 api.nexthop = (struct in6_addr **)STREAM_DATA (bgp_nexthop_buf);
1312 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
1313 api.ifindex_num = valid_nh_count;
1314 api.ifindex = (unsigned int *)STREAM_DATA (bgp_ifindices_buf);
1315 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
1316 api.metric = metric;
1317
1318 if (tag)
1319 {
1320 SET_FLAG (api.message, ZAPI_MESSAGE_TAG);
1321 api.tag = tag;
1322 }
1323
1324 if (p->family == AF_INET)
1325 {
1326 if (bgp_debug_zebra(p))
1327 {
1328 int i;
1329 zlog_debug("Zebra send: IPv4 route %s %s/%d metric %u tag %d",
1330 valid_nh_count ? "add" : "delete",
1331 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
1332 p->prefixlen, api.metric, api.tag);
1333 for (i = 0; i < api.nexthop_num; i++)
1334 zlog_debug(" IPv6 [nexthop %d] %s", i+1,
1335 inet_ntop(AF_INET6, api.nexthop[i], buf[1], sizeof(buf[1])));
1336 }
1337
1338 if (valid_nh_count)
1339 zapi_ipv4_route_ipv6_nexthop (ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD,
1340 zclient, (struct prefix_ipv4 *) p,
1341 (struct zapi_ipv6 *)&api);
1342 else
1343 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE,
1344 zclient, (struct prefix_ipv4 *) p, (struct zapi_ipv4 *)&api);
1345 }
1346 else
1347 {
1348 if (bgp_debug_zebra(p))
1349 {
1350 int i;
1351 zlog_debug("Zebra send: IPv6 route %s %s/%d metric %u tag %d",
1352 valid_nh_count ? "add" : "delete",
1353 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
1354 p->prefixlen, api.metric, api.tag);
1355 for (i = 0; i < api.nexthop_num; i++)
1356 zlog_debug(" IPv6 [nexthop %d] %s", i+1,
1357 inet_ntop(AF_INET6, api.nexthop[i], buf[1], sizeof(buf[1])));
1358 }
1359
1360 zapi_ipv6_route (valid_nh_count ?
1361 ZEBRA_IPV6_ROUTE_ADD : ZEBRA_IPV6_ROUTE_DELETE,
1362 zclient, (struct prefix_ipv6 *) p, &api);
1363 }
1364 }
1365 #endif /* HAVE_IPV6 */
1366 }
1367
1368 /* Announce all routes of a table to zebra */
1369 void
1370 bgp_zebra_announce_table (struct bgp *bgp, afi_t afi, safi_t safi)
1371 {
1372 struct bgp_node *rn;
1373 struct bgp_table *table;
1374 struct bgp_info *ri;
1375
1376 table = bgp->rib[afi][safi];
1377 if (!table) return;
1378
1379 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
1380 for (ri = rn->info; ri; ri = ri->next)
1381 if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)
1382 && ri->type == ZEBRA_ROUTE_BGP
1383 && ri->sub_type == BGP_ROUTE_NORMAL)
1384 bgp_zebra_announce (&rn->p, ri, bgp, afi, safi);
1385 }
1386
1387 void
1388 bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
1389 {
1390 int flags;
1391 struct peer *peer;
1392
1393 if (zclient->sock < 0)
1394 return;
1395
1396 if ((p->family == AF_INET && !zclient->redist[AFI_IP][ZEBRA_ROUTE_BGP].enabled)
1397 || (p->family == AF_INET6 && !zclient->redist[AFI_IP6][ZEBRA_ROUTE_BGP].enabled))
1398 return;
1399
1400 peer = info->peer;
1401
1402 flags = 0;
1403
1404 if (peer->sort == BGP_PEER_IBGP)
1405 {
1406 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
1407 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
1408 }
1409
1410 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
1411 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
1412 || bgp_flag_check(peer->bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
1413 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
1414
1415 if (p->family == AF_INET)
1416 {
1417 struct zapi_ipv4 api;
1418
1419 api.flags = flags;
1420
1421 api.type = ZEBRA_ROUTE_BGP;
1422 api.instance = 0;
1423 api.message = 0;
1424 api.safi = safi;
1425 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
1426 api.nexthop_num = 0;
1427 api.nexthop = NULL;
1428 api.ifindex_num = 0;
1429 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
1430 api.metric = info->attr->med;
1431
1432 if ((info->attr->extra) && (info->attr->extra->tag != 0))
1433 {
1434 SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
1435 api.tag = info->attr->extra->tag;
1436 }
1437
1438 if (bgp_debug_zebra(p))
1439 {
1440 char buf[2][INET_ADDRSTRLEN];
1441 zlog_debug("Zebra send: IPv4 route delete %s/%d metric %u tag %d",
1442 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
1443 p->prefixlen, api.metric, api.tag);
1444 }
1445
1446 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
1447 (struct prefix_ipv4 *) p, &api);
1448 }
1449 #ifdef HAVE_IPV6
1450 /* We have to think about a IPv6 link-local address curse. */
1451 if (p->family == AF_INET6)
1452 {
1453 struct zapi_ipv6 api;
1454
1455 assert (info->attr->extra);
1456
1457 api.flags = flags;
1458 api.type = ZEBRA_ROUTE_BGP;
1459 api.instance = 0;
1460 api.message = 0;
1461 api.safi = safi;
1462 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
1463 api.nexthop_num = 0;
1464 api.nexthop = NULL;
1465 api.ifindex_num = 0;
1466 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
1467 api.metric = info->attr->med;
1468
1469 if ((info->attr->extra) && (info->attr->extra->tag != 0))
1470 {
1471 SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
1472 api.tag = info->attr->extra->tag;
1473 }
1474
1475 if (bgp_debug_zebra(p))
1476 {
1477 char buf[2][INET6_ADDRSTRLEN];
1478 zlog_debug("Zebra send: IPv6 route delete %s/%d metric %u tag %d",
1479 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
1480 p->prefixlen, api.metric, api.tag);
1481 }
1482
1483 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
1484 (struct prefix_ipv6 *) p, &api);
1485 }
1486 #endif /* HAVE_IPV6 */
1487 }
1488 struct bgp_redist *
1489 bgp_redist_lookup (struct bgp *bgp, afi_t afi, u_char type, u_short instance)
1490 {
1491 struct list *red_list;
1492 struct listnode *node;
1493 struct bgp_redist *red;
1494
1495 red_list = bgp->redist[afi][type];
1496 if (!red_list)
1497 return(NULL);
1498
1499 for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
1500 if (red->instance == instance)
1501 return red;
1502
1503 return NULL;
1504 }
1505
1506 struct bgp_redist *
1507 bgp_redist_add (struct bgp *bgp, afi_t afi, u_char type, u_short instance)
1508 {
1509 struct list *red_list;
1510 struct bgp_redist *red;
1511
1512 red = bgp_redist_lookup(bgp, afi, type, instance);
1513 if (red)
1514 return red;
1515
1516 if (!bgp->redist[afi][type])
1517 bgp->redist[afi][type] = list_new();
1518
1519 red_list = bgp->redist[afi][type];
1520 red = (struct bgp_redist *)XCALLOC(MTYPE_BGP_REDIST, sizeof(struct bgp_redist));
1521 red->instance = instance;
1522
1523 listnode_add(red_list, red);
1524
1525 return red;
1526 }
1527
1528 static void
1529 bgp_redist_del (struct bgp *bgp, afi_t afi, u_char type, u_short instance)
1530 {
1531 struct bgp_redist *red;
1532
1533 red = bgp_redist_lookup(bgp, afi, type, instance);
1534
1535 if (red)
1536 {
1537 listnode_delete(bgp->redist[afi][type], red);
1538 if (!bgp->redist[afi][type]->count)
1539 {
1540 list_free(bgp->redist[afi][type]);
1541 bgp->redist[afi][type] = NULL;
1542 }
1543 }
1544 }
1545
1546 /* Other routes redistribution into BGP. */
1547 int
1548 bgp_redistribute_set (afi_t afi, int type, u_short instance)
1549 {
1550
1551 /* Return if already redistribute flag is set. */
1552 if (redist_check_instance(&zclient->redist[afi][type], instance))
1553 return CMD_WARNING;
1554
1555 redist_add_instance(&zclient->redist[afi][type], instance);
1556
1557 /* Return if zebra connection is not established. */
1558 if (zclient->sock < 0)
1559 return CMD_WARNING;
1560
1561 if (BGP_DEBUG (zebra, ZEBRA))
1562 zlog_debug("Zebra send: redistribute add afi %d %s %d", afi,
1563 zebra_route_string(type), instance);
1564
1565 /* Send distribute add message to zebra. */
1566 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, instance);
1567
1568 return CMD_SUCCESS;
1569 }
1570
1571 int
1572 bgp_redistribute_resend (struct bgp *bgp, afi_t afi, int type, u_short instance)
1573 {
1574 /* Return if zebra connection is not established. */
1575 if (zclient->sock < 0)
1576 return -1;
1577
1578 if (BGP_DEBUG (zebra, ZEBRA))
1579 zlog_debug("Zebra send: redistribute delete/add afi %d %s %d", afi,
1580 zebra_route_string(type), instance);
1581
1582 /* Send distribute add message to zebra. */
1583 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, instance);
1584 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, instance);
1585
1586 return 0;
1587 }
1588
1589 /* Redistribute with route-map specification. */
1590 int
1591 bgp_redistribute_rmap_set (struct bgp_redist *red, const char *name)
1592 {
1593 if (red->rmap.name
1594 && (strcmp (red->rmap.name, name) == 0))
1595 return 0;
1596
1597 if (red->rmap.name)
1598 XFREE(MTYPE_ROUTE_MAP_NAME, red->rmap.name);
1599 red->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, name);
1600 red->rmap.map = route_map_lookup_by_name (name);
1601
1602 return 1;
1603 }
1604
1605 /* Redistribute with metric specification. */
1606 int
1607 bgp_redistribute_metric_set (struct bgp *bgp, struct bgp_redist *red, afi_t afi,
1608 int type, u_int32_t metric)
1609 {
1610 struct bgp_node *rn;
1611 struct bgp_info *ri;
1612
1613 if (red->redist_metric_flag
1614 && red->redist_metric == metric)
1615 return 0;
1616
1617 red->redist_metric_flag = 1;
1618 red->redist_metric = metric;
1619
1620 for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn; rn = bgp_route_next(rn)) {
1621 for (ri = rn->info; ri; ri = ri->next) {
1622 if (ri->sub_type == BGP_ROUTE_REDISTRIBUTE && ri->type == type) {
1623 ri->attr->med = red->redist_metric;
1624 bgp_info_set_flag(rn, ri, BGP_INFO_ATTR_CHANGED);
1625 bgp_process(bgp, rn, afi, SAFI_UNICAST);
1626 }
1627 }
1628 }
1629
1630 return 1;
1631 }
1632
1633 /* Unset redistribution. */
1634 int
1635 bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type, u_short instance)
1636 {
1637 struct bgp_redist *red;
1638
1639 red = bgp_redist_lookup(bgp, afi, type, instance);
1640 if (!red)
1641 return CMD_SUCCESS;
1642
1643 /* Unset route-map. */
1644 if (red->rmap.name)
1645 XFREE(MTYPE_ROUTE_MAP_NAME, red->rmap.name);
1646 red->rmap.name = NULL;
1647 red->rmap.map = NULL;
1648
1649 /* Unset metric. */
1650 red->redist_metric_flag = 0;
1651 red->redist_metric = 0;
1652
1653 bgp_redist_del(bgp, afi, type, instance);
1654
1655 /* Return if zebra connection is disabled. */
1656 if (!redist_check_instance(&zclient->redist[afi][type], instance))
1657 return CMD_WARNING;
1658 redist_del_instance(&zclient->redist[afi][type], instance);
1659
1660 if (zclient->sock >= 0)
1661 {
1662 /* Send distribute delete message to zebra. */
1663 if (BGP_DEBUG (zebra, ZEBRA))
1664 zlog_debug("Zebra send: redistribute delete afi %d %s %d",
1665 afi, zebra_route_string(type), instance);
1666 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, instance);
1667 }
1668
1669 /* Withdraw redistributed routes from current BGP's routing table. */
1670 bgp_redistribute_withdraw (bgp, afi, type, instance);
1671
1672 return CMD_SUCCESS;
1673 }
1674
1675 void
1676 bgp_zclient_reset (void)
1677 {
1678 zclient_reset (zclient);
1679 }
1680
1681 void
1682 bgp_zebra_init (void)
1683 {
1684 /* Set default values. */
1685 zclient = zclient_new ();
1686 zclient_init (zclient, ZEBRA_ROUTE_BGP, 0);
1687 zclient->router_id_update = bgp_router_id_update;
1688 zclient->interface_add = bgp_interface_add;
1689 zclient->interface_delete = bgp_interface_delete;
1690 zclient->interface_address_add = bgp_interface_address_add;
1691 zclient->interface_address_delete = bgp_interface_address_delete;
1692 zclient->interface_nbr_address_add = bgp_interface_nbr_address_add;
1693 zclient->interface_nbr_address_delete = bgp_interface_nbr_address_delete;
1694 zclient->ipv4_route_add = zebra_read_ipv4;
1695 zclient->ipv4_route_delete = zebra_read_ipv4;
1696 zclient->interface_up = bgp_interface_up;
1697 zclient->interface_down = bgp_interface_down;
1698 #ifdef HAVE_IPV6
1699 zclient->ipv6_route_add = zebra_read_ipv6;
1700 zclient->ipv6_route_delete = zebra_read_ipv6;
1701 #endif /* HAVE_IPV6 */
1702 zclient->nexthop_update = bgp_read_nexthop_update;
1703 zclient->import_check_update = bgp_read_import_check_update;
1704
1705 /* Interface related init. */
1706 if_init ();
1707
1708 bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
1709 bgp_ifindices_buf = stream_new(BGP_IFINDICES_BUF_SIZE);
1710 }