root/net/phonet/pep-gprs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gprs_type_trans
  2. gprs_writeable
  3. gprs_state_change
  4. gprs_recv
  5. gprs_data_ready
  6. gprs_write_space
  7. gprs_open
  8. gprs_close
  9. gprs_xmit
  10. gprs_setup
  11. gprs_attach
  12. gprs_detach

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * File: pep-gprs.c
   4  *
   5  * GPRS over Phonet pipe end point socket
   6  *
   7  * Copyright (C) 2008 Nokia Corporation.
   8  *
   9  * Author: RĂ©mi Denis-Courmont
  10  */
  11 
  12 #include <linux/kernel.h>
  13 #include <linux/netdevice.h>
  14 #include <linux/if_ether.h>
  15 #include <linux/if_arp.h>
  16 #include <net/sock.h>
  17 
  18 #include <linux/if_phonet.h>
  19 #include <net/tcp_states.h>
  20 #include <net/phonet/gprs.h>
  21 
  22 #define GPRS_DEFAULT_MTU 1400
  23 
  24 struct gprs_dev {
  25         struct sock             *sk;
  26         void                    (*old_state_change)(struct sock *);
  27         void                    (*old_data_ready)(struct sock *);
  28         void                    (*old_write_space)(struct sock *);
  29 
  30         struct net_device       *dev;
  31 };
  32 
  33 static __be16 gprs_type_trans(struct sk_buff *skb)
  34 {
  35         const u8 *pvfc;
  36         u8 buf;
  37 
  38         pvfc = skb_header_pointer(skb, 0, 1, &buf);
  39         if (!pvfc)
  40                 return htons(0);
  41         /* Look at IP version field */
  42         switch (*pvfc >> 4) {
  43         case 4:
  44                 return htons(ETH_P_IP);
  45         case 6:
  46                 return htons(ETH_P_IPV6);
  47         }
  48         return htons(0);
  49 }
  50 
  51 static void gprs_writeable(struct gprs_dev *gp)
  52 {
  53         struct net_device *dev = gp->dev;
  54 
  55         if (pep_writeable(gp->sk))
  56                 netif_wake_queue(dev);
  57 }
  58 
  59 /*
  60  * Socket callbacks
  61  */
  62 
  63 static void gprs_state_change(struct sock *sk)
  64 {
  65         struct gprs_dev *gp = sk->sk_user_data;
  66 
  67         if (sk->sk_state == TCP_CLOSE_WAIT) {
  68                 struct net_device *dev = gp->dev;
  69 
  70                 netif_stop_queue(dev);
  71                 netif_carrier_off(dev);
  72         }
  73 }
  74 
  75 static int gprs_recv(struct gprs_dev *gp, struct sk_buff *skb)
  76 {
  77         struct net_device *dev = gp->dev;
  78         int err = 0;
  79         __be16 protocol = gprs_type_trans(skb);
  80 
  81         if (!protocol) {
  82                 err = -EINVAL;
  83                 goto drop;
  84         }
  85 
  86         if (skb_headroom(skb) & 3) {
  87                 struct sk_buff *rskb, *fs;
  88                 int flen = 0;
  89 
  90                 /* Phonet Pipe data header may be misaligned (3 bytes),
  91                  * so wrap the IP packet as a single fragment of an head-less
  92                  * socket buffer. The network stack will pull what it needs,
  93                  * but at least, the whole IP payload is not memcpy'd. */
  94                 rskb = netdev_alloc_skb(dev, 0);
  95                 if (!rskb) {
  96                         err = -ENOBUFS;
  97                         goto drop;
  98                 }
  99                 skb_shinfo(rskb)->frag_list = skb;
 100                 rskb->len += skb->len;
 101                 rskb->data_len += rskb->len;
 102                 rskb->truesize += rskb->len;
 103 
 104                 /* Avoid nested fragments */
 105                 skb_walk_frags(skb, fs)
 106                         flen += fs->len;
 107                 skb->next = skb_shinfo(skb)->frag_list;
 108                 skb_frag_list_init(skb);
 109                 skb->len -= flen;
 110                 skb->data_len -= flen;
 111                 skb->truesize -= flen;
 112 
 113                 skb = rskb;
 114         }
 115 
 116         skb->protocol = protocol;
 117         skb_reset_mac_header(skb);
 118         skb->dev = dev;
 119 
 120         if (likely(dev->flags & IFF_UP)) {
 121                 dev->stats.rx_packets++;
 122                 dev->stats.rx_bytes += skb->len;
 123                 netif_rx(skb);
 124                 skb = NULL;
 125         } else
 126                 err = -ENODEV;
 127 
 128 drop:
 129         if (skb) {
 130                 dev_kfree_skb(skb);
 131                 dev->stats.rx_dropped++;
 132         }
 133         return err;
 134 }
 135 
 136 static void gprs_data_ready(struct sock *sk)
 137 {
 138         struct gprs_dev *gp = sk->sk_user_data;
 139         struct sk_buff *skb;
 140 
 141         while ((skb = pep_read(sk)) != NULL) {
 142                 skb_orphan(skb);
 143                 gprs_recv(gp, skb);
 144         }
 145 }
 146 
 147 static void gprs_write_space(struct sock *sk)
 148 {
 149         struct gprs_dev *gp = sk->sk_user_data;
 150 
 151         if (netif_running(gp->dev))
 152                 gprs_writeable(gp);
 153 }
 154 
 155 /*
 156  * Network device callbacks
 157  */
 158 
 159 static int gprs_open(struct net_device *dev)
 160 {
 161         struct gprs_dev *gp = netdev_priv(dev);
 162 
 163         gprs_writeable(gp);
 164         return 0;
 165 }
 166 
 167 static int gprs_close(struct net_device *dev)
 168 {
 169         netif_stop_queue(dev);
 170         return 0;
 171 }
 172 
 173 static netdev_tx_t gprs_xmit(struct sk_buff *skb, struct net_device *dev)
 174 {
 175         struct gprs_dev *gp = netdev_priv(dev);
 176         struct sock *sk = gp->sk;
 177         int len, err;
 178 
 179         switch (skb->protocol) {
 180         case  htons(ETH_P_IP):
 181         case  htons(ETH_P_IPV6):
 182                 break;
 183         default:
 184                 dev_kfree_skb(skb);
 185                 return NETDEV_TX_OK;
 186         }
 187 
 188         skb_orphan(skb);
 189         skb_set_owner_w(skb, sk);
 190         len = skb->len;
 191         err = pep_write(sk, skb);
 192         if (err) {
 193                 net_dbg_ratelimited("%s: TX error (%d)\n", dev->name, err);
 194                 dev->stats.tx_aborted_errors++;
 195                 dev->stats.tx_errors++;
 196         } else {
 197                 dev->stats.tx_packets++;
 198                 dev->stats.tx_bytes += len;
 199         }
 200 
 201         netif_stop_queue(dev);
 202         if (pep_writeable(sk))
 203                 netif_wake_queue(dev);
 204         return NETDEV_TX_OK;
 205 }
 206 
 207 static const struct net_device_ops gprs_netdev_ops = {
 208         .ndo_open       = gprs_open,
 209         .ndo_stop       = gprs_close,
 210         .ndo_start_xmit = gprs_xmit,
 211 };
 212 
 213 static void gprs_setup(struct net_device *dev)
 214 {
 215         dev->features           = NETIF_F_FRAGLIST;
 216         dev->type               = ARPHRD_PHONET_PIPE;
 217         dev->flags              = IFF_POINTOPOINT | IFF_NOARP;
 218         dev->mtu                = GPRS_DEFAULT_MTU;
 219         dev->min_mtu            = 576;
 220         dev->max_mtu            = (PHONET_MAX_MTU - 11);
 221         dev->hard_header_len    = 0;
 222         dev->addr_len           = 0;
 223         dev->tx_queue_len       = 10;
 224 
 225         dev->netdev_ops         = &gprs_netdev_ops;
 226         dev->needs_free_netdev  = true;
 227 }
 228 
 229 /*
 230  * External interface
 231  */
 232 
 233 /*
 234  * Attach a GPRS interface to a datagram socket.
 235  * Returns the interface index on success, negative error code on error.
 236  */
 237 int gprs_attach(struct sock *sk)
 238 {
 239         static const char ifname[] = "gprs%d";
 240         struct gprs_dev *gp;
 241         struct net_device *dev;
 242         int err;
 243 
 244         if (unlikely(sk->sk_type == SOCK_STREAM))
 245                 return -EINVAL; /* need packet boundaries */
 246 
 247         /* Create net device */
 248         dev = alloc_netdev(sizeof(*gp), ifname, NET_NAME_UNKNOWN, gprs_setup);
 249         if (!dev)
 250                 return -ENOMEM;
 251         gp = netdev_priv(dev);
 252         gp->sk = sk;
 253         gp->dev = dev;
 254 
 255         netif_stop_queue(dev);
 256         err = register_netdev(dev);
 257         if (err) {
 258                 free_netdev(dev);
 259                 return err;
 260         }
 261 
 262         lock_sock(sk);
 263         if (unlikely(sk->sk_user_data)) {
 264                 err = -EBUSY;
 265                 goto out_rel;
 266         }
 267         if (unlikely((1 << sk->sk_state & (TCPF_CLOSE|TCPF_LISTEN)) ||
 268                         sock_flag(sk, SOCK_DEAD))) {
 269                 err = -EINVAL;
 270                 goto out_rel;
 271         }
 272         sk->sk_user_data        = gp;
 273         gp->old_state_change    = sk->sk_state_change;
 274         gp->old_data_ready      = sk->sk_data_ready;
 275         gp->old_write_space     = sk->sk_write_space;
 276         sk->sk_state_change     = gprs_state_change;
 277         sk->sk_data_ready       = gprs_data_ready;
 278         sk->sk_write_space      = gprs_write_space;
 279         release_sock(sk);
 280         sock_hold(sk);
 281 
 282         printk(KERN_DEBUG"%s: attached\n", dev->name);
 283         return dev->ifindex;
 284 
 285 out_rel:
 286         release_sock(sk);
 287         unregister_netdev(dev);
 288         return err;
 289 }
 290 
 291 void gprs_detach(struct sock *sk)
 292 {
 293         struct gprs_dev *gp = sk->sk_user_data;
 294         struct net_device *dev = gp->dev;
 295 
 296         lock_sock(sk);
 297         sk->sk_user_data        = NULL;
 298         sk->sk_state_change     = gp->old_state_change;
 299         sk->sk_data_ready       = gp->old_data_ready;
 300         sk->sk_write_space      = gp->old_write_space;
 301         release_sock(sk);
 302 
 303         printk(KERN_DEBUG"%s: detached\n", dev->name);
 304         unregister_netdev(dev);
 305         sock_put(sk);
 306 }

/* [<][>][^][v][top][bottom][index][help] */