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