summaryrefslogtreecommitdiff
path: root/zebra
diff options
context:
space:
mode:
Diffstat (limited to 'zebra')
-rw-r--r--zebra/connected.c6
-rw-r--r--zebra/if_netlink.c5
-rw-r--r--zebra/interface.c36
-rw-r--r--zebra/interface.h2
-rw-r--r--zebra/kernel_socket.c4
-rw-r--r--zebra/label_manager.c2
-rw-r--r--zebra/main.c17
-rw-r--r--zebra/rib.h7
-rw-r--r--zebra/rt.h9
-rw-r--r--zebra/rt_netlink.c64
-rw-r--r--zebra/rt_socket.c16
-rw-r--r--zebra/rtread_getmsg.c5
-rw-r--r--zebra/zebra_fpm.c20
-rw-r--r--zebra/zebra_mpls.c6
-rw-r--r--zebra/zebra_mroute.c2
-rw-r--r--zebra/zebra_ns.c2
-rw-r--r--zebra/zebra_ns.h3
-rw-r--r--zebra/zebra_ptm.c13
-rw-r--r--zebra/zebra_ptm_redistribute.c5
-rw-r--r--zebra/zebra_rib.c117
-rw-r--r--zebra/zebra_rnh.c4
-rw-r--r--zebra/zebra_routemap.c4
-rw-r--r--zebra/zebra_static.c20
-rw-r--r--zebra/zebra_static.h2
-rw-r--r--zebra/zebra_vrf.c15
-rw-r--r--zebra/zebra_vty.c628
-rw-r--r--zebra/zebra_vxlan.c10
-rw-r--r--zebra/zserv.c54
-rw-r--r--zebra/zserv.h2
29 files changed, 818 insertions, 262 deletions
diff --git a/zebra/connected.c b/zebra/connected.c
index 7b949c5041..d34fd9021a 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -238,10 +238,12 @@ void connected_up(struct interface *ifp, struct connected *ifc)
break;
}
- rib_add(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
+ 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_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 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);
if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index f73506bf91..14905b738b 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -387,6 +387,11 @@ static int get_iflink_speed(const char *ifname)
return (ecmd.speed_hi << 16) | ecmd.speed;
}
+uint32_t kernel_get_speed(struct interface *ifp)
+{
+ return get_iflink_speed(ifp->name);
+}
+
static int netlink_extract_bridge_info(struct rtattr *link_data,
struct zebra_l2info_bridge *bridge_info)
{
diff --git a/zebra/interface.c b/zebra/interface.c
index 18588ee52c..07570e64bf 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -57,8 +57,29 @@ DEFINE_HOOK(zebra_if_extra_info, (struct vty *vty, struct interface *ifp),
DEFINE_HOOK(zebra_if_config_wr, (struct vty *vty, struct interface *ifp),
(vty, ifp))
+
static void if_down_del_nbr_connected(struct interface *ifp);
+static int if_zebra_speed_update(struct thread *thread)
+{
+ struct interface *ifp = THREAD_ARG(thread);
+ struct zebra_if *zif = ifp->info;
+ uint32_t new_speed;
+
+ zif->speed_update = NULL;
+
+ new_speed = kernel_get_speed(ifp);
+ if (new_speed != ifp->speed) {
+ zlog_info("%s: %s old speed: %u new speed: %u",
+ __PRETTY_FUNCTION__, ifp->name,
+ ifp->speed, new_speed);
+ ifp->speed = new_speed;
+ if_add_update(ifp);
+ }
+
+ return 1;
+}
+
static void zebra_if_node_destroy(route_table_delegate_t *delegate,
struct route_table *table,
struct route_node *node)
@@ -119,6 +140,16 @@ static int if_zebra_new_hook(struct interface *ifp)
route_table_init_with_delegate(&zebra_if_table_delegate);
ifp->info = zebra_if;
+
+ /*
+ * Some platforms are telling us that the interface is
+ * up and ready to go. When we check the speed we
+ * sometimes get the wrong value. Wait a couple
+ * of seconds and ask again. Hopefully it's all settled
+ * down upon startup.
+ */
+ thread_add_timer(zebrad.master, if_zebra_speed_update,
+ ifp, 15, &zebra_if->speed_update);
return 0;
}
@@ -141,6 +172,8 @@ static int if_zebra_delete_hook(struct interface *ifp)
list_delete_and_null(&rtadv->AdvPrefixList);
#endif /* HAVE_RTADV */
+ THREAD_OFF(zebra_if->speed_update);
+
XFREE(MTYPE_TMP, zebra_if);
}
@@ -735,7 +768,8 @@ void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id)
zebra_interface_vrf_update_add(ifp, old_vrf_id);
/* Install connected routes (in new VRF). */
- if_install_connected(ifp);
+ if (if_is_operative(ifp))
+ if_install_connected(ifp);
static_ifindex_update(ifp, true);
diff --git a/zebra/interface.h b/zebra/interface.h
index 61c3359f3b..e13721448c 100644
--- a/zebra/interface.h
+++ b/zebra/interface.h
@@ -273,6 +273,8 @@ struct zebra_if {
/* Link fields - for sub-interfaces. */
ifindex_t link_ifindex;
struct interface *link;
+
+ struct thread *speed_update;
};
DECLARE_HOOK(zebra_if_extra_info, (struct vty *vty, struct interface *ifp),
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index 9fd7bb1c24..ba028ed09c 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -1048,7 +1048,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,
+ rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
&nh, 0, 0, 0, 0, 0);
else
@@ -1096,7 +1096,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,
+ rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
&nh, 0, 0, 0, 0, 0);
else
diff --git a/zebra/label_manager.c b/zebra/label_manager.c
index f38206d8e1..ace13eda71 100644
--- a/zebra/label_manager.c
+++ b/zebra/label_manager.c
@@ -121,7 +121,7 @@ static int reply_error(int cmd, struct zserv *zserv, vrf_id_t vrf_id)
s = zserv->obuf;
stream_reset(s);
- zserv_create_header(s, cmd, vrf_id);
+ zclient_create_header(s, cmd, vrf_id);
/* result */
stream_putc(s, 1);
diff --git a/zebra/main.c b/zebra/main.c
index e26c8e3d69..19b16936d9 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -300,6 +300,13 @@ int main(int argc, char **argv)
zebra_if_init();
zebra_debug_init();
router_id_cmd_init();
+
+ /*
+ * Initialize NS( and implicitly the VRF module), and make kernel
+ * routing socket. */
+ zebra_ns_init();
+
+ zebra_vty_init();
access_list_init();
prefix_list_init();
#if defined(HAVE_RTADV)
@@ -317,16 +324,6 @@ int main(int argc, char **argv)
/* For debug purpose. */
/* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
- /* Initialize NS( and implicitly the VRF module), and make kernel
- * routing socket. */
- zebra_ns_init();
-
- /*
- * Initialize show/config command after the vrf initialization is
- * complete
- */
- zebra_vty_init();
-
#if defined(HANDLE_ZAPI_FUZZING)
if (fuzzing) {
zserv_read_file(fuzzing);
diff --git a/zebra/rib.h b/zebra/rib.h
index c7e83480ca..664afd01b8 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -59,6 +59,7 @@ struct route_entry {
/* VRF identifier. */
vrf_id_t vrf_id;
+ vrf_id_t nh_vrf_id;
/* Which routing table */
uint32_t table;
@@ -293,8 +294,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, 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, 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, u_int32_t mtu,
uint8_t distance, route_tag_t tag);
@@ -439,6 +440,8 @@ DECLARE_HOOK(rib_update, (struct route_node * rn, const char *reason),
extern void zebra_vty_init(void);
+extern int static_config(struct vty *vty, struct zebra_vrf *zvrf,
+ afi_t afi, safi_t safi, const char *cmd);
extern pid_t pid;
#endif /*_ZEBRA_RIB_H */
diff --git a/zebra/rt.h b/zebra/rt.h
index 7f5bb4dd34..54d45b889a 100644
--- a/zebra/rt.h
+++ b/zebra/rt.h
@@ -60,15 +60,17 @@ enum southbound_results {
* semantics so we will end up with a delete than
* a re-add.
*/
-extern void kernel_route_rib(struct prefix *p, struct prefix *src_p,
- struct route_entry *old, struct route_entry *new);
+extern void kernel_route_rib(struct route_node *rn, struct prefix *p,
+ struct prefix *src_p, struct route_entry *old,
+ struct route_entry *new);
/*
* So route install/failure may not be immediately known
* so let's separate it out and allow the result to
* be passed back up.
*/
-extern void kernel_route_rib_pass_fail(struct prefix *p,
+extern void kernel_route_rib_pass_fail(struct route_node *rn,
+ struct prefix *p,
struct route_entry *re,
enum southbound_results res);
@@ -98,6 +100,7 @@ extern void kernel_lsp_pass_fail(zebra_lsp_t *lsp,
extern int mpls_kernel_init(void);
+extern uint32_t kernel_get_speed(struct interface *ifp);
extern int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *mroute);
extern int kernel_add_vtep(vni_t vni, struct interface *ifp,
struct in_addr *vtep_ip);
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index a77814668d..20cc292e11 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -403,6 +403,9 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
afi = AFI_IP6;
if (h->nlmsg_type == RTM_NEWROUTE) {
+ struct interface *ifp;
+ vrf_id_t nh_vrf_id = vrf_id;
+
if (!tb[RTA_MULTIPATH]) {
struct nexthop nh;
size_t sz = (afi == AFI_IP) ? 4 : 16;
@@ -434,7 +437,14 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
if (gate)
memcpy(&nh.gate, gate, sz);
- rib_add(afi, SAFI_UNICAST, vrf_id, proto,
+ if (index) {
+ ifp = if_lookup_by_index(index,
+ VRF_UNKNOWN);
+ if (ifp)
+ nh_vrf_id = ifp->vrf_id;
+ }
+
+ rib_add(afi, SAFI_UNICAST, vrf_id, nh_vrf_id, proto,
0, flags, &p, NULL, &nh, table, metric,
mtu, distance, tag);
} else {
@@ -453,6 +463,7 @@ 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);
@@ -464,6 +475,18 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
break;
index = rtnh->rtnh_ifindex;
+ if (index) {
+ /*
+ * Yes we are looking this up
+ * for every nexthop and just
+ * using the last one looked
+ * up right now
+ */
+ ifp = if_lookup_by_index(index,
+ VRF_UNKNOWN);
+ if (ifp)
+ re->nh_vrf_id = ifp->vrf_id;
+ }
gate = 0;
if (rtnh->rtnh_len > sizeof(*rtnh)) {
memset(tb, 0, sizeof(tb));
@@ -803,7 +826,7 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
struct rtmsg *rtmsg,
size_t req_size, int cmd)
{
- struct nexthop_label *nh_label;
+ struct mpls_label_stack *nh_label;
mpls_lse_t out_lse[MPLS_MAX_LABELS];
char label_buf[256];
@@ -940,10 +963,17 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
routedesc, inet6_ntoa(nexthop->gate.ipv6),
label_buf, nexthop->ifindex);
}
- if (nexthop->type == NEXTHOP_TYPE_IFINDEX
- || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) {
+
+ /*
+ * We have the ifindex so we should always send it
+ * This is especially useful if we are doing route
+ * leaking.
+ */
+ if (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)
addattr32(nlmsg, req_size, RTA_OIF, nexthop->ifindex);
+ if (nexthop->type == NEXTHOP_TYPE_IFINDEX
+ || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) {
if (cmd == RTM_NEWROUTE) {
if (nexthop->rmap_src.ipv4.s_addr)
addattr_l(nlmsg, req_size, RTA_PREFSRC,
@@ -961,8 +991,6 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
}
if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) {
- addattr32(nlmsg, req_size, RTA_OIF, nexthop->ifindex);
-
if (cmd == RTM_NEWROUTE) {
if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6))
addattr_l(nlmsg, req_size, RTA_PREFSRC,
@@ -1003,7 +1031,7 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
struct rtmsg *rtmsg,
union g_addr **src)
{
- struct nexthop_label *nh_label;
+ struct mpls_label_stack *nh_label;
mpls_lse_t out_lse[MPLS_MAX_LABELS];
char label_buf[256];
@@ -1141,11 +1169,18 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
routedesc, inet6_ntoa(nexthop->gate.ipv6),
label_buf, nexthop->ifindex);
}
+
+ /*
+ * We have figured out the ifindex so we should always send it
+ * This is especially useful if we are doing route
+ * leaking.
+ */
+ if (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)
+ rtnh->rtnh_ifindex = nexthop->ifindex;
+
/* ifindex */
if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
|| nexthop->type == NEXTHOP_TYPE_IFINDEX) {
- rtnh->rtnh_ifindex = nexthop->ifindex;
-
if (nexthop->rmap_src.ipv4.s_addr)
*src = &nexthop->rmap_src;
else if (nexthop->src.ipv4.s_addr)
@@ -1157,8 +1192,6 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
"nexthop via if %u",
routedesc, nexthop->ifindex);
} else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) {
- rtnh->rtnh_ifindex = nexthop->ifindex;
-
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
"netlink_route_multipath() (%s): "
@@ -1609,8 +1642,9 @@ int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *in)
return suc;
}
-void kernel_route_rib(struct prefix *p, struct prefix *src_p,
- struct route_entry *old, struct route_entry *new)
+void kernel_route_rib(struct route_node *rn, struct prefix *p,
+ struct prefix *src_p, struct route_entry *old,
+ struct route_entry *new)
{
int ret = 0;
@@ -1639,7 +1673,7 @@ void kernel_route_rib(struct prefix *p, struct prefix *src_p,
ret = netlink_route_multipath(RTM_NEWROUTE, p,
src_p, new, 0);
}
- kernel_route_rib_pass_fail(p, new,
+ kernel_route_rib_pass_fail(rn, p, new,
(!ret) ?
SOUTHBOUND_INSTALL_SUCCESS :
SOUTHBOUND_INSTALL_FAILURE);
@@ -1649,7 +1683,7 @@ void kernel_route_rib(struct prefix *p, struct prefix *src_p,
if (old) {
ret = netlink_route_multipath(RTM_DELROUTE, p, src_p, old, 0);
- kernel_route_rib_pass_fail(p, old,
+ kernel_route_rib_pass_fail(rn, p, old,
(!ret) ?
SOUTHBOUND_DELETE_SUCCESS :
SOUTHBOUND_DELETE_FAILURE);
diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c
index 0d1a80e737..6d4af1203c 100644
--- a/zebra/rt_socket.c
+++ b/zebra/rt_socket.c
@@ -67,7 +67,7 @@ static int sin_masklen(struct in_addr mask)
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
#ifdef __OpenBSD__
-static int kernel_rtm_add_labels(struct nexthop_label *nh_label,
+static int kernel_rtm_add_labels(struct mpls_label_stack *nh_label,
struct sockaddr_mpls *smpls)
{
if (nh_label->num_labels > 1) {
@@ -387,8 +387,9 @@ static int kernel_rtm(int cmd, struct prefix *p, struct route_entry *re)
return 0;
}
-void kernel_route_rib(struct prefix *p, struct prefix *src_p,
- struct route_entry *old, struct route_entry *new)
+void kernel_route_rib(struct route_node *rn, struct prefix *p,
+ struct prefix *src_p, struct route_entry *old,
+ struct route_entry *new)
{
int route = 0;
@@ -410,12 +411,12 @@ void kernel_route_rib(struct prefix *p, struct prefix *src_p,
zlog_err("Can't lower privileges");
if (new) {
- kernel_route_rib_pass_fail(p, new,
+ kernel_route_rib_pass_fail(rn, p, new,
(!route) ?
SOUTHBOUND_INSTALL_SUCCESS :
SOUTHBOUND_INSTALL_FAILURE);
} else {
- kernel_route_rib_pass_fail(p, old,
+ kernel_route_rib_pass_fail(rn, p, old,
(!route) ?
SOUTHBOUND_DELETE_SUCCESS :
SOUTHBOUND_DELETE_FAILURE);
@@ -473,4 +474,9 @@ extern int kernel_interface_set_master(struct interface *master,
return 0;
}
+uint32_t kernel_get_speed(struct interface *ifp)
+{
+ return ifp->speed;
+}
+
#endif /* !HAVE_NETLINK */
diff --git a/zebra/rtread_getmsg.c b/zebra/rtread_getmsg.c
index 69e45f9a6c..ba45f54ad2 100644
--- a/zebra/rtread_getmsg.c
+++ b/zebra/rtread_getmsg.c
@@ -97,8 +97,9 @@ static void handle_route_entry(mib2_ipRouteEntry_t *routeEntry)
nh.type = NEXTHOP_TYPE_IPV4;
nh.gate.ipv4.s_addr = routeEntry->ipRouteNextHop;
- rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0,
- zebra_flags, &prefix, NULL, &nh, 0, 0, 0, 0, 0);
+ rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, 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_fpm.c b/zebra/zebra_fpm.c
index 0d0a2cb3bf..a6e0882ff8 100644
--- a/zebra/zebra_fpm.c
+++ b/zebra/zebra_fpm.c
@@ -713,7 +713,15 @@ static int zfpm_read_cb(struct thread *thread)
nbyte = stream_read_try(ibuf, zfpm_g->sock,
FPM_MSG_HDR_LEN - already);
if (nbyte == 0 || nbyte == -1) {
- zfpm_connection_down("closed socket in read");
+ if (nbyte == -1) {
+ char buffer[1024];
+
+ sprintf(buffer, "closed socket in read(%d): %s",
+ errno, safe_strerror(errno));
+ zfpm_connection_down(buffer);
+ }
+ else
+ zfpm_connection_down("closed socket in read");
return 0;
}
@@ -743,7 +751,15 @@ static int zfpm_read_cb(struct thread *thread)
nbyte = stream_read_try(ibuf, zfpm_g->sock, msg_len - already);
if (nbyte == 0 || nbyte == -1) {
- zfpm_connection_down("failed to read message");
+ if (nbyte == -1) {
+ char buffer[1024];
+
+ sprintf(buffer, "failed to read message(%d) %s",
+ errno, safe_strerror(errno));
+ zfpm_connection_down(buffer);
+ }
+ else
+ zfpm_connection_down("failed to read message");
return 0;
}
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index 4c6fb002dc..61051ba87e 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -104,7 +104,7 @@ static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
ifindex_t ifindex, mpls_label_t out_label);
static int nhlfe_del(zebra_nhlfe_t *snhlfe);
static void nhlfe_out_label_update(zebra_nhlfe_t *nhlfe,
- struct nexthop_label *nh_label);
+ struct mpls_label_stack *nh_label);
static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp,
enum lsp_types_t type);
static int mpls_static_lsp_uninstall_all(struct zebra_vrf *zvrf,
@@ -457,7 +457,7 @@ static int fec_send(zebra_fec_t *fec, struct zserv *client)
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, ZEBRA_FEC_UPDATE, VRF_DEFAULT);
+ zclient_create_header(s, ZEBRA_FEC_UPDATE, VRF_DEFAULT);
stream_putw(s, rn->p.family);
stream_put_prefix(s, &rn->p);
@@ -1217,7 +1217,7 @@ static int nhlfe_del(zebra_nhlfe_t *nhlfe)
* Update label for NHLFE entry.
*/
static void nhlfe_out_label_update(zebra_nhlfe_t *nhlfe,
- struct nexthop_label *nh_label)
+ struct mpls_label_stack *nh_label)
{
nhlfe->nexthop->nh_label->label[0] = nh_label->label[0];
}
diff --git a/zebra/zebra_mroute.c b/zebra/zebra_mroute.c
index 519c120a67..e9cd19ebe0 100644
--- a/zebra/zebra_mroute.c
+++ b/zebra/zebra_mroute.c
@@ -61,7 +61,7 @@ stream_failure:
stream_reset(s);
- zserv_create_header(s, ZEBRA_IPMR_ROUTE_STATS, zvrf_id(zvrf));
+ zclient_create_header(s, ZEBRA_IPMR_ROUTE_STATS, zvrf_id(zvrf));
stream_put_in_addr(s, &mroute.sg.src);
stream_put_in_addr(s, &mroute.sg.grp);
stream_put(s, &mroute.lastused, sizeof(mroute.lastused));
diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c
index 5ede948e0a..b3b9c6d18a 100644
--- a/zebra/zebra_ns.c
+++ b/zebra/zebra_ns.c
@@ -81,7 +81,7 @@ int zebra_ns_init(void)
zebra_vrf_init();
- zebra_ns_enable(0, (void **)&dzns);
+ zebra_ns_enable(NS_DEFAULT, (void **)&dzns);
return 0;
}
diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h
index 0c340d8d59..5d90b9be67 100644
--- a/zebra/zebra_ns.h
+++ b/zebra/zebra_ns.h
@@ -57,9 +57,6 @@ struct zebra_ns {
#endif /* HAVE_RTADV */
};
-#define NS_DEFAULT 0
-#define NS_UNKNOWN UINT16_MAX
-
struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id);
int zebra_ns_init(void);
diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c
index 769d2f5666..7f5fd472f1 100644
--- a/zebra/zebra_ptm.c
+++ b/zebra/zebra_ptm.c
@@ -432,7 +432,7 @@ static void if_bfd_session_update(struct interface *ifp, struct prefix *dp,
} else {
zlog_debug(
"MESSAGE: ZEBRA_INTERFACE_BFD_DEST_UPDATE %s/%d "
- "with src %s/%d and vrf %d %s event",
+ "with src %s/%d and vrf %u %s event",
inet_ntop(dp->family, &dp->u.prefix, buf[0],
INET6_ADDRSTRLEN),
dp->prefixlen,
@@ -816,6 +816,8 @@ int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
ptm_cb.out_data);
zebra_ptm_send_message(ptm_cb.out_data, data_len);
+ return 0;
+
stream_failure:
ptm_lib_cleanup_msg(ptm_hdl, out_ctxt);
return 0;
@@ -946,6 +948,8 @@ int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
zebra_ptm_send_message(ptm_cb.out_data, data_len);
+ return 0;
+
stream_failure:
ptm_lib_cleanup_msg(ptm_hdl, out_ctxt);
return 0;
@@ -957,7 +961,7 @@ int zebra_ptm_bfd_client_register(struct zserv *client,
{
struct stream *s;
unsigned int pid;
- void *out_ctxt;
+ void *out_ctxt = NULL;
char tmp_buf[64];
int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF;
@@ -999,7 +1003,12 @@ int zebra_ptm_bfd_client_register(struct zserv *client,
SET_FLAG(ptm_cb.client_flags[client->proto],
ZEBRA_PTM_BFD_CLIENT_FLAG_REG);
+
+ return 0;
+
stream_failure:
+ if (out_ctxt)
+ ptm_lib_cleanup_msg(ptm_hdl, out_ctxt);
return 0;
}
diff --git a/zebra/zebra_ptm_redistribute.c b/zebra/zebra_ptm_redistribute.c
index 1378ea186d..8fddd400cc 100644
--- a/zebra/zebra_ptm_redistribute.c
+++ b/zebra/zebra_ptm_redistribute.c
@@ -41,7 +41,7 @@ static int zsend_interface_bfd_update(int cmd, struct zserv *client,
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, cmd, vrf_id);
+ zclient_create_header(s, cmd, vrf_id);
if (ifp)
stream_putl(s, ifp->ifindex);
else
@@ -96,8 +96,7 @@ static int zsend_bfd_peer_replay(int cmd, struct zserv *client)
s = client->obuf;
stream_reset(s);
- zserv_create_header(
- s, cmd, VRF_DEFAULT); // Pending: adjust when multi-vrf bfd work
+ zclient_create_header(s, cmd, VRF_DEFAULT);
/* Write packet size. */
stream_putw_at(s, 0, stream_get_endp(s));
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 41e14459b1..c200e2dbb3 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -256,7 +256,7 @@ struct nexthop *route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re,
if (src)
nexthop->src.ipv4 = *src;
nexthop->ifindex = ifindex;
- ifp = if_lookup_by_index(nexthop->ifindex, re->vrf_id);
+ ifp = if_lookup_by_index(nexthop->ifindex, re->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)
@@ -372,6 +372,12 @@ static void nexthop_set_resolved(afi_t afi, struct nexthop *newhop,
break;
}
+ /* Copy labels of the resolved route */
+ if (newhop->nh_label)
+ nexthop_add_labels(resolved_hop, newhop->nh_label_type,
+ newhop->nh_label->num_labels,
+ &newhop->nh_label->label[0]);
+
resolved_hop->rparent = nexthop;
nexthop_add(&nexthop->resolved, resolved_hop);
}
@@ -397,7 +403,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->vrf_id,
+ zebra_deregister_rnh_static_nexthops(re->nh_vrf_id,
nexthop->resolved, top);
nexthops_free(nexthop->resolved);
nexthop->resolved = NULL;
@@ -416,7 +422,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->vrf_id);
+ ifp = if_lookup_by_index(nexthop->ifindex, re->nh_vrf_id);
if (ifp && connected_is_unnumbered(ifp)) {
if (if_is_operative(ifp))
return 1;
@@ -444,7 +450,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
break;
}
/* Lookup table. */
- table = zebra_vrf_table(afi, SAFI_UNICAST, re->vrf_id);
+ table = zebra_vrf_table(afi, SAFI_UNICAST, re->nh_vrf_id);
if (!table)
return 0;
@@ -832,7 +838,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->vrf_id);
+ ifp = if_lookup_by_index(nexthop->ifindex, re->nh_vrf_id);
if (ifp && if_is_operative(ifp))
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else
@@ -860,7 +866,8 @@ static unsigned nexthop_active_check(struct route_node *rn,
if (rn->p.family != AF_INET)
family = AFI_IP6;
if (IN6_IS_ADDR_LINKLOCAL(&nexthop->gate.ipv6)) {
- ifp = if_lookup_by_index(nexthop->ifindex, re->vrf_id);
+ ifp = if_lookup_by_index(nexthop->ifindex,
+ re->nh_vrf_id);
if (ifp && if_is_operative(ifp))
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else
@@ -903,7 +910,7 @@ 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->vrf_id,
+ ret = zebra_route_map_check(family, re->type, p, nexthop, re->nh_vrf_id,
re->tag);
if (ret == RMAP_DENYMATCH) {
if (IS_ZEBRA_DEBUG_RIB) {
@@ -911,7 +918,8 @@ static unsigned nexthop_active_check(struct route_node *rn,
zlog_debug(
"%u:%s: Filtering out with NH out %s due to route map",
re->vrf_id, buf,
- ifindex2ifname(nexthop->ifindex, re->vrf_id));
+ ifindex2ifname(nexthop->ifindex,
+ re->nh_vrf_id));
}
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
}
@@ -990,14 +998,19 @@ int zebra_rib_labeled_unicast(struct route_entry *re)
return 1;
}
-void kernel_route_rib_pass_fail(struct prefix *p, struct route_entry *re,
+void kernel_route_rib_pass_fail(struct route_node *rn, struct prefix *p,
+ struct route_entry *re,
enum southbound_results res)
{
struct nexthop *nexthop;
char buf[PREFIX_STRLEN];
+ rib_dest_t *dest;
+
+ dest = rib_dest_from_rnode(rn);
switch (res) {
case SOUTHBOUND_INSTALL_SUCCESS:
+ dest->selected_fib = re;
for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
continue;
@@ -1011,16 +1024,37 @@ void kernel_route_rib_pass_fail(struct prefix *p, struct route_entry *re,
p, ZAPI_ROUTE_INSTALLED);
break;
case SOUTHBOUND_INSTALL_FAILURE:
+ /*
+ * I am not sure this is the right thing to do here
+ * but the code always set selected_fib before
+ * this assignment was moved here.
+ */
+ dest->selected_fib = re;
+
zsend_route_notify_owner(re->type, re->instance, re->vrf_id,
p, ZAPI_ROUTE_FAIL_INSTALL);
zlog_warn("%u:%s: Route install failed", re->vrf_id,
prefix2str(p, buf, sizeof(buf)));
break;
case SOUTHBOUND_DELETE_SUCCESS:
+ /*
+ * The case where selected_fib is not re is
+ * when we have received a system route
+ * that is overriding our installed route
+ * as such we should leave the selected_fib
+ * pointer alone
+ */
+ if (dest->selected_fib == re)
+ dest->selected_fib = NULL;
for (ALL_NEXTHOPS(re->nexthop, nexthop))
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
break;
case SOUTHBOUND_DELETE_FAILURE:
+ /*
+ * Should we set this to NULL if the
+ * delete fails?
+ */
+ dest->selected_fib = NULL;
zlog_warn("%u:%s: Route Deletion failure", re->vrf_id,
prefix2str(p, buf, sizeof(buf)));
break;
@@ -1075,7 +1109,7 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re,
* the kernel.
*/
hook_call(rib_update, rn, "installing in kernel");
- kernel_route_rib(p, src_p, old, re);
+ kernel_route_rib(rn, p, src_p, old, re);
zvrf->installs++;
return;
@@ -1102,7 +1136,7 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re)
* the kernel.
*/
hook_call(rib_update, rn, "uninstalling from kernel");
- kernel_route_rib(p, src_p, re, NULL);
+ kernel_route_rib(rn, p, src_p, re, NULL);
zvrf->removals++;
return;
@@ -1124,8 +1158,6 @@ static void rib_uninstall(struct route_node *rn, struct route_entry *re)
/* If labeled-unicast route, uninstall transit LSP. */
if (zebra_rib_labeled_unicast(re))
zebra_mpls_lsp_uninstall(info->zvrf, rn, re);
-
- dest->selected_fib = NULL;
}
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
@@ -1210,7 +1242,6 @@ static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
return;
}
- dest->selected_fib = new;
if (IS_ZEBRA_DEBUG_RIB) {
char buf[SRCDEST2STR_BUFFER];
srcdest_rnode2str(rn, buf, sizeof(buf));
@@ -1224,6 +1255,8 @@ static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
if (!RIB_SYSTEM_ROUTE(new))
rib_install_kernel(rn, new, NULL);
+ else
+ dest->selected_fib = new;
UNSET_FLAG(new->status, ROUTE_ENTRY_CHANGED);
}
@@ -1248,8 +1281,17 @@ static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
if (!RIB_SYSTEM_ROUTE(old))
rib_uninstall_kernel(rn, old);
-
- dest->selected_fib = NULL;
+ else {
+ /*
+ * We are setting this to NULL here
+ * because that is what we traditionally
+ * have been doing. I am not positive
+ * that this is the right thing to do
+ * but let's leave the code alone
+ * for the RIB_SYSTEM_ROUTE case
+ */
+ dest->selected_fib = NULL;
+ }
/* Update nexthop for route, reset changed flag. */
nexthop_active_update(rn, old, 1);
@@ -1263,7 +1305,6 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
{
struct nexthop *nexthop = NULL;
int nh_active = 0;
- int installed = 1;
rib_dest_t *dest = rib_dest_from_rnode(rn);
/*
@@ -1313,11 +1354,23 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
zebra_mpls_lsp_install(zvrf, rn, new);
rib_install_kernel(rn, new, old);
+ } else {
+ /*
+ * We do not need to install the
+ * selected route because it
+ * is already isntalled by
+ * the system( ie not us )
+ * so just mark it as winning
+ * we do need to ensure that
+ * if we uninstall a route
+ * from ourselves we don't
+ * over write this pointer
+ */
+ dest->selected_fib = NULL;
}
-
/* If install succeeded or system route, cleanup flags
* for prior route. */
- if (installed && new != old) {
+ if (new != old) {
if (RIB_SYSTEM_ROUTE(new)) {
if (!RIB_SYSTEM_ROUTE(old))
rib_uninstall_kernel(rn, old);
@@ -1328,10 +1381,6 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
NEXTHOP_FLAG_FIB);
}
}
-
- /* Update for redistribution. */
- if (installed)
- dest->selected_fib = new;
}
/*
@@ -1339,7 +1388,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
* failed, we
* may need to uninstall and delete for redistribution.
*/
- if (!nh_active || !installed) {
+ if (!nh_active) {
if (IS_ZEBRA_DEBUG_RIB) {
char buf[SRCDEST2STR_BUFFER];
srcdest_rnode2str(rn, buf, sizeof(buf));
@@ -1366,7 +1415,8 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
if (!RIB_SYSTEM_ROUTE(old))
rib_uninstall_kernel(rn, old);
- dest->selected_fib = NULL;
+ else
+ dest->selected_fib = NULL;
}
} else {
/*
@@ -1379,12 +1429,12 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
* to add routes.
*/
if (!RIB_SYSTEM_ROUTE(new)) {
- int in_fib = 0;
+ bool in_fib = false;
for (ALL_NEXTHOPS(new->nexthop, nexthop))
if (CHECK_FLAG(nexthop->flags,
NEXTHOP_FLAG_FIB)) {
- in_fib = 1;
+ in_fib = true;
break;
}
if (!in_fib)
@@ -2431,6 +2481,11 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
UNSET_FLAG(rtnh->flags,
NEXTHOP_FLAG_FIB);
+ /*
+ * This is a non FRR route
+ * as such we should mark
+ * it as deleted
+ */
dest->selected_fib = NULL;
} else {
/* This means someone else, other than Zebra,
@@ -2496,9 +2551,10 @@ 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, 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, 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,
u_int32_t mtu, uint8_t distance, route_tag_t tag)
{
struct route_entry *re;
@@ -2514,6 +2570,7 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
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 33d0b3a641..8983bdee09 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -951,6 +951,8 @@ static void copy_state(struct rnh *rnh, struct route_entry *re,
state->type = re->type;
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;
@@ -1000,7 +1002,7 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, cmd, vrf_id);
+ zclient_create_header(s, cmd, vrf_id);
stream_putw(s, rn->p.family);
switch (rn->p.family) {
diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c
index 61af60b5da..4c619e5782 100644
--- a/zebra/zebra_routemap.c
+++ b/zebra/zebra_routemap.c
@@ -1193,7 +1193,7 @@ static void *route_set_src_compile(const char *arg)
union g_addr src, *psrc;
if ((inet_pton(AF_INET6, arg, &src.ipv6) == 1)
- || (src.ipv4.s_addr && (inet_pton(AF_INET, arg, &src.ipv4) == 1))) {
+ || (inet_pton(AF_INET, arg, &src.ipv4) == 1)) {
psrc = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(union g_addr));
*psrc = src;
return psrc;
@@ -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->vrf_id;
+ nh_obj.vrf_id = re->nh_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 751ea08a38..2e8ab11b04 100644
--- a/zebra/zebra_static.c
+++ b/zebra/zebra_static.c
@@ -91,7 +91,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
nh_p.family = AF_INET;
nh_p.prefixlen = IPV4_MAX_BITLEN;
nh_p.u.prefix4 = si->addr.ipv4;
- zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
+ zebra_register_rnh_static_nh(si->nh_vrf_id, &nh_p, rn);
break;
case STATIC_IPV4_GATEWAY_IFNAME:
nexthop = route_entry_nexthop_ipv4_ifindex_add(
@@ -111,7 +111,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
nh_p.family = AF_INET6;
nh_p.prefixlen = IPV6_MAX_BITLEN;
nh_p.u.prefix6 = si->addr.ipv6;
- zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
+ zebra_register_rnh_static_nh(si->nh_vrf_id, &nh_p, rn);
break;
case STATIC_IPV6_GATEWAY_IFNAME:
nexthop = route_entry_nexthop_ipv6_ifindex_add(
@@ -141,7 +141,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
*/
if (si->type == STATIC_IPV4_GATEWAY
|| si->type == STATIC_IPV6_GATEWAY)
- zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1,
+ zebra_evaluate_rnh(si->nh_vrf_id, nh_p.family, 1,
RNH_NEXTHOP_TYPE, &nh_p);
else
rib_queue_add(rn);
@@ -155,8 +155,9 @@ 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
+ (si->vrf_id != VRF_DEFAULT)
? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id
: zebrad.rtm_table_default;
re->nexthop_num = 0;
@@ -169,7 +170,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
nh_p.family = AF_INET;
nh_p.prefixlen = IPV4_MAX_BITLEN;
nh_p.u.prefix4 = si->addr.ipv4;
- zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
+ zebra_register_rnh_static_nh(si->nh_vrf_id, &nh_p, rn);
break;
case STATIC_IPV4_GATEWAY_IFNAME:
nexthop = route_entry_nexthop_ipv4_ifindex_add(
@@ -189,7 +190,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
nh_p.family = AF_INET6;
nh_p.prefixlen = IPV6_MAX_BITLEN;
nh_p.u.prefix6 = si->addr.ipv6;
- zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
+ zebra_register_rnh_static_nh(si->nh_vrf_id, &nh_p, rn);
break;
case STATIC_IPV6_GATEWAY_IFNAME:
nexthop = route_entry_nexthop_ipv6_ifindex_add(
@@ -221,7 +222,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
if (si->type == STATIC_IPV4_GATEWAY
|| si->type == STATIC_IPV6_GATEWAY) {
rib_addnode(rn, re, 0);
- zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1,
+ zebra_evaluate_rnh(si->nh_vrf_id, nh_p.family, 1,
RNH_NEXTHOP_TYPE, &nh_p);
} else
rib_addnode(rn, re, 1);
@@ -378,6 +379,7 @@ int static_add_route(afi_t afi, safi_t safi, u_char type, struct prefix *p,
struct prefix_ipv6 *src_p, union g_addr *gate,
const char *ifname, enum static_blackhole_type bh_type,
route_tag_t tag, u_char distance, struct zebra_vrf *zvrf,
+ struct zebra_vrf *nh_zvrf,
struct static_nh_label *snh_label)
{
struct route_node *rn;
@@ -439,6 +441,8 @@ int static_add_route(afi_t afi, safi_t safi, u_char type, struct prefix *p,
si->bh_type = bh_type;
si->tag = tag;
si->vrf_id = zvrf_id(zvrf);
+ si->nh_vrf_id = zvrf_id(nh_zvrf);
+
if (ifname)
strlcpy(si->ifname, ifname, sizeof(si->ifname));
si->ifindex = IFINDEX_INTERNAL;
@@ -493,7 +497,7 @@ int static_add_route(afi_t afi, safi_t safi, u_char type, struct prefix *p,
else {
struct interface *ifp;
- ifp = if_lookup_by_name(ifname, zvrf_id(zvrf));
+ ifp = if_lookup_by_name(ifname, zvrf_id(nh_zvrf));
if (ifp && ifp->ifindex != IFINDEX_INTERNAL) {
si->ifindex = ifp->ifindex;
static_install_route(afi, safi, p, src_p, si);
diff --git a/zebra/zebra_static.h b/zebra/zebra_static.h
index 68fe73b0a3..234e3e4036 100644
--- a/zebra/zebra_static.h
+++ b/zebra/zebra_static.h
@@ -54,6 +54,7 @@ struct static_route {
/* VRF identifier. */
vrf_id_t vrf_id;
+ vrf_id_t nh_vrf_id;
/* Administrative distance. */
u_char distance;
@@ -89,6 +90,7 @@ extern int static_add_route(afi_t, safi_t safi, u_char type, struct prefix *p,
const char *ifname,
enum static_blackhole_type bh_type, route_tag_t tag,
u_char distance, struct zebra_vrf *zvrf,
+ struct zebra_vrf *nh_zvrf,
struct static_nh_label *snh_label);
extern int static_delete_route(afi_t, safi_t safi, u_char type,
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index 1ae9eac61f..246a7e7e4c 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -456,6 +456,7 @@ struct route_table *zebra_vrf_other_route_table(afi_t afi, u_int32_t table_id,
info->afi = afi;
info->safi = SAFI_UNICAST;
table->info = info;
+ table->cleanup = zebra_rtable_node_cleanup;
zvrf->other_table[afi][table_id] = table;
}
@@ -476,12 +477,18 @@ static int vrf_config_write(struct vty *vty)
if (!zvrf)
continue;
- if (strcmp(zvrf_name(zvrf), VRF_DEFAULT_NAME)) {
+ if (vrf->vrf_id != VRF_DEFAULT)
vty_out(vty, "vrf %s\n", zvrf_name(zvrf));
- if (zvrf->l3vni)
- vty_out(vty, " vni %u\n", zvrf->l3vni);
+
+ static_config(vty, zvrf, AFI_IP, SAFI_UNICAST, "ip route");
+ static_config(vty, zvrf, AFI_IP, SAFI_MULTICAST, "ip mroute");
+ static_config(vty, zvrf, AFI_IP6, SAFI_UNICAST, "ipv6 route");
+
+ if (vrf->vrf_id != VRF_DEFAULT && zvrf->l3vni)
+ vty_out(vty, " vni %u\n", zvrf->l3vni);
+
+ if (vrf->vrf_id != VRF_DEFAULT)
vty_out(vty, "!\n");
- }
}
return 0;
}
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 82b0157ad3..f0be862221 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -78,13 +78,16 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty,
#define CMD_VNI_RANGE "(1-16777215)"
/* General function for static route. */
-static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
- const char *negate, const char *dest_str,
- const char *mask_str, const char *src_str,
- const char *gate_str, const char *ifname,
- const char *flag_str, const char *tag_str,
- const char *distance_str, const char *vrf_id_str,
- const char *label_str)
+static int zebra_static_route_leak(struct vty *vty,
+ struct zebra_vrf *zvrf,
+ struct zebra_vrf *nh_zvrf,
+ afi_t afi, safi_t safi,
+ const char *negate, const char *dest_str,
+ const char *mask_str, const char *src_str,
+ const char *gate_str, const char *ifname,
+ const char *flag_str, const char *tag_str,
+ const char *distance_str,
+ const char *label_str)
{
int ret;
u_char distance;
@@ -95,7 +98,6 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
struct in_addr mask;
enum static_blackhole_type bh_type = 0;
route_tag_t tag = 0;
- struct zebra_vrf *zvrf;
u_char type;
struct static_nh_label snh_label;
@@ -145,14 +147,6 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
if (tag_str)
tag = strtoul(tag_str, NULL, 10);
- /* VRF id */
- zvrf = zebra_vrf_lookup_by_name(vrf_id_str);
-
- if (!zvrf) {
- vty_out(vty, "%% vrf %s is not defined\n", vrf_id_str);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
/* Labels */
memset(&snh_label, 0, sizeof(struct static_nh_label));
if (label_str) {
@@ -239,7 +233,8 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
if (!negate)
static_add_route(afi, safi, type, &p, src_p, gatep, ifname,
- bh_type, tag, distance, zvrf, &snh_label);
+ bh_type, tag, distance, zvrf, nh_zvrf,
+ &snh_label);
else
static_delete_route(afi, safi, type, &p, src_p, gatep, ifname,
tag, distance, zvrf, &snh_label);
@@ -247,6 +242,31 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
return CMD_SUCCESS;
}
+static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
+ const char *negate, const char *dest_str,
+ const char *mask_str, const char *src_str,
+ const char *gate_str, const char *ifname,
+ const char *flag_str, const char *tag_str,
+ const char *distance_str, const char *vrf_id_str,
+ const char *label_str)
+{
+ struct zebra_vrf *zvrf;
+
+ /* VRF id */
+ zvrf = zebra_vrf_lookup_by_name(vrf_id_str);
+
+ if (!zvrf) {
+ vty_out(vty, "%% vrf %s is not defined\n", vrf_id_str);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return zebra_static_route_leak(vty, zvrf, zvrf, afi, safi,
+ negate, dest_str, mask_str, src_str,
+ gate_str, ifname, flag_str, tag_str,
+ distance_str, label_str);
+}
+
+
/* Static unicast routes for multicast RPF lookup. */
DEFPY (ip_mroute_dist,
ip_mroute_dist_cmd,
@@ -387,6 +407,37 @@ DEFPY(ip_route_blackhole,
tag_str, distance_str, vrf, label);
}
+DEFPY(ip_route_blackhole_vrf,
+ ip_route_blackhole_vrf_cmd,
+ "[no] ip route\
+ <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
+ <reject|blackhole>$flag \
+ [{ \
+ tag (1-4294967295) \
+ |(1-255)$distance \
+ |label WORD \
+ }]",
+ NO_STR IP_STR
+ "Establish static routes\n"
+ "IP destination prefix (e.g. 10.0.0.0/8)\n"
+ "IP destination prefix\n"
+ "IP destination prefix mask\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"
+ MPLS_LABEL_HELPSTR)
+{
+ VTY_DECLVAR_CONTEXT(vrf, vrf);
+ struct zebra_vrf *zvrf = vrf->info;
+
+ return zebra_static_route_leak(vty, zvrf, zvrf,
+ AFI_IP, SAFI_UNICAST, no, prefix,
+ mask_str, NULL, NULL, NULL, flag,
+ tag_str, distance_str, label);
+}
+
DEFPY(ip_route_address_interface,
ip_route_address_interface_cmd,
"[no] ip route\
@@ -398,6 +449,7 @@ DEFPY(ip_route_address_interface,
|(1-255)$distance \
|vrf NAME \
|label WORD \
+ |nexthop-vrf NAME \
}]",
NO_STR IP_STR
"Establish static routes\n"
@@ -411,16 +463,89 @@ DEFPY(ip_route_address_interface,
"Tag value\n"
"Distance value for this route\n"
VRF_CMD_HELP_STR
- MPLS_LABEL_HELPSTR)
+ MPLS_LABEL_HELPSTR
+ VRF_CMD_HELP_STR)
{
+ struct zebra_vrf *zvrf;
+ struct zebra_vrf *nh_zvrf;
+
const char *flag = NULL;
if (ifname && !strncasecmp(ifname, "Null0", 5)) {
flag = "Null0";
ifname = NULL;
}
- return zebra_static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix,
- mask_str, NULL, gate_str, ifname, flag,
- tag_str, distance_str, vrf, label);
+
+ zvrf = zebra_vrf_lookup_by_name(vrf);
+ if (!zvrf) {
+ vty_out(vty, "%% vrf %s is not defined\n",
+ vrf);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (nexthop_vrf)
+ nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
+ else
+ nh_zvrf = zvrf;
+
+ if (!nh_zvrf) {
+ vty_out(vty, "%% nexthop vrf %s is not defined\n",
+ nexthop_vrf);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return zebra_static_route_leak(vty, zvrf, nh_zvrf,
+ AFI_IP, SAFI_UNICAST, no, prefix,
+ mask_str, NULL, gate_str, ifname, flag,
+ tag_str, distance_str, label);
+}
+
+DEFPY(ip_route_address_interface_vrf,
+ ip_route_address_interface_vrf_cmd,
+ "[no] ip route\
+ <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
+ A.B.C.D$gate \
+ INTERFACE$ifname \
+ [{ \
+ tag (1-4294967295) \
+ |(1-255)$distance \
+ |label WORD \
+ |nexthop-vrf NAME \
+ }]",
+ NO_STR IP_STR
+ "Establish static routes\n"
+ "IP destination prefix (e.g. 10.0.0.0/8)\n"
+ "IP destination prefix\n"
+ "IP destination prefix mask\n"
+ "IP gateway address\n"
+ "IP gateway interface name. Specify 'Null0' (case-insensitive) for a \
+ null route.\n"
+ "Set tag for this route\n"
+ "Tag value\n"
+ "Distance value for this route\n"
+ MPLS_LABEL_HELPSTR
+ VRF_CMD_HELP_STR)
+{
+ VTY_DECLVAR_CONTEXT(vrf, vrf);
+ const char *flag = NULL;
+ struct zebra_vrf *zvrf = vrf->info;
+ struct zebra_vrf *nh_zvrf;
+
+ if (ifname && !strncasecmp(ifname, "Null0", 5)) {
+ flag = "Null0";
+ ifname = NULL;
+ }
+
+ nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
+ if (!nh_zvrf) {
+ vty_out(vty, "%% nexthop vrf %s is not defined\n",
+ nexthop_vrf);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return zebra_static_route_leak(vty, zvrf, nh_zvrf,
+ AFI_IP, SAFI_UNICAST, no, prefix,
+ mask_str, NULL, gate_str, ifname, flag,
+ tag_str, distance_str, label);
}
DEFPY(ip_route,
@@ -433,6 +558,7 @@ DEFPY(ip_route,
|(1-255)$distance \
|vrf NAME \
|label WORD \
+ |nexthop-vrf NAME \
}]",
NO_STR IP_STR
"Establish static routes\n"
@@ -445,16 +571,88 @@ DEFPY(ip_route,
"Tag value\n"
"Distance value for this route\n"
VRF_CMD_HELP_STR
- MPLS_LABEL_HELPSTR)
+ MPLS_LABEL_HELPSTR
+ VRF_CMD_HELP_STR)
{
+ struct zebra_vrf *zvrf;
+ struct zebra_vrf *nh_zvrf;
const char *flag = NULL;
+
if (ifname && !strncasecmp(ifname, "Null0", 5)) {
flag = "Null0";
ifname = NULL;
}
- return zebra_static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix,
- mask_str, NULL, gate_str, ifname, flag,
- tag_str, distance_str, vrf, label);
+
+ zvrf = zebra_vrf_lookup_by_name(vrf);
+ if (!zvrf) {
+ vty_out(vty, "%% vrf %s is not defined\n",
+ vrf);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (nexthop_vrf)
+ nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
+ else
+ nh_zvrf = zvrf;
+
+ if (!nh_zvrf) {
+ vty_out(vty, "%% nexthop vrf %s is not defined\n",
+ nexthop_vrf);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+
+ return zebra_static_route_leak(vty, zvrf, nh_zvrf,
+ AFI_IP, SAFI_UNICAST, no, prefix,
+ mask_str, NULL, gate_str, ifname, flag,
+ tag_str, distance_str, label);
+}
+
+DEFPY(ip_route_vrf,
+ ip_route_vrf_cmd,
+ "[no] ip route\
+ <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
+ <A.B.C.D$gate|INTERFACE$ifname> \
+ [{ \
+ tag (1-4294967295) \
+ |(1-255)$distance \
+ |label WORD \
+ |nexthop-vrf NAME \
+ }]",
+ NO_STR IP_STR
+ "Establish static routes\n"
+ "IP destination prefix (e.g. 10.0.0.0/8)\n"
+ "IP destination prefix\n"
+ "IP destination prefix mask\n"
+ "IP gateway address\n"
+ "IP gateway interface name\n"
+ "Set tag for this route\n"
+ "Tag value\n"
+ "Distance value for this route\n"
+ MPLS_LABEL_HELPSTR
+ VRF_CMD_HELP_STR)
+{
+ VTY_DECLVAR_CONTEXT(vrf, vrf);
+ struct zebra_vrf *zvrf = vrf->info;
+ struct zebra_vrf *nh_zvrf;
+
+ const char *flag = NULL;
+ if (ifname && !strncasecmp(ifname, "Null0", 5)) {
+ flag = "Null0";
+ ifname = NULL;
+ }
+
+ nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
+ if (!nh_zvrf) {
+ vty_out(vty, "%% nexthop vrf %s is not defined\n",
+ nexthop_vrf);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return zebra_static_route_leak(vty, zvrf, nh_zvrf,
+ AFI_IP, SAFI_UNICAST, no, prefix,
+ mask_str, NULL, gate_str, ifname, flag,
+ tag_str, distance_str, label);
}
/* New RIB. Detailed information for IPv4 route. */
@@ -539,7 +737,7 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
if (nexthop->ifindex)
vty_out(vty, ", via %s",
ifindex2ifname(nexthop->ifindex,
- re->vrf_id));
+ re->nh_vrf_id));
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -549,12 +747,12 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
if (nexthop->ifindex)
vty_out(vty, ", via %s",
ifindex2ifname(nexthop->ifindex,
- re->vrf_id));
+ re->nh_vrf_id));
break;
case NEXTHOP_TYPE_IFINDEX:
vty_out(vty, " directly connected, %s",
ifindex2ifname(nexthop->ifindex,
- re->vrf_id));
+ re->nh_vrf_id));
break;
case NEXTHOP_TYPE_BLACKHOLE:
vty_out(vty, " unreachable");
@@ -576,6 +774,14 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
default:
break;
}
+
+ if (re->vrf_id != re->nh_vrf_id) {
+ struct vrf *vrf =
+ vrf_lookup_by_id(re->nh_vrf_id);
+
+ vty_out(vty, "(vrf %s)", vrf->name);
+ }
+
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
vty_out(vty, " (duplicate nexthop removed)");
@@ -715,7 +921,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->vrf_id));
+ re->nh_vrf_id));
}
break;
case NEXTHOP_TYPE_IPV6:
@@ -734,7 +940,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->vrf_id));
+ re->nh_vrf_id));
}
break;
@@ -747,7 +953,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->vrf_id));
+ re->nh_vrf_id));
break;
case NEXTHOP_TYPE_BLACKHOLE:
json_object_boolean_true_add(json_nexthop,
@@ -774,6 +980,14 @@ 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);
+
+ json_object_string_add(json_nexthop,
+ "vrf",
+ vrf->name);
+ }
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
json_object_boolean_true_add(json_nexthop,
"duplicate");
@@ -881,7 +1095,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->vrf_id));
+ re->nh_vrf_id));
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -891,12 +1105,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->vrf_id));
+ re->nh_vrf_id));
break;
case NEXTHOP_TYPE_IFINDEX:
vty_out(vty, " is directly connected, %s",
- ifindex2ifname(nexthop->ifindex, re->vrf_id));
+ ifindex2ifname(nexthop->ifindex,
+ re->nh_vrf_id));
break;
case NEXTHOP_TYPE_BLACKHOLE:
vty_out(vty, " unreachable");
@@ -917,6 +1132,14 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
default:
break;
}
+
+ if (re->nh_vrf_id != re->vrf_id) {
+ struct vrf *vrf =
+ vrf_lookup_by_id(re->nh_vrf_id);
+
+ vty_out(vty, "(vrf %s)", vrf->name);
+ }
+
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
vty_out(vty, " inactive");
@@ -1181,7 +1404,7 @@ DEFUN (ip_nht_default_route,
return CMD_SUCCESS;
zebra_rnh_ip_default_route = 1;
- zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
+ zebra_evaluate_rnh(VRF_DEFAULT, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
return CMD_SUCCESS;
}
@@ -1197,7 +1420,7 @@ DEFUN (no_ip_nht_default_route,
return CMD_SUCCESS;
zebra_rnh_ip_default_route = 0;
- zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
+ zebra_evaluate_rnh(VRF_DEFAULT, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
return CMD_SUCCESS;
}
@@ -1212,7 +1435,7 @@ DEFUN (ipv6_nht_default_route,
return CMD_SUCCESS;
zebra_rnh_ipv6_default_route = 1;
- zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
+ zebra_evaluate_rnh(VRF_DEFAULT, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
return CMD_SUCCESS;
}
@@ -1228,7 +1451,7 @@ DEFUN (no_ipv6_nht_default_route,
return CMD_SUCCESS;
zebra_rnh_ipv6_default_route = 0;
- zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
+ zebra_evaluate_rnh(VRF_DEFAULT, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
return CMD_SUCCESS;
}
@@ -1603,97 +1826,98 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty,
}
/* Write static route configuration. */
-static int static_config(struct vty *vty, afi_t afi, safi_t safi,
- const char *cmd)
+int static_config(struct vty *vty, struct zebra_vrf *zvrf,
+ afi_t afi, safi_t safi, const char *cmd)
{
+ char spacing[100];
struct route_node *rn;
struct static_route *si;
struct route_table *stable;
- struct vrf *vrf;
- struct zebra_vrf *zvrf;
char buf[SRCDEST2STR_BUFFER];
int write = 0;
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if (!(zvrf = vrf->info))
- continue;
- if ((stable = zvrf->stable[afi][safi]) == NULL)
- continue;
+ if ((stable = zvrf->stable[afi][safi]) == NULL)
+ return write;
- for (rn = route_top(stable); rn; rn = srcdest_route_next(rn))
- for (si = rn->info; si; si = si->next) {
- vty_out(vty, "%s %s", cmd,
- srcdest_rnode2str(rn, buf, sizeof buf));
+ sprintf(spacing, "%s%s",
+ (zvrf->vrf->vrf_id == VRF_DEFAULT) ? "" : " ",
+ cmd);
- switch (si->type) {
- case STATIC_IPV4_GATEWAY:
- vty_out(vty, " %s",
- inet_ntoa(si->addr.ipv4));
- break;
- case STATIC_IPV6_GATEWAY:
- vty_out(vty, " %s",
- inet_ntop(AF_INET6,
- &si->addr.ipv6, buf,
- sizeof buf));
- break;
- case STATIC_IFNAME:
- vty_out(vty, " %s", si->ifname);
- break;
- case STATIC_BLACKHOLE:
- switch (si->bh_type) {
- case STATIC_BLACKHOLE_DROP:
- vty_out(vty, " blackhole");
- break;
- case STATIC_BLACKHOLE_NULL:
- vty_out(vty, " Null0");
- break;
- case STATIC_BLACKHOLE_REJECT:
- vty_out(vty, " reject");
- break;
- }
+ for (rn = route_top(stable); rn; rn = srcdest_route_next(rn))
+ for (si = rn->info; si; si = si->next) {
+ vty_out(vty, "%s %s", spacing,
+ srcdest_rnode2str(rn, buf, sizeof buf));
+
+ switch (si->type) {
+ case STATIC_IPV4_GATEWAY:
+ vty_out(vty, " %s",
+ inet_ntoa(si->addr.ipv4));
+ break;
+ case STATIC_IPV6_GATEWAY:
+ vty_out(vty, " %s",
+ inet_ntop(AF_INET6,
+ &si->addr.ipv6, buf,
+ sizeof buf));
+ break;
+ case STATIC_IFNAME:
+ vty_out(vty, " %s", si->ifname);
+ break;
+ case STATIC_BLACKHOLE:
+ switch (si->bh_type) {
+ case STATIC_BLACKHOLE_DROP:
+ vty_out(vty, " blackhole");
break;
- case STATIC_IPV4_GATEWAY_IFNAME:
- vty_out(vty, " %s %s",
- inet_ntop(AF_INET,
- &si->addr.ipv4, buf,
- sizeof buf),
- si->ifname);
+ case STATIC_BLACKHOLE_NULL:
+ vty_out(vty, " Null0");
break;
- case STATIC_IPV6_GATEWAY_IFNAME:
- vty_out(vty, " %s %s",
- inet_ntop(AF_INET6,
- &si->addr.ipv6, buf,
- sizeof buf),
- si->ifname);
+ case STATIC_BLACKHOLE_REJECT:
+ vty_out(vty, " reject");
break;
}
+ break;
+ case STATIC_IPV4_GATEWAY_IFNAME:
+ vty_out(vty, " %s %s",
+ inet_ntop(AF_INET,
+ &si->addr.ipv4, buf,
+ sizeof buf),
+ si->ifname);
+ break;
+ case STATIC_IPV6_GATEWAY_IFNAME:
+ vty_out(vty, " %s %s",
+ inet_ntop(AF_INET6,
+ &si->addr.ipv6, buf,
+ sizeof buf),
+ si->ifname);
+ break;
+ }
- if (si->tag)
- vty_out(vty, " tag %" ROUTE_TAG_PRI,
- si->tag);
+ if (si->tag)
+ vty_out(vty, " tag %" ROUTE_TAG_PRI,
+ si->tag);
- if (si->distance
- != ZEBRA_STATIC_DISTANCE_DEFAULT)
- vty_out(vty, " %d", si->distance);
+ if (si->distance
+ != ZEBRA_STATIC_DISTANCE_DEFAULT)
+ vty_out(vty, " %d", si->distance);
- if (si->vrf_id != VRF_DEFAULT)
- vty_out(vty, " vrf %s",
- zvrf_name(zvrf));
+ if (si->nh_vrf_id != si->vrf_id) {
+ struct vrf *vrf;
+
+ vrf = vrf_lookup_by_id(si->nh_vrf_id);
+ vty_out(vty, " nexthop-vrf %s",
+ (vrf) ? vrf->name : "Unknown");
+ }
- /* Label information */
- if (si->snh_label.num_labels)
- vty_out(vty, " label %s",
- mpls_label2str(
- si->snh_label
- .num_labels,
- si->snh_label.label,
- buf, sizeof buf, 0));
+ /* Label information */
+ if (si->snh_label.num_labels)
+ vty_out(vty, " label %s",
+ mpls_label2str(si->snh_label.num_labels,
+ si->snh_label.label,
+ buf, sizeof buf, 0));
- vty_out(vty, "\n");
+ vty_out(vty, "\n");
- write = 1;
- }
- }
+ write = 1;
+ }
return write;
}
@@ -1727,6 +1951,38 @@ DEFPY(ipv6_route_blackhole,
tag_str, distance_str, vrf, label);
}
+DEFPY(ipv6_route_blackhole_vrf,
+ ipv6_route_blackhole_vrf_cmd,
+ "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
+ <Null0|reject|blackhole>$flag \
+ [{ \
+ tag (1-4294967295) \
+ |(1-255)$distance \
+ |label WORD \
+ }]",
+ NO_STR
+ IPV6_STR
+ "Establish static routes\n"
+ "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 source-dest route\n"
+ "IPv6 source prefix\n"
+ "Null interface\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 prefix\n"
+ MPLS_LABEL_HELPSTR)
+{
+ VTY_DECLVAR_CONTEXT(vrf, vrf);
+ struct zebra_vrf *zvrf = vrf->info;
+
+ return zebra_static_route_leak(vty, zvrf, zvrf,
+ AFI_IP6, SAFI_UNICAST, no, prefix_str,
+ NULL, from_str, NULL, NULL, flag,
+ tag_str, distance_str, label);
+}
+
DEFPY(ipv6_route_address_interface,
ipv6_route_address_interface_cmd,
"[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
@@ -1737,6 +1993,7 @@ DEFPY(ipv6_route_address_interface,
|(1-255)$distance \
|vrf NAME \
|label WORD \
+ |nexthop-vrf NAME \
}]",
NO_STR
IPV6_STR
@@ -1750,11 +2007,72 @@ DEFPY(ipv6_route_address_interface,
"Tag value\n"
"Distance value for this prefix\n"
VRF_CMD_HELP_STR
- MPLS_LABEL_HELPSTR)
+ MPLS_LABEL_HELPSTR
+ VRF_CMD_HELP_STR)
{
- return zebra_static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str,
- NULL, from_str, gate_str, ifname, NULL,
- tag_str, distance_str, vrf, label);
+ struct zebra_vrf *zvrf;
+ struct zebra_vrf *nh_zvrf;
+
+ nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
+ if (!nh_zvrf) {
+ vty_out(vty, "%% nexthop vrf %s is not defined\n",
+ nexthop_vrf);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ zvrf = zebra_vrf_lookup_by_name(vrf);
+ if (!nh_zvrf) {
+ vty_out(vty, "%% nexthop vrf %s is not defined\n",
+ vrf);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return zebra_static_route_leak(vty, zvrf, nh_zvrf,
+ AFI_IP6, SAFI_UNICAST, no, prefix_str,
+ NULL, from_str, gate_str, ifname, NULL,
+ tag_str, distance_str, label);
+}
+
+DEFPY(ipv6_route_address_interface_vrf,
+ ipv6_route_address_interface_vrf_cmd,
+ "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
+ X:X::X:X$gate \
+ INTERFACE$ifname \
+ [{ \
+ tag (1-4294967295) \
+ |(1-255)$distance \
+ |label WORD \
+ |nexthop-vrf NAME \
+ }]",
+ NO_STR
+ IPV6_STR
+ "Establish static routes\n"
+ "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 source-dest route\n"
+ "IPv6 source prefix\n"
+ "IPv6 gateway address\n"
+ "IPv6 gateway interface name\n"
+ "Set tag for this route\n"
+ "Tag value\n"
+ "Distance value for this prefix\n"
+ MPLS_LABEL_HELPSTR
+ VRF_CMD_HELP_STR)
+{
+ VTY_DECLVAR_CONTEXT(vrf, vrf);
+ struct zebra_vrf *zvrf = vrf->info;
+ struct zebra_vrf *nh_zvrf;
+
+ nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
+ if (!nh_zvrf) {
+ vty_out(vty, "%% nexthop vrf %s is not defined\n",
+ nexthop_vrf);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return zebra_static_route_leak(vty, zvrf, nh_zvrf,
+ AFI_IP6, SAFI_UNICAST, no, prefix_str,
+ NULL, from_str, gate_str, ifname, NULL,
+ tag_str, distance_str, label);
}
DEFPY(ipv6_route,
@@ -1766,6 +2084,7 @@ DEFPY(ipv6_route,
|(1-255)$distance \
|vrf NAME \
|label WORD \
+ |nexthop-vrf NAME \
}]",
NO_STR
IPV6_STR
@@ -1779,11 +2098,71 @@ DEFPY(ipv6_route,
"Tag value\n"
"Distance value for this prefix\n"
VRF_CMD_HELP_STR
- MPLS_LABEL_HELPSTR)
+ MPLS_LABEL_HELPSTR
+ VRF_CMD_HELP_STR)
{
- return zebra_static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str,
- NULL, from_str, gate_str, ifname, NULL,
- tag_str, distance_str, vrf, label);
+ struct zebra_vrf *zvrf;
+ struct zebra_vrf *nh_zvrf;
+
+ nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
+ if (!nh_zvrf) {
+ vty_out(vty, "%% nexthop vrf %s is not defined\n",
+ nexthop_vrf);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ zvrf = zebra_vrf_lookup_by_name(vrf);
+ if (!nh_zvrf) {
+ vty_out(vty, "%% nexthop vrf %s is not defined\n",
+ vrf);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return zebra_static_route_leak(vty, zvrf, nh_zvrf,
+ AFI_IP6, SAFI_UNICAST, no, prefix_str,
+ NULL, from_str, gate_str, ifname, NULL,
+ tag_str, distance_str, label);
+}
+
+DEFPY(ipv6_route_vrf,
+ ipv6_route_vrf_cmd,
+ "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
+ <X:X::X:X$gate|INTERFACE$ifname> \
+ [{ \
+ tag (1-4294967295) \
+ |(1-255)$distance \
+ |label WORD \
+ |nexthop-vrf NAME \
+ }]",
+ NO_STR
+ IPV6_STR
+ "Establish static routes\n"
+ "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 source-dest route\n"
+ "IPv6 source prefix\n"
+ "IPv6 gateway address\n"
+ "IPv6 gateway interface name\n"
+ "Set tag for this route\n"
+ "Tag value\n"
+ "Distance value for this prefix\n"
+ MPLS_LABEL_HELPSTR
+ VRF_CMD_HELP_STR)
+{
+ VTY_DECLVAR_CONTEXT(vrf, vrf);
+ struct zebra_vrf *zvrf = vrf->info;
+ struct zebra_vrf *nh_zvrf;
+
+ nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
+ if (!nh_zvrf) {
+ vty_out(vty, "%% nexthop vrf %s is not defined\n",
+ nexthop_vrf);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return zebra_static_route_leak(vty, zvrf, nh_zvrf,
+ AFI_IP6, SAFI_UNICAST, no, prefix_str,
+ NULL, from_str, gate_str, ifname, NULL,
+ tag_str, distance_str, label);
}
/*
@@ -1890,7 +2269,7 @@ DEFUN (show_vrf,
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
if (!(zvrf = vrf->info))
continue;
- if (!zvrf_id(zvrf))
+ if (zvrf_id(zvrf) == VRF_DEFAULT)
continue;
vty_out(vty, "vrf %s ", zvrf_name(zvrf));
@@ -2419,11 +2798,8 @@ static int zebra_ip_config(struct vty *vty)
{
int write = 0;
- write += static_config(vty, AFI_IP, SAFI_UNICAST, "ip route");
- write += static_config(vty, AFI_IP, SAFI_MULTICAST, "ip mroute");
- write += static_config(vty, AFI_IP6, SAFI_UNICAST, "ipv6 route");
-
write += zebra_import_table_config(vty);
+
return write;
}
@@ -2859,8 +3235,11 @@ void zebra_vty_init(void)
install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
install_element(CONFIG_NODE, &ip_route_blackhole_cmd);
+ install_element(VRF_NODE, &ip_route_blackhole_vrf_cmd);
install_element(CONFIG_NODE, &ip_route_address_interface_cmd);
+ install_element(VRF_NODE, &ip_route_address_interface_vrf_cmd);
install_element(CONFIG_NODE, &ip_route_cmd);
+ install_element(VRF_NODE, &ip_route_vrf_cmd);
install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
install_element(CONFIG_NODE, &zebra_workqueue_timer_cmd);
@@ -2882,8 +3261,11 @@ void zebra_vty_init(void)
install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
install_element(CONFIG_NODE, &ipv6_route_blackhole_cmd);
+ install_element(VRF_NODE, &ipv6_route_blackhole_vrf_cmd);
install_element(CONFIG_NODE, &ipv6_route_address_interface_cmd);
+ install_element(VRF_NODE, &ipv6_route_address_interface_vrf_cmd);
install_element(CONFIG_NODE, &ipv6_route_cmd);
+ install_element(VRF_NODE, &ipv6_route_vrf_cmd);
install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 0ef1802367..1690079f68 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -1166,7 +1166,7 @@ static int zvni_macip_send_msg_to_client(vni_t vni,
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, cmd, VRF_DEFAULT);
+ zclient_create_header(s, cmd, VRF_DEFAULT);
stream_putl(s, vni);
stream_put(s, macaddr->octet, ETH_ALEN);
if (ip) {
@@ -2531,7 +2531,7 @@ static int zvni_send_add_to_client(zebra_vni_t *zvni)
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, ZEBRA_VNI_ADD, VRF_DEFAULT);
+ zclient_create_header(s, ZEBRA_VNI_ADD, VRF_DEFAULT);
stream_putl(s, zvni->vni);
stream_put_in_addr(s, &zvni->local_vtep_ip);
stream_put(s, &zvni->vrf_id, sizeof(vrf_id_t)); /* tenant vrf */
@@ -2565,7 +2565,7 @@ static int zvni_send_del_to_client(vni_t vni)
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, ZEBRA_VNI_DEL, VRF_DEFAULT);
+ zclient_create_header(s, ZEBRA_VNI_DEL, VRF_DEFAULT);
stream_putl(s, vni);
/* Write packet size. */
@@ -3550,7 +3550,7 @@ static int zl3vni_send_add_to_client(zebra_l3vni_t *zl3vni)
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, ZEBRA_L3VNI_ADD,
+ zclient_create_header(s, ZEBRA_L3VNI_ADD,
zl3vni_vrf_id(zl3vni));
stream_putl(s, zl3vni->vni);
stream_put(s, &rmac, sizeof(struct ethaddr));
@@ -3586,7 +3586,7 @@ static int zl3vni_send_del_to_client(zebra_l3vni_t *zl3vni)
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, ZEBRA_L3VNI_DEL,
+ zclient_create_header(s, ZEBRA_L3VNI_DEL,
zl3vni_vrf_id(zl3vni));
stream_putl(s, zl3vni->vni);
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 7eded89f6d..3ee2bb59ec 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -149,16 +149,6 @@ int zebra_server_send_message(struct zserv *client)
return 0;
}
-void zserv_create_header(struct stream *s, uint16_t cmd, vrf_id_t vrf_id)
-{
- /* length placeholder, caller can update */
- stream_putw(s, ZEBRA_HEADER_SIZE);
- stream_putc(s, ZEBRA_HEADER_MARKER);
- stream_putc(s, ZSERV_VERSION);
- stream_putw(s, vrf_id);
- stream_putw(s, cmd);
-}
-
static void zserv_encode_interface(struct stream *s, struct interface *ifp)
{
/* Interface information. */
@@ -221,7 +211,7 @@ int zsend_interface_add(struct zserv *client, struct interface *ifp)
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, ZEBRA_INTERFACE_ADD, ifp->vrf_id);
+ zclient_create_header(s, ZEBRA_INTERFACE_ADD, ifp->vrf_id);
zserv_encode_interface(s, ifp);
client->ifadd_cnt++;
@@ -236,7 +226,7 @@ int zsend_interface_delete(struct zserv *client, struct interface *ifp)
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id);
+ zclient_create_header(s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id);
zserv_encode_interface(s, ifp);
client->ifdel_cnt++;
@@ -250,7 +240,7 @@ int zsend_vrf_add(struct zserv *client, struct zebra_vrf *zvrf)
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, ZEBRA_VRF_ADD, zvrf_id(zvrf));
+ zclient_create_header(s, ZEBRA_VRF_ADD, zvrf_id(zvrf));
zserv_encode_vrf(s, zvrf);
client->vrfadd_cnt++;
@@ -265,7 +255,7 @@ int zsend_vrf_delete(struct zserv *client, struct zebra_vrf *zvrf)
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, ZEBRA_VRF_DELETE, zvrf_id(zvrf));
+ zclient_create_header(s, ZEBRA_VRF_DELETE, zvrf_id(zvrf));
zserv_encode_vrf(s, zvrf);
client->vrfdel_cnt++;
@@ -285,7 +275,7 @@ int zsend_interface_link_params(struct zserv *client, struct interface *ifp)
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, ZEBRA_INTERFACE_LINK_PARAMS, ifp->vrf_id);
+ zclient_create_header(s, ZEBRA_INTERFACE_LINK_PARAMS, ifp->vrf_id);
/* Add Interface Index */
stream_putl(s, ifp->ifindex);
@@ -348,7 +338,7 @@ int zsend_interface_address(int cmd, struct zserv *client,
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, cmd, ifp->vrf_id);
+ zclient_create_header(s, cmd, ifp->vrf_id);
stream_putl(s, ifp->ifindex);
/* Interface address flag. */
@@ -393,7 +383,7 @@ static int zsend_interface_nbr_address(int cmd, struct zserv *client,
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, cmd, ifp->vrf_id);
+ zclient_create_header(s, cmd, ifp->vrf_id);
stream_putl(s, ifp->ifindex);
/* Prefix information. */
@@ -504,11 +494,11 @@ int zsend_interface_vrf_update(struct zserv *client, struct interface *ifp,
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id);
+ zclient_create_header(s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id);
/* Fill in the ifIndex of the interface and its new VRF (id) */
stream_putl(s, ifp->ifindex);
- stream_putw(s, vrf_id);
+ stream_putl(s, vrf_id);
/* Write packet size. */
stream_putw_at(s, 0, stream_get_endp(s));
@@ -581,7 +571,7 @@ int zsend_interface_update(int cmd, struct zserv *client, struct interface *ifp)
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, cmd, ifp->vrf_id);
+ zclient_create_header(s, cmd, ifp->vrf_id);
zserv_encode_interface(s, ifp);
if (cmd == ZEBRA_INTERFACE_UP)
@@ -602,6 +592,7 @@ 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;
@@ -957,7 +948,7 @@ static int zsend_ipv4_nexthop_lookup_mrib(struct zserv *client,
stream_reset(s);
/* Fill in result. */
- zserv_create_header(s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf_id(zvrf));
+ zclient_create_header(s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf_id(zvrf));
stream_put_in_addr(s, &addr);
if (re) {
@@ -1009,7 +1000,7 @@ int zsend_route_notify_owner(u_char proto, u_short instance,
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, ZEBRA_ROUTE_NOTIFY_OWNER, vrf_id);
+ zclient_create_header(s, ZEBRA_ROUTE_NOTIFY_OWNER, vrf_id);
stream_put(s, &note, sizeof(note));
@@ -1039,7 +1030,7 @@ int zsend_router_id_update(struct zserv *client, struct prefix *p,
stream_reset(s);
/* Message type. */
- zserv_create_header(s, ZEBRA_ROUTER_ID_UPDATE, vrf_id);
+ zclient_create_header(s, ZEBRA_ROUTER_ID_UPDATE, vrf_id);
/* Prefix information. */
stream_putc(s, p->family);
@@ -1063,7 +1054,7 @@ int zsend_pw_update(struct zserv *client, struct zebra_pw *pw)
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, ZEBRA_PW_STATUS_UPDATE, pw->vrf_id);
+ zclient_create_header(s, ZEBRA_PW_STATUS_UPDATE, pw->vrf_id);
stream_write(s, pw->ifname, IF_NAMESIZE);
stream_putl(s, pw->ifindex);
stream_putl(s, pw->status);
@@ -1146,6 +1137,7 @@ 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)) {
@@ -1372,6 +1364,7 @@ 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)) {
@@ -1581,6 +1574,7 @@ 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
@@ -1866,6 +1860,8 @@ static int zread_ipv6_add(struct zserv *client, u_short length,
/* 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);
@@ -2089,7 +2085,7 @@ static int zsend_label_manager_connect_response(struct zserv *client,
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, ZEBRA_LABEL_MANAGER_CONNECT, vrf_id);
+ zclient_create_header(s, ZEBRA_LABEL_MANAGER_CONNECT, vrf_id);
/* result */
stream_putc(s, result);
@@ -2151,7 +2147,7 @@ static int zsend_assign_label_chunk_response(struct zserv *client,
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, ZEBRA_GET_LABEL_CHUNK, vrf_id);
+ zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, vrf_id);
if (lmc) {
/* keep */
@@ -2472,11 +2468,11 @@ static int zread_interface_set_master(struct zserv *client,
int ifindex;
vrf_id_t vrf_id;
- STREAM_GETW(s, vrf_id);
+ STREAM_GETL(s, vrf_id);
STREAM_GETL(s, ifindex);
master = if_lookup_by_index(ifindex, vrf_id);
- STREAM_GETW(s, vrf_id);
+ STREAM_GETL(s, vrf_id);
STREAM_GETL(s, ifindex);
slave = if_lookup_by_index(ifindex, vrf_id);
@@ -2714,7 +2710,7 @@ static int zebra_client_read(struct thread *thread)
STREAM_GETW(client->ibuf, length);
STREAM_GETC(client->ibuf, marker);
STREAM_GETC(client->ibuf, version);
- STREAM_GETW(client->ibuf, vrf_id);
+ STREAM_GETL(client->ibuf, vrf_id);
STREAM_GETW(client->ibuf, command);
if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
diff --git a/zebra/zserv.h b/zebra/zserv.h
index 63db9d9eb9..4b3b0041b8 100644
--- a/zebra/zserv.h
+++ b/zebra/zserv.h
@@ -177,8 +177,6 @@ extern int zsend_route_notify_owner(u_char proto, u_short instance,
vrf_id_t vrf_id, struct prefix *p,
enum zapi_route_notify_owner note);
-extern void zserv_create_header(struct stream *s, uint16_t cmd,
- vrf_id_t vrf_id);
extern void zserv_nexthop_num_warn(const char *, const struct prefix *,
const unsigned int);
extern int zebra_server_send_message(struct zserv *client);