summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
Diffstat (limited to 'zebra')
-rw-r--r--zebra/ChangeLog12
-rw-r--r--zebra/connected.c12
-rw-r--r--zebra/interface.h4
-rw-r--r--zebra/ioctl.c4
-rw-r--r--zebra/kernel_socket.c16
-rw-r--r--zebra/rib.h18
-rw-r--r--zebra/rt_netlink.c30
-rw-r--r--zebra/rt_socket.c17
-rw-r--r--zebra/zebra_rib.c63
-rw-r--r--zebra/zebra_vty.c392
-rw-r--r--zebra/zserv.c47
-rw-r--r--zebra/zserv.h8
12 files changed, 540 insertions, 83 deletions
diff --git a/zebra/ChangeLog b/zebra/ChangeLog
index 1f392197..7f3d724c 100644
--- a/zebra/ChangeLog
+++ b/zebra/ChangeLog
@@ -1,3 +1,15 @@
+2003-05-25 Jim Crumpler <Jim.Crumpler@edion.com>
+
+ * zserv.c: Add "ip forwarding" command.
+
+2003-05-16 Gilad Arnold <gilad.arnold@terayon.com>
+
+ * zebra_rib.c: Fix memory leaks for ifname nexthops
+
+2003-04-19 Israel Keys <ikeys@agile.tv>
+
+ * rt_netlink.c: BLOCK on netlink while initialising
+
2003-02-06 Francois Deppierraz <francois@ctrlaltdel.ch>
* rt_netlink.c (netlink_route_multipath): Set RTM_F_EQUALIZE when
diff --git a/zebra/connected.c b/zebra/connected.c
index cb43074b..280e423e 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -69,7 +69,7 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
p.prefixlen = addr->prefixlen;
/* Point-to-point check. */
- if (if_is_pointopoint (ifp))
+ if (ifc_pointopoint (ifc) && dest)
p.prefix = dest->prefix;
else
p.prefix = addr->prefix;
@@ -162,7 +162,8 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc)
p.family = AF_INET;
p.prefixlen = addr->prefixlen;
- if (if_is_pointopoint (ifp))
+ /* Point-to-point check. */
+ if (dest && ifc_pointopoint (ifc))
p.prefix = dest->prefix;
else
p.prefix = addr->prefix;
@@ -249,7 +250,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
p.family = AF_INET6;
p.prefixlen = addr->prefixlen;
- if (if_is_pointopoint (ifp) && dest)
+ if (ifc_pointopoint (ifc) && dest)
{
if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
p.prefix = addr->prefix;
@@ -262,8 +263,11 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
/* Apply mask to the network. */
apply_mask_ipv6 (&p);
+#if ! defined (MUSICA) && ! defined (LINUX)
+ /* XXX: It is already done by rib_bogus_ipv6 within rib_add_ipv6 */
if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
return;
+#endif
rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0);
@@ -339,7 +343,7 @@ connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
p.family = AF_INET6;
p.prefixlen = addr->prefixlen;
- if (if_is_pointopoint (ifp) && dest)
+ if (ifc_pointopoint (ifc) && dest)
{
if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
p.prefix = addr->prefix;
diff --git a/zebra/interface.h b/zebra/interface.h
index dbfa8221..3ab624f2 100644
--- a/zebra/interface.h
+++ b/zebra/interface.h
@@ -31,7 +31,9 @@
/* Router advertisement feature. */
#if (defined(LINUX_IPV6) && (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1)) || defined(KAME)
-#define RTADV
+ #ifdef HAVE_RTADV
+ #define RTADV
+ #endif
#endif
#ifdef RTADV
diff --git a/zebra/ioctl.c b/zebra/ioctl.c
index 4c341e8b..f8e7f22b 100644
--- a/zebra/ioctl.c
+++ b/zebra/ioctl.c
@@ -489,8 +489,10 @@ if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc)
#endif
memcpy (&addreq.ifra_prefixmask, &mask, sizeof (struct sockaddr_in6));
+#ifdef HAVE_IFRA_LIFETIME
addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
+#endif
ret = if_ioctl_ipv6 (SIOCAIFADDR_IN6, (caddr_t) &addreq);
if (ret < 0)
@@ -528,8 +530,10 @@ if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc)
#endif
memcpy (&addreq.ifra_prefixmask, &mask, sizeof (struct sockaddr_in6));
+#ifdef HAVE_IFRA_LIFETIME
addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
+#endif
ret = if_ioctl_ipv6 (SIOCDIFADDR_IN6, (caddr_t) &addreq);
if (ret < 0)
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index b5431d3e..17893a87 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -477,6 +477,12 @@ rtm_read (struct rt_msghdr *rtm)
if (flags & RTF_STATIC)
SET_FLAG (zebra_flags, ZEBRA_FLAG_STATIC);
+ /* This is a reject or blackhole route */
+ if (flags & RTF_REJECT)
+ SET_FLAG (zebra_flags, ZEBRA_FLAG_REJECT);
+ if (flags & RTF_BLACKHOLE)
+ SET_FLAG (zebra_flags, ZEBRA_FLAG_BLACKHOLE);
+
if (dest.sa.sa_family == AF_INET)
{
struct prefix_ipv4 p;
@@ -620,6 +626,9 @@ rtm_write (int message,
/* Additional flags. */
if (zebra_flags & ZEBRA_FLAG_BLACKHOLE)
msg.rtm.rtm_flags |= RTF_BLACKHOLE;
+ if (zebra_flags & ZEBRA_FLAG_REJECT)
+ msg.rtm.rtm_flags |= RTF_REJECT;
+
#ifdef HAVE_SIN_LEN
#define SOCKADDRSET(X,R) \
@@ -754,9 +763,8 @@ kernel_read (struct thread *thread)
thread_add_read (master, kernel_read, NULL, sock);
-#ifdef DEBUG
- rtmsg_debug (&buf.r.rtm);
-#endif /* DEBUG */
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ rtmsg_debug (&buf.r.rtm);
rtm = &buf.r.rtm;
@@ -779,6 +787,8 @@ kernel_read (struct thread *thread)
break;
#endif /* RTM_IFANNOUNCE */
default:
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_info("Unprocessed RTM_type: %d", rtm->rtm_type);
break;
}
return 0;
diff --git a/zebra/rib.h b/zebra/rib.h
index f5012610..5b0dcfe9 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -84,6 +84,13 @@ struct static_ipv4
struct in_addr ipv4;
char *ifname;
} gate;
+
+ /* bit flags */
+ u_char flags;
+/*
+ see ZEBRA_FLAG_REJECT
+ ZEBRA_FLAG_BLACKHOLE
+ */
};
#ifdef HAVE_IPV6
@@ -106,6 +113,13 @@ struct static_ipv6
/* Nexthop value. */
struct in6_addr ipv6;
char *ifname;
+
+ /* bit flags */
+ u_char flags;
+/*
+ see ZEBRA_FLAG_REJECT
+ ZEBRA_FLAG_BLACKHOLE
+ */
};
#endif /* HAVE_IPV6 */
@@ -217,7 +231,7 @@ void rib_init ();
int
static_add_ipv4 (struct prefix *p, struct in_addr *gate, char *ifname,
- u_char distance, u_int32_t vrf_id);
+ u_char flags, u_char distance, u_int32_t vrf_id);
int
static_delete_ipv4 (struct prefix *p, struct in_addr *gate, char *ifname,
@@ -240,7 +254,7 @@ extern struct route_table *rib_table_ipv6;
int
static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
- char *ifname, u_char distance, u_int32_t vrf_id);
+ char *ifname, u_char flags, u_char distance, u_int32_t vrf_id);
int
static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index f4f51034..f1784a77 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -1193,7 +1193,8 @@ netlink_route (int cmd, int family, void *dest, int length, void *gate,
req.r.rtm_table = table;
req.r.rtm_dst_len = length;
- if (zebra_flags & ZEBRA_FLAG_BLACKHOLE)
+ if ((zebra_flags & ZEBRA_FLAG_BLACKHOLE)
+ || (zebra_flags & ZEBRA_FLAG_REJECT))
discard = 1;
else
discard = 0;
@@ -1203,10 +1204,16 @@ netlink_route (int cmd, int family, void *dest, int length, void *gate,
req.r.rtm_protocol = RTPROT_ZEBRA;
req.r.rtm_scope = RT_SCOPE_UNIVERSE;
- if (discard)
- req.r.rtm_type = RTN_BLACKHOLE;
+ if (discard)
+ {
+ if (zebra_flags & ZEBRA_FLAG_BLACKHOLE)
+ req.r.rtm_type = RTN_BLACKHOLE;
+ else if (zebra_flags & ZEBRA_FLAG_REJECT)
+ req.r.rtm_type = RTN_UNREACHABLE;
+ else assert(RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */
+ }
else
- req.r.rtm_type = RTN_UNICAST;
+ req.r.rtm_type = RTN_UNICAST;
}
if (dest)
@@ -1266,7 +1273,8 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
req.r.rtm_flags |= RTM_F_EQUALIZE;
#endif /* RTM_F_EQUALIZE */
- if (rib->flags & ZEBRA_FLAG_BLACKHOLE)
+ if ((rib->flags & ZEBRA_FLAG_BLACKHOLE)
+ || (rib->flags & ZEBRA_FLAG_REJECT))
discard = 1;
else
discard = 0;
@@ -1276,10 +1284,16 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
req.r.rtm_protocol = RTPROT_ZEBRA;
req.r.rtm_scope = RT_SCOPE_UNIVERSE;
- if (discard)
- req.r.rtm_type = RTN_BLACKHOLE;
+ if (discard)
+ {
+ if (rib->flags & ZEBRA_FLAG_BLACKHOLE)
+ req.r.rtm_type = RTN_BLACKHOLE;
+ else if (rib->flags & ZEBRA_FLAG_REJECT)
+ req.r.rtm_type = RTN_UNREACHABLE;
+ else assert(RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */
+ }
else
- req.r.rtm_type = RTN_UNICAST;
+ req.r.rtm_type = RTN_UNICAST;
}
addattr_l (&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen);
diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c
index 363363f7..d603c60d 100644
--- a/zebra/rt_socket.c
+++ b/zebra/rt_socket.c
@@ -132,15 +132,14 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family)
|| nexthop->type == NEXTHOP_TYPE_IFNAME
|| nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
ifindex = nexthop->ifindex;
- if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE)
- {
- struct in_addr loopback;
-
- loopback.s_addr = htonl (INADDR_LOOPBACK);
- sin_gate.sin_addr = loopback;
- gate = 1;
- }
- }
+ if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE)
+ {
+ struct in_addr loopback;
+ loopback.s_addr = htonl (INADDR_LOOPBACK);
+ sin_gate.sin_addr = loopback;
+ gate = 1;
+ }
+ }
if (cmd == RTM_ADD)
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index ec07e2e3..4098db26 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -187,8 +187,8 @@ nexthop_delete (struct rib *rib, struct nexthop *nexthop)
void
nexthop_free (struct nexthop *nexthop)
{
- if (nexthop->type == NEXTHOP_TYPE_IFNAME && nexthop->ifname)
- free (nexthop->ifname);
+ if (nexthop->ifname)
+ XFREE (0, nexthop->ifname);
XFREE (MTYPE_NEXTHOP, nexthop);
}
@@ -215,7 +215,7 @@ nexthop_ifname_add (struct rib *rib, char *ifname)
nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
memset (nexthop, 0, sizeof (struct nexthop));
nexthop->type = NEXTHOP_TYPE_IFNAME;
- nexthop->ifname = strdup (ifname);
+ nexthop->ifname = XSTRDUP (0, ifname);
nexthop_add (rib, nexthop);
@@ -305,7 +305,6 @@ nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
}
#endif /* HAVE_IPV6 */
-
struct nexthop *
nexthop_blackhole_add (struct rib *rib)
{
@@ -855,11 +854,13 @@ rib_process (struct route_node *rn, struct rib *del)
struct rib *next;
struct rib *fib = NULL;
struct rib *select = NULL;
+ int installed = 0;
+ struct nexthop *nexthop = NULL;
for (rib = rn->info; rib; rib = next)
{
next = rib->next;
-
+
/* Currently installed rib. */
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
fib = rib;
@@ -898,6 +899,22 @@ rib_process (struct route_node *rn, struct rib *del)
rib_install_kernel (rn, select);
redistribute_add (&rn->p, select);
}
+ else if (! RIB_SYSTEM_ROUTE (select))
+ {
+ /* Housekeeping code to deal with
+ race conditions in kernel with linux
+ netlink reporting interface up before IPv4 or IPv6 protocol
+ is ready to add routes.
+ This makes sure the routes are IN the kernel.
+ */
+
+ for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next)
+ {
+ if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
+ installed = 1;
+ }
+ if (! installed) rib_install_kernel (rn, select);
+ }
return;
}
@@ -1271,9 +1288,9 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
case STATIC_IPV4_IFNAME:
nexthop_ifname_add (rib, si->gate.ifname);
break;
- case STATIC_IPV4_BLACKHOLE:
- nexthop_blackhole_add (rib);
- break;
+ case STATIC_IPV4_BLACKHOLE:
+ nexthop_blackhole_add (rib);
+ break;
}
rib_process (rn, NULL);
}
@@ -1296,11 +1313,14 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
case STATIC_IPV4_IFNAME:
nexthop_ifname_add (rib, si->gate.ifname);
break;
- case STATIC_IPV4_BLACKHOLE:
- nexthop_blackhole_add (rib);
- break;
+ case STATIC_IPV4_BLACKHOLE:
+ nexthop_blackhole_add (rib);
+ break;
}
+ /* Save the flags of this static routes (reject, blackhole) */
+ rib->flags = si->flags;
+
/* Link this rib to the tree. */
rib_addnode (rn, rib);
@@ -1390,7 +1410,7 @@ static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
/* Add static route into static route configuration. */
int
static_add_ipv4 (struct prefix *p, struct in_addr *gate, char *ifname,
- u_char distance, u_int32_t vrf_id)
+ u_char flags, u_char distance, u_int32_t vrf_id)
{
u_char type = 0;
struct route_node *rn;
@@ -1443,6 +1463,7 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, char *ifname,
si->type = type;
si->distance = distance;
+ si->flags = flags;
if (gate)
si->gate.ipv4 = *gate;
@@ -1536,6 +1557,8 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, char *ifname,
si->next->prev = si->prev;
/* Free static route configuration. */
+ if (ifname)
+ XFREE (0, si->gate.ifname);
XFREE (MTYPE_STATIC_IPV4, si);
return 1;
@@ -1547,8 +1570,14 @@ int
rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
struct in6_addr *gate, unsigned int ifindex, int table)
{
- if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix))
+ if (type == ZEBRA_ROUTE_CONNECT && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)) {
+#if defined (MUSICA) || defined (LINUX)
+ /* IN6_IS_ADDR_V4COMPAT(&p->prefix) */
+ if (p->prefixlen == 96)
+ return 0;
+#endif /* MUSICA */
return 1;
+ }
if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
&& p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
{
@@ -1849,6 +1878,9 @@ static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
break;
}
+ /* Save the flags of this static routes (reject, blackhole) */
+ rib->flags = si->flags;
+
/* Link this rib to the tree. */
rib_addnode (rn, rib);
@@ -1938,7 +1970,7 @@ static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
/* Add static route into static route configuration. */
int
static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
- char *ifname, u_char distance, u_int32_t vrf_id)
+ char *ifname, u_char flags, u_char distance, u_int32_t vrf_id)
{
struct route_node *rn;
struct static_ipv6 *si;
@@ -1973,6 +2005,7 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
si->type = type;
si->distance = distance;
+ si->flags = flags;
switch (type)
{
@@ -2060,6 +2093,8 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
si->next->prev = si->prev;
/* Free static route configuration. */
+ if (ifname)
+ XFREE (0, si->ifname);
XFREE (MTYPE_STATIC_IPV6, si);
return 1;
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index f6e7f51d..c8168c90 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -89,7 +89,7 @@ route_type_char (u_char type)
int
zebra_static_ipv4 (struct vty *vty, int add_cmd,
char *dest_str, char *mask_str, char *gate_str,
- char *distance_str)
+ char *flag_str, char *distance_str)
{
int ret;
u_char distance;
@@ -97,6 +97,7 @@ zebra_static_ipv4 (struct vty *vty, int add_cmd,
struct in_addr gate;
struct in_addr mask;
char *ifname;
+ u_char flag = 0;
ret = str2prefix (dest_str, &p);
if (ret <= 0)
@@ -110,10 +111,10 @@ zebra_static_ipv4 (struct vty *vty, int add_cmd,
{
ret = inet_aton (mask_str, &mask);
if (ret == 0)
- {
- vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ {
+ vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
p.prefixlen = ip_masklen (mask);
}
@@ -129,13 +130,35 @@ zebra_static_ipv4 (struct vty *vty, int add_cmd,
/* Null0 static route. */
if (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0)
{
+ if (flag_str)
+ {
+ vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
if (add_cmd)
- static_add_ipv4 (&p, NULL, NULL, distance, 0);
+ static_add_ipv4 (&p, NULL, NULL, 0, distance, 0);
else
- static_delete_ipv4 (&p, NULL, NULL, distance, 0);
+ static_delete_ipv4 (&p, NULL, NULL, distance, 0);
return CMD_SUCCESS;
}
+ /* Route flags */
+ if (flag_str) {
+ switch(flag_str[0]) {
+ case 'r':
+ case 'R': /* XXX */
+ SET_FLAG (flag, ZEBRA_FLAG_REJECT);
+ break;
+ case 'b':
+ case 'B': /* XXX */
+ SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
+ break;
+ default:
+ vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
/* When gateway is A.B.C.D format, gate is treated as nexthop
address other case gate is treated as interface name. */
ret = inet_aton (gate_str, &gate);
@@ -145,7 +168,7 @@ zebra_static_ipv4 (struct vty *vty, int add_cmd,
ifname = gate_str;
if (add_cmd)
- static_add_ipv4 (&p, ifname ? NULL : &gate, ifname, distance, 0);
+ static_add_ipv4 (&p, ifname ? NULL : &gate, ifname, flag, distance, 0);
else
static_delete_ipv4 (&p, ifname ? NULL : &gate, ifname, distance, 0);
@@ -163,7 +186,21 @@ DEFUN (ip_route,
"IP gateway interface name\n"
"Null interface\n")
{
- return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL);
+ return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL);
+}
+
+DEFUN (ip_route_flags,
+ ip_route_flags_cmd,
+ "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
+ IP_STR
+ "Establish static routes\n"
+ "IP destination prefix (e.g. 10.0.0.0/8)\n"
+ "IP gateway address\n"
+ "IP gateway interface name\n"
+ "Emit an ICMP unreachable when matched\n"
+ "Silently discard pkts when matched\n")
+{
+ return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], NULL);
}
/* Mask as A.B.C.D format. */
@@ -178,7 +215,22 @@ DEFUN (ip_route_mask,
"IP gateway interface name\n"
"Null interface\n")
{
- return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL);
+ return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
+}
+
+DEFUN (ip_route_mask_flags,
+ ip_route_mask_flags_cmd,
+ "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
+ IP_STR
+ "Establish static routes\n"
+ "IP destination prefix\n"
+ "IP destination prefix mask\n"
+ "IP gateway address\n"
+ "IP gateway interface name\n"
+ "Emit an ICMP unreachable when matched\n"
+ "Silently discard pkts when matched\n")
+{
+ return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
}
/* Distance option value. */
@@ -193,7 +245,22 @@ DEFUN (ip_route_distance,
"Null interface\n"
"Distance value for this route\n")
{
- return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2]);
+ return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2]);
+}
+
+DEFUN (ip_route_flags_distance,
+ ip_route_flags_distance_cmd,
+ "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
+ IP_STR
+ "Establish static routes\n"
+ "IP destination prefix (e.g. 10.0.0.0/8)\n"
+ "IP gateway address\n"
+ "IP gateway interface name\n"
+ "Emit an ICMP unreachable when matched\n"
+ "Silently discard pkts when matched\n"
+ "Distance value for this route\n")
+{
+ return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], argv[3]);
}
DEFUN (ip_route_mask_distance,
@@ -208,7 +275,23 @@ DEFUN (ip_route_mask_distance,
"Null interface\n"
"Distance value for this route\n")
{
- return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3]);
+ return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
+}
+
+DEFUN (ip_route_mask_flags_distance,
+ ip_route_mask_flags_distance_cmd,
+ "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
+ IP_STR
+ "Establish static routes\n"
+ "IP destination prefix\n"
+ "IP destination prefix mask\n"
+ "IP gateway address\n"
+ "IP gateway interface name\n"
+ "Distance value for this route\n"
+ "Emit an ICMP unreachable when matched\n"
+ "Silently discard pkts when matched\n")
+{
+ return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
}
DEFUN (no_ip_route,
@@ -222,9 +305,21 @@ DEFUN (no_ip_route,
"IP gateway interface name\n"
"Null interface\n")
{
- return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL);
+ return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL);
}
+ALIAS (no_ip_route,
+ no_ip_route_flags_cmd,
+ "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
+ NO_STR
+ IP_STR
+ "Establish static routes\n"
+ "IP destination prefix (e.g. 10.0.0.0/8)\n"
+ "IP gateway address\n"
+ "IP gateway interface name\n"
+ "Emit an ICMP unreachable when matched\n"
+ "Silently discard pkts when matched\n")
+
DEFUN (no_ip_route_mask,
no_ip_route_mask_cmd,
"no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
@@ -237,9 +332,22 @@ DEFUN (no_ip_route_mask,
"IP gateway interface name\n"
"Null interface\n")
{
- return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL);
+ return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
}
+ALIAS (no_ip_route_mask,
+ no_ip_route_mask_flags_cmd,
+ "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
+ NO_STR
+ IP_STR
+ "Establish static routes\n"
+ "IP destination prefix\n"
+ "IP destination prefix mask\n"
+ "IP gateway address\n"
+ "IP gateway interface name\n"
+ "Emit an ICMP unreachable when matched\n"
+ "Silently discard pkts when matched\n")
+
DEFUN (no_ip_route_distance,
no_ip_route_distance_cmd,
"no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
@@ -252,7 +360,23 @@ DEFUN (no_ip_route_distance,
"Null interface\n"
"Distance value for this route\n")
{
- return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2]);
+ return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2]);
+}
+
+DEFUN (no_ip_route_flags_distance,
+ no_ip_route_flags_distance_cmd,
+ "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
+ NO_STR
+ IP_STR
+ "Establish static routes\n"
+ "IP destination prefix (e.g. 10.0.0.0/8)\n"
+ "IP gateway address\n"
+ "IP gateway interface name\n"
+ "Emit an ICMP unreachable when matched\n"
+ "Silently discard pkts when matched\n"
+ "Distance value for this route\n")
+{
+ return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2], argv[3]);
}
DEFUN (no_ip_route_mask_distance,
@@ -268,7 +392,24 @@ DEFUN (no_ip_route_mask_distance,
"Null interface\n"
"Distance value for this route\n")
{
- return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3]);
+ return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
+}
+
+DEFUN (no_ip_route_mask_flags_distance,
+ no_ip_route_mask_flags_distance_cmd,
+ "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
+ NO_STR
+ IP_STR
+ "Establish static routes\n"
+ "IP destination prefix\n"
+ "IP destination prefix mask\n"
+ "IP gateway address\n"
+ "IP gateway interface name\n"
+ "Emit an ICMP unreachable when matched\n"
+ "Silently discard pkts when matched\n"
+ "Distance value for this route\n")
+{
+ return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
}
/* New RIB. Detailed information for IPv4 route. */
@@ -289,6 +430,10 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
vty_out (vty, ", best");
if (rib->refcnt)
vty_out (vty, ", refcnt %ld", rib->refcnt);
+ if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
+ vty_out (vty, ", blackhole");
+ if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
+ vty_out (vty, ", reject");
vty_out (vty, "%s", VTY_NEWLINE);
#define ONE_DAY_SECOND 60*60*24
@@ -339,9 +484,9 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
case NEXTHOP_TYPE_IFNAME:
vty_out (vty, " directly connected, %s", nexthop->ifname);
break;
- case NEXTHOP_TYPE_BLACKHOLE:
- vty_out (vty, " directly connected, via Null0");
- break;
+ case NEXTHOP_TYPE_BLACKHOLE:
+ vty_out (vty, " directly connected, via Null0");
+ break;
default:
break;
}
@@ -422,8 +567,9 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
case NEXTHOP_TYPE_IFNAME:
vty_out (vty, " is directly connected, %s", nexthop->ifname);
break;
- case NEXTHOP_TYPE_BLACKHOLE:
- vty_out (vty, " is directly connected, Null0");
+ case NEXTHOP_TYPE_BLACKHOLE:
+ vty_out (vty, " is directly connected, Null0");
+ break;
default:
break;
}
@@ -450,6 +596,11 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
}
}
+ if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
+ vty_out (vty, ", bh");
+ if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
+ vty_out (vty, ", rej");
+
if (rib->type == ZEBRA_ROUTE_RIP
|| rib->type == ZEBRA_ROUTE_OSPF
|| rib->type == ZEBRA_ROUTE_BGP)
@@ -808,11 +959,17 @@ static_config_ipv4 (struct vty *vty)
case STATIC_IPV4_IFNAME:
vty_out (vty, " %s", si->gate.ifname);
break;
- case STATIC_IPV4_BLACKHOLE:
- vty_out (vty, " Null0");
- break;
+ case STATIC_IPV4_BLACKHOLE:
+ vty_out (vty, " Null0");
+ break;
}
+ if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
+ vty_out (vty, " %s", "reject");
+
+ if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
+ vty_out (vty, " %s", "blackhole");
+
if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
vty_out (vty, " %d", si->distance);
vty_out (vty, "%s", VTY_NEWLINE);
@@ -826,7 +983,7 @@ static_config_ipv4 (struct vty *vty)
/* General fucntion for IPv6 static route. */
int
static_ipv6_func (struct vty *vty, int add_cmd, char *dest_str,
- char *gate_str, char *ifname, char *distance_str)
+ char *gate_str, char *ifname, char *flag_str, char *distance_str)
{
int ret;
u_char distance;
@@ -835,6 +992,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, char *dest_str,
struct in6_addr gate_addr;
u_char type = 0;
int table = 0;
+ u_char flag = 0;
ret = str2prefix (dest_str, &p);
if (ret <= 0)
@@ -846,6 +1004,23 @@ static_ipv6_func (struct vty *vty, int add_cmd, char *dest_str,
/* Apply mask for given prefix. */
apply_mask (&p);
+ /* Route flags */
+ if (flag_str) {
+ switch(flag_str[0]) {
+ case 'r':
+ case 'R': /* XXX */
+ SET_FLAG (flag, ZEBRA_FLAG_REJECT);
+ break;
+ case 'b':
+ case 'B': /* XXX */
+ SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
+ break;
+ default:
+ vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
/* Administrative distance. */
if (distance_str)
distance = atoi (distance_str);
@@ -883,7 +1058,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, char *dest_str,
}
if (add_cmd)
- static_add_ipv6 (&p, type, gate, ifname, distance, table);
+ static_add_ipv6 (&p, type, gate, ifname, flag, distance, table);
else
static_delete_ipv6 (&p, type, gate, ifname, distance, table);
@@ -899,7 +1074,21 @@ DEFUN (ipv6_route,
"IPv6 gateway address\n"
"IPv6 gateway interface name\n")
{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL);
+ return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL);
+}
+
+DEFUN (ipv6_route_flags,
+ ipv6_route_flags_cmd,
+ "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
+ IP_STR
+ "Establish static routes\n"
+ "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 gateway address\n"
+ "IPv6 gateway interface name\n"
+ "Emit an ICMP unreachable when matched\n"
+ "Silently discard pkts when matched\n")
+{
+ return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
}
DEFUN (ipv6_route_ifname,
@@ -911,7 +1100,21 @@ DEFUN (ipv6_route_ifname,
"IPv6 gateway address\n"
"IPv6 gateway interface name\n")
{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL);
+ return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
+}
+
+DEFUN (ipv6_route_ifname_flags,
+ ipv6_route_ifname_flags_cmd,
+ "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
+ IP_STR
+ "Establish static routes\n"
+ "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 gateway address\n"
+ "IPv6 gateway interface name\n"
+ "Emit an ICMP unreachable when matched\n"
+ "Silently discard pkts when matched\n")
+{
+ return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
}
DEFUN (ipv6_route_pref,
@@ -924,7 +1127,22 @@ DEFUN (ipv6_route_pref,
"IPv6 gateway interface name\n"
"Distance value for this prefix\n")
{
- return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2]);
+ return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2]);
+}
+
+DEFUN (ipv6_route_flags_pref,
+ ipv6_route_flags_pref_cmd,
+ "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
+ IP_STR
+ "Establish static routes\n"
+ "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 gateway address\n"
+ "IPv6 gateway interface name\n"
+ "Emit an ICMP unreachable when matched\n"
+ "Silently discard pkts when matched\n"
+ "Distance value for this prefix\n")
+{
+ return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
}
DEFUN (ipv6_route_ifname_pref,
@@ -937,7 +1155,22 @@ DEFUN (ipv6_route_ifname_pref,
"IPv6 gateway interface name\n"
"Distance value for this prefix\n")
{
- return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3]);
+ return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
+}
+
+DEFUN (ipv6_route_ifname_flags_pref,
+ ipv6_route_ifname_flags_pref_cmd,
+ "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
+ IP_STR
+ "Establish static routes\n"
+ "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 gateway address\n"
+ "IPv6 gateway interface name\n"
+ "Emit an ICMP unreachable when matched\n"
+ "Silently discard pkts when matched\n"
+ "Distance value for this prefix\n")
+{
+ return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
}
DEFUN (no_ipv6_route,
@@ -950,9 +1183,21 @@ DEFUN (no_ipv6_route,
"IPv6 gateway address\n"
"IPv6 gateway interface name\n")
{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL);
+ return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
}
+ALIAS (no_ipv6_route,
+ no_ipv6_route_flags_cmd,
+ "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
+ NO_STR
+ IP_STR
+ "Establish static routes\n"
+ "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 gateway address\n"
+ "IPv6 gateway interface name\n"
+ "Emit an ICMP unreachable when matched\n"
+ "Silently discard pkts when matched\n")
+
DEFUN (no_ipv6_route_ifname,
no_ipv6_route_ifname_cmd,
"no ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
@@ -963,9 +1208,21 @@ DEFUN (no_ipv6_route_ifname,
"IPv6 gateway address\n"
"IPv6 gateway interface name\n")
{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL);
+ return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
}
+ALIAS (no_ipv6_route_ifname,
+ no_ipv6_route_ifname_flags_cmd,
+ "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
+ NO_STR
+ IP_STR
+ "Establish static routes\n"
+ "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 gateway address\n"
+ "IPv6 gateway interface name\n"
+ "Emit an ICMP unreachable when matched\n"
+ "Silently discard pkts when matched\n")
+
DEFUN (no_ipv6_route_pref,
no_ipv6_route_pref_cmd,
"no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
@@ -977,7 +1234,24 @@ DEFUN (no_ipv6_route_pref,
"IPv6 gateway interface name\n"
"Distance value for this prefix\n")
{
- return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2]);
+ return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2]);
+}
+
+DEFUN (no_ipv6_route_flags_pref,
+ no_ipv6_route_flags_pref_cmd,
+ "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
+ NO_STR
+ IP_STR
+ "Establish static routes\n"
+ "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 gateway address\n"
+ "IPv6 gateway interface name\n"
+ "Emit an ICMP unreachable when matched\n"
+ "Silently discard pkts when matched\n"
+ "Distance value for this prefix\n")
+{
+ /* We do not care about argv[2] */
+ return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
}
DEFUN (no_ipv6_route_ifname_pref,
@@ -991,10 +1265,26 @@ DEFUN (no_ipv6_route_ifname_pref,
"IPv6 gateway interface name\n"
"Distance value for this prefix\n")
{
- return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3]);
+ return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
}
-/* New RIB. Detailed information for IPv4 route. */
+DEFUN (no_ipv6_route_ifname_flags_pref,
+ no_ipv6_route_ifname_flags_pref_cmd,
+ "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
+ NO_STR
+ IP_STR
+ "Establish static routes\n"
+ "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 gateway address\n"
+ "IPv6 gateway interface name\n"
+ "Emit an ICMP unreachable when matched\n"
+ "Silently discard pkts when matched\n"
+ "Distance value for this prefix\n")
+{
+ return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
+}
+
+/* New RIB. Detailed information for IPv6 route. */
void
vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
{
@@ -1014,6 +1304,10 @@ vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
vty_out (vty, ", best");
if (rib->refcnt)
vty_out (vty, ", refcnt %ld", rib->refcnt);
+ if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
+ vty_out (vty, ", blackhole");
+ if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
+ vty_out (vty, ", reject");
vty_out (vty, "%s", VTY_NEWLINE);
#define ONE_DAY_SECOND 60*60*24
@@ -1191,6 +1485,11 @@ vty_show_ipv6_route (struct vty *vty, struct route_node *rn,
}
}
+ if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
+ vty_out (vty, ", bh");
+ if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
+ vty_out (vty, ", rej");
+
if (rib->type == ZEBRA_ROUTE_RIPNG
|| rib->type == ZEBRA_ROUTE_OSPF6
|| rib->type == ZEBRA_ROUTE_BGP)
@@ -1465,6 +1764,12 @@ static_config_ipv6 (struct vty *vty)
break;
}
+ if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
+ vty_out (vty, " %s", "reject");
+
+ if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
+ vty_out (vty, " %s", "blackhole");
+
if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
vty_out (vty, " %d", si->distance);
vty_out (vty, "%s", VTY_NEWLINE);
@@ -1499,13 +1804,20 @@ zebra_vty_route_init ()
install_node (&ip_node, zebra_ip_config);
install_element (CONFIG_NODE, &ip_route_cmd);
+ install_element (CONFIG_NODE, &ip_route_flags_cmd);
install_element (CONFIG_NODE, &ip_route_mask_cmd);
+ install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
install_element (CONFIG_NODE, &no_ip_route_cmd);
+ install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
+ install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
install_element (CONFIG_NODE, &ip_route_distance_cmd);
+ install_element (CONFIG_NODE, &ip_route_flags_distance_cmd);
install_element (CONFIG_NODE, &ip_route_mask_distance_cmd);
+ install_element (CONFIG_NODE, &ip_route_mask_flags_distance_cmd);
install_element (CONFIG_NODE, &no_ip_route_distance_cmd);
- install_element (CONFIG_NODE, &no_ip_route_mask_distance_cmd);
+ install_element (CONFIG_NODE, &no_ip_route_flags_distance_cmd);
+ install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_cmd);
install_element (VIEW_NODE, &show_ip_route_cmd);
install_element (VIEW_NODE, &show_ip_route_addr_cmd);
@@ -1527,13 +1839,21 @@ zebra_vty_route_init ()
#ifdef HAVE_IPV6
install_element (CONFIG_NODE, &ipv6_route_cmd);
+ install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
+ install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
install_element (CONFIG_NODE, &no_ipv6_route_cmd);
+ install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
+ install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
install_element (CONFIG_NODE, &ipv6_route_pref_cmd);
+ install_element (CONFIG_NODE, &ipv6_route_flags_pref_cmd);
install_element (CONFIG_NODE, &ipv6_route_ifname_pref_cmd);
+ install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_cmd);
install_element (CONFIG_NODE, &no_ipv6_route_pref_cmd);
+ install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_cmd);
install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_cmd);
+ install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_cmd);
install_element (VIEW_NODE, &show_ipv6_route_cmd);
install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd);
install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 0508f905..975574af 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -451,6 +451,7 @@ zsend_ipv4_add_multipath (struct zserv *client, struct prefix *p,
{
stream_putc (s, 1);
+ /* XXX: Waht's about NEXTHOP_TYPE_IPV4_IFNAME ? */
if (nexthop->type == NEXTHOP_TYPE_IPV4
|| nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
stream_put_in_addr (s, &nexthop->gate.ipv4);
@@ -532,6 +533,8 @@ zsend_ipv4_delete_multipath (struct zserv *client, struct prefix *p,
return 0;
}
+#if 0
+#warning oldies
int
zsend_ipv4_add (struct zserv *client, int type, int flags,
struct prefix_ipv4 *p, struct in_addr *nexthop,
@@ -613,8 +616,11 @@ zsend_ipv4_delete (struct zserv *client, int type, int flags,
return 0;
}
+#endif /* oldies */
#ifdef HAVE_IPV6
+#if 0
+#warning oldies
int
zsend_ipv6_add (struct zserv *client, int type, int flags,
struct prefix_ipv6 *p, struct in6_addr *nexthop,
@@ -655,6 +661,7 @@ zsend_ipv6_add (struct zserv *client, int type, int flags,
return 0;
}
+#endif /* oldies */
int
zsend_ipv6_add_multipath (struct zserv *client, struct prefix *p,
@@ -690,7 +697,9 @@ zsend_ipv6_add_multipath (struct zserv *client, struct prefix *p,
{
stream_putc (s, 1);
- if (nexthop->type == NEXTHOP_TYPE_IPV6)
+ if (nexthop->type == NEXTHOP_TYPE_IPV6
+ || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
+ || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
else
stream_write (s, (u_char *) &empty, 16);
@@ -714,6 +723,8 @@ zsend_ipv6_add_multipath (struct zserv *client, struct prefix *p,
return 0;
}
+#if 0
+#warning oldies
int
zsend_ipv6_delete (struct zserv *client, int type, int flags,
struct prefix_ipv6 *p, struct in6_addr *nexthop,
@@ -754,6 +765,7 @@ zsend_ipv6_delete (struct zserv *client, int type, int flags,
return 0;
}
+#endif /* oldies */
int
zsend_ipv6_delete_multipath (struct zserv *client, struct prefix *p,
@@ -1089,9 +1101,9 @@ zread_ipv4_add (struct zserv *client, u_short length)
case ZEBRA_NEXTHOP_IPV6:
stream_forward (s, IPV6_MAX_BYTELEN);
break;
- case ZEBRA_NEXTHOP_BLACKHOLE:
- nexthop_blackhole_add (rib);
- break;
+ case ZEBRA_NEXTHOP_BLACKHOLE:
+ nexthop_blackhole_add (rib);
+ break;
}
}
}
@@ -1757,6 +1769,32 @@ DEFUN (config_table,
return CMD_SUCCESS;
}
+DEFUN (ip_forwarding,
+ ip_forwarding_cmd,
+ "ip forwarding",
+ IP_STR
+ "Turn on IP forwarding")
+{
+ int ret;
+
+ ret = ipforward ();
+
+ if (ret != 0)
+ {
+ vty_out (vty, "IP forwarding is already on%s", VTY_NEWLINE);
+ return CMD_ERR_NOTHING_TODO;
+ }
+
+ ret = ipforward_on ();
+ if (ret == 0)
+ {
+ vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
+}
+
DEFUN (no_ip_forwarding,
no_ip_forwarding_cmd,
"no ip forwarding",
@@ -1941,6 +1979,7 @@ zebra_init ()
install_element (VIEW_NODE, &show_ip_forwarding_cmd);
install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
+ install_element (CONFIG_NODE, &ip_forwarding_cmd);
install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
install_element (ENABLE_NODE, &show_zebra_client_cmd);
diff --git a/zebra/zserv.h b/zebra/zserv.h
index c7622808..ec3c9f4b 100644
--- a/zebra/zserv.h
+++ b/zebra/zserv.h
@@ -25,8 +25,6 @@
/* Default port information. */
#define ZEBRA_PORT 2600
#define ZEBRA_VTY_PORT 2601
-#define ZEBRA_VTYSH_PATH "/tmp/.zebra"
-#define ZEBRA_SERV_PATH "/tmp/.zserv"
/* Default configuration filename. */
#define DEFAULT_CONFIG_FILE "zebra.conf"
@@ -91,6 +89,8 @@ zsend_interface_up (struct zserv *, struct interface *);
int
zsend_interface_down (struct zserv *, struct interface *);
+#if 0
+#warning oldies
int
zsend_ipv4_add (struct zserv *client, int type, int flags,
struct prefix_ipv4 *p, struct in_addr *nexthop,
@@ -100,6 +100,7 @@ int
zsend_ipv4_delete (struct zserv *client, int type, int flags,
struct prefix_ipv4 *p, struct in_addr *nexthop,
unsigned int ifindex);
+#endif
int
zsend_ipv4_add_multipath (struct zserv *, struct prefix *, struct rib *);
@@ -108,6 +109,8 @@ int
zsend_ipv4_delete_multipath (struct zserv *, struct prefix *, struct rib *);
#ifdef HAVE_IPV6
+#if 0
+#warning oldies
int
zsend_ipv6_add (struct zserv *client, int type, int flags,
struct prefix_ipv6 *p, struct in6_addr *nexthop,
@@ -117,6 +120,7 @@ int
zsend_ipv6_delete (struct zserv *client, int type, int flags,
struct prefix_ipv6 *p, struct in6_addr *nexthop,
unsigned int ifindex);
+#endif
int
zsend_ipv6_add_multipath (struct zserv *, struct prefix *, struct rib *);