|
@@ -345,9 +345,6 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
|
|
if (res.type != RTN_UNICAST &&
|
|
if (res.type != RTN_UNICAST &&
|
|
(res.type != RTN_LOCAL || !IN_DEV_ACCEPT_LOCAL(idev)))
|
|
(res.type != RTN_LOCAL || !IN_DEV_ACCEPT_LOCAL(idev)))
|
|
goto e_inval;
|
|
goto e_inval;
|
|
- if (!rpf && !fib_num_tclassid_users(net) &&
|
|
|
|
- (dev->ifindex != oif || !IN_DEV_TX_REDIRECTS(idev)))
|
|
|
|
- goto last_resort;
|
|
|
|
fib_combine_itag(itag, &res);
|
|
fib_combine_itag(itag, &res);
|
|
dev_match = false;
|
|
dev_match = false;
|
|
|
|
|
|
@@ -402,13 +399,26 @@ int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
|
|
struct in_device *idev, u32 *itag)
|
|
struct in_device *idev, u32 *itag)
|
|
{
|
|
{
|
|
int r = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(idev);
|
|
int r = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(idev);
|
|
|
|
+ struct net *net = dev_net(dev);
|
|
|
|
|
|
- if (!r && !fib_num_tclassid_users(dev_net(dev)) &&
|
|
|
|
- IN_DEV_ACCEPT_LOCAL(idev) &&
|
|
|
|
|
|
+ if (!r && !fib_num_tclassid_users(net) &&
|
|
(dev->ifindex != oif || !IN_DEV_TX_REDIRECTS(idev))) {
|
|
(dev->ifindex != oif || !IN_DEV_TX_REDIRECTS(idev))) {
|
|
|
|
+ if (IN_DEV_ACCEPT_LOCAL(idev))
|
|
|
|
+ goto ok;
|
|
|
|
+ /* if no local routes are added from user space we can check
|
|
|
|
+ * for local addresses looking-up the ifaddr table
|
|
|
|
+ */
|
|
|
|
+ if (net->ipv4.fib_has_custom_local_routes)
|
|
|
|
+ goto full_check;
|
|
|
|
+ if (inet_lookup_ifaddr_rcu(net, src))
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
|
|
+ok:
|
|
*itag = 0;
|
|
*itag = 0;
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+full_check:
|
|
return __fib_validate_source(skb, src, dst, tos, oif, dev, r, idev, itag);
|
|
return __fib_validate_source(skb, src, dst, tos, oif, dev, r, idev, itag);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -759,6 +769,8 @@ static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|
}
|
|
}
|
|
|
|
|
|
err = fib_table_insert(net, tb, &cfg, extack);
|
|
err = fib_table_insert(net, tb, &cfg, extack);
|
|
|
|
+ if (!err && cfg.fc_type == RTN_LOCAL)
|
|
|
|
+ net->ipv4.fib_has_custom_local_routes = true;
|
|
errout:
|
|
errout:
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|