gtp: switch from struct socket to struct sock for the GTP sockets
authorAndreas Schultz <aschultz@tpip.net>
Thu, 9 Mar 2017 16:42:56 +0000 (17:42 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 13 Mar 2017 20:04:30 +0000 (13:04 -0700)
After enabling the UDP encapsulation, only the sk member is used.

Holding the socket would prevent user space from closing the socket,
but holding a reference to the sk member does not have the same
effect.

This change will make it simpler to later detach the sockets from
the netdevice.

Signed-off-by: Andreas Schultz <aschultz@tpip.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/gtp.c

index 89698741682f41e2ea70868715ffcb4f4784e258..e1b5af377fbcda6a875d014ec2692e506e6be7b8 100644 (file)
@@ -66,8 +66,8 @@ struct pdp_ctx {
 struct gtp_dev {
        struct list_head        list;
 
-       struct socket           *sock0;
-       struct socket           *sock1u;
+       struct sock             *sk0;
+       struct sock             *sk1u;
 
        struct net_device       *dev;
 
@@ -261,17 +261,19 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb,
 
 static void gtp_encap_disable(struct gtp_dev *gtp)
 {
-       if (gtp->sock0 && gtp->sock0->sk) {
-               udp_sk(gtp->sock0->sk)->encap_type = 0;
-               rcu_assign_sk_user_data(gtp->sock0->sk, NULL);
+       if (gtp->sk0) {
+               udp_sk(gtp->sk0)->encap_type = 0;
+               rcu_assign_sk_user_data(gtp->sk0, NULL);
+               sock_put(gtp->sk0);
        }
-       if (gtp->sock1u && gtp->sock1u->sk) {
-               udp_sk(gtp->sock1u->sk)->encap_type = 0;
-               rcu_assign_sk_user_data(gtp->sock1u->sk, NULL);
+       if (gtp->sk1u) {
+               udp_sk(gtp->sk1u)->encap_type = 0;
+               rcu_assign_sk_user_data(gtp->sk1u, NULL);
+               sock_put(gtp->sk1u);
        }
 
-       gtp->sock0 = NULL;
-       gtp->sock1u = NULL;
+       gtp->sk0 = NULL;
+       gtp->sk1u = NULL;
 }
 
 static void gtp_encap_destroy(struct sock *sk)
@@ -484,14 +486,14 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev,
 
        switch (pctx->gtp_version) {
        case GTP_V0:
-               if (gtp->sock0)
-                       sk = gtp->sock0->sk;
+               if (gtp->sk0)
+                       sk = gtp->sk0;
                else
                        sk = NULL;
                break;
        case GTP_V1:
-               if (gtp->sock1u)
-                       sk = gtp->sock1u->sk;
+               if (gtp->sk1u)
+                       sk = gtp->sk1u;
                else
                        sk = NULL;
                break;
@@ -504,7 +506,7 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev,
                return -ENOENT;
        }
 
-       rt = ip4_route_output_gtp(sock_net(sk), &fl4, gtp->sock0->sk,
+       rt = ip4_route_output_gtp(sock_net(sk), &fl4, gtp->sk0,
                                  pctx->sgsn_addr_ip4.s_addr);
        if (IS_ERR(rt)) {
                netdev_dbg(dev, "no route to SSGN %pI4\n",
@@ -839,18 +841,20 @@ static int gtp_encap_enable(struct net_device *dev, struct gtp_dev *gtp,
 
        netdev_dbg(dev, "enable gtp on %p, %p\n", sock0, sock1u);
 
-       gtp->sock0 = sock0;
-       gtp->sock1u = sock1u;
+       sock_hold(sock0->sk);
+       gtp->sk0 = sock0->sk;
+       sock_hold(sock1u->sk);
+       gtp->sk1u = sock1u->sk;
 
        tuncfg.sk_user_data = gtp;
        tuncfg.encap_rcv = gtp_encap_recv;
        tuncfg.encap_destroy = gtp_encap_destroy;
 
        tuncfg.encap_type = UDP_ENCAP_GTP0;
-       setup_udp_tunnel_sock(sock_net(gtp->sock0->sk), gtp->sock0, &tuncfg);
+       setup_udp_tunnel_sock(sock_net(gtp->sk0), sock0, &tuncfg);
 
        tuncfg.encap_type = UDP_ENCAP_GTP1U;
-       setup_udp_tunnel_sock(sock_net(gtp->sock1u->sk), gtp->sock1u, &tuncfg);
+       setup_udp_tunnel_sock(sock_net(gtp->sk1u), sock1u, &tuncfg);
 
        err = 0;
 err2: