mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 11:15:47 +00:00
zebra: allow fully specified static ipv4 routes
Fully specified routes are useful when you need to ensure that the nexthop address is reachable through the specified interface. Addresses Issue #641. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
parent
c6cef20ba9
commit
599186ad97
@ -81,6 +81,10 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
|
||||
nh_p.u.prefix4 = si->addr.ipv4;
|
||||
zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
|
||||
break;
|
||||
case STATIC_IPV4_GATEWAY_IFINDEX:
|
||||
nexthop = route_entry_nexthop_ipv4_ifindex_add(
|
||||
re, &si->addr.ipv4, NULL, si->ifindex);
|
||||
break;
|
||||
case STATIC_IFINDEX:
|
||||
nexthop = route_entry_nexthop_ifindex_add(re,
|
||||
si->ifindex);
|
||||
@ -152,6 +156,10 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
|
||||
nh_p.u.prefix4 = si->addr.ipv4;
|
||||
zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn);
|
||||
break;
|
||||
case STATIC_IPV4_GATEWAY_IFINDEX:
|
||||
nexthop = route_entry_nexthop_ipv4_ifindex_add(
|
||||
re, &si->addr.ipv4, NULL, si->ifindex);
|
||||
break;
|
||||
case STATIC_IFINDEX:
|
||||
nexthop = route_entry_nexthop_ifindex_add(re,
|
||||
si->ifindex);
|
||||
@ -216,6 +224,11 @@ static int static_nexthop_same(struct nexthop *nexthop, struct static_route *si)
|
||||
&& si->type == STATIC_IPV4_GATEWAY
|
||||
&& IPV4_ADDR_SAME(&nexthop->gate.ipv4, &si->addr.ipv4))
|
||||
return 1;
|
||||
else if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
|
||||
&& si->type == STATIC_IPV4_GATEWAY_IFINDEX
|
||||
&& IPV4_ADDR_SAME(&nexthop->gate.ipv4, &si->addr.ipv4)
|
||||
&& nexthop->ifindex == si->ifindex)
|
||||
return 1;
|
||||
else if (nexthop->type == NEXTHOP_TYPE_IFINDEX
|
||||
&& si->type == STATIC_IFINDEX
|
||||
&& nexthop->ifindex == si->ifindex)
|
||||
@ -361,12 +374,17 @@ int static_add_route(afi_t afi, safi_t safi, u_char type, struct prefix *p,
|
||||
if (!stable)
|
||||
return -1;
|
||||
|
||||
if (!gate && (type == STATIC_IPV4_GATEWAY || type == STATIC_IPV6_GATEWAY
|
||||
|| type == STATIC_IPV6_GATEWAY_IFINDEX))
|
||||
if (!gate
|
||||
&& (type == STATIC_IPV4_GATEWAY
|
||||
|| type == STATIC_IPV4_GATEWAY_IFINDEX
|
||||
|| type == STATIC_IPV6_GATEWAY
|
||||
|| type == STATIC_IPV6_GATEWAY_IFINDEX))
|
||||
return -1;
|
||||
|
||||
if (!ifindex
|
||||
&& (type == STATIC_IFINDEX || type == STATIC_IPV6_GATEWAY_IFINDEX))
|
||||
&& (type == STATIC_IFINDEX
|
||||
|| type == STATIC_IPV4_GATEWAY_IFINDEX
|
||||
|| type == STATIC_IPV6_GATEWAY_IFINDEX))
|
||||
return -1;
|
||||
|
||||
/* Lookup static route prefix. */
|
||||
@ -411,11 +429,10 @@ int static_add_route(afi_t afi, safi_t safi, u_char type, struct prefix *p,
|
||||
|
||||
switch (type) {
|
||||
case STATIC_IPV4_GATEWAY:
|
||||
case STATIC_IPV4_GATEWAY_IFINDEX:
|
||||
si->addr.ipv4 = gate->ipv4;
|
||||
break;
|
||||
case STATIC_IPV6_GATEWAY:
|
||||
si->addr.ipv6 = gate->ipv6;
|
||||
break;
|
||||
case STATIC_IPV6_GATEWAY_IFINDEX:
|
||||
si->addr.ipv6 = gate->ipv6;
|
||||
break;
|
||||
|
@ -32,6 +32,7 @@ struct static_nh_label {
|
||||
typedef enum {
|
||||
STATIC_IFINDEX,
|
||||
STATIC_IPV4_GATEWAY,
|
||||
STATIC_IPV4_GATEWAY_IFINDEX,
|
||||
STATIC_BLACKHOLE,
|
||||
STATIC_IPV6_GATEWAY,
|
||||
STATIC_IPV6_GATEWAY_IFINDEX,
|
||||
@ -57,11 +58,6 @@ struct static_route {
|
||||
|
||||
/*
|
||||
* Nexthop value.
|
||||
*
|
||||
* Under IPv4 addr and ifindex are
|
||||
* used independentyly.
|
||||
* STATIC_IPV4_GATEWAY uses addr
|
||||
* STATIC_IFINDEX uses ifindex
|
||||
*/
|
||||
union g_addr addr;
|
||||
ifindex_t ifindex;
|
||||
|
@ -201,8 +201,7 @@ static int zebra_static_ipv4(struct vty *vty, safi_t safi, int add_cmd,
|
||||
if (gate_str == NULL && ifname == NULL)
|
||||
type = STATIC_BLACKHOLE;
|
||||
else if (gate_str && ifname)
|
||||
/* TODO: not implemented yet */
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
type = STATIC_IPV4_GATEWAY_IFINDEX;
|
||||
else if (ifname)
|
||||
type = STATIC_IFINDEX;
|
||||
else
|
||||
@ -457,6 +456,34 @@ DEFUN (ip_route_flags,
|
||||
NULL, argv[idx_reject_blackhole]->arg, tag, distance, vrf, NULL);
|
||||
}
|
||||
|
||||
DEFUN (ip_route_ifname,
|
||||
ip_route_ifname_cmd,
|
||||
"ip route A.B.C.D/M A.B.C.D INTERFACE [{tag (1-4294967295)|(1-255)|vrf NAME|label WORD}]",
|
||||
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"
|
||||
"Set tag for this route\n"
|
||||
"Tag value\n"
|
||||
"Distance value for this route\n"
|
||||
VRF_CMD_HELP_STR
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv4_prefixlen = 2;
|
||||
int idx_curr = 5;
|
||||
char *gate = argv[3]->arg;
|
||||
char *ifname = argv[4]->arg;
|
||||
char *tag, *distance, *vrf, *label;
|
||||
|
||||
zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance,
|
||||
&vrf, &label);
|
||||
|
||||
return zebra_static_ipv4(vty, SAFI_UNICAST, 1,
|
||||
argv[idx_ipv4_prefixlen]->arg, NULL, gate,
|
||||
ifname, NULL, tag, distance, vrf, label);
|
||||
}
|
||||
|
||||
/* Mask as A.B.C.D format. */
|
||||
DEFUN_HIDDEN (ip_route_mask,
|
||||
ip_route_mask_cmd,
|
||||
@ -494,6 +521,36 @@ DEFUN_HIDDEN (ip_route_mask,
|
||||
gate, ifname, NULL, tag, distance, vrf, label);
|
||||
}
|
||||
|
||||
DEFUN_HIDDEN (ip_route_mask_ifname,
|
||||
ip_route_mask_ifname_cmd,
|
||||
"ip route A.B.C.D A.B.C.D A.B.C.D INTERFACE [{tag (1-4294967295)|(1-255)|vrf NAME|label WORD}]",
|
||||
IP_STR
|
||||
"Establish static routes\n"
|
||||
"IP destination prefix\n"
|
||||
"IP destination prefix mask\n"
|
||||
"IP gateway address\n"
|
||||
"IP gateway interface name\n"
|
||||
"Set tag for this route\n"
|
||||
"Tag value\n"
|
||||
"Distance value for this route\n"
|
||||
VRF_CMD_HELP_STR
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv4 = 2;
|
||||
int idx_ipv4_2 = 3;
|
||||
int idx_curr = 6;
|
||||
char *gate = argv[4]->arg;
|
||||
char *ifname = argv[5]->arg;
|
||||
char *tag, *distance, *vrf, *label;
|
||||
|
||||
zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance,
|
||||
&vrf, &label);
|
||||
|
||||
return zebra_static_ipv4(vty, SAFI_UNICAST, 1, argv[idx_ipv4]->arg,
|
||||
argv[idx_ipv4_2]->arg,
|
||||
gate, ifname, NULL, tag, distance, vrf, label);
|
||||
}
|
||||
|
||||
DEFUN_HIDDEN (ip_route_mask_flags,
|
||||
ip_route_mask_flags_cmd,
|
||||
"ip route A.B.C.D A.B.C.D <reject|blackhole> [{tag (1-4294967295)|(1-255)|vrf NAME}]",
|
||||
@ -558,6 +615,35 @@ DEFUN (no_ip_route,
|
||||
gate, ifname, NULL, tag, distance, vrf, label);
|
||||
}
|
||||
|
||||
DEFUN (no_ip_route_ifname,
|
||||
no_ip_route_ifname_cmd,
|
||||
"no ip route A.B.C.D/M A.B.C.D INTERFACE [{tag (1-4294967295)|(1-255)|vrf NAME|label WORD}]",
|
||||
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"
|
||||
"Tag of this route\n"
|
||||
"Tag value\n"
|
||||
"Distance value for this route\n"
|
||||
VRF_CMD_HELP_STR
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv4_prefixlen = 3;
|
||||
int idx_curr = 6;
|
||||
char *gate = argv[4]->arg;
|
||||
char *ifname = argv[5]->arg;
|
||||
char *tag, *distance, *vrf, *label;
|
||||
|
||||
zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance,
|
||||
&vrf, &label);
|
||||
|
||||
return zebra_static_ipv4(vty, SAFI_UNICAST, 0,
|
||||
argv[idx_ipv4_prefixlen]->arg, NULL,
|
||||
gate, ifname, NULL, tag, distance, vrf, label);
|
||||
}
|
||||
|
||||
DEFUN (no_ip_route_flags,
|
||||
no_ip_route_flags_cmd,
|
||||
"no ip route A.B.C.D/M <reject|blackhole> [{tag (1-4294967295)|(1-255)|vrf NAME}]",
|
||||
@ -621,6 +707,37 @@ DEFUN_HIDDEN (no_ip_route_mask,
|
||||
gate, ifname, NULL, tag, distance, vrf, label);
|
||||
}
|
||||
|
||||
DEFUN_HIDDEN (no_ip_route_mask_ifname,
|
||||
no_ip_route_mask_ifname_cmd,
|
||||
"no ip route A.B.C.D A.B.C.D A.B.C.D INTERFACE [{tag (1-4294967295)|(1-255)|vrf NAME|label WORD}]",
|
||||
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"
|
||||
"Tag of this route\n"
|
||||
"Tag value\n"
|
||||
"Distance value for this route\n"
|
||||
VRF_CMD_HELP_STR
|
||||
MPLS_LABEL_HELPSTR)
|
||||
{
|
||||
int idx_ipv4 = 3;
|
||||
int idx_ipv4_2 = 4;
|
||||
int idx_curr = 7;
|
||||
char *gate = argv[5]->arg;
|
||||
char *ifname = argv[6]->arg;
|
||||
char *tag, *distance, *vrf, *label;
|
||||
|
||||
zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance,
|
||||
&vrf, &label);
|
||||
|
||||
return zebra_static_ipv4(vty, SAFI_UNICAST, 0, argv[idx_ipv4]->arg,
|
||||
argv[idx_ipv4_2]->arg,
|
||||
gate, ifname, NULL, tag, distance, vrf, label);
|
||||
}
|
||||
|
||||
DEFUN_HIDDEN (no_ip_route_mask_flags,
|
||||
no_ip_route_mask_flags_cmd,
|
||||
"no ip route A.B.C.D A.B.C.D <reject|blackhole> [{tag (1-4294967295)|(1-255)|vrf NAME}]",
|
||||
@ -1970,6 +2087,14 @@ static int static_config(struct vty *vty, afi_t afi, safi_t safi,
|
||||
else
|
||||
vty_out(vty, " Null0");
|
||||
break;
|
||||
case STATIC_IPV4_GATEWAY_IFINDEX:
|
||||
vty_out(vty, " %s %s",
|
||||
inet_ntop(AF_INET,
|
||||
&si->addr.ipv4, buf,
|
||||
sizeof buf),
|
||||
ifindex2ifname(si->ifindex,
|
||||
si->vrf_id));
|
||||
break;
|
||||
case STATIC_IPV6_GATEWAY_IFINDEX:
|
||||
vty_out(vty, " %s %s",
|
||||
inet_ntop(AF_INET6,
|
||||
@ -3288,11 +3413,17 @@ void zebra_vty_init(void)
|
||||
install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
|
||||
install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
|
||||
install_element(CONFIG_NODE, &ip_route_cmd);
|
||||
install_element(CONFIG_NODE, &ip_route_ifname_cmd);
|
||||
install_element(CONFIG_NODE, &ip_route_flags_cmd);
|
||||
install_element(CONFIG_NODE, &ip_route_mask_cmd);
|
||||
install_element(CONFIG_NODE, &ip_route_mask_ifname_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_ifname_cmd);
|
||||
install_element(CONFIG_NODE, &no_ip_route_mask_cmd);
|
||||
install_element(CONFIG_NODE, &no_ip_route_mask_flags_cmd);
|
||||
install_element(CONFIG_NODE, &no_ip_route_mask_ifname_cmd);
|
||||
install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
|
||||
install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
|
||||
|
||||
@ -3310,11 +3441,6 @@ void zebra_vty_init(void)
|
||||
install_element(VIEW_NODE, &show_ip_rpf_cmd);
|
||||
install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
|
||||
|
||||
/* Commands for VRF */
|
||||
|
||||
install_element(CONFIG_NODE, &no_ip_route_flags_cmd);
|
||||
install_element(CONFIG_NODE, &no_ip_route_mask_flags_cmd);
|
||||
|
||||
install_element(VIEW_NODE, &show_ip_route_vrf_all_addr_cmd);
|
||||
install_element(VIEW_NODE, &show_ip_route_vrf_all_prefix_cmd);
|
||||
install_element(VIEW_NODE, &show_ip_route_vrf_all_summary_cmd);
|
||||
|
Loading…
Reference in New Issue
Block a user