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