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