Add back support for null0 interface blackhole routes.

This commit is contained in:
paul 2003-05-25 21:35:06 +00:00
parent 726f9b2bbd
commit 595db7f165
10 changed files with 156 additions and 63 deletions

View File

@ -160,7 +160,7 @@ dnl -------------------
dnl Check header files. dnl Check header files.
dnl ------------------- dnl -------------------
AC_STDC_HEADERS AC_STDC_HEADERS
AC_CHECK_HEADERS(string.h stropts.h sys/conf.h sys/ksym.h sys/time.h sys/times.h sys/select.h sys/sysctl.h sys/sockio.h sys/types.h net/if_dl.h net/if_var.h linux/version.h kvm.h netdb.h netinet/in.h net/netopt.h netinet/in_var.h netinet/in6_var.h netinet6/in6_var.h netinet/in6.h netinet6/in6.h inet/nd.h asm/types.h netinet/icmp6.h netinet6/nd6.h libutil.h) AC_CHECK_HEADERS(string.h stropts.h sys/conf.h sys/ksym.h sys/time.h sys/times.h sys/select.h sys/sysctl.h sys/sockio.h sys/types.h net/if_dl.h net/if_var.h linux/version.h kvm.h netdb.h netinet/in.h net/netopt.h netinet/in_var.h netinet/in6_var.h netinet6/in6_var.h netinet/in6.h inet/nd.h asm/types.h netinet/icmp6.h netinet6/nd6.h libutil.h)
dnl check some types dnl check some types
AC_C_CONST AC_C_CONST

View File

@ -160,7 +160,7 @@ dnl -------------------
dnl Check header files. dnl Check header files.
dnl ------------------- dnl -------------------
AC_STDC_HEADERS AC_STDC_HEADERS
AC_CHECK_HEADERS(string.h stropts.h sys/conf.h sys/ksym.h sys/time.h sys/times.h sys/select.h sys/sysctl.h sys/sockio.h sys/types.h net/if_dl.h net/if_var.h linux/version.h kvm.h netdb.h netinet/in.h net/netopt.h netinet/in_var.h netinet/in6_var.h netinet6/in6_var.h netinet/in6.h netinet6/in6.h inet/nd.h asm/types.h netinet/icmp6.h netinet6/nd6.h libutil.h) AC_CHECK_HEADERS(string.h stropts.h sys/conf.h sys/ksym.h sys/time.h sys/times.h sys/select.h sys/sysctl.h sys/sockio.h sys/types.h net/if_dl.h net/if_var.h linux/version.h kvm.h netdb.h netinet/in.h net/netopt.h netinet/in_var.h netinet/in6_var.h netinet6/in6_var.h netinet/in6.h inet/nd.h asm/types.h netinet/icmp6.h netinet6/nd6.h libutil.h)
dnl check some types dnl check some types
AC_C_CONST AC_C_CONST

View File

@ -317,18 +317,24 @@ zapi_ipv4_add (struct zclient *zclient, struct prefix_ipv4 *p,
/* Nexthop, ifindex, distance and metric information. */ /* Nexthop, ifindex, distance and metric information. */
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP)) if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
{ {
stream_putc (s, api->nexthop_num + api->ifindex_num); if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
{
stream_putc (s, 1);
stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
}
else
stream_putc (s, api->nexthop_num + api->ifindex_num);
for (i = 0; i < api->nexthop_num; i++) for (i = 0; i < api->nexthop_num; i++)
{ {
stream_putc (s, ZEBRA_NEXTHOP_IPV4); stream_putc (s, ZEBRA_NEXTHOP_IPV4);
stream_put_in_addr (s, api->nexthop[i]); stream_put_in_addr (s, api->nexthop[i]);
} }
for (i = 0; i < api->ifindex_num; i++) for (i = 0; i < api->ifindex_num; i++)
{ {
stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
stream_putl (s, api->ifindex[i]); stream_putl (s, api->ifindex[i]);
} }
} }
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE)) if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
@ -371,18 +377,24 @@ zapi_ipv4_delete (struct zclient *zclient, struct prefix_ipv4 *p,
/* Nexthop, ifindex, distance and metric information. */ /* Nexthop, ifindex, distance and metric information. */
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP)) if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
{ {
stream_putc (s, api->nexthop_num + api->ifindex_num); if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
{
stream_putc (s, 1);
stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
}
else
stream_putc (s, api->nexthop_num + api->ifindex_num);
for (i = 0; i < api->nexthop_num; i++) for (i = 0; i < api->nexthop_num; i++)
{ {
stream_putc (s, ZEBRA_NEXTHOP_IPV4); stream_putc (s, ZEBRA_NEXTHOP_IPV4);
stream_put_in_addr (s, api->nexthop[i]); stream_put_in_addr (s, api->nexthop[i]);
} }
for (i = 0; i < api->ifindex_num; i++) for (i = 0; i < api->ifindex_num; i++)
{ {
stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
stream_putl (s, api->ifindex[i]); stream_putl (s, api->ifindex[i]);
} }
} }
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE)) if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))

View File

@ -271,6 +271,7 @@ struct in_pktinfo
#define ZEBRA_NEXTHOP_IPV6 6 #define ZEBRA_NEXTHOP_IPV6 6
#define ZEBRA_NEXTHOP_IPV6_IFINDEX 7 #define ZEBRA_NEXTHOP_IPV6_IFINDEX 7
#define ZEBRA_NEXTHOP_IPV6_IFNAME 8 #define ZEBRA_NEXTHOP_IPV6_IFNAME 8
#define ZEBRA_NEXTHOP_BLACKHOLE 9
#ifndef INADDR_LOOPBACK #ifndef INADDR_LOOPBACK
#define INADDR_LOOPBACK 0x7f000001 /* Internet address 127.0.0.1. */ #define INADDR_LOOPBACK 0x7f000001 /* Internet address 127.0.0.1. */

View File

@ -76,6 +76,7 @@ struct static_ipv4
u_char type; u_char type;
#define STATIC_IPV4_GATEWAY 1 #define STATIC_IPV4_GATEWAY 1
#define STATIC_IPV4_IFNAME 2 #define STATIC_IPV4_IFNAME 2
#define STATIC_IPV4_BLACKHOLE 3
/* Nexthop value. */ /* Nexthop value. */
union union
@ -137,6 +138,7 @@ struct nexthop
#define NEXTHOP_TYPE_IPV6 6 /* IPv6 nexthop. */ #define NEXTHOP_TYPE_IPV6 6 /* IPv6 nexthop. */
#define NEXTHOP_TYPE_IPV6_IFINDEX 7 /* IPv6 nexthop with ifindex. */ #define NEXTHOP_TYPE_IPV6_IFINDEX 7 /* IPv6 nexthop with ifindex. */
#define NEXTHOP_TYPE_IPV6_IFNAME 8 /* IPv6 nexthop with ifname. */ #define NEXTHOP_TYPE_IPV6_IFNAME 8 /* IPv6 nexthop with ifname. */
#define NEXTHOP_TYPE_BLACKHOLE 9 /* Null0 nexthop. */
u_char flags; u_char flags;
#define NEXTHOP_FLAG_ACTIVE (1 << 0) /* This nexthop is alive. */ #define NEXTHOP_FLAG_ACTIVE (1 << 0) /* This nexthop is alive. */
@ -194,6 +196,7 @@ struct vrf
struct nexthop *nexthop_ifindex_add (struct rib *, unsigned int); struct nexthop *nexthop_ifindex_add (struct rib *, unsigned int);
struct nexthop *nexthop_ifname_add (struct rib *, char *); struct nexthop *nexthop_ifname_add (struct rib *, char *);
struct nexthop *nexthop_blackhole_add (struct rib *);
struct nexthop *nexthop_ipv4_add (struct rib *, struct in_addr *); struct nexthop *nexthop_ipv4_add (struct rib *, struct in_addr *);
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
struct nexthop *nexthop_ipv6_add (struct rib *, struct in6_addr *); struct nexthop *nexthop_ipv6_add (struct rib *, struct in6_addr *);

View File

@ -1174,14 +1174,16 @@ netlink_route (int cmd, int family, void *dest, int length, void *gate,
req.r.rtm_protocol = RTPROT_ZEBRA; req.r.rtm_protocol = RTPROT_ZEBRA;
req.r.rtm_scope = RT_SCOPE_UNIVERSE; req.r.rtm_scope = RT_SCOPE_UNIVERSE;
if (discard) { if (discard)
if (zebra_flags & ZEBRA_FLAG_BLACKHOLE) {
req.r.rtm_type = RTN_BLACKHOLE; if (zebra_flags & ZEBRA_FLAG_BLACKHOLE)
else if (zebra_flags & ZEBRA_FLAG_REJECT) req.r.rtm_type = RTN_BLACKHOLE;
req.r.rtm_type = RTN_UNREACHABLE; else if (zebra_flags & ZEBRA_FLAG_REJECT)
else assert(RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */ req.r.rtm_type = RTN_UNREACHABLE;
} else else assert(RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */
req.r.rtm_type = RTN_UNICAST; }
else
req.r.rtm_type = RTN_UNICAST;
} }
if (dest) if (dest)
@ -1252,14 +1254,16 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
req.r.rtm_protocol = RTPROT_ZEBRA; req.r.rtm_protocol = RTPROT_ZEBRA;
req.r.rtm_scope = RT_SCOPE_UNIVERSE; req.r.rtm_scope = RT_SCOPE_UNIVERSE;
if (discard) { if (discard)
if (rib->flags & ZEBRA_FLAG_BLACKHOLE) {
req.r.rtm_type = RTN_BLACKHOLE; if (rib->flags & ZEBRA_FLAG_BLACKHOLE)
else if (rib->flags & ZEBRA_FLAG_REJECT) req.r.rtm_type = RTN_BLACKHOLE;
req.r.rtm_type = RTN_UNREACHABLE; else if (rib->flags & ZEBRA_FLAG_REJECT)
else assert(RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */ req.r.rtm_type = RTN_UNREACHABLE;
} else else assert(RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */
req.r.rtm_type = RTN_UNICAST; }
else
req.r.rtm_type = RTN_UNICAST;
} }
addattr_l (&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen); addattr_l (&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen);

View File

@ -129,7 +129,14 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family)
|| nexthop->type == NEXTHOP_TYPE_IFNAME || nexthop->type == NEXTHOP_TYPE_IFNAME
|| nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
ifindex = nexthop->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 (cmd == RTM_ADD) if (cmd == RTM_ADD)
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);

View File

@ -305,6 +305,21 @@ nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
} }
#endif /* HAVE_IPV6 */ #endif /* HAVE_IPV6 */
struct nexthop *
nexthop_blackhole_add (struct rib *rib)
{
struct nexthop *nexthop;
nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
memset (nexthop, 0, sizeof (struct nexthop));
nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
nexthop_add (rib, nexthop);
return nexthop;
}
/* If force flag is not set, do not modify falgs at all for uninstall /* If force flag is not set, do not modify falgs at all for uninstall
the route from FIB. */ the route from FIB. */
int int
@ -723,6 +738,9 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
} }
break; break;
#endif /* HAVE_IPV6 */ #endif /* HAVE_IPV6 */
case NEXTHOP_TYPE_BLACKHOLE:
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
break;
default: default:
break; break;
} }
@ -1270,6 +1288,9 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
case STATIC_IPV4_IFNAME: case STATIC_IPV4_IFNAME:
nexthop_ifname_add (rib, si->gate.ifname); nexthop_ifname_add (rib, si->gate.ifname);
break; break;
case STATIC_IPV4_BLACKHOLE:
nexthop_blackhole_add (rib);
break;
} }
rib_process (rn, NULL); rib_process (rn, NULL);
} }
@ -1292,6 +1313,9 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
case STATIC_IPV4_IFNAME: case STATIC_IPV4_IFNAME:
nexthop_ifname_add (rib, si->gate.ifname); nexthop_ifname_add (rib, si->gate.ifname);
break; break;
case STATIC_IPV4_BLACKHOLE:
nexthop_blackhole_add (rib);
break;
} }
/* Save the flags of this static routes (reject, blackhole) */ /* Save the flags of this static routes (reject, blackhole) */
@ -1316,6 +1340,9 @@ static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
&& si->type == STATIC_IPV4_IFNAME && si->type == STATIC_IPV4_IFNAME
&& strcmp (nexthop->ifname, si->gate.ifname) == 0) && strcmp (nexthop->ifname, si->gate.ifname) == 0)
return 1; return 1;
if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
&& si->type == STATIC_IPV4_BLACKHOLE)
return 1;
return 0;; return 0;;
} }
@ -1406,6 +1433,8 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, char *ifname,
type = STATIC_IPV4_GATEWAY; type = STATIC_IPV4_GATEWAY;
if (ifname) if (ifname)
type = STATIC_IPV4_IFNAME; type = STATIC_IPV4_IFNAME;
else
type = STATIC_IPV4_BLACKHOLE;
/* Do nothing if there is a same static route. */ /* Do nothing if there is a same static route. */
for (si = rn->info; si; si = si->next) for (si = rn->info; si; si = si->next)
@ -1499,6 +1528,8 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, char *ifname,
type = STATIC_IPV4_GATEWAY; type = STATIC_IPV4_GATEWAY;
else if (ifname) else if (ifname)
type = STATIC_IPV4_IFNAME; type = STATIC_IPV4_IFNAME;
else
type = STATIC_IPV4_BLACKHOLE;
/* Find same static route is the tree */ /* Find same static route is the tree */
for (si = rn->info; si; si = si->next) for (si = rn->info; si; si = si->next)

View File

@ -111,16 +111,37 @@ zebra_static_ipv4 (struct vty *vty, int add_cmd,
{ {
ret = inet_aton (mask_str, &mask); ret = inet_aton (mask_str, &mask);
if (ret == 0) if (ret == 0)
{ {
vty_out (vty, "%% Malformed address%s", VTY_NEWLINE); vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
return CMD_WARNING; return CMD_WARNING;
} }
p.prefixlen = ip_masklen (mask); p.prefixlen = ip_masklen (mask);
} }
/* Apply mask for given prefix. */ /* Apply mask for given prefix. */
apply_mask (&p); apply_mask (&p);
/* Administrative distance. */
if (distance_str)
distance = atoi (distance_str);
else
distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
/* 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, 0, distance, 0);
else
static_delete_ipv4 (&p, NULL, NULL, distance, 0);
return CMD_SUCCESS;
}
/* Route flags */ /* Route flags */
if (flag_str) { if (flag_str) {
switch(flag_str[0]) { switch(flag_str[0]) {
@ -134,16 +155,10 @@ zebra_static_ipv4 (struct vty *vty, int add_cmd,
break; break;
default: default:
vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE); vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
break; return CMD_WARNING;
} }
} }
/* Administrative distance. */
if (distance_str)
distance = atoi (distance_str);
else
distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
/* When gateway is A.B.C.D format, gate is treated as nexthop /* When gateway is A.B.C.D format, gate is treated as nexthop
address other case gate is treated as interface name. */ address other case gate is treated as interface name. */
ret = inet_aton (gate_str, &gate); ret = inet_aton (gate_str, &gate);
@ -163,12 +178,13 @@ zebra_static_ipv4 (struct vty *vty, int add_cmd,
/* Static route configuration. */ /* Static route configuration. */
DEFUN (ip_route, DEFUN (ip_route,
ip_route_cmd, ip_route_cmd,
"ip route A.B.C.D/M (A.B.C.D|INTERFACE)", "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
IP_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
"IP destination prefix (e.g. 10.0.0.0/8)\n" "IP destination prefix (e.g. 10.0.0.0/8)\n"
"IP gateway address\n" "IP gateway address\n"
"IP gateway interface name\n") "IP gateway interface name\n"
"Null interface\n")
{ {
return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL); return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL);
} }
@ -190,13 +206,14 @@ DEFUN (ip_route_flags,
/* Mask as A.B.C.D format. */ /* Mask as A.B.C.D format. */
DEFUN (ip_route_mask, DEFUN (ip_route_mask,
ip_route_mask_cmd, ip_route_mask_cmd,
"ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE)", "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
IP_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
"IP destination prefix\n" "IP destination prefix\n"
"IP destination prefix mask\n" "IP destination prefix mask\n"
"IP gateway address\n" "IP gateway address\n"
"IP gateway interface name\n") "IP gateway interface name\n"
"Null interface\n")
{ {
return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL); return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
} }
@ -219,12 +236,13 @@ DEFUN (ip_route_mask_flags,
/* Distance option value. */ /* Distance option value. */
DEFUN (ip_route_distance, DEFUN (ip_route_distance,
ip_route_distance_cmd, ip_route_distance_cmd,
"ip route A.B.C.D/M (A.B.C.D|INTERFACE) <1-255>", "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
IP_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
"IP destination prefix (e.g. 10.0.0.0/8)\n" "IP destination prefix (e.g. 10.0.0.0/8)\n"
"IP gateway address\n" "IP gateway address\n"
"IP gateway interface name\n" "IP gateway interface name\n"
"Null interface\n"
"Distance value for this route\n") "Distance value for this route\n")
{ {
return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2]); return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2]);
@ -247,13 +265,14 @@ DEFUN (ip_route_flags_distance,
DEFUN (ip_route_mask_distance, DEFUN (ip_route_mask_distance,
ip_route_mask_distance_cmd, ip_route_mask_distance_cmd,
"ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) <1-255>", "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
IP_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
"IP destination prefix\n" "IP destination prefix\n"
"IP destination prefix mask\n" "IP destination prefix mask\n"
"IP gateway address\n" "IP gateway address\n"
"IP gateway interface name\n" "IP gateway interface name\n"
"Null interface\n"
"Distance value for this route\n") "Distance value for this route\n")
{ {
return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]); return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
@ -277,13 +296,14 @@ DEFUN (ip_route_mask_flags_distance,
DEFUN (no_ip_route, DEFUN (no_ip_route,
no_ip_route_cmd, no_ip_route_cmd,
"no ip route A.B.C.D/M (A.B.C.D|INTERFACE)", "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
NO_STR NO_STR
IP_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
"IP destination prefix (e.g. 10.0.0.0/8)\n" "IP destination prefix (e.g. 10.0.0.0/8)\n"
"IP gateway address\n" "IP gateway address\n"
"IP gateway interface name\n") "IP gateway interface name\n"
"Null interface\n")
{ {
return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL); return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL);
} }
@ -302,14 +322,15 @@ ALIAS (no_ip_route,
DEFUN (no_ip_route_mask, DEFUN (no_ip_route_mask,
no_ip_route_mask_cmd, no_ip_route_mask_cmd,
"no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE)", "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
NO_STR NO_STR
IP_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
"IP destination prefix\n" "IP destination prefix\n"
"IP destination prefix mask\n" "IP destination prefix mask\n"
"IP gateway address\n" "IP gateway address\n"
"IP gateway interface name\n") "IP gateway interface name\n"
"Null interface\n")
{ {
return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL); return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
} }
@ -329,13 +350,14 @@ ALIAS (no_ip_route_mask,
DEFUN (no_ip_route_distance, DEFUN (no_ip_route_distance,
no_ip_route_distance_cmd, no_ip_route_distance_cmd,
"no ip route A.B.C.D/M (A.B.C.D|INTERFACE) <1-255>", "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
NO_STR NO_STR
IP_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
"IP destination prefix (e.g. 10.0.0.0/8)\n" "IP destination prefix (e.g. 10.0.0.0/8)\n"
"IP gateway address\n" "IP gateway address\n"
"IP gateway interface name\n" "IP gateway interface name\n"
"Null interface\n"
"Distance value for this route\n") "Distance value for this route\n")
{ {
return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2]); return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2]);
@ -359,7 +381,7 @@ DEFUN (no_ip_route_flags_distance,
DEFUN (no_ip_route_mask_distance, DEFUN (no_ip_route_mask_distance,
no_ip_route_mask_distance_cmd, no_ip_route_mask_distance_cmd,
"no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) <1-255>", "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
NO_STR NO_STR
IP_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
@ -367,6 +389,7 @@ DEFUN (no_ip_route_mask_distance,
"IP destination prefix mask\n" "IP destination prefix mask\n"
"IP gateway address\n" "IP gateway address\n"
"IP gateway interface name\n" "IP gateway interface name\n"
"Null interface\n"
"Distance value for this route\n") "Distance value for this route\n")
{ {
return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]); return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
@ -461,6 +484,9 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
case NEXTHOP_TYPE_IFNAME: case NEXTHOP_TYPE_IFNAME:
vty_out (vty, " directly connected, %s", nexthop->ifname); vty_out (vty, " directly connected, %s", nexthop->ifname);
break; break;
case NEXTHOP_TYPE_BLACKHOLE:
vty_out (vty, " directly connected, via Null0");
break;
default: default:
break; break;
} }
@ -541,6 +567,9 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
case NEXTHOP_TYPE_IFNAME: case NEXTHOP_TYPE_IFNAME:
vty_out (vty, " is directly connected, %s", nexthop->ifname); vty_out (vty, " is directly connected, %s", nexthop->ifname);
break; break;
case NEXTHOP_TYPE_BLACKHOLE:
vty_out (vty, " is directly connected, Null0");
break;
default: default:
break; break;
} }
@ -930,6 +959,9 @@ static_config_ipv4 (struct vty *vty)
case STATIC_IPV4_IFNAME: case STATIC_IPV4_IFNAME:
vty_out (vty, " %s", si->gate.ifname); vty_out (vty, " %s", si->gate.ifname);
break; break;
case STATIC_IPV4_BLACKHOLE:
vty_out (vty, " Null0");
break;
} }
if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT)) if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
@ -985,7 +1017,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, char *dest_str,
break; break;
default: default:
vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE); vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
break; return CMD_WARNING;
} }
} }
@ -1252,7 +1284,7 @@ DEFUN (no_ipv6_route_ifname_flags_pref,
return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]); return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
} }
/* New RIB. Detailed information for IPv4 route. */ /* New RIB. Detailed information for IPv6 route. */
void void
vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn) vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
{ {

View File

@ -1098,6 +1098,9 @@ zread_ipv4_add (struct zserv *client, u_short length)
case ZEBRA_NEXTHOP_IPV6: case ZEBRA_NEXTHOP_IPV6:
stream_forward (s, IPV6_MAX_BYTELEN); stream_forward (s, IPV6_MAX_BYTELEN);
break; break;
case ZEBRA_NEXTHOP_BLACKHOLE:
nexthop_blackhole_add (rib);
break;
} }
} }
} }