net: inet: Support UID-based routing in IP protocols.
[GitHub/LineageOS/android_kernel_samsung_universal7580.git] / net / ipv4 / route.c
index c564dcf2c80cbe823af74d0b593ee6dd0c63029d..292c08985b0f5e055e5ebec6a0327b7419f7a818 100644 (file)
@@ -515,7 +515,8 @@ void __ip_select_ident(struct iphdr *iph, int segs)
 }
 EXPORT_SYMBOL(__ip_select_ident);
 
-static void __build_flow_key(struct flowi4 *fl4, const struct sock *sk,
+static void __build_flow_key(const struct net *net, struct flowi4 *fl4,
+                            const struct sock *sk,
                             const struct iphdr *iph,
                             int oif, u8 tos,
                             u8 prot, u32 mark, int flow_flags)
@@ -531,7 +532,8 @@ static void __build_flow_key(struct flowi4 *fl4, const struct sock *sk,
        flowi4_init_output(fl4, oif, mark, tos,
                           RT_SCOPE_UNIVERSE, prot,
                           flow_flags,
-                          iph->daddr, iph->saddr, 0, 0);
+                          iph->daddr, iph->saddr, 0, 0,
+                          sock_net_uid(net, sk));
 }
 
 static void build_skb_flow_key(struct flowi4 *fl4, const struct sk_buff *skb,
@@ -543,7 +545,7 @@ static void build_skb_flow_key(struct flowi4 *fl4, const struct sk_buff *skb,
        u8 prot = iph->protocol;
        u32 mark = skb->mark;
 
-       __build_flow_key(fl4, sk, iph, oif, tos, prot, mark, 0);
+       __build_flow_key(sock_net(sk), fl4, sk, iph, oif, tos, prot, mark, 0);
 }
 
 static void build_sk_flow_key(struct flowi4 *fl4, const struct sock *sk)
@@ -560,7 +562,7 @@ static void build_sk_flow_key(struct flowi4 *fl4, const struct sock *sk)
                           RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,
                           inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,
                           inet_sk_flowi_flags(sk),
-                          daddr, inet->inet_saddr, 0, 0);
+                          daddr, inet->inet_saddr, 0, 0, sk->sk_uid);
        rcu_read_unlock();
 }
 
@@ -762,7 +764,7 @@ static void ip_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buf
 
        rt = (struct rtable *) dst;
 
-       __build_flow_key(&fl4, sk, iph, oif, tos, prot, mark, 0);
+       __build_flow_key(sock_net(sk), &fl4, sk, iph, oif, tos, prot, mark, 0);
        __ip_do_redirect(rt, skb, &fl4, true);
 }
 
@@ -980,7 +982,7 @@ void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu,
        if (!mark)
                mark = IP4_REPLY_MARK(net, skb->mark);
 
-       __build_flow_key(&fl4, NULL, iph, oif,
+       __build_flow_key(net, &fl4, NULL, iph, oif,
                         RT_TOS(iph->tos), protocol, mark, flow_flags);
        rt = __ip_route_output_key(net, &fl4);
        if (!IS_ERR(rt)) {
@@ -996,7 +998,7 @@ static void __ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
        struct flowi4 fl4;
        struct rtable *rt;
 
-       __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0);
+       __build_flow_key(sock_net(sk), &fl4, sk, iph, 0, 0, 0, 0, 0);
 
        if (!fl4.flowi4_mark)
                fl4.flowi4_mark = IP4_REPLY_MARK(sock_net(sk), skb->mark);
@@ -1015,6 +1017,7 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
        struct rtable *rt;
        struct dst_entry *odst = NULL;
        bool new = false;
+       struct net *net = sock_net(sk);
 
        bh_lock_sock(sk);
        odst = sk_dst_get(sk);
@@ -1024,7 +1027,7 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
                goto out;
        }
 
-       __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0);
+       __build_flow_key(net, &fl4, sk, iph, 0, 0, 0, 0, 0);
 
        rt = (struct rtable *)odst;
        if (odst->obsolete && odst->ops->check(odst, 0) == NULL) {
@@ -1064,7 +1067,7 @@ void ipv4_redirect(struct sk_buff *skb, struct net *net,
        struct flowi4 fl4;
        struct rtable *rt;
 
-       __build_flow_key(&fl4, NULL, iph, oif,
+       __build_flow_key(net, &fl4, NULL, iph, oif,
                         RT_TOS(iph->tos), protocol, mark, flow_flags);
        rt = __ip_route_output_key(net, &fl4);
        if (!IS_ERR(rt)) {
@@ -1079,9 +1082,10 @@ void ipv4_sk_redirect(struct sk_buff *skb, struct sock *sk)
        const struct iphdr *iph = (const struct iphdr *) skb->data;
        struct flowi4 fl4;
        struct rtable *rt;
+       struct net *net = sock_net(sk);
 
-       __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0);
-       rt = __ip_route_output_key(sock_net(sk), &fl4);
+       __build_flow_key(net, &fl4, sk, iph, 0, 0, 0, 0, 0);
+       rt = __ip_route_output_key(net, &fl4);
        if (!IS_ERR(rt)) {
                __ip_do_redirect(rt, skb, &fl4, false);
                ip_rt_put(rt);