summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure.ac6
-rw-r--r--ldpd/l2vpn.c8
-rw-r--r--ldpd/lde.c9
-rw-r--r--ldpd/lde.h8
-rw-r--r--ldpd/lde_lib.c20
-rw-r--r--ldpd/ldp_zebra.c23
-rw-r--r--ldpd/packet.c47
-rw-r--r--lib/zclient.c28
-rw-r--r--zebra/zebra_mpls.c71
-rw-r--r--zebra/zebra_mpls.h3
-rw-r--r--zebra/zebra_vrf.c8
-rw-r--r--zebra/zebra_vty.c172
-rw-r--r--zebra/zserv.c32
13 files changed, 163 insertions, 272 deletions
diff --git a/configure.ac b/configure.ac
index 7e751cd3fa..128300cc6c 100755
--- a/configure.ac
+++ b/configure.ac
@@ -1157,11 +1157,11 @@ else
fi
AM_CONDITIONAL(OSPFD, test "x$OSPFD" = "xospfd")
-if test "${enable_ldpd}" = "yes";then
+if test "${enable_ldpd}" = "no";then
+ LDPD=""
+else
LDPD="ldpd"
AC_DEFINE(HAVE_LDPD, 1, ldpd)
-else
- LDPD=""
fi
AM_CONDITIONAL(LDPD, test "x$LDPD" = "xldpd")
diff --git a/ldpd/l2vpn.c b/ldpd/l2vpn.c
index db382e484f..851ff77b73 100644
--- a/ldpd/l2vpn.c
+++ b/ldpd/l2vpn.c
@@ -195,7 +195,7 @@ l2vpn_pw_init(struct l2vpn_pw *pw)
l2vpn_pw_reset(pw);
l2vpn_pw_fec(pw, &fec);
- lde_kernel_insert(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0,
+ lde_kernel_insert(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0, 0,
0, (void *)pw);
}
@@ -205,7 +205,7 @@ l2vpn_pw_exit(struct l2vpn_pw *pw)
struct fec fec;
l2vpn_pw_fec(pw, &fec);
- lde_kernel_remove(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0);
+ lde_kernel_remove(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0, 0);
}
static void
@@ -374,7 +374,7 @@ l2vpn_recv_pw_status(struct lde_nbr *ln, struct notify_msg *nm)
if (pw == NULL)
return;
- fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)&ln->id, 0);
+ fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)&ln->id, 0, 0);
if (fnh == NULL)
return;
@@ -409,7 +409,7 @@ l2vpn_sync_pws(int af, union ldpd_addr *addr)
if (fn == NULL)
continue;
fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)
- &pw->lsr_id, 0);
+ &pw->lsr_id, 0, 0);
if (fnh == NULL)
continue;
diff --git a/ldpd/lde.c b/ldpd/lde.c
index 904d0f8d9a..67ed982ec5 100644
--- a/ldpd/lde.c
+++ b/ldpd/lde.c
@@ -432,14 +432,15 @@ lde_dispatch_parent(struct thread *thread)
switch (imsg.hdr.type) {
case IMSG_NETWORK_ADD:
lde_kernel_insert(&fec, kr.af, &kr.nexthop,
- kr.priority, kr.flags & F_CONNECTED, NULL);
+ kr.ifindex, kr.priority,
+ kr.flags & F_CONNECTED, NULL);
break;
case IMSG_NETWORK_ADD_END:
lde_kernel_reevaluate(&fec);
break;
case IMSG_NETWORK_DEL:
lde_kernel_remove(&fec, kr.af, &kr.nexthop,
- kr.priority);
+ kr.ifindex, kr.priority);
break;
}
break;
@@ -595,6 +596,7 @@ lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
kr.prefix.v4 = fn->fec.u.ipv4.prefix;
kr.prefixlen = fn->fec.u.ipv4.prefixlen;
kr.nexthop.v4 = fnh->nexthop.v4;
+ kr.ifindex = fnh->ifindex;
kr.local_label = fn->local_label;
kr.remote_label = fnh->remote_label;
kr.priority = fnh->priority;
@@ -612,6 +614,7 @@ lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
kr.prefix.v6 = fn->fec.u.ipv6.prefix;
kr.prefixlen = fn->fec.u.ipv6.prefixlen;
kr.nexthop.v6 = fnh->nexthop.v6;
+ kr.ifindex = fnh->ifindex;
kr.local_label = fn->local_label;
kr.remote_label = fnh->remote_label;
kr.priority = fnh->priority;
@@ -660,6 +663,7 @@ lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
kr.prefix.v4 = fn->fec.u.ipv4.prefix;
kr.prefixlen = fn->fec.u.ipv4.prefixlen;
kr.nexthop.v4 = fnh->nexthop.v4;
+ kr.ifindex = fnh->ifindex;
kr.local_label = fn->local_label;
kr.remote_label = fnh->remote_label;
kr.priority = fnh->priority;
@@ -677,6 +681,7 @@ lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
kr.prefix.v6 = fn->fec.u.ipv6.prefix;
kr.prefixlen = fn->fec.u.ipv6.prefixlen;
kr.nexthop.v6 = fnh->nexthop.v6;
+ kr.ifindex = fnh->ifindex;
kr.local_label = fn->local_label;
kr.remote_label = fnh->remote_label;
kr.priority = fnh->priority;
diff --git a/ldpd/lde.h b/ldpd/lde.h
index cf8f2129af..5f5d37defb 100644
--- a/ldpd/lde.h
+++ b/ldpd/lde.h
@@ -23,6 +23,7 @@
#include "openbsd-queue.h"
#include "openbsd-tree.h"
+#include "if.h"
enum fec_type {
FEC_TYPE_IPV4,
@@ -100,6 +101,7 @@ struct fec_nh {
LIST_ENTRY(fec_nh) entry;
int af;
union ldpd_addr nexthop;
+ ifindex_t ifindex;
uint32_t remote_label;
uint8_t priority;
uint8_t flags;
@@ -163,12 +165,12 @@ void rt_dump(pid_t);
void fec_snap(struct lde_nbr *);
void fec_tree_clear(void);
struct fec_nh *fec_nh_find(struct fec_node *, int, union ldpd_addr *,
- uint8_t);
+ ifindex_t, uint8_t);
uint32_t egress_label(enum fec_type);
void lde_kernel_insert(struct fec *, int, union ldpd_addr *,
- uint8_t, int, void *);
+ ifindex_t, uint8_t, int, void *);
void lde_kernel_remove(struct fec *, int, union ldpd_addr *,
- uint8_t);
+ ifindex_t, uint8_t);
void lde_kernel_reevaluate(struct fec *);
void lde_check_mapping(struct map *, struct lde_nbr *);
void lde_check_request(struct map *, struct lde_nbr *);
diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c
index 43e5f92f2f..14ac592af9 100644
--- a/ldpd/lde_lib.c
+++ b/ldpd/lde_lib.c
@@ -31,7 +31,7 @@ static int lde_nbr_is_nexthop(struct fec_node *,
static void fec_free(void *);
static struct fec_node *fec_add(struct fec *fec);
static struct fec_nh *fec_nh_add(struct fec_node *, int, union ldpd_addr *,
- uint8_t priority);
+ ifindex_t, uint8_t);
static void fec_nh_del(struct fec_nh *);
RB_GENERATE(fec_tree, fec, entry, fec_compare)
@@ -264,13 +264,14 @@ fec_add(struct fec *fec)
struct fec_nh *
fec_nh_find(struct fec_node *fn, int af, union ldpd_addr *nexthop,
- uint8_t priority)
+ ifindex_t ifindex, uint8_t priority)
{
struct fec_nh *fnh;
LIST_FOREACH(fnh, &fn->nexthops, entry)
if (fnh->af == af &&
ldp_addrcmp(af, &fnh->nexthop, nexthop) == 0 &&
+ fnh->ifindex == ifindex &&
fnh->priority == priority)
return (fnh);
@@ -279,7 +280,7 @@ fec_nh_find(struct fec_node *fn, int af, union ldpd_addr *nexthop,
static struct fec_nh *
fec_nh_add(struct fec_node *fn, int af, union ldpd_addr *nexthop,
- uint8_t priority)
+ ifindex_t ifindex, uint8_t priority)
{
struct fec_nh *fnh;
@@ -289,6 +290,7 @@ fec_nh_add(struct fec_node *fn, int af, union ldpd_addr *nexthop,
fnh->af = af;
fnh->nexthop = *nexthop;
+ fnh->ifindex = ifindex;
fnh->remote_label = NO_LABEL;
fnh->priority = priority;
LIST_INSERT_HEAD(&fn->nexthops, fnh, entry);
@@ -324,7 +326,7 @@ egress_label(enum fec_type fec_type)
void
lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop,
- uint8_t priority, int connected, void *data)
+ ifindex_t ifindex, uint8_t priority, int connected, void *data)
{
struct fec_node *fn;
struct fec_nh *fnh;
@@ -334,7 +336,7 @@ lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop,
fn = (struct fec_node *)fec_find(&ft, fec);
if (fn == NULL)
fn = fec_add(fec);
- fnh = fec_nh_find(fn, af, nexthop, priority);
+ fnh = fec_nh_find(fn, af, nexthop, ifindex, priority);
if (fnh != NULL) {
lde_send_change_klabel(fn, fnh);
fnh->flags |= F_FEC_NH_NEW;
@@ -355,7 +357,7 @@ lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop,
lde_send_labelmapping(ln, fn, 1);
}
- fnh = fec_nh_add(fn, af, nexthop, priority);
+ fnh = fec_nh_add(fn, af, nexthop, ifindex, priority);
fnh->flags |= F_FEC_NH_NEW;
lde_send_change_klabel(fn, fnh);
@@ -383,7 +385,7 @@ lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop,
void
lde_kernel_remove(struct fec *fec, int af, union ldpd_addr *nexthop,
- uint8_t priority)
+ ifindex_t ifindex, uint8_t priority)
{
struct fec_node *fn;
struct fec_nh *fnh;
@@ -392,7 +394,7 @@ lde_kernel_remove(struct fec *fec, int af, union ldpd_addr *nexthop,
if (fn == NULL)
/* route lost */
return;
- fnh = fec_nh_find(fn, af, nexthop, priority);
+ fnh = fec_nh_find(fn, af, nexthop, ifindex, priority);
if (fnh == NULL)
/* route lost */
return;
@@ -428,7 +430,7 @@ lde_kernel_reevaluate(struct fec *fec)
fnh->flags &= ~F_FEC_NH_NEW;
else
lde_kernel_remove(fec, fnh->af, &fnh->nexthop,
- fnh->priority);
+ fnh->ifindex, fnh->priority);
}
}
diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c
index 71c0a21dd4..a233cb72e7 100644
--- a/ldpd/ldp_zebra.c
+++ b/ldpd/ldp_zebra.c
@@ -100,10 +100,10 @@ zebra_send_mpls_labels(int cmd, struct kroute *kr)
kr->remote_label == NO_LABEL)
return (0);
- debug_zebra_out("prefix %s/%u nexthop %s labels %s/%s (%s)",
+ debug_zebra_out("prefix %s/%u nexthop %s ifindex %u labels %s/%s (%s)",
log_addr(kr->af, &kr->prefix), kr->prefixlen,
- log_addr(kr->af, &kr->nexthop), log_label(kr->local_label),
- log_label(kr->remote_label),
+ log_addr(kr->af, &kr->nexthop), kr->ifindex,
+ log_label(kr->local_label), log_label(kr->remote_label),
(cmd == ZEBRA_MPLS_LABELS_ADD) ? "add" : "delete");
/* Reset stream. */
@@ -127,6 +127,7 @@ zebra_send_mpls_labels(int cmd, struct kroute *kr)
default:
fatalx("kr_change: unknown af");
}
+ stream_putl(s, kr->ifindex);
stream_putc(s, kr->priority);
stream_putl(s, kr->local_label);
stream_putl(s, kr->remote_label);
@@ -426,19 +427,19 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
switch (command) {
case ZEBRA_REDISTRIBUTE_IPV4_ADD:
case ZEBRA_REDISTRIBUTE_IPV6_ADD:
- debug_zebra_in("route add %s/%d nexthop %s (%s)",
- log_addr(kr.af, &kr.prefix), kr.prefixlen,
- log_addr(kr.af, &kr.nexthop),
- zebra_route_string(type));
+ debug_zebra_in("route add %s/%d nexthop %s "
+ "ifindex %u (%s)", log_addr(kr.af, &kr.prefix),
+ kr.prefixlen, log_addr(kr.af, &kr.nexthop),
+ kr.ifindex, zebra_route_string(type));
main_imsg_compose_lde(IMSG_NETWORK_ADD, 0, &kr,
sizeof(kr));
break;
case ZEBRA_REDISTRIBUTE_IPV4_DEL:
case ZEBRA_REDISTRIBUTE_IPV6_DEL:
- debug_zebra_in("route delete %s/%d nexthop %s (%s)",
- log_addr(kr.af, &kr.prefix), kr.prefixlen,
- log_addr(kr.af, &kr.nexthop),
- zebra_route_string(type));
+ debug_zebra_in("route delete %s/%d nexthop %s "
+ "ifindex %u (%s)", log_addr(kr.af, &kr.prefix),
+ kr.prefixlen, log_addr(kr.af, &kr.nexthop),
+ kr.ifindex, zebra_route_string(type));
main_imsg_compose_lde(IMSG_NETWORK_DEL, 0, &kr,
sizeof(kr));
break;
diff --git a/ldpd/packet.c b/ldpd/packet.c
index 9b3151d720..be5ed8072b 100644
--- a/ldpd/packet.c
+++ b/ldpd/packet.c
@@ -285,53 +285,24 @@ disc_find_iface(unsigned int ifindex, int af, union ldpd_addr *src,
{
struct iface *iface;
struct iface_af *ia;
- struct if_addr *if_addr;
- in_addr_t mask;
iface = if_lookup(leconf, ifindex);
if (iface == NULL)
return (NULL);
+ ia = iface_af_get(iface, af);
+ if (!ia->enabled)
+ return (NULL);
+
/*
- * For unicast packets, we just need to make sure that the interface
- * is enabled for the given address-family.
+ * RFC 7552 - Section 5.1:
+ * "Link-local IPv6 address MUST be used as the source IP address in
+ * IPv6 LDP Link Hellos".
*/
- if (!multicast) {
- ia = iface_af_get(iface, af);
- if (ia->enabled)
- return (iface);
+ if (multicast && af == AF_INET6 && !IN6_IS_ADDR_LINKLOCAL(&src->v6))
return (NULL);
- }
- switch (af) {
- case AF_INET:
- LIST_FOREACH(if_addr, &iface->addr_list, entry) {
- if (if_addr->af != AF_INET)
- continue;
-
- switch (iface->type) {
- case IF_TYPE_POINTOPOINT:
- if (if_addr->dstbrd.v4.s_addr == src->v4.s_addr)
- return (iface);
- break;
- default:
- mask = prefixlen2mask(if_addr->prefixlen);
- if ((if_addr->addr.v4.s_addr & mask) ==
- (src->v4.s_addr & mask))
- return (iface);
- break;
- }
- }
- break;
- case AF_INET6:
- if (IN6_IS_ADDR_LINKLOCAL(&src->v6))
- return (iface);
- break;
- default:
- fatalx("disc_find_iface: unknown af");
- }
-
- return (NULL);
+ return (iface);
}
int
diff --git a/lib/zclient.c b/lib/zclient.c
index 894e0d19ef..440de3635f 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -216,7 +216,9 @@ zclient_socket(void)
ret = connect (sock, (struct sockaddr *) &serv, sizeof (serv));
if (ret < 0)
{
- zlog_warn ("%s connect failure: %d", __PRETTY_FUNCTION__, errno);
+ if (zclient_debug)
+ zlog_warn ("%s connect failure: %d(%s)", __PRETTY_FUNCTION__,
+ errno, safe_strerror (errno));
close (sock);
return -1;
}
@@ -252,7 +254,9 @@ zclient_socket_un (const char *path)
ret = connect (sock, (struct sockaddr *) &addr, len);
if (ret < 0)
{
- zlog_warn ("%s connect failure: %d", __PRETTY_FUNCTION__, errno);
+ if (zclient_debug)
+ zlog_warn ("%s connect failure: %d(%s)", __PRETTY_FUNCTION__,
+ errno, safe_strerror (errno));
close (sock);
return -1;
}
@@ -572,23 +576,11 @@ zclient_start (struct zclient *zclient)
if (zclient->t_connect)
return 0;
- /*
- * If we fail to connect to the socket on initialization,
- * Let's wait a second and see if we can reconnect.
- * Cause if we don't connect, we never attempt to
- * reconnect. On startup if zebra is slow we
- * can get into this situation.
- */
- while (zclient_socket_connect(zclient) < 0 && zclient->fail < 5)
+ if (zclient_socket_connect(zclient) < 0)
{
if (zclient_debug)
zlog_debug ("zclient connection fail");
zclient->fail++;
- sleep (1);
- }
-
- if (zclient->sock < 0)
- {
zclient_event (ZCLIENT_CONNECT, zclient);
return -1;
}
@@ -1727,11 +1719,9 @@ zclient_event (enum event event, struct zclient *zclient)
thread_add_event (zclient->master, zclient_connect, zclient, 0);
break;
case ZCLIENT_CONNECT:
- if (zclient->fail >= 10)
- return;
if (zclient_debug)
- zlog_debug ("zclient connect schedule interval is %d",
- zclient->fail < 3 ? 10 : 60);
+ zlog_debug ("zclient connect failures: %d schedule interval is now %d",
+ zclient->fail, zclient->fail < 3 ? 10 : 60);
if (! zclient->t_connect)
zclient->t_connect =
thread_add_timer (zclient->master, zclient_connect, zclient,
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:
diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h
index 9f24689595..a871fac651 100644
--- a/zebra/zebra_mpls.h
+++ b/zebra/zebra_mpls.h
@@ -169,7 +169,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);
/*
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index bf42792cf8..929743859e 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -271,11 +271,14 @@ zebra_vrf_delete (struct vrf *vrf)
/* release allocated memory */
for (afi = AFI_IP; afi <= AFI_IP6; afi++)
{
+ void *table_info;
+
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
{
table = zvrf->table[afi][safi];
- XFREE (MTYPE_RIB_TABLE_INFO, table->info);
+ table_info = table->info;
route_table_finish (table);
+ XFREE (MTYPE_RIB_TABLE_INFO, table_info);
table = zvrf->stable[afi][safi];
route_table_finish (table);
@@ -285,8 +288,9 @@ zebra_vrf_delete (struct vrf *vrf)
if (zvrf->other_table[afi][table_id])
{
table = zvrf->other_table[afi][table_id];
- XFREE (MTYPE_RIB_TABLE_INFO, table->info);
+ table_info = table->info;
route_table_finish (table);
+ XFREE (MTYPE_RIB_TABLE_INFO, table_info);
}
route_table_finish (zvrf->rnh_table[afi]);
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index f32b51f037..e5f9b17e81 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -407,40 +407,6 @@ DEFUN (ip_route,
DEFUN (ip_route_flags,
ip_route_flags_cmd,
- "ip route A.B.C.D/M <A.B.C.D|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR
- "Specify labels for this route\n"
- "One or more labels separated by '/'\n")
-{
- int idx_ipv4_prefixlen = 2;
- int idx_ipv4_ifname = 3;
- int idx_reject_blackhole = 4;
- int idx_curr = 5;
- char *tag, *distance, *vrf;
-
- tag = distance = vrf = NULL;
- zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
-
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
- argv[idx_ipv4_prefixlen]->arg,
- NULL,
- argv[idx_ipv4_ifname]->arg,
- argv[idx_reject_blackhole]->arg,
- tag, distance, vrf, NULL);
-}
-
-DEFUN (ip_route_flags2,
- ip_route_flags2_cmd,
"ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
IP_STR
"Establish static routes\n"
@@ -506,43 +472,6 @@ DEFUN (ip_route_mask,
DEFUN (ip_route_mask_flags,
ip_route_mask_flags_cmd,
- "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Set tag for this route\n"
- "Tag value\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR
- "Specify labels for this route\n"
- "One or more labels separated by '/'\n")
-{
- int idx_ipv4 = 2;
- int idx_ipv4_2 = 3;
- int idx_ipv4_ifname = 4;
- int idx_reject_blackhole = 5;
- int idx_curr = 6;
- char *tag, *distance, *vrf;
-
- tag = distance = vrf = NULL;
- zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
-
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
- argv[idx_ipv4]->arg,
- argv[idx_ipv4_2]->arg,
- argv[idx_ipv4_ifname]->arg,
- argv[idx_reject_blackhole]->arg,
- tag, distance, vrf, NULL);
-}
-
-
-DEFUN (ip_route_mask_flags2,
- ip_route_mask_flags2_cmd,
"ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
IP_STR
"Establish static routes\n"
@@ -607,8 +536,8 @@ DEFUN (no_ip_route,
tag, distance, vrf, NULL);
}
-DEFUN (no_ip_route_flags2,
- no_ip_route_flags2_cmd,
+DEFUN (no_ip_route_flags,
+ no_ip_route_flags_cmd,
"no ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
NO_STR
IP_STR
@@ -671,8 +600,8 @@ DEFUN (no_ip_route_mask,
tag, distance, vrf, NULL);
}
-DEFUN (no_ip_route_mask_flags2,
- no_ip_route_mask_flags2_cmd,
+DEFUN (no_ip_route_mask_flags,
+ no_ip_route_mask_flags_cmd,
"no ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
NO_STR
IP_STR
@@ -703,78 +632,6 @@ DEFUN (no_ip_route_mask_flags2,
tag, distance, vrf, NULL);
}
-DEFUN (no_ip_route_flags,
- no_ip_route_flags_cmd,
- "no ip route A.B.C.D/M <A.B.C.D|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix (e.g. 10.0.0.0/8)\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Tag of this route\n"
- "Tag value\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR
- "Specify labels for this route\n"
- "One or more labels separated by '/'\n")
-{
- int idx_ipv4_prefixlen = 3;
- int idx_ipv4_ifname = 4;
- int idx_reject_blackhole = 5;
- int idx_curr = 6;
- char *tag, *distance, *vrf;
-
- tag = distance = vrf = NULL;
- zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
-
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
- argv[idx_ipv4_prefixlen]->arg,
- NULL,
- argv[idx_ipv4_ifname]->arg,
- argv[idx_reject_blackhole]->arg,
- tag, distance, vrf, NULL);
-}
-
-DEFUN (no_ip_route_mask_flags,
- no_ip_route_mask_flags_cmd,
- "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
- NO_STR
- IP_STR
- "Establish static routes\n"
- "IP destination prefix\n"
- "IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
- "Tag of this route\n"
- "Tag value\n"
- "Distance value for this route\n"
- VRF_CMD_HELP_STR
- "Specify labels for this route\n"
- "One or more labels separated by '/'\n")
-{
- int idx_ipv4 = 3;
- int idx_ipv4_2 = 4;
- int idx_ipv4_ifname = 5;
- int idx_reject_blackhole = 6;
- int idx_curr = 7;
- char *tag, *distance, *vrf;
-
- tag = distance = vrf = NULL;
- zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
-
- return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
- argv[idx_ipv4]->arg,
- argv[idx_ipv4_2]->arg,
- argv[idx_ipv4_ifname]->arg,
- argv[idx_reject_blackhole]->arg,
- tag, distance, vrf, NULL);
-}
-
/* New RIB. Detailed information for IPv4 route. */
static void
vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
@@ -918,6 +775,15 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
default:
break;
}
+
+ /* Label information */
+ if (nexthop->nh_label && nexthop->nh_label->num_labels)
+ {
+ vty_out (vty, " label %s",
+ mpls_label2str (nexthop->nh_label->num_labels,
+ nexthop->nh_label->label, buf, BUFSIZ));
+ }
+
vty_out (vty, "%s", VTY_NEWLINE);
}
vty_out (vty, "%s", VTY_NEWLINE);
@@ -1158,6 +1024,14 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
break;
}
+ /* Label information */
+ if (nexthop->nh_label && nexthop->nh_label->num_labels)
+ {
+ vty_out (vty, " label %s",
+ mpls_label2str (nexthop->nh_label->num_labels,
+ nexthop->nh_label->label, buf, BUFSIZ));
+ }
+
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
vty_out (vty, ", bh");
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
@@ -3953,14 +3827,10 @@ zebra_vty_init (void)
install_element (CONFIG_NODE, &no_ip_multicast_mode_cmd);
install_element (CONFIG_NODE, &ip_route_cmd);
install_element (CONFIG_NODE, &ip_route_flags_cmd);
- install_element (CONFIG_NODE, &ip_route_flags2_cmd);
install_element (CONFIG_NODE, &ip_route_mask_cmd);
install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
- install_element (CONFIG_NODE, &ip_route_mask_flags2_cmd);
install_element (CONFIG_NODE, &no_ip_route_cmd);
- install_element (CONFIG_NODE, &no_ip_route_flags2_cmd);
install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_flags2_cmd);
install_element (CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
install_element (CONFIG_NODE, &no_ip_zebra_import_table_cmd);
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 61ea55f477..b7e45d8df1 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -1665,6 +1665,7 @@ zread_mpls_labels (int command, struct zserv *client, u_short length,
struct prefix prefix;
enum nexthop_types_t gtype;
union g_addr gate;
+ ifindex_t ifindex;
mpls_label_t in_label, out_label;
u_int8_t distance;
struct zebra_vrf *zvrf;
@@ -1684,37 +1685,56 @@ zread_mpls_labels (int command, struct zserv *client, u_short length,
case AF_INET:
prefix.u.prefix4.s_addr = stream_get_ipv4 (s);
prefix.prefixlen = stream_getc (s);
- gtype = NEXTHOP_TYPE_IPV4;
gate.ipv4.s_addr = stream_get_ipv4 (s);
break;
case AF_INET6:
stream_get (&prefix.u.prefix6, s, 16);
prefix.prefixlen = stream_getc (s);
- gtype = NEXTHOP_TYPE_IPV6;
stream_get (&gate.ipv6, s, 16);
break;
default:
return;
}
+ ifindex = stream_getl (s);
distance = stream_getc (s);
in_label = stream_getl (s);
out_label = stream_getl (s);
+ switch (prefix.family)
+ {
+ case AF_INET:
+ if (ifindex)
+ gtype = NEXTHOP_TYPE_IPV4_IFINDEX;
+ else
+ gtype = NEXTHOP_TYPE_IPV4;
+ break;
+ case AF_INET6:
+ if (ifindex)
+ gtype = NEXTHOP_TYPE_IPV6_IFINDEX;
+ else
+ gtype = NEXTHOP_TYPE_IPV6;
+ break;
+ default:
+ return;
+ }
+
if (! mpls_enabled)
return;
if (command == ZEBRA_MPLS_LABELS_ADD)
{
mpls_lsp_install (zvrf, type, in_label, out_label, gtype, &gate,
- NULL, 0);
+ NULL, ifindex);
if (out_label != MPLS_IMP_NULL_LABEL)
- mpls_ftn_update (1, zvrf, type, &prefix, &gate, distance, out_label);
+ mpls_ftn_update (1, zvrf, type, &prefix, gtype, &gate, ifindex,
+ distance, out_label);
}
else if (command == ZEBRA_MPLS_LABELS_DELETE)
{
- mpls_lsp_uninstall (zvrf, type, in_label, gtype, &gate, NULL, 0);
+ mpls_lsp_uninstall (zvrf, type, in_label, gtype, &gate, NULL, ifindex);
if (out_label != MPLS_IMP_NULL_LABEL)
- mpls_ftn_update (0, zvrf, type, &prefix, &gate, distance, out_label);
+ mpls_ftn_update (0, zvrf, type, &prefix, gtype, &gate, ifindex,
+ distance, out_label);
}
}