diff options
-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-- | zebra/zebra_mpls.c | 68 | ||||
-rw-r--r-- | zebra/zebra_mpls.h | 3 | ||||
-rw-r--r-- | zebra/zserv.c | 32 |
8 files changed, 112 insertions, 59 deletions
diff --git a/ldpd/l2vpn.c b/ldpd/l2vpn.c index db382e484..851ff77b7 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 904d0f8d9..67ed982ec 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 cf8f2129a..5f5d37def 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 43e5f92f2..14ac592af 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 71c0a21dd..a233cb72e 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/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 3333b7226..b057a7878 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: @@ -842,6 +856,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 +894,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 +1276,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 +1304,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 +1832,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 9f2468959..a871fac65 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/zserv.c b/zebra/zserv.c index 61ea55f47..b7e45d8df 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); } } |