/*
* SNAP data link layer. Derived from 802.2
*
- * Alan Cox <Alan.Cox@linux.org>,
+ * Alan Cox <alan@lxorguk.ukuu.org.uk>,
* from the 802.2 layer by Greg Page.
* Merged in additions from Greg Page's psnap.c.
*
#include <linux/mm.h>
#include <linux/in.h>
#include <linux/init.h>
+#include <linux/rculist.h>
static LIST_HEAD(snap_list);
static DEFINE_SPINLOCK(snap_lock);
/*
* Find a snap client by matching the 5 bytes.
*/
-static struct datalink_proto *find_snap_client(unsigned char *desc)
+static struct datalink_proto *find_snap_client(const unsigned char *desc)
{
- struct list_head *entry;
struct datalink_proto *proto = NULL, *p;
- list_for_each_rcu(entry, &snap_list) {
- p = list_entry(entry, struct datalink_proto, node);
+ list_for_each_entry_rcu(p, &snap_list, node) {
if (!memcmp(p->type, desc, 5)) {
proto = p;
break;
int rc = 1;
struct datalink_proto *proto;
static struct packet_type snap_packet_type = {
- .type = __constant_htons(ETH_P_SNAP),
+ .type = cpu_to_be16(ETH_P_SNAP),
};
+ if (unlikely(!pskb_may_pull(skb, 5)))
+ goto drop;
+
rcu_read_lock();
- proto = find_snap_client(skb->h.raw);
+ proto = find_snap_client(skb_transport_header(skb));
if (proto) {
/* Pass the frame on. */
- skb->h.raw += 5;
- skb_pull(skb, 5);
+ skb->transport_header += 5;
+ skb_pull_rcsum(skb, 5);
rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev);
- } else {
- skb->sk = NULL;
- kfree_skb(skb);
- rc = 1;
}
-
rcu_read_unlock();
+
+ if (unlikely(!proto))
+ goto drop;
+
+out:
return rc;
+
+drop:
+ kfree_skb(skb);
+ goto out;
}
/*
EXPORT_SYMBOL(register_snap_client);
EXPORT_SYMBOL(unregister_snap_client);
-static char snap_err_msg[] __initdata =
+static const char snap_err_msg[] __initconst =
KERN_CRIT "SNAP - unable to register with 802.2\n";
static int __init snap_init(void)
{
snap_sap = llc_sap_open(0xAA, snap_rcv);
-
- if (!snap_sap)
+ if (!snap_sap) {
printk(snap_err_msg);
+ return -EBUSY;
+ }
return 0;
}
static void __exit snap_exit(void)
{
- llc_sap_close(snap_sap);
+ llc_sap_put(snap_sap);
}
module_exit(snap_exit);
/*
* Register SNAP clients. We don't yet use this for IP.
*/
-struct datalink_proto *register_snap_client(unsigned char *desc,
+struct datalink_proto *register_snap_client(const unsigned char *desc,
int (*rcvfunc)(struct sk_buff *,
- struct net_device *,
+ struct net_device *,
struct packet_type *,
struct net_device *))
{
proto = kmalloc(sizeof(*proto), GFP_ATOMIC);
if (proto) {
- memcpy(proto->type, desc,5);
+ memcpy(proto->type, desc, 5);
proto->rcvfunc = rcvfunc;
proto->header_length = 5 + 3; /* snap + 802.2 */
proto->request = snap_request;