mirror of https://github.com/OpenIPC/firmware.git
183 lines
5.8 KiB
Diff
183 lines
5.8 KiB
Diff
diff -drupN a/net/ipv6/route.c b/net/ipv6/route.c
|
|
--- a/net/ipv6/route.c 2018-08-06 17:23:04.000000000 +0300
|
|
+++ b/net/ipv6/route.c 2022-06-12 05:28:14.000000000 +0300
|
|
@@ -1417,7 +1417,7 @@ static void ip6_rt_update_pmtu(struct ds
|
|
}
|
|
|
|
void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu,
|
|
- int oif, u32 mark)
|
|
+ int oif, u32 mark, kuid_t uid)
|
|
{
|
|
const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data;
|
|
struct dst_entry *dst;
|
|
@@ -1429,6 +1429,7 @@ void ip6_update_pmtu(struct sk_buff *skb
|
|
fl6.daddr = iph->daddr;
|
|
fl6.saddr = iph->saddr;
|
|
fl6.flowlabel = ip6_flowinfo(iph);
|
|
+ fl6.flowi6_uid = uid;
|
|
|
|
dst = ip6_route_output(net, NULL, &fl6);
|
|
if (!dst->error)
|
|
@@ -1442,7 +1443,7 @@ void ip6_sk_update_pmtu(struct sk_buff *
|
|
struct dst_entry *dst;
|
|
|
|
ip6_update_pmtu(skb, sock_net(sk), mtu,
|
|
- sk->sk_bound_dev_if, sk->sk_mark);
|
|
+ sk->sk_bound_dev_if, sk->sk_mark, sk->sk_uid);
|
|
|
|
dst = __sk_dst_get(sk);
|
|
if (!dst || !dst->obsolete ||
|
|
@@ -1534,7 +1535,8 @@ static struct dst_entry *ip6_route_redir
|
|
flags, __ip6_route_redirect);
|
|
}
|
|
|
|
-void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark)
|
|
+void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark,
|
|
+ kuid_t uid)
|
|
{
|
|
const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data;
|
|
struct dst_entry *dst;
|
|
@@ -1547,6 +1549,7 @@ void ip6_redirect(struct sk_buff *skb, s
|
|
fl6.daddr = iph->daddr;
|
|
fl6.saddr = iph->saddr;
|
|
fl6.flowlabel = ip6_flowinfo(iph);
|
|
+ fl6.flowi6_uid = uid;
|
|
|
|
dst = ip6_route_redirect(net, &fl6, &ipv6_hdr(skb)->saddr);
|
|
rt6_do_redirect(dst, NULL, skb);
|
|
@@ -1568,6 +1571,7 @@ void ip6_redirect_no_header(struct sk_bu
|
|
fl6.flowi6_mark = mark;
|
|
fl6.daddr = msg->dest;
|
|
fl6.saddr = iph->daddr;
|
|
+ fl6.flowi6_uid = sock_net_uid(net, NULL);
|
|
|
|
dst = ip6_route_redirect(net, &fl6, &iph->saddr);
|
|
rt6_do_redirect(dst, NULL, skb);
|
|
@@ -1576,7 +1580,8 @@ void ip6_redirect_no_header(struct sk_bu
|
|
|
|
void ip6_sk_redirect(struct sk_buff *skb, struct sock *sk)
|
|
{
|
|
- ip6_redirect(skb, sock_net(sk), sk->sk_bound_dev_if, sk->sk_mark);
|
|
+ ip6_redirect(skb, sock_net(sk), sk->sk_bound_dev_if, sk->sk_mark,
|
|
+ sk->sk_uid);
|
|
}
|
|
EXPORT_SYMBOL_GPL(ip6_sk_redirect);
|
|
|
|
@@ -2351,8 +2356,7 @@ static struct rt6_info *rt6_get_route_in
|
|
const struct in6_addr *gwaddr,
|
|
struct net_device *dev)
|
|
{
|
|
- u32 tb_id = l3mdev_fib_table(dev) ? : RT6_TABLE_INFO;
|
|
- int ifindex = dev->ifindex;
|
|
+ u32 tb_id = l3mdev_fib_table(dev) ? : addrconf_rt_table(dev, RT6_TABLE_INFO);
|
|
struct fib6_node *fn;
|
|
struct rt6_info *rt = NULL;
|
|
struct fib6_table *table;
|
|
@@ -2367,7 +2371,7 @@ static struct rt6_info *rt6_get_route_in
|
|
goto out;
|
|
|
|
for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
|
|
- if (rt->dst.dev->ifindex != ifindex)
|
|
+ if (rt->dst.dev->ifindex != dev->ifindex)
|
|
continue;
|
|
if ((rt->rt6i_flags & (RTF_ROUTEINFO|RTF_GATEWAY)) != (RTF_ROUTEINFO|RTF_GATEWAY))
|
|
continue;
|
|
@@ -2398,7 +2402,7 @@ static struct rt6_info *rt6_add_route_in
|
|
.fc_nlinfo.nl_net = net,
|
|
};
|
|
|
|
- cfg.fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_INFO,
|
|
+ cfg.fc_table = l3mdev_fib_table(dev) ? : addrconf_rt_table(dev, RT6_TABLE_INFO),
|
|
cfg.fc_dst = *prefix;
|
|
cfg.fc_gateway = *gwaddr;
|
|
|
|
@@ -2414,7 +2418,7 @@ static struct rt6_info *rt6_add_route_in
|
|
|
|
struct rt6_info *rt6_get_dflt_router(const struct in6_addr *addr, struct net_device *dev)
|
|
{
|
|
- u32 tb_id = l3mdev_fib_table(dev) ? : RT6_TABLE_DFLT;
|
|
+ u32 tb_id = l3mdev_fib_table(dev) ? : addrconf_rt_table(dev, RT6_TABLE_MAIN);
|
|
struct rt6_info *rt;
|
|
struct fib6_table *table;
|
|
|
|
@@ -2440,7 +2444,7 @@ struct rt6_info *rt6_add_dflt_router(con
|
|
unsigned int pref)
|
|
{
|
|
struct fib6_config cfg = {
|
|
- .fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_DFLT,
|
|
+ .fc_table = l3mdev_fib_table(dev) ? : addrconf_rt_table(dev, RT6_TABLE_DFLT),
|
|
.fc_metric = IP6_RT_PRIO_USER,
|
|
.fc_ifindex = dev->ifindex,
|
|
.fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT |
|
|
@@ -2463,43 +2467,16 @@ struct rt6_info *rt6_add_dflt_router(con
|
|
return rt6_get_dflt_router(gwaddr, dev);
|
|
}
|
|
|
|
-static void __rt6_purge_dflt_routers(struct fib6_table *table)
|
|
-{
|
|
- struct rt6_info *rt;
|
|
-
|
|
-restart:
|
|
- read_lock_bh(&table->tb6_lock);
|
|
- for (rt = table->tb6_root.leaf; rt; rt = rt->dst.rt6_next) {
|
|
- if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF) &&
|
|
- (!rt->rt6i_idev || rt->rt6i_idev->cnf.accept_ra != 2)) {
|
|
- dst_hold(&rt->dst);
|
|
- read_unlock_bh(&table->tb6_lock);
|
|
- ip6_del_rt(rt);
|
|
- goto restart;
|
|
- }
|
|
- }
|
|
- read_unlock_bh(&table->tb6_lock);
|
|
-
|
|
- table->flags &= ~RT6_TABLE_HAS_DFLT_ROUTER;
|
|
+int rt6_addrconf_purge(struct rt6_info *rt, void *arg) {
|
|
+ if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF) &&
|
|
+ (!rt->rt6i_idev || rt->rt6i_idev->cnf.accept_ra != 2))
|
|
+ return -1;
|
|
+ return 0;
|
|
}
|
|
|
|
void rt6_purge_dflt_routers(struct net *net)
|
|
{
|
|
- struct fib6_table *table;
|
|
- struct hlist_head *head;
|
|
- unsigned int h;
|
|
-
|
|
- rcu_read_lock();
|
|
-
|
|
- for (h = 0; h < FIB6_TABLE_HASHSZ; h++) {
|
|
- head = &net->ipv6.fib_table_hash[h];
|
|
- hlist_for_each_entry_rcu(table, head, tb6_hlist) {
|
|
- if (table->flags & RT6_TABLE_HAS_DFLT_ROUTER)
|
|
- __rt6_purge_dflt_routers(table);
|
|
- }
|
|
- }
|
|
-
|
|
- rcu_read_unlock();
|
|
+ fib6_clean_all(net, rt6_addrconf_purge, NULL);
|
|
}
|
|
|
|
static void rtmsg_to_fib6_config(struct net *net,
|
|
@@ -2818,6 +2795,7 @@ static const struct nla_policy rtm_ipv6_
|
|
[RTA_ENCAP_TYPE] = { .type = NLA_U16 },
|
|
[RTA_ENCAP] = { .type = NLA_NESTED },
|
|
[RTA_EXPIRES] = { .type = NLA_U32 },
|
|
+ [RTA_UID] = { .type = NLA_U32 },
|
|
[RTA_TABLE] = { .type = NLA_U32 },
|
|
};
|
|
|
|
@@ -3398,6 +3376,12 @@ static int inet6_rtm_getroute(struct sk_
|
|
if (tb[RTA_MARK])
|
|
fl6.flowi6_mark = nla_get_u32(tb[RTA_MARK]);
|
|
|
|
+ if (tb[RTA_UID])
|
|
+ fl6.flowi6_uid = make_kuid(current_user_ns(),
|
|
+ nla_get_u32(tb[RTA_UID]));
|
|
+ else
|
|
+ fl6.flowi6_uid = iif ? INVALID_UID : current_uid();
|
|
+
|
|
if (iif) {
|
|
struct net_device *dev;
|
|
int flags = 0;
|