diff options
Diffstat (limited to 'zebra/zebra_mpls.c')
| -rw-r--r-- | zebra/zebra_mpls.c | 71 |
1 files changed, 48 insertions, 23 deletions
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 3333b7226a..decf3f5f8d 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -169,6 +169,7 @@ nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop) struct prefix_ipv4 p; struct route_node *rn; struct rib *match; + struct nexthop *match_nh; table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT); if (!table) @@ -189,17 +190,22 @@ nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop) /* Locate a valid connected route. */ RNODE_FOREACH_RIB (rn, match) { - if ((match->type == ZEBRA_ROUTE_CONNECT) && - !CHECK_FLAG (match->status, RIB_ENTRY_REMOVED) && - CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED)) - break; + if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED) || + !CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED)) + continue; + + for (match_nh = match->nexthop; match_nh; match_nh = match_nh->next) + { + if (match->type == ZEBRA_ROUTE_CONNECT || + nexthop->ifindex == match_nh->ifindex) + { + nexthop->ifindex = match_nh->ifindex; + return 1; + } + } } - if (!match || !match->nexthop) - return 0; - - nexthop->ifindex = match->nexthop->ifindex; - return 1; + return 0; } @@ -268,6 +274,7 @@ nhlfe_nexthop_active (zebra_nhlfe_t *nhlfe) switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: if (nhlfe_nexthop_active_ipv4 (nhlfe, nexthop)) SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); else @@ -577,6 +584,7 @@ nhlfe2str (zebra_nhlfe_t *nhlfe, char *buf, int size) switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: inet_ntop (AF_INET, &nexthop->gate.ipv4, buf, size); break; case NEXTHOP_TYPE_IPV6: @@ -609,8 +617,11 @@ nhlfe_nhop_match (zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype, switch (nhop->type) { case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: cmp = memcmp(&(nhop->gate.ipv4), &(gate->ipv4), sizeof(struct in_addr)); + if (!cmp && nhop->type == NEXTHOP_TYPE_IPV4_IFINDEX) + cmp = !(nhop->ifindex == ifindex); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: @@ -686,7 +697,10 @@ nhlfe_add (zebra_lsp_t *lsp, enum lsp_types_t lsp_type, switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: nexthop->gate.ipv4 = gate->ipv4; + if (ifindex) + nexthop->ifindex = ifindex; break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: @@ -737,6 +751,9 @@ nhlfe_del (zebra_nhlfe_t *nhlfe) else lsp->nhlfe_list = nhlfe->next; + if (nhlfe == lsp->best_nhlfe) + lsp->best_nhlfe = NULL; + XFREE (MTYPE_NHLFE, nhlfe); return 0; @@ -842,6 +859,7 @@ nhlfe_json (zebra_nhlfe_t *nhlfe) switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: json_object_string_add(json_nhlfe, "nexthop", inet_ntoa (nexthop->gate.ipv4)); break; @@ -879,7 +897,10 @@ nhlfe_print (zebra_nhlfe_t *nhlfe, struct vty *vty) switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4)); + if (nexthop->ifindex) + vty_out (vty, " dev %s", ifindex2ifname (nexthop->ifindex)); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: @@ -1258,7 +1279,8 @@ mpls_label2str (u_int8_t num_labels, mpls_label_t *labels, */ int mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type, - struct prefix *prefix, union g_addr *gate, u_int8_t distance, + struct prefix *prefix, enum nexthop_types_t gtype, + union g_addr *gate, ifindex_t ifindex, u_int8_t distance, mpls_label_t out_label) { struct route_table *table; @@ -1285,27 +1307,29 @@ mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type, return -1; for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) - switch (prefix->family) - { - case AF_INET: - if (nexthop->type != NEXTHOP_TYPE_IPV4 && - nexthop->type != NEXTHOP_TYPE_IPV4_IFINDEX) - continue; + { + if (nexthop->type != gtype) + continue; + switch (gtype) + { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: if (! IPV4_ADDR_SAME (&nexthop->gate.ipv4, &gate->ipv4)) continue; - goto found; - break; - case AF_INET6: - if (nexthop->type != NEXTHOP_TYPE_IPV6 && - nexthop->type != NEXTHOP_TYPE_IPV6_IFINDEX) + if (gtype == NEXTHOP_TYPE_IPV4_IFINDEX && nexthop->ifindex != ifindex) continue; + goto found; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: if (! IPV6_ADDR_SAME (&nexthop->gate.ipv6, &gate->ipv6)) continue; + if (gtype == NEXTHOP_TYPE_IPV6_IFINDEX && nexthop->ifindex != ifindex) + continue; goto found; - break; default: break; - } + } + } /* nexthop not found */ return -1; @@ -1811,6 +1835,7 @@ zebra_mpls_print_lsp_table (struct vty *vty, struct zebra_vrf *zvrf, switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: vty_out (vty, "%15s", inet_ntoa (nexthop->gate.ipv4)); break; case NEXTHOP_TYPE_IPV6: |
