^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) #ifndef LLC_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #define LLC_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 1997 by Procom Technology, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * This program can be redistributed or modified under the terms of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * GNU General Public License as published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This program is distributed without any warranty or implied warranty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * of merchantability or fitness for a particular purpose.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * See the GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/if.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/rculist_nulls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/hash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/jhash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct net_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct packet_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct sk_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct llc_addr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) unsigned char lsap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) unsigned char mac[IFHWADDRLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define LLC_SAP_STATE_INACTIVE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define LLC_SAP_STATE_ACTIVE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define LLC_SK_DEV_HASH_BITS 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define LLC_SK_DEV_HASH_ENTRIES (1<<LLC_SK_DEV_HASH_BITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define LLC_SK_LADDR_HASH_BITS 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define LLC_SK_LADDR_HASH_ENTRIES (1<<LLC_SK_LADDR_HASH_BITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * struct llc_sap - Defines the SAP component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * @station - station this sap belongs to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * @state - sap state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * @p_bit - only lowest-order bit used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * @f_bit - only lowest-order bit used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * @laddr - SAP value in this 'lsap'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * @node - entry in station sap_list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * @sk_list - LLC sockets this one manages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct llc_sap {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) unsigned char state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) unsigned char p_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) unsigned char f_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) refcount_t refcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int (*rcv_func)(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct packet_type *pt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct net_device *orig_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct llc_addr laddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) spinlock_t sk_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int sk_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct hlist_nulls_head sk_laddr_hash[LLC_SK_LADDR_HASH_ENTRIES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct hlist_head sk_dev_hash[LLC_SK_DEV_HASH_ENTRIES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct rcu_head rcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct hlist_head *llc_sk_dev_hash(struct llc_sap *sap, int ifindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) u32 bucket = hash_32(ifindex, LLC_SK_DEV_HASH_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return &sap->sk_dev_hash[bucket];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) u32 llc_sk_laddr_hashfn(struct llc_sap *sap, const struct llc_addr *laddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return hash_32(jhash(laddr->mac, sizeof(laddr->mac), 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) LLC_SK_LADDR_HASH_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct hlist_nulls_head *llc_sk_laddr_hash(struct llc_sap *sap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) const struct llc_addr *laddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return &sap->sk_laddr_hash[llc_sk_laddr_hashfn(sap, laddr)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define LLC_DEST_INVALID 0 /* Invalid LLC PDU type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define LLC_DEST_SAP 1 /* Type 1 goes here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define LLC_DEST_CONN 2 /* Type 2 goes here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) extern struct list_head llc_sap_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int llc_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct net_device *orig_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int llc_mac_hdr_init(struct sk_buff *skb, const unsigned char *sa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) const unsigned char *da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) void llc_add_pack(int type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) void (*handler)(struct llc_sap *sap, struct sk_buff *skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) void llc_remove_pack(int type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) void llc_set_station_handler(void (*handler)(struct sk_buff *skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct llc_sap *llc_sap_open(unsigned char lsap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int (*rcv)(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct packet_type *pt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct net_device *orig_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static inline void llc_sap_hold(struct llc_sap *sap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) refcount_inc(&sap->refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static inline bool llc_sap_hold_safe(struct llc_sap *sap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return refcount_inc_not_zero(&sap->refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) void llc_sap_close(struct llc_sap *sap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static inline void llc_sap_put(struct llc_sap *sap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (refcount_dec_and_test(&sap->refcnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) llc_sap_close(sap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct llc_sap *llc_sap_find(unsigned char sap_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) unsigned char *dmac, unsigned char dsap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) void llc_station_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) void llc_station_exit(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) int llc_proc_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) void llc_proc_exit(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define llc_proc_init() (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define llc_proc_exit() do { } while(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #endif /* CONFIG_PROC_FS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #ifdef CONFIG_SYSCTL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) int llc_sysctl_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) void llc_sysctl_exit(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) extern int sysctl_llc2_ack_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) extern int sysctl_llc2_busy_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) extern int sysctl_llc2_p_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) extern int sysctl_llc2_rej_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define llc_sysctl_init() (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define llc_sysctl_exit() do { } while(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #endif /* CONFIG_SYSCTL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #endif /* LLC_H */