diff options
author | Martin Winter <mwinter@opensourcerouting.org> | 2018-02-14 04:05:42 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-14 04:05:42 +0100 |
commit | 74a75bdbadab86341c239dff5d33fad530754247 (patch) | |
tree | 03af0658c91e4dff6efed65bd20886adf3d1910f /zebra | |
parent | Merge pull request #1734 from donaldsharp/control_me (diff) | |
parent | zebra: Use appropriate output function for label printing (diff) | |
download | frr-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.c | 18 | ||||
-rw-r--r-- | zebra/kernel_socket.c | 8 | ||||
-rw-r--r-- | zebra/label_manager.c | 4 | ||||
-rw-r--r-- | zebra/rib.h | 20 | ||||
-rw-r--r-- | zebra/rt_netlink.c | 42 | ||||
-rw-r--r-- | zebra/rtread_getmsg.c | 6 | ||||
-rw-r--r-- | zebra/zebra_mpls.c | 82 | ||||
-rw-r--r-- | zebra/zebra_mpls.h | 37 | ||||
-rw-r--r-- | zebra/zebra_mpls_vty.c | 14 | ||||
-rw-r--r-- | zebra/zebra_rib.c | 50 | ||||
-rw-r--r-- | zebra/zebra_rnh.c | 3 | ||||
-rw-r--r-- | zebra/zebra_rnh.h | 9 | ||||
-rw-r--r-- | zebra/zebra_routemap.c | 2 | ||||
-rw-r--r-- | zebra/zebra_static.c | 31 | ||||
-rw-r--r-- | zebra/zebra_vrf.h | 3 | ||||
-rw-r--r-- | zebra/zebra_vty.c | 47 | ||||
-rw-r--r-- | zebra/zserv.c | 99 |
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; |