linux/net/phonet/pep-gprs.c
<<
>>
Prefs
   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
  24struct 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
  33static __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
  51static 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
  63static 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
  75static 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
 128drop:
 129        if (skb) {
 130                dev_kfree_skb(skb);
 131                dev->stats.rx_dropped++;
 132        }
 133        return err;
 134}
 135
 136static 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
 147static 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
 159static 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
 167static int gprs_close(struct net_device *dev)
 168{
 169        netif_stop_queue(dev);
 170        return 0;
 171}
 172
 173static 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
 207static 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
 213static 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 */
 237int 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
 285out_rel:
 286        release_sock(sk);
 287        unregister_netdev(dev);
 288        return err;
 289}
 290
 291void 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}
 307