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