blob: 6c21230a041a1a1a2d8d86943a647df089a21b51 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* 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"
Andrew J. Schorra39275d2006-11-30 16:36:57 +000039#include "bgpd/bgp_debug.h"
Josh Bailey8196f132011-07-20 20:47:07 -070040#include "bgpd/bgp_mpath.h"
paul718e3742002-12-13 20:15:29 +000041
42/* All information about zebra. */
Chris Caputo228da422009-07-18 05:44:03 +000043struct zclient *zclient = NULL;
hasso18a6dce2004-10-03 18:18:34 +000044struct in_addr router_id_zebra;
paul718e3742002-12-13 20:15:29 +000045
Josh Bailey8196f132011-07-20 20:47:07 -070046/* Growable buffer for nexthops sent to zebra */
47struct stream *bgp_nexthop_buf = NULL;
48
hasso18a6dce2004-10-03 18:18:34 +000049/* Router-id update message from zebra. */
paul94f2b392005-06-28 12:44:16 +000050static int
hasso18a6dce2004-10-03 18:18:34 +000051bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length)
paul718e3742002-12-13 20:15:29 +000052{
hasso18a6dce2004-10-03 18:18:34 +000053 struct prefix router_id;
paul1eb8ef22005-04-07 07:30:20 +000054 struct listnode *node, *nnode;
hasso18a6dce2004-10-03 18:18:34 +000055 struct bgp *bgp;
paul718e3742002-12-13 20:15:29 +000056
hasso18a6dce2004-10-03 18:18:34 +000057 zebra_router_id_update_read(zclient->ibuf,&router_id);
Andrew J. Schorra39275d2006-11-30 16:36:57 +000058
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
hasso18a6dce2004-10-03 18:18:34 +000066 router_id_zebra = router_id.u.prefix4;
67
paul1eb8ef22005-04-07 07:30:20 +000068 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
paul718e3742002-12-13 20:15:29 +000069 {
hasso18a6dce2004-10-03 18:18:34 +000070 if (!bgp->router_id_static.s_addr)
paul1eb8ef22005-04-07 07:30:20 +000071 bgp_router_id_set (bgp, &router_id.u.prefix4);
paul718e3742002-12-13 20:15:29 +000072 }
paul718e3742002-12-13 20:15:29 +000073
paul718e3742002-12-13 20:15:29 +000074 return 0;
75}
76
77/* Inteface addition message from zebra. */
paul94f2b392005-06-28 12:44:16 +000078static int
paul718e3742002-12-13 20:15:29 +000079bgp_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);
paul718e3742002-12-13 20:15:29 +000084
Andrew J. Schorra39275d2006-11-30 16:36:57 +000085 if (BGP_DEBUG(zebra, ZEBRA) && ifp)
86 zlog_debug("Zebra rcvd: interface add %s", ifp->name);
87
paul718e3742002-12-13 20:15:29 +000088 return 0;
89}
90
paul94f2b392005-06-28 12:44:16 +000091static int
paul718e3742002-12-13 20:15:29 +000092bgp_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);
ajsd2fc8892005-04-02 18:38:43 +0000100 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000101
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000102 if (BGP_DEBUG(zebra, ZEBRA))
103 zlog_debug("Zebra rcvd: interface delete %s", ifp->name);
104
paul718e3742002-12-13 20:15:29 +0000105 return 0;
106}
107
paul94f2b392005-06-28 12:44:16 +0000108static int
paul718e3742002-12-13 20:15:29 +0000109bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length)
110{
111 struct stream *s;
112 struct interface *ifp;
113 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000114 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000115
116 s = zclient->ibuf;
117 ifp = zebra_interface_state_read (s);
118
119 if (! ifp)
120 return 0;
121
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000122 if (BGP_DEBUG(zebra, ZEBRA))
123 zlog_debug("Zebra rcvd: interface %s up", ifp->name);
124
paul1eb8ef22005-04-07 07:30:20 +0000125 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
126 bgp_connected_add (c);
paul718e3742002-12-13 20:15:29 +0000127
128 return 0;
129}
130
paul94f2b392005-06-28 12:44:16 +0000131static int
paul718e3742002-12-13 20:15:29 +0000132bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length)
133{
134 struct stream *s;
135 struct interface *ifp;
136 struct connected *c;
paul1eb8ef22005-04-07 07:30:20 +0000137 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000138
139 s = zclient->ibuf;
140 ifp = zebra_interface_state_read (s);
141 if (! ifp)
142 return 0;
143
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000144 if (BGP_DEBUG(zebra, ZEBRA))
145 zlog_debug("Zebra rcvd: interface %s down", ifp->name);
146
paul1eb8ef22005-04-07 07:30:20 +0000147 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
148 bgp_connected_delete (c);
paul718e3742002-12-13 20:15:29 +0000149
150 /* Fast external-failover (Currently IPv4 only) */
151 {
paul1eb8ef22005-04-07 07:30:20 +0000152 struct listnode *mnode;
paul718e3742002-12-13 20:15:29 +0000153 struct bgp *bgp;
154 struct peer *peer;
155 struct interface *peer_if;
156
paul1eb8ef22005-04-07 07:30:20 +0000157 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
paul718e3742002-12-13 20:15:29 +0000158 {
159 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
160 continue;
161
paul1eb8ef22005-04-07 07:30:20 +0000162 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +0000163 {
164 if (peer->ttl != 1)
165 continue;
166
167 if (peer->su.sa.sa_family == AF_INET)
168 peer_if = if_lookup_by_ipv4 (&peer->su.sin.sin_addr);
169 else
170 continue;
171
172 if (ifp == peer_if)
173 BGP_EVENT_ADD (peer, BGP_Stop);
174 }
175 }
176 }
177
178 return 0;
179}
180
paul94f2b392005-06-28 12:44:16 +0000181static int
paul718e3742002-12-13 20:15:29 +0000182bgp_interface_address_add (int command, struct zclient *zclient,
183 zebra_size_t length)
184{
185 struct connected *ifc;
186
paul0a589352004-05-08 11:48:26 +0000187 ifc = zebra_interface_address_read (command, zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000188
189 if (ifc == NULL)
190 return 0;
191
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000192 if (BGP_DEBUG(zebra, ZEBRA))
193 {
194 char buf[128];
195 prefix2str(ifc->address, buf, sizeof(buf));
196 zlog_debug("Zebra rcvd: interface %s address add %s",
197 ifc->ifp->name, buf);
198 }
199
paul2e3b2e42002-12-13 21:03:13 +0000200 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000201 bgp_connected_add (ifc);
202
203 return 0;
204}
205
paul94f2b392005-06-28 12:44:16 +0000206static int
paul718e3742002-12-13 20:15:29 +0000207bgp_interface_address_delete (int command, struct zclient *zclient,
208 zebra_size_t length)
209{
210 struct connected *ifc;
211
paul0a589352004-05-08 11:48:26 +0000212 ifc = zebra_interface_address_read (command, zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000213
214 if (ifc == NULL)
215 return 0;
216
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000217 if (BGP_DEBUG(zebra, ZEBRA))
218 {
219 char buf[128];
220 prefix2str(ifc->address, buf, sizeof(buf));
221 zlog_debug("Zebra rcvd: interface %s address delete %s",
222 ifc->ifp->name, buf);
223 }
224
paul2e3b2e42002-12-13 21:03:13 +0000225 if (if_is_operative (ifc->ifp))
paul718e3742002-12-13 20:15:29 +0000226 bgp_connected_delete (ifc);
227
228 connected_free (ifc);
229
230 return 0;
231}
232
233/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000234static int
paul718e3742002-12-13 20:15:29 +0000235zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
236{
237 struct stream *s;
238 struct zapi_ipv4 api;
239 unsigned long ifindex;
240 struct in_addr nexthop;
241 struct prefix_ipv4 p;
242
243 s = zclient->ibuf;
244 ifindex = 0;
245 nexthop.s_addr = 0;
246
247 /* Type, flags, message. */
248 api.type = stream_getc (s);
249 api.flags = stream_getc (s);
250 api.message = stream_getc (s);
251
252 /* IPv4 prefix. */
253 memset (&p, 0, sizeof (struct prefix_ipv4));
254 p.family = AF_INET;
255 p.prefixlen = stream_getc (s);
256 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
257
258 /* Nexthop, ifindex, distance, metric. */
259 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
260 {
261 api.nexthop_num = stream_getc (s);
262 nexthop.s_addr = stream_get_ipv4 (s);
263 }
264 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
265 {
266 api.ifindex_num = stream_getc (s);
267 ifindex = stream_getl (s);
268 }
269 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
270 api.distance = stream_getc (s);
271 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
272 api.metric = stream_getl (s);
273 else
274 api.metric = 0;
275
276 if (command == ZEBRA_IPV4_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000277 {
278 if (BGP_DEBUG(zebra, ZEBRA))
279 {
280 char buf[2][INET_ADDRSTRLEN];
281 zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
282 zebra_route_string(api.type),
283 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
284 p.prefixlen,
285 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
286 api.metric);
287 }
288 bgp_redistribute_add((struct prefix *)&p, &nexthop, api.metric, api.type);
289 }
paul718e3742002-12-13 20:15:29 +0000290 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000291 {
292 if (BGP_DEBUG(zebra, ZEBRA))
293 {
294 char buf[2][INET_ADDRSTRLEN];
295 zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
296 "nexthop %s metric %u",
297 zebra_route_string(api.type),
298 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
299 p.prefixlen,
300 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
301 api.metric);
302 }
303 bgp_redistribute_delete((struct prefix *)&p, api.type);
304 }
paul718e3742002-12-13 20:15:29 +0000305
306 return 0;
307}
308
309#ifdef HAVE_IPV6
310/* Zebra route add and delete treatment. */
paul94f2b392005-06-28 12:44:16 +0000311static int
paul718e3742002-12-13 20:15:29 +0000312zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
313{
314 struct stream *s;
315 struct zapi_ipv6 api;
316 unsigned long ifindex;
317 struct in6_addr nexthop;
318 struct prefix_ipv6 p;
319
320 s = zclient->ibuf;
321 ifindex = 0;
322 memset (&nexthop, 0, sizeof (struct in6_addr));
323
324 /* Type, flags, message. */
325 api.type = stream_getc (s);
326 api.flags = stream_getc (s);
327 api.message = stream_getc (s);
328
329 /* IPv6 prefix. */
330 memset (&p, 0, sizeof (struct prefix_ipv6));
331 p.family = AF_INET6;
332 p.prefixlen = stream_getc (s);
333 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
334
335 /* Nexthop, ifindex, distance, metric. */
336 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
337 {
338 api.nexthop_num = stream_getc (s);
339 stream_get (&nexthop, s, 16);
340 }
341 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
342 {
343 api.ifindex_num = stream_getc (s);
344 ifindex = stream_getl (s);
345 }
346 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
347 api.distance = stream_getc (s);
348 else
349 api.distance = 0;
350 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
351 api.metric = stream_getl (s);
352 else
353 api.metric = 0;
354
355 /* Simply ignore link-local address. */
356 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
357 return 0;
358
359 if (command == ZEBRA_IPV6_ROUTE_ADD)
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000360 {
361 if (BGP_DEBUG(zebra, ZEBRA))
362 {
363 char buf[INET6_ADDRSTRLEN];
364 zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d metric %u",
365 zebra_route_string(api.type),
366 inet_ntop(AF_INET6, &p.prefix, buf, sizeof(buf)),
367 p.prefixlen, api.metric);
368 }
369 bgp_redistribute_add ((struct prefix *)&p, NULL, api.metric, api.type);
370 }
paul718e3742002-12-13 20:15:29 +0000371 else
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000372 {
373 if (BGP_DEBUG(zebra, ZEBRA))
374 {
375 char buf[INET6_ADDRSTRLEN];
376 zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d metric %u",
377 zebra_route_string(api.type),
378 inet_ntop(AF_INET6, &p.prefix, buf, sizeof(buf)),
379 p.prefixlen, api.metric);
380 }
381 bgp_redistribute_delete ((struct prefix *) &p, api.type);
382 }
paul718e3742002-12-13 20:15:29 +0000383
384 return 0;
385}
386#endif /* HAVE_IPV6 */
387
388struct interface *
389if_lookup_by_ipv4 (struct in_addr *addr)
390{
hasso52dc7ee2004-09-23 19:18:23 +0000391 struct listnode *ifnode;
392 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000393 struct interface *ifp;
394 struct connected *connected;
395 struct prefix_ipv4 p;
396 struct prefix *cp;
397
398 p.family = AF_INET;
399 p.prefix = *addr;
400 p.prefixlen = IPV4_MAX_BITLEN;
401
paul1eb8ef22005-04-07 07:30:20 +0000402 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000403 {
paul1eb8ef22005-04-07 07:30:20 +0000404 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000405 {
paul718e3742002-12-13 20:15:29 +0000406 cp = connected->address;
407
408 if (cp->family == AF_INET)
409 if (prefix_match (cp, (struct prefix *)&p))
410 return ifp;
411 }
412 }
413 return NULL;
414}
415
416struct interface *
417if_lookup_by_ipv4_exact (struct in_addr *addr)
418{
hasso52dc7ee2004-09-23 19:18:23 +0000419 struct listnode *ifnode;
420 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000421 struct interface *ifp;
422 struct connected *connected;
423 struct prefix *cp;
424
paul1eb8ef22005-04-07 07:30:20 +0000425 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000426 {
paul1eb8ef22005-04-07 07:30:20 +0000427 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000428 {
paul718e3742002-12-13 20:15:29 +0000429 cp = connected->address;
430
431 if (cp->family == AF_INET)
432 if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
433 return ifp;
434 }
435 }
436 return NULL;
437}
438
439#ifdef HAVE_IPV6
440struct interface *
441if_lookup_by_ipv6 (struct in6_addr *addr)
442{
hasso52dc7ee2004-09-23 19:18:23 +0000443 struct listnode *ifnode;
444 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000445 struct interface *ifp;
446 struct connected *connected;
447 struct prefix_ipv6 p;
448 struct prefix *cp;
449
450 p.family = AF_INET6;
451 p.prefix = *addr;
452 p.prefixlen = IPV6_MAX_BITLEN;
453
paul1eb8ef22005-04-07 07:30:20 +0000454 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000455 {
paul1eb8ef22005-04-07 07:30:20 +0000456 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000457 {
paul718e3742002-12-13 20:15:29 +0000458 cp = connected->address;
459
460 if (cp->family == AF_INET6)
461 if (prefix_match (cp, (struct prefix *)&p))
462 return ifp;
463 }
464 }
465 return NULL;
466}
467
468struct interface *
469if_lookup_by_ipv6_exact (struct in6_addr *addr)
470{
hasso52dc7ee2004-09-23 19:18:23 +0000471 struct listnode *ifnode;
472 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000473 struct interface *ifp;
474 struct connected *connected;
475 struct prefix *cp;
476
paul1eb8ef22005-04-07 07:30:20 +0000477 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
paul718e3742002-12-13 20:15:29 +0000478 {
paul1eb8ef22005-04-07 07:30:20 +0000479 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000480 {
paul718e3742002-12-13 20:15:29 +0000481 cp = connected->address;
482
483 if (cp->family == AF_INET6)
484 if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
485 return ifp;
486 }
487 }
488 return NULL;
489}
490
paul94f2b392005-06-28 12:44:16 +0000491static int
paul718e3742002-12-13 20:15:29 +0000492if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
493{
hasso52dc7ee2004-09-23 19:18:23 +0000494 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000495 struct connected *connected;
496 struct prefix *cp;
497
paul1eb8ef22005-04-07 07:30:20 +0000498 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000499 {
paul718e3742002-12-13 20:15:29 +0000500 cp = connected->address;
501
502 if (cp->family == AF_INET6)
503 if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
504 {
505 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
506 return 1;
507 }
508 }
509 return 0;
510}
511
paul94f2b392005-06-28 12:44:16 +0000512static int
paul718e3742002-12-13 20:15:29 +0000513if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
514{
hasso52dc7ee2004-09-23 19:18:23 +0000515 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000516 struct connected *connected;
517 struct prefix *cp;
518
paul1eb8ef22005-04-07 07:30:20 +0000519 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000520 {
paul718e3742002-12-13 20:15:29 +0000521 cp = connected->address;
522
523 if (cp->family == AF_INET6)
524 if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
525 {
526 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
527 return 1;
528 }
529 }
530 return 0;
531}
532#endif /* HAVE_IPV6 */
533
534int
535bgp_nexthop_set (union sockunion *local, union sockunion *remote,
536 struct bgp_nexthop *nexthop, struct peer *peer)
537{
538 int ret = 0;
539 struct interface *ifp = NULL;
540
541 memset (nexthop, 0, sizeof (struct bgp_nexthop));
542
543 if (!local)
544 return -1;
545 if (!remote)
546 return -1;
547
548 if (local->sa.sa_family == AF_INET)
549 {
550 nexthop->v4 = local->sin.sin_addr;
551 ifp = if_lookup_by_ipv4 (&local->sin.sin_addr);
552 }
553#ifdef HAVE_IPV6
554 if (local->sa.sa_family == AF_INET6)
555 {
556 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
557 {
558 if (peer->ifname)
559 ifp = if_lookup_by_index (if_nametoindex (peer->ifname));
560 }
561 else
562 ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr);
563 }
564#endif /* HAVE_IPV6 */
565
566 if (!ifp)
567 return -1;
568
569 nexthop->ifp = ifp;
570
571 /* IPv4 connection. */
572 if (local->sa.sa_family == AF_INET)
573 {
574#ifdef HAVE_IPV6
575 /* IPv6 nexthop*/
576 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
577
578 /* There is no global nexthop. */
579 if (!ret)
580 if_get_ipv6_local (ifp, &nexthop->v6_global);
581 else
582 if_get_ipv6_local (ifp, &nexthop->v6_local);
583#endif /* HAVE_IPV6 */
584 }
585
586#ifdef HAVE_IPV6
587 /* IPv6 connection. */
588 if (local->sa.sa_family == AF_INET6)
589 {
590 struct interface *direct = NULL;
591
592 /* IPv4 nexthop. I don't care about it. */
593 if (peer->local_id.s_addr)
594 nexthop->v4 = peer->local_id;
595
596 /* Global address*/
597 if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
598 {
599 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
600 IPV6_MAX_BYTELEN);
601
602 /* If directory connected set link-local address. */
603 direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);
604 if (direct)
605 if_get_ipv6_local (ifp, &nexthop->v6_local);
606 }
607 else
608 /* Link-local address. */
609 {
610 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
611
612 /* If there is no global address. Set link-local address as
613 global. I know this break RFC specification... */
614 if (!ret)
615 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
616 IPV6_MAX_BYTELEN);
617 else
618 memcpy (&nexthop->v6_local, &local->sin6.sin6_addr,
619 IPV6_MAX_BYTELEN);
620 }
621 }
622
623 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
624 if_lookup_by_ipv6 (&remote->sin6.sin6_addr))
625 peer->shared_network = 1;
626 else
627 peer->shared_network = 0;
628
629 /* KAME stack specific treatment. */
630#ifdef KAME
631 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
632 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
633 {
634 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
635 }
636 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
637 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
638 {
639 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
640 }
641#endif /* KAME */
642#endif /* HAVE_IPV6 */
643 return ret;
644}
645
paul718e3742002-12-13 20:15:29 +0000646void
647bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp)
648{
649 int flags;
650 u_char distance;
651 struct peer *peer;
Josh Bailey8196f132011-07-20 20:47:07 -0700652 struct bgp_info *mpinfo;
653 size_t oldsize, newsize;
paul718e3742002-12-13 20:15:29 +0000654
655 if (zclient->sock < 0)
656 return;
657
658 if (! zclient->redist[ZEBRA_ROUTE_BGP])
659 return;
660
661 flags = 0;
662 peer = info->peer;
663
664 if (peer_sort (peer) == BGP_PEER_IBGP || peer_sort (peer) == BGP_PEER_CONFED)
665 {
666 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
667 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
668 }
669
670 if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000671 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000672 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
673
Josh Bailey8196f132011-07-20 20:47:07 -0700674 /* resize nexthop buffer size if necessary */
675 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
676 (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1)))
677 {
678 newsize = (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1));
679 newsize = stream_resize (bgp_nexthop_buf, newsize);
680 if (newsize == oldsize)
681 {
682 zlog_err ("can't resize nexthop buffer");
683 return;
684 }
685 }
686
687 stream_reset (bgp_nexthop_buf);
688
paul718e3742002-12-13 20:15:29 +0000689 if (p->family == AF_INET)
690 {
691 struct zapi_ipv4 api;
692 struct in_addr *nexthop;
693
694 api.flags = flags;
695 nexthop = &info->attr->nexthop;
Josh Bailey8196f132011-07-20 20:47:07 -0700696 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
697 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
698 mpinfo = bgp_info_mpath_next (mpinfo))
699 {
700 nexthop = &mpinfo->attr->nexthop;
701 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
702 }
paul718e3742002-12-13 20:15:29 +0000703
704 api.type = ZEBRA_ROUTE_BGP;
705 api.message = 0;
706 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
Josh Bailey8196f132011-07-20 20:47:07 -0700707 api.nexthop_num = 1 + bgp_info_mpath_count (info);
708 api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
paul718e3742002-12-13 20:15:29 +0000709 api.ifindex_num = 0;
710 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
711 api.metric = info->attr->med;
712
713 distance = bgp_distance_apply (p, info, bgp);
714
715 if (distance)
716 {
717 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
718 api.distance = distance;
719 }
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000720
721 if (BGP_DEBUG(zebra, ZEBRA))
722 {
Josh Bailey8196f132011-07-20 20:47:07 -0700723 int i;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000724 char buf[2][INET_ADDRSTRLEN];
Josh Bailey8196f132011-07-20 20:47:07 -0700725 zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u"
726 " count %d",
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000727 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
728 p->prefixlen,
Josh Bailey8196f132011-07-20 20:47:07 -0700729 inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])),
730 api.metric, api.nexthop_num);
731 for (i = 1; i < api.nexthop_num; i++)
732 zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s",
733 i, inet_ntop(AF_INET, api.nexthop[i], buf[1],
734 sizeof(buf[1])));
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000735 }
736
paul0a589352004-05-08 11:48:26 +0000737 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient,
738 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000739 }
740#ifdef HAVE_IPV6
741 /* We have to think about a IPv6 link-local address curse. */
742 if (p->family == AF_INET6)
743 {
744 unsigned int ifindex;
745 struct in6_addr *nexthop;
746 struct zapi_ipv6 api;
747
748 ifindex = 0;
749 nexthop = NULL;
Paul Jakmafb982c22007-05-04 20:15:47 +0000750
751 assert (info->attr->extra);
752
paul718e3742002-12-13 20:15:29 +0000753 /* Only global address nexthop exists. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000754 if (info->attr->extra->mp_nexthop_len == 16)
755 nexthop = &info->attr->extra->mp_nexthop_global;
paul718e3742002-12-13 20:15:29 +0000756
757 /* If both global and link-local address present. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000758 if (info->attr->extra->mp_nexthop_len == 32)
paul718e3742002-12-13 20:15:29 +0000759 {
760 /* Workaround for Cisco's nexthop bug. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000761 if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
paul718e3742002-12-13 20:15:29 +0000762 && peer->su_remote->sa.sa_family == AF_INET6)
763 nexthop = &peer->su_remote->sin6.sin6_addr;
764 else
Paul Jakmafb982c22007-05-04 20:15:47 +0000765 nexthop = &info->attr->extra->mp_nexthop_local;
paul718e3742002-12-13 20:15:29 +0000766
767 if (info->peer->nexthop.ifp)
768 ifindex = info->peer->nexthop.ifp->ifindex;
769 }
770
771 if (nexthop == NULL)
772 return;
773
774 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
775 {
776 if (info->peer->ifname)
777 ifindex = if_nametoindex (info->peer->ifname);
778 else if (info->peer->nexthop.ifp)
779 ifindex = info->peer->nexthop.ifp->ifindex;
780 }
781
782 /* Make Zebra API structure. */
783 api.flags = flags;
784 api.type = ZEBRA_ROUTE_BGP;
785 api.message = 0;
786 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
787 api.nexthop_num = 1;
788 api.nexthop = &nexthop;
789 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
790 api.ifindex_num = 1;
791 api.ifindex = &ifindex;
792 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
793 api.metric = info->attr->med;
794
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000795 if (BGP_DEBUG(zebra, ZEBRA))
796 {
797 char buf[2][INET6_ADDRSTRLEN];
798 zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
799 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
800 p->prefixlen,
801 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
802 api.metric);
803 }
804
paul0a589352004-05-08 11:48:26 +0000805 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient,
806 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000807 }
808#endif /* HAVE_IPV6 */
809}
810
811void
812bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info)
813{
814 int flags;
815 struct peer *peer;
816
817 if (zclient->sock < 0)
818 return;
819
820 if (! zclient->redist[ZEBRA_ROUTE_BGP])
821 return;
822
823 peer = info->peer;
824 flags = 0;
825
826 if (peer_sort (peer) == BGP_PEER_IBGP)
827 {
828 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
829 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
830 }
831
832 if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
hasso6ffd2072005-02-02 14:50:11 +0000833 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
paul718e3742002-12-13 20:15:29 +0000834 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
835
836 if (p->family == AF_INET)
837 {
838 struct zapi_ipv4 api;
839 struct in_addr *nexthop;
840
841 api.flags = flags;
842 nexthop = &info->attr->nexthop;
843
844 api.type = ZEBRA_ROUTE_BGP;
845 api.message = 0;
846 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
847 api.nexthop_num = 1;
848 api.nexthop = &nexthop;
849 api.ifindex_num = 0;
850 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
851 api.metric = info->attr->med;
852
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000853 if (BGP_DEBUG(zebra, ZEBRA))
854 {
855 char buf[2][INET_ADDRSTRLEN];
856 zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u",
857 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
858 p->prefixlen,
859 inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])),
860 api.metric);
861 }
862
paul0a589352004-05-08 11:48:26 +0000863 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
864 (struct prefix_ipv4 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000865 }
866#ifdef HAVE_IPV6
867 /* We have to think about a IPv6 link-local address curse. */
868 if (p->family == AF_INET6)
869 {
870 struct zapi_ipv6 api;
871 unsigned int ifindex;
872 struct in6_addr *nexthop;
Paul Jakmafb982c22007-05-04 20:15:47 +0000873
874 assert (info->attr->extra);
875
paul718e3742002-12-13 20:15:29 +0000876 ifindex = 0;
877 nexthop = NULL;
878
879 /* Only global address nexthop exists. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000880 if (info->attr->extra->mp_nexthop_len == 16)
881 nexthop = &info->attr->extra->mp_nexthop_global;
paul718e3742002-12-13 20:15:29 +0000882
883 /* If both global and link-local address present. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000884 if (info->attr->extra->mp_nexthop_len == 32)
paul718e3742002-12-13 20:15:29 +0000885 {
Paul Jakmafb982c22007-05-04 20:15:47 +0000886 nexthop = &info->attr->extra->mp_nexthop_local;
paul718e3742002-12-13 20:15:29 +0000887 if (info->peer->nexthop.ifp)
888 ifindex = info->peer->nexthop.ifp->ifindex;
889 }
890
891 if (nexthop == NULL)
892 return;
893
894 if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
895 if (info->peer->ifname)
896 ifindex = if_nametoindex (info->peer->ifname);
897
898 api.flags = flags;
899 api.type = ZEBRA_ROUTE_BGP;
900 api.message = 0;
901 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
902 api.nexthop_num = 1;
903 api.nexthop = &nexthop;
904 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
905 api.ifindex_num = 1;
906 api.ifindex = &ifindex;
907 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
908 api.metric = info->attr->med;
909
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000910 if (BGP_DEBUG(zebra, ZEBRA))
911 {
912 char buf[2][INET6_ADDRSTRLEN];
913 zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u",
914 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
915 p->prefixlen,
916 inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
917 api.metric);
918 }
919
paul0a589352004-05-08 11:48:26 +0000920 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
921 (struct prefix_ipv6 *) p, &api);
paul718e3742002-12-13 20:15:29 +0000922 }
923#endif /* HAVE_IPV6 */
924}
925
926/* Other routes redistribution into BGP. */
927int
928bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
929{
930 /* Set flag to BGP instance. */
931 bgp->redist[afi][type] = 1;
932
933 /* Return if already redistribute flag is set. */
934 if (zclient->redist[type])
935 return CMD_WARNING;
936
937 zclient->redist[type] = 1;
938
939 /* Return if zebra connection is not established. */
940 if (zclient->sock < 0)
941 return CMD_WARNING;
Andrew J. Schorra39275d2006-11-30 16:36:57 +0000942
943 if (BGP_DEBUG(zebra, ZEBRA))
944 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
paul718e3742002-12-13 20:15:29 +0000945
946 /* Send distribute add message to zebra. */
ajs634f9ea2005-04-11 15:51:40 +0000947 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
paul718e3742002-12-13 20:15:29 +0000948
949 return CMD_SUCCESS;
950}
951
952/* Redistribute with route-map specification. */
953int
paulfd79ac92004-10-13 05:06:08 +0000954bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type,
955 const char *name)
paul718e3742002-12-13 20:15:29 +0000956{
957 if (bgp->rmap[afi][type].name
958 && (strcmp (bgp->rmap[afi][type].name, name) == 0))
959 return 0;
960
961 if (bgp->rmap[afi][type].name)
962 free (bgp->rmap[afi][type].name);
963 bgp->rmap[afi][type].name = strdup (name);
964 bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
965
966 return 1;
967}
968
969/* Redistribute with metric specification. */
970int
971bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
972 u_int32_t metric)
973{
974 if (bgp->redist_metric_flag[afi][type]
975 && bgp->redist_metric[afi][type] == metric)
976 return 0;
977
978 bgp->redist_metric_flag[afi][type] = 1;
979 bgp->redist_metric[afi][type] = metric;
980
981 return 1;
982}
983
984/* Unset redistribution. */
985int
986bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
987{
988 /* Unset flag from BGP instance. */
989 bgp->redist[afi][type] = 0;
990
991 /* Unset route-map. */
992 if (bgp->rmap[afi][type].name)
993 free (bgp->rmap[afi][type].name);
994 bgp->rmap[afi][type].name = NULL;
995 bgp->rmap[afi][type].map = NULL;
996
997 /* Unset metric. */
998 bgp->redist_metric_flag[afi][type] = 0;
999 bgp->redist_metric[afi][type] = 0;
1000
1001 /* Return if zebra connection is disabled. */
1002 if (! zclient->redist[type])
1003 return CMD_WARNING;
1004 zclient->redist[type] = 0;
1005
1006 if (bgp->redist[AFI_IP][type] == 0
1007 && bgp->redist[AFI_IP6][type] == 0
1008 && zclient->sock >= 0)
Andrew J. Schorra39275d2006-11-30 16:36:57 +00001009 {
1010 /* Send distribute delete message to zebra. */
1011 if (BGP_DEBUG(zebra, ZEBRA))
1012 zlog_debug("Zebra send: redistribute delete %s",
1013 zebra_route_string(type));
1014 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
1015 }
paul718e3742002-12-13 20:15:29 +00001016
1017 /* Withdraw redistributed routes from current BGP's routing table. */
1018 bgp_redistribute_withdraw (bgp, afi, type);
1019
1020 return CMD_SUCCESS;
1021}
1022
1023/* Unset redistribution route-map configuration. */
1024int
1025bgp_redistribute_routemap_unset (struct bgp *bgp, afi_t afi, int type)
1026{
1027 if (! bgp->rmap[afi][type].name)
1028 return 0;
1029
1030 /* Unset route-map. */
1031 free (bgp->rmap[afi][type].name);
1032 bgp->rmap[afi][type].name = NULL;
1033 bgp->rmap[afi][type].map = NULL;
1034
1035 return 1;
1036}
1037
1038/* Unset redistribution metric configuration. */
1039int
1040bgp_redistribute_metric_unset (struct bgp *bgp, afi_t afi, int type)
1041{
1042 if (! bgp->redist_metric_flag[afi][type])
1043 return 0;
1044
1045 /* Unset metric. */
1046 bgp->redist_metric_flag[afi][type] = 0;
1047 bgp->redist_metric[afi][type] = 0;
1048
1049 return 1;
1050}
1051
1052void
paul94f2b392005-06-28 12:44:16 +00001053bgp_zclient_reset (void)
paul718e3742002-12-13 20:15:29 +00001054{
1055 zclient_reset (zclient);
1056}
1057
1058void
paul94f2b392005-06-28 12:44:16 +00001059bgp_zebra_init (void)
paul718e3742002-12-13 20:15:29 +00001060{
1061 /* Set default values. */
1062 zclient = zclient_new ();
1063 zclient_init (zclient, ZEBRA_ROUTE_BGP);
hasso18a6dce2004-10-03 18:18:34 +00001064 zclient->router_id_update = bgp_router_id_update;
paul718e3742002-12-13 20:15:29 +00001065 zclient->interface_add = bgp_interface_add;
1066 zclient->interface_delete = bgp_interface_delete;
1067 zclient->interface_address_add = bgp_interface_address_add;
1068 zclient->interface_address_delete = bgp_interface_address_delete;
1069 zclient->ipv4_route_add = zebra_read_ipv4;
1070 zclient->ipv4_route_delete = zebra_read_ipv4;
1071 zclient->interface_up = bgp_interface_up;
1072 zclient->interface_down = bgp_interface_down;
1073#ifdef HAVE_IPV6
1074 zclient->ipv6_route_add = zebra_read_ipv6;
1075 zclient->ipv6_route_delete = zebra_read_ipv6;
1076#endif /* HAVE_IPV6 */
1077
1078 /* Interface related init. */
1079 if_init ();
Josh Bailey8196f132011-07-20 20:47:07 -07001080
1081 bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
paul718e3742002-12-13 20:15:29 +00001082}