int i2rs_route_add () { struct zapi_ipv4 api; struct prefix_ipv4 routeToAdd; struct in_addr nexthop[1]; struct in_addr *nexthop_p; unsigned int ifindex; printf("Start i2rs_route_add\n"); routeToAdd.family = AF_INET; routeToAdd.prefixlen = 24; // \24 mask inet_pton(AF_INET, "100.100.100.1", &routeToAdd.prefix.s_addr); printf("i2rs zebra ADD start\n"); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_STATIC; api.flags =0; // correct value unknown api.message = ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_METRIC; api.nexthop_num = 1; api.ifindex_num = 0; inet_pton(AF_INET, "100.100.100.1", &nexthop[0].s_addr); nexthop_p = nexthop; api.nexthop = &nexthop_p; ifindex = 1; //is 1 equal to eth0? api.ifindex = &ifindex; api.distance = 0; api.metric = 10; printf("zapi ip4 route call\n"); zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, &routeToAdd, &api); printf("zapi ip4 route call END\n"); }
/* Send ECMP routes to zebra. */ static void rip_zebra_ipv4_send (struct route_node *rp, u_char cmd) { static struct in_addr **nexthops = NULL; static unsigned int nexthops_len = 0; struct list *list = (struct list *)rp->info; struct zapi_ipv4 api; struct listnode *listnode = NULL; struct rip_info *rinfo = NULL; int count = 0; if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT)) { api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_RIP; api.flags = 0; api.message = 0; api.safi = SAFI_UNICAST; if (nexthops_len < listcount (list)) { nexthops_len = listcount (list); nexthops = XREALLOC (MTYPE_TMP, nexthops, nexthops_len * sizeof (struct in_addr *)); } SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); for (ALL_LIST_ELEMENTS_RO (list, listnode, rinfo)) { nexthops[count++] = &rinfo->nexthop; if (cmd == ZEBRA_IPV4_ROUTE_ADD) SET_FLAG (rinfo->flags, RIP_RTF_FIB); else UNSET_FLAG (rinfo->flags, RIP_RTF_FIB); } api.nexthop = nexthops; api.nexthop_num = count; api.ifindex_num = 0; rinfo = listgetdata (listhead (list)); SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = rinfo->metric; if (rinfo->distance && rinfo->distance != ZEBRA_RIP_DISTANCE_DEFAULT) { SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE); api.distance = rinfo->distance; } zapi_ipv4_route (cmd, zclient, (struct prefix_ipv4 *)&rp->p, &api); rip_global_route_changes++; }
void isis_zebra_route_del_ipv4 (struct prefix *prefix, struct isis_route_info *route_info) { struct zapi_ipv4 api; struct prefix_ipv4 prefix4; if (zclient->redist[ZEBRA_ROUTE_ISIS]) { api.type = ZEBRA_ROUTE_ISIS; api.flags = 0; api.message = 0; prefix4.family = AF_INET; prefix4.prefixlen = prefix->prefixlen; prefix4.prefix = prefix->u.prefix4; zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, &api); } return; }
void rip_zebra_ipv4_add (struct prefix_ipv4 *p, struct in_addr *nexthop, u_int32_t metric, u_char distance) { struct zapi_ipv4 api; #if 0 if(current_rip_entry>=rip_max_entry) { if(IS_RIP_DEBUG_ZEBRA) { zlog_info ("Discards rip packet for current rip entry over MAX ENTRY\n"); zlog_info ("current_rip_entry=%d\nrip_max_entry=%d\n",current_rip_entry,rip_max_entry); } return ; } #endif if (zclient->redist[ZEBRA_ROUTE_RIP]) { api.type = ZEBRA_ROUTE_RIP; api.flags = 0; api.message = 0; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api.nexthop = &nexthop; api.ifindex_num = 0; SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = metric; if (distance && distance != ZEBRA_RIP_DISTANCE_DEFAULT) { SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE); api.distance = distance; } zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api); current_rip_entry++; rip_global_route_changes++; } }
void rip_zebra_ipv4_delete (struct prefix_ipv4 *p, struct in_addr *nexthop, u_int32_t metric) { struct zapi_ipv4 api; if (zclient->redist[ZEBRA_ROUTE_RIP]) { api.type = ZEBRA_ROUTE_RIP; api.flags = 0; api.message = 0; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api.nexthop = &nexthop; api.ifindex_num = 0; SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = metric; zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api); current_rip_entry--; rip_global_route_changes++; } }
void bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi) { int flags; struct peer *peer; if (zclient->sock < 0) return; if (! zclient->redist[ZEBRA_ROUTE_BGP]) return; peer = info->peer; flags = 0; if (peer->sort == BGP_PEER_IBGP) { SET_FLAG (flags, ZEBRA_FLAG_INTERNAL); SET_FLAG (flags, ZEBRA_FLAG_IBGP); } if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1) || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)) SET_FLAG (flags, ZEBRA_FLAG_INTERNAL); if (p->family == AF_INET) { struct zapi_ipv4 api; struct in_addr *nexthop; api.flags = flags; nexthop = &info->attr->nexthop; api.type = ZEBRA_ROUTE_BGP; api.message = 0; api.safi = safi; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api.nexthop = &nexthop; api.ifindex_num = 0; SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = info->attr->med; if (BGP_DEBUG(zebra, ZEBRA)) { char buf[2][INET_ADDRSTRLEN]; zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u", inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])), p->prefixlen, inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])), api.metric); } zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, (struct prefix_ipv4 *) p, &api); } #ifdef HAVE_IPV6 /* We have to think about a IPv6 link-local address curse. */ if (p->family == AF_INET6) { struct zapi_ipv6 api; unsigned int ifindex; struct in6_addr *nexthop; assert (info->attr->extra); ifindex = 0; nexthop = NULL; /* Only global address nexthop exists. */ if (info->attr->extra->mp_nexthop_len == 16) nexthop = &info->attr->extra->mp_nexthop_global; /* If both global and link-local address present. */ if (info->attr->extra->mp_nexthop_len == 32) { nexthop = &info->attr->extra->mp_nexthop_local; if (info->peer->nexthop.ifp) ifindex = info->peer->nexthop.ifp->ifindex; } if (nexthop == NULL) return; if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex) if (info->peer->ifname) ifindex = if_nametoindex (info->peer->ifname); api.flags = flags; api.type = ZEBRA_ROUTE_BGP; api.message = 0; api.safi = safi; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api.nexthop = &nexthop; SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX); api.ifindex_num = 1; api.ifindex = &ifindex; SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = info->attr->med; if (BGP_DEBUG(zebra, ZEBRA)) { char buf[2][INET6_ADDRSTRLEN]; zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u", inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])), p->prefixlen, inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])), api.metric); } zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, (struct prefix_ipv6 *) p, &api); } #endif /* HAVE_IPV6 */ }
void bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi) { int flags; u_char distance; struct peer *peer; struct bgp_info *mpinfo; size_t oldsize, newsize; if (zclient->sock < 0) return; if (! zclient->redist[ZEBRA_ROUTE_BGP]) return; flags = 0; peer = info->peer; if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED) { SET_FLAG (flags, ZEBRA_FLAG_IBGP); SET_FLAG (flags, ZEBRA_FLAG_INTERNAL); } if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1) || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)) SET_FLAG (flags, ZEBRA_FLAG_INTERNAL); /* resize nexthop buffer size if necessary */ if ((oldsize = stream_get_size (bgp_nexthop_buf)) < (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1))) { newsize = (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1)); newsize = stream_resize (bgp_nexthop_buf, newsize); if (newsize == oldsize) { zlog_err ("can't resize nexthop buffer"); return; } } stream_reset (bgp_nexthop_buf); if (p->family == AF_INET) { struct zapi_ipv4 api; struct in_addr *nexthop; api.flags = flags; nexthop = &info->attr->nexthop; stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *)); for (mpinfo = bgp_info_mpath_first (info); mpinfo; mpinfo = bgp_info_mpath_next (mpinfo)) { nexthop = &mpinfo->attr->nexthop; stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *)); } api.type = ZEBRA_ROUTE_BGP; api.message = 0; api.safi = safi; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1 + bgp_info_mpath_count (info); api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf); api.ifindex_num = 0; SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = info->attr->med; distance = bgp_distance_apply (p, info, bgp); if (distance) { SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE); api.distance = distance; } if (BGP_DEBUG(zebra, ZEBRA)) { int i; char buf[2][INET_ADDRSTRLEN]; zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u" " count %d", inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])), p->prefixlen, inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])), api.metric, api.nexthop_num); for (i = 1; i < api.nexthop_num; i++) zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s", i, inet_ntop(AF_INET, api.nexthop[i], buf[1], sizeof(buf[1]))); } zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, (struct prefix_ipv4 *) p, &api); } #ifdef HAVE_IPV6 /* We have to think about a IPv6 link-local address curse. */ if (p->family == AF_INET6) { unsigned int ifindex; struct in6_addr *nexthop; struct zapi_ipv6 api; ifindex = 0; nexthop = NULL; assert (info->attr->extra); /* Only global address nexthop exists. */ if (info->attr->extra->mp_nexthop_len == 16) nexthop = &info->attr->extra->mp_nexthop_global; /* If both global and link-local address present. */ if (info->attr->extra->mp_nexthop_len == 32) { /* Workaround for Cisco's nexthop bug. */ if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global) && peer->su_remote->sa.sa_family == AF_INET6) nexthop = &peer->su_remote->sin6.sin6_addr; else nexthop = &info->attr->extra->mp_nexthop_local; if (info->peer->nexthop.ifp) ifindex = info->peer->nexthop.ifp->ifindex; } if (nexthop == NULL) return; if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex) { if (info->peer->ifname) ifindex = if_nametoindex (info->peer->ifname); else if (info->peer->nexthop.ifp) ifindex = info->peer->nexthop.ifp->ifindex; } /* Make Zebra API structure. */ api.flags = flags; api.type = ZEBRA_ROUTE_BGP; api.message = 0; api.safi = safi; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api.nexthop = &nexthop; SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX); api.ifindex_num = 1; api.ifindex = &ifindex; SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = info->attr->med; if (BGP_DEBUG(zebra, ZEBRA)) { char buf[2][INET6_ADDRSTRLEN]; zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u", inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])), p->prefixlen, inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])), api.metric); } zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, (struct prefix_ipv6 *) p, &api); } #endif /* HAVE_IPV6 */ }
void bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi) { int flags; struct peer *peer; if (zclient->sock < 0) return; if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT)) return; peer = info->peer; flags = 0; if (peer->sort == BGP_PEER_IBGP) { SET_FLAG (flags, ZEBRA_FLAG_INTERNAL); SET_FLAG (flags, ZEBRA_FLAG_IBGP); } if ((peer->sort == BGP_PEER_EBGP && peer_ttl (peer) != 1) || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)) SET_FLAG (flags, ZEBRA_FLAG_INTERNAL); if (p->family == AF_INET) { struct zapi_ipv4 api; api.vrf_id = VRF_DEFAULT; api.flags = flags; api.type = ZEBRA_ROUTE_BGP; api.message = 0; api.safi = safi; api.nexthop_num = 0; api.ifindex_num = 0; SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = info->attr->med; if ((info->attr->extra) && (info->attr->extra->tag != 0)) { SET_FLAG(api.message, ZAPI_MESSAGE_TAG); api.tag = info->attr->extra->tag; } if (BGP_DEBUG(zebra, ZEBRA)) { char buf[2][INET_ADDRSTRLEN]; zlog_debug("Zebra send: IPv4 route delete %s/%d metric %u tag %d", inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])), p->prefixlen, api.metric, api.tag); } zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, (struct prefix_ipv4 *) p, &api); } /* We have to think about a IPv6 link-local address curse. */ if (p->family == AF_INET6) { struct zapi_ipv6 api; api.vrf_id = VRF_DEFAULT; api.flags = flags; api.type = ZEBRA_ROUTE_BGP; api.message = 0; api.safi = safi; api.nexthop_num = 0; api.ifindex_num = 0; SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = info->attr->med; if ((info->attr->extra) && (info->attr->extra->tag != 0)) { SET_FLAG(api.message, ZAPI_MESSAGE_TAG); api.tag = info->attr->extra->tag; } if (BGP_DEBUG(zebra, ZEBRA)) { char buf[2][INET6_ADDRSTRLEN]; zlog_debug("Zebra send: IPv6 route delete %s/%d metric %u tag %d", inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])), p->prefixlen, api.metric, api.tag); } zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, (struct prefix_ipv6 *) p, &api); } }