summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
authorMartin Winter <mwinter@opensourcerouting.org>2018-02-14 04:05:42 +0100
committerGitHub <noreply@github.com>2018-02-14 04:05:42 +0100
commit74a75bdbadab86341c239dff5d33fad530754247 (patch)
tree03af0658c91e4dff6efed65bd20886adf3d1910f /zebra
parentMerge pull request #1734 from donaldsharp/control_me (diff)
parentzebra: Use appropriate output function for label printing (diff)
downloadfrr-74a75bdbadab86341c239dff5d33fad530754247.tar.xz
frr-74a75bdbadab86341c239dff5d33fad530754247.zip
Merge pull request #1701 from donaldsharp/zapi_vrf_label
Zapi vrf label
Diffstat (limited to 'zebra')
-rw-r--r--zebra/connected.c18
-rw-r--r--zebra/kernel_socket.c8
-rw-r--r--zebra/label_manager.c4
-rw-r--r--zebra/rib.h20
-rw-r--r--zebra/rt_netlink.c42
-rw-r--r--zebra/rtread_getmsg.c6
-rw-r--r--zebra/zebra_mpls.c82
-rw-r--r--zebra/zebra_mpls.h37
-rw-r--r--zebra/zebra_mpls_vty.c14
-rw-r--r--zebra/zebra_rib.c50
-rw-r--r--zebra/zebra_rnh.c3
-rw-r--r--zebra/zebra_rnh.h9
-rw-r--r--zebra/zebra_routemap.c2
-rw-r--r--zebra/zebra_static.c31
-rw-r--r--zebra/zebra_vrf.h3
-rw-r--r--zebra/zebra_vty.c47
-rw-r--r--zebra/zserv.c99
17 files changed, 323 insertions, 152 deletions
diff --git a/zebra/connected.c b/zebra/connected.c
index d34fd9021..e28ec8d09 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -203,7 +203,9 @@ void connected_up(struct interface *ifp, struct connected *ifc)
afi_t afi;
struct prefix p;
struct nexthop nh = {
- .type = NEXTHOP_TYPE_IFINDEX, .ifindex = ifp->ifindex,
+ .type = NEXTHOP_TYPE_IFINDEX,
+ .ifindex = ifp->ifindex,
+ .vrf_id = ifp->vrf_id,
};
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
@@ -238,13 +240,11 @@ void connected_up(struct interface *ifp, struct connected *ifc)
break;
}
- rib_add(afi, SAFI_UNICAST, ifp->vrf_id, ifp->vrf_id,
- ZEBRA_ROUTE_CONNECT, 0, 0,
- &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0);
+ rib_add(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, &p,
+ NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0);
- rib_add(afi, SAFI_MULTICAST, ifp->vrf_id, ifp->vrf_id,
- ZEBRA_ROUTE_CONNECT, 0, 0,
- &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0);
+ rib_add(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, &p,
+ NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0);
if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
char buf[PREFIX_STRLEN];
@@ -362,7 +362,9 @@ void connected_down(struct interface *ifp, struct connected *ifc)
afi_t afi;
struct prefix p;
struct nexthop nh = {
- .type = NEXTHOP_TYPE_IFINDEX, .ifindex = ifp->ifindex,
+ .type = NEXTHOP_TYPE_IFINDEX,
+ .ifindex = ifp->ifindex,
+ .vrf_id = ifp->vrf_id,
};
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index 2a3b95058..4d888d806 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -907,6 +907,8 @@ void rtm_read(struct rt_msghdr *rtm)
SET_FLAG(zebra_flags, ZEBRA_FLAG_STATIC);
memset(&nh, 0, sizeof(nh));
+
+ nh.vrf_id = VRF_DEFAULT;
/* This is a reject or blackhole route */
if (flags & RTF_REJECT) {
nh.type = NEXTHOP_TYPE_BLACKHOLE;
@@ -1049,7 +1051,7 @@ void rtm_read(struct rt_msghdr *rtm)
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|| rtm->rtm_type == RTM_CHANGE)
- rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, VRF_DEFAULT,
+ rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
&nh, 0, 0, 0, 0, 0);
else
@@ -1097,7 +1099,7 @@ void rtm_read(struct rt_msghdr *rtm)
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|| rtm->rtm_type == RTM_CHANGE)
- rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, VRF_DEFAULT,
+ rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
&nh, 0, 0, 0, 0, 0);
else
@@ -1195,7 +1197,7 @@ int rtm_write(int message, union sockunion *dest, union sockunion *mask,
msg.rtm.rtm_flags |= RTF_MPLS;
if (mpls->smpls.smpls_label
- != htonl(MPLS_IMP_NULL_LABEL << MPLS_LABEL_OFFSET))
+ != htonl(MPLS_LABEL_IMPLICIT_NULL << MPLS_LABEL_OFFSET))
msg.rtm.rtm_mpls = MPLS_OP_PUSH;
}
#endif
diff --git a/zebra/label_manager.c b/zebra/label_manager.c
index ace13eda7..5bf0fce09 100644
--- a/zebra/label_manager.c
+++ b/zebra/label_manager.c
@@ -283,13 +283,13 @@ struct label_manager_chunk *assign_label_chunk(u_char proto, u_short instance,
return NULL;
if (list_isempty(lbl_mgr.lc_list))
- lmc->start = MPLS_MIN_UNRESERVED_LABEL;
+ lmc->start = MPLS_LABEL_UNRESERVED_MIN;
else
lmc->start = ((struct label_manager_chunk *)listgetdata(
listtail(lbl_mgr.lc_list)))
->end
+ 1;
- if (lmc->start > MPLS_MAX_UNRESERVED_LABEL - size + 1) {
+ if (lmc->start > MPLS_LABEL_UNRESERVED_MAX - size + 1) {
zlog_err("Reached max labels. Start: %u, size: %u", lmc->start,
size);
XFREE(MTYPE_LM_CHUNK, lmc);
diff --git a/zebra/rib.h b/zebra/rib.h
index 664afd01b..9a5d88ed1 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -59,7 +59,6 @@ struct route_entry {
/* VRF identifier. */
vrf_id_t vrf_id;
- vrf_id_t nh_vrf_id;
/* Which routing table */
uint32_t table;
@@ -231,22 +230,27 @@ typedef enum {
} rib_update_event_t;
extern struct nexthop *route_entry_nexthop_ifindex_add(struct route_entry *,
- ifindex_t);
+ ifindex_t,
+ vrf_id_t nh_vrf_id);
extern struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *,
enum blackhole_type);
extern struct nexthop *route_entry_nexthop_ipv4_add(struct route_entry *,
struct in_addr *,
- struct in_addr *);
+ struct in_addr *,
+ vrf_id_t nh_vrf_id);
extern struct nexthop *
route_entry_nexthop_ipv4_ifindex_add(struct route_entry *, struct in_addr *,
- struct in_addr *, ifindex_t);
+ struct in_addr *, ifindex_t,
+ vrf_id_t nh_vrf_id);
extern void route_entry_nexthop_delete(struct route_entry *re,
struct nexthop *nexthop);
extern struct nexthop *route_entry_nexthop_ipv6_add(struct route_entry *,
- struct in6_addr *);
+ struct in6_addr *,
+ vrf_id_t nh_vrf_id);
extern struct nexthop *
route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re,
- struct in6_addr *ipv6, ifindex_t ifindex);
+ struct in6_addr *ipv6, ifindex_t ifindex,
+ vrf_id_t nh_vrf_id);
extern void route_entry_nexthop_add(struct route_entry *re,
struct nexthop *nexthop);
extern void route_entry_copy_nexthops(struct route_entry *re,
@@ -294,8 +298,8 @@ extern void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re);
/* NOTE:
* All rib_add function will not just add prefix into RIB, but
* also implicitly withdraw equal prefix of same type. */
-extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, vrf_id_t nh_vrf_id,
- int type, u_short instance, int flags, struct prefix *p,
+extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
+ u_short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, const struct nexthop *nh,
u_int32_t table_id, u_int32_t metric, u_int32_t mtu,
uint8_t distance, route_tag_t tag);
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 20cc292e1..d77899014 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -443,10 +443,10 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
if (ifp)
nh_vrf_id = ifp->vrf_id;
}
+ nh.vrf_id = nh_vrf_id;
- rib_add(afi, SAFI_UNICAST, vrf_id, nh_vrf_id, proto,
- 0, flags, &p, NULL, &nh, table, metric,
- mtu, distance, tag);
+ rib_add(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, &p,
+ NULL, &nh, table, metric, mtu, distance, tag);
} else {
/* This is a multipath route */
@@ -463,13 +463,13 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
re->metric = metric;
re->mtu = mtu;
re->vrf_id = vrf_id;
- re->nh_vrf_id = vrf_id;
re->table = table;
re->nexthop_num = 0;
re->uptime = time(NULL);
re->tag = tag;
for (;;) {
+ vrf_id_t nh_vrf_id;
if (len < (int)sizeof(*rtnh)
|| rtnh->rtnh_len > len)
break;
@@ -485,8 +485,17 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
ifp = if_lookup_by_index(index,
VRF_UNKNOWN);
if (ifp)
- re->nh_vrf_id = ifp->vrf_id;
- }
+ nh_vrf_id = ifp->vrf_id;
+ else {
+ zlog_warn(
+ "%s: Unknown interface %u specified, defaulting to VRF_DEFAULT",
+ __PRETTY_FUNCTION__,
+ index);
+ nh_vrf_id = VRF_DEFAULT;
+ }
+ } else
+ nh_vrf_id = vrf_id;
+
gate = 0;
if (rtnh->rtnh_len > sizeof(*rtnh)) {
memset(tb, 0, sizeof(tb));
@@ -503,24 +512,27 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
if (index)
route_entry_nexthop_ipv4_ifindex_add(
re, gate,
- prefsrc, index);
+ prefsrc, index,
+ nh_vrf_id);
else
route_entry_nexthop_ipv4_add(
re, gate,
- prefsrc);
+ prefsrc,
+ nh_vrf_id);
} else if (rtm->rtm_family
== AF_INET6) {
if (index)
route_entry_nexthop_ipv6_ifindex_add(
- re, gate,
- index);
+ re, gate, index,
+ nh_vrf_id);
else
route_entry_nexthop_ipv6_add(
- re, gate);
+ re, gate,
+ nh_vrf_id);
}
} else
- route_entry_nexthop_ifindex_add(re,
- index);
+ route_entry_nexthop_ifindex_add(
+ re, index, nh_vrf_id);
len -= NLMSG_ALIGN(rtnh->rtnh_len);
rtnh = RTNH_NEXT(rtnh);
@@ -852,7 +864,7 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
char label_buf1[20];
for (i = 0; i < nh_label->num_labels; i++) {
- if (nh_label->label[i] != MPLS_IMP_NULL_LABEL) {
+ if (nh_label->label[i] != MPLS_LABEL_IMPLICIT_NULL) {
bos = ((i == (nh_label->num_labels - 1)) ? 1
: 0);
out_lse[i] = mpls_lse_encode(nh_label->label[i],
@@ -1062,7 +1074,7 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
char label_buf1[20];
for (i = 0; i < nh_label->num_labels; i++) {
- if (nh_label->label[i] != MPLS_IMP_NULL_LABEL) {
+ if (nh_label->label[i] != MPLS_LABEL_IMPLICIT_NULL) {
bos = ((i == (nh_label->num_labels - 1)) ? 1
: 0);
out_lse[i] = mpls_lse_encode(nh_label->label[i],
diff --git a/zebra/rtread_getmsg.c b/zebra/rtread_getmsg.c
index ba45f54ad..95bc8db1c 100644
--- a/zebra/rtread_getmsg.c
+++ b/zebra/rtread_getmsg.c
@@ -94,12 +94,12 @@ static void handle_route_entry(mib2_ipRouteEntry_t *routeEntry)
prefix.prefixlen = ip_masklen(tmpaddr);
memset(&nh, 0, sizeof(nh));
+ nh.vrf_id = VRF_DEFAULT;
nh.type = NEXTHOP_TYPE_IPV4;
nh.gate.ipv4.s_addr = routeEntry->ipRouteNextHop;
- rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, VRF_DEFAULT,
- ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &prefix, NULL,
- &nh, 0, 0, 0, 0, 0);
+ rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0,
+ zebra_flags, &prefix, NULL, &nh, 0, 0, 0, 0, 0);
}
void route_read(struct zebra_ns *zns)
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index 22c81b578..ec80081a4 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -411,12 +411,13 @@ static int fec_change_update_lsp(struct zebra_vrf *zvrf, zebra_fec_t *fec,
afi_t afi;
/* Uninstall label forwarding entry, if previously installed. */
- if (old_label != MPLS_INVALID_LABEL && old_label != MPLS_IMP_NULL_LABEL)
+ if (old_label != MPLS_INVALID_LABEL &&
+ old_label != MPLS_LABEL_IMPLICIT_NULL)
lsp_uninstall(zvrf, old_label);
/* Install label forwarding entry corr. to new label, if needed. */
if (fec->label == MPLS_INVALID_LABEL
- || fec->label == MPLS_IMP_NULL_LABEL)
+ || fec->label == MPLS_LABEL_IMPLICIT_NULL)
return 0;
afi = family2afi(PREFIX_FAMILY(&fec->rn->p));
@@ -614,7 +615,7 @@ static int nhlfe_nexthop_active_ipv4(zebra_nhlfe_t *nhlfe,
struct route_entry *match;
struct nexthop *match_nh;
- table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
+ table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, nexthop->vrf_id);
if (!table)
return 0;
@@ -663,7 +664,7 @@ static int nhlfe_nexthop_active_ipv6(zebra_nhlfe_t *nhlfe,
struct route_node *rn;
struct route_entry *match;
- table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
+ table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, nexthop->vrf_id);
if (!table)
return 0;
@@ -711,6 +712,22 @@ static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe)
/* Check on nexthop based on type. */
switch (nexthop->type) {
+ case NEXTHOP_TYPE_IFINDEX:
+ /*
+ * Lookup if this type is special. The
+ * NEXTHOP_TYPE_IFINDEX is a pop and
+ * forward into a different table for
+ * processing. As such this ifindex
+ * passed to us may be a VRF device
+ * which will not be in the default
+ * VRF. So let's look in all of them
+ */
+ ifp = if_lookup_by_index(nexthop->ifindex, VRF_UNKNOWN);
+ if (ifp && if_is_operative(ifp))
+ SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+ else
+ UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+ break;
case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV4_IFINDEX:
if (nhlfe_nexthop_active_ipv4(nhlfe, nexthop))
@@ -728,7 +745,8 @@ static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe)
case NEXTHOP_TYPE_IPV6_IFINDEX:
if (IN6_IS_ADDR_LINKLOCAL(&nexthop->gate.ipv6)) {
- ifp = if_lookup_by_index(nexthop->ifindex, VRF_DEFAULT);
+ ifp = if_lookup_by_index(nexthop->ifindex,
+ nexthop->vrf_id);
if (ifp && if_is_operative(ifp))
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else
@@ -1052,6 +1070,8 @@ static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size)
case NEXTHOP_TYPE_IPV6:
inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, size);
break;
+ case NEXTHOP_TYPE_IFINDEX:
+ snprintf(buf, size, "Ifindex: %u", nexthop->ifindex);
default:
break;
}
@@ -1090,6 +1110,9 @@ static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
if (!cmp && nhop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
cmp = !(nhop->ifindex == ifindex);
break;
+ case NEXTHOP_TYPE_IFINDEX:
+ cmp = !(nhop->ifindex == ifindex);
+ break;
default:
break;
}
@@ -1149,6 +1172,7 @@ static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
}
nexthop_add_labels(nexthop, lsp_type, 1, &out_label);
+ nexthop->vrf_id = VRF_DEFAULT;
nexthop->type = gtype;
switch (nexthop->type) {
case NEXTHOP_TYPE_IPV4:
@@ -1163,6 +1187,9 @@ static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
if (ifindex)
nexthop->ifindex = ifindex;
break;
+ case NEXTHOP_TYPE_IFINDEX:
+ nexthop->ifindex = ifindex;
+ break;
default:
nexthop_free(nexthop);
XFREE(MTYPE_NHLFE, nhlfe);
@@ -1324,9 +1351,9 @@ static json_object *nhlfe_json(zebra_nhlfe_t *nhlfe)
inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
if (nexthop->ifindex)
- json_object_string_add(
- json_nhlfe, "interface",
- ifindex2ifname(nexthop->ifindex, VRF_DEFAULT));
+ json_object_string_add(json_nhlfe, "interface",
+ ifindex2ifname(nexthop->ifindex,
+ nexthop->vrf_id));
break;
default:
break;
@@ -1356,7 +1383,8 @@ static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty)
vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4));
if (nexthop->ifindex)
vty_out(vty, " dev %s",
- ifindex2ifname(nexthop->ifindex, VRF_DEFAULT));
+ ifindex2ifname(nexthop->ifindex,
+ nexthop->vrf_id));
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -1364,7 +1392,8 @@ static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty)
inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
if (nexthop->ifindex)
vty_out(vty, " dev %s",
- ifindex2ifname(nexthop->ifindex, VRF_DEFAULT));
+ ifindex2ifname(nexthop->ifindex,
+ nexthop->vrf_id));
break;
default:
break;
@@ -1793,7 +1822,7 @@ int zebra_mpls_lsp_install(struct zebra_vrf *zvrf, struct route_node *rn,
/* We cannot install a label forwarding entry if local label is the
* implicit-null label.
*/
- if (fec->label == MPLS_IMP_NULL_LABEL)
+ if (fec->label == MPLS_LABEL_IMPLICIT_NULL)
return 0;
if (lsp_install(zvrf, fec->label, rn, re))
@@ -2537,8 +2566,8 @@ int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf,
int cur_op, new_op;
cur_op = (slsp->snhlfe_list->out_label
- == MPLS_IMP_NULL_LABEL);
- new_op = (out_label == MPLS_IMP_NULL_LABEL);
+ == MPLS_LABEL_IMPLICIT_NULL);
+ new_op = (out_label == MPLS_LABEL_IMPLICIT_NULL);
if (cur_op != new_op)
return 0;
}
@@ -2764,6 +2793,15 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
nexthop = nhlfe->nexthop;
switch (nexthop->type) {
+ case NEXTHOP_TYPE_IFINDEX:
+ {
+ struct interface *ifp;
+
+ ifp = if_lookup_by_index(
+ nexthop->ifindex, VRF_UNKNOWN);
+ vty_out(vty, "%15s", ifp->name);
+ break;
+ }
case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV4_IFINDEX:
vty_out(vty, "%15s",
@@ -2780,8 +2818,16 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
break;
}
- vty_out(vty, " %8d\n",
- nexthop->nh_label->label[0]);
+ if (nexthop->type != NEXTHOP_TYPE_IFINDEX)
+ vty_out(vty, " %8s\n",
+ mpls_label2str(
+ nexthop->nh_label
+ ->num_labels,
+ &nexthop->nh_label
+ ->label[0],
+ buf, BUFSIZ, 1));
+ else
+ vty_out(vty, "\n");
}
}
@@ -2810,11 +2856,11 @@ int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf)
snhlfe2str(snhlfe, buf, sizeof(buf));
switch (snhlfe->out_label) {
- case MPLS_V4_EXP_NULL_LABEL:
- case MPLS_V6_EXP_NULL_LABEL:
+ case MPLS_LABEL_IPV4_EXPLICIT_NULL:
+ case MPLS_LABEL_IPV6_EXPLICIT_NULL:
strlcpy(lstr, "explicit-null", sizeof(lstr));
break;
- case MPLS_IMP_NULL_LABEL:
+ case MPLS_LABEL_IMPLICIT_NULL:
strlcpy(lstr, "implicit-null", sizeof(lstr));
break;
default:
diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h
index 27a497169..fd14b29ca 100644
--- a/zebra/zebra_mpls.h
+++ b/zebra/zebra_mpls.h
@@ -428,9 +428,19 @@ static inline u_char lsp_distance(enum lsp_types_t type)
return (route_distance(ZEBRA_ROUTE_LDP));
case ZEBRA_LSP_BGP:
return (route_distance(ZEBRA_ROUTE_BGP));
- default:
+ case ZEBRA_LSP_NONE:
+ case ZEBRA_LSP_SHARP:
+ case ZEBRA_LSP_SR:
return 150;
}
+
+ /*
+ * For some reason certain compilers do not believe
+ * that all the cases have been handled. And
+ * WTF does this work differently than when I removed
+ * the default case????
+ */
+ return 150;
}
/*
@@ -444,6 +454,8 @@ static inline enum lsp_types_t lsp_type_from_re_type(int re_type)
return ZEBRA_LSP_STATIC;
case ZEBRA_ROUTE_BGP:
return ZEBRA_LSP_BGP;
+ case ZEBRA_ROUTE_SHARP:
+ return ZEBRA_LSP_SHARP;
default:
return ZEBRA_LSP_NONE;
}
@@ -464,9 +476,18 @@ static inline int re_type_from_lsp_type(enum lsp_types_t lsp_type)
case ZEBRA_LSP_SR:
return ZEBRA_ROUTE_OSPF;
case ZEBRA_LSP_NONE:
- default:
return ZEBRA_ROUTE_KERNEL;
+ case ZEBRA_LSP_SHARP:
+ return ZEBRA_ROUTE_SHARP;
}
+
+ /*
+ * For some reason certain compilers do not believe
+ * that all the cases have been handled. And
+ * WTF does this work differently than when I removed
+ * the default case????
+ */
+ return ZEBRA_ROUTE_KERNEL;
}
/* NHLFE type as printable string. */
@@ -481,9 +502,19 @@ static inline const char *nhlfe_type2str(enum lsp_types_t lsp_type)
return "BGP";
case ZEBRA_LSP_SR:
return "SR";
- default:
+ case ZEBRA_LSP_SHARP:
+ return "SHARP";
+ case ZEBRA_LSP_NONE:
return "Unknown";
}
+
+ /*
+ * For some reason certain compilers do not believe
+ * that all the cases have been handled. And
+ * WTF does this work differently than when I removed
+ * the default case????
+ */
+ return "Unknown";
}
static inline void mpls_mark_lsps_for_processing(struct zebra_vrf *zvrf)
diff --git a/zebra/zebra_mpls_vty.c b/zebra/zebra_mpls_vty.c
index 9d100bb7d..0d922830c 100644
--- a/zebra/zebra_mpls_vty.c
+++ b/zebra/zebra_mpls_vty.c
@@ -68,7 +68,7 @@ static int zebra_mpls_transit_lsp(struct vty *vty, int add_cmd,
return CMD_WARNING_CONFIG_FAILED;
}
- out_label = MPLS_IMP_NULL_LABEL; /* as initialization */
+ out_label = MPLS_LABEL_IMPLICIT_NULL; /* as initialization */
label = atoi(inlabel_str);
if (!IS_MPLS_UNRESERVED_LABEL(label)) {
vty_out(vty, "%% Invalid label\n");
@@ -107,11 +107,11 @@ static int zebra_mpls_transit_lsp(struct vty *vty, int add_cmd,
if (outlabel_str) {
if (outlabel_str[0] == 'i')
- out_label = MPLS_IMP_NULL_LABEL;
+ out_label = MPLS_LABEL_IMPLICIT_NULL;
else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV4)
- out_label = MPLS_V4_EXP_NULL_LABEL;
+ out_label = MPLS_LABEL_IPV4_EXPLICIT_NULL;
else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV6)
- out_label = MPLS_V6_EXP_NULL_LABEL;
+ out_label = MPLS_LABEL_IPV6_EXPLICIT_NULL;
else
out_label = atoi(outlabel_str);
}
@@ -221,12 +221,12 @@ static int zebra_mpls_bind(struct vty *vty, int add_cmd, const char *prefix,
}
if (!strcmp(label_str, "implicit-null"))
- label = MPLS_IMP_NULL_LABEL;
+ label = MPLS_LABEL_IMPLICIT_NULL;
else if (!strcmp(label_str, "explicit-null")) {
if (p.family == AF_INET)
- label = MPLS_V4_EXP_NULL_LABEL;
+ label = MPLS_LABEL_IPV4_EXPLICIT_NULL;
else
- label = MPLS_V6_EXP_NULL_LABEL;
+ label = MPLS_LABEL_IPV6_EXPLICIT_NULL;
} else {
label = atoi(label_str);
if (!IS_MPLS_UNRESERVED_LABEL(label)) {
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 39c3d0fad..967bc9285 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -213,13 +213,15 @@ void route_entry_nexthop_delete(struct route_entry *re, struct nexthop *nexthop)
struct nexthop *route_entry_nexthop_ifindex_add(struct route_entry *re,
- ifindex_t ifindex)
+ ifindex_t ifindex,
+ vrf_id_t nh_vrf_id)
{
struct nexthop *nexthop;
nexthop = nexthop_new();
nexthop->type = NEXTHOP_TYPE_IFINDEX;
nexthop->ifindex = ifindex;
+ nexthop->vrf_id = nh_vrf_id;
route_entry_nexthop_add(re, nexthop);
@@ -228,12 +230,14 @@ struct nexthop *route_entry_nexthop_ifindex_add(struct route_entry *re,
struct nexthop *route_entry_nexthop_ipv4_add(struct route_entry *re,
struct in_addr *ipv4,
- struct in_addr *src)
+ struct in_addr *src,
+ vrf_id_t nh_vrf_id)
{
struct nexthop *nexthop;
nexthop = nexthop_new();
nexthop->type = NEXTHOP_TYPE_IPV4;
+ nexthop->vrf_id = nh_vrf_id;
nexthop->gate.ipv4 = *ipv4;
if (src)
nexthop->src.ipv4 = *src;
@@ -246,18 +250,20 @@ struct nexthop *route_entry_nexthop_ipv4_add(struct route_entry *re,
struct nexthop *route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re,
struct in_addr *ipv4,
struct in_addr *src,
- ifindex_t ifindex)
+ ifindex_t ifindex,
+ vrf_id_t nh_vrf_id)
{
struct nexthop *nexthop;
struct interface *ifp;
nexthop = nexthop_new();
+ nexthop->vrf_id = nh_vrf_id;
nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
nexthop->gate.ipv4 = *ipv4;
if (src)
nexthop->src.ipv4 = *src;
nexthop->ifindex = ifindex;
- ifp = if_lookup_by_index(nexthop->ifindex, re->nh_vrf_id);
+ ifp = if_lookup_by_index(nexthop->ifindex, nh_vrf_id);
/*Pending: need to think if null ifp here is ok during bootup?
There was a crash because ifp here was coming to be NULL */
if (ifp)
@@ -272,11 +278,13 @@ struct nexthop *route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re,
}
struct nexthop *route_entry_nexthop_ipv6_add(struct route_entry *re,
- struct in6_addr *ipv6)
+ struct in6_addr *ipv6,
+ vrf_id_t nh_vrf_id)
{
struct nexthop *nexthop;
nexthop = nexthop_new();
+ nexthop->vrf_id = nh_vrf_id;
nexthop->type = NEXTHOP_TYPE_IPV6;
nexthop->gate.ipv6 = *ipv6;
@@ -287,11 +295,13 @@ struct nexthop *route_entry_nexthop_ipv6_add(struct route_entry *re,
struct nexthop *route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re,
struct in6_addr *ipv6,
- ifindex_t ifindex)
+ ifindex_t ifindex,
+ vrf_id_t nh_vrf_id)
{
struct nexthop *nexthop;
nexthop = nexthop_new();
+ nexthop->vrf_id = nh_vrf_id;
nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
nexthop->gate.ipv6 = *ipv6;
nexthop->ifindex = ifindex;
@@ -307,6 +317,7 @@ struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *re,
struct nexthop *nexthop;
nexthop = nexthop_new();
+ nexthop->vrf_id = VRF_DEFAULT;
nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
nexthop->bh_type = bh_type;
@@ -323,6 +334,7 @@ static void nexthop_set_resolved(afi_t afi, struct nexthop *newhop,
resolved_hop = nexthop_new();
SET_FLAG(resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
+ resolved_hop->vrf_id = nexthop->vrf_id;
switch (newhop->type) {
case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV4_IFINDEX:
@@ -404,7 +416,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
if (set) {
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
- zebra_deregister_rnh_static_nexthops(re->nh_vrf_id,
+ zebra_deregister_rnh_static_nexthops(nexthop->vrf_id,
nexthop->resolved, top);
nexthops_free(nexthop->resolved);
nexthop->resolved = NULL;
@@ -423,7 +435,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
* address in the routing table.
*/
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) {
- ifp = if_lookup_by_index(nexthop->ifindex, re->nh_vrf_id);
+ ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id);
if (ifp && connected_is_unnumbered(ifp)) {
if (if_is_operative(ifp))
return 1;
@@ -451,7 +463,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
break;
}
/* Lookup table. */
- table = zebra_vrf_table(afi, SAFI_UNICAST, re->nh_vrf_id);
+ table = zebra_vrf_table(afi, SAFI_UNICAST, nexthop->vrf_id);
if (!table)
return 0;
@@ -473,7 +485,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
/* However, do not resolve over default route unless explicitly
* allowed. */
if (is_default_prefix(&rn->p)
- && !nh_resolve_via_default(p.family))
+ && !rnh_resolve_via_default(p.family))
return 0;
dest = rib_dest_from_rnode(rn);
@@ -839,7 +851,7 @@ static unsigned nexthop_active_check(struct route_node *rn,
family = 0;
switch (nexthop->type) {
case NEXTHOP_TYPE_IFINDEX:
- ifp = if_lookup_by_index(nexthop->ifindex, re->nh_vrf_id);
+ ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id);
if (ifp && if_is_operative(ifp))
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else
@@ -868,7 +880,7 @@ static unsigned nexthop_active_check(struct route_node *rn,
family = AFI_IP6;
if (IN6_IS_ADDR_LINKLOCAL(&nexthop->gate.ipv6)) {
ifp = if_lookup_by_index(nexthop->ifindex,
- re->nh_vrf_id);
+ nexthop->vrf_id);
if (ifp && if_is_operative(ifp))
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else
@@ -911,8 +923,8 @@ static unsigned nexthop_active_check(struct route_node *rn,
memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr));
/* It'll get set if required inside */
- ret = zebra_route_map_check(family, re->type, p, nexthop, re->nh_vrf_id,
- re->tag);
+ ret = zebra_route_map_check(family, re->type, p, nexthop,
+ nexthop->vrf_id, re->tag);
if (ret == RMAP_DENYMATCH) {
if (IS_ZEBRA_DEBUG_RIB) {
srcdest_rnode2str(rn, buf, sizeof(buf));
@@ -920,7 +932,7 @@ static unsigned nexthop_active_check(struct route_node *rn,
"%u:%s: Filtering out with NH out %s due to route map",
re->vrf_id, buf,
ifindex2ifname(nexthop->ifindex,
- re->nh_vrf_id));
+ nexthop->vrf_id));
}
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
}
@@ -2555,10 +2567,9 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
}
-int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, vrf_id_t nh_vrf_id,
- int type, u_short instance, int flags, struct prefix *p,
- struct prefix_ipv6 *src_p, const struct nexthop *nh,
- u_int32_t table_id, u_int32_t metric,
+int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
+ int flags, struct prefix *p, struct prefix_ipv6 *src_p,
+ const struct nexthop *nh, u_int32_t table_id, u_int32_t metric,
u_int32_t mtu, uint8_t distance, route_tag_t tag)
{
struct route_entry *re;
@@ -2574,7 +2585,6 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, vrf_id_t nh_vrf_id,
re->mtu = mtu;
re->table = table_id;
re->vrf_id = vrf_id;
- re->nh_vrf_id = nh_vrf_id;
re->nexthop_num = 0;
re->uptime = time(NULL);
re->tag = tag;
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c
index cea46ffc1..9fc5afff0 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -659,7 +659,7 @@ static struct route_entry *zebra_rnh_resolve_nexthop_entry(vrf_id_t vrfid,
* match route to be exact if so specified
*/
if (is_default_prefix(&rn->p) &&
- !nh_resolve_via_default(rn->p.family))
+ !rnh_resolve_via_default(rn->p.family))
return NULL;
/* Identify appropriate route entry. */
@@ -952,7 +952,6 @@ static void copy_state(struct rnh *rnh, struct route_entry *re,
state->distance = re->distance;
state->metric = re->metric;
state->vrf_id = re->vrf_id;
- state->nh_vrf_id = re->vrf_id;
route_entry_copy_nexthops(state, re->nexthop);
rnh->state = state;
diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h
index 7e183684d..bd121ec83 100644
--- a/zebra/zebra_rnh.h
+++ b/zebra/zebra_rnh.h
@@ -54,6 +54,15 @@ typedef enum { RNH_NEXTHOP_TYPE, RNH_IMPORT_CHECK_TYPE } rnh_type_t;
extern int zebra_rnh_ip_default_route;
extern int zebra_rnh_ipv6_default_route;
+static inline int rnh_resolve_via_default(int family)
+{
+ if (((family == AF_INET) && zebra_rnh_ip_default_route)
+ || ((family == AF_INET6) && zebra_rnh_ipv6_default_route))
+ return 1;
+ else
+ return 0;
+}
+
extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid,
rnh_type_t type);
extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid,
diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c
index 4c619e578..882a03f84 100644
--- a/zebra/zebra_routemap.c
+++ b/zebra/zebra_routemap.c
@@ -1329,7 +1329,7 @@ route_map_result_t zebra_nht_route_map_check(int family, int client_proto,
struct nh_rmap_obj nh_obj;
nh_obj.nexthop = nexthop;
- nh_obj.vrf_id = re->nh_vrf_id;
+ nh_obj.vrf_id = nexthop->vrf_id;
nh_obj.source_protocol = re->type;
nh_obj.metric = re->metric;
nh_obj.tag = re->tag;
diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c
index 2e8ab11b0..b42bd818a 100644
--- a/zebra/zebra_static.c
+++ b/zebra/zebra_static.c
@@ -87,7 +87,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
switch (si->type) {
case STATIC_IPV4_GATEWAY:
nexthop = route_entry_nexthop_ipv4_add(
- re, &si->addr.ipv4, NULL);
+ re, &si->addr.ipv4, NULL, si->nh_vrf_id);
nh_p.family = AF_INET;
nh_p.prefixlen = IPV4_MAX_BITLEN;
nh_p.u.prefix4 = si->addr.ipv4;
@@ -95,19 +95,20 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
break;
case STATIC_IPV4_GATEWAY_IFNAME:
nexthop = route_entry_nexthop_ipv4_ifindex_add(
- re, &si->addr.ipv4, NULL, si->ifindex);
+ re, &si->addr.ipv4, NULL, si->ifindex,
+ si->nh_vrf_id);
break;
case STATIC_IFNAME:
- nexthop = route_entry_nexthop_ifindex_add(re,
- si->ifindex);
+ nexthop = route_entry_nexthop_ifindex_add(
+ re, si->ifindex, si->nh_vrf_id);
break;
case STATIC_BLACKHOLE:
nexthop = route_entry_nexthop_blackhole_add(
re, bh_type);
break;
case STATIC_IPV6_GATEWAY:
- nexthop = route_entry_nexthop_ipv6_add(re,
- &si->addr.ipv6);
+ nexthop = route_entry_nexthop_ipv6_add(
+ re, &si->addr.ipv6, si->nh_vrf_id);
nh_p.family = AF_INET6;
nh_p.prefixlen = IPV6_MAX_BITLEN;
nh_p.u.prefix6 = si->addr.ipv6;
@@ -115,7 +116,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
break;
case STATIC_IPV6_GATEWAY_IFNAME:
nexthop = route_entry_nexthop_ipv6_ifindex_add(
- re, &si->addr.ipv6, si->ifindex);
+ re, &si->addr.ipv6, si->ifindex, si->nh_vrf_id);
break;
}
/* Update label(s), if present. */
@@ -155,7 +156,6 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
re->metric = 0;
re->mtu = 0;
re->vrf_id = si->vrf_id;
- re->nh_vrf_id = si->nh_vrf_id;
re->table =
(si->vrf_id != VRF_DEFAULT)
? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id
@@ -166,7 +166,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
switch (si->type) {
case STATIC_IPV4_GATEWAY:
nexthop = route_entry_nexthop_ipv4_add(
- re, &si->addr.ipv4, NULL);
+ re, &si->addr.ipv4, NULL, si->nh_vrf_id);
nh_p.family = AF_INET;
nh_p.prefixlen = IPV4_MAX_BITLEN;
nh_p.u.prefix4 = si->addr.ipv4;
@@ -174,19 +174,20 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
break;
case STATIC_IPV4_GATEWAY_IFNAME:
nexthop = route_entry_nexthop_ipv4_ifindex_add(
- re, &si->addr.ipv4, NULL, si->ifindex);
+ re, &si->addr.ipv4, NULL, si->ifindex,
+ si->nh_vrf_id);
break;
case STATIC_IFNAME:
- nexthop = route_entry_nexthop_ifindex_add(re,
- si->ifindex);
+ nexthop = route_entry_nexthop_ifindex_add(
+ re, si->ifindex, si->nh_vrf_id);
break;
case STATIC_BLACKHOLE:
nexthop = route_entry_nexthop_blackhole_add(
re, bh_type);
break;
case STATIC_IPV6_GATEWAY:
- nexthop = route_entry_nexthop_ipv6_add(re,
- &si->addr.ipv6);
+ nexthop = route_entry_nexthop_ipv6_add(
+ re, &si->addr.ipv6, si->nh_vrf_id);
nh_p.family = AF_INET6;
nh_p.prefixlen = IPV6_MAX_BITLEN;
nh_p.u.prefix6 = si->addr.ipv6;
@@ -194,7 +195,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
break;
case STATIC_IPV6_GATEWAY_IFNAME:
nexthop = route_entry_nexthop_ipv6_ifindex_add(
- re, &si->addr.ipv6, si->ifindex);
+ re, &si->addr.ipv6, si->ifindex, si->nh_vrf_id);
break;
}
/* Update label(s), if present. */
diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h
index fe7e77e8b..bfeb4b386 100644
--- a/zebra/zebra_vrf.h
+++ b/zebra/zebra_vrf.h
@@ -79,6 +79,9 @@ struct zebra_vrf {
*/
struct zebra_ns *zns;
+ /* MPLS Label to handle L3VPN <-> vrf popping */
+ mpls_label_t label;
+
/* MPLS static LSP config table */
struct hash *slsp_table;
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 93397afa7..f5ad9c1c8 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -165,8 +165,8 @@ static int zebra_static_route_leak(struct vty *vty,
case -2:
vty_out(vty,
"%% Cannot use reserved label(s) (%d-%d)\n",
- MPLS_MIN_RESERVED_LABEL,
- MPLS_MAX_RESERVED_LABEL);
+ MPLS_LABEL_RESERVED_MIN,
+ MPLS_LABEL_RESERVED_MAX);
break;
case -3:
vty_out(vty,
@@ -770,8 +770,9 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
inet_ntoa(nexthop->gate.ipv4));
if (nexthop->ifindex)
vty_out(vty, ", via %s",
- ifindex2ifname(nexthop->ifindex,
- re->nh_vrf_id));
+ ifindex2ifname(
+ nexthop->ifindex,
+ nexthop->vrf_id));
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -780,13 +781,14 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
buf, sizeof buf));
if (nexthop->ifindex)
vty_out(vty, ", via %s",
- ifindex2ifname(nexthop->ifindex,
- re->nh_vrf_id));
+ ifindex2ifname(
+ nexthop->ifindex,
+ nexthop->vrf_id));
break;
case NEXTHOP_TYPE_IFINDEX:
vty_out(vty, " directly connected, %s",
ifindex2ifname(nexthop->ifindex,
- re->nh_vrf_id));
+ nexthop->vrf_id));
break;
case NEXTHOP_TYPE_BLACKHOLE:
vty_out(vty, " unreachable");
@@ -809,9 +811,9 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
break;
}
- if (re->vrf_id != re->nh_vrf_id) {
+ if (re->vrf_id != nexthop->vrf_id) {
struct vrf *vrf =
- vrf_lookup_by_id(re->nh_vrf_id);
+ vrf_lookup_by_id(nexthop->vrf_id);
vty_out(vty, "(vrf %s)", vrf->name);
}
@@ -954,8 +956,9 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
nexthop->ifindex);
json_object_string_add(
json_nexthop, "interfaceName",
- ifindex2ifname(nexthop->ifindex,
- re->nh_vrf_id));
+ ifindex2ifname(
+ nexthop->ifindex,
+ nexthop->vrf_id));
}
break;
case NEXTHOP_TYPE_IPV6:
@@ -973,8 +976,9 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
nexthop->ifindex);
json_object_string_add(
json_nexthop, "interfaceName",
- ifindex2ifname(nexthop->ifindex,
- re->nh_vrf_id));
+ ifindex2ifname(
+ nexthop->ifindex,
+ nexthop->vrf_id));
}
break;
@@ -987,7 +991,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
json_object_string_add(
json_nexthop, "interfaceName",
ifindex2ifname(nexthop->ifindex,
- re->nh_vrf_id));
+ nexthop->vrf_id));
break;
case NEXTHOP_TYPE_BLACKHOLE:
json_object_boolean_true_add(json_nexthop,
@@ -1014,9 +1018,9 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
break;
}
- if (re->nh_vrf_id != re->vrf_id) {
+ if (nexthop->vrf_id != re->vrf_id) {
struct vrf *vrf =
- vrf_lookup_by_id(re->nh_vrf_id);
+ vrf_lookup_by_id(nexthop->vrf_id);
json_object_string_add(json_nexthop,
"vrf",
@@ -1129,7 +1133,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
if (nexthop->ifindex)
vty_out(vty, ", %s",
ifindex2ifname(nexthop->ifindex,
- re->nh_vrf_id));
+ nexthop->vrf_id));
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -1139,13 +1143,13 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
if (nexthop->ifindex)
vty_out(vty, ", %s",
ifindex2ifname(nexthop->ifindex,
- re->nh_vrf_id));
+ nexthop->vrf_id));
break;
case NEXTHOP_TYPE_IFINDEX:
vty_out(vty, " is directly connected, %s",
ifindex2ifname(nexthop->ifindex,
- re->nh_vrf_id));
+ nexthop->vrf_id));
break;
case NEXTHOP_TYPE_BLACKHOLE:
vty_out(vty, " unreachable");
@@ -1167,9 +1171,8 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
break;
}
- if (re->nh_vrf_id != re->vrf_id) {
- struct vrf *vrf =
- vrf_lookup_by_id(re->nh_vrf_id);
+ if (nexthop->vrf_id != re->vrf_id) {
+ struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
vty_out(vty, "(vrf %s)", vrf->name);
}
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 71437bab1..704b86196 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,51 @@ stream_failure:
return 1;
}
+static void zread_vrf_label(struct zserv *client,
+ struct zebra_vrf *zvrf)
+{
+ struct interface *ifp;
+ mpls_label_t nlabel;
+ struct stream *s;
+ struct zebra_vrf *def_zvrf;
+ enum lsp_types_t ltype;
+
+ s = client->ibuf;
+ STREAM_GETL(s, nlabel);
+ if (nlabel == zvrf->label) {
+ /*
+ * 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 != MPLS_LABEL_NONE)
+ mpls_lsp_uninstall(def_zvrf, ltype, zvrf->label,
+ 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 = nlabel;
+stream_failure:
+ return;
+}
+
static inline void zserv_handle_commands(struct zserv *client,
uint16_t command,
uint16_t length,
@@ -2569,6 +2615,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;