void route_delete(struct prefix *p, vrf_id_t vrf_id, uint8_t instance) { struct zapi_route api; memset(&api, 0, sizeof(api)); api.vrf_id = vrf_id; api.type = ZEBRA_ROUTE_SHARP; api.safi = SAFI_UNICAST; api.instance = instance; memcpy(&api.prefix, p, sizeof(*p)); zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); return; }
void route_add(struct prefix *p, vrf_id_t vrf_id, uint8_t instance, struct nexthop_group *nhg) { struct zapi_route api; struct zapi_nexthop *api_nh; struct nexthop *nh; int i = 0; memset(&api, 0, sizeof(api)); api.vrf_id = vrf_id; api.type = ZEBRA_ROUTE_SHARP; api.instance = instance; api.safi = SAFI_UNICAST; memcpy(&api.prefix, p, sizeof(*p)); SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION); SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); for (ALL_NEXTHOPS_PTR(nhg, nh)) { api_nh = &api.nexthops[i]; api_nh->vrf_id = nh->vrf_id; api_nh->type = nh->type; switch (nh->type) { case NEXTHOP_TYPE_IPV4: api_nh->gate = nh->gate; break; case NEXTHOP_TYPE_IPV4_IFINDEX: api_nh->gate = nh->gate; api_nh->ifindex = nh->ifindex; break; case NEXTHOP_TYPE_IFINDEX: api_nh->ifindex = nh->ifindex; break; case NEXTHOP_TYPE_IPV6: memcpy(&api_nh->gate.ipv6, &nh->gate.ipv6, 16); break; case NEXTHOP_TYPE_IPV6_IFINDEX: api_nh->ifindex = nh->ifindex; memcpy(&api_nh->gate.ipv6, &nh->gate.ipv6, 16); break; case NEXTHOP_TYPE_BLACKHOLE: api_nh->bh_type = nh->bh_type; break; } i++; } api.nexthop_num = i; zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); }
void eigrp_zebra_route_add(struct prefix *p, struct list *successors) { struct zapi_route api; struct zapi_nexthop *api_nh; struct eigrp_nexthop_entry *te; struct listnode *node; int count = 0; if (!zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP]) return; memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_EIGRP; api.safi = SAFI_UNICAST; memcpy(&api.prefix, p, sizeof(*p)); SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); /* Nexthop, ifindex, distance and metric information. */ for (ALL_LIST_ELEMENTS_RO(successors, node, te)) { if (count >= MULTIPATH_NUM) break; api_nh = &api.nexthops[count]; api_nh->vrf_id = VRF_DEFAULT; if (te->adv_router->src.s_addr) { api_nh->gate.ipv4 = te->adv_router->src; api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; } else api_nh->type = NEXTHOP_TYPE_IFINDEX; api_nh->ifindex = te->ei->ifp->ifindex; count++; } api.nexthop_num = count; if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE)) { char buf[2][PREFIX_STRLEN]; zlog_debug("Zebra: Route add %s nexthop %s", prefix2str(p, buf[0], PREFIX_STRLEN), inet_ntop(AF_INET, 0, buf[1], PREFIX_STRLEN)); } zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); }
void eigrp_zebra_route_delete(struct prefix *p) { struct zapi_route api; if (!zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP]) return; memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_EIGRP; api.safi = SAFI_UNICAST; memcpy(&api.prefix, p, sizeof(*p)); zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE)) { char buf[PREFIX_STRLEN]; zlog_debug("Zebra: Route del %s", prefix2str(p, buf, PREFIX_STRLEN)); } return; }
/* Send ECMP routes to zebra. */ static void rip_zebra_ipv4_send(struct rip *rip, struct route_node *rp, uint8_t cmd) { struct list *list = (struct list *)rp->info; struct zapi_route api; struct zapi_nexthop *api_nh; struct listnode *listnode = NULL; struct rip_info *rinfo = NULL; int count = 0; memset(&api, 0, sizeof(api)); api.vrf_id = rip->vrf->vrf_id; api.type = ZEBRA_ROUTE_RIP; api.safi = SAFI_UNICAST; SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { if (count >= MULTIPATH_NUM) break; api_nh = &api.nexthops[count]; api_nh->vrf_id = rip->vrf->vrf_id; api_nh->gate = rinfo->nh.gate; api_nh->type = NEXTHOP_TYPE_IPV4; if (cmd == ZEBRA_ROUTE_ADD) SET_FLAG(rinfo->flags, RIP_RTF_FIB); else UNSET_FLAG(rinfo->flags, RIP_RTF_FIB); count++; } api.prefix = rp->p; api.nexthop_num = count; 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; } if (rinfo->tag) { SET_FLAG(api.message, ZAPI_MESSAGE_TAG); api.tag = rinfo->tag; } zclient_route_send(cmd, zclient, &api); if (IS_RIP_DEBUG_ZEBRA) { if (rip->ecmp) zlog_debug("%s: %s/%d nexthops %d", (cmd == ZEBRA_ROUTE_ADD) ? "Install into zebra" : "Delete from zebra", inet_ntoa(rp->p.u.prefix4), rp->p.prefixlen, count); else zlog_debug("%s: %s/%d", (cmd == ZEBRA_ROUTE_ADD) ? "Install into zebra" : "Delete from zebra", inet_ntoa(rp->p.u.prefix4), rp->p.prefixlen); } rip->counters.route_changes++; }
void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix *p, struct interface *ifp, const union sockunion *nexthop, uint32_t mtu) { struct zapi_route api; struct zapi_nexthop *api_nh; if (zclient->sock < 0) return; memset(&api, 0, sizeof(api)); api.type = ZEBRA_ROUTE_NHRP; api.safi = SAFI_UNICAST; api.vrf_id = VRF_DEFAULT; api.prefix = *p; switch (type) { case NHRP_CACHE_NEGATIVE: zapi_route_set_blackhole(&api, BLACKHOLE_REJECT); ifp = NULL; nexthop = NULL; break; case NHRP_CACHE_DYNAMIC: case NHRP_CACHE_NHS: case NHRP_CACHE_STATIC: /* Regular route, so these are announced * to other routing daemons */ break; default: SET_FLAG(api.flags, ZEBRA_FLAG_FIB_OVERRIDE); break; } SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION); SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api_nh = &api.nexthops[0]; api_nh->vrf_id = VRF_DEFAULT; switch (api.prefix.family) { case AF_INET: if (nexthop) { api_nh->gate.ipv4 = nexthop->sin.sin_addr; api_nh->type = NEXTHOP_TYPE_IPV4; } if (ifp) { api_nh->ifindex = ifp->ifindex; if (api_nh->type == NEXTHOP_TYPE_IPV4) api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; else api_nh->type = NEXTHOP_TYPE_IFINDEX; } break; case AF_INET6: if (nexthop) { api_nh->gate.ipv6 = nexthop->sin6.sin6_addr; api_nh->type = NEXTHOP_TYPE_IPV6; } if (ifp) { api_nh->ifindex = ifp->ifindex; if (api_nh->type == NEXTHOP_TYPE_IPV6) api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; else api_nh->type = NEXTHOP_TYPE_IFINDEX; } break; } if (mtu) { SET_FLAG(api.message, ZAPI_MESSAGE_MTU); api.mtu = mtu; } if (unlikely(debug_flags & NHRP_DEBUG_ROUTE)) { char buf[2][PREFIX_STRLEN]; prefix2str(&api.prefix, buf[0], sizeof(buf[0])); zlog_debug( "Zebra send: route %s %s nexthop %s metric %u" " count %d dev %s", add ? "add" : "del", buf[0], nexthop ? inet_ntop(api.prefix.family, &api_nh->gate, buf[1], sizeof(buf[1])) : "<onlink>", api.metric, api.nexthop_num, ifp ? ifp->name : "none"); } zclient_route_send(add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, zclient, &api); }