mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 13:33:15 +00:00
Merge pull request #1618 from donaldsharp/zebra_startup_ordering
zebra route-leaking for static routes
This commit is contained in:
commit
d6fed38109
@ -166,6 +166,7 @@ zebra_route(int add, int family, const unsigned char *pref, unsigned short plen,
|
||||
api.type = ZEBRA_ROUTE_BABEL;
|
||||
api.safi = SAFI_UNICAST;
|
||||
api.vrf_id = VRF_DEFAULT;
|
||||
api.nh_vrf_id = VRF_DEFAULT;
|
||||
api.prefix = quagga_prefix;
|
||||
|
||||
if(metric >= KERNEL_INFINITY) {
|
||||
|
@ -1001,6 +1001,7 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
|
||||
memset(&api, 0, sizeof(api));
|
||||
memcpy(&api.rmac, &(info->attr->rmac), sizeof(struct ethaddr));
|
||||
api.vrf_id = bgp->vrf_id;
|
||||
api.nh_vrf_id = bgp->vrf_id;
|
||||
api.type = ZEBRA_ROUTE_BGP;
|
||||
api.safi = safi;
|
||||
api.prefix = *p;
|
||||
@ -1253,6 +1254,7 @@ void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info, safi_t safi)
|
||||
memset(&api, 0, sizeof(api));
|
||||
memcpy(&api.rmac, &(info->attr->rmac), sizeof(struct ethaddr));
|
||||
api.vrf_id = peer->bgp->vrf_id;
|
||||
api.nh_vrf_id = peer->bgp->vrf_id;
|
||||
api.type = ZEBRA_ROUTE_BGP;
|
||||
api.safi = safi;
|
||||
api.prefix = *p;
|
||||
|
@ -396,6 +396,7 @@ static void vnc_zebra_route_msg(struct prefix *p, unsigned int nhp_count,
|
||||
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = VRF_DEFAULT;
|
||||
api.nh_vrf_id = VRF_DEFAULT;
|
||||
api.type = ZEBRA_ROUTE_VNC;
|
||||
api.safi = SAFI_UNICAST;
|
||||
api.prefix = *p;
|
||||
|
@ -366,6 +366,7 @@ void eigrp_zebra_route_add(struct prefix *p, struct list *successors)
|
||||
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = VRF_DEFAULT;
|
||||
api.nh_vrf_id = VRF_DEFAULT;
|
||||
api.type = ZEBRA_ROUTE_EIGRP;
|
||||
api.safi = SAFI_UNICAST;
|
||||
memcpy(&api.prefix, p, sizeof(*p));
|
||||
@ -407,6 +408,7 @@ void eigrp_zebra_route_delete(struct prefix *p)
|
||||
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = VRF_DEFAULT;
|
||||
api.nh_vrf_id = VRF_DEFAULT;
|
||||
api.type = ZEBRA_ROUTE_EIGRP;
|
||||
api.safi = SAFI_UNICAST;
|
||||
memcpy(&api.prefix, p, sizeof(*p));
|
||||
|
@ -261,6 +261,7 @@ static void isis_zebra_route_add_route(struct prefix *prefix,
|
||||
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = VRF_DEFAULT;
|
||||
api.nh_vrf_id = VRF_DEFAULT;
|
||||
api.type = ZEBRA_ROUTE_ISIS;
|
||||
api.safi = SAFI_UNICAST;
|
||||
api.prefix = *prefix;
|
||||
@ -329,6 +330,7 @@ static void isis_zebra_route_del_route(struct prefix *prefix,
|
||||
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = VRF_DEFAULT;
|
||||
api.nh_vrf_id = VRF_DEFAULT;
|
||||
api.type = ZEBRA_ROUTE_ISIS;
|
||||
api.safi = SAFI_UNICAST;
|
||||
api.prefix = *prefix;
|
||||
|
12
lib/if.c
12
lib/if.c
@ -219,6 +219,18 @@ struct interface *if_lookup_by_index(ifindex_t ifindex, vrf_id_t vrf_id)
|
||||
struct vrf *vrf;
|
||||
struct interface if_tmp;
|
||||
|
||||
if (vrf_id == VRF_UNKNOWN) {
|
||||
struct interface *ifp;
|
||||
|
||||
RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) {
|
||||
ifp = if_lookup_by_index(ifindex, vrf->vrf_id);
|
||||
if (ifp)
|
||||
return ifp;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vrf = vrf_lookup_by_id(vrf_id);
|
||||
if (!vrf)
|
||||
return NULL;
|
||||
|
7
lib/if.h
7
lib/if.h
@ -452,6 +452,13 @@ struct nbr_connected {
|
||||
/* Prototypes. */
|
||||
extern int if_cmp_name_func(char *, char *);
|
||||
|
||||
/*
|
||||
* Passing in VRF_UNKNOWN is a valid thing to do, unless we
|
||||
* are creating a new interface.
|
||||
*
|
||||
* This is useful for vrf route-leaking. So more than anything
|
||||
* else think before you use VRF_UNKNOWN
|
||||
*/
|
||||
extern void if_update_to_new_vrf(struct interface *, vrf_id_t vrf_id);
|
||||
extern struct interface *if_create(const char *name, vrf_id_t vrf_id);
|
||||
extern struct interface *if_lookup_by_index(ifindex_t, vrf_id_t vrf_id);
|
||||
|
@ -942,6 +942,8 @@ int zapi_route_encode(u_char cmd, struct stream *s, struct zapi_route *api)
|
||||
}
|
||||
|
||||
stream_putw(s, api->nexthop_num);
|
||||
if (api->nexthop_num)
|
||||
stream_putw(s, api->nh_vrf_id);
|
||||
|
||||
for (i = 0; i < api->nexthop_num; i++) {
|
||||
api_nh = &api->nexthops[i];
|
||||
@ -1091,6 +1093,9 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (api->nexthop_num)
|
||||
STREAM_GETW(s, api->nh_vrf_id);
|
||||
|
||||
for (i = 0; i < api->nexthop_num; i++) {
|
||||
api_nh = &api->nexthops[i];
|
||||
|
||||
|
@ -281,6 +281,7 @@ struct zapi_route {
|
||||
u_int32_t mtu;
|
||||
|
||||
vrf_id_t vrf_id;
|
||||
vrf_id_t nh_vrf_id;
|
||||
|
||||
struct ethaddr rmac;
|
||||
};
|
||||
@ -420,6 +421,11 @@ extern struct interface *zebra_interface_vrf_update_read(struct stream *s,
|
||||
vrf_id_t *new_vrf_id);
|
||||
extern void zebra_interface_if_set_value(struct stream *, struct interface *);
|
||||
extern void zebra_router_id_update_read(struct stream *s, struct prefix *rid);
|
||||
|
||||
#if CONFDATE > 20180823
|
||||
CPP_NOTICE("zapi_ipv4_route, zapi_ipv6_route, zapi_ipv4_route_ipv6_nexthop as well as the zapi_ipv4 and zapi_ipv6 data structures should be removed now");
|
||||
#endif
|
||||
|
||||
extern int zapi_ipv4_route(u_char, struct zclient *, struct prefix_ipv4 *,
|
||||
struct zapi_ipv4 *) __attribute__((deprecated));
|
||||
|
||||
|
@ -95,6 +95,8 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.type = ZEBRA_ROUTE_NHRP;
|
||||
api.safi = SAFI_UNICAST;
|
||||
api.vrf_id = VRF_DEFAULT;
|
||||
api.nh_vrf_id = VRF_DEFAULT;
|
||||
api.prefix = *p;
|
||||
|
||||
switch (type) {
|
||||
|
@ -337,6 +337,7 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request)
|
||||
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = VRF_DEFAULT;
|
||||
api.nh_vrf_id = VRF_DEFAULT;
|
||||
api.type = ZEBRA_ROUTE_OSPF6;
|
||||
api.safi = SAFI_UNICAST;
|
||||
api.prefix = *dest;
|
||||
@ -387,6 +388,7 @@ void ospf6_zebra_add_discard(struct ospf6_route *request)
|
||||
if (!CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) {
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = VRF_DEFAULT;
|
||||
api.nh_vrf_id = VRF_DEFAULT;
|
||||
api.type = ZEBRA_ROUTE_OSPF6;
|
||||
api.safi = SAFI_UNICAST;
|
||||
api.prefix = *dest;
|
||||
@ -420,6 +422,7 @@ void ospf6_zebra_delete_discard(struct ospf6_route *request)
|
||||
if (CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) {
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = VRF_DEFAULT;
|
||||
api.nh_vrf_id = VRF_DEFAULT;
|
||||
api.type = ZEBRA_ROUTE_OSPF6;
|
||||
api.safi = SAFI_UNICAST;
|
||||
api.prefix = *dest;
|
||||
|
@ -389,6 +389,7 @@ void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p,
|
||||
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = ospf->vrf_id;
|
||||
api.nh_vrf_id = ospf->vrf_id;
|
||||
api.type = ZEBRA_ROUTE_OSPF;
|
||||
api.instance = ospf->instance;
|
||||
api.safi = SAFI_UNICAST;
|
||||
@ -466,6 +467,7 @@ void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p,
|
||||
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = ospf->vrf_id;
|
||||
api.nh_vrf_id = ospf->vrf_id;
|
||||
api.type = ZEBRA_ROUTE_OSPF;
|
||||
api.instance = ospf->instance;
|
||||
api.safi = SAFI_UNICAST;
|
||||
@ -487,6 +489,7 @@ void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p)
|
||||
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = ospf->vrf_id;
|
||||
api.nh_vrf_id = ospf->vrf_id;
|
||||
api.type = ZEBRA_ROUTE_OSPF;
|
||||
api.instance = ospf->instance;
|
||||
api.safi = SAFI_UNICAST;
|
||||
@ -506,6 +509,7 @@ void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p)
|
||||
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = ospf->vrf_id;
|
||||
api.nh_vrf_id = ospf->vrf_id;
|
||||
api.type = ZEBRA_ROUTE_OSPF;
|
||||
api.instance = ospf->instance;
|
||||
api.safi = SAFI_UNICAST;
|
||||
|
@ -48,6 +48,7 @@ static void rip_zebra_ipv4_send(struct route_node *rp, u_char cmd)
|
||||
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = VRF_DEFAULT;
|
||||
api.nh_vrf_id = VRF_DEFAULT;
|
||||
api.type = ZEBRA_ROUTE_RIP;
|
||||
api.safi = SAFI_UNICAST;
|
||||
|
||||
|
@ -48,6 +48,7 @@ static void ripng_zebra_ipv6_send(struct route_node *rp, u_char cmd)
|
||||
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = VRF_DEFAULT;
|
||||
api.nh_vrf_id = VRF_DEFAULT;
|
||||
api.type = ZEBRA_ROUTE_RIPNG;
|
||||
api.safi = SAFI_UNICAST;
|
||||
api.prefix = rp->p;
|
||||
|
@ -159,6 +159,7 @@ void route_add(struct prefix *p, struct nexthop *nh)
|
||||
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = VRF_DEFAULT;
|
||||
api.nh_vrf_id = VRF_DEFAULT;
|
||||
api.type = ZEBRA_ROUTE_SHARP;
|
||||
api.safi = SAFI_UNICAST;
|
||||
memcpy(&api.prefix, p, sizeof(*p));
|
||||
@ -180,6 +181,7 @@ void route_delete(struct prefix *p)
|
||||
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = VRF_DEFAULT;
|
||||
api.nh_vrf_id = VRF_DEFAULT;
|
||||
api.type = ZEBRA_ROUTE_SHARP;
|
||||
api.safi = SAFI_UNICAST;
|
||||
memcpy(&api.prefix, p, sizeof(*p));
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
17
zebra/main.c
17
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);
|
||||
|
@ -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 */
|
||||
|
@ -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));
|
||||
@ -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,
|
||||
@ -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): "
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
@ -403,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;
|
||||
@ -422,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;
|
||||
@ -450,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;
|
||||
|
||||
@ -838,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
|
||||
@ -866,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
|
||||
@ -909,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) {
|
||||
@ -917,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);
|
||||
}
|
||||
@ -2502,9 +2504,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;
|
||||
@ -2520,6 +2523,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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,6 +155,7 @@ 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
|
||||
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -476,13 +476,19 @@ 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)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -78,12 +78,15 @@ 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,
|
||||
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 *vrf_id_str,
|
||||
const char *distance_str,
|
||||
const char *label_str)
|
||||
{
|
||||
int ret;
|
||||
@ -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,85 @@ 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,
|
||||
|
||||
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_IP, SAFI_UNICAST, no, prefix,
|
||||
mask_str, NULL, gate_str, ifname, flag,
|
||||
tag_str, distance_str, vrf, label);
|
||||
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 +554,7 @@ DEFPY(ip_route,
|
||||
|(1-255)$distance \
|
||||
|vrf NAME \
|
||||
|label WORD \
|
||||
|nexthop-vrf NAME \
|
||||
}]",
|
||||
NO_STR IP_STR
|
||||
"Establish static routes\n"
|
||||
@ -445,16 +567,83 @@ 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;
|
||||
}
|
||||
|
||||
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_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;
|
||||
}
|
||||
return zebra_static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix,
|
||||
|
||||
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, vrf, label);
|
||||
tag_str, distance_str, label);
|
||||
}
|
||||
|
||||
/* New RIB. Detailed information for IPv4 route. */
|
||||
@ -539,7 +728,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 +738,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 +765,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 +912,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 +931,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 +944,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 +971,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 +1086,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 +1096,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 +1123,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");
|
||||
|
||||
@ -1603,26 +1817,26 @@ 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;
|
||||
return write;
|
||||
|
||||
sprintf(spacing, "%s%s",
|
||||
(zvrf->vrf->vrf_id == VRF_DEFAULT) ? "" : " ",
|
||||
cmd);
|
||||
|
||||
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,
|
||||
vty_out(vty, "%s %s", spacing,
|
||||
srcdest_rnode2str(rn, buf, sizeof buf));
|
||||
|
||||
switch (si->type) {
|
||||
@ -1676,16 +1890,18 @@ static int static_config(struct vty *vty, afi_t afi, safi_t safi,
|
||||
!= 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,
|
||||
mpls_label2str(si->snh_label.num_labels,
|
||||
si->snh_label.label,
|
||||
buf, sizeof buf, 0));
|
||||
|
||||
@ -1693,7 +1909,6 @@ static int static_config(struct vty *vty, afi_t afi, safi_t safi,
|
||||
|
||||
write = 1;
|
||||
}
|
||||
}
|
||||
return write;
|
||||
}
|
||||
|
||||
@ -1727,6 +1942,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 +1984,7 @@ DEFPY(ipv6_route_address_interface,
|
||||
|(1-255)$distance \
|
||||
|vrf NAME \
|
||||
|label WORD \
|
||||
|nexthop-vrf NAME \
|
||||
}]",
|
||||
NO_STR
|
||||
IPV6_STR
|
||||
@ -1750,11 +1998,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,
|
||||
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, vrf, label);
|
||||
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 +2075,7 @@ DEFPY(ipv6_route,
|
||||
|(1-255)$distance \
|
||||
|vrf NAME \
|
||||
|label WORD \
|
||||
|nexthop-vrf NAME \
|
||||
}]",
|
||||
NO_STR
|
||||
IPV6_STR
|
||||
@ -1779,11 +2089,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,
|
||||
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, vrf, label);
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2419,11 +2789,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 +3226,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 +3252,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);
|
||||
|
@ -592,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;
|
||||
@ -1136,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)) {
|
||||
@ -1362,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)) {
|
||||
@ -1571,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
|
||||
@ -1856,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);
|
||||
|
Loading…
Reference in New Issue
Block a user