summaryrefslogtreecommitdiff
path: root/zebra
diff options
context:
space:
mode:
Diffstat (limited to 'zebra')
-rw-r--r--zebra/connected.c4
-rw-r--r--zebra/debug.c12
-rw-r--r--zebra/kernel_socket.c8
-rw-r--r--zebra/redistribute.c2
-rw-r--r--zebra/rib.h2
-rw-r--r--zebra/rt_netlink.c25
-rw-r--r--zebra/zebra_mpls.h18
-rw-r--r--zebra/zebra_ns.c2
-rw-r--r--zebra/zebra_rib.c156
-rw-r--r--zebra/zebra_vty.c186
-rw-r--r--zebra/zserv.c6
11 files changed, 254 insertions, 167 deletions
diff --git a/zebra/connected.c b/zebra/connected.c
index 77a560c6bd..18dc6a970b 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -396,10 +396,10 @@ void connected_down(struct interface *ifp, struct connected *ifc)
* head.
*/
rib_delete(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
- &p, NULL, &nh, 0, 0);
+ &p, NULL, &nh, 0, 0, false);
rib_delete(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
- 0, &p, NULL, &nh, 0, 0);
+ 0, &p, NULL, &nh, 0, 0, false);
if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
char buf[PREFIX_STRLEN];
diff --git a/zebra/debug.c b/zebra/debug.c
index afeba1c6de..ac96051abd 100644
--- a/zebra/debug.c
+++ b/zebra/debug.c
@@ -83,6 +83,8 @@ DEFUN_NOSH (show_debugging_zebra,
vty_out(vty, " Zebra next-hop tracking debugging is on\n");
if (IS_ZEBRA_DEBUG_MPLS)
vty_out(vty, " Zebra MPLS debugging is on\n");
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ vty_out(vty, " Zebra VXLAN debugging is on\n");
if (IS_ZEBRA_DEBUG_PW)
vty_out(vty, " Zebra pseudowire debugging is on\n");
@@ -97,7 +99,7 @@ DEFUN (debug_zebra_events,
"Debug option set for zebra events\n")
{
zebra_debug_event = ZEBRA_DEBUG_EVENT;
- return CMD_WARNING_CONFIG_FAILED;
+ return CMD_SUCCESS;
}
DEFUN (debug_zebra_nht,
@@ -108,7 +110,7 @@ DEFUN (debug_zebra_nht,
"Debug option set for zebra next hop tracking\n")
{
zebra_debug_nht = ZEBRA_DEBUG_NHT;
- return CMD_WARNING_CONFIG_FAILED;
+ return CMD_SUCCESS;
}
DEFUN (debug_zebra_mpls,
@@ -119,7 +121,7 @@ DEFUN (debug_zebra_mpls,
"Debug option set for zebra MPLS LSPs\n")
{
zebra_debug_mpls = ZEBRA_DEBUG_MPLS;
- return CMD_WARNING_CONFIG_FAILED;
+ return CMD_SUCCESS;
}
DEFUN (debug_zebra_vxlan,
@@ -130,7 +132,7 @@ DEFUN (debug_zebra_vxlan,
"Debug option set for zebra VxLAN (EVPN)\n")
{
zebra_debug_vxlan = ZEBRA_DEBUG_VXLAN;
- return CMD_WARNING;
+ return CMD_SUCCESS;
}
DEFUN (debug_zebra_pw,
@@ -145,7 +147,7 @@ DEFUN (debug_zebra_pw,
UNSET_FLAG(zebra_debug_pw, ZEBRA_DEBUG_PW);
else
SET_FLAG(zebra_debug_pw, ZEBRA_DEBUG_PW);
- return CMD_WARNING;
+ return CMD_SUCCESS;
}
DEFUN (debug_zebra_packet,
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index df8cdb3ab3..9907ef5b79 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -1042,7 +1042,7 @@ void rtm_read(struct rt_msghdr *rtm)
if (rtm->rtm_type == RTM_CHANGE)
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
- NULL, 0, 0);
+ NULL, 0, 0, true);
if (!nh.type) {
nh.type = NEXTHOP_TYPE_IPV4;
@@ -1057,7 +1057,7 @@ void rtm_read(struct rt_msghdr *rtm)
else
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
- &nh, 0, 0);
+ &nh, 0, 0, true);
}
if (dest.sa.sa_family == AF_INET6) {
/* One day we might have a debug section here like one in the
@@ -1088,7 +1088,7 @@ void rtm_read(struct rt_msghdr *rtm)
if (rtm->rtm_type == RTM_CHANGE)
rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
- NULL, 0, 0);
+ NULL, 0, 0, true);
if (!nh.type) {
nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX
@@ -1105,7 +1105,7 @@ void rtm_read(struct rt_msghdr *rtm)
else
rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
- &nh, 0, 0);
+ &nh, 0, 0, true);
}
}
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index 76e0df40b9..890ad887da 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -558,7 +558,7 @@ int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re)
rib_delete(afi, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE,
re->table, re->flags, &p, NULL, NULL,
- zebrad.rtm_table_default, re->metric);
+ zebrad.rtm_table_default, re->metric, false);
return 0;
}
diff --git a/zebra/rib.h b/zebra/rib.h
index fec5c2aacf..e3ed6210ca 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -304,7 +304,7 @@ extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *,
extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
u_short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, const struct nexthop *nh,
- u_int32_t table_id, u_int32_t metric);
+ u_int32_t table_id, u_int32_t metric, bool fromkernel);
extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t,
union g_addr *,
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 039fac4e67..573f60f4ca 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -526,7 +526,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
if (re->nexthop_num == 0)
XFREE(MTYPE_RE, re);
else
- rib_add_multipath(AFI_IP, SAFI_UNICAST, &p,
+ rib_add_multipath(afi, SAFI_UNICAST, &p,
NULL, re);
}
} else {
@@ -560,13 +560,13 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
memcpy(&nh.gate, gate, sz);
rib_delete(afi, SAFI_UNICAST, vrf_id,
proto, 0, flags, &p, NULL, &nh,
- table, metric);
+ table, metric, true);
} else {
/* XXX: need to compare the entire list of nexthops
* here for NLM_F_APPEND stupidity */
rib_delete(afi, SAFI_UNICAST, vrf_id,
proto, 0, flags, &p, NULL, NULL,
- table, metric);
+ table, metric, true);
}
}
@@ -1446,8 +1446,8 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
&& CHECK_FLAG(nexthop->flags,
NEXTHOP_FLAG_FIB))) {
routedesc = nexthop->rparent
- ? "recursive, 1 hop"
- : "single hop";
+ ? "recursive, single-path"
+ : "single-path";
_netlink_route_debug(cmd, p, nexthop, routedesc,
family, zvrf);
@@ -1529,8 +1529,8 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
&& CHECK_FLAG(nexthop->flags,
NEXTHOP_FLAG_FIB))) {
routedesc = nexthop->rparent
- ? "recursive, multihop"
- : "multihop";
+ ? "recursive, multipath"
+ : "multipath";
nexthop_num++;
_netlink_route_debug(cmd, p, nexthop, routedesc,
@@ -2349,6 +2349,7 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
unsigned int nexthop_num;
const char *routedesc;
struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT);
+ int route_type;
struct {
struct nlmsghdr n;
@@ -2382,9 +2383,11 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
}
}
- if (nexthop_num == 0) // unexpected
+ if (nexthop_num == 0 || !lsp->best_nhlfe) // unexpected
return 0;
+ route_type = re_type_from_lsp_type(lsp->best_nhlfe->type);
+
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
req.n.nlmsg_type = cmd;
@@ -2393,7 +2396,7 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
req.r.rtm_family = AF_MPLS;
req.r.rtm_table = RT_TABLE_MAIN;
req.r.rtm_dst_len = MPLS_LABEL_LEN_BITS;
- req.r.rtm_protocol = RTPROT_ZEBRA;
+ req.r.rtm_protocol = zebra2proto(route_type);
req.r.rtm_scope = RT_SCOPE_UNIVERSE;
req.r.rtm_type = RTN_UNICAST;
@@ -2409,7 +2412,7 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
* chosen depend on the operation.
*/
if (nexthop_num == 1 || multipath_num == 1) {
- routedesc = "single hop";
+ routedesc = "single-path";
_netlink_mpls_debug(cmd, lsp->ile.in_label, routedesc);
nexthop_num = 0;
@@ -2457,7 +2460,7 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
rta->rta_len = RTA_LENGTH(0);
rtnh = RTA_DATA(rta);
- routedesc = "multihop";
+ routedesc = "multipath";
_netlink_mpls_debug(cmd, lsp->ile.in_label, routedesc);
nexthop_num = 0;
diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h
index 51279798a4..22c771c348 100644
--- a/zebra/zebra_mpls.h
+++ b/zebra/zebra_mpls.h
@@ -436,6 +436,24 @@ static inline enum lsp_types_t lsp_type_from_re_type(int re_type)
}
}
+/*
+ * Map LSP type to RIB type.
+ */
+static inline int re_type_from_lsp_type(enum lsp_types_t lsp_type)
+{
+ switch (lsp_type) {
+ case ZEBRA_LSP_STATIC:
+ return ZEBRA_ROUTE_STATIC;
+ case ZEBRA_LSP_LDP:
+ return ZEBRA_ROUTE_LDP;
+ case ZEBRA_LSP_BGP:
+ return ZEBRA_ROUTE_BGP;
+ case ZEBRA_LSP_NONE:
+ default:
+ return ZEBRA_ROUTE_KERNEL;
+ }
+}
+
/* NHLFE type as printable string. */
static inline const char *nhlfe_type2str(enum lsp_types_t lsp_type)
{
diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c
index 7014731e04..78072f43bb 100644
--- a/zebra/zebra_ns.c
+++ b/zebra/zebra_ns.c
@@ -32,7 +32,7 @@
DEFINE_MTYPE(ZEBRA, ZEBRA_NS, "Zebra Name Space")
-struct zebra_ns *dzns;
+static struct zebra_ns *dzns;
struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id)
{
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 00550fa07d..fab8c3c932 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -261,7 +261,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, VRF_DEFAULT);
+ ifp = if_lookup_by_index(nexthop->ifindex, re->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)
@@ -417,7 +417,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, VRF_DEFAULT);
+ ifp = if_lookup_by_index(nexthop->ifindex, re->vrf_id);
if (ifp && connected_is_unnumbered(ifp)) {
if (if_is_operative(ifp))
return 1;
@@ -2216,23 +2216,18 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
struct route_entry *same;
struct nexthop *nexthop;
int ret = 0;
- int family;
if (!re)
return 0;
- if (p->family == AF_INET)
- family = AFI_IP;
- else
- family = AFI_IP6;
-
- assert(!src_p || family == AFI_IP6);
+ assert(!src_p || afi == AFI_IP6);
/* Lookup table. */
- table = zebra_vrf_table_with_table_id(family, safi, re->vrf_id,
- re->table);
- if (!table)
+ table = zebra_vrf_table_with_table_id(afi, safi, re->vrf_id, re->table);
+ if (!table) {
+ XFREE(MTYPE_RE, re);
return 0;
+ }
/* Make it sure prefixlen is applied to the prefix. */
apply_mask(p);
@@ -2258,8 +2253,18 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED))
continue;
- if (same->type == re->type && same->instance == re->instance
- && same->table == re->table && !RIB_SYSTEM_ROUTE(same))
+ if (same->type != re->type)
+ continue;
+ if (same->instance != re->instance)
+ continue;
+ if (same->type == ZEBRA_ROUTE_KERNEL &&
+ same->metric != re->metric)
+ continue;
+ /*
+ * We should allow duplicate connected routes because of
+ * IPv6 link-local routes and unnumbered interfaces on Linux.
+ */
+ if (same->type != ZEBRA_ROUTE_CONNECT)
break;
}
@@ -2294,7 +2299,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
u_short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, const struct nexthop *nh,
- u_int32_t table_id, u_int32_t metric)
+ u_int32_t table_id, u_int32_t metric, bool fromkernel)
{
struct route_table *table;
struct route_node *rn;
@@ -2375,6 +2380,21 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
/* If same type of route can't be found and this message is from
kernel. */
if (!same) {
+ /*
+ * In the past(HA!) we could get here because
+ * we were receiving a route delete from the
+ * kernel and we're not marking the proto
+ * as coming from it's appropriate originator.
+ * Now that we are properly noticing the fact
+ * that the kernel has deleted our route we
+ * are not going to get called in this path
+ * I am going to leave this here because
+ * this might still work this way on non-linux
+ * platforms as well as some weird state I have
+ * not properly thought of yet.
+ * If we can show that this code path is
+ * dead then we can remove it.
+ */
if (fib && type == ZEBRA_ROUTE_KERNEL
&& CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE)) {
if (IS_ZEBRA_DEBUG_RIB) {
@@ -2423,8 +2443,17 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
}
}
- if (same)
+ if (same) {
+ if (fromkernel &&
+ CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE) &&
+ !allow_delete) {
+ rib_install_kernel(rn, same, NULL);
+ route_unlock_node(rn);
+
+ return;
+ }
rib_delnode(rn, same);
+ }
route_unlock_node(rn);
return;
@@ -2437,70 +2466,10 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
u_int32_t mtu, u_char distance)
{
struct route_entry *re;
- struct route_entry *same = NULL;
- struct route_table *table;
- struct route_node *rn;
- struct nexthop *rtnh;
-
- assert(!src_p || afi == AFI_IP6);
-
- /* Lookup table. */
- table = zebra_vrf_table_with_table_id(afi, safi, vrf_id, table_id);
- if (!table)
- return 0;
-
- /* Make sure mask is applied. */
- apply_mask(p);
- if (src_p)
- apply_mask_ipv6(src_p);
-
- /* Set default distance by route type. */
- if (distance == 0) {
- distance = route_distance(type);
-
- /* iBGP distance is 200. */
- if (type == ZEBRA_ROUTE_BGP
- && CHECK_FLAG(flags, ZEBRA_FLAG_IBGP))
- distance = 200;
- }
-
- /* Lookup route node.*/
- rn = srcdest_rnode_get(table, p, src_p);
-
- /* If same type of route are installed, treat it as a implicit
- withdraw. */
- RNODE_FOREACH_RE (rn, re) {
- if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
- continue;
-
- if (re->type != type)
- continue;
- if (re->instance != instance)
- continue;
- if (re->type == ZEBRA_ROUTE_KERNEL &&
- re->metric != metric)
- continue;
- if (!RIB_SYSTEM_ROUTE(re)) {
- same = re;
- break;
- }
- /* Duplicate system route comes in. */
- rtnh = re->nexthop;
- if (nexthop_same_no_recurse(rtnh, nh))
- return 0;
- /*
- * Nexthop is different. Remove the old route unless it's
- * a connected route. This exception is necessary because
- * of IPv6 link-local routes and unnumbered interfaces on
- * Linux.
- */
- else if (type != ZEBRA_ROUTE_CONNECT)
- same = re;
- }
+ struct nexthop *nexthop;
- /* Allocate new re structure. */
+ /* Allocate new route_entry structure. */
re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
-
re->type = type;
re->instance = instance;
re->distance = distance;
@@ -2512,33 +2481,12 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
re->nexthop_num = 0;
re->uptime = time(NULL);
- rtnh = nexthop_new();
- *rtnh = *nh;
- route_entry_nexthop_add(re, rtnh);
-
- /* If this route is kernel route, set FIB flag to the route. */
- if (RIB_SYSTEM_ROUTE(re))
- for (rtnh = re->nexthop; rtnh; rtnh = rtnh->next)
- SET_FLAG(rtnh->flags, NEXTHOP_FLAG_FIB);
-
- /* Link new rib to node.*/
- if (IS_ZEBRA_DEBUG_RIB) {
- rnode_debug(
- rn, vrf_id,
- "Inserting route rn %p, re %p (type %d) existing %p",
- (void *)rn, (void *)re, re->type, (void *)same);
-
- if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- route_entry_dump(p, src_p, re);
- }
- rib_addnode(rn, re, 1);
-
- /* Free implicit route.*/
- if (same)
- rib_delnode(rn, same);
+ /* Add nexthop. */
+ nexthop = nexthop_new();
+ *nexthop = *nh;
+ route_entry_nexthop_add(re, nexthop);
- route_unlock_node(rn);
- return 0;
+ return rib_add_multipath(afi, safi, p, src_p, re);
}
/* Schedule routes of a particular table (address-family) based on event. */
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index df1eef119a..04cd17cedb 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -166,10 +166,13 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
}
/* Null0 static route. */
- if ((ifname != NULL)
- && (strncasecmp(ifname, "Null0", strlen(ifname)) == 0)) {
- bh_type = STATIC_BLACKHOLE_NULL;
- ifname = NULL;
+ if (ifname != NULL) {
+ if (strncasecmp(ifname, "Null0", strlen(ifname)) == 0 ||
+ strncasecmp(ifname, "reject", strlen(ifname)) == 0 ||
+ strncasecmp(ifname, "blackhole", strlen(ifname)) == 0) {
+ vty_out(vty, "%% Nexthop interface cannot be Null0, reject or blackhole\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
}
/* Route flags */
@@ -181,6 +184,9 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
case 'b':
bh_type = STATIC_BLACKHOLE_DROP;
break;
+ case 'N':
+ bh_type = STATIC_BLACKHOLE_NULL;
+ break;
default:
vty_out(vty, "%% Malformed flag %s \n", flag_str);
return CMD_WARNING_CONFIG_FAILED;
@@ -333,27 +339,22 @@ DEFUN (show_ip_rpf_addr,
}
/* Static route configuration. */
-DEFPY(ip_route, ip_route_cmd,
+DEFPY(ip_route_blackhole,
+ ip_route_blackhole_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}\
- |null0$ifname\
- |<reject|blackhole>$flag\
- >\
- [{\
- tag (1-4294967295)\
- |(1-255)$distance\
- |vrf NAME\
- |label WORD\
+ <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
+ <Null0|reject|blackhole>$flag \
+ [{ \
+ tag (1-4294967295) \
+ |(1-255)$distance \
+ |vrf NAME \
+ |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"
- "IP gateway address\n"
- "IP gateway interface name\n"
"Null interface\n"
"Emit an ICMP unreachable when matched\n"
"Silently discard pkts when matched\n"
@@ -364,9 +365,67 @@ DEFPY(ip_route, ip_route_cmd,
MPLS_LABEL_HELPSTR)
{
return zebra_static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix,
- mask_str, NULL, gate_str, ifname, flag,
+ mask_str, NULL, NULL, NULL, flag,
+ tag_str, distance_str, vrf, label);
+}
+
+DEFPY(ip_route_address_interface,
+ ip_route_address_interface_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 \
+ |vrf NAME \
+ |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"
+ "IP gateway address\n"
+ "IP gateway interface name\n"
+ "Set tag for this route\n"
+ "Tag value\n"
+ "Distance value for this route\n"
+ VRF_CMD_HELP_STR
+ MPLS_LABEL_HELPSTR)
+{
+ return zebra_static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix,
+ mask_str, NULL, gate_str, ifname, NULL,
+ tag_str, distance_str, vrf, label);
+}
+
+DEFPY(ip_route,
+ ip_route_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 \
+ |vrf NAME \
+ |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"
+ "IP gateway address\n"
+ "IP gateway interface name\n"
+ "Set tag for this route\n"
+ "Tag value\n"
+ "Distance value for this route\n"
+ VRF_CMD_HELP_STR
+ MPLS_LABEL_HELPSTR)
+{
+ return zebra_static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix,
+ mask_str, NULL, gate_str, ifname, NULL,
tag_str, distance_str, vrf, label);
- return 0;
}
/* New RIB. Detailed information for IPv4 route. */
@@ -1752,19 +1811,75 @@ static int static_config(struct vty *vty, afi_t afi, safi_t safi,
return write;
}
+DEFPY(ipv6_route_blackhole,
+ ipv6_route_blackhole_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 \
+ |vrf NAME \
+ |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"
+ VRF_CMD_HELP_STR
+ MPLS_LABEL_HELPSTR)
+{
+ return zebra_static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str,
+ NULL, from_str, NULL, NULL, flag,
+ tag_str, distance_str, vrf, 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] \
+ X:X::X:X$gate \
+ INTERFACE$ifname \
+ [{ \
+ tag (1-4294967295) \
+ |(1-255)$distance \
+ |vrf NAME \
+ |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"
+ "IPv6 gateway address\n"
+ "IPv6 gateway interface name\n"
+ "Set tag for this route\n"
+ "Tag value\n"
+ "Distance value for this prefix\n"
+ VRF_CMD_HELP_STR
+ MPLS_LABEL_HELPSTR)
+{
+ 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);
+}
+
DEFPY(ipv6_route,
ipv6_route_cmd,
- "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M]\
- <\
- {X:X::X:X$gate|INTERFACE$ifname}\
- |null0$ifname\
- |<reject|blackhole>$flag\
- >\
- [{\
- tag (1-4294967295)\
- |(1-255)$distance\
- |vrf NAME\
- |label WORD\
+ "[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 \
+ |vrf NAME \
+ |label WORD \
}]",
NO_STR
IPV6_STR
@@ -1774,9 +1889,6 @@ DEFPY(ipv6_route,
"IPv6 source prefix\n"
"IPv6 gateway address\n"
"IPv6 gateway interface name\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"
@@ -1784,7 +1896,7 @@ DEFPY(ipv6_route,
MPLS_LABEL_HELPSTR)
{
return zebra_static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str,
- NULL, from_str, gate_str, ifname, flag,
+ NULL, from_str, gate_str, ifname, NULL,
tag_str, distance_str, vrf, label);
}
@@ -2664,6 +2776,8 @@ void zebra_vty_init(void)
install_element(CONFIG_NODE, &ip_mroute_dist_cmd);
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(CONFIG_NODE, &ip_route_address_interface_cmd);
install_element(CONFIG_NODE, &ip_route_cmd);
install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
@@ -2687,6 +2801,8 @@ void zebra_vty_init(void)
install_element(VIEW_NODE, &show_ip_route_vrf_all_summary_cmd);
install_element(VIEW_NODE, &show_ip_route_vrf_all_summary_prefix_cmd);
+ install_element(CONFIG_NODE, &ipv6_route_blackhole_cmd);
+ install_element(CONFIG_NODE, &ipv6_route_address_interface_cmd);
install_element(CONFIG_NODE, &ipv6_route_cmd);
install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 2c0e1a0200..fd2c5dd97c 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -1165,7 +1165,7 @@ static int zread_route_del(struct zserv *client, u_short length,
rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance,
api.flags, &api.prefix, src_p, NULL, zvrf->table_id,
- api.metric);
+ api.metric, false);
/* Stats */
switch (api.prefix.family) {
@@ -1331,7 +1331,7 @@ static int zread_ipv4_delete(struct zserv *client, u_short length,
table_id = zvrf->table_id;
rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance,
- api.flags, &p, NULL, NULL, table_id, 0);
+ api.flags, &p, NULL, NULL, table_id, 0, false);
client->v4_route_del_cnt++;
return 0;
}
@@ -1693,7 +1693,7 @@ static int zread_ipv6_delete(struct zserv *client, u_short length,
src_pp = NULL;
rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, api.instance,
- api.flags, &p, src_pp, NULL, client->rtm_table, 0);
+ api.flags, &p, src_pp, NULL, client->rtm_table, 0, false);
client->v6_route_del_cnt++;
return 0;