diff options
Diffstat (limited to 'zebra/zserv.c')
| -rw-r--r-- | zebra/zserv.c | 123 |
1 files changed, 98 insertions, 25 deletions
diff --git a/zebra/zserv.c b/zebra/zserv.c index 71437bab15..b3b1fa79e9 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -592,7 +592,6 @@ int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p, memset(&api, 0, sizeof(api)); api.vrf_id = re->vrf_id; - api.nh_vrf_id = re->nh_vrf_id; api.type = re->type; api.instance = re->instance; api.flags = re->flags; @@ -614,6 +613,7 @@ int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p, continue; api_nh = &api.nexthops[count]; + api_nh->vrf_id = nexthop->vrf_id; api_nh->type = nexthop->type; switch (nexthop->type) { case NEXTHOP_TYPE_BLACKHOLE: @@ -1137,7 +1137,6 @@ static int zread_route_add(struct zserv *client, u_short length, re->flags = api.flags; re->uptime = time(NULL); re->vrf_id = vrf_id; - re->nh_vrf_id = api.nh_vrf_id; re->table = zvrf->table_id; if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { @@ -1148,11 +1147,12 @@ static int zread_route_add(struct zserv *client, u_short length, switch (api_nh->type) { case NEXTHOP_TYPE_IFINDEX: nexthop = route_entry_nexthop_ifindex_add( - re, api_nh->ifindex); + re, api_nh->ifindex, re->vrf_id); break; case NEXTHOP_TYPE_IPV4: nexthop = route_entry_nexthop_ipv4_add( - re, &api_nh->gate.ipv4, NULL); + re, &api_nh->gate.ipv4, NULL, + re->vrf_id); break; case NEXTHOP_TYPE_IPV4_IFINDEX: { @@ -1168,8 +1168,8 @@ static int zread_route_add(struct zserv *client, u_short length, } nexthop = route_entry_nexthop_ipv4_ifindex_add( - re, &api_nh->gate.ipv4, NULL, - ifindex); + re, &api_nh->gate.ipv4, NULL, ifindex, + re->vrf_id); /* if this an EVPN route entry, program the nh as neigh @@ -1192,12 +1192,12 @@ static int zread_route_add(struct zserv *client, u_short length, } case NEXTHOP_TYPE_IPV6: nexthop = route_entry_nexthop_ipv6_add( - re, &api_nh->gate.ipv6); + re, &api_nh->gate.ipv6, re->vrf_id); break; case NEXTHOP_TYPE_IPV6_IFINDEX: nexthop = route_entry_nexthop_ipv6_ifindex_add( - re, &api_nh->gate.ipv6, - api_nh->ifindex); + re, &api_nh->gate.ipv6, api_nh->ifindex, + re->vrf_id); break; case NEXTHOP_TYPE_BLACKHOLE: nexthop = route_entry_nexthop_blackhole_add( @@ -1364,7 +1364,6 @@ static int zread_ipv4_add(struct zserv *client, u_short length, /* VRF ID */ re->vrf_id = zvrf_id(zvrf); - re->nh_vrf_id = zvrf_id(zvrf); /* Nexthop parse. */ if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) { @@ -1381,13 +1380,14 @@ static int zread_ipv4_add(struct zserv *client, u_short length, switch (nexthop_type) { case NEXTHOP_TYPE_IFINDEX: STREAM_GETL(s, ifindex); - route_entry_nexthop_ifindex_add(re, ifindex); + route_entry_nexthop_ifindex_add(re, ifindex, + re->vrf_id); break; case NEXTHOP_TYPE_IPV4: STREAM_GET(&nhop_addr.s_addr, s, IPV4_MAX_BYTELEN); nexthop = route_entry_nexthop_ipv4_add( - re, &nhop_addr, NULL); + re, &nhop_addr, NULL, re->vrf_id); /* For labeled-unicast, each nexthop is followed * by label. */ if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) { @@ -1401,7 +1401,8 @@ static int zread_ipv4_add(struct zserv *client, u_short length, IPV4_MAX_BYTELEN); STREAM_GETL(s, ifindex); route_entry_nexthop_ipv4_ifindex_add( - re, &nhop_addr, NULL, ifindex); + re, &nhop_addr, NULL, ifindex, + re->vrf_id); break; case NEXTHOP_TYPE_IPV6: zlog_warn("%s: Please use ZEBRA_ROUTE_ADD if you want to pass v6 nexthops", @@ -1574,7 +1575,6 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, /* VRF ID */ re->vrf_id = zvrf_id(zvrf); - re->nh_vrf_id = zvrf_id(zvrf); /* We need to give nh-addr, nh-ifindex with the same next-hop object * to the re to ensure that IPv6 multipathing works; need to coalesce @@ -1635,10 +1635,11 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, nexthop = route_entry_nexthop_ipv6_ifindex_add( re, &nexthops[i], - ifindices[i]); + ifindices[i], + re->vrf_id); else nexthop = route_entry_nexthop_ipv6_add( - re, &nexthops[i]); + re, &nexthops[i], re->vrf_id); if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) nexthop_add_labels(nexthop, label_type, @@ -1646,7 +1647,7 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, } else { if ((i < if_count) && ifindices[i]) route_entry_nexthop_ifindex_add( - re, ifindices[i]); + re, ifindices[i], re->vrf_id); } } } @@ -1760,6 +1761,9 @@ static int zread_ipv6_add(struct zserv *client, u_short length, } else src_pp = NULL; + /* VRF ID */ + re->vrf_id = zvrf_id(zvrf); + /* We need to give nh-addr, nh-ifindex with the same next-hop object * to the re to ensure that IPv6 multipathing works; need to coalesce * these. Clients should send the same number of paired set of @@ -1797,7 +1801,7 @@ static int zread_ipv6_add(struct zserv *client, u_short length, STREAM_GET(&nhop_addr, s, 16); STREAM_GETL(s, ifindex); route_entry_nexthop_ipv6_ifindex_add( - re, &nhop_addr, ifindex); + re, &nhop_addr, ifindex, re->vrf_id); break; case NEXTHOP_TYPE_IFINDEX: if (if_count < multipath_num) { @@ -1824,17 +1828,18 @@ static int zread_ipv6_add(struct zserv *client, u_short length, nexthop = route_entry_nexthop_ipv6_ifindex_add( re, &nexthops[i], - ifindices[i]); + ifindices[i], + re->vrf_id); else nexthop = route_entry_nexthop_ipv6_add( - re, &nexthops[i]); + re, &nexthops[i], re->vrf_id); if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) nexthop_add_labels(nexthop, label_type, 1, &labels[i]); } else { if ((i < if_count) && ifindices[i]) route_entry_nexthop_ifindex_add( - re, ifindices[i]); + re, ifindices[i], re->vrf_id); } } } @@ -1858,10 +1863,6 @@ static int zread_ipv6_add(struct zserv *client, u_short length, else re->mtu = 0; - /* VRF ID */ - re->vrf_id = zvrf_id(zvrf); - re->nh_vrf_id = zvrf_id(zvrf); - re->table = zvrf->table_id; ret = rib_add_multipath(AFI_IP6, safi, &p, src_pp, re); @@ -2485,6 +2486,75 @@ stream_failure: return 1; } + +static void zread_vrf_label(struct zserv *client, + struct zebra_vrf *zvrf) +{ + struct interface *ifp; + mpls_label_t nlabel; + afi_t afi; + struct stream *s; + struct zebra_vrf *def_zvrf; + enum lsp_types_t ltype; + + s = client->ibuf; + STREAM_GETL(s, nlabel); + STREAM_GETC(s, afi); + if (nlabel == zvrf->label[afi]) { + /* + * Nothing to do here move along + */ + return; + } + + STREAM_GETC(s, ltype); + + if (zvrf->vrf->vrf_id != VRF_DEFAULT) + ifp = if_lookup_by_name(zvrf->vrf->name, zvrf->vrf->vrf_id); + else + ifp = if_lookup_by_name("lo", VRF_DEFAULT); + + if (!ifp) { + zlog_debug("Unable to find specified Interface for %s", + zvrf->vrf->name); + return; + } + + def_zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); + + if (zvrf->label[afi] != MPLS_LABEL_NONE) { + afi_t scrubber; + bool really_remove; + + really_remove = true; + for (scrubber = AFI_IP; scrubber < AFI_MAX ; scrubber++) { + if (scrubber == afi) + continue; + + if (zvrf->label[scrubber] == MPLS_LABEL_NONE) + continue; + + if (zvrf->label[afi] == zvrf->label[scrubber]) { + really_remove = false; + break; + } + } + + if (really_remove) + mpls_lsp_uninstall(def_zvrf, ltype, zvrf->label[afi], + NEXTHOP_TYPE_IFINDEX, NULL, + ifp->ifindex); + } + + if (nlabel != MPLS_LABEL_NONE) + mpls_lsp_install(def_zvrf, ltype, nlabel, MPLS_LABEL_IMPLICIT_NULL, + NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); + + zvrf->label[afi] = nlabel; +stream_failure: + return; +} + static inline void zserv_handle_commands(struct zserv *client, uint16_t command, uint16_t length, @@ -2569,6 +2639,9 @@ static inline void zserv_handle_commands(struct zserv *client, case ZEBRA_VRF_UNREGISTER: zread_vrf_unregister(client, length, zvrf); break; + case ZEBRA_VRF_LABEL: + zread_vrf_label(client, zvrf); + break; case ZEBRA_BFD_CLIENT_REGISTER: zebra_ptm_bfd_client_register(client, length); break; |
