1 /* 2 * SNAP data link layer. Derived from 802.2 3 * 4 * Alan Cox <Alan.Cox@linux.org>, 5 * from the 802.2 layer by Greg Page. 6 * Merged in additions from Greg Page's psnap.c. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * as published by the Free Software Foundation; either version 11 * 2 of the License, or (at your option) any later version. 12 */ 13 14 #include <linux/module.h> 15 #include <linux/netdevice.h> 16 #include <linux/skbuff.h> 17 #include <net/datalink.h> 18 #include <net/llc.h> 19 #include <net/psnap.h> 20 #include <linux/mm.h> 21 #include <linux/in.h> 22 #include <linux/init.h> 23 24 static LIST_HEAD(snap_list); 25 static DEFINE_SPINLOCK(snap_lock); 26 static struct llc_sap *snap_sap; 27 28 /* 29 * Find a snap client by matching the 5 bytes. 30 */ 31 static struct datalink_proto *find_snap_client(unsigned char *desc) 32 { 33 struct list_head *entry; 34 struct datalink_proto *proto = NULL, *p; 35 36 list_for_each_rcu(entry, &snap_list) { 37 p = list_entry(entry, struct datalink_proto, node); 38 if (!memcmp(p->type, desc, 5)) { 39 proto = p; 40 break; 41 } 42 } 43 return proto; 44 } 45 46 /* 47 * A SNAP packet has arrived 48 */ 49 static int snap_rcv(struct sk_buff *skb, struct net_device *dev, 50 struct packet_type *pt, struct net_device *orig_dev) 51 { 52 int rc = 1; 53 struct datalink_proto *proto; 54 static struct packet_type snap_packet_type = { 55 .type = __constant_htons(ETH_P_SNAP), 56 }; 57 58 rcu_read_lock(); 59 proto = find_snap_client(skb_transport_header(skb)); 60 if (proto) { 61 /* Pass the frame on. */ 62 skb->transport_header += 5; 63 skb_pull_rcsum(skb, 5); 64 rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev); 65 } else { 66 skb->sk = NULL; 67 kfree_skb(skb); 68 rc = 1; 69 } 70 71 rcu_read_unlock(); 72 return rc; 73 } 74 75 /* 76 * Put a SNAP header on a frame and pass to 802.2 77 */ 78 static int snap_request(struct datalink_proto *dl, 79 struct sk_buff *skb, u8 *dest) 80 { 81 memcpy(skb_push(skb, 5), dl->type, 5); 82 llc_build_and_send_ui_pkt(snap_sap, skb, dest, snap_sap->laddr.lsap); 83 return 0; 84 } 85 86 /* 87 * Set up the SNAP layer 88 */ 89 EXPORT_SYMBOL(register_snap_client); 90 EXPORT_SYMBOL(unregister_snap_client); 91 92 static char snap_err_msg[] __initdata = 93 KERN_CRIT "SNAP - unable to register with 802.2\n"; 94 95 static int __init snap_init(void) 96 { 97 snap_sap = llc_sap_open(0xAA, snap_rcv); 98 99 if (!snap_sap) 100 printk(snap_err_msg); 101 102 return 0; 103 } 104 105 module_init(snap_init); 106 107 static void __exit snap_exit(void) 108 { 109 llc_sap_put(snap_sap); 110 } 111 112 module_exit(snap_exit); 113 114 115 /* 116 * Register SNAP clients. We don't yet use this for IP. 117 */ 118 struct datalink_proto *register_snap_client(unsigned char *desc, 119 int (*rcvfunc)(struct sk_buff *, 120 struct net_device *, 121 struct packet_type *, 122 struct net_device *)) 123 { 124 struct datalink_proto *proto = NULL; 125 126 spin_lock_bh(&snap_lock); 127 128 if (find_snap_client(desc)) 129 goto out; 130 131 proto = kmalloc(sizeof(*proto), GFP_ATOMIC); 132 if (proto) { 133 memcpy(proto->type, desc,5); 134 proto->rcvfunc = rcvfunc; 135 proto->header_length = 5 + 3; /* snap + 802.2 */ 136 proto->request = snap_request; 137 list_add_rcu(&proto->node, &snap_list); 138 } 139 out: 140 spin_unlock_bh(&snap_lock); 141 142 synchronize_net(); 143 return proto; 144 } 145 146 /* 147 * Unregister SNAP clients. Protocols no longer want to play with us ... 148 */ 149 void unregister_snap_client(struct datalink_proto *proto) 150 { 151 spin_lock_bh(&snap_lock); 152 list_del_rcu(&proto->node); 153 spin_unlock_bh(&snap_lock); 154 155 synchronize_net(); 156 157 kfree(proto); 158 } 159 160 MODULE_LICENSE("GPL"); 161