summaryrefslogtreecommitdiff
path: root/zebra/zebra_mpls.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_mpls.c')
-rw-r--r--zebra/zebra_mpls.c71
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: