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.c101
1 files changed, 92 insertions, 9 deletions
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index a2d1513ce4..c9450541e8 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -752,7 +752,7 @@ static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe)
}
break;
- default:
+ case NEXTHOP_TYPE_BLACKHOLE:
break;
}
@@ -1183,7 +1183,7 @@ static char *nhlfe2str(const zebra_nhlfe_t *nhlfe, char *buf, int size)
break;
case NEXTHOP_TYPE_IFINDEX:
snprintf(buf, size, "Ifindex: %u", nexthop->ifindex);
- default:
+ case NEXTHOP_TYPE_BLACKHOLE:
break;
}
@@ -1224,7 +1224,7 @@ static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
case NEXTHOP_TYPE_IFINDEX:
cmp = !(nhop->ifindex == ifindex);
break;
- default:
+ case NEXTHOP_TYPE_BLACKHOLE:
break;
}
@@ -1294,7 +1294,10 @@ static zebra_nhlfe_t *nhlfe_alloc(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
case NEXTHOP_TYPE_IFINDEX:
nexthop->ifindex = ifindex;
break;
- default:
+ case NEXTHOP_TYPE_BLACKHOLE:
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("%s: invalid: blackhole nexthop", __func__);
+
nexthop_free(nexthop);
XFREE(MTYPE_NHLFE, nhlfe);
return NULL;
@@ -1319,10 +1322,21 @@ static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
if (!lsp)
return NULL;
+ /* Must have labels */
+ if (num_labels == 0 || labels == NULL) {
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("%s: invalid nexthop: no labels", __func__);
+
+ return NULL;
+ }
+
/* Allocate new object */
nhlfe = nhlfe_alloc(lsp, lsp_type, gtype, gate, ifindex, num_labels,
labels);
+ if (!nhlfe)
+ return NULL;
+
/* Enqueue to LSP: primaries at head of list, backups at tail */
if (is_backup) {
SET_FLAG(nhlfe->flags, NHLFE_FLAG_IS_BACKUP);
@@ -1527,7 +1541,13 @@ static json_object *nhlfe_json(zebra_nhlfe_t *nhlfe)
ifindex2ifname(nexthop->ifindex,
nexthop->vrf_id));
break;
- default:
+ case NEXTHOP_TYPE_IFINDEX:
+ if (nexthop->ifindex)
+ json_object_string_add(json_nhlfe, "interface",
+ ifindex2ifname(nexthop->ifindex,
+ nexthop->vrf_id));
+ break;
+ case NEXTHOP_TYPE_BLACKHOLE:
break;
}
@@ -1588,7 +1608,13 @@ static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty,
ifindex2ifname(nexthop->ifindex,
nexthop->vrf_id));
break;
- default:
+ case NEXTHOP_TYPE_IFINDEX:
+ if (nexthop->ifindex)
+ vty_out(vty, " dev %s",
+ ifindex2ifname(nexthop->ifindex,
+ nexthop->vrf_id));
+ break;
+ case NEXTHOP_TYPE_BLACKHOLE:
break;
}
vty_out(vty, "%s",
@@ -2830,8 +2856,21 @@ static bool ftn_update_znh(bool add_p, enum lsp_types_t type,
break;
success = true;
break;
- default:
+ case NEXTHOP_TYPE_IFINDEX:
+ if (znh->type != NEXTHOP_TYPE_IFINDEX)
+ continue;
+ if (nexthop->ifindex != znh->ifindex)
+ continue;
+
+ found = true;
+
+ if (!ftn_update_nexthop(add_p, nexthop, type, znh))
+ break;
+ success = true;
break;
+ case NEXTHOP_TYPE_BLACKHOLE:
+ /* Not valid */
+ continue;
}
if (found)
@@ -3752,7 +3791,7 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
inet_ntop(AF_INET6, &nexthop->gate.ipv6,
nh_buf, sizeof(nh_buf));
break;
- default:
+ case NEXTHOP_TYPE_BLACKHOLE:
break;
}
@@ -3795,7 +3834,11 @@ static char *nhlfe_config_str(const zebra_nhlfe_t *nhlfe, char *buf, int size)
buf[0] = '\0';
switch (nh->type) {
case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
inet_ntop(AF_INET, &nh->gate.ipv4, buf, size);
+ if (nh->ifindex)
+ strlcat(buf, ifindex2ifname(nh->ifindex, VRF_DEFAULT),
+ size);
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -3805,7 +3848,13 @@ static char *nhlfe_config_str(const zebra_nhlfe_t *nhlfe, char *buf, int size)
ifindex2ifname(nh->ifindex, VRF_DEFAULT),
size);
break;
- default:
+ case NEXTHOP_TYPE_IFINDEX:
+ if (nh->ifindex)
+ strlcat(buf,
+ ifindex2ifname(nh->ifindex, VRF_DEFAULT),
+ size);
+ break;
+ case NEXTHOP_TYPE_BLACKHOLE:
break;
}
@@ -3932,6 +3981,40 @@ void zebra_mpls_cleanup_tables(struct zebra_vrf *zvrf)
}
/*
+ * When a vrf label is assigned and the client goes away
+ * we should cleanup the vrf labels associated with
+ * that zclient.
+ */
+void zebra_mpls_client_cleanup_vrf_label(uint8_t proto)
+{
+ struct vrf *vrf;
+ struct zebra_vrf *def_zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
+
+ if (def_zvrf == NULL)
+ return;
+
+ RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
+ struct zebra_vrf *zvrf = vrf->info;
+ afi_t afi;
+
+ if (!zvrf)
+ continue;
+
+ for (afi = AFI_IP; afi < AFI_MAX; afi++) {
+ if (zvrf->label_proto[afi] == proto
+ && zvrf->label[afi] != MPLS_LABEL_NONE)
+ lsp_uninstall(def_zvrf, zvrf->label[afi]);
+
+ /*
+ * Cleanup data structures by fiat
+ */
+ zvrf->label_proto[afi] = 0;
+ zvrf->label[afi] = MPLS_LABEL_NONE;
+ }
+ }
+}
+
+/*
* Called upon process exiting, need to delete LSP forwarding
* entries from the kernel.
* NOTE: Currently supported only for default VRF.