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