diff options
Diffstat (limited to 'staticd/static_zebra.c')
| -rw-r--r-- | staticd/static_zebra.c | 142 |
1 files changed, 91 insertions, 51 deletions
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index c42f632ffb..d8a4b7f0cb 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -89,7 +89,6 @@ static int static_ifp_up(struct interface *ifp) struct static_vrf *svrf = static_vrf_lookup_by_id(ifp->vrf_id); static_fixup_vrf_ids(svrf); - static_config_install_delayed_routes(svrf); } /* Install any static reliant on this interface coming up */ @@ -265,8 +264,8 @@ static void static_nht_hash_free(void *data) XFREE(MTYPE_TMP, nhtd); } -void static_zebra_nht_register(struct route_node *rn, - struct static_route *si, bool reg) +void static_zebra_nht_register(struct route_node *rn, struct static_nexthop *nh, + bool reg) { struct static_nht_data *nhtd, lookup; uint32_t cmd; @@ -276,14 +275,14 @@ void static_zebra_nht_register(struct route_node *rn, cmd = (reg) ? ZEBRA_NEXTHOP_REGISTER : ZEBRA_NEXTHOP_UNREGISTER; - if (si->nh_registered && reg) + if (nh->nh_registered && reg) return; - if (!si->nh_registered && !reg) + if (!nh->nh_registered && !reg) return; memset(&p, 0, sizeof(p)); - switch (si->type) { + switch (nh->type) { case STATIC_IFNAME: case STATIC_BLACKHOLE: return; @@ -291,23 +290,23 @@ void static_zebra_nht_register(struct route_node *rn, case STATIC_IPV4_GATEWAY_IFNAME: p.family = AF_INET; p.prefixlen = IPV4_MAX_BITLEN; - p.u.prefix4 = si->addr.ipv4; + p.u.prefix4 = nh->addr.ipv4; afi = AFI_IP; break; case STATIC_IPV6_GATEWAY: case STATIC_IPV6_GATEWAY_IFNAME: p.family = AF_INET6; p.prefixlen = IPV6_MAX_BITLEN; - p.u.prefix6 = si->addr.ipv6; + p.u.prefix6 = nh->addr.ipv6; afi = AFI_IP6; break; } memset(&lookup, 0, sizeof(lookup)); lookup.nh = &p; - lookup.nh_vrf_id = si->nh_vrf_id; + lookup.nh_vrf_id = nh->nh_vrf_id; - si->nh_registered = reg; + nh->nh_registered = reg; if (reg) { nhtd = hash_get(static_nht_hash, &lookup, @@ -318,8 +317,8 @@ void static_zebra_nht_register(struct route_node *rn, zlog_debug("Registered nexthop(%pFX) for %pRN %d", &p, rn, nhtd->nh_num); if (nhtd->refcount > 1 && nhtd->nh_num) { - static_nht_update(&rn->p, nhtd->nh, nhtd->nh_num, - afi, si->nh_vrf_id); + static_nht_update(&rn->p, nhtd->nh, nhtd->nh_num, afi, + nh->nh_vrf_id); return; } } else { @@ -335,25 +334,72 @@ void static_zebra_nht_register(struct route_node *rn, static_nht_hash_free(nhtd); } - if (zclient_send_rnh(zclient, cmd, &p, false, si->nh_vrf_id) < 0) + if (zclient_send_rnh(zclient, cmd, &p, false, nh->nh_vrf_id) < 0) zlog_warn("%s: Failure to send nexthop to zebra", __func__); } +/* + * When nexthop gets updated via configuration then use the + * already registered NH and resend the route to zebra + */ +int static_zebra_nh_update(struct route_node *rn, struct static_nexthop *nh) +{ + struct static_nht_data *nhtd, lookup = {}; + struct prefix p = {}; + afi_t afi = AFI_IP; + + if (!nh->nh_registered) + return 0; + + switch (nh->type) { + case STATIC_IFNAME: + case STATIC_BLACKHOLE: + return 0; + case STATIC_IPV4_GATEWAY: + case STATIC_IPV4_GATEWAY_IFNAME: + p.family = AF_INET; + p.prefixlen = IPV4_MAX_BITLEN; + p.u.prefix4 = nh->addr.ipv4; + afi = AFI_IP; + break; + case STATIC_IPV6_GATEWAY: + case STATIC_IPV6_GATEWAY_IFNAME: + p.family = AF_INET6; + p.prefixlen = IPV6_MAX_BITLEN; + p.u.prefix6 = nh->addr.ipv6; + afi = AFI_IP6; + break; + } + + lookup.nh = &p; + lookup.nh_vrf_id = nh->nh_vrf_id; + + nhtd = hash_lookup(static_nht_hash, &lookup); + if (nhtd && nhtd->nh_num) { + nh->state = STATIC_START; + static_nht_update(&rn->p, nhtd->nh, nhtd->nh_num, afi, + nh->nh_vrf_id); + return 1; + } + return 0; +} extern void static_zebra_route_add(struct route_node *rn, - struct static_route *si_changed, - vrf_id_t vrf_id, safi_t safi, bool install) + struct static_path *pn, safi_t safi, + bool install) { - struct static_route *si = rn->info; + struct static_nexthop *nh; const struct prefix *p, *src_pp; struct zapi_nexthop *api_nh; struct zapi_route api; uint32_t nh_num = 0; + struct stable_info *info; p = src_pp = NULL; srcdest_rnode_prefixes(rn, &p, &src_pp); memset(&api, 0, sizeof(api)); - api.vrf_id = vrf_id; + info = static_get_stable_info(rn); + api.vrf_id = GET_STABLE_VRF_ID(info); api.type = ZEBRA_ROUTE_STATIC; api.safi = safi; memcpy(&api.prefix, p, sizeof(api.prefix)); @@ -365,71 +411,65 @@ extern void static_zebra_route_add(struct route_node *rn, SET_FLAG(api.flags, ZEBRA_FLAG_RR_USE_DISTANCE); SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION); SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - if (si_changed->distance) { + if (pn->distance) { SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); - api.distance = si_changed->distance; + api.distance = pn->distance; } - if (si_changed->tag) { + if (pn->tag) { SET_FLAG(api.message, ZAPI_MESSAGE_TAG); - api.tag = si_changed->tag; + api.tag = pn->tag; } - if (si_changed->table_id != 0) { + if (pn->table_id != 0) { SET_FLAG(api.message, ZAPI_MESSAGE_TABLEID); - api.tableid = si_changed->table_id; + api.tableid = pn->table_id; } - for (/*loaded above*/; si; si = si->next) { + frr_each(static_nexthop_list, &pn->nexthop_list, nh) { api_nh = &api.nexthops[nh_num]; - if (si->nh_vrf_id == VRF_UNKNOWN) - continue; - - if (si->distance != si_changed->distance) - continue; - - if (si->table_id != si_changed->table_id) + if (nh->nh_vrf_id == VRF_UNKNOWN) continue; - api_nh->vrf_id = si->nh_vrf_id; - if (si->onlink) + api_nh->vrf_id = nh->nh_vrf_id; + if (nh->onlink) SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK); - si->state = STATIC_SENT_TO_ZEBRA; + nh->state = STATIC_SENT_TO_ZEBRA; - switch (si->type) { + switch (nh->type) { case STATIC_IFNAME: - if (si->ifindex == IFINDEX_INTERNAL) + if (nh->ifindex == IFINDEX_INTERNAL) continue; - api_nh->ifindex = si->ifindex; + api_nh->ifindex = nh->ifindex; api_nh->type = NEXTHOP_TYPE_IFINDEX; break; case STATIC_IPV4_GATEWAY: - if (!si->nh_valid) + if (!nh->nh_valid) continue; api_nh->type = NEXTHOP_TYPE_IPV4; - api_nh->gate = si->addr; + api_nh->gate = nh->addr; break; case STATIC_IPV4_GATEWAY_IFNAME: - if (si->ifindex == IFINDEX_INTERNAL) + if (nh->ifindex == IFINDEX_INTERNAL) continue; - api_nh->ifindex = si->ifindex; + api_nh->ifindex = nh->ifindex; api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; - api_nh->gate = si->addr; + api_nh->gate = nh->addr; break; case STATIC_IPV6_GATEWAY: - if (!si->nh_valid) + if (!nh->nh_valid) continue; api_nh->type = NEXTHOP_TYPE_IPV6; - api_nh->gate = si->addr; + api_nh->gate = nh->addr; break; case STATIC_IPV6_GATEWAY_IFNAME: - if (si->ifindex == IFINDEX_INTERNAL) + if (nh->ifindex == IFINDEX_INTERNAL) continue; api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; - api_nh->ifindex = si->ifindex; - api_nh->gate = si->addr; + api_nh->ifindex = nh->ifindex; + api_nh->gate = nh->addr; break; case STATIC_BLACKHOLE: api_nh->type = NEXTHOP_TYPE_BLACKHOLE; - switch (si->bh_type) { + switch (nh->bh_type) { case STATIC_BLACKHOLE_DROP: case STATIC_BLACKHOLE_NULL: api_nh->bh_type = BLACKHOLE_NULL; @@ -440,13 +480,13 @@ extern void static_zebra_route_add(struct route_node *rn, break; } - if (si->snh_label.num_labels) { + if (nh->snh_label.num_labels) { int i; SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL); - api_nh->label_num = si->snh_label.num_labels; + api_nh->label_num = nh->snh_label.num_labels; for (i = 0; i < api_nh->label_num; i++) - api_nh->labels[i] = si->snh_label.label[i]; + api_nh->labels[i] = nh->snh_label.label[i]; } nh_num++; } |
