| 1 |
|
| 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 <[email protected]>
|
| 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
|
| 89 | #define LLC_DEST_SAP 1
|
| 90 | #define LLC_DEST_CONN 2
|
| 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
|
| 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
|
| 159 | #endif
|