Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  SNAP data link layer. Derived from 802.2
0004  *
0005  *      Alan Cox <alan@lxorguk.ukuu.org.uk>,
0006  *      from the 802.2 layer by Greg Page.
0007  *      Merged in additions from Greg Page's psnap.c.
0008  */
0009 
0010 #include <linux/module.h>
0011 #include <linux/netdevice.h>
0012 #include <linux/skbuff.h>
0013 #include <linux/slab.h>
0014 #include <net/datalink.h>
0015 #include <net/llc.h>
0016 #include <net/psnap.h>
0017 #include <linux/mm.h>
0018 #include <linux/in.h>
0019 #include <linux/init.h>
0020 #include <linux/rculist.h>
0021 
0022 static LIST_HEAD(snap_list);
0023 static DEFINE_SPINLOCK(snap_lock);
0024 static struct llc_sap *snap_sap;
0025 
0026 /*
0027  *  Find a snap client by matching the 5 bytes.
0028  */
0029 static struct datalink_proto *find_snap_client(const unsigned char *desc)
0030 {
0031     struct datalink_proto *proto = NULL, *p;
0032 
0033     list_for_each_entry_rcu(p, &snap_list, node, lockdep_is_held(&snap_lock)) {
0034         if (!memcmp(p->type, desc, 5)) {
0035             proto = p;
0036             break;
0037         }
0038     }
0039     return proto;
0040 }
0041 
0042 /*
0043  *  A SNAP packet has arrived
0044  */
0045 static int snap_rcv(struct sk_buff *skb, struct net_device *dev,
0046             struct packet_type *pt, struct net_device *orig_dev)
0047 {
0048     int rc = 1;
0049     struct datalink_proto *proto;
0050     static struct packet_type snap_packet_type = {
0051         .type = cpu_to_be16(ETH_P_SNAP),
0052     };
0053 
0054     if (unlikely(!pskb_may_pull(skb, 5)))
0055         goto drop;
0056 
0057     rcu_read_lock();
0058     proto = find_snap_client(skb_transport_header(skb));
0059     if (proto) {
0060         /* Pass the frame on. */
0061         skb->transport_header += 5;
0062         skb_pull_rcsum(skb, 5);
0063         rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev);
0064     }
0065     rcu_read_unlock();
0066 
0067     if (unlikely(!proto))
0068         goto drop;
0069 
0070 out:
0071     return rc;
0072 
0073 drop:
0074     kfree_skb(skb);
0075     goto out;
0076 }
0077 
0078 /*
0079  *  Put a SNAP header on a frame and pass to 802.2
0080  */
0081 static int snap_request(struct datalink_proto *dl,
0082             struct sk_buff *skb, const u8 *dest)
0083 {
0084     memcpy(skb_push(skb, 5), dl->type, 5);
0085     llc_build_and_send_ui_pkt(snap_sap, skb, dest, snap_sap->laddr.lsap);
0086     return 0;
0087 }
0088 
0089 /*
0090  *  Set up the SNAP layer
0091  */
0092 EXPORT_SYMBOL(register_snap_client);
0093 EXPORT_SYMBOL(unregister_snap_client);
0094 
0095 static const char snap_err_msg[] __initconst =
0096     KERN_CRIT "SNAP - unable to register with 802.2\n";
0097 
0098 static int __init snap_init(void)
0099 {
0100     snap_sap = llc_sap_open(0xAA, snap_rcv);
0101     if (!snap_sap) {
0102         printk(snap_err_msg);
0103         return -EBUSY;
0104     }
0105 
0106     return 0;
0107 }
0108 
0109 module_init(snap_init);
0110 
0111 static void __exit snap_exit(void)
0112 {
0113     llc_sap_put(snap_sap);
0114 }
0115 
0116 module_exit(snap_exit);
0117 
0118 
0119 /*
0120  *  Register SNAP clients. We don't yet use this for IP.
0121  */
0122 struct datalink_proto *register_snap_client(const unsigned char *desc,
0123                         int (*rcvfunc)(struct sk_buff *,
0124                                struct net_device *,
0125                                struct packet_type *,
0126                                struct net_device *))
0127 {
0128     struct datalink_proto *proto = NULL;
0129 
0130     spin_lock_bh(&snap_lock);
0131 
0132     if (find_snap_client(desc))
0133         goto out;
0134 
0135     proto = kmalloc(sizeof(*proto), GFP_ATOMIC);
0136     if (proto) {
0137         memcpy(proto->type, desc, 5);
0138         proto->rcvfunc      = rcvfunc;
0139         proto->header_length    = 5 + 3; /* snap + 802.2 */
0140         proto->request      = snap_request;
0141         list_add_rcu(&proto->node, &snap_list);
0142     }
0143 out:
0144     spin_unlock_bh(&snap_lock);
0145 
0146     return proto;
0147 }
0148 
0149 /*
0150  *  Unregister SNAP clients. Protocols no longer want to play with us ...
0151  */
0152 void unregister_snap_client(struct datalink_proto *proto)
0153 {
0154     spin_lock_bh(&snap_lock);
0155     list_del_rcu(&proto->node);
0156     spin_unlock_bh(&snap_lock);
0157 
0158     synchronize_net();
0159 
0160     kfree(proto);
0161 }
0162 
0163 MODULE_LICENSE("GPL");