arm64: configs: add some devfreq gov for rk3399 linux
[firefly-linux-kernel-4.4.55.git] / net / netfilter / xt_socket.c
index 2ec08f04b816bc863e582fed000a2143d0b688a5..8a2a489b2cd39ad420bfcc6ba2e82e3a9bbcd4c2 100644 (file)
@@ -143,11 +143,12 @@ static bool xt_socket_sk_is_transparent(struct sock *sk)
        }
 }
 
-static struct sock *xt_socket_lookup_slow_v4(struct net *net,
+struct sock *xt_socket_lookup_slow_v4(struct net *net,
                                             const struct sk_buff *skb,
                                             const struct net_device *indev)
 {
        const struct iphdr *iph = ip_hdr(skb);
+       struct sock *sk = skb->sk;
        __be32 uninitialized_var(daddr), uninitialized_var(saddr);
        __be16 uninitialized_var(dport), uninitialized_var(sport);
        u8 uninitialized_var(protocol);
@@ -198,9 +199,16 @@ static struct sock *xt_socket_lookup_slow_v4(struct net *net,
        }
 #endif
 
-       return xt_socket_get_sock_v4(net, protocol, saddr, daddr,
-                                    sport, dport, indev);
+       if (sk)
+               atomic_inc(&sk->sk_refcnt);
+       else
+               sk = xt_socket_get_sock_v4(dev_net(skb->dev), protocol,
+                                          saddr, daddr, sport, dport,
+                                          indev);
+
+       return sk;
 }
+EXPORT_SYMBOL(xt_socket_lookup_slow_v4);
 
 static bool
 socket_match(const struct sk_buff *skb, struct xt_action_param *par,
@@ -232,8 +240,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
                    transparent)
                        pskb->mark = sk->sk_mark;
 
-               if (sk != skb->sk)
-                       sock_gen_put(sk);
+               sock_gen_put(sk);
 
                if (wildcard || !transparent)
                        sk = NULL;
@@ -336,10 +343,11 @@ xt_socket_get_sock_v6(struct net *net, const u8 protocol,
        return NULL;
 }
 
-static struct sock *xt_socket_lookup_slow_v6(struct net *net,
+struct sock *xt_socket_lookup_slow_v6(struct net *net,
                                             const struct sk_buff *skb,
                                             const struct net_device *indev)
 {
+       struct sock *sk = skb->sk;
        __be16 uninitialized_var(dport), uninitialized_var(sport);
        const struct in6_addr *daddr = NULL, *saddr = NULL;
        struct ipv6hdr *iph = ipv6_hdr(skb);
@@ -373,9 +381,16 @@ static struct sock *xt_socket_lookup_slow_v6(struct net *net,
                return NULL;
        }
 
-       return xt_socket_get_sock_v6(net, tproto, saddr, daddr,
-                                    sport, dport, indev);
+       if (sk)
+               atomic_inc(&sk->sk_refcnt);
+       else
+               sk = xt_socket_get_sock_v6(dev_net(skb->dev), tproto,
+                                          saddr, daddr, sport, dport,
+                                          indev);
+
+       return sk;
 }
+EXPORT_SYMBOL(xt_socket_lookup_slow_v6);
 
 static bool
 socket_mt6_v1_v2_v3(const struct sk_buff *skb, struct xt_action_param *par)