diff options
| -rwxr-xr-x | configure.ac | 6 | ||||
| -rw-r--r-- | ldpd/l2vpn.c | 8 | ||||
| -rw-r--r-- | ldpd/lde.c | 9 | ||||
| -rw-r--r-- | ldpd/lde.h | 8 | ||||
| -rw-r--r-- | ldpd/lde_lib.c | 20 | ||||
| -rw-r--r-- | ldpd/ldp_zebra.c | 23 | ||||
| -rw-r--r-- | ldpd/packet.c | 47 | ||||
| -rw-r--r-- | lib/zclient.c | 28 | ||||
| -rw-r--r-- | zebra/zebra_mpls.c | 71 | ||||
| -rw-r--r-- | zebra/zebra_mpls.h | 3 | ||||
| -rw-r--r-- | zebra/zebra_vrf.c | 8 | ||||
| -rw-r--r-- | zebra/zebra_vty.c | 172 | ||||
| -rw-r--r-- | zebra/zserv.c | 32 |
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); } } |
