0001 #ifndef LLC_H
0002 #define LLC_H
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/if.h>
0016 #include <linux/if_ether.h>
0017 #include <linux/list.h>
0018 #include <linux/spinlock.h>
0019 #include <linux/rculist_nulls.h>
0020 #include <linux/hash.h>
0021 #include <linux/jhash.h>
0022
0023 #include <linux/atomic.h>
0024
0025 struct net_device;
0026 struct packet_type;
0027 struct sk_buff;
0028
0029 struct llc_addr {
0030 unsigned char lsap;
0031 unsigned char mac[IFHWADDRLEN];
0032 };
0033
0034 #define LLC_SAP_STATE_INACTIVE 1
0035 #define LLC_SAP_STATE_ACTIVE 2
0036
0037 #define LLC_SK_DEV_HASH_BITS 6
0038 #define LLC_SK_DEV_HASH_ENTRIES (1<<LLC_SK_DEV_HASH_BITS)
0039
0040 #define LLC_SK_LADDR_HASH_BITS 6
0041 #define LLC_SK_LADDR_HASH_ENTRIES (1<<LLC_SK_LADDR_HASH_BITS)
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054 struct llc_sap {
0055 unsigned char state;
0056 unsigned char p_bit;
0057 unsigned char f_bit;
0058 refcount_t refcnt;
0059 int (*rcv_func)(struct sk_buff *skb,
0060 struct net_device *dev,
0061 struct packet_type *pt,
0062 struct net_device *orig_dev);
0063 struct llc_addr laddr;
0064 struct list_head node;
0065 spinlock_t sk_lock;
0066 int sk_count;
0067 struct hlist_nulls_head sk_laddr_hash[LLC_SK_LADDR_HASH_ENTRIES];
0068 struct hlist_head sk_dev_hash[LLC_SK_DEV_HASH_ENTRIES];
0069 struct rcu_head rcu;
0070 };
0071
0072 static inline
0073 struct hlist_head *llc_sk_dev_hash(struct llc_sap *sap, int ifindex)
0074 {
0075 u32 bucket = hash_32(ifindex, LLC_SK_DEV_HASH_BITS);
0076
0077 return &sap->sk_dev_hash[bucket];
0078 }
0079
0080 static inline
0081 u32 llc_sk_laddr_hashfn(struct llc_sap *sap, const struct llc_addr *laddr)
0082 {
0083 return hash_32(jhash(laddr->mac, sizeof(laddr->mac), 0),
0084 LLC_SK_LADDR_HASH_BITS);
0085 }
0086
0087 static inline
0088 struct hlist_nulls_head *llc_sk_laddr_hash(struct llc_sap *sap,
0089 const struct llc_addr *laddr)
0090 {
0091 return &sap->sk_laddr_hash[llc_sk_laddr_hashfn(sap, laddr)];
0092 }
0093
0094 #define LLC_DEST_INVALID 0
0095 #define LLC_DEST_SAP 1
0096 #define LLC_DEST_CONN 2
0097
0098 extern struct list_head llc_sap_list;
0099
0100 int llc_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
0101 struct net_device *orig_dev);
0102
0103 int llc_mac_hdr_init(struct sk_buff *skb, const unsigned char *sa,
0104 const unsigned char *da);
0105
0106 void llc_add_pack(int type,
0107 void (*handler)(struct llc_sap *sap, struct sk_buff *skb));
0108 void llc_remove_pack(int type);
0109
0110 void llc_set_station_handler(void (*handler)(struct sk_buff *skb));
0111
0112 struct llc_sap *llc_sap_open(unsigned char lsap,
0113 int (*rcv)(struct sk_buff *skb,
0114 struct net_device *dev,
0115 struct packet_type *pt,
0116 struct net_device *orig_dev));
0117 static inline void llc_sap_hold(struct llc_sap *sap)
0118 {
0119 refcount_inc(&sap->refcnt);
0120 }
0121
0122 static inline bool llc_sap_hold_safe(struct llc_sap *sap)
0123 {
0124 return refcount_inc_not_zero(&sap->refcnt);
0125 }
0126
0127 void llc_sap_close(struct llc_sap *sap);
0128
0129 static inline void llc_sap_put(struct llc_sap *sap)
0130 {
0131 if (refcount_dec_and_test(&sap->refcnt))
0132 llc_sap_close(sap);
0133 }
0134
0135 struct llc_sap *llc_sap_find(unsigned char sap_value);
0136
0137 int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
0138 const unsigned char *dmac, unsigned char dsap);
0139
0140 void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb);
0141 void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
0142
0143 void llc_station_init(void);
0144 void llc_station_exit(void);
0145
0146 #ifdef CONFIG_PROC_FS
0147 int llc_proc_init(void);
0148 void llc_proc_exit(void);
0149 #else
0150 #define llc_proc_init() (0)
0151 #define llc_proc_exit() do { } while(0)
0152 #endif
0153 #ifdef CONFIG_SYSCTL
0154 int llc_sysctl_init(void);
0155 void llc_sysctl_exit(void);
0156
0157 extern int sysctl_llc2_ack_timeout;
0158 extern int sysctl_llc2_busy_timeout;
0159 extern int sysctl_llc2_p_timeout;
0160 extern int sysctl_llc2_rej_timeout;
0161 #else
0162 #define llc_sysctl_init() (0)
0163 #define llc_sysctl_exit() do { } while(0)
0164 #endif
0165 #endif