Route (reject|blackhole) support from 6Wind patch.

This commit is contained in:
hasso 2003-05-25 19:21:25 +00:00
parent 15291357d1
commit 81dfcaa2e2
9 changed files with 403 additions and 131 deletions

View File

@ -317,12 +317,6 @@ zapi_ipv4_add (struct zclient *zclient, struct prefix_ipv4 *p,
/* Nexthop, ifindex, distance and metric information. */
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
{
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++)
@ -377,12 +371,6 @@ zapi_ipv4_delete (struct zclient *zclient, struct prefix_ipv4 *p,
/* Nexthop, ifindex, distance and metric information. */
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
{
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++)

View File

@ -256,6 +256,7 @@ struct in_pktinfo
#define ZEBRA_FLAG_SELECTED 0x10
#define ZEBRA_FLAG_CHANGED 0x20
#define ZEBRA_FLAG_STATIC 0x40
#define ZEBRA_FLAG_REJECT 0x80
/* Zebra nexthop flags. */
#define ZEBRA_NEXTHOP_IFINDEX 1
@ -266,7 +267,6 @@ struct in_pktinfo
#define ZEBRA_NEXTHOP_IPV6 6
#define ZEBRA_NEXTHOP_IPV6_IFINDEX 7
#define ZEBRA_NEXTHOP_IPV6_IFNAME 8
#define ZEBRA_NEXTHOP_BLACKHOLE 9
#ifndef INADDR_LOOPBACK
#define INADDR_LOOPBACK 0x7f000001 /* Internet address 127.0.0.1. */

View File

@ -148,6 +148,7 @@ rtm_flag_dump (int flag)
struct message *mes;
static char buf[BUFSIZ];
buf[0] = '0';
for (mes = rtm_flag_str; mes->key != 0; mes++)
{
if (mes->key & flag)
@ -476,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;
@ -619,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) \

View File

@ -76,7 +76,6 @@ struct static_ipv4
u_char type;
#define STATIC_IPV4_GATEWAY 1
#define STATIC_IPV4_IFNAME 2
#define STATIC_IPV4_BLACKHOLE 3
/* Nexthop value. */
union
@ -84,6 +83,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 +112,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 */
@ -124,7 +137,6 @@ struct nexthop
#define NEXTHOP_TYPE_IPV6 6 /* IPv6 nexthop. */
#define NEXTHOP_TYPE_IPV6_IFINDEX 7 /* IPv6 nexthop with ifindex. */
#define NEXTHOP_TYPE_IPV6_IFNAME 8 /* IPv6 nexthop with ifname. */
#define NEXTHOP_TYPE_BLACKHOLE 9 /* Null0 nexthop. */
u_char flags;
#define NEXTHOP_FLAG_ACTIVE (1 << 0) /* This nexthop is alive. */
@ -182,7 +194,6 @@ struct vrf
struct nexthop *nexthop_ifindex_add (struct rib *, unsigned int);
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 *);
#ifdef HAVE_IPV6
struct nexthop *nexthop_ipv6_add (struct rib *, struct in6_addr *);
@ -217,7 +228,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 +251,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,

View File

@ -1163,7 +1163,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;
@ -1173,9 +1174,13 @@ 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;
else
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;
}
@ -1236,7 +1241,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;
@ -1246,9 +1252,13 @@ 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;
else
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;
}

View File

@ -129,14 +129,6 @@ 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 (cmd == RTM_ADD)

View File

@ -305,22 +305,6 @@ nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *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
the route from FIB. */
int
@ -739,9 +723,6 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
}
break;
#endif /* HAVE_IPV6 */
case NEXTHOP_TYPE_BLACKHOLE:
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
break;
default:
break;
}
@ -1289,9 +1270,6 @@ 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;
}
rib_process (rn, NULL);
}
@ -1314,11 +1292,11 @@ 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;
}
/* Save the flags of this static routes (reject, blackhole) */
rib->flags = si->flags;
/* Link this rib to the tree. */
rib_addnode (rn, rib);
@ -1338,9 +1316,6 @@ static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
&& si->type == STATIC_IPV4_IFNAME
&& strcmp (nexthop->ifname, si->gate.ifname) == 0)
return 1;
if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
&& si->type == STATIC_IPV4_BLACKHOLE)
return 1;
return 0;;
}
@ -1408,7 +1383,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;
@ -1429,10 +1404,8 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, char *ifname,
/* Make flags. */
if (gate)
type = STATIC_IPV4_GATEWAY;
else if (ifname)
if (ifname)
type = STATIC_IPV4_IFNAME;
else
type = STATIC_IPV4_BLACKHOLE;
/* Do nothing if there is a same static route. */
for (si = rn->info; si; si = si->next)
@ -1461,6 +1434,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;
@ -1525,8 +1499,6 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, char *ifname,
type = STATIC_IPV4_GATEWAY;
else if (ifname)
type = STATIC_IPV4_IFNAME;
else
type = STATIC_IPV4_BLACKHOLE;
/* Find same static route is the tree */
for (si = rn->info; si; si = si->next)
@ -1869,6 +1841,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);
@ -1958,7 +1933,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;
@ -1993,6 +1968,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)
{

View File

@ -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)
@ -120,22 +121,29 @@ zebra_static_ipv4 (struct vty *vty, int add_cmd,
/* 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);
break;
}
}
/* 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 (add_cmd)
static_add_ipv4 (&p, NULL, NULL, distance, 0);
else
static_delete_ipv4 (&p, NULL, NULL, distance, 0);
return CMD_SUCCESS;
}
/* 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 +153,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);
@ -155,79 +163,160 @@ zebra_static_ipv4 (struct vty *vty, int add_cmd,
/* Static route configuration. */
DEFUN (ip_route,
ip_route_cmd,
"ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
"ip route A.B.C.D/M (A.B.C.D|INTERFACE)",
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")
{
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"
"Null interface\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], NULL);
return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], NULL);
}
/* Mask as A.B.C.D format. */
DEFUN (ip_route_mask,
ip_route_mask_cmd,
"ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
"ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE)",
IP_STR
"Establish static routes\n"
"IP destination prefix\n"
"IP destination prefix mask\n"
"IP gateway address\n"
"IP gateway interface name\n")
{
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"
"Null interface\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], NULL);
return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
}
/* Distance option value. */
DEFUN (ip_route_distance,
ip_route_distance_cmd,
"ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
"ip route A.B.C.D/M (A.B.C.D|INTERFACE) <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"
"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,
ip_route_mask_distance_cmd,
"ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
"ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) <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"
"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,
no_ip_route_cmd,
"no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
"no ip route A.B.C.D/M (A.B.C.D|INTERFACE)",
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")
{
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"
"Null interface\n")
{
return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL);
}
"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)",
"no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE)",
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")
{
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"
@ -235,29 +324,42 @@ DEFUN (no_ip_route_mask,
"IP destination prefix mask\n"
"IP gateway address\n"
"IP gateway interface name\n"
"Null interface\n")
{
return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL);
}
"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>",
"no ip route A.B.C.D/M (A.B.C.D|INTERFACE) <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"
"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,
no_ip_route_mask_distance_cmd,
"no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
"no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) <1-255>",
NO_STR
IP_STR
"Establish static routes\n"
@ -265,10 +367,26 @@ DEFUN (no_ip_route_mask_distance,
"IP destination prefix mask\n"
"IP gateway address\n"
"IP gateway interface name\n"
"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 +407,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 +461,6 @@ 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;
default:
break;
}
@ -422,8 +541,6 @@ 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");
default:
break;
}
@ -450,6 +567,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 +930,14 @@ 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;
}
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 +951,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 +960,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 +972,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);
break;
}
}
/* Administrative distance. */
if (distance_str)
distance = atoi (distance_str);
@ -883,7 +1026,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 +1042,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 +1068,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 +1095,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 +1123,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 +1151,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 +1176,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 +1202,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,7 +1233,23 @@ 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]);
}
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 IPv4 route. */
@ -1014,6 +1272,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 +1453,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 +1732,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 +1772,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 +1807,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);

View File

@ -1086,9 +1086,6 @@ 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;
}
}
}