static char bpq_eth_addr[6];
-static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *);
+static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *);
static int bpq_device_event(struct notifier_block *, unsigned long, void *);
static const char *bpq_print_ethaddr(const unsigned char *);
};
-#define MAXBPQDEV 100
-
struct bpqdev {
struct list_head bpq_list; /* list of bpq devices chain */
struct net_device *ethdev; /* link to ethernet device */
*/
static inline struct net_device *bpq_get_ether_dev(struct net_device *dev)
{
- struct bpqdev *bpq = (struct bpqdev *) dev->priv;
+ struct bpqdev *bpq = netdev_priv(dev);
return bpq ? bpq->ethdev : NULL;
}
{
struct bpqdev *bpq;
- list_for_each_entry(bpq, &bpq_devices, bpq_list) {
+ list_for_each_entry_rcu(bpq, &bpq_devices, bpq_list) {
if (bpq->ethdev == dev)
return bpq->axdev;
}
/*
* Receive an AX.25 frame via an ethernet interface.
*/
-static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype)
+static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev)
{
int len;
char * ptr;
* we check the source address of the sender.
*/
- bpq = (struct bpqdev *)dev->priv;
+ bpq = netdev_priv(dev);
eth = eth_hdr(skb);
ptr = skb_push(skb, 1);
*ptr = 0;
- skb->dev = dev;
- skb->protocol = htons(ETH_P_AX25);
- skb->mac.raw = skb->data;
- skb->pkt_type = PACKET_HOST;
-
+ skb->protocol = ax25_type_trans(skb, dev);
netif_rx(skb);
dev->last_rx = jiffies;
unlock:
skb = newskb;
}
- skb->protocol = htons(ETH_P_AX25);
-
ptr = skb_push(skb, 2);
*ptr++ = (size + 5) % 256;
*ptr++ = (size + 5) / 256;
- bpq = (struct bpqdev *)dev->priv;
+ bpq = netdev_priv(dev);
if ((dev = bpq_get_ether_dev(dev)) == NULL) {
bpq->stats.tx_dropped++;
return -ENODEV;
}
- skb->dev = dev;
+ skb->protocol = ax25_type_trans(skb, dev);
skb->nh.raw = skb->data;
dev->hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0);
bpq->stats.tx_packets++;
*/
static struct net_device_stats *bpq_get_stats(struct net_device *dev)
{
- struct bpqdev *bpq = (struct bpqdev *) dev->priv;
+ struct bpqdev *bpq = netdev_priv(dev);
return &bpq->stats;
}
static int bpq_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct bpq_ethaddr __user *ethaddr = ifr->ifr_data;
- struct bpqdev *bpq = dev->priv;
+ struct bpqdev *bpq = netdev_priv(dev);
struct bpq_req req;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- if (bpq == NULL) /* woops! */
- return -ENODEV;
-
switch (cmd) {
case SIOCSBPQETHOPT:
if (copy_from_user(&req, ifr->ifr_data, sizeof(struct bpq_req)))
if (*pos == 0)
return SEQ_START_TOKEN;
- list_for_each_entry(bpqdev, &bpq_devices, bpq_list) {
+ list_for_each_entry_rcu(bpqdev, &bpq_devices, bpq_list) {
if (i == *pos)
return bpqdev;
}
p = ((struct bpqdev *)v)->bpq_list.next;
return (p == &bpq_devices) ? NULL
- : list_entry(p, struct bpqdev, bpq_list);
+ : rcu_dereference(list_entry(p, struct bpqdev, bpq_list));
}
static void bpq_seq_stop(struct seq_file *seq, void *v)
dev->flags = 0;
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
- dev->hard_header = ax25_encapsulate;
+ dev->hard_header = ax25_hard_header;
dev->rebuild_header = ax25_rebuild_header;
#endif
return -ENOMEM;
- bpq = ndev->priv;
+ bpq = netdev_priv(ndev);
dev_hold(edev);
bpq->ethdev = edev;
bpq->axdev = ndev;
static void bpq_free_device(struct net_device *ndev)
{
- struct bpqdev *bpq = ndev->priv;
+ struct bpqdev *bpq = netdev_priv(ndev);
dev_put(bpq->ethdev);
list_del_rcu(&bpq->bpq_list);
if (!dev_is_ethdev(dev))
return NOTIFY_DONE;
- rcu_read_lock();
-
switch (event) {
case NETDEV_UP: /* new ethernet device -> new BPQ interface */
if (bpq_get_ax25_dev(dev) == NULL)
default:
break;
}
- rcu_read_unlock();
return NOTIFY_DONE;
}