net/ipv6: Refactor gateway validation on route add
Move gateway validation code from ip6_route_info_create into ip6_validate_gw. Code move plus adjustments to handle the potential reset of dev and idev and to make checkpatch happy. Signed-off-by: David Ahern <dsahern@gmail.com> Reviewed-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1ad2ff028f
commit
9fbb704c33
120
net/ipv6/route.c
120
net/ipv6/route.c
@ -2550,7 +2550,7 @@ static struct rt6_info *ip6_nh_lookup_table(struct net *net,
|
|||||||
|
|
||||||
static int ip6_route_check_nh_onlink(struct net *net,
|
static int ip6_route_check_nh_onlink(struct net *net,
|
||||||
struct fib6_config *cfg,
|
struct fib6_config *cfg,
|
||||||
struct net_device *dev,
|
const struct net_device *dev,
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
u32 tbid = l3mdev_fib_table(dev) ? : RT_TABLE_MAIN;
|
u32 tbid = l3mdev_fib_table(dev) ? : RT_TABLE_MAIN;
|
||||||
@ -2626,6 +2626,68 @@ out:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ip6_validate_gw(struct net *net, struct fib6_config *cfg,
|
||||||
|
struct net_device **_dev, struct inet6_dev **idev,
|
||||||
|
struct netlink_ext_ack *extack)
|
||||||
|
{
|
||||||
|
const struct in6_addr *gw_addr = &cfg->fc_gateway;
|
||||||
|
int gwa_type = ipv6_addr_type(gw_addr);
|
||||||
|
const struct net_device *dev = *_dev;
|
||||||
|
int err = -EINVAL;
|
||||||
|
|
||||||
|
/* if gw_addr is local we will fail to detect this in case
|
||||||
|
* address is still TENTATIVE (DAD in progress). rt6_lookup()
|
||||||
|
* will return already-added prefix route via interface that
|
||||||
|
* prefix route was assigned to, which might be non-loopback.
|
||||||
|
*/
|
||||||
|
if (ipv6_chk_addr_and_flags(net, gw_addr,
|
||||||
|
gwa_type & IPV6_ADDR_LINKLOCAL ?
|
||||||
|
dev : NULL, 0, 0)) {
|
||||||
|
NL_SET_ERR_MSG(extack, "Invalid gateway address");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gwa_type != (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_UNICAST)) {
|
||||||
|
/* IPv6 strictly inhibits using not link-local
|
||||||
|
* addresses as nexthop address.
|
||||||
|
* Otherwise, router will not able to send redirects.
|
||||||
|
* It is very good, but in some (rare!) circumstances
|
||||||
|
* (SIT, PtP, NBMA NOARP links) it is handy to allow
|
||||||
|
* some exceptions. --ANK
|
||||||
|
* We allow IPv4-mapped nexthops to support RFC4798-type
|
||||||
|
* addressing
|
||||||
|
*/
|
||||||
|
if (!(gwa_type & (IPV6_ADDR_UNICAST | IPV6_ADDR_MAPPED))) {
|
||||||
|
NL_SET_ERR_MSG(extack, "Invalid gateway address");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg->fc_flags & RTNH_F_ONLINK)
|
||||||
|
err = ip6_route_check_nh_onlink(net, cfg, dev, extack);
|
||||||
|
else
|
||||||
|
err = ip6_route_check_nh(net, cfg, _dev, idev);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reload in case device was changed */
|
||||||
|
dev = *_dev;
|
||||||
|
|
||||||
|
err = -EINVAL;
|
||||||
|
if (!dev) {
|
||||||
|
NL_SET_ERR_MSG(extack, "Egress device not specified");
|
||||||
|
goto out;
|
||||||
|
} else if (dev->flags & IFF_LOOPBACK) {
|
||||||
|
NL_SET_ERR_MSG(extack,
|
||||||
|
"Egress device can not be loopback device for this route");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
err = 0;
|
||||||
|
out:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
|
static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
@ -2808,61 +2870,11 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cfg->fc_flags & RTF_GATEWAY) {
|
if (cfg->fc_flags & RTF_GATEWAY) {
|
||||||
const struct in6_addr *gw_addr;
|
err = ip6_validate_gw(net, cfg, &dev, &idev, extack);
|
||||||
int gwa_type;
|
if (err)
|
||||||
|
|
||||||
gw_addr = &cfg->fc_gateway;
|
|
||||||
gwa_type = ipv6_addr_type(gw_addr);
|
|
||||||
|
|
||||||
/* if gw_addr is local we will fail to detect this in case
|
|
||||||
* address is still TENTATIVE (DAD in progress). rt6_lookup()
|
|
||||||
* will return already-added prefix route via interface that
|
|
||||||
* prefix route was assigned to, which might be non-loopback.
|
|
||||||
*/
|
|
||||||
err = -EINVAL;
|
|
||||||
if (ipv6_chk_addr_and_flags(net, gw_addr,
|
|
||||||
gwa_type & IPV6_ADDR_LINKLOCAL ?
|
|
||||||
dev : NULL, 0, 0)) {
|
|
||||||
NL_SET_ERR_MSG(extack, "Invalid gateway address");
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
rt->rt6i_gateway = *gw_addr;
|
|
||||||
|
|
||||||
if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) {
|
rt->rt6i_gateway = cfg->fc_gateway;
|
||||||
/* IPv6 strictly inhibits using not link-local
|
|
||||||
addresses as nexthop address.
|
|
||||||
Otherwise, router will not able to send redirects.
|
|
||||||
It is very good, but in some (rare!) circumstances
|
|
||||||
(SIT, PtP, NBMA NOARP links) it is handy to allow
|
|
||||||
some exceptions. --ANK
|
|
||||||
We allow IPv4-mapped nexthops to support RFC4798-type
|
|
||||||
addressing
|
|
||||||
*/
|
|
||||||
if (!(gwa_type & (IPV6_ADDR_UNICAST |
|
|
||||||
IPV6_ADDR_MAPPED))) {
|
|
||||||
NL_SET_ERR_MSG(extack,
|
|
||||||
"Invalid gateway address");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg->fc_flags & RTNH_F_ONLINK) {
|
|
||||||
err = ip6_route_check_nh_onlink(net, cfg, dev,
|
|
||||||
extack);
|
|
||||||
} else {
|
|
||||||
err = ip6_route_check_nh(net, cfg, &dev, &idev);
|
|
||||||
}
|
|
||||||
if (err)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
err = -EINVAL;
|
|
||||||
if (!dev) {
|
|
||||||
NL_SET_ERR_MSG(extack, "Egress device not specified");
|
|
||||||
goto out;
|
|
||||||
} else if (dev->flags & IFF_LOOPBACK) {
|
|
||||||
NL_SET_ERR_MSG(extack,
|
|
||||||
"Egress device can not be loopback device for this route");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
|
Loading…
Reference in New Issue
Block a user