diff options
Diffstat (limited to 'include/net')
131 files changed, 26615 insertions, 0 deletions
diff --git a/include/net/act_api.h b/include/net/act_api.h new file mode 100644 index 000000000000..ed00a995f576 --- /dev/null +++ b/include/net/act_api.h | |||
@@ -0,0 +1,116 @@ | |||
1 | #ifndef __NET_ACT_API_H | ||
2 | #define __NET_ACT_API_H | ||
3 | |||
4 | /* | ||
5 | * Public police action API for classifiers/qdiscs | ||
6 | */ | ||
7 | |||
8 | #include <net/sch_generic.h> | ||
9 | #include <net/pkt_sched.h> | ||
10 | |||
11 | #define tca_gen(name) \ | ||
12 | struct tcf_##name *next; \ | ||
13 | u32 index; \ | ||
14 | int refcnt; \ | ||
15 | int bindcnt; \ | ||
16 | u32 capab; \ | ||
17 | int action; \ | ||
18 | struct tcf_t tm; \ | ||
19 | struct gnet_stats_basic bstats; \ | ||
20 | struct gnet_stats_queue qstats; \ | ||
21 | struct gnet_stats_rate_est rate_est; \ | ||
22 | spinlock_t *stats_lock; \ | ||
23 | spinlock_t lock | ||
24 | |||
25 | struct tcf_police | ||
26 | { | ||
27 | tca_gen(police); | ||
28 | int result; | ||
29 | u32 ewma_rate; | ||
30 | u32 burst; | ||
31 | u32 mtu; | ||
32 | u32 toks; | ||
33 | u32 ptoks; | ||
34 | psched_time_t t_c; | ||
35 | struct qdisc_rate_table *R_tab; | ||
36 | struct qdisc_rate_table *P_tab; | ||
37 | }; | ||
38 | |||
39 | #ifdef CONFIG_NET_CLS_ACT | ||
40 | |||
41 | #define ACT_P_CREATED 1 | ||
42 | #define ACT_P_DELETED 1 | ||
43 | |||
44 | struct tcf_act_hdr | ||
45 | { | ||
46 | tca_gen(act_hdr); | ||
47 | }; | ||
48 | |||
49 | struct tc_action | ||
50 | { | ||
51 | void *priv; | ||
52 | struct tc_action_ops *ops; | ||
53 | __u32 type; /* for backward compat(TCA_OLD_COMPAT) */ | ||
54 | __u32 order; | ||
55 | struct tc_action *next; | ||
56 | }; | ||
57 | |||
58 | #define TCA_CAP_NONE 0 | ||
59 | struct tc_action_ops | ||
60 | { | ||
61 | struct tc_action_ops *next; | ||
62 | char kind[IFNAMSIZ]; | ||
63 | __u32 type; /* TBD to match kind */ | ||
64 | __u32 capab; /* capabilities includes 4 bit version */ | ||
65 | struct module *owner; | ||
66 | int (*act)(struct sk_buff **, struct tc_action *); | ||
67 | int (*get_stats)(struct sk_buff *, struct tc_action *); | ||
68 | int (*dump)(struct sk_buff *, struct tc_action *,int , int); | ||
69 | int (*cleanup)(struct tc_action *, int bind); | ||
70 | int (*lookup)(struct tc_action *, u32 ); | ||
71 | int (*init)(struct rtattr *,struct rtattr *,struct tc_action *, int , int ); | ||
72 | int (*walk)(struct sk_buff *, struct netlink_callback *, int , struct tc_action *); | ||
73 | }; | ||
74 | |||
75 | extern int tcf_register_action(struct tc_action_ops *a); | ||
76 | extern int tcf_unregister_action(struct tc_action_ops *a); | ||
77 | extern void tcf_action_destroy(struct tc_action *a, int bind); | ||
78 | extern int tcf_action_exec(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res); | ||
79 | extern struct tc_action *tcf_action_init(struct rtattr *rta, struct rtattr *est, char *n, int ovr, int bind, int *err); | ||
80 | extern struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est, char *n, int ovr, int bind, int *err); | ||
81 | extern int tcf_action_dump(struct sk_buff *skb, struct tc_action *a, int, int); | ||
82 | extern int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int); | ||
83 | extern int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int); | ||
84 | extern int tcf_action_copy_stats (struct sk_buff *,struct tc_action *, int); | ||
85 | #endif /* CONFIG_NET_CLS_ACT */ | ||
86 | |||
87 | extern int tcf_police(struct sk_buff *skb, struct tcf_police *p); | ||
88 | extern void tcf_police_destroy(struct tcf_police *p); | ||
89 | extern struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est); | ||
90 | extern int tcf_police_dump(struct sk_buff *skb, struct tcf_police *p); | ||
91 | extern int tcf_police_dump_stats(struct sk_buff *skb, struct tcf_police *p); | ||
92 | |||
93 | static inline int | ||
94 | tcf_police_release(struct tcf_police *p, int bind) | ||
95 | { | ||
96 | int ret = 0; | ||
97 | #ifdef CONFIG_NET_CLS_ACT | ||
98 | if (p) { | ||
99 | if (bind) { | ||
100 | p->bindcnt--; | ||
101 | } | ||
102 | p->refcnt--; | ||
103 | if (p->refcnt <= 0 && !p->bindcnt) { | ||
104 | tcf_police_destroy(p); | ||
105 | ret = 1; | ||
106 | } | ||
107 | } | ||
108 | #else | ||
109 | if (p && --p->refcnt == 0) | ||
110 | tcf_police_destroy(p); | ||
111 | |||
112 | #endif /* CONFIG_NET_CLS_ACT */ | ||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | #endif | ||
diff --git a/include/net/addrconf.h b/include/net/addrconf.h new file mode 100644 index 000000000000..7af9a13cb9be --- /dev/null +++ b/include/net/addrconf.h | |||
@@ -0,0 +1,240 @@ | |||
1 | #ifndef _ADDRCONF_H | ||
2 | #define _ADDRCONF_H | ||
3 | |||
4 | #define RETRANS_TIMER HZ | ||
5 | |||
6 | #define MAX_RTR_SOLICITATIONS 3 | ||
7 | #define RTR_SOLICITATION_INTERVAL (4*HZ) | ||
8 | |||
9 | #define MIN_VALID_LIFETIME (2*3600) /* 2 hours */ | ||
10 | |||
11 | #define TEMP_VALID_LIFETIME (7*86400) | ||
12 | #define TEMP_PREFERRED_LIFETIME (86400) | ||
13 | #define REGEN_MAX_RETRY (5) | ||
14 | #define MAX_DESYNC_FACTOR (600) | ||
15 | |||
16 | #define ADDR_CHECK_FREQUENCY (120*HZ) | ||
17 | |||
18 | #define IPV6_MAX_ADDRESSES 16 | ||
19 | |||
20 | struct prefix_info { | ||
21 | __u8 type; | ||
22 | __u8 length; | ||
23 | __u8 prefix_len; | ||
24 | |||
25 | #if defined(__BIG_ENDIAN_BITFIELD) | ||
26 | __u8 onlink : 1, | ||
27 | autoconf : 1, | ||
28 | reserved : 6; | ||
29 | #elif defined(__LITTLE_ENDIAN_BITFIELD) | ||
30 | __u8 reserved : 6, | ||
31 | autoconf : 1, | ||
32 | onlink : 1; | ||
33 | #else | ||
34 | #error "Please fix <asm/byteorder.h>" | ||
35 | #endif | ||
36 | __u32 valid; | ||
37 | __u32 prefered; | ||
38 | __u32 reserved2; | ||
39 | |||
40 | struct in6_addr prefix; | ||
41 | }; | ||
42 | |||
43 | |||
44 | #ifdef __KERNEL__ | ||
45 | |||
46 | #include <linux/in6.h> | ||
47 | #include <linux/netdevice.h> | ||
48 | #include <net/if_inet6.h> | ||
49 | |||
50 | #define IN6_ADDR_HSIZE 16 | ||
51 | |||
52 | extern int addrconf_init(void); | ||
53 | extern void addrconf_cleanup(void); | ||
54 | |||
55 | extern int addrconf_add_ifaddr(void __user *arg); | ||
56 | extern int addrconf_del_ifaddr(void __user *arg); | ||
57 | extern int addrconf_set_dstaddr(void __user *arg); | ||
58 | |||
59 | extern int ipv6_chk_addr(struct in6_addr *addr, | ||
60 | struct net_device *dev, | ||
61 | int strict); | ||
62 | extern struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, | ||
63 | struct net_device *dev, | ||
64 | int strict); | ||
65 | extern int ipv6_get_saddr(struct dst_entry *dst, | ||
66 | struct in6_addr *daddr, | ||
67 | struct in6_addr *saddr); | ||
68 | extern int ipv6_dev_get_saddr(struct net_device *dev, | ||
69 | struct in6_addr *daddr, | ||
70 | struct in6_addr *saddr); | ||
71 | extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *); | ||
72 | extern int ipv6_rcv_saddr_equal(const struct sock *sk, | ||
73 | const struct sock *sk2); | ||
74 | extern void addrconf_join_solict(struct net_device *dev, | ||
75 | struct in6_addr *addr); | ||
76 | extern void addrconf_leave_solict(struct inet6_dev *idev, | ||
77 | struct in6_addr *addr); | ||
78 | |||
79 | /* | ||
80 | * multicast prototypes (mcast.c) | ||
81 | */ | ||
82 | extern int ipv6_sock_mc_join(struct sock *sk, int ifindex, | ||
83 | struct in6_addr *addr); | ||
84 | extern int ipv6_sock_mc_drop(struct sock *sk, int ifindex, | ||
85 | struct in6_addr *addr); | ||
86 | extern void ipv6_sock_mc_close(struct sock *sk); | ||
87 | extern int inet6_mc_check(struct sock *sk, struct in6_addr *mc_addr, | ||
88 | struct in6_addr *src_addr); | ||
89 | |||
90 | extern int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr); | ||
91 | extern int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr); | ||
92 | extern int ipv6_dev_mc_dec(struct net_device *dev, struct in6_addr *addr); | ||
93 | extern void ipv6_mc_up(struct inet6_dev *idev); | ||
94 | extern void ipv6_mc_down(struct inet6_dev *idev); | ||
95 | extern void ipv6_mc_init_dev(struct inet6_dev *idev); | ||
96 | extern void ipv6_mc_destroy_dev(struct inet6_dev *idev); | ||
97 | extern void addrconf_dad_failure(struct inet6_ifaddr *ifp); | ||
98 | |||
99 | extern int ipv6_chk_mcast_addr(struct net_device *dev, struct in6_addr *group, | ||
100 | struct in6_addr *src_addr); | ||
101 | extern int ipv6_is_mld(struct sk_buff *skb, int nexthdr); | ||
102 | |||
103 | extern void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len); | ||
104 | |||
105 | extern int ipv6_get_hoplimit(struct net_device *dev); | ||
106 | |||
107 | /* | ||
108 | * anycast prototypes (anycast.c) | ||
109 | */ | ||
110 | extern int ipv6_sock_ac_join(struct sock *sk,int ifindex,struct in6_addr *addr); | ||
111 | extern int ipv6_sock_ac_drop(struct sock *sk,int ifindex,struct in6_addr *addr); | ||
112 | extern void ipv6_sock_ac_close(struct sock *sk); | ||
113 | extern int inet6_ac_check(struct sock *sk, struct in6_addr *addr, int ifindex); | ||
114 | |||
115 | extern int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr); | ||
116 | extern int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr); | ||
117 | extern int ipv6_chk_acast_addr(struct net_device *dev, struct in6_addr *addr); | ||
118 | |||
119 | |||
120 | /* Device notifier */ | ||
121 | extern int register_inet6addr_notifier(struct notifier_block *nb); | ||
122 | extern int unregister_inet6addr_notifier(struct notifier_block *nb); | ||
123 | |||
124 | static inline struct inet6_dev * | ||
125 | __in6_dev_get(struct net_device *dev) | ||
126 | { | ||
127 | return (struct inet6_dev *)dev->ip6_ptr; | ||
128 | } | ||
129 | |||
130 | extern rwlock_t addrconf_lock; | ||
131 | |||
132 | static inline struct inet6_dev * | ||
133 | in6_dev_get(struct net_device *dev) | ||
134 | { | ||
135 | struct inet6_dev *idev = NULL; | ||
136 | read_lock(&addrconf_lock); | ||
137 | idev = dev->ip6_ptr; | ||
138 | if (idev) | ||
139 | atomic_inc(&idev->refcnt); | ||
140 | read_unlock(&addrconf_lock); | ||
141 | return idev; | ||
142 | } | ||
143 | |||
144 | extern void in6_dev_finish_destroy(struct inet6_dev *idev); | ||
145 | |||
146 | static inline void | ||
147 | in6_dev_put(struct inet6_dev *idev) | ||
148 | { | ||
149 | if (atomic_dec_and_test(&idev->refcnt)) | ||
150 | in6_dev_finish_destroy(idev); | ||
151 | } | ||
152 | |||
153 | #define __in6_dev_put(idev) atomic_dec(&(idev)->refcnt) | ||
154 | #define in6_dev_hold(idev) atomic_inc(&(idev)->refcnt) | ||
155 | |||
156 | |||
157 | extern void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp); | ||
158 | |||
159 | static inline void in6_ifa_put(struct inet6_ifaddr *ifp) | ||
160 | { | ||
161 | if (atomic_dec_and_test(&ifp->refcnt)) | ||
162 | inet6_ifa_finish_destroy(ifp); | ||
163 | } | ||
164 | |||
165 | #define __in6_ifa_put(ifp) atomic_dec(&(ifp)->refcnt) | ||
166 | #define in6_ifa_hold(ifp) atomic_inc(&(ifp)->refcnt) | ||
167 | |||
168 | |||
169 | extern void addrconf_forwarding_on(void); | ||
170 | /* | ||
171 | * Hash function taken from net_alias.c | ||
172 | */ | ||
173 | |||
174 | static __inline__ u8 ipv6_addr_hash(const struct in6_addr *addr) | ||
175 | { | ||
176 | __u32 word; | ||
177 | |||
178 | /* | ||
179 | * We perform the hash function over the last 64 bits of the address | ||
180 | * This will include the IEEE address token on links that support it. | ||
181 | */ | ||
182 | |||
183 | word = addr->s6_addr32[2] ^ addr->s6_addr32[3]; | ||
184 | word ^= (word >> 16); | ||
185 | word ^= (word >> 8); | ||
186 | |||
187 | return ((word ^ (word >> 4)) & 0x0f); | ||
188 | } | ||
189 | |||
190 | /* | ||
191 | * compute link-local solicited-node multicast address | ||
192 | */ | ||
193 | |||
194 | static inline void addrconf_addr_solict_mult(const struct in6_addr *addr, | ||
195 | struct in6_addr *solicited) | ||
196 | { | ||
197 | ipv6_addr_set(solicited, | ||
198 | __constant_htonl(0xFF020000), 0, | ||
199 | __constant_htonl(0x1), | ||
200 | __constant_htonl(0xFF000000) | addr->s6_addr32[3]); | ||
201 | } | ||
202 | |||
203 | |||
204 | static inline void ipv6_addr_all_nodes(struct in6_addr *addr) | ||
205 | { | ||
206 | ipv6_addr_set(addr, | ||
207 | __constant_htonl(0xFF020000), 0, 0, | ||
208 | __constant_htonl(0x1)); | ||
209 | } | ||
210 | |||
211 | static inline void ipv6_addr_all_routers(struct in6_addr *addr) | ||
212 | { | ||
213 | ipv6_addr_set(addr, | ||
214 | __constant_htonl(0xFF020000), 0, 0, | ||
215 | __constant_htonl(0x2)); | ||
216 | } | ||
217 | |||
218 | static inline int ipv6_addr_is_multicast(const struct in6_addr *addr) | ||
219 | { | ||
220 | return (addr->s6_addr32[0] & __constant_htonl(0xFF000000)) == __constant_htonl(0xFF000000); | ||
221 | } | ||
222 | |||
223 | static inline int ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr) | ||
224 | { | ||
225 | return (addr->s6_addr32[0] == htonl(0xff020000) && | ||
226 | addr->s6_addr32[1] == 0 && | ||
227 | addr->s6_addr32[2] == 0 && | ||
228 | addr->s6_addr32[3] == htonl(0x00000001)); | ||
229 | } | ||
230 | |||
231 | static inline int ipv6_addr_is_ll_all_routers(const struct in6_addr *addr) | ||
232 | { | ||
233 | return (addr->s6_addr32[0] == htonl(0xff020000) && | ||
234 | addr->s6_addr32[1] == 0 && | ||
235 | addr->s6_addr32[2] == 0 && | ||
236 | addr->s6_addr32[3] == htonl(0x00000002)); | ||
237 | } | ||
238 | |||
239 | #endif | ||
240 | #endif | ||
diff --git a/include/net/af_unix.h b/include/net/af_unix.h new file mode 100644 index 000000000000..b60b3846b9d1 --- /dev/null +++ b/include/net/af_unix.h | |||
@@ -0,0 +1,78 @@ | |||
1 | #ifndef __LINUX_NET_AFUNIX_H | ||
2 | #define __LINUX_NET_AFUNIX_H | ||
3 | extern void unix_inflight(struct file *fp); | ||
4 | extern void unix_notinflight(struct file *fp); | ||
5 | extern void unix_gc(void); | ||
6 | |||
7 | #define UNIX_HASH_SIZE 256 | ||
8 | |||
9 | extern struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; | ||
10 | extern rwlock_t unix_table_lock; | ||
11 | |||
12 | extern atomic_t unix_tot_inflight; | ||
13 | |||
14 | static inline struct sock *first_unix_socket(int *i) | ||
15 | { | ||
16 | for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) { | ||
17 | if (!hlist_empty(&unix_socket_table[*i])) | ||
18 | return __sk_head(&unix_socket_table[*i]); | ||
19 | } | ||
20 | return NULL; | ||
21 | } | ||
22 | |||
23 | static inline struct sock *next_unix_socket(int *i, struct sock *s) | ||
24 | { | ||
25 | struct sock *next = sk_next(s); | ||
26 | /* More in this chain? */ | ||
27 | if (next) | ||
28 | return next; | ||
29 | /* Look for next non-empty chain. */ | ||
30 | for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) { | ||
31 | if (!hlist_empty(&unix_socket_table[*i])) | ||
32 | return __sk_head(&unix_socket_table[*i]); | ||
33 | } | ||
34 | return NULL; | ||
35 | } | ||
36 | |||
37 | #define forall_unix_sockets(i, s) \ | ||
38 | for (s = first_unix_socket(&(i)); s; s = next_unix_socket(&(i),(s))) | ||
39 | |||
40 | struct unix_address { | ||
41 | atomic_t refcnt; | ||
42 | int len; | ||
43 | unsigned hash; | ||
44 | struct sockaddr_un name[0]; | ||
45 | }; | ||
46 | |||
47 | struct unix_skb_parms { | ||
48 | struct ucred creds; /* Skb credentials */ | ||
49 | struct scm_fp_list *fp; /* Passed files */ | ||
50 | }; | ||
51 | |||
52 | #define UNIXCB(skb) (*(struct unix_skb_parms*)&((skb)->cb)) | ||
53 | #define UNIXCREDS(skb) (&UNIXCB((skb)).creds) | ||
54 | |||
55 | #define unix_state_rlock(s) read_lock(&unix_sk(s)->lock) | ||
56 | #define unix_state_runlock(s) read_unlock(&unix_sk(s)->lock) | ||
57 | #define unix_state_wlock(s) write_lock(&unix_sk(s)->lock) | ||
58 | #define unix_state_wunlock(s) write_unlock(&unix_sk(s)->lock) | ||
59 | |||
60 | #ifdef __KERNEL__ | ||
61 | /* The AF_UNIX socket */ | ||
62 | struct unix_sock { | ||
63 | /* WARNING: sk has to be the first member */ | ||
64 | struct sock sk; | ||
65 | struct unix_address *addr; | ||
66 | struct dentry *dentry; | ||
67 | struct vfsmount *mnt; | ||
68 | struct semaphore readsem; | ||
69 | struct sock *peer; | ||
70 | struct sock *other; | ||
71 | struct sock *gc_tree; | ||
72 | atomic_t inflight; | ||
73 | rwlock_t lock; | ||
74 | wait_queue_head_t peer_wait; | ||
75 | }; | ||
76 | #define unix_sk(__sk) ((struct unix_sock *)__sk) | ||
77 | #endif | ||
78 | #endif | ||
diff --git a/include/net/ah.h b/include/net/ah.h new file mode 100644 index 000000000000..ceff00afae09 --- /dev/null +++ b/include/net/ah.h | |||
@@ -0,0 +1,35 @@ | |||
1 | #ifndef _NET_AH_H | ||
2 | #define _NET_AH_H | ||
3 | |||
4 | #include <net/xfrm.h> | ||
5 | |||
6 | /* This is the maximum truncated ICV length that we know of. */ | ||
7 | #define MAX_AH_AUTH_LEN 12 | ||
8 | |||
9 | struct ah_data | ||
10 | { | ||
11 | u8 *key; | ||
12 | int key_len; | ||
13 | u8 *work_icv; | ||
14 | int icv_full_len; | ||
15 | int icv_trunc_len; | ||
16 | |||
17 | void (*icv)(struct ah_data*, | ||
18 | struct sk_buff *skb, u8 *icv); | ||
19 | |||
20 | struct crypto_tfm *tfm; | ||
21 | }; | ||
22 | |||
23 | static inline void | ||
24 | ah_hmac_digest(struct ah_data *ahp, struct sk_buff *skb, u8 *auth_data) | ||
25 | { | ||
26 | struct crypto_tfm *tfm = ahp->tfm; | ||
27 | |||
28 | memset(auth_data, 0, ahp->icv_trunc_len); | ||
29 | crypto_hmac_init(tfm, ahp->key, &ahp->key_len); | ||
30 | skb_icv_walk(skb, tfm, 0, skb->len, crypto_hmac_update); | ||
31 | crypto_hmac_final(tfm, ahp->key, &ahp->key_len, ahp->work_icv); | ||
32 | memcpy(auth_data, ahp->work_icv, ahp->icv_trunc_len); | ||
33 | } | ||
34 | |||
35 | #endif | ||
diff --git a/include/net/arp.h b/include/net/arp.h new file mode 100644 index 000000000000..a1f09fad6a52 --- /dev/null +++ b/include/net/arp.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /* linux/net/inet/arp.h */ | ||
2 | #ifndef _ARP_H | ||
3 | #define _ARP_H | ||
4 | |||
5 | #include <linux/if_arp.h> | ||
6 | #include <net/neighbour.h> | ||
7 | |||
8 | #define HAVE_ARP_CREATE | ||
9 | |||
10 | extern struct neigh_table arp_tbl; | ||
11 | |||
12 | extern void arp_init(void); | ||
13 | extern int arp_rcv(struct sk_buff *skb, struct net_device *dev, | ||
14 | struct packet_type *pt); | ||
15 | extern int arp_find(unsigned char *haddr, struct sk_buff *skb); | ||
16 | extern int arp_ioctl(unsigned int cmd, void __user *arg); | ||
17 | extern void arp_send(int type, int ptype, u32 dest_ip, | ||
18 | struct net_device *dev, u32 src_ip, | ||
19 | unsigned char *dest_hw, unsigned char *src_hw, unsigned char *th); | ||
20 | extern int arp_bind_neighbour(struct dst_entry *dst); | ||
21 | extern int arp_mc_map(u32 addr, u8 *haddr, struct net_device *dev, int dir); | ||
22 | extern void arp_ifdown(struct net_device *dev); | ||
23 | |||
24 | extern struct sk_buff *arp_create(int type, int ptype, u32 dest_ip, | ||
25 | struct net_device *dev, u32 src_ip, | ||
26 | unsigned char *dest_hw, unsigned char *src_hw, | ||
27 | unsigned char *target_hw); | ||
28 | extern void arp_xmit(struct sk_buff *skb); | ||
29 | |||
30 | extern struct neigh_ops arp_broken_ops; | ||
31 | |||
32 | #endif /* _ARP_H */ | ||
diff --git a/include/net/atmclip.h b/include/net/atmclip.h new file mode 100644 index 000000000000..47048b1d179a --- /dev/null +++ b/include/net/atmclip.h | |||
@@ -0,0 +1,62 @@ | |||
1 | /* net/atm/atmarp.h - RFC1577 ATM ARP */ | ||
2 | |||
3 | /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ | ||
4 | |||
5 | |||
6 | #ifndef _ATMCLIP_H | ||
7 | #define _ATMCLIP_H | ||
8 | |||
9 | #include <linux/netdevice.h> | ||
10 | #include <linux/skbuff.h> | ||
11 | #include <linux/atm.h> | ||
12 | #include <linux/atmdev.h> | ||
13 | #include <linux/atmarp.h> | ||
14 | #include <linux/spinlock.h> | ||
15 | #include <net/neighbour.h> | ||
16 | |||
17 | |||
18 | #define CLIP_VCC(vcc) ((struct clip_vcc *) ((vcc)->user_back)) | ||
19 | #define NEIGH2ENTRY(neigh) ((struct atmarp_entry *) (neigh)->primary_key) | ||
20 | |||
21 | |||
22 | struct clip_vcc { | ||
23 | struct atm_vcc *vcc; /* VCC descriptor */ | ||
24 | struct atmarp_entry *entry; /* ATMARP table entry, NULL if IP addr. | ||
25 | isn't known yet */ | ||
26 | int xoff; /* 1 if send buffer is full */ | ||
27 | unsigned char encap; /* 0: NULL, 1: LLC/SNAP */ | ||
28 | unsigned long last_use; /* last send or receive operation */ | ||
29 | unsigned long idle_timeout; /* keep open idle for so many jiffies*/ | ||
30 | void (*old_push)(struct atm_vcc *vcc,struct sk_buff *skb); | ||
31 | /* keep old push fn for chaining */ | ||
32 | void (*old_pop)(struct atm_vcc *vcc,struct sk_buff *skb); | ||
33 | /* keep old pop fn for chaining */ | ||
34 | struct clip_vcc *next; /* next VCC */ | ||
35 | }; | ||
36 | |||
37 | |||
38 | struct atmarp_entry { | ||
39 | u32 ip; /* IP address */ | ||
40 | struct clip_vcc *vccs; /* active VCCs; NULL if resolution is | ||
41 | pending */ | ||
42 | unsigned long expires; /* entry expiration time */ | ||
43 | struct neighbour *neigh; /* neighbour back-pointer */ | ||
44 | }; | ||
45 | |||
46 | |||
47 | #define PRIV(dev) ((struct clip_priv *) netdev_priv(dev)) | ||
48 | |||
49 | |||
50 | struct clip_priv { | ||
51 | int number; /* for convenience ... */ | ||
52 | spinlock_t xoff_lock; /* ensures that pop is atomic (SMP) */ | ||
53 | struct net_device_stats stats; | ||
54 | struct net_device *next; /* next CLIP interface */ | ||
55 | }; | ||
56 | |||
57 | |||
58 | #ifdef __KERNEL__ | ||
59 | extern struct neigh_table *clip_tbl_hook; | ||
60 | #endif | ||
61 | |||
62 | #endif | ||
diff --git a/include/net/ax25.h b/include/net/ax25.h new file mode 100644 index 000000000000..fb95ecb6fe03 --- /dev/null +++ b/include/net/ax25.h | |||
@@ -0,0 +1,385 @@ | |||
1 | /* | ||
2 | * Declarations of AX.25 type objects. | ||
3 | * | ||
4 | * Alan Cox (GW4PTS) 10/11/93 | ||
5 | */ | ||
6 | #ifndef _AX25_H | ||
7 | #define _AX25_H | ||
8 | |||
9 | #include <linux/config.h> | ||
10 | #include <linux/ax25.h> | ||
11 | #include <linux/spinlock.h> | ||
12 | #include <linux/timer.h> | ||
13 | #include <linux/list.h> | ||
14 | #include <asm/atomic.h> | ||
15 | |||
16 | #define AX25_T1CLAMPLO 1 | ||
17 | #define AX25_T1CLAMPHI (30 * HZ) | ||
18 | |||
19 | #define AX25_BPQ_HEADER_LEN 16 | ||
20 | #define AX25_KISS_HEADER_LEN 1 | ||
21 | |||
22 | #define AX25_HEADER_LEN 17 | ||
23 | #define AX25_ADDR_LEN 7 | ||
24 | #define AX25_DIGI_HEADER_LEN (AX25_MAX_DIGIS * AX25_ADDR_LEN) | ||
25 | #define AX25_MAX_HEADER_LEN (AX25_HEADER_LEN + AX25_DIGI_HEADER_LEN) | ||
26 | |||
27 | /* AX.25 Protocol IDs */ | ||
28 | #define AX25_P_ROSE 0x01 | ||
29 | #define AX25_P_IP 0xCC | ||
30 | #define AX25_P_ARP 0xCD | ||
31 | #define AX25_P_TEXT 0xF0 | ||
32 | #define AX25_P_NETROM 0xCF | ||
33 | #define AX25_P_SEGMENT 0x08 | ||
34 | |||
35 | /* AX.25 Segment control values */ | ||
36 | #define AX25_SEG_REM 0x7F | ||
37 | #define AX25_SEG_FIRST 0x80 | ||
38 | |||
39 | #define AX25_CBIT 0x80 /* Command/Response bit */ | ||
40 | #define AX25_EBIT 0x01 /* HDLC Address Extension bit */ | ||
41 | #define AX25_HBIT 0x80 /* Has been repeated bit */ | ||
42 | |||
43 | #define AX25_SSSID_SPARE 0x60 /* Unused bits in SSID for standard AX.25 */ | ||
44 | #define AX25_ESSID_SPARE 0x20 /* Unused bits in SSID for extended AX.25 */ | ||
45 | #define AX25_DAMA_FLAG 0x20 /* Well, it is *NOT* unused! (dl1bke 951121 */ | ||
46 | |||
47 | #define AX25_COND_ACK_PENDING 0x01 | ||
48 | #define AX25_COND_REJECT 0x02 | ||
49 | #define AX25_COND_PEER_RX_BUSY 0x04 | ||
50 | #define AX25_COND_OWN_RX_BUSY 0x08 | ||
51 | #define AX25_COND_DAMA_MODE 0x10 | ||
52 | |||
53 | #ifndef _LINUX_NETDEVICE_H | ||
54 | #include <linux/netdevice.h> | ||
55 | #endif | ||
56 | |||
57 | /* Upper sub-layer (LAPB) definitions */ | ||
58 | |||
59 | /* Control field templates */ | ||
60 | #define AX25_I 0x00 /* Information frames */ | ||
61 | #define AX25_S 0x01 /* Supervisory frames */ | ||
62 | #define AX25_RR 0x01 /* Receiver ready */ | ||
63 | #define AX25_RNR 0x05 /* Receiver not ready */ | ||
64 | #define AX25_REJ 0x09 /* Reject */ | ||
65 | #define AX25_U 0x03 /* Unnumbered frames */ | ||
66 | #define AX25_SABM 0x2f /* Set Asynchronous Balanced Mode */ | ||
67 | #define AX25_SABME 0x6f /* Set Asynchronous Balanced Mode Extended */ | ||
68 | #define AX25_DISC 0x43 /* Disconnect */ | ||
69 | #define AX25_DM 0x0f /* Disconnected mode */ | ||
70 | #define AX25_UA 0x63 /* Unnumbered acknowledge */ | ||
71 | #define AX25_FRMR 0x87 /* Frame reject */ | ||
72 | #define AX25_UI 0x03 /* Unnumbered information */ | ||
73 | #define AX25_XID 0xaf /* Exchange information */ | ||
74 | #define AX25_TEST 0xe3 /* Test */ | ||
75 | |||
76 | #define AX25_PF 0x10 /* Poll/final bit for standard AX.25 */ | ||
77 | #define AX25_EPF 0x01 /* Poll/final bit for extended AX.25 */ | ||
78 | |||
79 | #define AX25_ILLEGAL 0x100 /* Impossible to be a real frame type */ | ||
80 | |||
81 | #define AX25_POLLOFF 0 | ||
82 | #define AX25_POLLON 1 | ||
83 | |||
84 | /* AX25 L2 C-bit */ | ||
85 | #define AX25_COMMAND 1 | ||
86 | #define AX25_RESPONSE 2 | ||
87 | |||
88 | /* Define Link State constants. */ | ||
89 | |||
90 | enum { | ||
91 | AX25_STATE_0, | ||
92 | AX25_STATE_1, | ||
93 | AX25_STATE_2, | ||
94 | AX25_STATE_3, | ||
95 | AX25_STATE_4 | ||
96 | }; | ||
97 | |||
98 | #define AX25_MODULUS 8 /* Standard AX.25 modulus */ | ||
99 | #define AX25_EMODULUS 128 /* Extended AX.25 modulus */ | ||
100 | |||
101 | enum { | ||
102 | AX25_PROTO_STD_SIMPLEX, | ||
103 | AX25_PROTO_STD_DUPLEX, | ||
104 | AX25_PROTO_DAMA_SLAVE, | ||
105 | AX25_PROTO_DAMA_MASTER | ||
106 | }; | ||
107 | |||
108 | enum { | ||
109 | AX25_VALUES_IPDEFMODE, /* 0=DG 1=VC */ | ||
110 | AX25_VALUES_AXDEFMODE, /* 0=Normal 1=Extended Seq Nos */ | ||
111 | AX25_VALUES_BACKOFF, /* 0=None 1=Linear 2=Exponential */ | ||
112 | AX25_VALUES_CONMODE, /* Allow connected modes - 0=No 1=no "PID text" 2=all PIDs */ | ||
113 | AX25_VALUES_WINDOW, /* Default window size for standard AX.25 */ | ||
114 | AX25_VALUES_EWINDOW, /* Default window size for extended AX.25 */ | ||
115 | AX25_VALUES_T1, /* Default T1 timeout value */ | ||
116 | AX25_VALUES_T2, /* Default T2 timeout value */ | ||
117 | AX25_VALUES_T3, /* Default T3 timeout value */ | ||
118 | AX25_VALUES_IDLE, /* Connected mode idle timer */ | ||
119 | AX25_VALUES_N2, /* Default N2 value */ | ||
120 | AX25_VALUES_PACLEN, /* AX.25 MTU */ | ||
121 | AX25_VALUES_PROTOCOL, /* Std AX.25, DAMA Slave, DAMA Master */ | ||
122 | AX25_VALUES_DS_TIMEOUT, /* DAMA Slave timeout */ | ||
123 | AX25_MAX_VALUES /* THIS MUST REMAIN THE LAST ENTRY OF THIS LIST */ | ||
124 | }; | ||
125 | |||
126 | #define AX25_DEF_IPDEFMODE 0 /* Datagram */ | ||
127 | #define AX25_DEF_AXDEFMODE 0 /* Normal */ | ||
128 | #define AX25_DEF_BACKOFF 1 /* Linear backoff */ | ||
129 | #define AX25_DEF_CONMODE 2 /* Connected mode allowed */ | ||
130 | #define AX25_DEF_WINDOW 2 /* Window=2 */ | ||
131 | #define AX25_DEF_EWINDOW 32 /* Module-128 Window=32 */ | ||
132 | #define AX25_DEF_T1 (10 * HZ) /* T1=10s */ | ||
133 | #define AX25_DEF_T2 (3 * HZ) /* T2=3s */ | ||
134 | #define AX25_DEF_T3 (300 * HZ) /* T3=300s */ | ||
135 | #define AX25_DEF_N2 10 /* N2=10 */ | ||
136 | #define AX25_DEF_IDLE (0 * 60 * HZ) /* Idle=None */ | ||
137 | #define AX25_DEF_PACLEN 256 /* Paclen=256 */ | ||
138 | #define AX25_DEF_PROTOCOL AX25_PROTO_STD_SIMPLEX /* Standard AX.25 */ | ||
139 | #define AX25_DEF_DS_TIMEOUT (3 * 60 * HZ) /* DAMA timeout 3 minutes */ | ||
140 | |||
141 | typedef struct ax25_uid_assoc { | ||
142 | struct ax25_uid_assoc *next; | ||
143 | uid_t uid; | ||
144 | ax25_address call; | ||
145 | } ax25_uid_assoc; | ||
146 | |||
147 | typedef struct { | ||
148 | ax25_address calls[AX25_MAX_DIGIS]; | ||
149 | unsigned char repeated[AX25_MAX_DIGIS]; | ||
150 | unsigned char ndigi; | ||
151 | char lastrepeat; | ||
152 | } ax25_digi; | ||
153 | |||
154 | typedef struct ax25_route { | ||
155 | struct ax25_route *next; | ||
156 | atomic_t ref; | ||
157 | ax25_address callsign; | ||
158 | struct net_device *dev; | ||
159 | ax25_digi *digipeat; | ||
160 | char ip_mode; | ||
161 | struct timer_list timer; | ||
162 | } ax25_route; | ||
163 | |||
164 | typedef struct { | ||
165 | char slave; /* slave_mode? */ | ||
166 | struct timer_list slave_timer; /* timeout timer */ | ||
167 | unsigned short slave_timeout; /* when? */ | ||
168 | } ax25_dama_info; | ||
169 | |||
170 | struct ctl_table; | ||
171 | |||
172 | typedef struct ax25_dev { | ||
173 | struct ax25_dev *next; | ||
174 | struct net_device *dev; | ||
175 | struct net_device *forward; | ||
176 | struct ctl_table *systable; | ||
177 | int values[AX25_MAX_VALUES]; | ||
178 | #if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER) | ||
179 | ax25_dama_info dama; | ||
180 | #endif | ||
181 | } ax25_dev; | ||
182 | |||
183 | typedef struct ax25_cb { | ||
184 | struct hlist_node ax25_node; | ||
185 | ax25_address source_addr, dest_addr; | ||
186 | ax25_digi *digipeat; | ||
187 | ax25_dev *ax25_dev; | ||
188 | unsigned char iamdigi; | ||
189 | unsigned char state, modulus, pidincl; | ||
190 | unsigned short vs, vr, va; | ||
191 | unsigned char condition, backoff; | ||
192 | unsigned char n2, n2count; | ||
193 | struct timer_list t1timer, t2timer, t3timer, idletimer; | ||
194 | unsigned long t1, t2, t3, idle, rtt; | ||
195 | unsigned short paclen, fragno, fraglen; | ||
196 | struct sk_buff_head write_queue; | ||
197 | struct sk_buff_head reseq_queue; | ||
198 | struct sk_buff_head ack_queue; | ||
199 | struct sk_buff_head frag_queue; | ||
200 | unsigned char window; | ||
201 | struct timer_list timer, dtimer; | ||
202 | struct sock *sk; /* Backlink to socket */ | ||
203 | atomic_t refcount; | ||
204 | } ax25_cb; | ||
205 | |||
206 | #define ax25_sk(__sk) ((ax25_cb *)(__sk)->sk_protinfo) | ||
207 | |||
208 | #define ax25_for_each(__ax25, node, list) \ | ||
209 | hlist_for_each_entry(__ax25, node, list, ax25_node) | ||
210 | |||
211 | #define ax25_cb_hold(__ax25) \ | ||
212 | atomic_inc(&((__ax25)->refcount)) | ||
213 | |||
214 | static __inline__ void ax25_cb_put(ax25_cb *ax25) | ||
215 | { | ||
216 | if (atomic_dec_and_test(&ax25->refcount)) { | ||
217 | if (ax25->digipeat) | ||
218 | kfree(ax25->digipeat); | ||
219 | kfree(ax25); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | /* af_ax25.c */ | ||
224 | extern struct hlist_head ax25_list; | ||
225 | extern spinlock_t ax25_list_lock; | ||
226 | extern void ax25_cb_add(ax25_cb *); | ||
227 | struct sock *ax25_find_listener(ax25_address *, int, struct net_device *, int); | ||
228 | struct sock *ax25_get_socket(ax25_address *, ax25_address *, int); | ||
229 | extern ax25_cb *ax25_find_cb(ax25_address *, ax25_address *, ax25_digi *, struct net_device *); | ||
230 | extern void ax25_send_to_raw(ax25_address *, struct sk_buff *, int); | ||
231 | extern void ax25_destroy_socket(ax25_cb *); | ||
232 | extern ax25_cb *ax25_create_cb(void); | ||
233 | extern void ax25_fillin_cb(ax25_cb *, ax25_dev *); | ||
234 | extern struct sock *ax25_make_new(struct sock *, struct ax25_dev *); | ||
235 | |||
236 | /* ax25_addr.c */ | ||
237 | extern ax25_address null_ax25_address; | ||
238 | extern char *ax2asc(ax25_address *); | ||
239 | extern ax25_address *asc2ax(char *); | ||
240 | extern int ax25cmp(ax25_address *, ax25_address *); | ||
241 | extern int ax25digicmp(ax25_digi *, ax25_digi *); | ||
242 | extern unsigned char *ax25_addr_parse(unsigned char *, int, ax25_address *, ax25_address *, ax25_digi *, int *, int *); | ||
243 | extern int ax25_addr_build(unsigned char *, ax25_address *, ax25_address *, ax25_digi *, int, int); | ||
244 | extern int ax25_addr_size(ax25_digi *); | ||
245 | extern void ax25_digi_invert(ax25_digi *, ax25_digi *); | ||
246 | |||
247 | /* ax25_dev.c */ | ||
248 | extern ax25_dev *ax25_dev_list; | ||
249 | extern spinlock_t ax25_dev_lock; | ||
250 | |||
251 | static inline ax25_dev *ax25_dev_ax25dev(struct net_device *dev) | ||
252 | { | ||
253 | return dev->ax25_ptr; | ||
254 | } | ||
255 | |||
256 | extern ax25_dev *ax25_addr_ax25dev(ax25_address *); | ||
257 | extern void ax25_dev_device_up(struct net_device *); | ||
258 | extern void ax25_dev_device_down(struct net_device *); | ||
259 | extern int ax25_fwd_ioctl(unsigned int, struct ax25_fwd_struct *); | ||
260 | extern struct net_device *ax25_fwd_dev(struct net_device *); | ||
261 | extern void ax25_dev_free(void); | ||
262 | |||
263 | /* ax25_ds_in.c */ | ||
264 | extern int ax25_ds_frame_in(ax25_cb *, struct sk_buff *, int); | ||
265 | |||
266 | /* ax25_ds_subr.c */ | ||
267 | extern void ax25_ds_nr_error_recovery(ax25_cb *); | ||
268 | extern void ax25_ds_enquiry_response(ax25_cb *); | ||
269 | extern void ax25_ds_establish_data_link(ax25_cb *); | ||
270 | extern void ax25_dev_dama_off(ax25_dev *); | ||
271 | extern void ax25_dama_on(ax25_cb *); | ||
272 | extern void ax25_dama_off(ax25_cb *); | ||
273 | |||
274 | /* ax25_ds_timer.c */ | ||
275 | extern void ax25_ds_set_timer(ax25_dev *); | ||
276 | extern void ax25_ds_del_timer(ax25_dev *); | ||
277 | extern void ax25_ds_timer(ax25_cb *); | ||
278 | extern void ax25_ds_t1_timeout(ax25_cb *); | ||
279 | extern void ax25_ds_heartbeat_expiry(ax25_cb *); | ||
280 | extern void ax25_ds_t3timer_expiry(ax25_cb *); | ||
281 | extern void ax25_ds_idletimer_expiry(ax25_cb *); | ||
282 | |||
283 | /* ax25_iface.c */ | ||
284 | extern int ax25_protocol_register(unsigned int, int (*)(struct sk_buff *, ax25_cb *)); | ||
285 | extern void ax25_protocol_release(unsigned int); | ||
286 | extern int ax25_linkfail_register(void (*)(ax25_cb *, int)); | ||
287 | extern void ax25_linkfail_release(void (*)(ax25_cb *, int)); | ||
288 | extern int ax25_listen_register(ax25_address *, struct net_device *); | ||
289 | extern void ax25_listen_release(ax25_address *, struct net_device *); | ||
290 | extern int (*ax25_protocol_function(unsigned int))(struct sk_buff *, ax25_cb *); | ||
291 | extern int ax25_listen_mine(ax25_address *, struct net_device *); | ||
292 | extern void ax25_link_failed(ax25_cb *, int); | ||
293 | extern int ax25_protocol_is_registered(unsigned int); | ||
294 | |||
295 | /* ax25_in.c */ | ||
296 | extern int ax25_rx_iframe(ax25_cb *, struct sk_buff *); | ||
297 | extern int ax25_kiss_rcv(struct sk_buff *, struct net_device *, struct packet_type *); | ||
298 | |||
299 | /* ax25_ip.c */ | ||
300 | extern int ax25_encapsulate(struct sk_buff *, struct net_device *, unsigned short, void *, void *, unsigned int); | ||
301 | extern int ax25_rebuild_header(struct sk_buff *); | ||
302 | |||
303 | /* ax25_out.c */ | ||
304 | extern ax25_cb *ax25_send_frame(struct sk_buff *, int, ax25_address *, ax25_address *, ax25_digi *, struct net_device *); | ||
305 | extern void ax25_output(ax25_cb *, int, struct sk_buff *); | ||
306 | extern void ax25_kick(ax25_cb *); | ||
307 | extern void ax25_transmit_buffer(ax25_cb *, struct sk_buff *, int); | ||
308 | extern void ax25_queue_xmit(struct sk_buff *); | ||
309 | extern int ax25_check_iframes_acked(ax25_cb *, unsigned short); | ||
310 | |||
311 | /* ax25_route.c */ | ||
312 | extern void ax25_rt_device_down(struct net_device *); | ||
313 | extern int ax25_rt_ioctl(unsigned int, void __user *); | ||
314 | extern struct file_operations ax25_route_fops; | ||
315 | extern int ax25_rt_autobind(ax25_cb *, ax25_address *); | ||
316 | extern ax25_route *ax25_rt_find_route(ax25_route *, ax25_address *, | ||
317 | struct net_device *); | ||
318 | extern struct sk_buff *ax25_rt_build_path(struct sk_buff *, ax25_address *, ax25_address *, ax25_digi *); | ||
319 | extern void ax25_rt_free(void); | ||
320 | |||
321 | static inline void ax25_put_route(ax25_route *ax25_rt) | ||
322 | { | ||
323 | atomic_dec(&ax25_rt->ref); | ||
324 | } | ||
325 | |||
326 | /* ax25_std_in.c */ | ||
327 | extern int ax25_std_frame_in(ax25_cb *, struct sk_buff *, int); | ||
328 | |||
329 | /* ax25_std_subr.c */ | ||
330 | extern void ax25_std_nr_error_recovery(ax25_cb *); | ||
331 | extern void ax25_std_establish_data_link(ax25_cb *); | ||
332 | extern void ax25_std_transmit_enquiry(ax25_cb *); | ||
333 | extern void ax25_std_enquiry_response(ax25_cb *); | ||
334 | extern void ax25_std_timeout_response(ax25_cb *); | ||
335 | |||
336 | /* ax25_std_timer.c */ | ||
337 | extern void ax25_std_heartbeat_expiry(ax25_cb *); | ||
338 | extern void ax25_std_t1timer_expiry(ax25_cb *); | ||
339 | extern void ax25_std_t2timer_expiry(ax25_cb *); | ||
340 | extern void ax25_std_t3timer_expiry(ax25_cb *); | ||
341 | extern void ax25_std_idletimer_expiry(ax25_cb *); | ||
342 | |||
343 | /* ax25_subr.c */ | ||
344 | extern void ax25_clear_queues(ax25_cb *); | ||
345 | extern void ax25_frames_acked(ax25_cb *, unsigned short); | ||
346 | extern void ax25_requeue_frames(ax25_cb *); | ||
347 | extern int ax25_validate_nr(ax25_cb *, unsigned short); | ||
348 | extern int ax25_decode(ax25_cb *, struct sk_buff *, int *, int *, int *); | ||
349 | extern void ax25_send_control(ax25_cb *, int, int, int); | ||
350 | extern void ax25_return_dm(struct net_device *, ax25_address *, ax25_address *, ax25_digi *); | ||
351 | extern void ax25_calculate_t1(ax25_cb *); | ||
352 | extern void ax25_calculate_rtt(ax25_cb *); | ||
353 | extern void ax25_disconnect(ax25_cb *, int); | ||
354 | |||
355 | /* ax25_timer.c */ | ||
356 | extern void ax25_start_heartbeat(ax25_cb *); | ||
357 | extern void ax25_start_t1timer(ax25_cb *); | ||
358 | extern void ax25_start_t2timer(ax25_cb *); | ||
359 | extern void ax25_start_t3timer(ax25_cb *); | ||
360 | extern void ax25_start_idletimer(ax25_cb *); | ||
361 | extern void ax25_stop_heartbeat(ax25_cb *); | ||
362 | extern void ax25_stop_t1timer(ax25_cb *); | ||
363 | extern void ax25_stop_t2timer(ax25_cb *); | ||
364 | extern void ax25_stop_t3timer(ax25_cb *); | ||
365 | extern void ax25_stop_idletimer(ax25_cb *); | ||
366 | extern int ax25_t1timer_running(ax25_cb *); | ||
367 | extern unsigned long ax25_display_timer(struct timer_list *); | ||
368 | |||
369 | /* ax25_uid.c */ | ||
370 | extern int ax25_uid_policy; | ||
371 | extern ax25_address *ax25_findbyuid(uid_t); | ||
372 | extern int ax25_uid_ioctl(int, struct sockaddr_ax25 *); | ||
373 | extern struct file_operations ax25_uid_fops; | ||
374 | extern void ax25_uid_free(void); | ||
375 | |||
376 | /* sysctl_net_ax25.c */ | ||
377 | #ifdef CONFIG_SYSCTL | ||
378 | extern void ax25_register_sysctl(void); | ||
379 | extern void ax25_unregister_sysctl(void); | ||
380 | #else | ||
381 | static inline void ax25_register_sysctl(void) {}; | ||
382 | static inline void ax25_unregister_sysctl(void) {}; | ||
383 | #endif /* CONFIG_SYSCTL */ | ||
384 | |||
385 | #endif | ||
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h new file mode 100644 index 000000000000..42a84c53678b --- /dev/null +++ b/include/net/bluetooth/bluetooth.h | |||
@@ -0,0 +1,181 @@ | |||
1 | /* | ||
2 | BlueZ - Bluetooth protocol stack for Linux | ||
3 | Copyright (C) 2000-2001 Qualcomm Incorporated | ||
4 | |||
5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License version 2 as | ||
9 | published by the Free Software Foundation; | ||
10 | |||
11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
12 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
14 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
15 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
16 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
17 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
18 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
19 | |||
20 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
21 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
22 | SOFTWARE IS DISCLAIMED. | ||
23 | */ | ||
24 | |||
25 | #ifndef __BLUETOOTH_H | ||
26 | #define __BLUETOOTH_H | ||
27 | |||
28 | #include <asm/types.h> | ||
29 | #include <asm/byteorder.h> | ||
30 | #include <linux/list.h> | ||
31 | #include <linux/poll.h> | ||
32 | #include <net/sock.h> | ||
33 | |||
34 | #ifndef AF_BLUETOOTH | ||
35 | #define AF_BLUETOOTH 31 | ||
36 | #define PF_BLUETOOTH AF_BLUETOOTH | ||
37 | #endif | ||
38 | |||
39 | /* Reserv for core and drivers use */ | ||
40 | #define BT_SKB_RESERVE 8 | ||
41 | |||
42 | #define BTPROTO_L2CAP 0 | ||
43 | #define BTPROTO_HCI 1 | ||
44 | #define BTPROTO_SCO 2 | ||
45 | #define BTPROTO_RFCOMM 3 | ||
46 | #define BTPROTO_BNEP 4 | ||
47 | #define BTPROTO_CMTP 5 | ||
48 | #define BTPROTO_HIDP 6 | ||
49 | #define BTPROTO_AVDTP 7 | ||
50 | |||
51 | #define SOL_HCI 0 | ||
52 | #define SOL_L2CAP 6 | ||
53 | #define SOL_SCO 17 | ||
54 | #define SOL_RFCOMM 18 | ||
55 | |||
56 | #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg) | ||
57 | #define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __FUNCTION__ , ## arg) | ||
58 | #define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __FUNCTION__ , ## arg) | ||
59 | |||
60 | #ifdef HCI_DATA_DUMP | ||
61 | #define BT_DMP(buf, len) bt_dump(__FUNCTION__, buf, len) | ||
62 | #else | ||
63 | #define BT_DMP(D...) | ||
64 | #endif | ||
65 | |||
66 | extern struct proc_dir_entry *proc_bt; | ||
67 | |||
68 | /* Connection and socket states */ | ||
69 | enum { | ||
70 | BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */ | ||
71 | BT_OPEN, | ||
72 | BT_BOUND, | ||
73 | BT_LISTEN, | ||
74 | BT_CONNECT, | ||
75 | BT_CONNECT2, | ||
76 | BT_CONFIG, | ||
77 | BT_DISCONN, | ||
78 | BT_CLOSED | ||
79 | }; | ||
80 | |||
81 | /* Endianness conversions */ | ||
82 | #define htobs(a) __cpu_to_le16(a) | ||
83 | #define htobl(a) __cpu_to_le32(a) | ||
84 | #define btohs(a) __le16_to_cpu(a) | ||
85 | #define btohl(a) __le32_to_cpu(a) | ||
86 | |||
87 | /* BD Address */ | ||
88 | typedef struct { | ||
89 | __u8 b[6]; | ||
90 | } __attribute__((packed)) bdaddr_t; | ||
91 | |||
92 | #define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}}) | ||
93 | #define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}}) | ||
94 | |||
95 | /* Copy, swap, convert BD Address */ | ||
96 | static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2) | ||
97 | { | ||
98 | return memcmp(ba1, ba2, sizeof(bdaddr_t)); | ||
99 | } | ||
100 | static inline void bacpy(bdaddr_t *dst, bdaddr_t *src) | ||
101 | { | ||
102 | memcpy(dst, src, sizeof(bdaddr_t)); | ||
103 | } | ||
104 | |||
105 | void baswap(bdaddr_t *dst, bdaddr_t *src); | ||
106 | char *batostr(bdaddr_t *ba); | ||
107 | bdaddr_t *strtoba(char *str); | ||
108 | |||
109 | /* Common socket structures and functions */ | ||
110 | |||
111 | #define bt_sk(__sk) ((struct bt_sock *) __sk) | ||
112 | |||
113 | struct bt_sock { | ||
114 | struct sock sk; | ||
115 | bdaddr_t src; | ||
116 | bdaddr_t dst; | ||
117 | struct list_head accept_q; | ||
118 | struct sock *parent; | ||
119 | }; | ||
120 | |||
121 | struct bt_sock_list { | ||
122 | struct hlist_head head; | ||
123 | rwlock_t lock; | ||
124 | }; | ||
125 | |||
126 | int bt_sock_register(int proto, struct net_proto_family *ops); | ||
127 | int bt_sock_unregister(int proto); | ||
128 | void bt_sock_link(struct bt_sock_list *l, struct sock *s); | ||
129 | void bt_sock_unlink(struct bt_sock_list *l, struct sock *s); | ||
130 | int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); | ||
131 | uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait); | ||
132 | int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo); | ||
133 | |||
134 | void bt_accept_enqueue(struct sock *parent, struct sock *sk); | ||
135 | void bt_accept_unlink(struct sock *sk); | ||
136 | struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock); | ||
137 | |||
138 | /* Skb helpers */ | ||
139 | struct bt_skb_cb { | ||
140 | int incoming; | ||
141 | }; | ||
142 | #define bt_cb(skb) ((struct bt_skb_cb *)(skb->cb)) | ||
143 | |||
144 | static inline struct sk_buff *bt_skb_alloc(unsigned int len, int how) | ||
145 | { | ||
146 | struct sk_buff *skb; | ||
147 | |||
148 | if ((skb = alloc_skb(len + BT_SKB_RESERVE, how))) { | ||
149 | skb_reserve(skb, BT_SKB_RESERVE); | ||
150 | bt_cb(skb)->incoming = 0; | ||
151 | } | ||
152 | return skb; | ||
153 | } | ||
154 | |||
155 | static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long len, | ||
156 | int nb, int *err) | ||
157 | { | ||
158 | struct sk_buff *skb; | ||
159 | |||
160 | if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) { | ||
161 | skb_reserve(skb, BT_SKB_RESERVE); | ||
162 | bt_cb(skb)->incoming = 0; | ||
163 | } | ||
164 | |||
165 | return skb; | ||
166 | } | ||
167 | |||
168 | static inline int skb_frags_no(struct sk_buff *skb) | ||
169 | { | ||
170 | register struct sk_buff *frag = skb_shinfo(skb)->frag_list; | ||
171 | register int n = 1; | ||
172 | |||
173 | for (; frag; frag=frag->next, n++); | ||
174 | return n; | ||
175 | } | ||
176 | |||
177 | void bt_dump(char *pref, __u8 *buf, int count); | ||
178 | |||
179 | int bt_err(__u16 code); | ||
180 | |||
181 | #endif /* __BLUETOOTH_H */ | ||
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h new file mode 100644 index 000000000000..6f0706f4af68 --- /dev/null +++ b/include/net/bluetooth/hci.h | |||
@@ -0,0 +1,755 @@ | |||
1 | /* | ||
2 | BlueZ - Bluetooth protocol stack for Linux | ||
3 | Copyright (C) 2000-2001 Qualcomm Incorporated | ||
4 | |||
5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License version 2 as | ||
9 | published by the Free Software Foundation; | ||
10 | |||
11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
12 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
14 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
15 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
16 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
17 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
18 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
19 | |||
20 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
21 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
22 | SOFTWARE IS DISCLAIMED. | ||
23 | */ | ||
24 | |||
25 | #ifndef __HCI_H | ||
26 | #define __HCI_H | ||
27 | |||
28 | #define HCI_MAX_ACL_SIZE 1024 | ||
29 | #define HCI_MAX_SCO_SIZE 255 | ||
30 | #define HCI_MAX_EVENT_SIZE 260 | ||
31 | #define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4) | ||
32 | |||
33 | /* HCI dev events */ | ||
34 | #define HCI_DEV_REG 1 | ||
35 | #define HCI_DEV_UNREG 2 | ||
36 | #define HCI_DEV_UP 3 | ||
37 | #define HCI_DEV_DOWN 4 | ||
38 | #define HCI_DEV_SUSPEND 5 | ||
39 | #define HCI_DEV_RESUME 6 | ||
40 | |||
41 | /* HCI notify events */ | ||
42 | #define HCI_NOTIFY_CONN_ADD 1 | ||
43 | #define HCI_NOTIFY_CONN_DEL 2 | ||
44 | #define HCI_NOTIFY_VOICE_SETTING 3 | ||
45 | |||
46 | /* HCI device types */ | ||
47 | #define HCI_VHCI 0 | ||
48 | #define HCI_USB 1 | ||
49 | #define HCI_PCCARD 2 | ||
50 | #define HCI_UART 3 | ||
51 | #define HCI_RS232 4 | ||
52 | #define HCI_PCI 5 | ||
53 | |||
54 | /* HCI device quirks */ | ||
55 | enum { | ||
56 | HCI_QUIRK_RESET_ON_INIT, | ||
57 | HCI_QUIRK_RAW_DEVICE | ||
58 | }; | ||
59 | |||
60 | /* HCI device flags */ | ||
61 | enum { | ||
62 | HCI_UP, | ||
63 | HCI_INIT, | ||
64 | HCI_RUNNING, | ||
65 | |||
66 | HCI_PSCAN, | ||
67 | HCI_ISCAN, | ||
68 | HCI_AUTH, | ||
69 | HCI_ENCRYPT, | ||
70 | HCI_INQUIRY, | ||
71 | |||
72 | HCI_RAW, | ||
73 | |||
74 | HCI_SECMGR | ||
75 | }; | ||
76 | |||
77 | /* HCI ioctl defines */ | ||
78 | #define HCIDEVUP _IOW('H', 201, int) | ||
79 | #define HCIDEVDOWN _IOW('H', 202, int) | ||
80 | #define HCIDEVRESET _IOW('H', 203, int) | ||
81 | #define HCIDEVRESTAT _IOW('H', 204, int) | ||
82 | |||
83 | #define HCIGETDEVLIST _IOR('H', 210, int) | ||
84 | #define HCIGETDEVINFO _IOR('H', 211, int) | ||
85 | #define HCIGETCONNLIST _IOR('H', 212, int) | ||
86 | #define HCIGETCONNINFO _IOR('H', 213, int) | ||
87 | |||
88 | #define HCISETRAW _IOW('H', 220, int) | ||
89 | #define HCISETSCAN _IOW('H', 221, int) | ||
90 | #define HCISETAUTH _IOW('H', 222, int) | ||
91 | #define HCISETENCRYPT _IOW('H', 223, int) | ||
92 | #define HCISETPTYPE _IOW('H', 224, int) | ||
93 | #define HCISETLINKPOL _IOW('H', 225, int) | ||
94 | #define HCISETLINKMODE _IOW('H', 226, int) | ||
95 | #define HCISETACLMTU _IOW('H', 227, int) | ||
96 | #define HCISETSCOMTU _IOW('H', 228, int) | ||
97 | |||
98 | #define HCISETSECMGR _IOW('H', 230, int) | ||
99 | |||
100 | #define HCIINQUIRY _IOR('H', 240, int) | ||
101 | |||
102 | /* HCI timeouts */ | ||
103 | #define HCI_CONN_TIMEOUT (HZ * 40) | ||
104 | #define HCI_DISCONN_TIMEOUT (HZ * 2) | ||
105 | #define HCI_CONN_IDLE_TIMEOUT (HZ * 60) | ||
106 | |||
107 | /* HCI Packet types */ | ||
108 | #define HCI_COMMAND_PKT 0x01 | ||
109 | #define HCI_ACLDATA_PKT 0x02 | ||
110 | #define HCI_SCODATA_PKT 0x03 | ||
111 | #define HCI_EVENT_PKT 0x04 | ||
112 | #define HCI_VENDOR_PKT 0xff | ||
113 | |||
114 | /* HCI Packet types */ | ||
115 | #define HCI_DM1 0x0008 | ||
116 | #define HCI_DM3 0x0400 | ||
117 | #define HCI_DM5 0x4000 | ||
118 | #define HCI_DH1 0x0010 | ||
119 | #define HCI_DH3 0x0800 | ||
120 | #define HCI_DH5 0x8000 | ||
121 | |||
122 | #define HCI_HV1 0x0020 | ||
123 | #define HCI_HV2 0x0040 | ||
124 | #define HCI_HV3 0x0080 | ||
125 | |||
126 | #define SCO_PTYPE_MASK (HCI_HV1 | HCI_HV2 | HCI_HV3) | ||
127 | #define ACL_PTYPE_MASK (~SCO_PTYPE_MASK) | ||
128 | |||
129 | /* ACL flags */ | ||
130 | #define ACL_CONT 0x01 | ||
131 | #define ACL_START 0x02 | ||
132 | #define ACL_ACTIVE_BCAST 0x04 | ||
133 | #define ACL_PICO_BCAST 0x08 | ||
134 | |||
135 | /* Baseband links */ | ||
136 | #define SCO_LINK 0x00 | ||
137 | #define ACL_LINK 0x01 | ||
138 | |||
139 | /* LMP features */ | ||
140 | #define LMP_3SLOT 0x01 | ||
141 | #define LMP_5SLOT 0x02 | ||
142 | #define LMP_ENCRYPT 0x04 | ||
143 | #define LMP_SOFFSET 0x08 | ||
144 | #define LMP_TACCURACY 0x10 | ||
145 | #define LMP_RSWITCH 0x20 | ||
146 | #define LMP_HOLD 0x40 | ||
147 | #define LMP_SNIF 0x80 | ||
148 | |||
149 | #define LMP_PARK 0x01 | ||
150 | #define LMP_RSSI 0x02 | ||
151 | #define LMP_QUALITY 0x04 | ||
152 | #define LMP_SCO 0x08 | ||
153 | #define LMP_HV2 0x10 | ||
154 | #define LMP_HV3 0x20 | ||
155 | #define LMP_ULAW 0x40 | ||
156 | #define LMP_ALAW 0x80 | ||
157 | |||
158 | #define LMP_CVSD 0x01 | ||
159 | #define LMP_PSCHEME 0x02 | ||
160 | #define LMP_PCONTROL 0x04 | ||
161 | |||
162 | /* Link policies */ | ||
163 | #define HCI_LP_RSWITCH 0x0001 | ||
164 | #define HCI_LP_HOLD 0x0002 | ||
165 | #define HCI_LP_SNIFF 0x0004 | ||
166 | #define HCI_LP_PARK 0x0008 | ||
167 | |||
168 | /* Link mode */ | ||
169 | #define HCI_LM_ACCEPT 0x8000 | ||
170 | #define HCI_LM_MASTER 0x0001 | ||
171 | #define HCI_LM_AUTH 0x0002 | ||
172 | #define HCI_LM_ENCRYPT 0x0004 | ||
173 | #define HCI_LM_TRUSTED 0x0008 | ||
174 | #define HCI_LM_RELIABLE 0x0010 | ||
175 | #define HCI_LM_SECURE 0x0020 | ||
176 | |||
177 | /* ----- HCI Commands ---- */ | ||
178 | /* OGF & OCF values */ | ||
179 | |||
180 | /* Informational Parameters */ | ||
181 | #define OGF_INFO_PARAM 0x04 | ||
182 | |||
183 | #define OCF_READ_LOCAL_VERSION 0x0001 | ||
184 | struct hci_rp_read_loc_version { | ||
185 | __u8 status; | ||
186 | __u8 hci_ver; | ||
187 | __u16 hci_rev; | ||
188 | __u8 lmp_ver; | ||
189 | __u16 manufacturer; | ||
190 | __u16 lmp_subver; | ||
191 | } __attribute__ ((packed)); | ||
192 | |||
193 | #define OCF_READ_LOCAL_FEATURES 0x0003 | ||
194 | struct hci_rp_read_loc_features { | ||
195 | __u8 status; | ||
196 | __u8 features[8]; | ||
197 | } __attribute__ ((packed)); | ||
198 | |||
199 | #define OCF_READ_BUFFER_SIZE 0x0005 | ||
200 | struct hci_rp_read_buffer_size { | ||
201 | __u8 status; | ||
202 | __u16 acl_mtu; | ||
203 | __u8 sco_mtu; | ||
204 | __u16 acl_max_pkt; | ||
205 | __u16 sco_max_pkt; | ||
206 | } __attribute__ ((packed)); | ||
207 | |||
208 | #define OCF_READ_BD_ADDR 0x0009 | ||
209 | struct hci_rp_read_bd_addr { | ||
210 | __u8 status; | ||
211 | bdaddr_t bdaddr; | ||
212 | } __attribute__ ((packed)); | ||
213 | |||
214 | /* Host Controller and Baseband */ | ||
215 | #define OGF_HOST_CTL 0x03 | ||
216 | #define OCF_RESET 0x0003 | ||
217 | #define OCF_READ_AUTH_ENABLE 0x001F | ||
218 | #define OCF_WRITE_AUTH_ENABLE 0x0020 | ||
219 | #define AUTH_DISABLED 0x00 | ||
220 | #define AUTH_ENABLED 0x01 | ||
221 | |||
222 | #define OCF_READ_ENCRYPT_MODE 0x0021 | ||
223 | #define OCF_WRITE_ENCRYPT_MODE 0x0022 | ||
224 | #define ENCRYPT_DISABLED 0x00 | ||
225 | #define ENCRYPT_P2P 0x01 | ||
226 | #define ENCRYPT_BOTH 0x02 | ||
227 | |||
228 | #define OCF_WRITE_CA_TIMEOUT 0x0016 | ||
229 | #define OCF_WRITE_PG_TIMEOUT 0x0018 | ||
230 | |||
231 | #define OCF_WRITE_SCAN_ENABLE 0x001A | ||
232 | #define SCAN_DISABLED 0x00 | ||
233 | #define SCAN_INQUIRY 0x01 | ||
234 | #define SCAN_PAGE 0x02 | ||
235 | |||
236 | #define OCF_SET_EVENT_FLT 0x0005 | ||
237 | struct hci_cp_set_event_flt { | ||
238 | __u8 flt_type; | ||
239 | __u8 cond_type; | ||
240 | __u8 condition[0]; | ||
241 | } __attribute__ ((packed)); | ||
242 | |||
243 | /* Filter types */ | ||
244 | #define HCI_FLT_CLEAR_ALL 0x00 | ||
245 | #define HCI_FLT_INQ_RESULT 0x01 | ||
246 | #define HCI_FLT_CONN_SETUP 0x02 | ||
247 | |||
248 | /* CONN_SETUP Condition types */ | ||
249 | #define HCI_CONN_SETUP_ALLOW_ALL 0x00 | ||
250 | #define HCI_CONN_SETUP_ALLOW_CLASS 0x01 | ||
251 | #define HCI_CONN_SETUP_ALLOW_BDADDR 0x02 | ||
252 | |||
253 | /* CONN_SETUP Conditions */ | ||
254 | #define HCI_CONN_SETUP_AUTO_OFF 0x01 | ||
255 | #define HCI_CONN_SETUP_AUTO_ON 0x02 | ||
256 | |||
257 | #define OCF_READ_CLASS_OF_DEV 0x0023 | ||
258 | struct hci_rp_read_dev_class { | ||
259 | __u8 status; | ||
260 | __u8 dev_class[3]; | ||
261 | } __attribute__ ((packed)); | ||
262 | |||
263 | #define OCF_WRITE_CLASS_OF_DEV 0x0024 | ||
264 | struct hci_cp_write_dev_class { | ||
265 | __u8 dev_class[3]; | ||
266 | } __attribute__ ((packed)); | ||
267 | |||
268 | #define OCF_READ_VOICE_SETTING 0x0025 | ||
269 | struct hci_rp_read_voice_setting { | ||
270 | __u8 status; | ||
271 | __u16 voice_setting; | ||
272 | } __attribute__ ((packed)); | ||
273 | |||
274 | #define OCF_WRITE_VOICE_SETTING 0x0026 | ||
275 | struct hci_cp_write_voice_setting { | ||
276 | __u16 voice_setting; | ||
277 | } __attribute__ ((packed)); | ||
278 | |||
279 | #define OCF_HOST_BUFFER_SIZE 0x0033 | ||
280 | struct hci_cp_host_buffer_size { | ||
281 | __u16 acl_mtu; | ||
282 | __u8 sco_mtu; | ||
283 | __u16 acl_max_pkt; | ||
284 | __u16 sco_max_pkt; | ||
285 | } __attribute__ ((packed)); | ||
286 | |||
287 | /* Link Control */ | ||
288 | #define OGF_LINK_CTL 0x01 | ||
289 | #define OCF_CREATE_CONN 0x0005 | ||
290 | struct hci_cp_create_conn { | ||
291 | bdaddr_t bdaddr; | ||
292 | __u16 pkt_type; | ||
293 | __u8 pscan_rep_mode; | ||
294 | __u8 pscan_mode; | ||
295 | __u16 clock_offset; | ||
296 | __u8 role_switch; | ||
297 | } __attribute__ ((packed)); | ||
298 | |||
299 | #define OCF_ACCEPT_CONN_REQ 0x0009 | ||
300 | struct hci_cp_accept_conn_req { | ||
301 | bdaddr_t bdaddr; | ||
302 | __u8 role; | ||
303 | } __attribute__ ((packed)); | ||
304 | |||
305 | #define OCF_REJECT_CONN_REQ 0x000a | ||
306 | struct hci_cp_reject_conn_req { | ||
307 | bdaddr_t bdaddr; | ||
308 | __u8 reason; | ||
309 | } __attribute__ ((packed)); | ||
310 | |||
311 | #define OCF_DISCONNECT 0x0006 | ||
312 | struct hci_cp_disconnect { | ||
313 | __u16 handle; | ||
314 | __u8 reason; | ||
315 | } __attribute__ ((packed)); | ||
316 | |||
317 | #define OCF_ADD_SCO 0x0007 | ||
318 | struct hci_cp_add_sco { | ||
319 | __u16 handle; | ||
320 | __u16 pkt_type; | ||
321 | } __attribute__ ((packed)); | ||
322 | |||
323 | #define OCF_INQUIRY 0x0001 | ||
324 | struct hci_cp_inquiry { | ||
325 | __u8 lap[3]; | ||
326 | __u8 length; | ||
327 | __u8 num_rsp; | ||
328 | } __attribute__ ((packed)); | ||
329 | |||
330 | #define OCF_INQUIRY_CANCEL 0x0002 | ||
331 | |||
332 | #define OCF_LINK_KEY_REPLY 0x000B | ||
333 | struct hci_cp_link_key_reply { | ||
334 | bdaddr_t bdaddr; | ||
335 | __u8 link_key[16]; | ||
336 | } __attribute__ ((packed)); | ||
337 | |||
338 | #define OCF_LINK_KEY_NEG_REPLY 0x000C | ||
339 | struct hci_cp_link_key_neg_reply { | ||
340 | bdaddr_t bdaddr; | ||
341 | } __attribute__ ((packed)); | ||
342 | |||
343 | #define OCF_PIN_CODE_REPLY 0x000D | ||
344 | struct hci_cp_pin_code_reply { | ||
345 | bdaddr_t bdaddr; | ||
346 | __u8 pin_len; | ||
347 | __u8 pin_code[16]; | ||
348 | } __attribute__ ((packed)); | ||
349 | |||
350 | #define OCF_PIN_CODE_NEG_REPLY 0x000E | ||
351 | struct hci_cp_pin_code_neg_reply { | ||
352 | bdaddr_t bdaddr; | ||
353 | } __attribute__ ((packed)); | ||
354 | |||
355 | #define OCF_CHANGE_CONN_PTYPE 0x000F | ||
356 | struct hci_cp_change_conn_ptype { | ||
357 | __u16 handle; | ||
358 | __u16 pkt_type; | ||
359 | } __attribute__ ((packed)); | ||
360 | |||
361 | #define OCF_AUTH_REQUESTED 0x0011 | ||
362 | struct hci_cp_auth_requested { | ||
363 | __u16 handle; | ||
364 | } __attribute__ ((packed)); | ||
365 | |||
366 | #define OCF_SET_CONN_ENCRYPT 0x0013 | ||
367 | struct hci_cp_set_conn_encrypt { | ||
368 | __u16 handle; | ||
369 | __u8 encrypt; | ||
370 | } __attribute__ ((packed)); | ||
371 | |||
372 | #define OCF_CHANGE_CONN_LINK_KEY 0x0015 | ||
373 | struct hci_cp_change_conn_link_key { | ||
374 | __u16 handle; | ||
375 | } __attribute__ ((packed)); | ||
376 | |||
377 | #define OCF_READ_REMOTE_FEATURES 0x001B | ||
378 | struct hci_cp_read_rmt_features { | ||
379 | __u16 handle; | ||
380 | } __attribute__ ((packed)); | ||
381 | |||
382 | #define OCF_READ_REMOTE_VERSION 0x001D | ||
383 | struct hci_cp_read_rmt_version { | ||
384 | __u16 handle; | ||
385 | } __attribute__ ((packed)); | ||
386 | |||
387 | /* Link Policy */ | ||
388 | #define OGF_LINK_POLICY 0x02 | ||
389 | #define OCF_ROLE_DISCOVERY 0x0009 | ||
390 | struct hci_cp_role_discovery { | ||
391 | __u16 handle; | ||
392 | } __attribute__ ((packed)); | ||
393 | struct hci_rp_role_discovery { | ||
394 | __u8 status; | ||
395 | __u16 handle; | ||
396 | __u8 role; | ||
397 | } __attribute__ ((packed)); | ||
398 | |||
399 | #define OCF_READ_LINK_POLICY 0x000C | ||
400 | struct hci_cp_read_link_policy { | ||
401 | __u16 handle; | ||
402 | } __attribute__ ((packed)); | ||
403 | struct hci_rp_read_link_policy { | ||
404 | __u8 status; | ||
405 | __u16 handle; | ||
406 | __u16 policy; | ||
407 | } __attribute__ ((packed)); | ||
408 | |||
409 | #define OCF_SWITCH_ROLE 0x000B | ||
410 | struct hci_cp_switch_role { | ||
411 | bdaddr_t bdaddr; | ||
412 | __u8 role; | ||
413 | } __attribute__ ((packed)); | ||
414 | |||
415 | #define OCF_WRITE_LINK_POLICY 0x000D | ||
416 | struct hci_cp_write_link_policy { | ||
417 | __u16 handle; | ||
418 | __u16 policy; | ||
419 | } __attribute__ ((packed)); | ||
420 | struct hci_rp_write_link_policy { | ||
421 | __u8 status; | ||
422 | __u16 handle; | ||
423 | } __attribute__ ((packed)); | ||
424 | |||
425 | /* Status params */ | ||
426 | #define OGF_STATUS_PARAM 0x05 | ||
427 | |||
428 | /* Testing commands */ | ||
429 | #define OGF_TESTING_CMD 0x3E | ||
430 | |||
431 | /* Vendor specific commands */ | ||
432 | #define OGF_VENDOR_CMD 0x3F | ||
433 | |||
434 | /* ---- HCI Events ---- */ | ||
435 | #define HCI_EV_INQUIRY_COMPLETE 0x01 | ||
436 | |||
437 | #define HCI_EV_INQUIRY_RESULT 0x02 | ||
438 | struct inquiry_info { | ||
439 | bdaddr_t bdaddr; | ||
440 | __u8 pscan_rep_mode; | ||
441 | __u8 pscan_period_mode; | ||
442 | __u8 pscan_mode; | ||
443 | __u8 dev_class[3]; | ||
444 | __u16 clock_offset; | ||
445 | } __attribute__ ((packed)); | ||
446 | |||
447 | #define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22 | ||
448 | struct inquiry_info_with_rssi { | ||
449 | bdaddr_t bdaddr; | ||
450 | __u8 pscan_rep_mode; | ||
451 | __u8 pscan_period_mode; | ||
452 | __u8 dev_class[3]; | ||
453 | __u16 clock_offset; | ||
454 | __s8 rssi; | ||
455 | } __attribute__ ((packed)); | ||
456 | |||
457 | #define HCI_EV_CONN_COMPLETE 0x03 | ||
458 | struct hci_ev_conn_complete { | ||
459 | __u8 status; | ||
460 | __u16 handle; | ||
461 | bdaddr_t bdaddr; | ||
462 | __u8 link_type; | ||
463 | __u8 encr_mode; | ||
464 | } __attribute__ ((packed)); | ||
465 | |||
466 | #define HCI_EV_CONN_REQUEST 0x04 | ||
467 | struct hci_ev_conn_request { | ||
468 | bdaddr_t bdaddr; | ||
469 | __u8 dev_class[3]; | ||
470 | __u8 link_type; | ||
471 | } __attribute__ ((packed)); | ||
472 | |||
473 | #define HCI_EV_DISCONN_COMPLETE 0x05 | ||
474 | struct hci_ev_disconn_complete { | ||
475 | __u8 status; | ||
476 | __u16 handle; | ||
477 | __u8 reason; | ||
478 | } __attribute__ ((packed)); | ||
479 | |||
480 | #define HCI_EV_AUTH_COMPLETE 0x06 | ||
481 | struct hci_ev_auth_complete { | ||
482 | __u8 status; | ||
483 | __u16 handle; | ||
484 | } __attribute__ ((packed)); | ||
485 | |||
486 | #define HCI_EV_ENCRYPT_CHANGE 0x08 | ||
487 | struct hci_ev_encrypt_change { | ||
488 | __u8 status; | ||
489 | __u16 handle; | ||
490 | __u8 encrypt; | ||
491 | } __attribute__ ((packed)); | ||
492 | |||
493 | #define HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE 0x09 | ||
494 | struct hci_ev_change_conn_link_key_complete { | ||
495 | __u8 status; | ||
496 | __u16 handle; | ||
497 | } __attribute__ ((packed)); | ||
498 | |||
499 | #define HCI_EV_QOS_SETUP_COMPLETE 0x0D | ||
500 | struct hci_qos { | ||
501 | __u8 service_type; | ||
502 | __u32 token_rate; | ||
503 | __u32 peak_bandwidth; | ||
504 | __u32 latency; | ||
505 | __u32 delay_variation; | ||
506 | } __attribute__ ((packed)); | ||
507 | struct hci_ev_qos_setup_complete { | ||
508 | __u8 status; | ||
509 | __u16 handle; | ||
510 | struct hci_qos qos; | ||
511 | } __attribute__ ((packed)); | ||
512 | |||
513 | #define HCI_EV_CMD_COMPLETE 0x0E | ||
514 | struct hci_ev_cmd_complete { | ||
515 | __u8 ncmd; | ||
516 | __u16 opcode; | ||
517 | } __attribute__ ((packed)); | ||
518 | |||
519 | #define HCI_EV_CMD_STATUS 0x0F | ||
520 | struct hci_ev_cmd_status { | ||
521 | __u8 status; | ||
522 | __u8 ncmd; | ||
523 | __u16 opcode; | ||
524 | } __attribute__ ((packed)); | ||
525 | |||
526 | #define HCI_EV_NUM_COMP_PKTS 0x13 | ||
527 | struct hci_ev_num_comp_pkts { | ||
528 | __u8 num_hndl; | ||
529 | /* variable length part */ | ||
530 | } __attribute__ ((packed)); | ||
531 | |||
532 | #define HCI_EV_ROLE_CHANGE 0x12 | ||
533 | struct hci_ev_role_change { | ||
534 | __u8 status; | ||
535 | bdaddr_t bdaddr; | ||
536 | __u8 role; | ||
537 | } __attribute__ ((packed)); | ||
538 | |||
539 | #define HCI_EV_MODE_CHANGE 0x14 | ||
540 | struct hci_ev_mode_change { | ||
541 | __u8 status; | ||
542 | __u16 handle; | ||
543 | __u8 mode; | ||
544 | __u16 interval; | ||
545 | } __attribute__ ((packed)); | ||
546 | |||
547 | #define HCI_EV_PIN_CODE_REQ 0x16 | ||
548 | struct hci_ev_pin_code_req { | ||
549 | bdaddr_t bdaddr; | ||
550 | } __attribute__ ((packed)); | ||
551 | |||
552 | #define HCI_EV_LINK_KEY_REQ 0x17 | ||
553 | struct hci_ev_link_key_req { | ||
554 | bdaddr_t bdaddr; | ||
555 | } __attribute__ ((packed)); | ||
556 | |||
557 | #define HCI_EV_LINK_KEY_NOTIFY 0x18 | ||
558 | struct hci_ev_link_key_notify { | ||
559 | bdaddr_t bdaddr; | ||
560 | __u8 link_key[16]; | ||
561 | __u8 key_type; | ||
562 | } __attribute__ ((packed)); | ||
563 | |||
564 | #define HCI_EV_RMT_FEATURES 0x0B | ||
565 | struct hci_ev_rmt_features { | ||
566 | __u8 status; | ||
567 | __u16 handle; | ||
568 | __u8 features[8]; | ||
569 | } __attribute__ ((packed)); | ||
570 | |||
571 | #define HCI_EV_RMT_VERSION 0x0C | ||
572 | struct hci_ev_rmt_version { | ||
573 | __u8 status; | ||
574 | __u16 handle; | ||
575 | __u8 lmp_ver; | ||
576 | __u16 manufacturer; | ||
577 | __u16 lmp_subver; | ||
578 | } __attribute__ ((packed)); | ||
579 | |||
580 | #define HCI_EV_CLOCK_OFFSET 0x01C | ||
581 | struct hci_ev_clock_offset { | ||
582 | __u8 status; | ||
583 | __u16 handle; | ||
584 | __u16 clock_offset; | ||
585 | } __attribute__ ((packed)); | ||
586 | |||
587 | /* Internal events generated by Bluetooth stack */ | ||
588 | #define HCI_EV_STACK_INTERNAL 0xFD | ||
589 | struct hci_ev_stack_internal { | ||
590 | __u16 type; | ||
591 | __u8 data[0]; | ||
592 | } __attribute__ ((packed)); | ||
593 | |||
594 | #define HCI_EV_SI_DEVICE 0x01 | ||
595 | struct hci_ev_si_device { | ||
596 | __u16 event; | ||
597 | __u16 dev_id; | ||
598 | } __attribute__ ((packed)); | ||
599 | |||
600 | #define HCI_EV_SI_SECURITY 0x02 | ||
601 | struct hci_ev_si_security { | ||
602 | __u16 event; | ||
603 | __u16 proto; | ||
604 | __u16 subproto; | ||
605 | __u8 incoming; | ||
606 | } __attribute__ ((packed)); | ||
607 | |||
608 | /* ---- HCI Packet structures ---- */ | ||
609 | #define HCI_COMMAND_HDR_SIZE 3 | ||
610 | #define HCI_EVENT_HDR_SIZE 2 | ||
611 | #define HCI_ACL_HDR_SIZE 4 | ||
612 | #define HCI_SCO_HDR_SIZE 3 | ||
613 | |||
614 | struct hci_command_hdr { | ||
615 | __u16 opcode; /* OCF & OGF */ | ||
616 | __u8 plen; | ||
617 | } __attribute__ ((packed)); | ||
618 | |||
619 | struct hci_event_hdr { | ||
620 | __u8 evt; | ||
621 | __u8 plen; | ||
622 | } __attribute__ ((packed)); | ||
623 | |||
624 | struct hci_acl_hdr { | ||
625 | __u16 handle; /* Handle & Flags(PB, BC) */ | ||
626 | __u16 dlen; | ||
627 | } __attribute__ ((packed)); | ||
628 | |||
629 | struct hci_sco_hdr { | ||
630 | __u16 handle; | ||
631 | __u8 dlen; | ||
632 | } __attribute__ ((packed)); | ||
633 | |||
634 | /* Command opcode pack/unpack */ | ||
635 | #define hci_opcode_pack(ogf, ocf) (__u16)((ocf & 0x03ff)|(ogf << 10)) | ||
636 | #define hci_opcode_ogf(op) (op >> 10) | ||
637 | #define hci_opcode_ocf(op) (op & 0x03ff) | ||
638 | |||
639 | /* ACL handle and flags pack/unpack */ | ||
640 | #define hci_handle_pack(h, f) (__u16)((h & 0x0fff)|(f << 12)) | ||
641 | #define hci_handle(h) (h & 0x0fff) | ||
642 | #define hci_flags(h) (h >> 12) | ||
643 | |||
644 | /* ---- HCI Sockets ---- */ | ||
645 | |||
646 | /* Socket options */ | ||
647 | #define HCI_DATA_DIR 1 | ||
648 | #define HCI_FILTER 2 | ||
649 | #define HCI_TIME_STAMP 3 | ||
650 | |||
651 | /* CMSG flags */ | ||
652 | #define HCI_CMSG_DIR 0x0001 | ||
653 | #define HCI_CMSG_TSTAMP 0x0002 | ||
654 | |||
655 | struct sockaddr_hci { | ||
656 | sa_family_t hci_family; | ||
657 | unsigned short hci_dev; | ||
658 | }; | ||
659 | #define HCI_DEV_NONE 0xffff | ||
660 | |||
661 | struct hci_filter { | ||
662 | unsigned long type_mask; | ||
663 | unsigned long event_mask[2]; | ||
664 | __u16 opcode; | ||
665 | }; | ||
666 | |||
667 | struct hci_ufilter { | ||
668 | __u32 type_mask; | ||
669 | __u32 event_mask[2]; | ||
670 | __u16 opcode; | ||
671 | }; | ||
672 | |||
673 | #define HCI_FLT_TYPE_BITS 31 | ||
674 | #define HCI_FLT_EVENT_BITS 63 | ||
675 | #define HCI_FLT_OGF_BITS 63 | ||
676 | #define HCI_FLT_OCF_BITS 127 | ||
677 | |||
678 | /* ---- HCI Ioctl requests structures ---- */ | ||
679 | struct hci_dev_stats { | ||
680 | __u32 err_rx; | ||
681 | __u32 err_tx; | ||
682 | __u32 cmd_tx; | ||
683 | __u32 evt_rx; | ||
684 | __u32 acl_tx; | ||
685 | __u32 acl_rx; | ||
686 | __u32 sco_tx; | ||
687 | __u32 sco_rx; | ||
688 | __u32 byte_rx; | ||
689 | __u32 byte_tx; | ||
690 | }; | ||
691 | |||
692 | struct hci_dev_info { | ||
693 | __u16 dev_id; | ||
694 | char name[8]; | ||
695 | |||
696 | bdaddr_t bdaddr; | ||
697 | |||
698 | __u32 flags; | ||
699 | __u8 type; | ||
700 | |||
701 | __u8 features[8]; | ||
702 | |||
703 | __u32 pkt_type; | ||
704 | __u32 link_policy; | ||
705 | __u32 link_mode; | ||
706 | |||
707 | __u16 acl_mtu; | ||
708 | __u16 acl_pkts; | ||
709 | __u16 sco_mtu; | ||
710 | __u16 sco_pkts; | ||
711 | |||
712 | struct hci_dev_stats stat; | ||
713 | }; | ||
714 | |||
715 | struct hci_conn_info { | ||
716 | __u16 handle; | ||
717 | bdaddr_t bdaddr; | ||
718 | __u8 type; | ||
719 | __u8 out; | ||
720 | __u16 state; | ||
721 | __u32 link_mode; | ||
722 | }; | ||
723 | |||
724 | struct hci_dev_req { | ||
725 | __u16 dev_id; | ||
726 | __u32 dev_opt; | ||
727 | }; | ||
728 | |||
729 | struct hci_dev_list_req { | ||
730 | __u16 dev_num; | ||
731 | struct hci_dev_req dev_req[0]; /* hci_dev_req structures */ | ||
732 | }; | ||
733 | |||
734 | struct hci_conn_list_req { | ||
735 | __u16 dev_id; | ||
736 | __u16 conn_num; | ||
737 | struct hci_conn_info conn_info[0]; | ||
738 | }; | ||
739 | |||
740 | struct hci_conn_info_req { | ||
741 | bdaddr_t bdaddr; | ||
742 | __u8 type; | ||
743 | struct hci_conn_info conn_info[0]; | ||
744 | }; | ||
745 | |||
746 | struct hci_inquiry_req { | ||
747 | __u16 dev_id; | ||
748 | __u16 flags; | ||
749 | __u8 lap[3]; | ||
750 | __u8 length; | ||
751 | __u8 num_rsp; | ||
752 | }; | ||
753 | #define IREQ_CACHE_FLUSH 0x0001 | ||
754 | |||
755 | #endif /* __HCI_H */ | ||
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h new file mode 100644 index 000000000000..6d63a47c731b --- /dev/null +++ b/include/net/bluetooth/hci_core.h | |||
@@ -0,0 +1,626 @@ | |||
1 | /* | ||
2 | BlueZ - Bluetooth protocol stack for Linux | ||
3 | Copyright (C) 2000-2001 Qualcomm Incorporated | ||
4 | |||
5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License version 2 as | ||
9 | published by the Free Software Foundation; | ||
10 | |||
11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
12 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
14 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
15 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
16 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
17 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
18 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
19 | |||
20 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
21 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
22 | SOFTWARE IS DISCLAIMED. | ||
23 | */ | ||
24 | |||
25 | #ifndef __HCI_CORE_H | ||
26 | #define __HCI_CORE_H | ||
27 | |||
28 | #include <linux/proc_fs.h> | ||
29 | #include <net/bluetooth/hci.h> | ||
30 | |||
31 | /* HCI upper protocols */ | ||
32 | #define HCI_PROTO_L2CAP 0 | ||
33 | #define HCI_PROTO_SCO 1 | ||
34 | |||
35 | #define HCI_INIT_TIMEOUT (HZ * 10) | ||
36 | |||
37 | extern struct proc_dir_entry *proc_bt_hci; | ||
38 | |||
39 | /* HCI Core structures */ | ||
40 | |||
41 | struct inquiry_data { | ||
42 | bdaddr_t bdaddr; | ||
43 | __u8 pscan_rep_mode; | ||
44 | __u8 pscan_period_mode; | ||
45 | __u8 pscan_mode; | ||
46 | __u8 dev_class[3]; | ||
47 | __u16 clock_offset; | ||
48 | __s8 rssi; | ||
49 | }; | ||
50 | |||
51 | struct inquiry_entry { | ||
52 | struct inquiry_entry *next; | ||
53 | __u32 timestamp; | ||
54 | struct inquiry_data data; | ||
55 | }; | ||
56 | |||
57 | struct inquiry_cache { | ||
58 | spinlock_t lock; | ||
59 | __u32 timestamp; | ||
60 | struct inquiry_entry *list; | ||
61 | }; | ||
62 | |||
63 | struct hci_conn_hash { | ||
64 | struct list_head list; | ||
65 | spinlock_t lock; | ||
66 | unsigned int acl_num; | ||
67 | unsigned int sco_num; | ||
68 | }; | ||
69 | |||
70 | struct hci_dev { | ||
71 | struct list_head list; | ||
72 | spinlock_t lock; | ||
73 | atomic_t refcnt; | ||
74 | |||
75 | char name[8]; | ||
76 | unsigned long flags; | ||
77 | __u16 id; | ||
78 | __u8 type; | ||
79 | bdaddr_t bdaddr; | ||
80 | __u8 features[8]; | ||
81 | __u16 voice_setting; | ||
82 | |||
83 | __u16 pkt_type; | ||
84 | __u16 link_policy; | ||
85 | __u16 link_mode; | ||
86 | |||
87 | unsigned long quirks; | ||
88 | |||
89 | atomic_t cmd_cnt; | ||
90 | unsigned int acl_cnt; | ||
91 | unsigned int sco_cnt; | ||
92 | |||
93 | unsigned int acl_mtu; | ||
94 | unsigned int sco_mtu; | ||
95 | unsigned int acl_pkts; | ||
96 | unsigned int sco_pkts; | ||
97 | |||
98 | unsigned long cmd_last_tx; | ||
99 | unsigned long acl_last_tx; | ||
100 | unsigned long sco_last_tx; | ||
101 | |||
102 | struct tasklet_struct cmd_task; | ||
103 | struct tasklet_struct rx_task; | ||
104 | struct tasklet_struct tx_task; | ||
105 | |||
106 | struct sk_buff_head rx_q; | ||
107 | struct sk_buff_head raw_q; | ||
108 | struct sk_buff_head cmd_q; | ||
109 | |||
110 | struct sk_buff *sent_cmd; | ||
111 | |||
112 | struct semaphore req_lock; | ||
113 | wait_queue_head_t req_wait_q; | ||
114 | __u32 req_status; | ||
115 | __u32 req_result; | ||
116 | |||
117 | struct inquiry_cache inq_cache; | ||
118 | struct hci_conn_hash conn_hash; | ||
119 | |||
120 | struct hci_dev_stats stat; | ||
121 | |||
122 | struct sk_buff_head driver_init; | ||
123 | |||
124 | void *driver_data; | ||
125 | void *core_data; | ||
126 | |||
127 | atomic_t promisc; | ||
128 | |||
129 | #ifdef CONFIG_PROC_FS | ||
130 | struct proc_dir_entry *proc; | ||
131 | #endif | ||
132 | |||
133 | struct class_device class_dev; | ||
134 | |||
135 | struct module *owner; | ||
136 | |||
137 | int (*open)(struct hci_dev *hdev); | ||
138 | int (*close)(struct hci_dev *hdev); | ||
139 | int (*flush)(struct hci_dev *hdev); | ||
140 | int (*send)(struct sk_buff *skb); | ||
141 | void (*destruct)(struct hci_dev *hdev); | ||
142 | void (*notify)(struct hci_dev *hdev, unsigned int evt); | ||
143 | int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); | ||
144 | }; | ||
145 | |||
146 | struct hci_conn { | ||
147 | struct list_head list; | ||
148 | |||
149 | atomic_t refcnt; | ||
150 | spinlock_t lock; | ||
151 | |||
152 | bdaddr_t dst; | ||
153 | __u16 handle; | ||
154 | __u16 state; | ||
155 | __u8 type; | ||
156 | __u8 out; | ||
157 | __u8 dev_class[3]; | ||
158 | __u32 link_mode; | ||
159 | unsigned long pend; | ||
160 | |||
161 | unsigned int sent; | ||
162 | |||
163 | struct sk_buff_head data_q; | ||
164 | |||
165 | struct timer_list timer; | ||
166 | |||
167 | struct hci_dev *hdev; | ||
168 | void *l2cap_data; | ||
169 | void *sco_data; | ||
170 | void *priv; | ||
171 | |||
172 | struct hci_conn *link; | ||
173 | }; | ||
174 | |||
175 | extern struct hci_proto *hci_proto[]; | ||
176 | extern struct list_head hci_dev_list; | ||
177 | extern struct list_head hci_cb_list; | ||
178 | extern rwlock_t hci_dev_list_lock; | ||
179 | extern rwlock_t hci_cb_list_lock; | ||
180 | |||
181 | /* ----- Inquiry cache ----- */ | ||
182 | #define INQUIRY_CACHE_AGE_MAX (HZ*30) // 30 seconds | ||
183 | #define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds | ||
184 | |||
185 | #define inquiry_cache_lock(c) spin_lock(&c->lock) | ||
186 | #define inquiry_cache_unlock(c) spin_unlock(&c->lock) | ||
187 | #define inquiry_cache_lock_bh(c) spin_lock_bh(&c->lock) | ||
188 | #define inquiry_cache_unlock_bh(c) spin_unlock_bh(&c->lock) | ||
189 | |||
190 | static inline void inquiry_cache_init(struct hci_dev *hdev) | ||
191 | { | ||
192 | struct inquiry_cache *c = &hdev->inq_cache; | ||
193 | spin_lock_init(&c->lock); | ||
194 | c->list = NULL; | ||
195 | } | ||
196 | |||
197 | static inline int inquiry_cache_empty(struct hci_dev *hdev) | ||
198 | { | ||
199 | struct inquiry_cache *c = &hdev->inq_cache; | ||
200 | return (c->list == NULL); | ||
201 | } | ||
202 | |||
203 | static inline long inquiry_cache_age(struct hci_dev *hdev) | ||
204 | { | ||
205 | struct inquiry_cache *c = &hdev->inq_cache; | ||
206 | return jiffies - c->timestamp; | ||
207 | } | ||
208 | |||
209 | static inline long inquiry_entry_age(struct inquiry_entry *e) | ||
210 | { | ||
211 | return jiffies - e->timestamp; | ||
212 | } | ||
213 | |||
214 | struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr); | ||
215 | void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data); | ||
216 | |||
217 | /* ----- HCI Connections ----- */ | ||
218 | enum { | ||
219 | HCI_CONN_AUTH_PEND, | ||
220 | HCI_CONN_ENCRYPT_PEND, | ||
221 | HCI_CONN_RSWITCH_PEND | ||
222 | }; | ||
223 | |||
224 | static inline void hci_conn_hash_init(struct hci_dev *hdev) | ||
225 | { | ||
226 | struct hci_conn_hash *h = &hdev->conn_hash; | ||
227 | INIT_LIST_HEAD(&h->list); | ||
228 | spin_lock_init(&h->lock); | ||
229 | h->acl_num = 0; | ||
230 | h->sco_num = 0; | ||
231 | } | ||
232 | |||
233 | static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) | ||
234 | { | ||
235 | struct hci_conn_hash *h = &hdev->conn_hash; | ||
236 | list_add(&c->list, &h->list); | ||
237 | if (c->type == ACL_LINK) | ||
238 | h->acl_num++; | ||
239 | else | ||
240 | h->sco_num++; | ||
241 | } | ||
242 | |||
243 | static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) | ||
244 | { | ||
245 | struct hci_conn_hash *h = &hdev->conn_hash; | ||
246 | list_del(&c->list); | ||
247 | if (c->type == ACL_LINK) | ||
248 | h->acl_num--; | ||
249 | else | ||
250 | h->sco_num--; | ||
251 | } | ||
252 | |||
253 | static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev, | ||
254 | __u16 handle) | ||
255 | { | ||
256 | struct hci_conn_hash *h = &hdev->conn_hash; | ||
257 | struct list_head *p; | ||
258 | struct hci_conn *c; | ||
259 | |||
260 | list_for_each(p, &h->list) { | ||
261 | c = list_entry(p, struct hci_conn, list); | ||
262 | if (c->handle == handle) | ||
263 | return c; | ||
264 | } | ||
265 | return NULL; | ||
266 | } | ||
267 | |||
268 | static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev, | ||
269 | __u8 type, bdaddr_t *ba) | ||
270 | { | ||
271 | struct hci_conn_hash *h = &hdev->conn_hash; | ||
272 | struct list_head *p; | ||
273 | struct hci_conn *c; | ||
274 | |||
275 | list_for_each(p, &h->list) { | ||
276 | c = list_entry(p, struct hci_conn, list); | ||
277 | if (c->type == type && !bacmp(&c->dst, ba)) | ||
278 | return c; | ||
279 | } | ||
280 | return NULL; | ||
281 | } | ||
282 | |||
283 | void hci_acl_disconn(struct hci_conn *conn, __u8 reason); | ||
284 | void hci_add_sco(struct hci_conn *conn, __u16 handle); | ||
285 | |||
286 | struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst); | ||
287 | int hci_conn_del(struct hci_conn *conn); | ||
288 | void hci_conn_hash_flush(struct hci_dev *hdev); | ||
289 | |||
290 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src); | ||
291 | int hci_conn_auth(struct hci_conn *conn); | ||
292 | int hci_conn_encrypt(struct hci_conn *conn); | ||
293 | int hci_conn_change_link_key(struct hci_conn *conn); | ||
294 | int hci_conn_switch_role(struct hci_conn *conn, uint8_t role); | ||
295 | |||
296 | static inline void hci_conn_set_timer(struct hci_conn *conn, unsigned long timeout) | ||
297 | { | ||
298 | mod_timer(&conn->timer, jiffies + timeout); | ||
299 | } | ||
300 | |||
301 | static inline void hci_conn_del_timer(struct hci_conn *conn) | ||
302 | { | ||
303 | del_timer(&conn->timer); | ||
304 | } | ||
305 | |||
306 | static inline void hci_conn_hold(struct hci_conn *conn) | ||
307 | { | ||
308 | atomic_inc(&conn->refcnt); | ||
309 | hci_conn_del_timer(conn); | ||
310 | } | ||
311 | |||
312 | static inline void hci_conn_put(struct hci_conn *conn) | ||
313 | { | ||
314 | if (atomic_dec_and_test(&conn->refcnt)) { | ||
315 | if (conn->type == ACL_LINK) { | ||
316 | unsigned long timeo = (conn->out) ? | ||
317 | HCI_DISCONN_TIMEOUT : HCI_DISCONN_TIMEOUT * 2; | ||
318 | hci_conn_set_timer(conn, timeo); | ||
319 | } else | ||
320 | hci_conn_set_timer(conn, HZ / 100); | ||
321 | } | ||
322 | } | ||
323 | |||
324 | /* ----- HCI tasks ----- */ | ||
325 | static inline void hci_sched_cmd(struct hci_dev *hdev) | ||
326 | { | ||
327 | tasklet_schedule(&hdev->cmd_task); | ||
328 | } | ||
329 | |||
330 | static inline void hci_sched_rx(struct hci_dev *hdev) | ||
331 | { | ||
332 | tasklet_schedule(&hdev->rx_task); | ||
333 | } | ||
334 | |||
335 | static inline void hci_sched_tx(struct hci_dev *hdev) | ||
336 | { | ||
337 | tasklet_schedule(&hdev->tx_task); | ||
338 | } | ||
339 | |||
340 | /* ----- HCI Devices ----- */ | ||
341 | static inline void __hci_dev_put(struct hci_dev *d) | ||
342 | { | ||
343 | if (atomic_dec_and_test(&d->refcnt)) | ||
344 | d->destruct(d); | ||
345 | } | ||
346 | |||
347 | static inline void hci_dev_put(struct hci_dev *d) | ||
348 | { | ||
349 | __hci_dev_put(d); | ||
350 | module_put(d->owner); | ||
351 | } | ||
352 | |||
353 | static inline struct hci_dev *__hci_dev_hold(struct hci_dev *d) | ||
354 | { | ||
355 | atomic_inc(&d->refcnt); | ||
356 | return d; | ||
357 | } | ||
358 | |||
359 | static inline struct hci_dev *hci_dev_hold(struct hci_dev *d) | ||
360 | { | ||
361 | if (try_module_get(d->owner)) | ||
362 | return __hci_dev_hold(d); | ||
363 | return NULL; | ||
364 | } | ||
365 | |||
366 | #define hci_dev_lock(d) spin_lock(&d->lock) | ||
367 | #define hci_dev_unlock(d) spin_unlock(&d->lock) | ||
368 | #define hci_dev_lock_bh(d) spin_lock_bh(&d->lock) | ||
369 | #define hci_dev_unlock_bh(d) spin_unlock_bh(&d->lock) | ||
370 | |||
371 | struct hci_dev *hci_dev_get(int index); | ||
372 | struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst); | ||
373 | |||
374 | struct hci_dev *hci_alloc_dev(void); | ||
375 | void hci_free_dev(struct hci_dev *hdev); | ||
376 | int hci_register_dev(struct hci_dev *hdev); | ||
377 | int hci_unregister_dev(struct hci_dev *hdev); | ||
378 | int hci_suspend_dev(struct hci_dev *hdev); | ||
379 | int hci_resume_dev(struct hci_dev *hdev); | ||
380 | int hci_dev_open(__u16 dev); | ||
381 | int hci_dev_close(__u16 dev); | ||
382 | int hci_dev_reset(__u16 dev); | ||
383 | int hci_dev_reset_stat(__u16 dev); | ||
384 | int hci_dev_cmd(unsigned int cmd, void __user *arg); | ||
385 | int hci_get_dev_list(void __user *arg); | ||
386 | int hci_get_dev_info(void __user *arg); | ||
387 | int hci_get_conn_list(void __user *arg); | ||
388 | int hci_get_conn_info(struct hci_dev *hdev, void __user *arg); | ||
389 | int hci_inquiry(void __user *arg); | ||
390 | |||
391 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); | ||
392 | |||
393 | /* Receive frame from HCI drivers */ | ||
394 | static inline int hci_recv_frame(struct sk_buff *skb) | ||
395 | { | ||
396 | struct hci_dev *hdev = (struct hci_dev *) skb->dev; | ||
397 | if (!hdev || (!test_bit(HCI_UP, &hdev->flags) | ||
398 | && !test_bit(HCI_INIT, &hdev->flags))) { | ||
399 | kfree_skb(skb); | ||
400 | return -ENXIO; | ||
401 | } | ||
402 | |||
403 | /* Incomming skb */ | ||
404 | bt_cb(skb)->incoming = 1; | ||
405 | |||
406 | /* Time stamp */ | ||
407 | do_gettimeofday(&skb->stamp); | ||
408 | |||
409 | /* Queue frame for rx task */ | ||
410 | skb_queue_tail(&hdev->rx_q, skb); | ||
411 | hci_sched_rx(hdev); | ||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | int hci_register_sysfs(struct hci_dev *hdev); | ||
416 | void hci_unregister_sysfs(struct hci_dev *hdev); | ||
417 | |||
418 | #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->class_dev.dev = (pdev)) | ||
419 | |||
420 | /* ----- LMP capabilities ----- */ | ||
421 | #define lmp_rswitch_capable(dev) (dev->features[0] & LMP_RSWITCH) | ||
422 | #define lmp_encrypt_capable(dev) (dev->features[0] & LMP_ENCRYPT) | ||
423 | |||
424 | /* ----- HCI protocols ----- */ | ||
425 | struct hci_proto { | ||
426 | char *name; | ||
427 | unsigned int id; | ||
428 | unsigned long flags; | ||
429 | |||
430 | void *priv; | ||
431 | |||
432 | int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type); | ||
433 | int (*connect_cfm) (struct hci_conn *conn, __u8 status); | ||
434 | int (*disconn_ind) (struct hci_conn *conn, __u8 reason); | ||
435 | int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags); | ||
436 | int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb); | ||
437 | int (*auth_cfm) (struct hci_conn *conn, __u8 status); | ||
438 | int (*encrypt_cfm) (struct hci_conn *conn, __u8 status); | ||
439 | }; | ||
440 | |||
441 | static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) | ||
442 | { | ||
443 | register struct hci_proto *hp; | ||
444 | int mask = 0; | ||
445 | |||
446 | hp = hci_proto[HCI_PROTO_L2CAP]; | ||
447 | if (hp && hp->connect_ind) | ||
448 | mask |= hp->connect_ind(hdev, bdaddr, type); | ||
449 | |||
450 | hp = hci_proto[HCI_PROTO_SCO]; | ||
451 | if (hp && hp->connect_ind) | ||
452 | mask |= hp->connect_ind(hdev, bdaddr, type); | ||
453 | |||
454 | return mask; | ||
455 | } | ||
456 | |||
457 | static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status) | ||
458 | { | ||
459 | register struct hci_proto *hp; | ||
460 | |||
461 | hp = hci_proto[HCI_PROTO_L2CAP]; | ||
462 | if (hp && hp->connect_cfm) | ||
463 | hp->connect_cfm(conn, status); | ||
464 | |||
465 | hp = hci_proto[HCI_PROTO_SCO]; | ||
466 | if (hp && hp->connect_cfm) | ||
467 | hp->connect_cfm(conn, status); | ||
468 | } | ||
469 | |||
470 | static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason) | ||
471 | { | ||
472 | register struct hci_proto *hp; | ||
473 | |||
474 | hp = hci_proto[HCI_PROTO_L2CAP]; | ||
475 | if (hp && hp->disconn_ind) | ||
476 | hp->disconn_ind(conn, reason); | ||
477 | |||
478 | hp = hci_proto[HCI_PROTO_SCO]; | ||
479 | if (hp && hp->disconn_ind) | ||
480 | hp->disconn_ind(conn, reason); | ||
481 | } | ||
482 | |||
483 | static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) | ||
484 | { | ||
485 | register struct hci_proto *hp; | ||
486 | |||
487 | hp = hci_proto[HCI_PROTO_L2CAP]; | ||
488 | if (hp && hp->auth_cfm) | ||
489 | hp->auth_cfm(conn, status); | ||
490 | |||
491 | hp = hci_proto[HCI_PROTO_SCO]; | ||
492 | if (hp && hp->auth_cfm) | ||
493 | hp->auth_cfm(conn, status); | ||
494 | } | ||
495 | |||
496 | static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status) | ||
497 | { | ||
498 | register struct hci_proto *hp; | ||
499 | |||
500 | hp = hci_proto[HCI_PROTO_L2CAP]; | ||
501 | if (hp && hp->encrypt_cfm) | ||
502 | hp->encrypt_cfm(conn, status); | ||
503 | |||
504 | hp = hci_proto[HCI_PROTO_SCO]; | ||
505 | if (hp && hp->encrypt_cfm) | ||
506 | hp->encrypt_cfm(conn, status); | ||
507 | } | ||
508 | |||
509 | int hci_register_proto(struct hci_proto *hproto); | ||
510 | int hci_unregister_proto(struct hci_proto *hproto); | ||
511 | |||
512 | /* ----- HCI callbacks ----- */ | ||
513 | struct hci_cb { | ||
514 | struct list_head list; | ||
515 | |||
516 | char *name; | ||
517 | |||
518 | void (*auth_cfm) (struct hci_conn *conn, __u8 status); | ||
519 | void (*encrypt_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt); | ||
520 | void (*key_change_cfm) (struct hci_conn *conn, __u8 status); | ||
521 | void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role); | ||
522 | }; | ||
523 | |||
524 | static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) | ||
525 | { | ||
526 | struct list_head *p; | ||
527 | |||
528 | hci_proto_auth_cfm(conn, status); | ||
529 | |||
530 | read_lock_bh(&hci_cb_list_lock); | ||
531 | list_for_each(p, &hci_cb_list) { | ||
532 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); | ||
533 | if (cb->auth_cfm) | ||
534 | cb->auth_cfm(conn, status); | ||
535 | } | ||
536 | read_unlock_bh(&hci_cb_list_lock); | ||
537 | } | ||
538 | |||
539 | static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) | ||
540 | { | ||
541 | struct list_head *p; | ||
542 | |||
543 | hci_proto_encrypt_cfm(conn, status); | ||
544 | |||
545 | read_lock_bh(&hci_cb_list_lock); | ||
546 | list_for_each(p, &hci_cb_list) { | ||
547 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); | ||
548 | if (cb->encrypt_cfm) | ||
549 | cb->encrypt_cfm(conn, status, encrypt); | ||
550 | } | ||
551 | read_unlock_bh(&hci_cb_list_lock); | ||
552 | } | ||
553 | |||
554 | static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status) | ||
555 | { | ||
556 | struct list_head *p; | ||
557 | |||
558 | read_lock_bh(&hci_cb_list_lock); | ||
559 | list_for_each(p, &hci_cb_list) { | ||
560 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); | ||
561 | if (cb->key_change_cfm) | ||
562 | cb->key_change_cfm(conn, status); | ||
563 | } | ||
564 | read_unlock_bh(&hci_cb_list_lock); | ||
565 | } | ||
566 | |||
567 | static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, __u8 role) | ||
568 | { | ||
569 | struct list_head *p; | ||
570 | |||
571 | read_lock_bh(&hci_cb_list_lock); | ||
572 | list_for_each(p, &hci_cb_list) { | ||
573 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); | ||
574 | if (cb->role_switch_cfm) | ||
575 | cb->role_switch_cfm(conn, status, role); | ||
576 | } | ||
577 | read_unlock_bh(&hci_cb_list_lock); | ||
578 | } | ||
579 | |||
580 | int hci_register_cb(struct hci_cb *hcb); | ||
581 | int hci_unregister_cb(struct hci_cb *hcb); | ||
582 | |||
583 | int hci_register_notifier(struct notifier_block *nb); | ||
584 | int hci_unregister_notifier(struct notifier_block *nb); | ||
585 | |||
586 | int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param); | ||
587 | int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags); | ||
588 | int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); | ||
589 | |||
590 | void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf); | ||
591 | |||
592 | void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data); | ||
593 | |||
594 | /* ----- HCI Sockets ----- */ | ||
595 | void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); | ||
596 | |||
597 | /* HCI info for socket */ | ||
598 | #define hci_pi(sk) ((struct hci_pinfo *) sk) | ||
599 | |||
600 | struct hci_pinfo { | ||
601 | struct bt_sock bt; | ||
602 | struct hci_dev *hdev; | ||
603 | struct hci_filter filter; | ||
604 | __u32 cmsg_mask; | ||
605 | }; | ||
606 | |||
607 | /* HCI security filter */ | ||
608 | #define HCI_SFLT_MAX_OGF 5 | ||
609 | |||
610 | struct hci_sec_filter { | ||
611 | __u32 type_mask; | ||
612 | __u32 event_mask[2]; | ||
613 | __u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4]; | ||
614 | }; | ||
615 | |||
616 | /* ----- HCI requests ----- */ | ||
617 | #define HCI_REQ_DONE 0 | ||
618 | #define HCI_REQ_PEND 1 | ||
619 | #define HCI_REQ_CANCELED 2 | ||
620 | |||
621 | #define hci_req_lock(d) down(&d->req_lock) | ||
622 | #define hci_req_unlock(d) up(&d->req_lock) | ||
623 | |||
624 | void hci_req_complete(struct hci_dev *hdev, int result); | ||
625 | |||
626 | #endif /* __HCI_CORE_H */ | ||
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h new file mode 100644 index 000000000000..8242a0ee1f58 --- /dev/null +++ b/include/net/bluetooth/l2cap.h | |||
@@ -0,0 +1,238 @@ | |||
1 | /* | ||
2 | BlueZ - Bluetooth protocol stack for Linux | ||
3 | Copyright (C) 2000-2001 Qualcomm Incorporated | ||
4 | |||
5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License version 2 as | ||
9 | published by the Free Software Foundation; | ||
10 | |||
11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
12 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
14 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
15 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
16 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
17 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
18 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
19 | |||
20 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
21 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
22 | SOFTWARE IS DISCLAIMED. | ||
23 | */ | ||
24 | |||
25 | #ifndef __L2CAP_H | ||
26 | #define __L2CAP_H | ||
27 | |||
28 | /* L2CAP defaults */ | ||
29 | #define L2CAP_DEFAULT_MTU 672 | ||
30 | #define L2CAP_DEFAULT_FLUSH_TO 0xFFFF | ||
31 | |||
32 | #define L2CAP_CONN_TIMEOUT (HZ * 40) | ||
33 | |||
34 | /* L2CAP socket address */ | ||
35 | struct sockaddr_l2 { | ||
36 | sa_family_t l2_family; | ||
37 | unsigned short l2_psm; | ||
38 | bdaddr_t l2_bdaddr; | ||
39 | }; | ||
40 | |||
41 | /* L2CAP socket options */ | ||
42 | #define L2CAP_OPTIONS 0x01 | ||
43 | struct l2cap_options { | ||
44 | __u16 omtu; | ||
45 | __u16 imtu; | ||
46 | __u16 flush_to; | ||
47 | __u8 mode; | ||
48 | }; | ||
49 | |||
50 | #define L2CAP_CONNINFO 0x02 | ||
51 | struct l2cap_conninfo { | ||
52 | __u16 hci_handle; | ||
53 | __u8 dev_class[3]; | ||
54 | }; | ||
55 | |||
56 | #define L2CAP_LM 0x03 | ||
57 | #define L2CAP_LM_MASTER 0x0001 | ||
58 | #define L2CAP_LM_AUTH 0x0002 | ||
59 | #define L2CAP_LM_ENCRYPT 0x0004 | ||
60 | #define L2CAP_LM_TRUSTED 0x0008 | ||
61 | #define L2CAP_LM_RELIABLE 0x0010 | ||
62 | #define L2CAP_LM_SECURE 0x0020 | ||
63 | |||
64 | /* L2CAP command codes */ | ||
65 | #define L2CAP_COMMAND_REJ 0x01 | ||
66 | #define L2CAP_CONN_REQ 0x02 | ||
67 | #define L2CAP_CONN_RSP 0x03 | ||
68 | #define L2CAP_CONF_REQ 0x04 | ||
69 | #define L2CAP_CONF_RSP 0x05 | ||
70 | #define L2CAP_DISCONN_REQ 0x06 | ||
71 | #define L2CAP_DISCONN_RSP 0x07 | ||
72 | #define L2CAP_ECHO_REQ 0x08 | ||
73 | #define L2CAP_ECHO_RSP 0x09 | ||
74 | #define L2CAP_INFO_REQ 0x0a | ||
75 | #define L2CAP_INFO_RSP 0x0b | ||
76 | |||
77 | /* L2CAP structures */ | ||
78 | struct l2cap_hdr { | ||
79 | __u16 len; | ||
80 | __u16 cid; | ||
81 | } __attribute__ ((packed)); | ||
82 | #define L2CAP_HDR_SIZE 4 | ||
83 | |||
84 | struct l2cap_cmd_hdr { | ||
85 | __u8 code; | ||
86 | __u8 ident; | ||
87 | __u16 len; | ||
88 | } __attribute__ ((packed)); | ||
89 | #define L2CAP_CMD_HDR_SIZE 4 | ||
90 | |||
91 | struct l2cap_cmd_rej { | ||
92 | __u16 reason; | ||
93 | } __attribute__ ((packed)); | ||
94 | |||
95 | struct l2cap_conn_req { | ||
96 | __u16 psm; | ||
97 | __u16 scid; | ||
98 | } __attribute__ ((packed)); | ||
99 | |||
100 | struct l2cap_conn_rsp { | ||
101 | __u16 dcid; | ||
102 | __u16 scid; | ||
103 | __u16 result; | ||
104 | __u16 status; | ||
105 | } __attribute__ ((packed)); | ||
106 | |||
107 | /* connect result */ | ||
108 | #define L2CAP_CR_SUCCESS 0x0000 | ||
109 | #define L2CAP_CR_PEND 0x0001 | ||
110 | #define L2CAP_CR_BAD_PSM 0x0002 | ||
111 | #define L2CAP_CR_SEC_BLOCK 0x0003 | ||
112 | #define L2CAP_CR_NO_MEM 0x0004 | ||
113 | |||
114 | /* connect status */ | ||
115 | #define L2CAP_CS_NO_INFO 0x0000 | ||
116 | #define L2CAP_CS_AUTHEN_PEND 0x0001 | ||
117 | #define L2CAP_CS_AUTHOR_PEND 0x0002 | ||
118 | |||
119 | struct l2cap_conf_req { | ||
120 | __u16 dcid; | ||
121 | __u16 flags; | ||
122 | __u8 data[0]; | ||
123 | } __attribute__ ((packed)); | ||
124 | |||
125 | struct l2cap_conf_rsp { | ||
126 | __u16 scid; | ||
127 | __u16 flags; | ||
128 | __u16 result; | ||
129 | __u8 data[0]; | ||
130 | } __attribute__ ((packed)); | ||
131 | |||
132 | #define L2CAP_CONF_SUCCESS 0x00 | ||
133 | #define L2CAP_CONF_UNACCEPT 0x01 | ||
134 | |||
135 | struct l2cap_conf_opt { | ||
136 | __u8 type; | ||
137 | __u8 len; | ||
138 | __u8 val[0]; | ||
139 | } __attribute__ ((packed)); | ||
140 | #define L2CAP_CONF_OPT_SIZE 2 | ||
141 | |||
142 | #define L2CAP_CONF_MTU 0x01 | ||
143 | #define L2CAP_CONF_FLUSH_TO 0x02 | ||
144 | #define L2CAP_CONF_QOS 0x03 | ||
145 | #define L2CAP_CONF_RFC 0x04 | ||
146 | |||
147 | #define L2CAP_CONF_MAX_SIZE 22 | ||
148 | |||
149 | struct l2cap_disconn_req { | ||
150 | __u16 dcid; | ||
151 | __u16 scid; | ||
152 | } __attribute__ ((packed)); | ||
153 | |||
154 | struct l2cap_disconn_rsp { | ||
155 | __u16 dcid; | ||
156 | __u16 scid; | ||
157 | } __attribute__ ((packed)); | ||
158 | |||
159 | struct l2cap_info_req { | ||
160 | __u16 type; | ||
161 | __u8 data[0]; | ||
162 | } __attribute__ ((packed)); | ||
163 | |||
164 | struct l2cap_info_rsp { | ||
165 | __u16 type; | ||
166 | __u16 result; | ||
167 | __u8 data[0]; | ||
168 | } __attribute__ ((packed)); | ||
169 | |||
170 | /* info type */ | ||
171 | #define L2CAP_IT_CL_MTU 0x0001 | ||
172 | #define L2CAP_IT_FEAT_MASK 0x0002 | ||
173 | |||
174 | /* info result */ | ||
175 | #define L2CAP_IR_SUCCESS 0x0000 | ||
176 | #define L2CAP_IR_NOTSUPP 0x0001 | ||
177 | |||
178 | /* ----- L2CAP connections ----- */ | ||
179 | struct l2cap_chan_list { | ||
180 | struct sock *head; | ||
181 | rwlock_t lock; | ||
182 | long num; | ||
183 | }; | ||
184 | |||
185 | struct l2cap_conn { | ||
186 | struct hci_conn *hcon; | ||
187 | |||
188 | bdaddr_t *dst; | ||
189 | bdaddr_t *src; | ||
190 | |||
191 | unsigned int mtu; | ||
192 | |||
193 | spinlock_t lock; | ||
194 | |||
195 | struct sk_buff *rx_skb; | ||
196 | __u32 rx_len; | ||
197 | __u8 rx_ident; | ||
198 | __u8 tx_ident; | ||
199 | |||
200 | struct l2cap_chan_list chan_list; | ||
201 | }; | ||
202 | |||
203 | /* ----- L2CAP channel and socket info ----- */ | ||
204 | #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) | ||
205 | |||
206 | struct l2cap_pinfo { | ||
207 | struct bt_sock bt; | ||
208 | __u16 psm; | ||
209 | __u16 dcid; | ||
210 | __u16 scid; | ||
211 | |||
212 | __u16 imtu; | ||
213 | __u16 omtu; | ||
214 | __u16 flush_to; | ||
215 | |||
216 | __u32 link_mode; | ||
217 | |||
218 | __u8 conf_state; | ||
219 | __u8 conf_retry; | ||
220 | __u16 conf_mtu; | ||
221 | |||
222 | __u8 ident; | ||
223 | |||
224 | __u16 sport; | ||
225 | |||
226 | struct l2cap_conn *conn; | ||
227 | struct sock *next_c; | ||
228 | struct sock *prev_c; | ||
229 | }; | ||
230 | |||
231 | #define L2CAP_CONF_REQ_SENT 0x01 | ||
232 | #define L2CAP_CONF_INPUT_DONE 0x02 | ||
233 | #define L2CAP_CONF_OUTPUT_DONE 0x04 | ||
234 | #define L2CAP_CONF_MAX_RETRIES 2 | ||
235 | |||
236 | void l2cap_load(void); | ||
237 | |||
238 | #endif /* __L2CAP_H */ | ||
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h new file mode 100644 index 000000000000..13669bad00b3 --- /dev/null +++ b/include/net/bluetooth/rfcomm.h | |||
@@ -0,0 +1,353 @@ | |||
1 | /* | ||
2 | RFCOMM implementation for Linux Bluetooth stack (BlueZ). | ||
3 | Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com> | ||
4 | Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License version 2 as | ||
8 | published by the Free Software Foundation; | ||
9 | |||
10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
11 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
12 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
13 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
14 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
15 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
16 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
17 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
18 | |||
19 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
20 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
21 | SOFTWARE IS DISCLAIMED. | ||
22 | */ | ||
23 | |||
24 | #ifndef __RFCOMM_H | ||
25 | #define __RFCOMM_H | ||
26 | |||
27 | #define RFCOMM_PSM 3 | ||
28 | |||
29 | #define RFCOMM_CONN_TIMEOUT (HZ * 30) | ||
30 | #define RFCOMM_DISC_TIMEOUT (HZ * 20) | ||
31 | #define RFCOMM_AUTH_TIMEOUT (HZ * 25) | ||
32 | |||
33 | #define RFCOMM_DEFAULT_MTU 127 | ||
34 | #define RFCOMM_DEFAULT_CREDITS 7 | ||
35 | |||
36 | #define RFCOMM_MAX_L2CAP_MTU 1024 | ||
37 | #define RFCOMM_MAX_CREDITS 40 | ||
38 | |||
39 | #define RFCOMM_SKB_HEAD_RESERVE 8 | ||
40 | #define RFCOMM_SKB_TAIL_RESERVE 2 | ||
41 | #define RFCOMM_SKB_RESERVE (RFCOMM_SKB_HEAD_RESERVE + RFCOMM_SKB_TAIL_RESERVE) | ||
42 | |||
43 | #define RFCOMM_SABM 0x2f | ||
44 | #define RFCOMM_DISC 0x43 | ||
45 | #define RFCOMM_UA 0x63 | ||
46 | #define RFCOMM_DM 0x0f | ||
47 | #define RFCOMM_UIH 0xef | ||
48 | |||
49 | #define RFCOMM_TEST 0x08 | ||
50 | #define RFCOMM_FCON 0x28 | ||
51 | #define RFCOMM_FCOFF 0x18 | ||
52 | #define RFCOMM_MSC 0x38 | ||
53 | #define RFCOMM_RPN 0x24 | ||
54 | #define RFCOMM_RLS 0x14 | ||
55 | #define RFCOMM_PN 0x20 | ||
56 | #define RFCOMM_NSC 0x04 | ||
57 | |||
58 | #define RFCOMM_V24_FC 0x02 | ||
59 | #define RFCOMM_V24_RTC 0x04 | ||
60 | #define RFCOMM_V24_RTR 0x08 | ||
61 | #define RFCOMM_V24_IC 0x40 | ||
62 | #define RFCOMM_V24_DV 0x80 | ||
63 | |||
64 | #define RFCOMM_RPN_BR_2400 0x0 | ||
65 | #define RFCOMM_RPN_BR_4800 0x1 | ||
66 | #define RFCOMM_RPN_BR_7200 0x2 | ||
67 | #define RFCOMM_RPN_BR_9600 0x3 | ||
68 | #define RFCOMM_RPN_BR_19200 0x4 | ||
69 | #define RFCOMM_RPN_BR_38400 0x5 | ||
70 | #define RFCOMM_RPN_BR_57600 0x6 | ||
71 | #define RFCOMM_RPN_BR_115200 0x7 | ||
72 | #define RFCOMM_RPN_BR_230400 0x8 | ||
73 | |||
74 | #define RFCOMM_RPN_DATA_5 0x0 | ||
75 | #define RFCOMM_RPN_DATA_6 0x1 | ||
76 | #define RFCOMM_RPN_DATA_7 0x2 | ||
77 | #define RFCOMM_RPN_DATA_8 0x3 | ||
78 | |||
79 | #define RFCOMM_RPN_STOP_1 0 | ||
80 | #define RFCOMM_RPN_STOP_15 1 | ||
81 | |||
82 | #define RFCOMM_RPN_PARITY_NONE 0x0 | ||
83 | #define RFCOMM_RPN_PARITY_ODD 0x4 | ||
84 | #define RFCOMM_RPN_PARITY_EVEN 0x5 | ||
85 | #define RFCOMM_RPN_PARITY_MARK 0x6 | ||
86 | #define RFCOMM_RPN_PARITY_SPACE 0x7 | ||
87 | |||
88 | #define RFCOMM_RPN_FLOW_NONE 0x00 | ||
89 | |||
90 | #define RFCOMM_RPN_XON_CHAR 0x11 | ||
91 | #define RFCOMM_RPN_XOFF_CHAR 0x13 | ||
92 | |||
93 | #define RFCOMM_RPN_PM_BITRATE 0x0001 | ||
94 | #define RFCOMM_RPN_PM_DATA 0x0002 | ||
95 | #define RFCOMM_RPN_PM_STOP 0x0004 | ||
96 | #define RFCOMM_RPN_PM_PARITY 0x0008 | ||
97 | #define RFCOMM_RPN_PM_PARITY_TYPE 0x0010 | ||
98 | #define RFCOMM_RPN_PM_XON 0x0020 | ||
99 | #define RFCOMM_RPN_PM_XOFF 0x0040 | ||
100 | #define RFCOMM_RPN_PM_FLOW 0x3F00 | ||
101 | |||
102 | #define RFCOMM_RPN_PM_ALL 0x3F7F | ||
103 | |||
104 | struct rfcomm_hdr { | ||
105 | u8 addr; | ||
106 | u8 ctrl; | ||
107 | u8 len; // Actual size can be 2 bytes | ||
108 | } __attribute__ ((packed)); | ||
109 | |||
110 | struct rfcomm_cmd { | ||
111 | u8 addr; | ||
112 | u8 ctrl; | ||
113 | u8 len; | ||
114 | u8 fcs; | ||
115 | } __attribute__ ((packed)); | ||
116 | |||
117 | struct rfcomm_mcc { | ||
118 | u8 type; | ||
119 | u8 len; | ||
120 | } __attribute__ ((packed)); | ||
121 | |||
122 | struct rfcomm_pn { | ||
123 | u8 dlci; | ||
124 | u8 flow_ctrl; | ||
125 | u8 priority; | ||
126 | u8 ack_timer; | ||
127 | u16 mtu; | ||
128 | u8 max_retrans; | ||
129 | u8 credits; | ||
130 | } __attribute__ ((packed)); | ||
131 | |||
132 | struct rfcomm_rpn { | ||
133 | u8 dlci; | ||
134 | u8 bit_rate; | ||
135 | u8 line_settings; | ||
136 | u8 flow_ctrl; | ||
137 | u8 xon_char; | ||
138 | u8 xoff_char; | ||
139 | u16 param_mask; | ||
140 | } __attribute__ ((packed)); | ||
141 | |||
142 | struct rfcomm_rls { | ||
143 | u8 dlci; | ||
144 | u8 status; | ||
145 | } __attribute__ ((packed)); | ||
146 | |||
147 | struct rfcomm_msc { | ||
148 | u8 dlci; | ||
149 | u8 v24_sig; | ||
150 | } __attribute__ ((packed)); | ||
151 | |||
152 | /* ---- Core structures, flags etc ---- */ | ||
153 | |||
154 | struct rfcomm_session { | ||
155 | struct list_head list; | ||
156 | struct socket *sock; | ||
157 | unsigned long state; | ||
158 | unsigned long flags; | ||
159 | atomic_t refcnt; | ||
160 | int initiator; | ||
161 | |||
162 | /* Default DLC parameters */ | ||
163 | int cfc; | ||
164 | uint mtu; | ||
165 | |||
166 | struct list_head dlcs; | ||
167 | }; | ||
168 | |||
169 | struct rfcomm_dlc { | ||
170 | struct list_head list; | ||
171 | struct rfcomm_session *session; | ||
172 | struct sk_buff_head tx_queue; | ||
173 | struct timer_list timer; | ||
174 | |||
175 | spinlock_t lock; | ||
176 | unsigned long state; | ||
177 | unsigned long flags; | ||
178 | atomic_t refcnt; | ||
179 | u8 dlci; | ||
180 | u8 addr; | ||
181 | u8 priority; | ||
182 | u8 v24_sig; | ||
183 | u8 mscex; | ||
184 | |||
185 | u32 link_mode; | ||
186 | |||
187 | uint mtu; | ||
188 | uint cfc; | ||
189 | uint rx_credits; | ||
190 | uint tx_credits; | ||
191 | |||
192 | void *owner; | ||
193 | |||
194 | void (*data_ready)(struct rfcomm_dlc *d, struct sk_buff *skb); | ||
195 | void (*state_change)(struct rfcomm_dlc *d, int err); | ||
196 | void (*modem_status)(struct rfcomm_dlc *d, u8 v24_sig); | ||
197 | }; | ||
198 | |||
199 | /* DLC and session flags */ | ||
200 | #define RFCOMM_RX_THROTTLED 0 | ||
201 | #define RFCOMM_TX_THROTTLED 1 | ||
202 | #define RFCOMM_TIMED_OUT 2 | ||
203 | #define RFCOMM_MSC_PENDING 3 | ||
204 | #define RFCOMM_AUTH_PENDING 4 | ||
205 | #define RFCOMM_AUTH_ACCEPT 5 | ||
206 | #define RFCOMM_AUTH_REJECT 6 | ||
207 | |||
208 | /* Scheduling flags and events */ | ||
209 | #define RFCOMM_SCHED_STATE 0 | ||
210 | #define RFCOMM_SCHED_RX 1 | ||
211 | #define RFCOMM_SCHED_TX 2 | ||
212 | #define RFCOMM_SCHED_TIMEO 3 | ||
213 | #define RFCOMM_SCHED_AUTH 4 | ||
214 | #define RFCOMM_SCHED_WAKEUP 31 | ||
215 | |||
216 | /* MSC exchange flags */ | ||
217 | #define RFCOMM_MSCEX_TX 1 | ||
218 | #define RFCOMM_MSCEX_RX 2 | ||
219 | #define RFCOMM_MSCEX_OK (RFCOMM_MSCEX_TX + RFCOMM_MSCEX_RX) | ||
220 | |||
221 | /* CFC states */ | ||
222 | #define RFCOMM_CFC_UNKNOWN -1 | ||
223 | #define RFCOMM_CFC_DISABLED 0 | ||
224 | #define RFCOMM_CFC_ENABLED RFCOMM_MAX_CREDITS | ||
225 | |||
226 | /* ---- RFCOMM DLCs (channels) ---- */ | ||
227 | struct rfcomm_dlc *rfcomm_dlc_alloc(int prio); | ||
228 | void rfcomm_dlc_free(struct rfcomm_dlc *d); | ||
229 | int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel); | ||
230 | int rfcomm_dlc_close(struct rfcomm_dlc *d, int reason); | ||
231 | int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb); | ||
232 | int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig); | ||
233 | int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig); | ||
234 | |||
235 | #define rfcomm_dlc_lock(d) spin_lock(&d->lock) | ||
236 | #define rfcomm_dlc_unlock(d) spin_unlock(&d->lock) | ||
237 | |||
238 | static inline void rfcomm_dlc_hold(struct rfcomm_dlc *d) | ||
239 | { | ||
240 | atomic_inc(&d->refcnt); | ||
241 | } | ||
242 | |||
243 | static inline void rfcomm_dlc_put(struct rfcomm_dlc *d) | ||
244 | { | ||
245 | if (atomic_dec_and_test(&d->refcnt)) | ||
246 | rfcomm_dlc_free(d); | ||
247 | } | ||
248 | |||
249 | extern void FASTCALL(__rfcomm_dlc_throttle(struct rfcomm_dlc *d)); | ||
250 | extern void FASTCALL(__rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)); | ||
251 | |||
252 | static inline void rfcomm_dlc_throttle(struct rfcomm_dlc *d) | ||
253 | { | ||
254 | if (!test_and_set_bit(RFCOMM_RX_THROTTLED, &d->flags)) | ||
255 | __rfcomm_dlc_throttle(d); | ||
256 | } | ||
257 | |||
258 | static inline void rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) | ||
259 | { | ||
260 | if (test_and_clear_bit(RFCOMM_RX_THROTTLED, &d->flags)) | ||
261 | __rfcomm_dlc_unthrottle(d); | ||
262 | } | ||
263 | |||
264 | /* ---- RFCOMM sessions ---- */ | ||
265 | void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst); | ||
266 | |||
267 | static inline void rfcomm_session_hold(struct rfcomm_session *s) | ||
268 | { | ||
269 | atomic_inc(&s->refcnt); | ||
270 | } | ||
271 | |||
272 | /* ---- RFCOMM chechsum ---- */ | ||
273 | extern u8 rfcomm_crc_table[]; | ||
274 | |||
275 | /* ---- RFCOMM sockets ---- */ | ||
276 | struct sockaddr_rc { | ||
277 | sa_family_t rc_family; | ||
278 | bdaddr_t rc_bdaddr; | ||
279 | u8 rc_channel; | ||
280 | }; | ||
281 | |||
282 | #define RFCOMM_CONNINFO 0x02 | ||
283 | struct rfcomm_conninfo { | ||
284 | __u16 hci_handle; | ||
285 | __u8 dev_class[3]; | ||
286 | }; | ||
287 | |||
288 | #define RFCOMM_LM 0x03 | ||
289 | #define RFCOMM_LM_MASTER 0x0001 | ||
290 | #define RFCOMM_LM_AUTH 0x0002 | ||
291 | #define RFCOMM_LM_ENCRYPT 0x0004 | ||
292 | #define RFCOMM_LM_TRUSTED 0x0008 | ||
293 | #define RFCOMM_LM_RELIABLE 0x0010 | ||
294 | #define RFCOMM_LM_SECURE 0x0020 | ||
295 | |||
296 | #define rfcomm_pi(sk) ((struct rfcomm_pinfo *) sk) | ||
297 | |||
298 | struct rfcomm_pinfo { | ||
299 | struct bt_sock bt; | ||
300 | struct rfcomm_dlc *dlc; | ||
301 | u8 channel; | ||
302 | u32 link_mode; | ||
303 | }; | ||
304 | |||
305 | int rfcomm_init_sockets(void); | ||
306 | void rfcomm_cleanup_sockets(void); | ||
307 | |||
308 | int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d); | ||
309 | |||
310 | /* ---- RFCOMM TTY ---- */ | ||
311 | #define RFCOMM_MAX_DEV 256 | ||
312 | |||
313 | #define RFCOMMCREATEDEV _IOW('R', 200, int) | ||
314 | #define RFCOMMRELEASEDEV _IOW('R', 201, int) | ||
315 | #define RFCOMMGETDEVLIST _IOR('R', 210, int) | ||
316 | #define RFCOMMGETDEVINFO _IOR('R', 211, int) | ||
317 | #define RFCOMMSTEALDLC _IOW('R', 220, int) | ||
318 | |||
319 | #define RFCOMM_REUSE_DLC 0 | ||
320 | #define RFCOMM_RELEASE_ONHUP 1 | ||
321 | #define RFCOMM_HANGUP_NOW 2 | ||
322 | #define RFCOMM_TTY_ATTACHED 3 | ||
323 | |||
324 | struct rfcomm_dev_req { | ||
325 | s16 dev_id; | ||
326 | u32 flags; | ||
327 | bdaddr_t src; | ||
328 | bdaddr_t dst; | ||
329 | u8 channel; | ||
330 | |||
331 | }; | ||
332 | |||
333 | struct rfcomm_dev_info { | ||
334 | s16 id; | ||
335 | u32 flags; | ||
336 | u16 state; | ||
337 | bdaddr_t src; | ||
338 | bdaddr_t dst; | ||
339 | u8 channel; | ||
340 | }; | ||
341 | |||
342 | struct rfcomm_dev_list_req { | ||
343 | u16 dev_num; | ||
344 | struct rfcomm_dev_info dev_info[0]; | ||
345 | }; | ||
346 | |||
347 | int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg); | ||
348 | int rfcomm_init_ttys(void); | ||
349 | void rfcomm_cleanup_ttys(void); | ||
350 | |||
351 | extern struct proc_dir_entry *proc_bt_rfcomm; | ||
352 | |||
353 | #endif /* __RFCOMM_H */ | ||
diff --git a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h new file mode 100644 index 000000000000..e28a2a771471 --- /dev/null +++ b/include/net/bluetooth/sco.h | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | BlueZ - Bluetooth protocol stack for Linux | ||
3 | Copyright (C) 2000-2001 Qualcomm Incorporated | ||
4 | |||
5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License version 2 as | ||
9 | published by the Free Software Foundation; | ||
10 | |||
11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
12 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
14 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
15 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
16 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
17 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
18 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
19 | |||
20 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
21 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
22 | SOFTWARE IS DISCLAIMED. | ||
23 | */ | ||
24 | |||
25 | #ifndef __SCO_H | ||
26 | #define __SCO_H | ||
27 | |||
28 | /* SCO defaults */ | ||
29 | #define SCO_DEFAULT_MTU 500 | ||
30 | #define SCO_DEFAULT_FLUSH_TO 0xFFFF | ||
31 | |||
32 | #define SCO_CONN_TIMEOUT (HZ * 40) | ||
33 | #define SCO_DISCONN_TIMEOUT (HZ * 2) | ||
34 | #define SCO_CONN_IDLE_TIMEOUT (HZ * 60) | ||
35 | |||
36 | /* SCO socket address */ | ||
37 | struct sockaddr_sco { | ||
38 | sa_family_t sco_family; | ||
39 | bdaddr_t sco_bdaddr; | ||
40 | }; | ||
41 | |||
42 | /* SCO socket options */ | ||
43 | #define SCO_OPTIONS 0x01 | ||
44 | struct sco_options { | ||
45 | __u16 mtu; | ||
46 | }; | ||
47 | |||
48 | #define SCO_CONNINFO 0x02 | ||
49 | struct sco_conninfo { | ||
50 | __u16 hci_handle; | ||
51 | __u8 dev_class[3]; | ||
52 | }; | ||
53 | |||
54 | /* ---- SCO connections ---- */ | ||
55 | struct sco_conn { | ||
56 | struct hci_conn *hcon; | ||
57 | |||
58 | bdaddr_t *dst; | ||
59 | bdaddr_t *src; | ||
60 | |||
61 | spinlock_t lock; | ||
62 | struct sock *sk; | ||
63 | |||
64 | unsigned int mtu; | ||
65 | }; | ||
66 | |||
67 | #define sco_conn_lock(c) spin_lock(&c->lock); | ||
68 | #define sco_conn_unlock(c) spin_unlock(&c->lock); | ||
69 | |||
70 | /* ----- SCO socket info ----- */ | ||
71 | #define sco_pi(sk) ((struct sco_pinfo *) sk) | ||
72 | |||
73 | struct sco_pinfo { | ||
74 | struct bt_sock bt; | ||
75 | __u32 flags; | ||
76 | struct sco_conn *conn; | ||
77 | }; | ||
78 | |||
79 | #endif /* __SCO_H */ | ||
diff --git a/include/net/checksum.h b/include/net/checksum.h new file mode 100644 index 000000000000..e3ea7cc2c728 --- /dev/null +++ b/include/net/checksum.h | |||
@@ -0,0 +1,87 @@ | |||
1 | /* | ||
2 | * INET An implementation of the TCP/IP protocol suite for the LINUX | ||
3 | * operating system. INET is implemented using the BSD Socket | ||
4 | * interface as the means of communication with the user level. | ||
5 | * | ||
6 | * Checksumming functions for IP, TCP, UDP and so on | ||
7 | * | ||
8 | * Authors: Jorge Cwik, <jorge@laser.satlink.net> | ||
9 | * Arnt Gulbrandsen, <agulbra@nvg.unit.no> | ||
10 | * Borrows very liberally from tcp.c and ip.c, see those | ||
11 | * files for more names. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version | ||
16 | * 2 of the License, or (at your option) any later version. | ||
17 | */ | ||
18 | |||
19 | #ifndef _CHECKSUM_H | ||
20 | #define _CHECKSUM_H | ||
21 | |||
22 | #include <linux/errno.h> | ||
23 | #include <asm/types.h> | ||
24 | #include <asm/byteorder.h> | ||
25 | #include <asm/uaccess.h> | ||
26 | #include <asm/checksum.h> | ||
27 | |||
28 | #ifndef _HAVE_ARCH_COPY_AND_CSUM_FROM_USER | ||
29 | static inline | ||
30 | unsigned int csum_and_copy_from_user (const unsigned char __user *src, unsigned char *dst, | ||
31 | int len, int sum, int *err_ptr) | ||
32 | { | ||
33 | if (access_ok(VERIFY_READ, src, len)) | ||
34 | return csum_partial_copy_from_user(src, dst, len, sum, err_ptr); | ||
35 | |||
36 | if (len) | ||
37 | *err_ptr = -EFAULT; | ||
38 | |||
39 | return sum; | ||
40 | } | ||
41 | #endif | ||
42 | |||
43 | #ifndef HAVE_CSUM_COPY_USER | ||
44 | static __inline__ unsigned int csum_and_copy_to_user | ||
45 | (const unsigned char *src, unsigned char __user *dst, int len, unsigned int sum, int *err_ptr) | ||
46 | { | ||
47 | sum = csum_partial(src, len, sum); | ||
48 | |||
49 | if (access_ok(VERIFY_WRITE, dst, len)) { | ||
50 | if (copy_to_user(dst, src, len) == 0) | ||
51 | return sum; | ||
52 | } | ||
53 | if (len) | ||
54 | *err_ptr = -EFAULT; | ||
55 | |||
56 | return -1; /* invalid checksum */ | ||
57 | } | ||
58 | #endif | ||
59 | |||
60 | static inline unsigned int csum_add(unsigned int csum, unsigned int addend) | ||
61 | { | ||
62 | csum += addend; | ||
63 | return csum + (csum < addend); | ||
64 | } | ||
65 | |||
66 | static inline unsigned int csum_sub(unsigned int csum, unsigned int addend) | ||
67 | { | ||
68 | return csum_add(csum, ~addend); | ||
69 | } | ||
70 | |||
71 | static inline unsigned int | ||
72 | csum_block_add(unsigned int csum, unsigned int csum2, int offset) | ||
73 | { | ||
74 | if (offset&1) | ||
75 | csum2 = ((csum2&0xFF00FF)<<8)+((csum2>>8)&0xFF00FF); | ||
76 | return csum_add(csum, csum2); | ||
77 | } | ||
78 | |||
79 | static inline unsigned int | ||
80 | csum_block_sub(unsigned int csum, unsigned int csum2, int offset) | ||
81 | { | ||
82 | if (offset&1) | ||
83 | csum2 = ((csum2&0xFF00FF)<<8)+((csum2>>8)&0xFF00FF); | ||
84 | return csum_sub(csum, csum2); | ||
85 | } | ||
86 | |||
87 | #endif | ||
diff --git a/include/net/compat.h b/include/net/compat.h new file mode 100644 index 000000000000..9983fd857804 --- /dev/null +++ b/include/net/compat.h | |||
@@ -0,0 +1,39 @@ | |||
1 | #ifndef NET_COMPAT_H | ||
2 | #define NET_COMPAT_H | ||
3 | |||
4 | #include <linux/config.h> | ||
5 | |||
6 | #if defined(CONFIG_COMPAT) | ||
7 | |||
8 | #include <linux/compat.h> | ||
9 | |||
10 | struct compat_msghdr { | ||
11 | compat_uptr_t msg_name; /* void * */ | ||
12 | compat_int_t msg_namelen; | ||
13 | compat_uptr_t msg_iov; /* struct compat_iovec * */ | ||
14 | compat_size_t msg_iovlen; | ||
15 | compat_uptr_t msg_control; /* void * */ | ||
16 | compat_size_t msg_controllen; | ||
17 | compat_uint_t msg_flags; | ||
18 | }; | ||
19 | |||
20 | struct compat_cmsghdr { | ||
21 | compat_size_t cmsg_len; | ||
22 | compat_int_t cmsg_level; | ||
23 | compat_int_t cmsg_type; | ||
24 | }; | ||
25 | |||
26 | #else /* defined(CONFIG_COMPAT) */ | ||
27 | #define compat_msghdr msghdr /* to avoid compiler warnings */ | ||
28 | #endif /* defined(CONFIG_COMPAT) */ | ||
29 | |||
30 | extern int get_compat_msghdr(struct msghdr *, struct compat_msghdr __user *); | ||
31 | extern int verify_compat_iovec(struct msghdr *, struct iovec *, char *, int); | ||
32 | extern asmlinkage long compat_sys_sendmsg(int,struct compat_msghdr __user *,unsigned); | ||
33 | extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr __user *,unsigned); | ||
34 | extern asmlinkage long compat_sys_getsockopt(int, int, int, char __user *, int __user *); | ||
35 | extern int put_cmsg_compat(struct msghdr*, int, int, int, void *); | ||
36 | extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, unsigned char *, | ||
37 | int); | ||
38 | |||
39 | #endif /* NET_COMPAT_H */ | ||
diff --git a/include/net/datalink.h b/include/net/datalink.h new file mode 100644 index 000000000000..5797ba3d2eb5 --- /dev/null +++ b/include/net/datalink.h | |||
@@ -0,0 +1,18 @@ | |||
1 | #ifndef _NET_INET_DATALINK_H_ | ||
2 | #define _NET_INET_DATALINK_H_ | ||
3 | |||
4 | struct datalink_proto { | ||
5 | unsigned char type[8]; | ||
6 | |||
7 | struct llc_sap *sap; | ||
8 | |||
9 | unsigned short header_length; | ||
10 | |||
11 | int (*rcvfunc)(struct sk_buff *, struct net_device *, | ||
12 | struct packet_type *); | ||
13 | int (*request)(struct datalink_proto *, struct sk_buff *, | ||
14 | unsigned char *); | ||
15 | struct list_head node; | ||
16 | }; | ||
17 | |||
18 | #endif | ||
diff --git a/include/net/dn.h b/include/net/dn.h new file mode 100644 index 000000000000..5551c46db397 --- /dev/null +++ b/include/net/dn.h | |||
@@ -0,0 +1,236 @@ | |||
1 | #ifndef _NET_DN_H | ||
2 | #define _NET_DN_H | ||
3 | |||
4 | #include <linux/dn.h> | ||
5 | #include <net/sock.h> | ||
6 | #include <asm/byteorder.h> | ||
7 | |||
8 | typedef unsigned short dn_address; | ||
9 | |||
10 | #define dn_ntohs(x) le16_to_cpu((unsigned short)(x)) | ||
11 | #define dn_htons(x) cpu_to_le16((unsigned short)(x)) | ||
12 | |||
13 | struct dn_scp /* Session Control Port */ | ||
14 | { | ||
15 | unsigned char state; | ||
16 | #define DN_O 1 /* Open */ | ||
17 | #define DN_CR 2 /* Connect Receive */ | ||
18 | #define DN_DR 3 /* Disconnect Reject */ | ||
19 | #define DN_DRC 4 /* Discon. Rej. Complete*/ | ||
20 | #define DN_CC 5 /* Connect Confirm */ | ||
21 | #define DN_CI 6 /* Connect Initiate */ | ||
22 | #define DN_NR 7 /* No resources */ | ||
23 | #define DN_NC 8 /* No communication */ | ||
24 | #define DN_CD 9 /* Connect Delivery */ | ||
25 | #define DN_RJ 10 /* Rejected */ | ||
26 | #define DN_RUN 11 /* Running */ | ||
27 | #define DN_DI 12 /* Disconnect Initiate */ | ||
28 | #define DN_DIC 13 /* Disconnect Complete */ | ||
29 | #define DN_DN 14 /* Disconnect Notificat */ | ||
30 | #define DN_CL 15 /* Closed */ | ||
31 | #define DN_CN 16 /* Closed Notification */ | ||
32 | |||
33 | unsigned short addrloc; | ||
34 | unsigned short addrrem; | ||
35 | unsigned short numdat; | ||
36 | unsigned short numoth; | ||
37 | unsigned short numoth_rcv; | ||
38 | unsigned short numdat_rcv; | ||
39 | unsigned short ackxmt_dat; | ||
40 | unsigned short ackxmt_oth; | ||
41 | unsigned short ackrcv_dat; | ||
42 | unsigned short ackrcv_oth; | ||
43 | unsigned char flowrem_sw; | ||
44 | unsigned char flowloc_sw; | ||
45 | #define DN_SEND 2 | ||
46 | #define DN_DONTSEND 1 | ||
47 | #define DN_NOCHANGE 0 | ||
48 | unsigned short flowrem_dat; | ||
49 | unsigned short flowrem_oth; | ||
50 | unsigned short flowloc_dat; | ||
51 | unsigned short flowloc_oth; | ||
52 | unsigned char services_rem; | ||
53 | unsigned char services_loc; | ||
54 | unsigned char info_rem; | ||
55 | unsigned char info_loc; | ||
56 | |||
57 | unsigned short segsize_rem; | ||
58 | unsigned short segsize_loc; | ||
59 | |||
60 | unsigned char nonagle; | ||
61 | unsigned char multi_ireq; | ||
62 | unsigned char accept_mode; | ||
63 | unsigned long seg_total; /* Running total of current segment */ | ||
64 | |||
65 | struct optdata_dn conndata_in; | ||
66 | struct optdata_dn conndata_out; | ||
67 | struct optdata_dn discdata_in; | ||
68 | struct optdata_dn discdata_out; | ||
69 | struct accessdata_dn accessdata; | ||
70 | |||
71 | struct sockaddr_dn addr; /* Local address */ | ||
72 | struct sockaddr_dn peer; /* Remote address */ | ||
73 | |||
74 | /* | ||
75 | * In this case the RTT estimation is not specified in the | ||
76 | * docs, nor is any back off algorithm. Here we follow well | ||
77 | * known tcp algorithms with a few small variations. | ||
78 | * | ||
79 | * snd_window: Max number of packets we send before we wait for | ||
80 | * an ack to come back. This will become part of a | ||
81 | * more complicated scheme when we support flow | ||
82 | * control. | ||
83 | * | ||
84 | * nsp_srtt: Round-Trip-Time (x8) in jiffies. This is a rolling | ||
85 | * average. | ||
86 | * nsp_rttvar: Round-Trip-Time-Varience (x4) in jiffies. This is the | ||
87 | * varience of the smoothed average (but calculated in | ||
88 | * a simpler way than for normal statistical varience | ||
89 | * calculations). | ||
90 | * | ||
91 | * nsp_rxtshift: Backoff counter. Value is zero normally, each time | ||
92 | * a packet is lost is increases by one until an ack | ||
93 | * is received. Its used to index an array of backoff | ||
94 | * multipliers. | ||
95 | */ | ||
96 | #define NSP_MIN_WINDOW 1 | ||
97 | #define NSP_MAX_WINDOW (0x07fe) | ||
98 | unsigned long max_window; | ||
99 | unsigned long snd_window; | ||
100 | #define NSP_INITIAL_SRTT (HZ) | ||
101 | unsigned long nsp_srtt; | ||
102 | #define NSP_INITIAL_RTTVAR (HZ*3) | ||
103 | unsigned long nsp_rttvar; | ||
104 | #define NSP_MAXRXTSHIFT 12 | ||
105 | unsigned long nsp_rxtshift; | ||
106 | |||
107 | /* | ||
108 | * Output queues, one for data, one for otherdata/linkservice | ||
109 | */ | ||
110 | struct sk_buff_head data_xmit_queue; | ||
111 | struct sk_buff_head other_xmit_queue; | ||
112 | |||
113 | /* | ||
114 | * Input queue for other data | ||
115 | */ | ||
116 | struct sk_buff_head other_receive_queue; | ||
117 | int other_report; | ||
118 | |||
119 | /* | ||
120 | * Stuff to do with the slow timer | ||
121 | */ | ||
122 | unsigned long stamp; /* time of last transmit */ | ||
123 | unsigned long persist; | ||
124 | int (*persist_fxn)(struct sock *sk); | ||
125 | unsigned long keepalive; | ||
126 | void (*keepalive_fxn)(struct sock *sk); | ||
127 | |||
128 | /* | ||
129 | * This stuff is for the fast timer for delayed acks | ||
130 | */ | ||
131 | struct timer_list delack_timer; | ||
132 | int delack_pending; | ||
133 | void (*delack_fxn)(struct sock *sk); | ||
134 | |||
135 | }; | ||
136 | |||
137 | static inline struct dn_scp *DN_SK(struct sock *sk) | ||
138 | { | ||
139 | return (struct dn_scp *)(sk + 1); | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * src,dst : Source and Destination DECnet addresses | ||
144 | * hops : Number of hops through the network | ||
145 | * dst_port, src_port : NSP port numbers | ||
146 | * services, info : Useful data extracted from conninit messages | ||
147 | * rt_flags : Routing flags byte | ||
148 | * nsp_flags : NSP layer flags byte | ||
149 | * segsize : Size of segment | ||
150 | * segnum : Number, for data, otherdata and linkservice | ||
151 | * xmit_count : Number of times we've transmitted this skb | ||
152 | * stamp : Time stamp of most recent transmission, used in RTT calculations | ||
153 | * iif: Input interface number | ||
154 | * | ||
155 | * As a general policy, this structure keeps all addresses in network | ||
156 | * byte order, and all else in host byte order. Thus dst, src, dst_port | ||
157 | * and src_port are in network order. All else is in host order. | ||
158 | * | ||
159 | */ | ||
160 | #define DN_SKB_CB(skb) ((struct dn_skb_cb *)(skb)->cb) | ||
161 | struct dn_skb_cb { | ||
162 | unsigned short dst; | ||
163 | unsigned short src; | ||
164 | unsigned short hops; | ||
165 | unsigned short dst_port; | ||
166 | unsigned short src_port; | ||
167 | unsigned char services; | ||
168 | unsigned char info; | ||
169 | unsigned char rt_flags; | ||
170 | unsigned char nsp_flags; | ||
171 | unsigned short segsize; | ||
172 | unsigned short segnum; | ||
173 | unsigned short xmit_count; | ||
174 | unsigned long stamp; | ||
175 | int iif; | ||
176 | }; | ||
177 | |||
178 | static inline dn_address dn_eth2dn(unsigned char *ethaddr) | ||
179 | { | ||
180 | return ethaddr[4] | (ethaddr[5] << 8); | ||
181 | } | ||
182 | |||
183 | static inline dn_address dn_saddr2dn(struct sockaddr_dn *saddr) | ||
184 | { | ||
185 | return *(dn_address *)saddr->sdn_nodeaddr; | ||
186 | } | ||
187 | |||
188 | static inline void dn_dn2eth(unsigned char *ethaddr, dn_address addr) | ||
189 | { | ||
190 | ethaddr[0] = 0xAA; | ||
191 | ethaddr[1] = 0x00; | ||
192 | ethaddr[2] = 0x04; | ||
193 | ethaddr[3] = 0x00; | ||
194 | ethaddr[4] = (unsigned char)(addr & 0xff); | ||
195 | ethaddr[5] = (unsigned char)(addr >> 8); | ||
196 | } | ||
197 | |||
198 | static inline void dn_sk_ports_copy(struct flowi *fl, struct dn_scp *scp) | ||
199 | { | ||
200 | fl->uli_u.dnports.sport = scp->addrloc; | ||
201 | fl->uli_u.dnports.dport = scp->addrrem; | ||
202 | fl->uli_u.dnports.objnum = scp->addr.sdn_objnum; | ||
203 | if (fl->uli_u.dnports.objnum == 0) { | ||
204 | fl->uli_u.dnports.objnamel = scp->addr.sdn_objnamel; | ||
205 | memcpy(fl->uli_u.dnports.objname, scp->addr.sdn_objname, 16); | ||
206 | } | ||
207 | } | ||
208 | |||
209 | extern unsigned dn_mss_from_pmtu(struct net_device *dev, int mtu); | ||
210 | |||
211 | #define DN_MENUVER_ACC 0x01 | ||
212 | #define DN_MENUVER_USR 0x02 | ||
213 | #define DN_MENUVER_PRX 0x04 | ||
214 | #define DN_MENUVER_UIC 0x08 | ||
215 | |||
216 | extern struct sock *dn_sklist_find_listener(struct sockaddr_dn *addr); | ||
217 | extern struct sock *dn_find_by_skb(struct sk_buff *skb); | ||
218 | #define DN_ASCBUF_LEN 9 | ||
219 | extern char *dn_addr2asc(dn_address, char *); | ||
220 | extern int dn_destroy_timer(struct sock *sk); | ||
221 | |||
222 | extern int dn_sockaddr2username(struct sockaddr_dn *addr, unsigned char *buf, unsigned char type); | ||
223 | extern int dn_username2sockaddr(unsigned char *data, int len, struct sockaddr_dn *addr, unsigned char *type); | ||
224 | |||
225 | extern void dn_start_slow_timer(struct sock *sk); | ||
226 | extern void dn_stop_slow_timer(struct sock *sk); | ||
227 | |||
228 | extern dn_address decnet_address; | ||
229 | extern int decnet_debug_level; | ||
230 | extern int decnet_time_wait; | ||
231 | extern int decnet_dn_count; | ||
232 | extern int decnet_di_count; | ||
233 | extern int decnet_dr_count; | ||
234 | extern int decnet_no_fc_max_cwnd; | ||
235 | |||
236 | #endif /* _NET_DN_H */ | ||
diff --git a/include/net/dn_dev.h b/include/net/dn_dev.h new file mode 100644 index 000000000000..86e8e86e624a --- /dev/null +++ b/include/net/dn_dev.h | |||
@@ -0,0 +1,194 @@ | |||
1 | #ifndef _NET_DN_DEV_H | ||
2 | #define _NET_DN_DEV_H | ||
3 | |||
4 | |||
5 | struct dn_dev; | ||
6 | |||
7 | struct dn_ifaddr { | ||
8 | struct dn_ifaddr *ifa_next; | ||
9 | struct dn_dev *ifa_dev; | ||
10 | dn_address ifa_local; | ||
11 | dn_address ifa_address; | ||
12 | unsigned char ifa_flags; | ||
13 | unsigned char ifa_scope; | ||
14 | char ifa_label[IFNAMSIZ]; | ||
15 | }; | ||
16 | |||
17 | #define DN_DEV_S_RU 0 /* Run - working normally */ | ||
18 | #define DN_DEV_S_CR 1 /* Circuit Rejected */ | ||
19 | #define DN_DEV_S_DS 2 /* Data Link Start */ | ||
20 | #define DN_DEV_S_RI 3 /* Routing Layer Initialize */ | ||
21 | #define DN_DEV_S_RV 4 /* Routing Layer Verify */ | ||
22 | #define DN_DEV_S_RC 5 /* Routing Layer Complete */ | ||
23 | #define DN_DEV_S_OF 6 /* Off */ | ||
24 | #define DN_DEV_S_HA 7 /* Halt */ | ||
25 | |||
26 | |||
27 | /* | ||
28 | * The dn_dev_parms structure contains the set of parameters | ||
29 | * for each device (hence inclusion in the dn_dev structure) | ||
30 | * and an array is used to store the default types of supported | ||
31 | * device (in dn_dev.c). | ||
32 | * | ||
33 | * The type field matches the ARPHRD_ constants and is used in | ||
34 | * searching the list for supported devices when new devices | ||
35 | * come up. | ||
36 | * | ||
37 | * The mode field is used to find out if a device is broadcast, | ||
38 | * multipoint, or pointopoint. Please note that DECnet thinks | ||
39 | * different ways about devices to the rest of the kernel | ||
40 | * so the normal IFF_xxx flags are invalid here. For devices | ||
41 | * which can be any combination of the previously mentioned | ||
42 | * attributes, you can set this on a per device basis by | ||
43 | * installing an up() routine. | ||
44 | * | ||
45 | * The device state field, defines the initial state in which the | ||
46 | * device will come up. In the dn_dev structure, it is the actual | ||
47 | * state. | ||
48 | * | ||
49 | * Things have changed here. I've killed timer1 since it's a user space | ||
50 | * issue for a user space routing deamon to sort out. The kernel does | ||
51 | * not need to be bothered with it. | ||
52 | * | ||
53 | * Timers: | ||
54 | * t2 - Rate limit timer, min time between routing and hello messages | ||
55 | * t3 - Hello timer, send hello messages when it expires | ||
56 | * | ||
57 | * Callbacks: | ||
58 | * up() - Called to initialize device, return value can veto use of | ||
59 | * device with DECnet. | ||
60 | * down() - Called to turn device off when it goes down | ||
61 | * timer3() - Called once for each ifaddr when timer 3 goes off | ||
62 | * | ||
63 | * sysctl - Hook for sysctl things | ||
64 | * | ||
65 | */ | ||
66 | struct dn_dev_parms { | ||
67 | int type; /* ARPHRD_xxx */ | ||
68 | int mode; /* Broadcast, Unicast, Mulitpoint */ | ||
69 | #define DN_DEV_BCAST 1 | ||
70 | #define DN_DEV_UCAST 2 | ||
71 | #define DN_DEV_MPOINT 4 | ||
72 | int state; /* Initial state */ | ||
73 | int forwarding; /* 0=EndNode, 1=L1Router, 2=L2Router */ | ||
74 | unsigned long t2; /* Default value of t2 */ | ||
75 | unsigned long t3; /* Default value of t3 */ | ||
76 | int priority; /* Priority to be a router */ | ||
77 | char *name; /* Name for sysctl */ | ||
78 | int ctl_name; /* Index for sysctl */ | ||
79 | int (*up)(struct net_device *); | ||
80 | void (*down)(struct net_device *); | ||
81 | void (*timer3)(struct net_device *, struct dn_ifaddr *ifa); | ||
82 | void *sysctl; | ||
83 | }; | ||
84 | |||
85 | |||
86 | struct dn_dev { | ||
87 | struct dn_ifaddr *ifa_list; | ||
88 | struct net_device *dev; | ||
89 | struct dn_dev_parms parms; | ||
90 | char use_long; | ||
91 | struct timer_list timer; | ||
92 | unsigned long t3; | ||
93 | struct neigh_parms *neigh_parms; | ||
94 | unsigned char addr[ETH_ALEN]; | ||
95 | struct neighbour *router; /* Default router on circuit */ | ||
96 | struct neighbour *peer; /* Peer on pointopoint links */ | ||
97 | unsigned long uptime; /* Time device went up in jiffies */ | ||
98 | }; | ||
99 | |||
100 | struct dn_short_packet | ||
101 | { | ||
102 | unsigned char msgflg __attribute__((packed)); | ||
103 | unsigned short dstnode __attribute__((packed)); | ||
104 | unsigned short srcnode __attribute__((packed)); | ||
105 | unsigned char forward __attribute__((packed)); | ||
106 | }; | ||
107 | |||
108 | struct dn_long_packet | ||
109 | { | ||
110 | unsigned char msgflg __attribute__((packed)); | ||
111 | unsigned char d_area __attribute__((packed)); | ||
112 | unsigned char d_subarea __attribute__((packed)); | ||
113 | unsigned char d_id[6] __attribute__((packed)); | ||
114 | unsigned char s_area __attribute__((packed)); | ||
115 | unsigned char s_subarea __attribute__((packed)); | ||
116 | unsigned char s_id[6] __attribute__((packed)); | ||
117 | unsigned char nl2 __attribute__((packed)); | ||
118 | unsigned char visit_ct __attribute__((packed)); | ||
119 | unsigned char s_class __attribute__((packed)); | ||
120 | unsigned char pt __attribute__((packed)); | ||
121 | }; | ||
122 | |||
123 | /*------------------------- DRP - Routing messages ---------------------*/ | ||
124 | |||
125 | struct endnode_hello_message | ||
126 | { | ||
127 | unsigned char msgflg __attribute__((packed)); | ||
128 | unsigned char tiver[3] __attribute__((packed)); | ||
129 | unsigned char id[6] __attribute__((packed)); | ||
130 | unsigned char iinfo __attribute__((packed)); | ||
131 | unsigned short blksize __attribute__((packed)); | ||
132 | unsigned char area __attribute__((packed)); | ||
133 | unsigned char seed[8] __attribute__((packed)); | ||
134 | unsigned char neighbor[6] __attribute__((packed)); | ||
135 | unsigned short timer __attribute__((packed)); | ||
136 | unsigned char mpd __attribute__((packed)); | ||
137 | unsigned char datalen __attribute__((packed)); | ||
138 | unsigned char data[2] __attribute__((packed)); | ||
139 | }; | ||
140 | |||
141 | struct rtnode_hello_message | ||
142 | { | ||
143 | unsigned char msgflg __attribute__((packed)); | ||
144 | unsigned char tiver[3] __attribute__((packed)); | ||
145 | unsigned char id[6] __attribute__((packed)); | ||
146 | unsigned char iinfo __attribute__((packed)); | ||
147 | unsigned short blksize __attribute__((packed)); | ||
148 | unsigned char priority __attribute__((packed)); | ||
149 | unsigned char area __attribute__((packed)); | ||
150 | unsigned short timer __attribute__((packed)); | ||
151 | unsigned char mpd __attribute__((packed)); | ||
152 | }; | ||
153 | |||
154 | |||
155 | extern void dn_dev_init(void); | ||
156 | extern void dn_dev_cleanup(void); | ||
157 | |||
158 | extern int dn_dev_ioctl(unsigned int cmd, void __user *arg); | ||
159 | |||
160 | extern void dn_dev_devices_off(void); | ||
161 | extern void dn_dev_devices_on(void); | ||
162 | |||
163 | extern void dn_dev_init_pkt(struct sk_buff *skb); | ||
164 | extern void dn_dev_veri_pkt(struct sk_buff *skb); | ||
165 | extern void dn_dev_hello(struct sk_buff *skb); | ||
166 | |||
167 | extern void dn_dev_up(struct net_device *); | ||
168 | extern void dn_dev_down(struct net_device *); | ||
169 | |||
170 | extern int dn_dev_set_default(struct net_device *dev, int force); | ||
171 | extern struct net_device *dn_dev_get_default(void); | ||
172 | extern int dn_dev_bind_default(dn_address *addr); | ||
173 | |||
174 | extern int register_dnaddr_notifier(struct notifier_block *nb); | ||
175 | extern int unregister_dnaddr_notifier(struct notifier_block *nb); | ||
176 | |||
177 | static inline int dn_dev_islocal(struct net_device *dev, dn_address addr) | ||
178 | { | ||
179 | struct dn_dev *dn_db = dev->dn_ptr; | ||
180 | struct dn_ifaddr *ifa; | ||
181 | |||
182 | if (dn_db == NULL) { | ||
183 | printk(KERN_DEBUG "dn_dev_islocal: Called for non DECnet device\n"); | ||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next) | ||
188 | if ((addr ^ ifa->ifa_local) == 0) | ||
189 | return 1; | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | #endif /* _NET_DN_DEV_H */ | ||
diff --git a/include/net/dn_fib.h b/include/net/dn_fib.h new file mode 100644 index 000000000000..cd3c96d9601b --- /dev/null +++ b/include/net/dn_fib.h | |||
@@ -0,0 +1,204 @@ | |||
1 | #ifndef _NET_DN_FIB_H | ||
2 | #define _NET_DN_FIB_H | ||
3 | |||
4 | /* WARNING: The ordering of these elements must match ordering | ||
5 | * of RTA_* rtnetlink attribute numbers. | ||
6 | */ | ||
7 | struct dn_kern_rta | ||
8 | { | ||
9 | void *rta_dst; | ||
10 | void *rta_src; | ||
11 | int *rta_iif; | ||
12 | int *rta_oif; | ||
13 | void *rta_gw; | ||
14 | u32 *rta_priority; | ||
15 | void *rta_prefsrc; | ||
16 | struct rtattr *rta_mx; | ||
17 | struct rtattr *rta_mp; | ||
18 | unsigned char *rta_protoinfo; | ||
19 | u32 *rta_flow; | ||
20 | struct rta_cacheinfo *rta_ci; | ||
21 | struct rta_session *rta_sess; | ||
22 | }; | ||
23 | |||
24 | struct dn_fib_res { | ||
25 | struct dn_fib_rule *r; | ||
26 | struct dn_fib_info *fi; | ||
27 | unsigned char prefixlen; | ||
28 | unsigned char nh_sel; | ||
29 | unsigned char type; | ||
30 | unsigned char scope; | ||
31 | }; | ||
32 | |||
33 | struct dn_fib_nh { | ||
34 | struct net_device *nh_dev; | ||
35 | unsigned nh_flags; | ||
36 | unsigned char nh_scope; | ||
37 | int nh_weight; | ||
38 | int nh_power; | ||
39 | int nh_oif; | ||
40 | u32 nh_gw; | ||
41 | }; | ||
42 | |||
43 | struct dn_fib_info { | ||
44 | struct dn_fib_info *fib_next; | ||
45 | struct dn_fib_info *fib_prev; | ||
46 | int fib_treeref; | ||
47 | atomic_t fib_clntref; | ||
48 | int fib_dead; | ||
49 | unsigned fib_flags; | ||
50 | int fib_protocol; | ||
51 | dn_address fib_prefsrc; | ||
52 | __u32 fib_priority; | ||
53 | __u32 fib_metrics[RTAX_MAX]; | ||
54 | #define dn_fib_mtu fib_metrics[RTAX_MTU-1] | ||
55 | #define dn_fib_window fib_metrics[RTAX_WINDOW-1] | ||
56 | #define dn_fib_rtt fib_metrics[RTAX_RTT-1] | ||
57 | #define dn_fib_advmss fib_metrics[RTAX_ADVMSS-1] | ||
58 | int fib_nhs; | ||
59 | int fib_power; | ||
60 | struct dn_fib_nh fib_nh[0]; | ||
61 | #define dn_fib_dev fib_nh[0].nh_dev | ||
62 | }; | ||
63 | |||
64 | |||
65 | #define DN_FIB_RES_RESET(res) ((res).nh_sel = 0) | ||
66 | #define DN_FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel]) | ||
67 | |||
68 | #define DN_FIB_RES_PREFSRC(res) ((res).fi->fib_prefsrc ? : __dn_fib_res_prefsrc(&res)) | ||
69 | #define DN_FIB_RES_GW(res) (DN_FIB_RES_NH(res).nh_gw) | ||
70 | #define DN_FIB_RES_DEV(res) (DN_FIB_RES_NH(res).nh_dev) | ||
71 | #define DN_FIB_RES_OIF(res) (DN_FIB_RES_NH(res).nh_oif) | ||
72 | |||
73 | typedef struct { | ||
74 | u16 datum; | ||
75 | } dn_fib_key_t; | ||
76 | |||
77 | typedef struct { | ||
78 | u16 datum; | ||
79 | } dn_fib_hash_t; | ||
80 | |||
81 | typedef struct { | ||
82 | u16 datum; | ||
83 | } dn_fib_idx_t; | ||
84 | |||
85 | struct dn_fib_node { | ||
86 | struct dn_fib_node *fn_next; | ||
87 | struct dn_fib_info *fn_info; | ||
88 | #define DN_FIB_INFO(f) ((f)->fn_info) | ||
89 | dn_fib_key_t fn_key; | ||
90 | u8 fn_type; | ||
91 | u8 fn_scope; | ||
92 | u8 fn_state; | ||
93 | }; | ||
94 | |||
95 | |||
96 | struct dn_fib_table { | ||
97 | int n; | ||
98 | |||
99 | int (*insert)(struct dn_fib_table *t, struct rtmsg *r, | ||
100 | struct dn_kern_rta *rta, struct nlmsghdr *n, | ||
101 | struct netlink_skb_parms *req); | ||
102 | int (*delete)(struct dn_fib_table *t, struct rtmsg *r, | ||
103 | struct dn_kern_rta *rta, struct nlmsghdr *n, | ||
104 | struct netlink_skb_parms *req); | ||
105 | int (*lookup)(struct dn_fib_table *t, const struct flowi *fl, | ||
106 | struct dn_fib_res *res); | ||
107 | int (*flush)(struct dn_fib_table *t); | ||
108 | int (*dump)(struct dn_fib_table *t, struct sk_buff *skb, struct netlink_callback *cb); | ||
109 | |||
110 | unsigned char data[0]; | ||
111 | }; | ||
112 | |||
113 | #ifdef CONFIG_DECNET_ROUTER | ||
114 | /* | ||
115 | * dn_fib.c | ||
116 | */ | ||
117 | extern void dn_fib_init(void); | ||
118 | extern void dn_fib_cleanup(void); | ||
119 | |||
120 | extern int dn_fib_ioctl(struct socket *sock, unsigned int cmd, | ||
121 | unsigned long arg); | ||
122 | extern struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r, | ||
123 | struct dn_kern_rta *rta, | ||
124 | const struct nlmsghdr *nlh, int *errp); | ||
125 | extern int dn_fib_semantic_match(int type, struct dn_fib_info *fi, | ||
126 | const struct flowi *fl, | ||
127 | struct dn_fib_res *res); | ||
128 | extern void dn_fib_release_info(struct dn_fib_info *fi); | ||
129 | extern u16 dn_fib_get_attr16(struct rtattr *attr, int attrlen, int type); | ||
130 | extern void dn_fib_flush(void); | ||
131 | extern void dn_fib_select_multipath(const struct flowi *fl, | ||
132 | struct dn_fib_res *res); | ||
133 | extern int dn_fib_sync_down(dn_address local, struct net_device *dev, | ||
134 | int force); | ||
135 | extern int dn_fib_sync_up(struct net_device *dev); | ||
136 | |||
137 | /* | ||
138 | * dn_tables.c | ||
139 | */ | ||
140 | extern struct dn_fib_table *dn_fib_get_table(int n, int creat); | ||
141 | extern struct dn_fib_table *dn_fib_empty_table(void); | ||
142 | extern void dn_fib_table_init(void); | ||
143 | extern void dn_fib_table_cleanup(void); | ||
144 | |||
145 | /* | ||
146 | * dn_rules.c | ||
147 | */ | ||
148 | extern void dn_fib_rules_init(void); | ||
149 | extern void dn_fib_rules_cleanup(void); | ||
150 | extern void dn_fib_rule_put(struct dn_fib_rule *); | ||
151 | extern __u16 dn_fib_rules_policy(__u16 saddr, struct dn_fib_res *res, unsigned *flags); | ||
152 | extern unsigned dnet_addr_type(__u16 addr); | ||
153 | extern int dn_fib_lookup(const struct flowi *fl, struct dn_fib_res *res); | ||
154 | |||
155 | /* | ||
156 | * rtnetlink interface | ||
157 | */ | ||
158 | extern int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); | ||
159 | extern int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); | ||
160 | extern int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb); | ||
161 | |||
162 | extern int dn_fib_rtm_delrule(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); | ||
163 | extern int dn_fib_rtm_newrule(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); | ||
164 | extern int dn_fib_dump_rules(struct sk_buff *skb, struct netlink_callback *cb); | ||
165 | |||
166 | extern void dn_fib_free_info(struct dn_fib_info *fi); | ||
167 | |||
168 | static inline void dn_fib_info_put(struct dn_fib_info *fi) | ||
169 | { | ||
170 | if (atomic_dec_and_test(&fi->fib_clntref)) | ||
171 | dn_fib_free_info(fi); | ||
172 | } | ||
173 | |||
174 | static inline void dn_fib_res_put(struct dn_fib_res *res) | ||
175 | { | ||
176 | if (res->fi) | ||
177 | dn_fib_info_put(res->fi); | ||
178 | if (res->r) | ||
179 | dn_fib_rule_put(res->r); | ||
180 | } | ||
181 | |||
182 | extern struct dn_fib_table *dn_fib_tables[]; | ||
183 | |||
184 | #else /* Endnode */ | ||
185 | |||
186 | #define dn_fib_init() do { } while(0) | ||
187 | #define dn_fib_cleanup() do { } while(0) | ||
188 | |||
189 | #define dn_fib_lookup(fl, res) (-ESRCH) | ||
190 | #define dn_fib_info_put(fi) do { } while(0) | ||
191 | #define dn_fib_select_multipath(fl, res) do { } while(0) | ||
192 | #define dn_fib_rules_policy(saddr,res,flags) (0) | ||
193 | #define dn_fib_res_put(res) do { } while(0) | ||
194 | |||
195 | #endif /* CONFIG_DECNET_ROUTER */ | ||
196 | |||
197 | static inline u16 dnet_make_mask(int n) | ||
198 | { | ||
199 | if (n) | ||
200 | return htons(~((1<<(16-n))-1)); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | #endif /* _NET_DN_FIB_H */ | ||
diff --git a/include/net/dn_neigh.h b/include/net/dn_neigh.h new file mode 100644 index 000000000000..4b1eb038d637 --- /dev/null +++ b/include/net/dn_neigh.h | |||
@@ -0,0 +1,28 @@ | |||
1 | #ifndef _NET_DN_NEIGH_H | ||
2 | #define _NET_DN_NEIGH_H | ||
3 | |||
4 | /* | ||
5 | * The position of the first two fields of | ||
6 | * this structure are critical - SJW | ||
7 | */ | ||
8 | struct dn_neigh { | ||
9 | struct neighbour n; | ||
10 | dn_address addr; | ||
11 | unsigned long flags; | ||
12 | #define DN_NDFLAG_R1 0x0001 /* Router L1 */ | ||
13 | #define DN_NDFLAG_R2 0x0002 /* Router L2 */ | ||
14 | #define DN_NDFLAG_P3 0x0004 /* Phase III Node */ | ||
15 | unsigned long blksize; | ||
16 | unsigned char priority; | ||
17 | }; | ||
18 | |||
19 | extern void dn_neigh_init(void); | ||
20 | extern void dn_neigh_cleanup(void); | ||
21 | extern int dn_neigh_router_hello(struct sk_buff *skb); | ||
22 | extern int dn_neigh_endnode_hello(struct sk_buff *skb); | ||
23 | extern void dn_neigh_pointopoint_hello(struct sk_buff *skb); | ||
24 | extern int dn_neigh_elist(struct net_device *dev, unsigned char *ptr, int n); | ||
25 | |||
26 | extern struct neigh_table dn_neigh_table; | ||
27 | |||
28 | #endif /* _NET_DN_NEIGH_H */ | ||
diff --git a/include/net/dn_nsp.h b/include/net/dn_nsp.h new file mode 100644 index 000000000000..6bbeafa73e8b --- /dev/null +++ b/include/net/dn_nsp.h | |||
@@ -0,0 +1,209 @@ | |||
1 | #ifndef _NET_DN_NSP_H | ||
2 | #define _NET_DN_NSP_H | ||
3 | /****************************************************************************** | ||
4 | (c) 1995-1998 E.M. Serrat emserrat@geocities.com | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | *******************************************************************************/ | ||
16 | /* dn_nsp.c functions prototyping */ | ||
17 | |||
18 | extern void dn_nsp_send_data_ack(struct sock *sk); | ||
19 | extern void dn_nsp_send_oth_ack(struct sock *sk); | ||
20 | extern void dn_nsp_delayed_ack(struct sock *sk); | ||
21 | extern void dn_send_conn_ack(struct sock *sk); | ||
22 | extern void dn_send_conn_conf(struct sock *sk, int gfp); | ||
23 | extern void dn_nsp_send_disc(struct sock *sk, unsigned char type, | ||
24 | unsigned short reason, int gfp); | ||
25 | extern void dn_nsp_return_disc(struct sk_buff *skb, unsigned char type, | ||
26 | unsigned short reason); | ||
27 | extern void dn_nsp_send_link(struct sock *sk, unsigned char lsflags, char fcval); | ||
28 | extern void dn_nsp_send_conninit(struct sock *sk, unsigned char flags); | ||
29 | |||
30 | extern void dn_nsp_output(struct sock *sk); | ||
31 | extern int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff_head *q, unsigned short acknum); | ||
32 | extern void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb, int gfp, int oob); | ||
33 | extern unsigned long dn_nsp_persist(struct sock *sk); | ||
34 | extern int dn_nsp_xmit_timeout(struct sock *sk); | ||
35 | |||
36 | extern int dn_nsp_rx(struct sk_buff *); | ||
37 | extern int dn_nsp_backlog_rcv(struct sock *sk, struct sk_buff *skb); | ||
38 | |||
39 | extern struct sk_buff *dn_alloc_skb(struct sock *sk, int size, int pri); | ||
40 | extern struct sk_buff *dn_alloc_send_skb(struct sock *sk, size_t *size, int noblock, long timeo, int *err); | ||
41 | |||
42 | #define NSP_REASON_OK 0 /* No error */ | ||
43 | #define NSP_REASON_NR 1 /* No resources */ | ||
44 | #define NSP_REASON_UN 2 /* Unrecognised node name */ | ||
45 | #define NSP_REASON_SD 3 /* Node shutting down */ | ||
46 | #define NSP_REASON_ID 4 /* Invalid destination end user */ | ||
47 | #define NSP_REASON_ER 5 /* End user lacks resources */ | ||
48 | #define NSP_REASON_OB 6 /* Object too busy */ | ||
49 | #define NSP_REASON_US 7 /* Unspecified error */ | ||
50 | #define NSP_REASON_TP 8 /* Third-Party abort */ | ||
51 | #define NSP_REASON_EA 9 /* End user has aborted the link */ | ||
52 | #define NSP_REASON_IF 10 /* Invalid node name format */ | ||
53 | #define NSP_REASON_LS 11 /* Local node shutdown */ | ||
54 | #define NSP_REASON_LL 32 /* Node lacks logical-link resources */ | ||
55 | #define NSP_REASON_LE 33 /* End user lacks logical-link resources */ | ||
56 | #define NSP_REASON_UR 34 /* Unacceptable RQSTRID or PASSWORD field */ | ||
57 | #define NSP_REASON_UA 36 /* Unacceptable ACCOUNT field */ | ||
58 | #define NSP_REASON_TM 38 /* End user timed out logical link */ | ||
59 | #define NSP_REASON_NU 39 /* Node unreachable */ | ||
60 | #define NSP_REASON_NL 41 /* No-link message */ | ||
61 | #define NSP_REASON_DC 42 /* Disconnect confirm */ | ||
62 | #define NSP_REASON_IO 43 /* Image data field overflow */ | ||
63 | |||
64 | #define NSP_DISCINIT 0x38 | ||
65 | #define NSP_DISCCONF 0x48 | ||
66 | |||
67 | /*------------------------- NSP - messages ------------------------------*/ | ||
68 | /* Data Messages */ | ||
69 | /*---------------*/ | ||
70 | |||
71 | /* Data Messages (data segment/interrupt/link service) */ | ||
72 | |||
73 | struct nsp_data_seg_msg | ||
74 | { | ||
75 | unsigned char msgflg __attribute__((packed)); | ||
76 | unsigned short dstaddr __attribute__((packed)); | ||
77 | unsigned short srcaddr __attribute__((packed)); | ||
78 | }; | ||
79 | |||
80 | struct nsp_data_opt_msg | ||
81 | { | ||
82 | unsigned short acknum __attribute__((packed)); | ||
83 | unsigned short segnum __attribute__((packed)); | ||
84 | unsigned short lsflgs __attribute__((packed)); | ||
85 | }; | ||
86 | |||
87 | struct nsp_data_opt_msg1 | ||
88 | { | ||
89 | unsigned short acknum __attribute__((packed)); | ||
90 | unsigned short segnum __attribute__((packed)); | ||
91 | }; | ||
92 | |||
93 | |||
94 | /* Acknowledgment Message (data/other data) */ | ||
95 | struct nsp_data_ack_msg | ||
96 | { | ||
97 | unsigned char msgflg __attribute__((packed)); | ||
98 | unsigned short dstaddr __attribute__((packed)); | ||
99 | unsigned short srcaddr __attribute__((packed)); | ||
100 | unsigned short acknum __attribute__((packed)); | ||
101 | }; | ||
102 | |||
103 | /* Connect Acknowledgment Message */ | ||
104 | struct nsp_conn_ack_msg | ||
105 | { | ||
106 | unsigned char msgflg __attribute__((packed)); | ||
107 | unsigned short dstaddr __attribute__((packed)); | ||
108 | }; | ||
109 | |||
110 | |||
111 | /* Connect Initiate/Retransmit Initiate/Connect Confirm */ | ||
112 | struct nsp_conn_init_msg | ||
113 | { | ||
114 | unsigned char msgflg __attribute__((packed)); | ||
115 | #define NSP_CI 0x18 /* Connect Initiate */ | ||
116 | #define NSP_RCI 0x68 /* Retrans. Conn Init */ | ||
117 | unsigned short dstaddr __attribute__((packed)); | ||
118 | unsigned short srcaddr __attribute__((packed)); | ||
119 | unsigned char services __attribute__((packed)); | ||
120 | #define NSP_FC_NONE 0x00 /* Flow Control None */ | ||
121 | #define NSP_FC_SRC 0x04 /* Seg Req. Count */ | ||
122 | #define NSP_FC_SCMC 0x08 /* Sess. Control Mess */ | ||
123 | #define NSP_FC_MASK 0x0c /* FC type mask */ | ||
124 | unsigned char info __attribute__((packed)); | ||
125 | unsigned short segsize __attribute__((packed)); | ||
126 | }; | ||
127 | |||
128 | /* Disconnect Initiate/Disconnect Confirm */ | ||
129 | struct nsp_disconn_init_msg | ||
130 | { | ||
131 | unsigned char msgflg __attribute__((packed)); | ||
132 | unsigned short dstaddr __attribute__((packed)); | ||
133 | unsigned short srcaddr __attribute__((packed)); | ||
134 | unsigned short reason __attribute__((packed)); | ||
135 | }; | ||
136 | |||
137 | |||
138 | |||
139 | struct srcobj_fmt | ||
140 | { | ||
141 | char format __attribute__((packed)); | ||
142 | unsigned char task __attribute__((packed)); | ||
143 | unsigned short grpcode __attribute__((packed)); | ||
144 | unsigned short usrcode __attribute__((packed)); | ||
145 | char dlen __attribute__((packed)); | ||
146 | }; | ||
147 | |||
148 | /* | ||
149 | * A collection of functions for manipulating the sequence | ||
150 | * numbers used in NSP. Similar in operation to the functions | ||
151 | * of the same name in TCP. | ||
152 | */ | ||
153 | static __inline__ int dn_before(unsigned short seq1, unsigned short seq2) | ||
154 | { | ||
155 | seq1 &= 0x0fff; | ||
156 | seq2 &= 0x0fff; | ||
157 | |||
158 | return (int)((seq1 - seq2) & 0x0fff) > 2048; | ||
159 | } | ||
160 | |||
161 | |||
162 | static __inline__ int dn_after(unsigned short seq1, unsigned short seq2) | ||
163 | { | ||
164 | seq1 &= 0x0fff; | ||
165 | seq2 &= 0x0fff; | ||
166 | |||
167 | return (int)((seq2 - seq1) & 0x0fff) > 2048; | ||
168 | } | ||
169 | |||
170 | static __inline__ int dn_equal(unsigned short seq1, unsigned short seq2) | ||
171 | { | ||
172 | return ((seq1 ^ seq2) & 0x0fff) == 0; | ||
173 | } | ||
174 | |||
175 | static __inline__ int dn_before_or_equal(unsigned short seq1, unsigned short seq2) | ||
176 | { | ||
177 | return (dn_before(seq1, seq2) || dn_equal(seq1, seq2)); | ||
178 | } | ||
179 | |||
180 | static __inline__ void seq_add(unsigned short *seq, unsigned short off) | ||
181 | { | ||
182 | (*seq) += off; | ||
183 | (*seq) &= 0x0fff; | ||
184 | } | ||
185 | |||
186 | static __inline__ int seq_next(unsigned short seq1, unsigned short seq2) | ||
187 | { | ||
188 | return dn_equal(seq1 + 1, seq2); | ||
189 | } | ||
190 | |||
191 | /* | ||
192 | * Can we delay the ack ? | ||
193 | */ | ||
194 | static __inline__ int sendack(unsigned short seq) | ||
195 | { | ||
196 | return (int)((seq & 0x1000) ? 0 : 1); | ||
197 | } | ||
198 | |||
199 | /* | ||
200 | * Is socket congested ? | ||
201 | */ | ||
202 | static __inline__ int dn_congested(struct sock *sk) | ||
203 | { | ||
204 | return atomic_read(&sk->sk_rmem_alloc) > (sk->sk_rcvbuf >> 1); | ||
205 | } | ||
206 | |||
207 | #define DN_MAX_NSP_DATA_HEADER (11) | ||
208 | |||
209 | #endif /* _NET_DN_NSP_H */ | ||
diff --git a/include/net/dn_route.h b/include/net/dn_route.h new file mode 100644 index 000000000000..d084721db198 --- /dev/null +++ b/include/net/dn_route.h | |||
@@ -0,0 +1,112 @@ | |||
1 | #ifndef _NET_DN_ROUTE_H | ||
2 | #define _NET_DN_ROUTE_H | ||
3 | |||
4 | /****************************************************************************** | ||
5 | (c) 1995-1998 E.M. Serrat emserrat@geocities.com | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | *******************************************************************************/ | ||
17 | |||
18 | extern struct sk_buff *dn_alloc_skb(struct sock *sk, int size, int pri); | ||
19 | extern int dn_route_output_sock(struct dst_entry **pprt, struct flowi *, struct sock *sk, int flags); | ||
20 | extern int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb); | ||
21 | extern int dn_cache_getroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); | ||
22 | extern void dn_rt_cache_flush(int delay); | ||
23 | |||
24 | /* Masks for flags field */ | ||
25 | #define DN_RT_F_PID 0x07 /* Mask for packet type */ | ||
26 | #define DN_RT_F_PF 0x80 /* Padding Follows */ | ||
27 | #define DN_RT_F_VER 0x40 /* Version =0 discard packet if ==1 */ | ||
28 | #define DN_RT_F_IE 0x20 /* Intra Ethernet, Reserved in short pkt */ | ||
29 | #define DN_RT_F_RTS 0x10 /* Packet is being returned to sender */ | ||
30 | #define DN_RT_F_RQR 0x08 /* Return packet to sender upon non-delivery */ | ||
31 | |||
32 | /* Mask for types of routing packets */ | ||
33 | #define DN_RT_PKT_MSK 0x06 | ||
34 | /* Types of routing packets */ | ||
35 | #define DN_RT_PKT_SHORT 0x02 /* Short routing packet */ | ||
36 | #define DN_RT_PKT_LONG 0x06 /* Long routing packet */ | ||
37 | |||
38 | /* Mask for control/routing selection */ | ||
39 | #define DN_RT_PKT_CNTL 0x01 /* Set to 1 if a control packet */ | ||
40 | /* Types of control packets */ | ||
41 | #define DN_RT_CNTL_MSK 0x0f /* Mask for control packets */ | ||
42 | #define DN_RT_PKT_INIT 0x01 /* Initialisation packet */ | ||
43 | #define DN_RT_PKT_VERI 0x03 /* Verification Message */ | ||
44 | #define DN_RT_PKT_HELO 0x05 /* Hello and Test Message */ | ||
45 | #define DN_RT_PKT_L1RT 0x07 /* Level 1 Routing Message */ | ||
46 | #define DN_RT_PKT_L2RT 0x09 /* Level 2 Routing Message */ | ||
47 | #define DN_RT_PKT_ERTH 0x0b /* Ethernet Router Hello */ | ||
48 | #define DN_RT_PKT_EEDH 0x0d /* Ethernet EndNode Hello */ | ||
49 | |||
50 | /* Values for info field in hello message */ | ||
51 | #define DN_RT_INFO_TYPE 0x03 /* Type mask */ | ||
52 | #define DN_RT_INFO_L1RT 0x02 /* L1 Router */ | ||
53 | #define DN_RT_INFO_L2RT 0x01 /* L2 Router */ | ||
54 | #define DN_RT_INFO_ENDN 0x03 /* EndNode */ | ||
55 | #define DN_RT_INFO_VERI 0x04 /* Verification Reqd. */ | ||
56 | #define DN_RT_INFO_RJCT 0x08 /* Reject Flag, Reserved */ | ||
57 | #define DN_RT_INFO_VFLD 0x10 /* Verification Failed, Reserved */ | ||
58 | #define DN_RT_INFO_NOML 0x20 /* No Multicast traffic accepted */ | ||
59 | #define DN_RT_INFO_BLKR 0x40 /* Blocking Requested */ | ||
60 | |||
61 | /* | ||
62 | * The fl structure is what we used to look up the route. | ||
63 | * The rt_saddr & rt_daddr entries are the same as key.saddr & key.daddr | ||
64 | * except for local input routes, where the rt_saddr = fl.fld_dst and | ||
65 | * rt_daddr = fl.fld_src to allow the route to be used for returning | ||
66 | * packets to the originating host. | ||
67 | */ | ||
68 | struct dn_route { | ||
69 | union { | ||
70 | struct dst_entry dst; | ||
71 | struct dn_route *rt_next; | ||
72 | } u; | ||
73 | |||
74 | __u16 rt_saddr; | ||
75 | __u16 rt_daddr; | ||
76 | __u16 rt_gateway; | ||
77 | __u16 rt_local_src; /* Source used for forwarding packets */ | ||
78 | __u16 rt_src_map; | ||
79 | __u16 rt_dst_map; | ||
80 | |||
81 | unsigned rt_flags; | ||
82 | unsigned rt_type; | ||
83 | |||
84 | struct flowi fl; | ||
85 | }; | ||
86 | |||
87 | extern void dn_route_init(void); | ||
88 | extern void dn_route_cleanup(void); | ||
89 | |||
90 | #include <net/sock.h> | ||
91 | #include <linux/if_arp.h> | ||
92 | |||
93 | static inline void dn_rt_send(struct sk_buff *skb) | ||
94 | { | ||
95 | dev_queue_xmit(skb); | ||
96 | } | ||
97 | |||
98 | static inline void dn_rt_finish_output(struct sk_buff *skb, char *dst, char *src) | ||
99 | { | ||
100 | struct net_device *dev = skb->dev; | ||
101 | |||
102 | if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK)) | ||
103 | dst = NULL; | ||
104 | |||
105 | if (!dev->hard_header || (dev->hard_header(skb, dev, ETH_P_DNA_RT, | ||
106 | dst, src, skb->len) >= 0)) | ||
107 | dn_rt_send(skb); | ||
108 | else | ||
109 | kfree_skb(skb); | ||
110 | } | ||
111 | |||
112 | #endif /* _NET_DN_ROUTE_H */ | ||
diff --git a/include/net/dsfield.h b/include/net/dsfield.h new file mode 100644 index 000000000000..a79c9e075f7f --- /dev/null +++ b/include/net/dsfield.h | |||
@@ -0,0 +1,54 @@ | |||
1 | /* include/net/dsfield.h - Manipulation of the Differentiated Services field */ | ||
2 | |||
3 | /* Written 1998-2000 by Werner Almesberger, EPFL ICA */ | ||
4 | |||
5 | |||
6 | #ifndef __NET_DSFIELD_H | ||
7 | #define __NET_DSFIELD_H | ||
8 | |||
9 | #include <linux/types.h> | ||
10 | #include <linux/ip.h> | ||
11 | #include <linux/ipv6.h> | ||
12 | #include <asm/byteorder.h> | ||
13 | |||
14 | |||
15 | static inline __u8 ipv4_get_dsfield(struct iphdr *iph) | ||
16 | { | ||
17 | return iph->tos; | ||
18 | } | ||
19 | |||
20 | |||
21 | static inline __u8 ipv6_get_dsfield(struct ipv6hdr *ipv6h) | ||
22 | { | ||
23 | return ntohs(*(__u16 *) ipv6h) >> 4; | ||
24 | } | ||
25 | |||
26 | |||
27 | static inline void ipv4_change_dsfield(struct iphdr *iph,__u8 mask, | ||
28 | __u8 value) | ||
29 | { | ||
30 | __u32 check = ntohs(iph->check); | ||
31 | __u8 dsfield; | ||
32 | |||
33 | dsfield = (iph->tos & mask) | value; | ||
34 | check += iph->tos; | ||
35 | if ((check+1) >> 16) check = (check+1) & 0xffff; | ||
36 | check -= dsfield; | ||
37 | check += check >> 16; /* adjust carry */ | ||
38 | iph->check = htons(check); | ||
39 | iph->tos = dsfield; | ||
40 | } | ||
41 | |||
42 | |||
43 | static inline void ipv6_change_dsfield(struct ipv6hdr *ipv6h,__u8 mask, | ||
44 | __u8 value) | ||
45 | { | ||
46 | __u16 tmp; | ||
47 | |||
48 | tmp = ntohs(*(__u16 *) ipv6h); | ||
49 | tmp = (tmp & ((mask << 4) | 0xf00f)) | (value << 4); | ||
50 | *(__u16 *) ipv6h = htons(tmp); | ||
51 | } | ||
52 | |||
53 | |||
54 | #endif | ||
diff --git a/include/net/dst.h b/include/net/dst.h new file mode 100644 index 000000000000..50adc9136530 --- /dev/null +++ b/include/net/dst.h | |||
@@ -0,0 +1,279 @@ | |||
1 | /* | ||
2 | * net/dst.h Protocol independent destination cache definitions. | ||
3 | * | ||
4 | * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #ifndef _NET_DST_H | ||
9 | #define _NET_DST_H | ||
10 | |||
11 | #include <linux/config.h> | ||
12 | #include <linux/rtnetlink.h> | ||
13 | #include <linux/rcupdate.h> | ||
14 | #include <linux/jiffies.h> | ||
15 | #include <net/neighbour.h> | ||
16 | #include <asm/processor.h> | ||
17 | |||
18 | /* | ||
19 | * 0 - no debugging messages | ||
20 | * 1 - rare events and bugs (default) | ||
21 | * 2 - trace mode. | ||
22 | */ | ||
23 | #define RT_CACHE_DEBUG 0 | ||
24 | |||
25 | #define DST_GC_MIN (HZ/10) | ||
26 | #define DST_GC_INC (HZ/2) | ||
27 | #define DST_GC_MAX (120*HZ) | ||
28 | |||
29 | /* Each dst_entry has reference count and sits in some parent list(s). | ||
30 | * When it is removed from parent list, it is "freed" (dst_free). | ||
31 | * After this it enters dead state (dst->obsolete > 0) and if its refcnt | ||
32 | * is zero, it can be destroyed immediately, otherwise it is added | ||
33 | * to gc list and garbage collector periodically checks the refcnt. | ||
34 | */ | ||
35 | |||
36 | struct sk_buff; | ||
37 | |||
38 | struct dst_entry | ||
39 | { | ||
40 | struct dst_entry *next; | ||
41 | atomic_t __refcnt; /* client references */ | ||
42 | int __use; | ||
43 | struct dst_entry *child; | ||
44 | struct net_device *dev; | ||
45 | int obsolete; | ||
46 | int flags; | ||
47 | #define DST_HOST 1 | ||
48 | #define DST_NOXFRM 2 | ||
49 | #define DST_NOPOLICY 4 | ||
50 | #define DST_NOHASH 8 | ||
51 | #define DST_BALANCED 0x10 | ||
52 | unsigned long lastuse; | ||
53 | unsigned long expires; | ||
54 | |||
55 | unsigned short header_len; /* more space at head required */ | ||
56 | unsigned short trailer_len; /* space to reserve at tail */ | ||
57 | |||
58 | u32 metrics[RTAX_MAX]; | ||
59 | struct dst_entry *path; | ||
60 | |||
61 | unsigned long rate_last; /* rate limiting for ICMP */ | ||
62 | unsigned long rate_tokens; | ||
63 | |||
64 | int error; | ||
65 | |||
66 | struct neighbour *neighbour; | ||
67 | struct hh_cache *hh; | ||
68 | struct xfrm_state *xfrm; | ||
69 | |||
70 | int (*input)(struct sk_buff*); | ||
71 | int (*output)(struct sk_buff*); | ||
72 | |||
73 | #ifdef CONFIG_NET_CLS_ROUTE | ||
74 | __u32 tclassid; | ||
75 | #endif | ||
76 | |||
77 | struct dst_ops *ops; | ||
78 | struct rcu_head rcu_head; | ||
79 | |||
80 | char info[0]; | ||
81 | }; | ||
82 | |||
83 | |||
84 | struct dst_ops | ||
85 | { | ||
86 | unsigned short family; | ||
87 | unsigned short protocol; | ||
88 | unsigned gc_thresh; | ||
89 | |||
90 | int (*gc)(void); | ||
91 | struct dst_entry * (*check)(struct dst_entry *, __u32 cookie); | ||
92 | void (*destroy)(struct dst_entry *); | ||
93 | void (*ifdown)(struct dst_entry *, | ||
94 | struct net_device *dev, int how); | ||
95 | struct dst_entry * (*negative_advice)(struct dst_entry *); | ||
96 | void (*link_failure)(struct sk_buff *); | ||
97 | void (*update_pmtu)(struct dst_entry *dst, u32 mtu); | ||
98 | int (*get_mss)(struct dst_entry *dst, u32 mtu); | ||
99 | int entry_size; | ||
100 | |||
101 | atomic_t entries; | ||
102 | kmem_cache_t *kmem_cachep; | ||
103 | }; | ||
104 | |||
105 | #ifdef __KERNEL__ | ||
106 | |||
107 | static inline u32 | ||
108 | dst_metric(const struct dst_entry *dst, int metric) | ||
109 | { | ||
110 | return dst->metrics[metric-1]; | ||
111 | } | ||
112 | |||
113 | static inline u32 dst_mtu(const struct dst_entry *dst) | ||
114 | { | ||
115 | u32 mtu = dst_metric(dst, RTAX_MTU); | ||
116 | /* | ||
117 | * Alexey put it here, so ask him about it :) | ||
118 | */ | ||
119 | barrier(); | ||
120 | return mtu; | ||
121 | } | ||
122 | |||
123 | static inline u32 | ||
124 | dst_allfrag(const struct dst_entry *dst) | ||
125 | { | ||
126 | int ret = dst_metric(dst, RTAX_FEATURES) & RTAX_FEATURE_ALLFRAG; | ||
127 | /* Yes, _exactly_. This is paranoia. */ | ||
128 | barrier(); | ||
129 | return ret; | ||
130 | } | ||
131 | |||
132 | static inline int | ||
133 | dst_metric_locked(struct dst_entry *dst, int metric) | ||
134 | { | ||
135 | return dst_metric(dst, RTAX_LOCK) & (1<<metric); | ||
136 | } | ||
137 | |||
138 | static inline void dst_hold(struct dst_entry * dst) | ||
139 | { | ||
140 | atomic_inc(&dst->__refcnt); | ||
141 | } | ||
142 | |||
143 | static inline | ||
144 | struct dst_entry * dst_clone(struct dst_entry * dst) | ||
145 | { | ||
146 | if (dst) | ||
147 | atomic_inc(&dst->__refcnt); | ||
148 | return dst; | ||
149 | } | ||
150 | |||
151 | static inline | ||
152 | void dst_release(struct dst_entry * dst) | ||
153 | { | ||
154 | if (dst) { | ||
155 | WARN_ON(atomic_read(&dst->__refcnt) < 1); | ||
156 | smp_mb__before_atomic_dec(); | ||
157 | atomic_dec(&dst->__refcnt); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | /* Children define the path of the packet through the | ||
162 | * Linux networking. Thus, destinations are stackable. | ||
163 | */ | ||
164 | |||
165 | static inline struct dst_entry *dst_pop(struct dst_entry *dst) | ||
166 | { | ||
167 | struct dst_entry *child = dst_clone(dst->child); | ||
168 | |||
169 | dst_release(dst); | ||
170 | return child; | ||
171 | } | ||
172 | |||
173 | extern void * dst_alloc(struct dst_ops * ops); | ||
174 | extern void __dst_free(struct dst_entry * dst); | ||
175 | extern struct dst_entry *dst_destroy(struct dst_entry * dst); | ||
176 | |||
177 | static inline void dst_free(struct dst_entry * dst) | ||
178 | { | ||
179 | if (dst->obsolete > 1) | ||
180 | return; | ||
181 | if (!atomic_read(&dst->__refcnt)) { | ||
182 | dst = dst_destroy(dst); | ||
183 | if (!dst) | ||
184 | return; | ||
185 | } | ||
186 | __dst_free(dst); | ||
187 | } | ||
188 | |||
189 | static inline void dst_rcu_free(struct rcu_head *head) | ||
190 | { | ||
191 | struct dst_entry *dst = container_of(head, struct dst_entry, rcu_head); | ||
192 | dst_free(dst); | ||
193 | } | ||
194 | |||
195 | static inline void dst_confirm(struct dst_entry *dst) | ||
196 | { | ||
197 | if (dst) | ||
198 | neigh_confirm(dst->neighbour); | ||
199 | } | ||
200 | |||
201 | static inline void dst_negative_advice(struct dst_entry **dst_p) | ||
202 | { | ||
203 | struct dst_entry * dst = *dst_p; | ||
204 | if (dst && dst->ops->negative_advice) | ||
205 | *dst_p = dst->ops->negative_advice(dst); | ||
206 | } | ||
207 | |||
208 | static inline void dst_link_failure(struct sk_buff *skb) | ||
209 | { | ||
210 | struct dst_entry * dst = skb->dst; | ||
211 | if (dst && dst->ops && dst->ops->link_failure) | ||
212 | dst->ops->link_failure(skb); | ||
213 | } | ||
214 | |||
215 | static inline void dst_set_expires(struct dst_entry *dst, int timeout) | ||
216 | { | ||
217 | unsigned long expires = jiffies + timeout; | ||
218 | |||
219 | if (expires == 0) | ||
220 | expires = 1; | ||
221 | |||
222 | if (dst->expires == 0 || time_before(expires, dst->expires)) | ||
223 | dst->expires = expires; | ||
224 | } | ||
225 | |||
226 | /* Output packet to network from transport. */ | ||
227 | static inline int dst_output(struct sk_buff *skb) | ||
228 | { | ||
229 | int err; | ||
230 | |||
231 | for (;;) { | ||
232 | err = skb->dst->output(skb); | ||
233 | |||
234 | if (likely(err == 0)) | ||
235 | return err; | ||
236 | if (unlikely(err != NET_XMIT_BYPASS)) | ||
237 | return err; | ||
238 | } | ||
239 | } | ||
240 | |||
241 | /* Input packet from network to transport. */ | ||
242 | static inline int dst_input(struct sk_buff *skb) | ||
243 | { | ||
244 | int err; | ||
245 | |||
246 | for (;;) { | ||
247 | err = skb->dst->input(skb); | ||
248 | |||
249 | if (likely(err == 0)) | ||
250 | return err; | ||
251 | /* Oh, Jamal... Seems, I will not forgive you this mess. :-) */ | ||
252 | if (unlikely(err != NET_XMIT_BYPASS)) | ||
253 | return err; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie) | ||
258 | { | ||
259 | if (dst->obsolete) | ||
260 | dst = dst->ops->check(dst, cookie); | ||
261 | return dst; | ||
262 | } | ||
263 | |||
264 | extern void dst_init(void); | ||
265 | |||
266 | struct flowi; | ||
267 | #ifndef CONFIG_XFRM | ||
268 | static inline int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, | ||
269 | struct sock *sk, int flags) | ||
270 | { | ||
271 | return 0; | ||
272 | } | ||
273 | #else | ||
274 | extern int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, | ||
275 | struct sock *sk, int flags); | ||
276 | #endif | ||
277 | #endif | ||
278 | |||
279 | #endif /* _NET_DST_H */ | ||
diff --git a/include/net/esp.h b/include/net/esp.h new file mode 100644 index 000000000000..90cd94fad7d9 --- /dev/null +++ b/include/net/esp.h | |||
@@ -0,0 +1,59 @@ | |||
1 | #ifndef _NET_ESP_H | ||
2 | #define _NET_ESP_H | ||
3 | |||
4 | #include <net/xfrm.h> | ||
5 | #include <asm/scatterlist.h> | ||
6 | |||
7 | #define ESP_NUM_FAST_SG 4 | ||
8 | |||
9 | struct esp_data | ||
10 | { | ||
11 | struct scatterlist sgbuf[ESP_NUM_FAST_SG]; | ||
12 | |||
13 | /* Confidentiality */ | ||
14 | struct { | ||
15 | u8 *key; /* Key */ | ||
16 | int key_len; /* Key length */ | ||
17 | u8 *ivec; /* ivec buffer */ | ||
18 | /* ivlen is offset from enc_data, where encrypted data start. | ||
19 | * It is logically different of crypto_tfm_alg_ivsize(tfm). | ||
20 | * We assume that it is either zero (no ivec), or | ||
21 | * >= crypto_tfm_alg_ivsize(tfm). */ | ||
22 | int ivlen; | ||
23 | int padlen; /* 0..255 */ | ||
24 | struct crypto_tfm *tfm; /* crypto handle */ | ||
25 | } conf; | ||
26 | |||
27 | /* Integrity. It is active when icv_full_len != 0 */ | ||
28 | struct { | ||
29 | u8 *key; /* Key */ | ||
30 | int key_len; /* Length of the key */ | ||
31 | u8 *work_icv; | ||
32 | int icv_full_len; | ||
33 | int icv_trunc_len; | ||
34 | void (*icv)(struct esp_data*, | ||
35 | struct sk_buff *skb, | ||
36 | int offset, int len, u8 *icv); | ||
37 | struct crypto_tfm *tfm; | ||
38 | } auth; | ||
39 | }; | ||
40 | |||
41 | extern int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len); | ||
42 | extern int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer); | ||
43 | extern void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len); | ||
44 | |||
45 | static inline void | ||
46 | esp_hmac_digest(struct esp_data *esp, struct sk_buff *skb, int offset, | ||
47 | int len, u8 *auth_data) | ||
48 | { | ||
49 | struct crypto_tfm *tfm = esp->auth.tfm; | ||
50 | char *icv = esp->auth.work_icv; | ||
51 | |||
52 | memset(auth_data, 0, esp->auth.icv_trunc_len); | ||
53 | crypto_hmac_init(tfm, esp->auth.key, &esp->auth.key_len); | ||
54 | skb_icv_walk(skb, tfm, offset, len, crypto_hmac_update); | ||
55 | crypto_hmac_final(tfm, esp->auth.key, &esp->auth.key_len, icv); | ||
56 | memcpy(auth_data, icv, esp->auth.icv_trunc_len); | ||
57 | } | ||
58 | |||
59 | #endif | ||
diff --git a/include/net/flow.h b/include/net/flow.h new file mode 100644 index 000000000000..9a5c94b1a0ec --- /dev/null +++ b/include/net/flow.h | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Generic internet FLOW. | ||
4 | * | ||
5 | */ | ||
6 | |||
7 | #ifndef _NET_FLOW_H | ||
8 | #define _NET_FLOW_H | ||
9 | |||
10 | #include <linux/in6.h> | ||
11 | #include <asm/atomic.h> | ||
12 | |||
13 | struct flowi { | ||
14 | int oif; | ||
15 | int iif; | ||
16 | |||
17 | union { | ||
18 | struct { | ||
19 | __u32 daddr; | ||
20 | __u32 saddr; | ||
21 | __u32 fwmark; | ||
22 | __u8 tos; | ||
23 | __u8 scope; | ||
24 | } ip4_u; | ||
25 | |||
26 | struct { | ||
27 | struct in6_addr daddr; | ||
28 | struct in6_addr saddr; | ||
29 | __u32 flowlabel; | ||
30 | } ip6_u; | ||
31 | |||
32 | struct { | ||
33 | __u16 daddr; | ||
34 | __u16 saddr; | ||
35 | __u32 fwmark; | ||
36 | __u8 scope; | ||
37 | } dn_u; | ||
38 | } nl_u; | ||
39 | #define fld_dst nl_u.dn_u.daddr | ||
40 | #define fld_src nl_u.dn_u.saddr | ||
41 | #define fld_fwmark nl_u.dn_u.fwmark | ||
42 | #define fld_scope nl_u.dn_u.scope | ||
43 | #define fl6_dst nl_u.ip6_u.daddr | ||
44 | #define fl6_src nl_u.ip6_u.saddr | ||
45 | #define fl6_flowlabel nl_u.ip6_u.flowlabel | ||
46 | #define fl4_dst nl_u.ip4_u.daddr | ||
47 | #define fl4_src nl_u.ip4_u.saddr | ||
48 | #define fl4_fwmark nl_u.ip4_u.fwmark | ||
49 | #define fl4_tos nl_u.ip4_u.tos | ||
50 | #define fl4_scope nl_u.ip4_u.scope | ||
51 | |||
52 | __u8 proto; | ||
53 | __u8 flags; | ||
54 | #define FLOWI_FLAG_MULTIPATHOLDROUTE 0x01 | ||
55 | union { | ||
56 | struct { | ||
57 | __u16 sport; | ||
58 | __u16 dport; | ||
59 | } ports; | ||
60 | |||
61 | struct { | ||
62 | __u8 type; | ||
63 | __u8 code; | ||
64 | } icmpt; | ||
65 | |||
66 | struct { | ||
67 | __u16 sport; | ||
68 | __u16 dport; | ||
69 | __u8 objnum; | ||
70 | __u8 objnamel; /* Not 16 bits since max val is 16 */ | ||
71 | __u8 objname[16]; /* Not zero terminated */ | ||
72 | } dnports; | ||
73 | |||
74 | __u32 spi; | ||
75 | } uli_u; | ||
76 | #define fl_ip_sport uli_u.ports.sport | ||
77 | #define fl_ip_dport uli_u.ports.dport | ||
78 | #define fl_icmp_type uli_u.icmpt.type | ||
79 | #define fl_icmp_code uli_u.icmpt.code | ||
80 | #define fl_ipsec_spi uli_u.spi | ||
81 | } __attribute__((__aligned__(BITS_PER_LONG/8))); | ||
82 | |||
83 | #define FLOW_DIR_IN 0 | ||
84 | #define FLOW_DIR_OUT 1 | ||
85 | #define FLOW_DIR_FWD 2 | ||
86 | |||
87 | typedef void (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir, | ||
88 | void **objp, atomic_t **obj_refp); | ||
89 | |||
90 | extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, | ||
91 | flow_resolve_t resolver); | ||
92 | extern void flow_cache_flush(void); | ||
93 | extern atomic_t flow_cache_genid; | ||
94 | |||
95 | #endif | ||
diff --git a/include/net/gen_stats.h b/include/net/gen_stats.h new file mode 100644 index 000000000000..0b95cf031d6e --- /dev/null +++ b/include/net/gen_stats.h | |||
@@ -0,0 +1,49 @@ | |||
1 | #ifndef __NET_GEN_STATS_H | ||
2 | #define __NET_GEN_STATS_H | ||
3 | |||
4 | #include <linux/gen_stats.h> | ||
5 | #include <linux/socket.h> | ||
6 | #include <linux/rtnetlink.h> | ||
7 | #include <linux/pkt_sched.h> | ||
8 | |||
9 | struct gnet_dump | ||
10 | { | ||
11 | spinlock_t * lock; | ||
12 | struct sk_buff * skb; | ||
13 | struct rtattr * tail; | ||
14 | |||
15 | /* Backward compatability */ | ||
16 | int compat_tc_stats; | ||
17 | int compat_xstats; | ||
18 | void * xstats; | ||
19 | int xstats_len; | ||
20 | struct tc_stats tc_stats; | ||
21 | }; | ||
22 | |||
23 | extern int gnet_stats_start_copy(struct sk_buff *skb, int type, | ||
24 | spinlock_t *lock, struct gnet_dump *d); | ||
25 | |||
26 | extern int gnet_stats_start_copy_compat(struct sk_buff *skb, int type, | ||
27 | int tc_stats_type,int xstats_type, | ||
28 | spinlock_t *lock, struct gnet_dump *d); | ||
29 | |||
30 | extern int gnet_stats_copy_basic(struct gnet_dump *d, | ||
31 | struct gnet_stats_basic *b); | ||
32 | extern int gnet_stats_copy_rate_est(struct gnet_dump *d, | ||
33 | struct gnet_stats_rate_est *r); | ||
34 | extern int gnet_stats_copy_queue(struct gnet_dump *d, | ||
35 | struct gnet_stats_queue *q); | ||
36 | extern int gnet_stats_copy_app(struct gnet_dump *d, void *st, int len); | ||
37 | |||
38 | extern int gnet_stats_finish_copy(struct gnet_dump *d); | ||
39 | |||
40 | extern int gen_new_estimator(struct gnet_stats_basic *bstats, | ||
41 | struct gnet_stats_rate_est *rate_est, | ||
42 | spinlock_t *stats_lock, struct rtattr *opt); | ||
43 | extern void gen_kill_estimator(struct gnet_stats_basic *bstats, | ||
44 | struct gnet_stats_rate_est *rate_est); | ||
45 | extern int gen_replace_estimator(struct gnet_stats_basic *bstats, | ||
46 | struct gnet_stats_rate_est *rate_est, | ||
47 | spinlock_t *stats_lock, struct rtattr *opt); | ||
48 | |||
49 | #endif | ||
diff --git a/include/net/icmp.h b/include/net/icmp.h new file mode 100644 index 000000000000..3fc192478aa2 --- /dev/null +++ b/include/net/icmp.h | |||
@@ -0,0 +1,60 @@ | |||
1 | /* | ||
2 | * INET An implementation of the TCP/IP protocol suite for the LINUX | ||
3 | * operating system. INET is implemented using the BSD Socket | ||
4 | * interface as the means of communication with the user level. | ||
5 | * | ||
6 | * Definitions for the ICMP module. | ||
7 | * | ||
8 | * Version: @(#)icmp.h 1.0.4 05/13/93 | ||
9 | * | ||
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | ||
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version | ||
16 | * 2 of the License, or (at your option) any later version. | ||
17 | */ | ||
18 | #ifndef _ICMP_H | ||
19 | #define _ICMP_H | ||
20 | |||
21 | #include <linux/config.h> | ||
22 | #include <linux/icmp.h> | ||
23 | #include <linux/skbuff.h> | ||
24 | |||
25 | #include <net/sock.h> | ||
26 | #include <net/protocol.h> | ||
27 | #include <net/snmp.h> | ||
28 | #include <linux/ip.h> | ||
29 | |||
30 | struct icmp_err { | ||
31 | int errno; | ||
32 | unsigned fatal:1; | ||
33 | }; | ||
34 | |||
35 | extern struct icmp_err icmp_err_convert[]; | ||
36 | DECLARE_SNMP_STAT(struct icmp_mib, icmp_statistics); | ||
37 | #define ICMP_INC_STATS(field) SNMP_INC_STATS(icmp_statistics, field) | ||
38 | #define ICMP_INC_STATS_BH(field) SNMP_INC_STATS_BH(icmp_statistics, field) | ||
39 | #define ICMP_INC_STATS_USER(field) SNMP_INC_STATS_USER(icmp_statistics, field) | ||
40 | |||
41 | extern void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info); | ||
42 | extern int icmp_rcv(struct sk_buff *skb); | ||
43 | extern int icmp_ioctl(struct sock *sk, int cmd, unsigned long arg); | ||
44 | extern void icmp_init(struct net_proto_family *ops); | ||
45 | |||
46 | /* Move into dst.h ? */ | ||
47 | extern int xrlim_allow(struct dst_entry *dst, int timeout); | ||
48 | |||
49 | struct raw_sock { | ||
50 | /* inet_sock has to be the first member */ | ||
51 | struct inet_sock inet; | ||
52 | struct icmp_filter filter; | ||
53 | }; | ||
54 | |||
55 | static inline struct raw_sock *raw_sk(const struct sock *sk) | ||
56 | { | ||
57 | return (struct raw_sock *)sk; | ||
58 | } | ||
59 | |||
60 | #endif /* _ICMP_H */ | ||
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h new file mode 100644 index 000000000000..e97a9accb71d --- /dev/null +++ b/include/net/if_inet6.h | |||
@@ -0,0 +1,285 @@ | |||
1 | /* | ||
2 | * inet6 interface/address list definitions | ||
3 | * Linux INET6 implementation | ||
4 | * | ||
5 | * Authors: | ||
6 | * Pedro Roque <roque@di.fc.ul.pt> | ||
7 | * | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | */ | ||
14 | |||
15 | #ifndef _NET_IF_INET6_H | ||
16 | #define _NET_IF_INET6_H | ||
17 | |||
18 | #include <net/snmp.h> | ||
19 | #include <linux/ipv6.h> | ||
20 | |||
21 | /* inet6_dev.if_flags */ | ||
22 | |||
23 | #define IF_RA_OTHERCONF 0x80 | ||
24 | #define IF_RA_MANAGED 0x40 | ||
25 | #define IF_RA_RCVD 0x20 | ||
26 | #define IF_RS_SENT 0x10 | ||
27 | |||
28 | /* prefix flags */ | ||
29 | #define IF_PREFIX_ONLINK 0x01 | ||
30 | #define IF_PREFIX_AUTOCONF 0x02 | ||
31 | |||
32 | #ifdef __KERNEL__ | ||
33 | |||
34 | struct inet6_ifaddr | ||
35 | { | ||
36 | struct in6_addr addr; | ||
37 | __u32 prefix_len; | ||
38 | |||
39 | __u32 valid_lft; | ||
40 | __u32 prefered_lft; | ||
41 | unsigned long cstamp; /* created timestamp */ | ||
42 | unsigned long tstamp; /* updated timestamp */ | ||
43 | atomic_t refcnt; | ||
44 | spinlock_t lock; | ||
45 | |||
46 | __u8 probes; | ||
47 | __u8 flags; | ||
48 | |||
49 | __u16 scope; | ||
50 | |||
51 | struct timer_list timer; | ||
52 | |||
53 | struct inet6_dev *idev; | ||
54 | struct rt6_info *rt; | ||
55 | |||
56 | struct inet6_ifaddr *lst_next; /* next addr in addr_lst */ | ||
57 | struct inet6_ifaddr *if_next; /* next addr in inet6_dev */ | ||
58 | |||
59 | #ifdef CONFIG_IPV6_PRIVACY | ||
60 | struct inet6_ifaddr *tmp_next; /* next addr in tempaddr_lst */ | ||
61 | struct inet6_ifaddr *ifpub; | ||
62 | int regen_count; | ||
63 | #endif | ||
64 | |||
65 | int dead; | ||
66 | }; | ||
67 | |||
68 | struct ip6_sf_socklist | ||
69 | { | ||
70 | unsigned int sl_max; | ||
71 | unsigned int sl_count; | ||
72 | struct in6_addr sl_addr[0]; | ||
73 | }; | ||
74 | |||
75 | #define IP6_SFLSIZE(count) (sizeof(struct ip6_sf_socklist) + \ | ||
76 | (count) * sizeof(struct in6_addr)) | ||
77 | |||
78 | #define IP6_SFBLOCK 10 /* allocate this many at once */ | ||
79 | |||
80 | struct ipv6_mc_socklist | ||
81 | { | ||
82 | struct in6_addr addr; | ||
83 | int ifindex; | ||
84 | struct ipv6_mc_socklist *next; | ||
85 | unsigned int sfmode; /* MCAST_{INCLUDE,EXCLUDE} */ | ||
86 | struct ip6_sf_socklist *sflist; | ||
87 | }; | ||
88 | |||
89 | struct ip6_sf_list | ||
90 | { | ||
91 | struct ip6_sf_list *sf_next; | ||
92 | struct in6_addr sf_addr; | ||
93 | unsigned long sf_count[2]; /* include/exclude counts */ | ||
94 | unsigned char sf_gsresp; /* include in g & s response? */ | ||
95 | unsigned char sf_oldin; /* change state */ | ||
96 | unsigned char sf_crcount; /* retrans. left to send */ | ||
97 | }; | ||
98 | |||
99 | #define MAF_TIMER_RUNNING 0x01 | ||
100 | #define MAF_LAST_REPORTER 0x02 | ||
101 | #define MAF_LOADED 0x04 | ||
102 | #define MAF_NOREPORT 0x08 | ||
103 | #define MAF_GSQUERY 0x10 | ||
104 | |||
105 | struct ifmcaddr6 | ||
106 | { | ||
107 | struct in6_addr mca_addr; | ||
108 | struct inet6_dev *idev; | ||
109 | struct ifmcaddr6 *next; | ||
110 | struct ip6_sf_list *mca_sources; | ||
111 | struct ip6_sf_list *mca_tomb; | ||
112 | unsigned int mca_sfmode; | ||
113 | unsigned long mca_sfcount[2]; | ||
114 | struct timer_list mca_timer; | ||
115 | unsigned mca_flags; | ||
116 | int mca_users; | ||
117 | atomic_t mca_refcnt; | ||
118 | spinlock_t mca_lock; | ||
119 | unsigned char mca_crcount; | ||
120 | unsigned long mca_cstamp; | ||
121 | unsigned long mca_tstamp; | ||
122 | }; | ||
123 | |||
124 | /* Anycast stuff */ | ||
125 | |||
126 | struct ipv6_ac_socklist | ||
127 | { | ||
128 | struct in6_addr acl_addr; | ||
129 | int acl_ifindex; | ||
130 | struct ipv6_ac_socklist *acl_next; | ||
131 | }; | ||
132 | |||
133 | struct ifacaddr6 | ||
134 | { | ||
135 | struct in6_addr aca_addr; | ||
136 | struct inet6_dev *aca_idev; | ||
137 | struct rt6_info *aca_rt; | ||
138 | struct ifacaddr6 *aca_next; | ||
139 | int aca_users; | ||
140 | atomic_t aca_refcnt; | ||
141 | spinlock_t aca_lock; | ||
142 | unsigned long aca_cstamp; | ||
143 | unsigned long aca_tstamp; | ||
144 | }; | ||
145 | |||
146 | #define IFA_HOST IPV6_ADDR_LOOPBACK | ||
147 | #define IFA_LINK IPV6_ADDR_LINKLOCAL | ||
148 | #define IFA_SITE IPV6_ADDR_SITELOCAL | ||
149 | #define IFA_GLOBAL 0x0000U | ||
150 | |||
151 | struct ipv6_devstat { | ||
152 | struct proc_dir_entry *proc_dir_entry; | ||
153 | DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6); | ||
154 | }; | ||
155 | |||
156 | struct inet6_dev | ||
157 | { | ||
158 | struct net_device *dev; | ||
159 | |||
160 | struct inet6_ifaddr *addr_list; | ||
161 | |||
162 | struct ifmcaddr6 *mc_list; | ||
163 | struct ifmcaddr6 *mc_tomb; | ||
164 | rwlock_t mc_lock; | ||
165 | unsigned long mc_v1_seen; | ||
166 | unsigned long mc_maxdelay; | ||
167 | unsigned char mc_qrv; | ||
168 | unsigned char mc_gq_running; | ||
169 | unsigned char mc_ifc_count; | ||
170 | struct timer_list mc_gq_timer; /* general query timer */ | ||
171 | struct timer_list mc_ifc_timer; /* interface change timer */ | ||
172 | |||
173 | struct ifacaddr6 *ac_list; | ||
174 | rwlock_t lock; | ||
175 | atomic_t refcnt; | ||
176 | __u32 if_flags; | ||
177 | int dead; | ||
178 | |||
179 | #ifdef CONFIG_IPV6_PRIVACY | ||
180 | u8 rndid[8]; | ||
181 | u8 entropy[8]; | ||
182 | struct timer_list regen_timer; | ||
183 | struct inet6_ifaddr *tempaddr_list; | ||
184 | __u8 work_eui64[8]; | ||
185 | __u8 work_digest[16]; | ||
186 | #endif | ||
187 | |||
188 | struct neigh_parms *nd_parms; | ||
189 | struct inet6_dev *next; | ||
190 | struct ipv6_devconf cnf; | ||
191 | struct ipv6_devstat stats; | ||
192 | unsigned long tstamp; /* ipv6InterfaceTable update timestamp */ | ||
193 | }; | ||
194 | |||
195 | extern struct ipv6_devconf ipv6_devconf; | ||
196 | |||
197 | static inline void ipv6_eth_mc_map(struct in6_addr *addr, char *buf) | ||
198 | { | ||
199 | /* | ||
200 | * +-------+-------+-------+-------+-------+-------+ | ||
201 | * | 33 | 33 | DST13 | DST14 | DST15 | DST16 | | ||
202 | * +-------+-------+-------+-------+-------+-------+ | ||
203 | */ | ||
204 | |||
205 | buf[0]= 0x33; | ||
206 | buf[1]= 0x33; | ||
207 | |||
208 | memcpy(buf + 2, &addr->s6_addr32[3], sizeof(__u32)); | ||
209 | } | ||
210 | |||
211 | static inline void ipv6_tr_mc_map(struct in6_addr *addr, char *buf) | ||
212 | { | ||
213 | /* All nodes FF01::1, FF02::1, FF02::1:FFxx:xxxx */ | ||
214 | |||
215 | if (((addr->s6_addr[0] == 0xFF) && | ||
216 | ((addr->s6_addr[1] == 0x01) || (addr->s6_addr[1] == 0x02)) && | ||
217 | (addr->s6_addr16[1] == 0) && | ||
218 | (addr->s6_addr32[1] == 0) && | ||
219 | (addr->s6_addr32[2] == 0) && | ||
220 | (addr->s6_addr16[6] == 0) && | ||
221 | (addr->s6_addr[15] == 1)) || | ||
222 | ((addr->s6_addr[0] == 0xFF) && | ||
223 | (addr->s6_addr[1] == 0x02) && | ||
224 | (addr->s6_addr16[1] == 0) && | ||
225 | (addr->s6_addr32[1] == 0) && | ||
226 | (addr->s6_addr16[4] == 0) && | ||
227 | (addr->s6_addr[10] == 0) && | ||
228 | (addr->s6_addr[11] == 1) && | ||
229 | (addr->s6_addr[12] == 0xff))) | ||
230 | { | ||
231 | buf[0]=0xC0; | ||
232 | buf[1]=0x00; | ||
233 | buf[2]=0x01; | ||
234 | buf[3]=0x00; | ||
235 | buf[4]=0x00; | ||
236 | buf[5]=0x00; | ||
237 | /* All routers FF0x::2 */ | ||
238 | } else if ((addr->s6_addr[0] ==0xff) && | ||
239 | ((addr->s6_addr[1] & 0xF0) == 0) && | ||
240 | (addr->s6_addr16[1] == 0) && | ||
241 | (addr->s6_addr32[1] == 0) && | ||
242 | (addr->s6_addr32[2] == 0) && | ||
243 | (addr->s6_addr16[6] == 0) && | ||
244 | (addr->s6_addr[15] == 2)) | ||
245 | { | ||
246 | buf[0]=0xC0; | ||
247 | buf[1]=0x00; | ||
248 | buf[2]=0x02; | ||
249 | buf[3]=0x00; | ||
250 | buf[4]=0x00; | ||
251 | buf[5]=0x00; | ||
252 | } else { | ||
253 | unsigned char i ; | ||
254 | |||
255 | i = addr->s6_addr[15] & 7 ; | ||
256 | buf[0]=0xC0; | ||
257 | buf[1]=0x00; | ||
258 | buf[2]=0x00; | ||
259 | buf[3]=0x01 << i ; | ||
260 | buf[4]=0x00; | ||
261 | buf[5]=0x00; | ||
262 | } | ||
263 | } | ||
264 | |||
265 | static inline void ipv6_arcnet_mc_map(const struct in6_addr *addr, char *buf) | ||
266 | { | ||
267 | buf[0] = 0x00; | ||
268 | } | ||
269 | |||
270 | static inline void ipv6_ib_mc_map(struct in6_addr *addr, char *buf) | ||
271 | { | ||
272 | buf[0] = 0; /* Reserved */ | ||
273 | buf[1] = 0xff; /* Multicast QPN */ | ||
274 | buf[2] = 0xff; | ||
275 | buf[3] = 0xff; | ||
276 | buf[4] = 0xff; | ||
277 | buf[5] = 0x12; /* link local scope */ | ||
278 | buf[6] = 0x60; /* IPv6 signature */ | ||
279 | buf[7] = 0x1b; | ||
280 | buf[8] = 0; /* P_Key */ | ||
281 | buf[9] = 0; | ||
282 | memcpy(buf + 10, addr->s6_addr + 6, 10); | ||
283 | } | ||
284 | #endif | ||
285 | #endif | ||
diff --git a/include/net/inet_common.h b/include/net/inet_common.h new file mode 100644 index 000000000000..fbc1f4d140d8 --- /dev/null +++ b/include/net/inet_common.h | |||
@@ -0,0 +1,44 @@ | |||
1 | #ifndef _INET_COMMON_H | ||
2 | #define _INET_COMMON_H | ||
3 | |||
4 | extern struct proto_ops inet_stream_ops; | ||
5 | extern struct proto_ops inet_dgram_ops; | ||
6 | |||
7 | /* | ||
8 | * INET4 prototypes used by INET6 | ||
9 | */ | ||
10 | |||
11 | extern void inet_remove_sock(struct sock *sk1); | ||
12 | extern void inet_put_sock(unsigned short num, | ||
13 | struct sock *sk); | ||
14 | extern int inet_release(struct socket *sock); | ||
15 | extern int inet_stream_connect(struct socket *sock, | ||
16 | struct sockaddr * uaddr, | ||
17 | int addr_len, int flags); | ||
18 | extern int inet_dgram_connect(struct socket *sock, | ||
19 | struct sockaddr * uaddr, | ||
20 | int addr_len, int flags); | ||
21 | extern int inet_accept(struct socket *sock, | ||
22 | struct socket *newsock, int flags); | ||
23 | extern int inet_sendmsg(struct kiocb *iocb, | ||
24 | struct socket *sock, | ||
25 | struct msghdr *msg, | ||
26 | size_t size); | ||
27 | extern int inet_shutdown(struct socket *sock, int how); | ||
28 | extern unsigned int inet_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait); | ||
29 | extern int inet_listen(struct socket *sock, int backlog); | ||
30 | |||
31 | extern void inet_sock_destruct(struct sock *sk); | ||
32 | extern atomic_t inet_sock_nr; | ||
33 | |||
34 | extern int inet_bind(struct socket *sock, | ||
35 | struct sockaddr *uaddr, int addr_len); | ||
36 | extern int inet_getname(struct socket *sock, | ||
37 | struct sockaddr *uaddr, | ||
38 | int *uaddr_len, int peer); | ||
39 | extern int inet_ioctl(struct socket *sock, | ||
40 | unsigned int cmd, unsigned long arg); | ||
41 | |||
42 | #endif | ||
43 | |||
44 | |||
diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h new file mode 100644 index 000000000000..f87845e2e965 --- /dev/null +++ b/include/net/inet_ecn.h | |||
@@ -0,0 +1,108 @@ | |||
1 | #ifndef _INET_ECN_H_ | ||
2 | #define _INET_ECN_H_ | ||
3 | |||
4 | #include <linux/ip.h> | ||
5 | #include <net/dsfield.h> | ||
6 | |||
7 | enum { | ||
8 | INET_ECN_NOT_ECT = 0, | ||
9 | INET_ECN_ECT_1 = 1, | ||
10 | INET_ECN_ECT_0 = 2, | ||
11 | INET_ECN_CE = 3, | ||
12 | INET_ECN_MASK = 3, | ||
13 | }; | ||
14 | |||
15 | static inline int INET_ECN_is_ce(__u8 dsfield) | ||
16 | { | ||
17 | return (dsfield & INET_ECN_MASK) == INET_ECN_CE; | ||
18 | } | ||
19 | |||
20 | static inline int INET_ECN_is_not_ect(__u8 dsfield) | ||
21 | { | ||
22 | return (dsfield & INET_ECN_MASK) == INET_ECN_NOT_ECT; | ||
23 | } | ||
24 | |||
25 | static inline int INET_ECN_is_capable(__u8 dsfield) | ||
26 | { | ||
27 | return (dsfield & INET_ECN_ECT_0); | ||
28 | } | ||
29 | |||
30 | static inline __u8 INET_ECN_encapsulate(__u8 outer, __u8 inner) | ||
31 | { | ||
32 | outer &= ~INET_ECN_MASK; | ||
33 | outer |= !INET_ECN_is_ce(inner) ? (inner & INET_ECN_MASK) : | ||
34 | INET_ECN_ECT_0; | ||
35 | return outer; | ||
36 | } | ||
37 | |||
38 | #define INET_ECN_xmit(sk) do { inet_sk(sk)->tos |= INET_ECN_ECT_0; } while (0) | ||
39 | #define INET_ECN_dontxmit(sk) \ | ||
40 | do { inet_sk(sk)->tos &= ~INET_ECN_MASK; } while (0) | ||
41 | |||
42 | #define IP6_ECN_flow_init(label) do { \ | ||
43 | (label) &= ~htonl(INET_ECN_MASK << 20); \ | ||
44 | } while (0) | ||
45 | |||
46 | #define IP6_ECN_flow_xmit(sk, label) do { \ | ||
47 | if (INET_ECN_is_capable(inet_sk(sk)->tos)) \ | ||
48 | (label) |= __constant_htons(INET_ECN_ECT_0 << 4); \ | ||
49 | } while (0) | ||
50 | |||
51 | static inline void IP_ECN_set_ce(struct iphdr *iph) | ||
52 | { | ||
53 | u32 check = iph->check; | ||
54 | u32 ecn = (iph->tos + 1) & INET_ECN_MASK; | ||
55 | |||
56 | /* | ||
57 | * After the last operation we have (in binary): | ||
58 | * INET_ECN_NOT_ECT => 01 | ||
59 | * INET_ECN_ECT_1 => 10 | ||
60 | * INET_ECN_ECT_0 => 11 | ||
61 | * INET_ECN_CE => 00 | ||
62 | */ | ||
63 | if (!(ecn & 2)) | ||
64 | return; | ||
65 | |||
66 | /* | ||
67 | * The following gives us: | ||
68 | * INET_ECN_ECT_1 => check += htons(0xFFFD) | ||
69 | * INET_ECN_ECT_0 => check += htons(0xFFFE) | ||
70 | */ | ||
71 | check += htons(0xFFFB) + htons(ecn); | ||
72 | |||
73 | iph->check = check + (check>=0xFFFF); | ||
74 | iph->tos |= INET_ECN_CE; | ||
75 | } | ||
76 | |||
77 | static inline void IP_ECN_clear(struct iphdr *iph) | ||
78 | { | ||
79 | iph->tos &= ~INET_ECN_MASK; | ||
80 | } | ||
81 | |||
82 | static inline void ipv4_copy_dscp(struct iphdr *outer, struct iphdr *inner) | ||
83 | { | ||
84 | u32 dscp = ipv4_get_dsfield(outer) & ~INET_ECN_MASK; | ||
85 | ipv4_change_dsfield(inner, INET_ECN_MASK, dscp); | ||
86 | } | ||
87 | |||
88 | struct ipv6hdr; | ||
89 | |||
90 | static inline void IP6_ECN_set_ce(struct ipv6hdr *iph) | ||
91 | { | ||
92 | if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph))) | ||
93 | return; | ||
94 | *(u32*)iph |= htonl(INET_ECN_CE << 20); | ||
95 | } | ||
96 | |||
97 | static inline void IP6_ECN_clear(struct ipv6hdr *iph) | ||
98 | { | ||
99 | *(u32*)iph &= ~htonl(INET_ECN_MASK << 20); | ||
100 | } | ||
101 | |||
102 | static inline void ipv6_copy_dscp(struct ipv6hdr *outer, struct ipv6hdr *inner) | ||
103 | { | ||
104 | u32 dscp = ipv6_get_dsfield(outer) & ~INET_ECN_MASK; | ||
105 | ipv6_change_dsfield(inner, INET_ECN_MASK, dscp); | ||
106 | } | ||
107 | |||
108 | #endif | ||
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h new file mode 100644 index 000000000000..7fda471002b6 --- /dev/null +++ b/include/net/inetpeer.h | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | * INETPEER - A storage for permanent information about peers | ||
3 | * | ||
4 | * Version: $Id: inetpeer.h,v 1.2 2002/01/12 07:54:56 davem Exp $ | ||
5 | * | ||
6 | * Authors: Andrey V. Savochkin <saw@msu.ru> | ||
7 | */ | ||
8 | |||
9 | #ifndef _NET_INETPEER_H | ||
10 | #define _NET_INETPEER_H | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/jiffies.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | #include <asm/atomic.h> | ||
17 | |||
18 | struct inet_peer | ||
19 | { | ||
20 | struct inet_peer *avl_left, *avl_right; | ||
21 | struct inet_peer *unused_next, **unused_prevp; | ||
22 | unsigned long dtime; /* the time of last use of not | ||
23 | * referenced entries */ | ||
24 | atomic_t refcnt; | ||
25 | __u32 v4daddr; /* peer's address */ | ||
26 | __u16 avl_height; | ||
27 | __u16 ip_id_count; /* IP ID for the next packet */ | ||
28 | __u32 tcp_ts; | ||
29 | unsigned long tcp_ts_stamp; | ||
30 | }; | ||
31 | |||
32 | void inet_initpeers(void) __init; | ||
33 | |||
34 | /* can be called with or without local BH being disabled */ | ||
35 | struct inet_peer *inet_getpeer(__u32 daddr, int create); | ||
36 | |||
37 | extern spinlock_t inet_peer_unused_lock; | ||
38 | extern struct inet_peer **inet_peer_unused_tailp; | ||
39 | /* can be called from BH context or outside */ | ||
40 | static inline void inet_putpeer(struct inet_peer *p) | ||
41 | { | ||
42 | spin_lock_bh(&inet_peer_unused_lock); | ||
43 | if (atomic_dec_and_test(&p->refcnt)) { | ||
44 | p->unused_prevp = inet_peer_unused_tailp; | ||
45 | p->unused_next = NULL; | ||
46 | *inet_peer_unused_tailp = p; | ||
47 | inet_peer_unused_tailp = &p->unused_next; | ||
48 | p->dtime = jiffies; | ||
49 | } | ||
50 | spin_unlock_bh(&inet_peer_unused_lock); | ||
51 | } | ||
52 | |||
53 | extern spinlock_t inet_peer_idlock; | ||
54 | /* can be called with or without local BH being disabled */ | ||
55 | static inline __u16 inet_getid(struct inet_peer *p, int more) | ||
56 | { | ||
57 | __u16 id; | ||
58 | |||
59 | spin_lock_bh(&inet_peer_idlock); | ||
60 | id = p->ip_id_count; | ||
61 | p->ip_id_count += 1 + more; | ||
62 | spin_unlock_bh(&inet_peer_idlock); | ||
63 | return id; | ||
64 | } | ||
65 | |||
66 | #endif /* _NET_INETPEER_H */ | ||
diff --git a/include/net/ip.h b/include/net/ip.h new file mode 100644 index 000000000000..b4db1375da2c --- /dev/null +++ b/include/net/ip.h | |||
@@ -0,0 +1,353 @@ | |||
1 | /* | ||
2 | * INET An implementation of the TCP/IP protocol suite for the LINUX | ||
3 | * operating system. INET is implemented using the BSD Socket | ||
4 | * interface as the means of communication with the user level. | ||
5 | * | ||
6 | * Definitions for the IP module. | ||
7 | * | ||
8 | * Version: @(#)ip.h 1.0.2 05/07/93 | ||
9 | * | ||
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | ||
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | ||
12 | * Alan Cox, <gw4pts@gw4pts.ampr.org> | ||
13 | * | ||
14 | * Changes: | ||
15 | * Mike McLagan : Routing by source | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or | ||
18 | * modify it under the terms of the GNU General Public License | ||
19 | * as published by the Free Software Foundation; either version | ||
20 | * 2 of the License, or (at your option) any later version. | ||
21 | */ | ||
22 | #ifndef _IP_H | ||
23 | #define _IP_H | ||
24 | |||
25 | #include <linux/config.h> | ||
26 | #include <linux/types.h> | ||
27 | #include <linux/socket.h> | ||
28 | #include <linux/ip.h> | ||
29 | #include <linux/in.h> | ||
30 | #include <linux/netdevice.h> | ||
31 | #include <linux/inetdevice.h> | ||
32 | #include <linux/in_route.h> | ||
33 | #include <net/route.h> | ||
34 | #include <net/arp.h> | ||
35 | #include <net/snmp.h> | ||
36 | |||
37 | struct sock; | ||
38 | |||
39 | struct inet_skb_parm | ||
40 | { | ||
41 | struct ip_options opt; /* Compiled IP options */ | ||
42 | unsigned char flags; | ||
43 | |||
44 | #define IPSKB_MASQUERADED 1 | ||
45 | #define IPSKB_TRANSLATED 2 | ||
46 | #define IPSKB_FORWARDED 4 | ||
47 | #define IPSKB_XFRM_TUNNEL_SIZE 8 | ||
48 | }; | ||
49 | |||
50 | struct ipcm_cookie | ||
51 | { | ||
52 | u32 addr; | ||
53 | int oif; | ||
54 | struct ip_options *opt; | ||
55 | }; | ||
56 | |||
57 | #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) | ||
58 | |||
59 | struct ip_ra_chain | ||
60 | { | ||
61 | struct ip_ra_chain *next; | ||
62 | struct sock *sk; | ||
63 | void (*destructor)(struct sock *); | ||
64 | }; | ||
65 | |||
66 | extern struct ip_ra_chain *ip_ra_chain; | ||
67 | extern rwlock_t ip_ra_lock; | ||
68 | |||
69 | /* IP flags. */ | ||
70 | #define IP_CE 0x8000 /* Flag: "Congestion" */ | ||
71 | #define IP_DF 0x4000 /* Flag: "Don't Fragment" */ | ||
72 | #define IP_MF 0x2000 /* Flag: "More Fragments" */ | ||
73 | #define IP_OFFSET 0x1FFF /* "Fragment Offset" part */ | ||
74 | |||
75 | #define IP_FRAG_TIME (30 * HZ) /* fragment lifetime */ | ||
76 | |||
77 | extern void ip_mc_dropsocket(struct sock *); | ||
78 | extern void ip_mc_dropdevice(struct net_device *dev); | ||
79 | extern int igmp_mc_proc_init(void); | ||
80 | |||
81 | /* | ||
82 | * Functions provided by ip.c | ||
83 | */ | ||
84 | |||
85 | extern int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk, | ||
86 | u32 saddr, u32 daddr, | ||
87 | struct ip_options *opt); | ||
88 | extern int ip_rcv(struct sk_buff *skb, struct net_device *dev, | ||
89 | struct packet_type *pt); | ||
90 | extern int ip_local_deliver(struct sk_buff *skb); | ||
91 | extern int ip_mr_input(struct sk_buff *skb); | ||
92 | extern int ip_output(struct sk_buff *skb); | ||
93 | extern int ip_mc_output(struct sk_buff *skb); | ||
94 | extern int ip_fragment(struct sk_buff *skb, int (*out)(struct sk_buff*)); | ||
95 | extern int ip_do_nat(struct sk_buff *skb); | ||
96 | extern void ip_send_check(struct iphdr *ip); | ||
97 | extern int ip_queue_xmit(struct sk_buff *skb, int ipfragok); | ||
98 | extern void ip_init(void); | ||
99 | extern int ip_append_data(struct sock *sk, | ||
100 | int getfrag(void *from, char *to, int offset, int len, | ||
101 | int odd, struct sk_buff *skb), | ||
102 | void *from, int len, int protolen, | ||
103 | struct ipcm_cookie *ipc, | ||
104 | struct rtable *rt, | ||
105 | unsigned int flags); | ||
106 | extern int ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb); | ||
107 | extern ssize_t ip_append_page(struct sock *sk, struct page *page, | ||
108 | int offset, size_t size, int flags); | ||
109 | extern int ip_push_pending_frames(struct sock *sk); | ||
110 | extern void ip_flush_pending_frames(struct sock *sk); | ||
111 | |||
112 | /* datagram.c */ | ||
113 | extern int ip4_datagram_connect(struct sock *sk, | ||
114 | struct sockaddr *uaddr, int addr_len); | ||
115 | |||
116 | /* | ||
117 | * Map a multicast IP onto multicast MAC for type Token Ring. | ||
118 | * This conforms to RFC1469 Option 2 Multicasting i.e. | ||
119 | * using a functional address to transmit / receive | ||
120 | * multicast packets. | ||
121 | */ | ||
122 | |||
123 | static inline void ip_tr_mc_map(u32 addr, char *buf) | ||
124 | { | ||
125 | buf[0]=0xC0; | ||
126 | buf[1]=0x00; | ||
127 | buf[2]=0x00; | ||
128 | buf[3]=0x04; | ||
129 | buf[4]=0x00; | ||
130 | buf[5]=0x00; | ||
131 | } | ||
132 | |||
133 | struct ip_reply_arg { | ||
134 | struct kvec iov[1]; | ||
135 | u32 csum; | ||
136 | int csumoffset; /* u16 offset of csum in iov[0].iov_base */ | ||
137 | /* -1 if not needed */ | ||
138 | }; | ||
139 | |||
140 | void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg, | ||
141 | unsigned int len); | ||
142 | |||
143 | extern int ip_finish_output(struct sk_buff *skb); | ||
144 | |||
145 | struct ipv4_config | ||
146 | { | ||
147 | int log_martians; | ||
148 | int autoconfig; | ||
149 | int no_pmtu_disc; | ||
150 | }; | ||
151 | |||
152 | extern struct ipv4_config ipv4_config; | ||
153 | DECLARE_SNMP_STAT(struct ipstats_mib, ip_statistics); | ||
154 | #define IP_INC_STATS(field) SNMP_INC_STATS(ip_statistics, field) | ||
155 | #define IP_INC_STATS_BH(field) SNMP_INC_STATS_BH(ip_statistics, field) | ||
156 | #define IP_INC_STATS_USER(field) SNMP_INC_STATS_USER(ip_statistics, field) | ||
157 | DECLARE_SNMP_STAT(struct linux_mib, net_statistics); | ||
158 | #define NET_INC_STATS(field) SNMP_INC_STATS(net_statistics, field) | ||
159 | #define NET_INC_STATS_BH(field) SNMP_INC_STATS_BH(net_statistics, field) | ||
160 | #define NET_INC_STATS_USER(field) SNMP_INC_STATS_USER(net_statistics, field) | ||
161 | #define NET_ADD_STATS_BH(field, adnd) SNMP_ADD_STATS_BH(net_statistics, field, adnd) | ||
162 | #define NET_ADD_STATS_USER(field, adnd) SNMP_ADD_STATS_USER(net_statistics, field, adnd) | ||
163 | |||
164 | extern int sysctl_local_port_range[2]; | ||
165 | extern int sysctl_ip_default_ttl; | ||
166 | |||
167 | #ifdef CONFIG_INET | ||
168 | /* The function in 2.2 was invalid, producing wrong result for | ||
169 | * check=0xFEFF. It was noticed by Arthur Skawina _year_ ago. --ANK(000625) */ | ||
170 | static inline | ||
171 | int ip_decrease_ttl(struct iphdr *iph) | ||
172 | { | ||
173 | u32 check = iph->check; | ||
174 | check += htons(0x0100); | ||
175 | iph->check = check + (check>=0xFFFF); | ||
176 | return --iph->ttl; | ||
177 | } | ||
178 | |||
179 | static inline | ||
180 | int ip_dont_fragment(struct sock *sk, struct dst_entry *dst) | ||
181 | { | ||
182 | return (inet_sk(sk)->pmtudisc == IP_PMTUDISC_DO || | ||
183 | (inet_sk(sk)->pmtudisc == IP_PMTUDISC_WANT && | ||
184 | !(dst_metric(dst, RTAX_LOCK)&(1<<RTAX_MTU)))); | ||
185 | } | ||
186 | |||
187 | extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more); | ||
188 | |||
189 | static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct sock *sk) | ||
190 | { | ||
191 | if (iph->frag_off & htons(IP_DF)) { | ||
192 | /* This is only to work around buggy Windows95/2000 | ||
193 | * VJ compression implementations. If the ID field | ||
194 | * does not change, they drop every other packet in | ||
195 | * a TCP stream using header compression. | ||
196 | */ | ||
197 | iph->id = (sk && inet_sk(sk)->daddr) ? | ||
198 | htons(inet_sk(sk)->id++) : 0; | ||
199 | } else | ||
200 | __ip_select_ident(iph, dst, 0); | ||
201 | } | ||
202 | |||
203 | static inline void ip_select_ident_more(struct iphdr *iph, struct dst_entry *dst, struct sock *sk, int more) | ||
204 | { | ||
205 | if (iph->frag_off & htons(IP_DF)) { | ||
206 | if (sk && inet_sk(sk)->daddr) { | ||
207 | iph->id = htons(inet_sk(sk)->id); | ||
208 | inet_sk(sk)->id += 1 + more; | ||
209 | } else | ||
210 | iph->id = 0; | ||
211 | } else | ||
212 | __ip_select_ident(iph, dst, more); | ||
213 | } | ||
214 | |||
215 | /* | ||
216 | * Map a multicast IP onto multicast MAC for type ethernet. | ||
217 | */ | ||
218 | |||
219 | static inline void ip_eth_mc_map(u32 addr, char *buf) | ||
220 | { | ||
221 | addr=ntohl(addr); | ||
222 | buf[0]=0x01; | ||
223 | buf[1]=0x00; | ||
224 | buf[2]=0x5e; | ||
225 | buf[5]=addr&0xFF; | ||
226 | addr>>=8; | ||
227 | buf[4]=addr&0xFF; | ||
228 | addr>>=8; | ||
229 | buf[3]=addr&0x7F; | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * Map a multicast IP onto multicast MAC for type IP-over-InfiniBand. | ||
234 | * Leave P_Key as 0 to be filled in by driver. | ||
235 | */ | ||
236 | |||
237 | static inline void ip_ib_mc_map(u32 addr, char *buf) | ||
238 | { | ||
239 | buf[0] = 0; /* Reserved */ | ||
240 | buf[1] = 0xff; /* Multicast QPN */ | ||
241 | buf[2] = 0xff; | ||
242 | buf[3] = 0xff; | ||
243 | addr = ntohl(addr); | ||
244 | buf[4] = 0xff; | ||
245 | buf[5] = 0x12; /* link local scope */ | ||
246 | buf[6] = 0x40; /* IPv4 signature */ | ||
247 | buf[7] = 0x1b; | ||
248 | buf[8] = 0; /* P_Key */ | ||
249 | buf[9] = 0; | ||
250 | buf[10] = 0; | ||
251 | buf[11] = 0; | ||
252 | buf[12] = 0; | ||
253 | buf[13] = 0; | ||
254 | buf[14] = 0; | ||
255 | buf[15] = 0; | ||
256 | buf[19] = addr & 0xff; | ||
257 | addr >>= 8; | ||
258 | buf[18] = addr & 0xff; | ||
259 | addr >>= 8; | ||
260 | buf[17] = addr & 0xff; | ||
261 | addr >>= 8; | ||
262 | buf[16] = addr & 0x0f; | ||
263 | } | ||
264 | |||
265 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
266 | #include <linux/ipv6.h> | ||
267 | #endif | ||
268 | |||
269 | static __inline__ void inet_reset_saddr(struct sock *sk) | ||
270 | { | ||
271 | inet_sk(sk)->rcv_saddr = inet_sk(sk)->saddr = 0; | ||
272 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
273 | if (sk->sk_family == PF_INET6) { | ||
274 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
275 | |||
276 | memset(&np->saddr, 0, sizeof(np->saddr)); | ||
277 | memset(&np->rcv_saddr, 0, sizeof(np->rcv_saddr)); | ||
278 | } | ||
279 | #endif | ||
280 | } | ||
281 | |||
282 | #endif | ||
283 | |||
284 | extern int ip_call_ra_chain(struct sk_buff *skb); | ||
285 | |||
286 | /* | ||
287 | * Functions provided by ip_fragment.o | ||
288 | */ | ||
289 | |||
290 | enum ip_defrag_users | ||
291 | { | ||
292 | IP_DEFRAG_LOCAL_DELIVER, | ||
293 | IP_DEFRAG_CALL_RA_CHAIN, | ||
294 | IP_DEFRAG_CONNTRACK_IN, | ||
295 | IP_DEFRAG_CONNTRACK_OUT, | ||
296 | IP_DEFRAG_NAT_OUT, | ||
297 | IP_DEFRAG_VS_IN, | ||
298 | IP_DEFRAG_VS_OUT, | ||
299 | IP_DEFRAG_VS_FWD | ||
300 | }; | ||
301 | |||
302 | struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user); | ||
303 | extern int ip_frag_nqueues; | ||
304 | extern atomic_t ip_frag_mem; | ||
305 | |||
306 | /* | ||
307 | * Functions provided by ip_forward.c | ||
308 | */ | ||
309 | |||
310 | extern int ip_forward(struct sk_buff *skb); | ||
311 | extern int ip_net_unreachable(struct sk_buff *skb); | ||
312 | |||
313 | /* | ||
314 | * Functions provided by ip_options.c | ||
315 | */ | ||
316 | |||
317 | extern void ip_options_build(struct sk_buff *skb, struct ip_options *opt, u32 daddr, struct rtable *rt, int is_frag); | ||
318 | extern int ip_options_echo(struct ip_options *dopt, struct sk_buff *skb); | ||
319 | extern void ip_options_fragment(struct sk_buff *skb); | ||
320 | extern int ip_options_compile(struct ip_options *opt, struct sk_buff *skb); | ||
321 | extern int ip_options_get(struct ip_options **optp, unsigned char *data, int optlen, int user); | ||
322 | extern void ip_options_undo(struct ip_options * opt); | ||
323 | extern void ip_forward_options(struct sk_buff *skb); | ||
324 | extern int ip_options_rcv_srr(struct sk_buff *skb); | ||
325 | |||
326 | /* | ||
327 | * Functions provided by ip_sockglue.c | ||
328 | */ | ||
329 | |||
330 | extern void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb); | ||
331 | extern int ip_cmsg_send(struct msghdr *msg, struct ipcm_cookie *ipc); | ||
332 | extern int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, int optlen); | ||
333 | extern int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); | ||
334 | extern int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *)); | ||
335 | |||
336 | extern int ip_recv_error(struct sock *sk, struct msghdr *msg, int len); | ||
337 | extern void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, | ||
338 | u16 port, u32 info, u8 *payload); | ||
339 | extern void ip_local_error(struct sock *sk, int err, u32 daddr, u16 dport, | ||
340 | u32 info); | ||
341 | |||
342 | /* sysctl helpers - any sysctl which holds a value that ends up being | ||
343 | * fed into the routing cache should use these handlers. | ||
344 | */ | ||
345 | int ipv4_doint_and_flush(ctl_table *ctl, int write, | ||
346 | struct file* filp, void __user *buffer, | ||
347 | size_t *lenp, loff_t *ppos); | ||
348 | int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen, | ||
349 | void __user *oldval, size_t __user *oldlenp, | ||
350 | void __user *newval, size_t newlen, | ||
351 | void **context); | ||
352 | |||
353 | #endif /* _IP_H */ | ||
diff --git a/include/net/ip6_checksum.h b/include/net/ip6_checksum.h new file mode 100644 index 000000000000..3dfc885bdf25 --- /dev/null +++ b/include/net/ip6_checksum.h | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * INET An implementation of the TCP/IP protocol suite for the LINUX | ||
3 | * operating system. INET is implemented using the BSD Socket | ||
4 | * interface as the means of communication with the user level. | ||
5 | * | ||
6 | * Checksumming functions for IPv6 | ||
7 | * | ||
8 | * Authors: Jorge Cwik, <jorge@laser.satlink.net> | ||
9 | * Arnt Gulbrandsen, <agulbra@nvg.unit.no> | ||
10 | * Borrows very liberally from tcp.c and ip.c, see those | ||
11 | * files for more names. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version | ||
16 | * 2 of the License, or (at your option) any later version. | ||
17 | */ | ||
18 | |||
19 | /* | ||
20 | * Fixes: | ||
21 | * | ||
22 | * Ralf Baechle : generic ipv6 checksum | ||
23 | * <ralf@waldorf-gmbh.de> | ||
24 | */ | ||
25 | |||
26 | #ifndef _CHECKSUM_IPV6_H | ||
27 | #define _CHECKSUM_IPV6_H | ||
28 | |||
29 | #include <asm/types.h> | ||
30 | #include <asm/byteorder.h> | ||
31 | #include <net/ip.h> | ||
32 | #include <asm/checksum.h> | ||
33 | #include <linux/in6.h> | ||
34 | |||
35 | #ifndef _HAVE_ARCH_IPV6_CSUM | ||
36 | |||
37 | static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, | ||
38 | struct in6_addr *daddr, | ||
39 | __u16 len, | ||
40 | unsigned short proto, | ||
41 | unsigned int csum) | ||
42 | { | ||
43 | |||
44 | int carry; | ||
45 | __u32 ulen; | ||
46 | __u32 uproto; | ||
47 | |||
48 | csum += saddr->s6_addr32[0]; | ||
49 | carry = (csum < saddr->s6_addr32[0]); | ||
50 | csum += carry; | ||
51 | |||
52 | csum += saddr->s6_addr32[1]; | ||
53 | carry = (csum < saddr->s6_addr32[1]); | ||
54 | csum += carry; | ||
55 | |||
56 | csum += saddr->s6_addr32[2]; | ||
57 | carry = (csum < saddr->s6_addr32[2]); | ||
58 | csum += carry; | ||
59 | |||
60 | csum += saddr->s6_addr32[3]; | ||
61 | carry = (csum < saddr->s6_addr32[3]); | ||
62 | csum += carry; | ||
63 | |||
64 | csum += daddr->s6_addr32[0]; | ||
65 | carry = (csum < daddr->s6_addr32[0]); | ||
66 | csum += carry; | ||
67 | |||
68 | csum += daddr->s6_addr32[1]; | ||
69 | carry = (csum < daddr->s6_addr32[1]); | ||
70 | csum += carry; | ||
71 | |||
72 | csum += daddr->s6_addr32[2]; | ||
73 | carry = (csum < daddr->s6_addr32[2]); | ||
74 | csum += carry; | ||
75 | |||
76 | csum += daddr->s6_addr32[3]; | ||
77 | carry = (csum < daddr->s6_addr32[3]); | ||
78 | csum += carry; | ||
79 | |||
80 | ulen = htonl((__u32) len); | ||
81 | csum += ulen; | ||
82 | carry = (csum < ulen); | ||
83 | csum += carry; | ||
84 | |||
85 | uproto = htonl(proto); | ||
86 | csum += uproto; | ||
87 | carry = (csum < uproto); | ||
88 | csum += carry; | ||
89 | |||
90 | return csum_fold(csum); | ||
91 | } | ||
92 | |||
93 | #endif | ||
94 | #endif | ||
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h new file mode 100644 index 000000000000..319904518194 --- /dev/null +++ b/include/net/ip6_fib.h | |||
@@ -0,0 +1,185 @@ | |||
1 | /* | ||
2 | * Linux INET6 implementation | ||
3 | * | ||
4 | * Authors: | ||
5 | * Pedro Roque <roque@di.fc.ul.pt> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version | ||
10 | * 2 of the License, or (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #ifndef _IP6_FIB_H | ||
14 | #define _IP6_FIB_H | ||
15 | |||
16 | #ifdef __KERNEL__ | ||
17 | |||
18 | #include <linux/ipv6_route.h> | ||
19 | |||
20 | #include <net/dst.h> | ||
21 | #include <net/flow.h> | ||
22 | #include <linux/rtnetlink.h> | ||
23 | #include <linux/spinlock.h> | ||
24 | |||
25 | struct rt6_info; | ||
26 | |||
27 | struct fib6_node | ||
28 | { | ||
29 | struct fib6_node *parent; | ||
30 | struct fib6_node *left; | ||
31 | struct fib6_node *right; | ||
32 | |||
33 | struct fib6_node *subtree; | ||
34 | |||
35 | struct rt6_info *leaf; | ||
36 | |||
37 | __u16 fn_bit; /* bit key */ | ||
38 | __u16 fn_flags; | ||
39 | __u32 fn_sernum; | ||
40 | }; | ||
41 | |||
42 | |||
43 | /* | ||
44 | * routing information | ||
45 | * | ||
46 | */ | ||
47 | |||
48 | struct rt6key | ||
49 | { | ||
50 | struct in6_addr addr; | ||
51 | int plen; | ||
52 | }; | ||
53 | |||
54 | struct rt6_info | ||
55 | { | ||
56 | union { | ||
57 | struct dst_entry dst; | ||
58 | struct rt6_info *next; | ||
59 | } u; | ||
60 | |||
61 | struct inet6_dev *rt6i_idev; | ||
62 | |||
63 | #define rt6i_dev u.dst.dev | ||
64 | #define rt6i_nexthop u.dst.neighbour | ||
65 | #define rt6i_expires u.dst.expires | ||
66 | |||
67 | struct fib6_node *rt6i_node; | ||
68 | |||
69 | struct in6_addr rt6i_gateway; | ||
70 | |||
71 | u32 rt6i_flags; | ||
72 | u32 rt6i_metric; | ||
73 | atomic_t rt6i_ref; | ||
74 | |||
75 | struct rt6key rt6i_dst; | ||
76 | struct rt6key rt6i_src; | ||
77 | |||
78 | u8 rt6i_protocol; | ||
79 | }; | ||
80 | |||
81 | struct fib6_walker_t | ||
82 | { | ||
83 | struct fib6_walker_t *prev, *next; | ||
84 | struct fib6_node *root, *node; | ||
85 | struct rt6_info *leaf; | ||
86 | unsigned char state; | ||
87 | unsigned char prune; | ||
88 | int (*func)(struct fib6_walker_t *); | ||
89 | void *args; | ||
90 | }; | ||
91 | |||
92 | extern struct fib6_walker_t fib6_walker_list; | ||
93 | extern rwlock_t fib6_walker_lock; | ||
94 | |||
95 | static inline void fib6_walker_link(struct fib6_walker_t *w) | ||
96 | { | ||
97 | write_lock_bh(&fib6_walker_lock); | ||
98 | w->next = fib6_walker_list.next; | ||
99 | w->prev = &fib6_walker_list; | ||
100 | w->next->prev = w; | ||
101 | w->prev->next = w; | ||
102 | write_unlock_bh(&fib6_walker_lock); | ||
103 | } | ||
104 | |||
105 | static inline void fib6_walker_unlink(struct fib6_walker_t *w) | ||
106 | { | ||
107 | write_lock_bh(&fib6_walker_lock); | ||
108 | w->next->prev = w->prev; | ||
109 | w->prev->next = w->next; | ||
110 | w->prev = w->next = w; | ||
111 | write_unlock_bh(&fib6_walker_lock); | ||
112 | } | ||
113 | |||
114 | struct rt6_statistics { | ||
115 | __u32 fib_nodes; | ||
116 | __u32 fib_route_nodes; | ||
117 | __u32 fib_rt_alloc; /* permanent routes */ | ||
118 | __u32 fib_rt_entries; /* rt entries in table */ | ||
119 | __u32 fib_rt_cache; /* cache routes */ | ||
120 | __u32 fib_discarded_routes; | ||
121 | }; | ||
122 | |||
123 | #define RTN_TL_ROOT 0x0001 | ||
124 | #define RTN_ROOT 0x0002 /* tree root node */ | ||
125 | #define RTN_RTINFO 0x0004 /* node with valid routing info */ | ||
126 | |||
127 | /* | ||
128 | * priority levels (or metrics) | ||
129 | * | ||
130 | */ | ||
131 | |||
132 | #define RTPRI_FIREWALL 8 /* Firewall control information */ | ||
133 | #define RTPRI_FLOW 16 /* Flow based forwarding rules */ | ||
134 | #define RTPRI_KERN_CTL 32 /* Kernel control routes */ | ||
135 | |||
136 | #define RTPRI_USER_MIN 256 /* Mimimum user priority */ | ||
137 | #define RTPRI_USER_MAX 1024 /* Maximum user priority */ | ||
138 | |||
139 | #define RTPRI_KERN_DFLT 4096 /* Kernel default routes */ | ||
140 | |||
141 | #define MAX_FLOW_BACKTRACE 32 | ||
142 | |||
143 | |||
144 | typedef void (*f_pnode)(struct fib6_node *fn, void *); | ||
145 | |||
146 | extern struct fib6_node ip6_routing_table; | ||
147 | |||
148 | /* | ||
149 | * exported functions | ||
150 | */ | ||
151 | |||
152 | extern struct fib6_node *fib6_lookup(struct fib6_node *root, | ||
153 | struct in6_addr *daddr, | ||
154 | struct in6_addr *saddr); | ||
155 | |||
156 | struct fib6_node *fib6_locate(struct fib6_node *root, | ||
157 | struct in6_addr *daddr, int dst_len, | ||
158 | struct in6_addr *saddr, int src_len); | ||
159 | |||
160 | extern void fib6_clean_tree(struct fib6_node *root, | ||
161 | int (*func)(struct rt6_info *, void *arg), | ||
162 | int prune, void *arg); | ||
163 | |||
164 | extern int fib6_walk(struct fib6_walker_t *w); | ||
165 | extern int fib6_walk_continue(struct fib6_walker_t *w); | ||
166 | |||
167 | extern int fib6_add(struct fib6_node *root, | ||
168 | struct rt6_info *rt, | ||
169 | struct nlmsghdr *nlh, | ||
170 | void *rtattr); | ||
171 | |||
172 | extern int fib6_del(struct rt6_info *rt, | ||
173 | struct nlmsghdr *nlh, | ||
174 | void *rtattr); | ||
175 | |||
176 | extern void inet6_rt_notify(int event, struct rt6_info *rt, | ||
177 | struct nlmsghdr *nlh); | ||
178 | |||
179 | extern void fib6_run_gc(unsigned long dummy); | ||
180 | |||
181 | extern void fib6_gc_cleanup(void); | ||
182 | |||
183 | extern void fib6_init(void); | ||
184 | #endif | ||
185 | #endif | ||
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h new file mode 100644 index 000000000000..d5d1dd10cdb8 --- /dev/null +++ b/include/net/ip6_route.h | |||
@@ -0,0 +1,141 @@ | |||
1 | #ifndef _NET_IP6_ROUTE_H | ||
2 | #define _NET_IP6_ROUTE_H | ||
3 | |||
4 | #define IP6_RT_PRIO_FW 16 | ||
5 | #define IP6_RT_PRIO_USER 1024 | ||
6 | #define IP6_RT_PRIO_ADDRCONF 256 | ||
7 | #define IP6_RT_PRIO_KERN 512 | ||
8 | #define IP6_RT_FLOW_MASK 0x00ff | ||
9 | |||
10 | #ifdef __KERNEL__ | ||
11 | |||
12 | #include <net/flow.h> | ||
13 | #include <net/ip6_fib.h> | ||
14 | #include <net/sock.h> | ||
15 | #include <linux/tcp.h> | ||
16 | #include <linux/ip.h> | ||
17 | #include <linux/ipv6.h> | ||
18 | |||
19 | struct pol_chain { | ||
20 | int type; | ||
21 | int priority; | ||
22 | struct fib6_node *rules; | ||
23 | struct pol_chain *next; | ||
24 | }; | ||
25 | |||
26 | extern struct rt6_info ip6_null_entry; | ||
27 | |||
28 | extern int ip6_rt_gc_interval; | ||
29 | |||
30 | extern void ip6_route_input(struct sk_buff *skb); | ||
31 | |||
32 | extern struct dst_entry * ip6_route_output(struct sock *sk, | ||
33 | struct flowi *fl); | ||
34 | |||
35 | extern int ip6_route_me_harder(struct sk_buff *skb); | ||
36 | |||
37 | extern void ip6_route_init(void); | ||
38 | extern void ip6_route_cleanup(void); | ||
39 | |||
40 | extern int ipv6_route_ioctl(unsigned int cmd, void __user *arg); | ||
41 | |||
42 | extern int ip6_route_add(struct in6_rtmsg *rtmsg, | ||
43 | struct nlmsghdr *, | ||
44 | void *rtattr); | ||
45 | extern int ip6_ins_rt(struct rt6_info *, | ||
46 | struct nlmsghdr *, | ||
47 | void *rtattr); | ||
48 | extern int ip6_del_rt(struct rt6_info *, | ||
49 | struct nlmsghdr *, | ||
50 | void *rtattr); | ||
51 | |||
52 | extern int ip6_rt_addr_add(struct in6_addr *addr, | ||
53 | struct net_device *dev, | ||
54 | int anycast); | ||
55 | |||
56 | extern int ip6_rt_addr_del(struct in6_addr *addr, | ||
57 | struct net_device *dev); | ||
58 | |||
59 | extern void rt6_sndmsg(int type, struct in6_addr *dst, | ||
60 | struct in6_addr *src, | ||
61 | struct in6_addr *gw, | ||
62 | struct net_device *dev, | ||
63 | int dstlen, int srclen, | ||
64 | int metric, __u32 flags); | ||
65 | |||
66 | extern struct rt6_info *rt6_lookup(struct in6_addr *daddr, | ||
67 | struct in6_addr *saddr, | ||
68 | int oif, int flags); | ||
69 | |||
70 | extern struct dst_entry *ndisc_dst_alloc(struct net_device *dev, | ||
71 | struct neighbour *neigh, | ||
72 | struct in6_addr *addr, | ||
73 | int (*output)(struct sk_buff *)); | ||
74 | extern int ndisc_dst_gc(int *more); | ||
75 | extern void fib6_force_start_gc(void); | ||
76 | |||
77 | extern struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | ||
78 | const struct in6_addr *addr, | ||
79 | int anycast); | ||
80 | |||
81 | /* | ||
82 | * support functions for ND | ||
83 | * | ||
84 | */ | ||
85 | extern struct rt6_info * rt6_get_dflt_router(struct in6_addr *addr, | ||
86 | struct net_device *dev); | ||
87 | extern struct rt6_info * rt6_add_dflt_router(struct in6_addr *gwaddr, | ||
88 | struct net_device *dev); | ||
89 | |||
90 | extern void rt6_purge_dflt_routers(void); | ||
91 | |||
92 | extern void rt6_reset_dflt_pointer(struct rt6_info *rt); | ||
93 | |||
94 | extern void rt6_redirect(struct in6_addr *dest, | ||
95 | struct in6_addr *saddr, | ||
96 | struct neighbour *neigh, | ||
97 | u8 *lladdr, | ||
98 | int on_link); | ||
99 | |||
100 | extern void rt6_pmtu_discovery(struct in6_addr *daddr, | ||
101 | struct in6_addr *saddr, | ||
102 | struct net_device *dev, | ||
103 | u32 pmtu); | ||
104 | |||
105 | struct nlmsghdr; | ||
106 | struct netlink_callback; | ||
107 | extern int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb); | ||
108 | extern int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); | ||
109 | extern int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); | ||
110 | extern int inet6_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); | ||
111 | |||
112 | extern void rt6_ifdown(struct net_device *dev); | ||
113 | extern void rt6_mtu_change(struct net_device *dev, unsigned mtu); | ||
114 | |||
115 | extern rwlock_t rt6_lock; | ||
116 | |||
117 | /* | ||
118 | * Store a destination cache entry in a socket | ||
119 | */ | ||
120 | static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst, | ||
121 | struct in6_addr *daddr) | ||
122 | { | ||
123 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
124 | struct rt6_info *rt = (struct rt6_info *) dst; | ||
125 | |||
126 | write_lock(&sk->sk_dst_lock); | ||
127 | __sk_dst_set(sk, dst); | ||
128 | np->daddr_cache = daddr; | ||
129 | np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0; | ||
130 | write_unlock(&sk->sk_dst_lock); | ||
131 | } | ||
132 | |||
133 | static inline int ipv6_unicast_destination(struct sk_buff *skb) | ||
134 | { | ||
135 | struct rt6_info *rt = (struct rt6_info *) skb->dst; | ||
136 | |||
137 | return rt->rt6i_flags & RTF_LOCAL; | ||
138 | } | ||
139 | |||
140 | #endif | ||
141 | #endif | ||
diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h new file mode 100644 index 000000000000..29c9da707c7a --- /dev/null +++ b/include/net/ip6_tunnel.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | * $Id$ | ||
3 | */ | ||
4 | |||
5 | #ifndef _NET_IP6_TUNNEL_H | ||
6 | #define _NET_IP6_TUNNEL_H | ||
7 | |||
8 | #include <linux/ipv6.h> | ||
9 | #include <linux/netdevice.h> | ||
10 | #include <linux/ip6_tunnel.h> | ||
11 | |||
12 | /* capable of sending packets */ | ||
13 | #define IP6_TNL_F_CAP_XMIT 0x10000 | ||
14 | /* capable of receiving packets */ | ||
15 | #define IP6_TNL_F_CAP_RCV 0x20000 | ||
16 | |||
17 | #define IP6_TNL_MAX 128 | ||
18 | |||
19 | /* IPv6 tunnel */ | ||
20 | |||
21 | struct ip6_tnl { | ||
22 | struct ip6_tnl *next; /* next tunnel in list */ | ||
23 | struct net_device *dev; /* virtual device associated with tunnel */ | ||
24 | struct net_device_stats stat; /* statistics for tunnel device */ | ||
25 | int recursion; /* depth of hard_start_xmit recursion */ | ||
26 | struct ip6_tnl_parm parms; /* tunnel configuration paramters */ | ||
27 | struct flowi fl; /* flowi template for xmit */ | ||
28 | struct dst_entry *dst_cache; /* cached dst */ | ||
29 | u32 dst_cookie; | ||
30 | }; | ||
31 | |||
32 | /* Tunnel encapsulation limit destination sub-option */ | ||
33 | |||
34 | struct ipv6_tlv_tnl_enc_lim { | ||
35 | __u8 type; /* type-code for option */ | ||
36 | __u8 length; /* option length */ | ||
37 | __u8 encap_limit; /* tunnel encapsulation limit */ | ||
38 | } __attribute__ ((packed)); | ||
39 | |||
40 | #endif | ||
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h new file mode 100644 index 000000000000..e5a5f6b62f88 --- /dev/null +++ b/include/net/ip_fib.h | |||
@@ -0,0 +1,284 @@ | |||
1 | /* | ||
2 | * INET An implementation of the TCP/IP protocol suite for the LINUX | ||
3 | * operating system. INET is implemented using the BSD Socket | ||
4 | * interface as the means of communication with the user level. | ||
5 | * | ||
6 | * Definitions for the Forwarding Information Base. | ||
7 | * | ||
8 | * Authors: A.N.Kuznetsov, <kuznet@ms2.inr.ac.ru> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * as published by the Free Software Foundation; either version | ||
13 | * 2 of the License, or (at your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #ifndef _NET_IP_FIB_H | ||
17 | #define _NET_IP_FIB_H | ||
18 | |||
19 | #include <linux/config.h> | ||
20 | #include <net/flow.h> | ||
21 | #include <linux/seq_file.h> | ||
22 | |||
23 | /* WARNING: The ordering of these elements must match ordering | ||
24 | * of RTA_* rtnetlink attribute numbers. | ||
25 | */ | ||
26 | struct kern_rta { | ||
27 | void *rta_dst; | ||
28 | void *rta_src; | ||
29 | int *rta_iif; | ||
30 | int *rta_oif; | ||
31 | void *rta_gw; | ||
32 | u32 *rta_priority; | ||
33 | void *rta_prefsrc; | ||
34 | struct rtattr *rta_mx; | ||
35 | struct rtattr *rta_mp; | ||
36 | unsigned char *rta_protoinfo; | ||
37 | u32 *rta_flow; | ||
38 | struct rta_cacheinfo *rta_ci; | ||
39 | struct rta_session *rta_sess; | ||
40 | u32 *rta_mp_alg; | ||
41 | }; | ||
42 | |||
43 | struct fib_info; | ||
44 | |||
45 | struct fib_nh { | ||
46 | struct net_device *nh_dev; | ||
47 | struct hlist_node nh_hash; | ||
48 | struct fib_info *nh_parent; | ||
49 | unsigned nh_flags; | ||
50 | unsigned char nh_scope; | ||
51 | #ifdef CONFIG_IP_ROUTE_MULTIPATH | ||
52 | int nh_weight; | ||
53 | int nh_power; | ||
54 | #endif | ||
55 | #ifdef CONFIG_NET_CLS_ROUTE | ||
56 | __u32 nh_tclassid; | ||
57 | #endif | ||
58 | int nh_oif; | ||
59 | u32 nh_gw; | ||
60 | }; | ||
61 | |||
62 | /* | ||
63 | * This structure contains data shared by many of routes. | ||
64 | */ | ||
65 | |||
66 | struct fib_info { | ||
67 | struct hlist_node fib_hash; | ||
68 | struct hlist_node fib_lhash; | ||
69 | int fib_treeref; | ||
70 | atomic_t fib_clntref; | ||
71 | int fib_dead; | ||
72 | unsigned fib_flags; | ||
73 | int fib_protocol; | ||
74 | u32 fib_prefsrc; | ||
75 | u32 fib_priority; | ||
76 | u32 fib_metrics[RTAX_MAX]; | ||
77 | #define fib_mtu fib_metrics[RTAX_MTU-1] | ||
78 | #define fib_window fib_metrics[RTAX_WINDOW-1] | ||
79 | #define fib_rtt fib_metrics[RTAX_RTT-1] | ||
80 | #define fib_advmss fib_metrics[RTAX_ADVMSS-1] | ||
81 | int fib_nhs; | ||
82 | #ifdef CONFIG_IP_ROUTE_MULTIPATH | ||
83 | int fib_power; | ||
84 | #endif | ||
85 | #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED | ||
86 | u32 fib_mp_alg; | ||
87 | #endif | ||
88 | struct fib_nh fib_nh[0]; | ||
89 | #define fib_dev fib_nh[0].nh_dev | ||
90 | }; | ||
91 | |||
92 | |||
93 | #ifdef CONFIG_IP_MULTIPLE_TABLES | ||
94 | struct fib_rule; | ||
95 | #endif | ||
96 | |||
97 | struct fib_result { | ||
98 | unsigned char prefixlen; | ||
99 | unsigned char nh_sel; | ||
100 | unsigned char type; | ||
101 | unsigned char scope; | ||
102 | #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED | ||
103 | __u32 network; | ||
104 | __u32 netmask; | ||
105 | #endif | ||
106 | struct fib_info *fi; | ||
107 | #ifdef CONFIG_IP_MULTIPLE_TABLES | ||
108 | struct fib_rule *r; | ||
109 | #endif | ||
110 | }; | ||
111 | |||
112 | |||
113 | #ifdef CONFIG_IP_ROUTE_MULTIPATH | ||
114 | |||
115 | #define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel]) | ||
116 | #define FIB_RES_RESET(res) ((res).nh_sel = 0) | ||
117 | |||
118 | #else /* CONFIG_IP_ROUTE_MULTIPATH */ | ||
119 | |||
120 | #define FIB_RES_NH(res) ((res).fi->fib_nh[0]) | ||
121 | #define FIB_RES_RESET(res) | ||
122 | |||
123 | #endif /* CONFIG_IP_ROUTE_MULTIPATH */ | ||
124 | |||
125 | #define FIB_RES_PREFSRC(res) ((res).fi->fib_prefsrc ? : __fib_res_prefsrc(&res)) | ||
126 | #define FIB_RES_GW(res) (FIB_RES_NH(res).nh_gw) | ||
127 | #define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev) | ||
128 | #define FIB_RES_OIF(res) (FIB_RES_NH(res).nh_oif) | ||
129 | |||
130 | #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED | ||
131 | #define FIB_RES_NETWORK(res) ((res).network) | ||
132 | #define FIB_RES_NETMASK(res) ((res).netmask) | ||
133 | #else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ | ||
134 | #define FIB_RES_NETWORK(res) (0) | ||
135 | #define FIB_RES_NETMASK(res) (0) | ||
136 | #endif /* CONFIG_IP_ROUTE_MULTIPATH_WRANDOM */ | ||
137 | |||
138 | struct fib_table { | ||
139 | unsigned char tb_id; | ||
140 | unsigned tb_stamp; | ||
141 | int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res); | ||
142 | int (*tb_insert)(struct fib_table *table, struct rtmsg *r, | ||
143 | struct kern_rta *rta, struct nlmsghdr *n, | ||
144 | struct netlink_skb_parms *req); | ||
145 | int (*tb_delete)(struct fib_table *table, struct rtmsg *r, | ||
146 | struct kern_rta *rta, struct nlmsghdr *n, | ||
147 | struct netlink_skb_parms *req); | ||
148 | int (*tb_dump)(struct fib_table *table, struct sk_buff *skb, | ||
149 | struct netlink_callback *cb); | ||
150 | int (*tb_flush)(struct fib_table *table); | ||
151 | void (*tb_select_default)(struct fib_table *table, | ||
152 | const struct flowi *flp, struct fib_result *res); | ||
153 | |||
154 | unsigned char tb_data[0]; | ||
155 | }; | ||
156 | |||
157 | #ifndef CONFIG_IP_MULTIPLE_TABLES | ||
158 | |||
159 | extern struct fib_table *ip_fib_local_table; | ||
160 | extern struct fib_table *ip_fib_main_table; | ||
161 | |||
162 | static inline struct fib_table *fib_get_table(int id) | ||
163 | { | ||
164 | if (id != RT_TABLE_LOCAL) | ||
165 | return ip_fib_main_table; | ||
166 | return ip_fib_local_table; | ||
167 | } | ||
168 | |||
169 | static inline struct fib_table *fib_new_table(int id) | ||
170 | { | ||
171 | return fib_get_table(id); | ||
172 | } | ||
173 | |||
174 | static inline int fib_lookup(const struct flowi *flp, struct fib_result *res) | ||
175 | { | ||
176 | if (ip_fib_local_table->tb_lookup(ip_fib_local_table, flp, res) && | ||
177 | ip_fib_main_table->tb_lookup(ip_fib_main_table, flp, res)) | ||
178 | return -ENETUNREACH; | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static inline void fib_select_default(const struct flowi *flp, struct fib_result *res) | ||
183 | { | ||
184 | if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) | ||
185 | ip_fib_main_table->tb_select_default(ip_fib_main_table, flp, res); | ||
186 | } | ||
187 | |||
188 | #else /* CONFIG_IP_MULTIPLE_TABLES */ | ||
189 | #define ip_fib_local_table (fib_tables[RT_TABLE_LOCAL]) | ||
190 | #define ip_fib_main_table (fib_tables[RT_TABLE_MAIN]) | ||
191 | |||
192 | extern struct fib_table * fib_tables[RT_TABLE_MAX+1]; | ||
193 | extern int fib_lookup(const struct flowi *flp, struct fib_result *res); | ||
194 | extern struct fib_table *__fib_new_table(int id); | ||
195 | extern void fib_rule_put(struct fib_rule *r); | ||
196 | |||
197 | static inline struct fib_table *fib_get_table(int id) | ||
198 | { | ||
199 | if (id == 0) | ||
200 | id = RT_TABLE_MAIN; | ||
201 | |||
202 | return fib_tables[id]; | ||
203 | } | ||
204 | |||
205 | static inline struct fib_table *fib_new_table(int id) | ||
206 | { | ||
207 | if (id == 0) | ||
208 | id = RT_TABLE_MAIN; | ||
209 | |||
210 | return fib_tables[id] ? : __fib_new_table(id); | ||
211 | } | ||
212 | |||
213 | extern void fib_select_default(const struct flowi *flp, struct fib_result *res); | ||
214 | |||
215 | #endif /* CONFIG_IP_MULTIPLE_TABLES */ | ||
216 | |||
217 | /* Exported by fib_frontend.c */ | ||
218 | extern void ip_fib_init(void); | ||
219 | extern int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); | ||
220 | extern int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); | ||
221 | extern int inet_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); | ||
222 | extern int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb); | ||
223 | extern int fib_validate_source(u32 src, u32 dst, u8 tos, int oif, | ||
224 | struct net_device *dev, u32 *spec_dst, u32 *itag); | ||
225 | extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res); | ||
226 | |||
227 | /* Exported by fib_semantics.c */ | ||
228 | extern int ip_fib_check_default(u32 gw, struct net_device *dev); | ||
229 | extern int fib_sync_down(u32 local, struct net_device *dev, int force); | ||
230 | extern int fib_sync_up(struct net_device *dev); | ||
231 | extern int fib_convert_rtentry(int cmd, struct nlmsghdr *nl, struct rtmsg *rtm, | ||
232 | struct kern_rta *rta, struct rtentry *r); | ||
233 | extern u32 __fib_res_prefsrc(struct fib_result *res); | ||
234 | |||
235 | /* Exported by fib_hash.c */ | ||
236 | extern struct fib_table *fib_hash_init(int id); | ||
237 | |||
238 | #ifdef CONFIG_IP_MULTIPLE_TABLES | ||
239 | /* Exported by fib_rules.c */ | ||
240 | |||
241 | extern int inet_rtm_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); | ||
242 | extern int inet_rtm_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg); | ||
243 | extern int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb); | ||
244 | #ifdef CONFIG_NET_CLS_ROUTE | ||
245 | extern u32 fib_rules_tclass(struct fib_result *res); | ||
246 | #endif | ||
247 | extern void fib_rules_init(void); | ||
248 | #endif | ||
249 | |||
250 | static inline void fib_combine_itag(u32 *itag, struct fib_result *res) | ||
251 | { | ||
252 | #ifdef CONFIG_NET_CLS_ROUTE | ||
253 | #ifdef CONFIG_IP_MULTIPLE_TABLES | ||
254 | u32 rtag; | ||
255 | #endif | ||
256 | *itag = FIB_RES_NH(*res).nh_tclassid<<16; | ||
257 | #ifdef CONFIG_IP_MULTIPLE_TABLES | ||
258 | rtag = fib_rules_tclass(res); | ||
259 | if (*itag == 0) | ||
260 | *itag = (rtag<<16); | ||
261 | *itag |= (rtag>>16); | ||
262 | #endif | ||
263 | #endif | ||
264 | } | ||
265 | |||
266 | extern void free_fib_info(struct fib_info *fi); | ||
267 | |||
268 | static inline void fib_info_put(struct fib_info *fi) | ||
269 | { | ||
270 | if (atomic_dec_and_test(&fi->fib_clntref)) | ||
271 | free_fib_info(fi); | ||
272 | } | ||
273 | |||
274 | static inline void fib_res_put(struct fib_result *res) | ||
275 | { | ||
276 | if (res->fi) | ||
277 | fib_info_put(res->fi); | ||
278 | #ifdef CONFIG_IP_MULTIPLE_TABLES | ||
279 | if (res->r) | ||
280 | fib_rule_put(res->r); | ||
281 | #endif | ||
282 | } | ||
283 | |||
284 | #endif /* _NET_FIB_H */ | ||
diff --git a/include/net/ip_mp_alg.h b/include/net/ip_mp_alg.h new file mode 100644 index 000000000000..77225735cbd4 --- /dev/null +++ b/include/net/ip_mp_alg.h | |||
@@ -0,0 +1,99 @@ | |||
1 | /* ip_mp_alg.h: IPV4 multipath algorithm support. | ||
2 | * | ||
3 | * Copyright (C) 2004, 2005 Einar Lueck <elueck@de.ibm.com> | ||
4 | * Copyright (C) 2005 David S. Miller <davem@davemloft.net> | ||
5 | */ | ||
6 | |||
7 | #ifndef _NET_IP_MP_ALG_H | ||
8 | #define _NET_IP_MP_ALG_H | ||
9 | |||
10 | #include <linux/config.h> | ||
11 | #include <linux/ip_mp_alg.h> | ||
12 | #include <net/flow.h> | ||
13 | #include <net/route.h> | ||
14 | |||
15 | struct fib_nh; | ||
16 | |||
17 | struct ip_mp_alg_ops { | ||
18 | void (*mp_alg_select_route)(const struct flowi *flp, | ||
19 | struct rtable *rth, struct rtable **rp); | ||
20 | void (*mp_alg_flush)(void); | ||
21 | void (*mp_alg_set_nhinfo)(__u32 network, __u32 netmask, | ||
22 | unsigned char prefixlen, | ||
23 | const struct fib_nh *nh); | ||
24 | void (*mp_alg_remove)(struct rtable *rth); | ||
25 | }; | ||
26 | |||
27 | extern int multipath_alg_register(struct ip_mp_alg_ops *, enum ip_mp_alg); | ||
28 | extern void multipath_alg_unregister(struct ip_mp_alg_ops *, enum ip_mp_alg); | ||
29 | |||
30 | extern struct ip_mp_alg_ops *ip_mp_alg_table[]; | ||
31 | |||
32 | static inline int multipath_select_route(const struct flowi *flp, | ||
33 | struct rtable *rth, | ||
34 | struct rtable **rp) | ||
35 | { | ||
36 | #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED | ||
37 | struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg]; | ||
38 | |||
39 | /* mp_alg_select_route _MUST_ be implemented */ | ||
40 | if (ops && (rth->u.dst.flags & DST_BALANCED)) { | ||
41 | ops->mp_alg_select_route(flp, rth, rp); | ||
42 | return 1; | ||
43 | } | ||
44 | #endif | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | static inline void multipath_flush(void) | ||
49 | { | ||
50 | #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED | ||
51 | int i; | ||
52 | |||
53 | for (i = IP_MP_ALG_NONE; i <= IP_MP_ALG_MAX; i++) { | ||
54 | struct ip_mp_alg_ops *ops = ip_mp_alg_table[i]; | ||
55 | |||
56 | if (ops && ops->mp_alg_flush) | ||
57 | ops->mp_alg_flush(); | ||
58 | } | ||
59 | #endif | ||
60 | } | ||
61 | |||
62 | static inline void multipath_set_nhinfo(struct rtable *rth, | ||
63 | __u32 network, __u32 netmask, | ||
64 | unsigned char prefixlen, | ||
65 | const struct fib_nh *nh) | ||
66 | { | ||
67 | #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED | ||
68 | struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg]; | ||
69 | |||
70 | if (ops && ops->mp_alg_set_nhinfo) | ||
71 | ops->mp_alg_set_nhinfo(network, netmask, prefixlen, nh); | ||
72 | #endif | ||
73 | } | ||
74 | |||
75 | static inline void multipath_remove(struct rtable *rth) | ||
76 | { | ||
77 | #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED | ||
78 | struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg]; | ||
79 | |||
80 | if (ops && ops->mp_alg_remove && | ||
81 | (rth->u.dst.flags & DST_BALANCED)) | ||
82 | ops->mp_alg_remove(rth); | ||
83 | #endif | ||
84 | } | ||
85 | |||
86 | static inline int multipath_comparekeys(const struct flowi *flp1, | ||
87 | const struct flowi *flp2) | ||
88 | { | ||
89 | return flp1->fl4_dst == flp2->fl4_dst && | ||
90 | flp1->fl4_src == flp2->fl4_src && | ||
91 | flp1->oif == flp2->oif && | ||
92 | #ifdef CONFIG_IP_ROUTE_FWMARK | ||
93 | flp1->fl4_fwmark == flp2->fl4_fwmark && | ||
94 | #endif | ||
95 | !((flp1->fl4_tos ^ flp2->fl4_tos) & | ||
96 | (IPTOS_RT_MASK | RTO_ONLINK)); | ||
97 | } | ||
98 | |||
99 | #endif /* _NET_IP_MP_ALG_H */ | ||
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h new file mode 100644 index 000000000000..52da5d26617a --- /dev/null +++ b/include/net/ip_vs.h | |||
@@ -0,0 +1,999 @@ | |||
1 | /* | ||
2 | * IP Virtual Server | ||
3 | * data structure and functionality definitions | ||
4 | */ | ||
5 | |||
6 | #ifndef _IP_VS_H | ||
7 | #define _IP_VS_H | ||
8 | |||
9 | #include <asm/types.h> /* For __uXX types */ | ||
10 | |||
11 | #define IP_VS_VERSION_CODE 0x010201 | ||
12 | #define NVERSION(version) \ | ||
13 | (version >> 16) & 0xFF, \ | ||
14 | (version >> 8) & 0xFF, \ | ||
15 | version & 0xFF | ||
16 | |||
17 | /* | ||
18 | * Virtual Service Flags | ||
19 | */ | ||
20 | #define IP_VS_SVC_F_PERSISTENT 0x0001 /* persistent port */ | ||
21 | #define IP_VS_SVC_F_HASHED 0x0002 /* hashed entry */ | ||
22 | |||
23 | /* | ||
24 | * Destination Server Flags | ||
25 | */ | ||
26 | #define IP_VS_DEST_F_AVAILABLE 0x0001 /* server is available */ | ||
27 | #define IP_VS_DEST_F_OVERLOAD 0x0002 /* server is overloaded */ | ||
28 | |||
29 | /* | ||
30 | * IPVS sync daemon states | ||
31 | */ | ||
32 | #define IP_VS_STATE_NONE 0x0000 /* daemon is stopped */ | ||
33 | #define IP_VS_STATE_MASTER 0x0001 /* started as master */ | ||
34 | #define IP_VS_STATE_BACKUP 0x0002 /* started as backup */ | ||
35 | |||
36 | /* | ||
37 | * IPVS socket options | ||
38 | */ | ||
39 | #define IP_VS_BASE_CTL (64+1024+64) /* base */ | ||
40 | |||
41 | #define IP_VS_SO_SET_NONE IP_VS_BASE_CTL /* just peek */ | ||
42 | #define IP_VS_SO_SET_INSERT (IP_VS_BASE_CTL+1) | ||
43 | #define IP_VS_SO_SET_ADD (IP_VS_BASE_CTL+2) | ||
44 | #define IP_VS_SO_SET_EDIT (IP_VS_BASE_CTL+3) | ||
45 | #define IP_VS_SO_SET_DEL (IP_VS_BASE_CTL+4) | ||
46 | #define IP_VS_SO_SET_FLUSH (IP_VS_BASE_CTL+5) | ||
47 | #define IP_VS_SO_SET_LIST (IP_VS_BASE_CTL+6) | ||
48 | #define IP_VS_SO_SET_ADDDEST (IP_VS_BASE_CTL+7) | ||
49 | #define IP_VS_SO_SET_DELDEST (IP_VS_BASE_CTL+8) | ||
50 | #define IP_VS_SO_SET_EDITDEST (IP_VS_BASE_CTL+9) | ||
51 | #define IP_VS_SO_SET_TIMEOUT (IP_VS_BASE_CTL+10) | ||
52 | #define IP_VS_SO_SET_STARTDAEMON (IP_VS_BASE_CTL+11) | ||
53 | #define IP_VS_SO_SET_STOPDAEMON (IP_VS_BASE_CTL+12) | ||
54 | #define IP_VS_SO_SET_RESTORE (IP_VS_BASE_CTL+13) | ||
55 | #define IP_VS_SO_SET_SAVE (IP_VS_BASE_CTL+14) | ||
56 | #define IP_VS_SO_SET_ZERO (IP_VS_BASE_CTL+15) | ||
57 | #define IP_VS_SO_SET_MAX IP_VS_SO_SET_ZERO | ||
58 | |||
59 | #define IP_VS_SO_GET_VERSION IP_VS_BASE_CTL | ||
60 | #define IP_VS_SO_GET_INFO (IP_VS_BASE_CTL+1) | ||
61 | #define IP_VS_SO_GET_SERVICES (IP_VS_BASE_CTL+2) | ||
62 | #define IP_VS_SO_GET_SERVICE (IP_VS_BASE_CTL+3) | ||
63 | #define IP_VS_SO_GET_DESTS (IP_VS_BASE_CTL+4) | ||
64 | #define IP_VS_SO_GET_DEST (IP_VS_BASE_CTL+5) /* not used now */ | ||
65 | #define IP_VS_SO_GET_TIMEOUT (IP_VS_BASE_CTL+6) | ||
66 | #define IP_VS_SO_GET_DAEMON (IP_VS_BASE_CTL+7) | ||
67 | #define IP_VS_SO_GET_MAX IP_VS_SO_GET_DAEMON | ||
68 | |||
69 | |||
70 | /* | ||
71 | * IPVS Connection Flags | ||
72 | */ | ||
73 | #define IP_VS_CONN_F_FWD_MASK 0x0007 /* mask for the fwd methods */ | ||
74 | #define IP_VS_CONN_F_MASQ 0x0000 /* masquerading/NAT */ | ||
75 | #define IP_VS_CONN_F_LOCALNODE 0x0001 /* local node */ | ||
76 | #define IP_VS_CONN_F_TUNNEL 0x0002 /* tunneling */ | ||
77 | #define IP_VS_CONN_F_DROUTE 0x0003 /* direct routing */ | ||
78 | #define IP_VS_CONN_F_BYPASS 0x0004 /* cache bypass */ | ||
79 | #define IP_VS_CONN_F_SYNC 0x0020 /* entry created by sync */ | ||
80 | #define IP_VS_CONN_F_HASHED 0x0040 /* hashed entry */ | ||
81 | #define IP_VS_CONN_F_NOOUTPUT 0x0080 /* no output packets */ | ||
82 | #define IP_VS_CONN_F_INACTIVE 0x0100 /* not established */ | ||
83 | #define IP_VS_CONN_F_OUT_SEQ 0x0200 /* must do output seq adjust */ | ||
84 | #define IP_VS_CONN_F_IN_SEQ 0x0400 /* must do input seq adjust */ | ||
85 | #define IP_VS_CONN_F_SEQ_MASK 0x0600 /* in/out sequence mask */ | ||
86 | #define IP_VS_CONN_F_NO_CPORT 0x0800 /* no client port set yet */ | ||
87 | |||
88 | /* Move it to better place one day, for now keep it unique */ | ||
89 | #define NFC_IPVS_PROPERTY 0x10000 | ||
90 | |||
91 | #define IP_VS_SCHEDNAME_MAXLEN 16 | ||
92 | #define IP_VS_IFNAME_MAXLEN 16 | ||
93 | |||
94 | |||
95 | /* | ||
96 | * The struct ip_vs_service_user and struct ip_vs_dest_user are | ||
97 | * used to set IPVS rules through setsockopt. | ||
98 | */ | ||
99 | struct ip_vs_service_user { | ||
100 | /* virtual service addresses */ | ||
101 | u_int16_t protocol; | ||
102 | u_int32_t addr; /* virtual ip address */ | ||
103 | u_int16_t port; | ||
104 | u_int32_t fwmark; /* firwall mark of service */ | ||
105 | |||
106 | /* virtual service options */ | ||
107 | char sched_name[IP_VS_SCHEDNAME_MAXLEN]; | ||
108 | unsigned flags; /* virtual service flags */ | ||
109 | unsigned timeout; /* persistent timeout in sec */ | ||
110 | u_int32_t netmask; /* persistent netmask */ | ||
111 | }; | ||
112 | |||
113 | |||
114 | struct ip_vs_dest_user { | ||
115 | /* destination server address */ | ||
116 | u_int32_t addr; | ||
117 | u_int16_t port; | ||
118 | |||
119 | /* real server options */ | ||
120 | unsigned conn_flags; /* connection flags */ | ||
121 | int weight; /* destination weight */ | ||
122 | |||
123 | /* thresholds for active connections */ | ||
124 | u_int32_t u_threshold; /* upper threshold */ | ||
125 | u_int32_t l_threshold; /* lower threshold */ | ||
126 | }; | ||
127 | |||
128 | |||
129 | /* | ||
130 | * IPVS statistics object (for user space) | ||
131 | */ | ||
132 | struct ip_vs_stats_user | ||
133 | { | ||
134 | __u32 conns; /* connections scheduled */ | ||
135 | __u32 inpkts; /* incoming packets */ | ||
136 | __u32 outpkts; /* outgoing packets */ | ||
137 | __u64 inbytes; /* incoming bytes */ | ||
138 | __u64 outbytes; /* outgoing bytes */ | ||
139 | |||
140 | __u32 cps; /* current connection rate */ | ||
141 | __u32 inpps; /* current in packet rate */ | ||
142 | __u32 outpps; /* current out packet rate */ | ||
143 | __u32 inbps; /* current in byte rate */ | ||
144 | __u32 outbps; /* current out byte rate */ | ||
145 | }; | ||
146 | |||
147 | |||
148 | /* The argument to IP_VS_SO_GET_INFO */ | ||
149 | struct ip_vs_getinfo { | ||
150 | /* version number */ | ||
151 | unsigned int version; | ||
152 | |||
153 | /* size of connection hash table */ | ||
154 | unsigned int size; | ||
155 | |||
156 | /* number of virtual services */ | ||
157 | unsigned int num_services; | ||
158 | }; | ||
159 | |||
160 | |||
161 | /* The argument to IP_VS_SO_GET_SERVICE */ | ||
162 | struct ip_vs_service_entry { | ||
163 | /* which service: user fills in these */ | ||
164 | u_int16_t protocol; | ||
165 | u_int32_t addr; /* virtual address */ | ||
166 | u_int16_t port; | ||
167 | u_int32_t fwmark; /* firwall mark of service */ | ||
168 | |||
169 | /* service options */ | ||
170 | char sched_name[IP_VS_SCHEDNAME_MAXLEN]; | ||
171 | unsigned flags; /* virtual service flags */ | ||
172 | unsigned timeout; /* persistent timeout */ | ||
173 | u_int32_t netmask; /* persistent netmask */ | ||
174 | |||
175 | /* number of real servers */ | ||
176 | unsigned int num_dests; | ||
177 | |||
178 | /* statistics */ | ||
179 | struct ip_vs_stats_user stats; | ||
180 | }; | ||
181 | |||
182 | |||
183 | struct ip_vs_dest_entry { | ||
184 | u_int32_t addr; /* destination address */ | ||
185 | u_int16_t port; | ||
186 | unsigned conn_flags; /* connection flags */ | ||
187 | int weight; /* destination weight */ | ||
188 | |||
189 | u_int32_t u_threshold; /* upper threshold */ | ||
190 | u_int32_t l_threshold; /* lower threshold */ | ||
191 | |||
192 | u_int32_t activeconns; /* active connections */ | ||
193 | u_int32_t inactconns; /* inactive connections */ | ||
194 | u_int32_t persistconns; /* persistent connections */ | ||
195 | |||
196 | /* statistics */ | ||
197 | struct ip_vs_stats_user stats; | ||
198 | }; | ||
199 | |||
200 | |||
201 | /* The argument to IP_VS_SO_GET_DESTS */ | ||
202 | struct ip_vs_get_dests { | ||
203 | /* which service: user fills in these */ | ||
204 | u_int16_t protocol; | ||
205 | u_int32_t addr; /* virtual address */ | ||
206 | u_int16_t port; | ||
207 | u_int32_t fwmark; /* firwall mark of service */ | ||
208 | |||
209 | /* number of real servers */ | ||
210 | unsigned int num_dests; | ||
211 | |||
212 | /* the real servers */ | ||
213 | struct ip_vs_dest_entry entrytable[0]; | ||
214 | }; | ||
215 | |||
216 | |||
217 | /* The argument to IP_VS_SO_GET_SERVICES */ | ||
218 | struct ip_vs_get_services { | ||
219 | /* number of virtual services */ | ||
220 | unsigned int num_services; | ||
221 | |||
222 | /* service table */ | ||
223 | struct ip_vs_service_entry entrytable[0]; | ||
224 | }; | ||
225 | |||
226 | |||
227 | /* The argument to IP_VS_SO_GET_TIMEOUT */ | ||
228 | struct ip_vs_timeout_user { | ||
229 | int tcp_timeout; | ||
230 | int tcp_fin_timeout; | ||
231 | int udp_timeout; | ||
232 | }; | ||
233 | |||
234 | |||
235 | /* The argument to IP_VS_SO_GET_DAEMON */ | ||
236 | struct ip_vs_daemon_user { | ||
237 | /* sync daemon state (master/backup) */ | ||
238 | int state; | ||
239 | |||
240 | /* multicast interface name */ | ||
241 | char mcast_ifn[IP_VS_IFNAME_MAXLEN]; | ||
242 | |||
243 | /* SyncID we belong to */ | ||
244 | int syncid; | ||
245 | }; | ||
246 | |||
247 | |||
248 | #ifdef __KERNEL__ | ||
249 | |||
250 | #include <linux/config.h> | ||
251 | #include <linux/list.h> /* for struct list_head */ | ||
252 | #include <linux/spinlock.h> /* for struct rwlock_t */ | ||
253 | #include <linux/skbuff.h> /* for struct sk_buff */ | ||
254 | #include <linux/ip.h> /* for struct iphdr */ | ||
255 | #include <asm/atomic.h> /* for struct atomic_t */ | ||
256 | #include <linux/netdevice.h> /* for struct neighbour */ | ||
257 | #include <net/dst.h> /* for struct dst_entry */ | ||
258 | #include <net/tcp.h> | ||
259 | #include <net/udp.h> | ||
260 | #include <linux/compiler.h> | ||
261 | |||
262 | |||
263 | #ifdef CONFIG_IP_VS_DEBUG | ||
264 | extern int ip_vs_get_debug_level(void); | ||
265 | #define IP_VS_DBG(level, msg...) \ | ||
266 | do { \ | ||
267 | if (level <= ip_vs_get_debug_level()) \ | ||
268 | printk(KERN_DEBUG "IPVS: " msg); \ | ||
269 | } while (0) | ||
270 | #define IP_VS_DBG_RL(msg...) \ | ||
271 | do { \ | ||
272 | if (net_ratelimit()) \ | ||
273 | printk(KERN_DEBUG "IPVS: " msg); \ | ||
274 | } while (0) | ||
275 | #define IP_VS_DBG_PKT(level, pp, skb, ofs, msg) \ | ||
276 | do { \ | ||
277 | if (level <= ip_vs_get_debug_level()) \ | ||
278 | pp->debug_packet(pp, skb, ofs, msg); \ | ||
279 | } while (0) | ||
280 | #define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg) \ | ||
281 | do { \ | ||
282 | if (level <= ip_vs_get_debug_level() && \ | ||
283 | net_ratelimit()) \ | ||
284 | pp->debug_packet(pp, skb, ofs, msg); \ | ||
285 | } while (0) | ||
286 | #else /* NO DEBUGGING at ALL */ | ||
287 | #define IP_VS_DBG(level, msg...) do {} while (0) | ||
288 | #define IP_VS_DBG_RL(msg...) do {} while (0) | ||
289 | #define IP_VS_DBG_PKT(level, pp, skb, ofs, msg) do {} while (0) | ||
290 | #define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg) do {} while (0) | ||
291 | #endif | ||
292 | |||
293 | #define IP_VS_BUG() BUG() | ||
294 | #define IP_VS_ERR(msg...) printk(KERN_ERR "IPVS: " msg) | ||
295 | #define IP_VS_INFO(msg...) printk(KERN_INFO "IPVS: " msg) | ||
296 | #define IP_VS_WARNING(msg...) \ | ||
297 | printk(KERN_WARNING "IPVS: " msg) | ||
298 | #define IP_VS_ERR_RL(msg...) \ | ||
299 | do { \ | ||
300 | if (net_ratelimit()) \ | ||
301 | printk(KERN_ERR "IPVS: " msg); \ | ||
302 | } while (0) | ||
303 | |||
304 | #ifdef CONFIG_IP_VS_DEBUG | ||
305 | #define EnterFunction(level) \ | ||
306 | do { \ | ||
307 | if (level <= ip_vs_get_debug_level()) \ | ||
308 | printk(KERN_DEBUG "Enter: %s, %s line %i\n", \ | ||
309 | __FUNCTION__, __FILE__, __LINE__); \ | ||
310 | } while (0) | ||
311 | #define LeaveFunction(level) \ | ||
312 | do { \ | ||
313 | if (level <= ip_vs_get_debug_level()) \ | ||
314 | printk(KERN_DEBUG "Leave: %s, %s line %i\n", \ | ||
315 | __FUNCTION__, __FILE__, __LINE__); \ | ||
316 | } while (0) | ||
317 | #else | ||
318 | #define EnterFunction(level) do {} while (0) | ||
319 | #define LeaveFunction(level) do {} while (0) | ||
320 | #endif | ||
321 | |||
322 | #define IP_VS_WAIT_WHILE(expr) while (expr) { cpu_relax(); } | ||
323 | |||
324 | |||
325 | /* | ||
326 | * The port number of FTP service (in network order). | ||
327 | */ | ||
328 | #define FTPPORT __constant_htons(21) | ||
329 | #define FTPDATA __constant_htons(20) | ||
330 | |||
331 | /* | ||
332 | * IPVS sysctl variables under the /proc/sys/net/ipv4/vs/ | ||
333 | */ | ||
334 | #define NET_IPV4_VS 21 | ||
335 | |||
336 | enum { | ||
337 | NET_IPV4_VS_DEBUG_LEVEL=1, | ||
338 | NET_IPV4_VS_AMEMTHRESH=2, | ||
339 | NET_IPV4_VS_AMDROPRATE=3, | ||
340 | NET_IPV4_VS_DROP_ENTRY=4, | ||
341 | NET_IPV4_VS_DROP_PACKET=5, | ||
342 | NET_IPV4_VS_SECURE_TCP=6, | ||
343 | NET_IPV4_VS_TO_ES=7, | ||
344 | NET_IPV4_VS_TO_SS=8, | ||
345 | NET_IPV4_VS_TO_SR=9, | ||
346 | NET_IPV4_VS_TO_FW=10, | ||
347 | NET_IPV4_VS_TO_TW=11, | ||
348 | NET_IPV4_VS_TO_CL=12, | ||
349 | NET_IPV4_VS_TO_CW=13, | ||
350 | NET_IPV4_VS_TO_LA=14, | ||
351 | NET_IPV4_VS_TO_LI=15, | ||
352 | NET_IPV4_VS_TO_SA=16, | ||
353 | NET_IPV4_VS_TO_UDP=17, | ||
354 | NET_IPV4_VS_TO_ICMP=18, | ||
355 | NET_IPV4_VS_LBLC_EXPIRE=19, | ||
356 | NET_IPV4_VS_LBLCR_EXPIRE=20, | ||
357 | NET_IPV4_VS_CACHE_BYPASS=22, | ||
358 | NET_IPV4_VS_EXPIRE_NODEST_CONN=23, | ||
359 | NET_IPV4_VS_SYNC_THRESHOLD=24, | ||
360 | NET_IPV4_VS_NAT_ICMP_SEND=25, | ||
361 | NET_IPV4_VS_EXPIRE_QUIESCENT_TEMPLATE=26, | ||
362 | NET_IPV4_VS_LAST | ||
363 | }; | ||
364 | |||
365 | /* | ||
366 | * TCP State Values | ||
367 | */ | ||
368 | enum { | ||
369 | IP_VS_TCP_S_NONE = 0, | ||
370 | IP_VS_TCP_S_ESTABLISHED, | ||
371 | IP_VS_TCP_S_SYN_SENT, | ||
372 | IP_VS_TCP_S_SYN_RECV, | ||
373 | IP_VS_TCP_S_FIN_WAIT, | ||
374 | IP_VS_TCP_S_TIME_WAIT, | ||
375 | IP_VS_TCP_S_CLOSE, | ||
376 | IP_VS_TCP_S_CLOSE_WAIT, | ||
377 | IP_VS_TCP_S_LAST_ACK, | ||
378 | IP_VS_TCP_S_LISTEN, | ||
379 | IP_VS_TCP_S_SYNACK, | ||
380 | IP_VS_TCP_S_LAST | ||
381 | }; | ||
382 | |||
383 | /* | ||
384 | * UDP State Values | ||
385 | */ | ||
386 | enum { | ||
387 | IP_VS_UDP_S_NORMAL, | ||
388 | IP_VS_UDP_S_LAST, | ||
389 | }; | ||
390 | |||
391 | /* | ||
392 | * ICMP State Values | ||
393 | */ | ||
394 | enum { | ||
395 | IP_VS_ICMP_S_NORMAL, | ||
396 | IP_VS_ICMP_S_LAST, | ||
397 | }; | ||
398 | |||
399 | /* | ||
400 | * Delta sequence info structure | ||
401 | * Each ip_vs_conn has 2 (output AND input seq. changes). | ||
402 | * Only used in the VS/NAT. | ||
403 | */ | ||
404 | struct ip_vs_seq { | ||
405 | __u32 init_seq; /* Add delta from this seq */ | ||
406 | __u32 delta; /* Delta in sequence numbers */ | ||
407 | __u32 previous_delta; /* Delta in sequence numbers | ||
408 | before last resized pkt */ | ||
409 | }; | ||
410 | |||
411 | |||
412 | /* | ||
413 | * IPVS statistics object | ||
414 | */ | ||
415 | struct ip_vs_stats | ||
416 | { | ||
417 | __u32 conns; /* connections scheduled */ | ||
418 | __u32 inpkts; /* incoming packets */ | ||
419 | __u32 outpkts; /* outgoing packets */ | ||
420 | __u64 inbytes; /* incoming bytes */ | ||
421 | __u64 outbytes; /* outgoing bytes */ | ||
422 | |||
423 | __u32 cps; /* current connection rate */ | ||
424 | __u32 inpps; /* current in packet rate */ | ||
425 | __u32 outpps; /* current out packet rate */ | ||
426 | __u32 inbps; /* current in byte rate */ | ||
427 | __u32 outbps; /* current out byte rate */ | ||
428 | |||
429 | spinlock_t lock; /* spin lock */ | ||
430 | }; | ||
431 | |||
432 | struct ip_vs_conn; | ||
433 | struct ip_vs_app; | ||
434 | |||
435 | struct ip_vs_protocol { | ||
436 | struct ip_vs_protocol *next; | ||
437 | char *name; | ||
438 | __u16 protocol; | ||
439 | int dont_defrag; | ||
440 | atomic_t appcnt; /* counter of proto app incs */ | ||
441 | int *timeout_table; /* protocol timeout table */ | ||
442 | |||
443 | void (*init)(struct ip_vs_protocol *pp); | ||
444 | |||
445 | void (*exit)(struct ip_vs_protocol *pp); | ||
446 | |||
447 | int (*conn_schedule)(struct sk_buff *skb, | ||
448 | struct ip_vs_protocol *pp, | ||
449 | int *verdict, struct ip_vs_conn **cpp); | ||
450 | |||
451 | struct ip_vs_conn * | ||
452 | (*conn_in_get)(const struct sk_buff *skb, | ||
453 | struct ip_vs_protocol *pp, | ||
454 | const struct iphdr *iph, | ||
455 | unsigned int proto_off, | ||
456 | int inverse); | ||
457 | |||
458 | struct ip_vs_conn * | ||
459 | (*conn_out_get)(const struct sk_buff *skb, | ||
460 | struct ip_vs_protocol *pp, | ||
461 | const struct iphdr *iph, | ||
462 | unsigned int proto_off, | ||
463 | int inverse); | ||
464 | |||
465 | int (*snat_handler)(struct sk_buff **pskb, | ||
466 | struct ip_vs_protocol *pp, struct ip_vs_conn *cp); | ||
467 | |||
468 | int (*dnat_handler)(struct sk_buff **pskb, | ||
469 | struct ip_vs_protocol *pp, struct ip_vs_conn *cp); | ||
470 | |||
471 | int (*csum_check)(struct sk_buff *skb, struct ip_vs_protocol *pp); | ||
472 | |||
473 | const char *(*state_name)(int state); | ||
474 | |||
475 | int (*state_transition)(struct ip_vs_conn *cp, int direction, | ||
476 | const struct sk_buff *skb, | ||
477 | struct ip_vs_protocol *pp); | ||
478 | |||
479 | int (*register_app)(struct ip_vs_app *inc); | ||
480 | |||
481 | void (*unregister_app)(struct ip_vs_app *inc); | ||
482 | |||
483 | int (*app_conn_bind)(struct ip_vs_conn *cp); | ||
484 | |||
485 | void (*debug_packet)(struct ip_vs_protocol *pp, | ||
486 | const struct sk_buff *skb, | ||
487 | int offset, | ||
488 | const char *msg); | ||
489 | |||
490 | void (*timeout_change)(struct ip_vs_protocol *pp, int flags); | ||
491 | |||
492 | int (*set_state_timeout)(struct ip_vs_protocol *pp, char *sname, int to); | ||
493 | }; | ||
494 | |||
495 | extern struct ip_vs_protocol * ip_vs_proto_get(unsigned short proto); | ||
496 | |||
497 | /* | ||
498 | * IP_VS structure allocated for each dynamically scheduled connection | ||
499 | */ | ||
500 | struct ip_vs_conn { | ||
501 | struct list_head c_list; /* hashed list heads */ | ||
502 | |||
503 | /* Protocol, addresses and port numbers */ | ||
504 | __u32 caddr; /* client address */ | ||
505 | __u32 vaddr; /* virtual address */ | ||
506 | __u32 daddr; /* destination address */ | ||
507 | __u16 cport; | ||
508 | __u16 vport; | ||
509 | __u16 dport; | ||
510 | __u16 protocol; /* Which protocol (TCP/UDP) */ | ||
511 | |||
512 | /* counter and timer */ | ||
513 | atomic_t refcnt; /* reference count */ | ||
514 | struct timer_list timer; /* Expiration timer */ | ||
515 | volatile unsigned long timeout; /* timeout */ | ||
516 | |||
517 | /* Flags and state transition */ | ||
518 | spinlock_t lock; /* lock for state transition */ | ||
519 | volatile __u16 flags; /* status flags */ | ||
520 | volatile __u16 state; /* state info */ | ||
521 | |||
522 | /* Control members */ | ||
523 | struct ip_vs_conn *control; /* Master control connection */ | ||
524 | atomic_t n_control; /* Number of controlled ones */ | ||
525 | struct ip_vs_dest *dest; /* real server */ | ||
526 | atomic_t in_pkts; /* incoming packet counter */ | ||
527 | |||
528 | /* packet transmitter for different forwarding methods. If it | ||
529 | mangles the packet, it must return NF_DROP or better NF_STOLEN, | ||
530 | otherwise this must be changed to a sk_buff **. | ||
531 | */ | ||
532 | int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp, | ||
533 | struct ip_vs_protocol *pp); | ||
534 | |||
535 | /* Note: we can group the following members into a structure, | ||
536 | in order to save more space, and the following members are | ||
537 | only used in VS/NAT anyway */ | ||
538 | struct ip_vs_app *app; /* bound ip_vs_app object */ | ||
539 | void *app_data; /* Application private data */ | ||
540 | struct ip_vs_seq in_seq; /* incoming seq. struct */ | ||
541 | struct ip_vs_seq out_seq; /* outgoing seq. struct */ | ||
542 | }; | ||
543 | |||
544 | |||
545 | /* | ||
546 | * The information about the virtual service offered to the net | ||
547 | * and the forwarding entries | ||
548 | */ | ||
549 | struct ip_vs_service { | ||
550 | struct list_head s_list; /* for normal service table */ | ||
551 | struct list_head f_list; /* for fwmark-based service table */ | ||
552 | atomic_t refcnt; /* reference counter */ | ||
553 | atomic_t usecnt; /* use counter */ | ||
554 | |||
555 | __u16 protocol; /* which protocol (TCP/UDP) */ | ||
556 | __u32 addr; /* IP address for virtual service */ | ||
557 | __u16 port; /* port number for the service */ | ||
558 | __u32 fwmark; /* firewall mark of the service */ | ||
559 | unsigned flags; /* service status flags */ | ||
560 | unsigned timeout; /* persistent timeout in ticks */ | ||
561 | __u32 netmask; /* grouping granularity */ | ||
562 | |||
563 | struct list_head destinations; /* real server d-linked list */ | ||
564 | __u32 num_dests; /* number of servers */ | ||
565 | struct ip_vs_stats stats; /* statistics for the service */ | ||
566 | struct ip_vs_app *inc; /* bind conns to this app inc */ | ||
567 | |||
568 | /* for scheduling */ | ||
569 | struct ip_vs_scheduler *scheduler; /* bound scheduler object */ | ||
570 | rwlock_t sched_lock; /* lock sched_data */ | ||
571 | void *sched_data; /* scheduler application data */ | ||
572 | }; | ||
573 | |||
574 | |||
575 | /* | ||
576 | * The real server destination forwarding entry | ||
577 | * with ip address, port number, and so on. | ||
578 | */ | ||
579 | struct ip_vs_dest { | ||
580 | struct list_head n_list; /* for the dests in the service */ | ||
581 | struct list_head d_list; /* for table with all the dests */ | ||
582 | |||
583 | __u32 addr; /* IP address of the server */ | ||
584 | __u16 port; /* port number of the server */ | ||
585 | volatile unsigned flags; /* dest status flags */ | ||
586 | atomic_t conn_flags; /* flags to copy to conn */ | ||
587 | atomic_t weight; /* server weight */ | ||
588 | |||
589 | atomic_t refcnt; /* reference counter */ | ||
590 | struct ip_vs_stats stats; /* statistics */ | ||
591 | |||
592 | /* connection counters and thresholds */ | ||
593 | atomic_t activeconns; /* active connections */ | ||
594 | atomic_t inactconns; /* inactive connections */ | ||
595 | atomic_t persistconns; /* persistent connections */ | ||
596 | __u32 u_threshold; /* upper threshold */ | ||
597 | __u32 l_threshold; /* lower threshold */ | ||
598 | |||
599 | /* for destination cache */ | ||
600 | spinlock_t dst_lock; /* lock of dst_cache */ | ||
601 | struct dst_entry *dst_cache; /* destination cache entry */ | ||
602 | u32 dst_rtos; /* RT_TOS(tos) for dst */ | ||
603 | |||
604 | /* for virtual service */ | ||
605 | struct ip_vs_service *svc; /* service it belongs to */ | ||
606 | __u16 protocol; /* which protocol (TCP/UDP) */ | ||
607 | __u32 vaddr; /* virtual IP address */ | ||
608 | __u16 vport; /* virtual port number */ | ||
609 | __u32 vfwmark; /* firewall mark of service */ | ||
610 | }; | ||
611 | |||
612 | |||
613 | /* | ||
614 | * The scheduler object | ||
615 | */ | ||
616 | struct ip_vs_scheduler { | ||
617 | struct list_head n_list; /* d-linked list head */ | ||
618 | char *name; /* scheduler name */ | ||
619 | atomic_t refcnt; /* reference counter */ | ||
620 | struct module *module; /* THIS_MODULE/NULL */ | ||
621 | |||
622 | /* scheduler initializing service */ | ||
623 | int (*init_service)(struct ip_vs_service *svc); | ||
624 | /* scheduling service finish */ | ||
625 | int (*done_service)(struct ip_vs_service *svc); | ||
626 | /* scheduler updating service */ | ||
627 | int (*update_service)(struct ip_vs_service *svc); | ||
628 | |||
629 | /* selecting a server from the given service */ | ||
630 | struct ip_vs_dest* (*schedule)(struct ip_vs_service *svc, | ||
631 | const struct sk_buff *skb); | ||
632 | }; | ||
633 | |||
634 | |||
635 | /* | ||
636 | * The application module object (a.k.a. app incarnation) | ||
637 | */ | ||
638 | struct ip_vs_app | ||
639 | { | ||
640 | struct list_head a_list; /* member in app list */ | ||
641 | int type; /* IP_VS_APP_TYPE_xxx */ | ||
642 | char *name; /* application module name */ | ||
643 | __u16 protocol; | ||
644 | struct module *module; /* THIS_MODULE/NULL */ | ||
645 | struct list_head incs_list; /* list of incarnations */ | ||
646 | |||
647 | /* members for application incarnations */ | ||
648 | struct list_head p_list; /* member in proto app list */ | ||
649 | struct ip_vs_app *app; /* its real application */ | ||
650 | __u16 port; /* port number in net order */ | ||
651 | atomic_t usecnt; /* usage counter */ | ||
652 | |||
653 | /* output hook: return false if can't linearize. diff set for TCP. */ | ||
654 | int (*pkt_out)(struct ip_vs_app *, struct ip_vs_conn *, | ||
655 | struct sk_buff **, int *diff); | ||
656 | |||
657 | /* input hook: return false if can't linearize. diff set for TCP. */ | ||
658 | int (*pkt_in)(struct ip_vs_app *, struct ip_vs_conn *, | ||
659 | struct sk_buff **, int *diff); | ||
660 | |||
661 | /* ip_vs_app initializer */ | ||
662 | int (*init_conn)(struct ip_vs_app *, struct ip_vs_conn *); | ||
663 | |||
664 | /* ip_vs_app finish */ | ||
665 | int (*done_conn)(struct ip_vs_app *, struct ip_vs_conn *); | ||
666 | |||
667 | |||
668 | /* not used now */ | ||
669 | int (*bind_conn)(struct ip_vs_app *, struct ip_vs_conn *, | ||
670 | struct ip_vs_protocol *); | ||
671 | |||
672 | void (*unbind_conn)(struct ip_vs_app *, struct ip_vs_conn *); | ||
673 | |||
674 | int * timeout_table; | ||
675 | int * timeouts; | ||
676 | int timeouts_size; | ||
677 | |||
678 | int (*conn_schedule)(struct sk_buff *skb, struct ip_vs_app *app, | ||
679 | int *verdict, struct ip_vs_conn **cpp); | ||
680 | |||
681 | struct ip_vs_conn * | ||
682 | (*conn_in_get)(const struct sk_buff *skb, struct ip_vs_app *app, | ||
683 | const struct iphdr *iph, unsigned int proto_off, | ||
684 | int inverse); | ||
685 | |||
686 | struct ip_vs_conn * | ||
687 | (*conn_out_get)(const struct sk_buff *skb, struct ip_vs_app *app, | ||
688 | const struct iphdr *iph, unsigned int proto_off, | ||
689 | int inverse); | ||
690 | |||
691 | int (*state_transition)(struct ip_vs_conn *cp, int direction, | ||
692 | const struct sk_buff *skb, | ||
693 | struct ip_vs_app *app); | ||
694 | |||
695 | void (*timeout_change)(struct ip_vs_app *app, int flags); | ||
696 | }; | ||
697 | |||
698 | |||
699 | /* | ||
700 | * IPVS core functions | ||
701 | * (from ip_vs_core.c) | ||
702 | */ | ||
703 | extern const char *ip_vs_proto_name(unsigned proto); | ||
704 | extern void ip_vs_init_hash_table(struct list_head *table, int rows); | ||
705 | #define IP_VS_INIT_HASH_TABLE(t) ip_vs_init_hash_table(t, sizeof(t)/sizeof(t[0])) | ||
706 | |||
707 | #define IP_VS_APP_TYPE_UNSPEC 0 | ||
708 | #define IP_VS_APP_TYPE_FTP 1 | ||
709 | |||
710 | /* | ||
711 | * ip_vs_conn handling functions | ||
712 | * (from ip_vs_conn.c) | ||
713 | */ | ||
714 | |||
715 | /* | ||
716 | * IPVS connection entry hash table | ||
717 | */ | ||
718 | #ifndef CONFIG_IP_VS_TAB_BITS | ||
719 | #define CONFIG_IP_VS_TAB_BITS 12 | ||
720 | #endif | ||
721 | /* make sure that IP_VS_CONN_TAB_BITS is located in [8, 20] */ | ||
722 | #if CONFIG_IP_VS_TAB_BITS < 8 | ||
723 | #define IP_VS_CONN_TAB_BITS 8 | ||
724 | #endif | ||
725 | #if CONFIG_IP_VS_TAB_BITS > 20 | ||
726 | #define IP_VS_CONN_TAB_BITS 20 | ||
727 | #endif | ||
728 | #if 8 <= CONFIG_IP_VS_TAB_BITS && CONFIG_IP_VS_TAB_BITS <= 20 | ||
729 | #define IP_VS_CONN_TAB_BITS CONFIG_IP_VS_TAB_BITS | ||
730 | #endif | ||
731 | #define IP_VS_CONN_TAB_SIZE (1 << IP_VS_CONN_TAB_BITS) | ||
732 | #define IP_VS_CONN_TAB_MASK (IP_VS_CONN_TAB_SIZE - 1) | ||
733 | |||
734 | enum { | ||
735 | IP_VS_DIR_INPUT = 0, | ||
736 | IP_VS_DIR_OUTPUT, | ||
737 | IP_VS_DIR_INPUT_ONLY, | ||
738 | IP_VS_DIR_LAST, | ||
739 | }; | ||
740 | |||
741 | extern struct ip_vs_conn *ip_vs_conn_in_get | ||
742 | (int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port); | ||
743 | extern struct ip_vs_conn *ip_vs_conn_out_get | ||
744 | (int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port); | ||
745 | |||
746 | /* put back the conn without restarting its timer */ | ||
747 | static inline void __ip_vs_conn_put(struct ip_vs_conn *cp) | ||
748 | { | ||
749 | atomic_dec(&cp->refcnt); | ||
750 | } | ||
751 | extern void ip_vs_conn_put(struct ip_vs_conn *cp); | ||
752 | extern void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __u16 cport); | ||
753 | |||
754 | extern struct ip_vs_conn * | ||
755 | ip_vs_conn_new(int proto, __u32 caddr, __u16 cport, __u32 vaddr, __u16 vport, | ||
756 | __u32 daddr, __u16 dport, unsigned flags, | ||
757 | struct ip_vs_dest *dest); | ||
758 | extern void ip_vs_conn_expire_now(struct ip_vs_conn *cp); | ||
759 | |||
760 | extern const char * ip_vs_state_name(__u16 proto, int state); | ||
761 | |||
762 | extern void ip_vs_tcp_conn_listen(struct ip_vs_conn *cp); | ||
763 | extern int ip_vs_check_template(struct ip_vs_conn *ct); | ||
764 | extern void ip_vs_secure_tcp_set(int on); | ||
765 | extern void ip_vs_random_dropentry(void); | ||
766 | extern int ip_vs_conn_init(void); | ||
767 | extern void ip_vs_conn_cleanup(void); | ||
768 | |||
769 | static inline void ip_vs_control_del(struct ip_vs_conn *cp) | ||
770 | { | ||
771 | struct ip_vs_conn *ctl_cp = cp->control; | ||
772 | if (!ctl_cp) { | ||
773 | IP_VS_ERR("request control DEL for uncontrolled: " | ||
774 | "%d.%d.%d.%d:%d to %d.%d.%d.%d:%d\n", | ||
775 | NIPQUAD(cp->caddr),ntohs(cp->cport), | ||
776 | NIPQUAD(cp->vaddr),ntohs(cp->vport)); | ||
777 | return; | ||
778 | } | ||
779 | |||
780 | IP_VS_DBG(7, "DELeting control for: " | ||
781 | "cp.dst=%d.%d.%d.%d:%d ctl_cp.dst=%d.%d.%d.%d:%d\n", | ||
782 | NIPQUAD(cp->caddr),ntohs(cp->cport), | ||
783 | NIPQUAD(ctl_cp->caddr),ntohs(ctl_cp->cport)); | ||
784 | |||
785 | cp->control = NULL; | ||
786 | if (atomic_read(&ctl_cp->n_control) == 0) { | ||
787 | IP_VS_ERR("BUG control DEL with n=0 : " | ||
788 | "%d.%d.%d.%d:%d to %d.%d.%d.%d:%d\n", | ||
789 | NIPQUAD(cp->caddr),ntohs(cp->cport), | ||
790 | NIPQUAD(cp->vaddr),ntohs(cp->vport)); | ||
791 | return; | ||
792 | } | ||
793 | atomic_dec(&ctl_cp->n_control); | ||
794 | } | ||
795 | |||
796 | static inline void | ||
797 | ip_vs_control_add(struct ip_vs_conn *cp, struct ip_vs_conn *ctl_cp) | ||
798 | { | ||
799 | if (cp->control) { | ||
800 | IP_VS_ERR("request control ADD for already controlled: " | ||
801 | "%d.%d.%d.%d:%d to %d.%d.%d.%d:%d\n", | ||
802 | NIPQUAD(cp->caddr),ntohs(cp->cport), | ||
803 | NIPQUAD(cp->vaddr),ntohs(cp->vport)); | ||
804 | ip_vs_control_del(cp); | ||
805 | } | ||
806 | |||
807 | IP_VS_DBG(7, "ADDing control for: " | ||
808 | "cp.dst=%d.%d.%d.%d:%d ctl_cp.dst=%d.%d.%d.%d:%d\n", | ||
809 | NIPQUAD(cp->caddr),ntohs(cp->cport), | ||
810 | NIPQUAD(ctl_cp->caddr),ntohs(ctl_cp->cport)); | ||
811 | |||
812 | cp->control = ctl_cp; | ||
813 | atomic_inc(&ctl_cp->n_control); | ||
814 | } | ||
815 | |||
816 | |||
817 | /* | ||
818 | * IPVS application functions | ||
819 | * (from ip_vs_app.c) | ||
820 | */ | ||
821 | #define IP_VS_APP_MAX_PORTS 8 | ||
822 | extern int register_ip_vs_app(struct ip_vs_app *app); | ||
823 | extern void unregister_ip_vs_app(struct ip_vs_app *app); | ||
824 | extern int ip_vs_bind_app(struct ip_vs_conn *cp, struct ip_vs_protocol *pp); | ||
825 | extern void ip_vs_unbind_app(struct ip_vs_conn *cp); | ||
826 | extern int | ||
827 | register_ip_vs_app_inc(struct ip_vs_app *app, __u16 proto, __u16 port); | ||
828 | extern int ip_vs_app_inc_get(struct ip_vs_app *inc); | ||
829 | extern void ip_vs_app_inc_put(struct ip_vs_app *inc); | ||
830 | |||
831 | extern int ip_vs_app_pkt_out(struct ip_vs_conn *, struct sk_buff **pskb); | ||
832 | extern int ip_vs_app_pkt_in(struct ip_vs_conn *, struct sk_buff **pskb); | ||
833 | extern int ip_vs_skb_replace(struct sk_buff *skb, int pri, | ||
834 | char *o_buf, int o_len, char *n_buf, int n_len); | ||
835 | extern int ip_vs_app_init(void); | ||
836 | extern void ip_vs_app_cleanup(void); | ||
837 | |||
838 | |||
839 | /* | ||
840 | * IPVS protocol functions (from ip_vs_proto.c) | ||
841 | */ | ||
842 | extern int ip_vs_protocol_init(void); | ||
843 | extern void ip_vs_protocol_cleanup(void); | ||
844 | extern void ip_vs_protocol_timeout_change(int flags); | ||
845 | extern int *ip_vs_create_timeout_table(int *table, int size); | ||
846 | extern int | ||
847 | ip_vs_set_state_timeout(int *table, int num, char **names, char *name, int to); | ||
848 | extern void | ||
849 | ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb, | ||
850 | int offset, const char *msg); | ||
851 | |||
852 | extern struct ip_vs_protocol ip_vs_protocol_tcp; | ||
853 | extern struct ip_vs_protocol ip_vs_protocol_udp; | ||
854 | extern struct ip_vs_protocol ip_vs_protocol_icmp; | ||
855 | extern struct ip_vs_protocol ip_vs_protocol_esp; | ||
856 | extern struct ip_vs_protocol ip_vs_protocol_ah; | ||
857 | |||
858 | |||
859 | /* | ||
860 | * Registering/unregistering scheduler functions | ||
861 | * (from ip_vs_sched.c) | ||
862 | */ | ||
863 | extern int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler); | ||
864 | extern int unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler); | ||
865 | extern int ip_vs_bind_scheduler(struct ip_vs_service *svc, | ||
866 | struct ip_vs_scheduler *scheduler); | ||
867 | extern int ip_vs_unbind_scheduler(struct ip_vs_service *svc); | ||
868 | extern struct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name); | ||
869 | extern void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler); | ||
870 | extern struct ip_vs_conn * | ||
871 | ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb); | ||
872 | extern int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, | ||
873 | struct ip_vs_protocol *pp); | ||
874 | |||
875 | |||
876 | /* | ||
877 | * IPVS control data and functions (from ip_vs_ctl.c) | ||
878 | */ | ||
879 | extern int sysctl_ip_vs_cache_bypass; | ||
880 | extern int sysctl_ip_vs_expire_nodest_conn; | ||
881 | extern int sysctl_ip_vs_expire_quiescent_template; | ||
882 | extern int sysctl_ip_vs_sync_threshold[2]; | ||
883 | extern int sysctl_ip_vs_nat_icmp_send; | ||
884 | extern struct ip_vs_stats ip_vs_stats; | ||
885 | |||
886 | extern struct ip_vs_service * | ||
887 | ip_vs_service_get(__u32 fwmark, __u16 protocol, __u32 vaddr, __u16 vport); | ||
888 | |||
889 | static inline void ip_vs_service_put(struct ip_vs_service *svc) | ||
890 | { | ||
891 | atomic_dec(&svc->usecnt); | ||
892 | } | ||
893 | |||
894 | extern struct ip_vs_dest * | ||
895 | ip_vs_lookup_real_service(__u16 protocol, __u32 daddr, __u16 dport); | ||
896 | extern int ip_vs_use_count_inc(void); | ||
897 | extern void ip_vs_use_count_dec(void); | ||
898 | extern int ip_vs_control_init(void); | ||
899 | extern void ip_vs_control_cleanup(void); | ||
900 | |||
901 | |||
902 | /* | ||
903 | * IPVS sync daemon data and function prototypes | ||
904 | * (from ip_vs_sync.c) | ||
905 | */ | ||
906 | extern volatile int ip_vs_sync_state; | ||
907 | extern volatile int ip_vs_master_syncid; | ||
908 | extern volatile int ip_vs_backup_syncid; | ||
909 | extern char ip_vs_master_mcast_ifn[IP_VS_IFNAME_MAXLEN]; | ||
910 | extern char ip_vs_backup_mcast_ifn[IP_VS_IFNAME_MAXLEN]; | ||
911 | extern int start_sync_thread(int state, char *mcast_ifn, __u8 syncid); | ||
912 | extern int stop_sync_thread(int state); | ||
913 | extern void ip_vs_sync_conn(struct ip_vs_conn *cp); | ||
914 | |||
915 | |||
916 | /* | ||
917 | * IPVS rate estimator prototypes (from ip_vs_est.c) | ||
918 | */ | ||
919 | extern int ip_vs_new_estimator(struct ip_vs_stats *stats); | ||
920 | extern void ip_vs_kill_estimator(struct ip_vs_stats *stats); | ||
921 | extern void ip_vs_zero_estimator(struct ip_vs_stats *stats); | ||
922 | |||
923 | /* | ||
924 | * Various IPVS packet transmitters (from ip_vs_xmit.c) | ||
925 | */ | ||
926 | extern int ip_vs_null_xmit | ||
927 | (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp); | ||
928 | extern int ip_vs_bypass_xmit | ||
929 | (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp); | ||
930 | extern int ip_vs_nat_xmit | ||
931 | (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp); | ||
932 | extern int ip_vs_tunnel_xmit | ||
933 | (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp); | ||
934 | extern int ip_vs_dr_xmit | ||
935 | (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp); | ||
936 | extern int ip_vs_icmp_xmit | ||
937 | (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp, int offset); | ||
938 | extern void ip_vs_dst_reset(struct ip_vs_dest *dest); | ||
939 | |||
940 | |||
941 | /* | ||
942 | * This is a simple mechanism to ignore packets when | ||
943 | * we are loaded. Just set ip_vs_drop_rate to 'n' and | ||
944 | * we start to drop 1/rate of the packets | ||
945 | */ | ||
946 | extern int ip_vs_drop_rate; | ||
947 | extern int ip_vs_drop_counter; | ||
948 | |||
949 | static __inline__ int ip_vs_todrop(void) | ||
950 | { | ||
951 | if (!ip_vs_drop_rate) return 0; | ||
952 | if (--ip_vs_drop_counter > 0) return 0; | ||
953 | ip_vs_drop_counter = ip_vs_drop_rate; | ||
954 | return 1; | ||
955 | } | ||
956 | |||
957 | /* | ||
958 | * ip_vs_fwd_tag returns the forwarding tag of the connection | ||
959 | */ | ||
960 | #define IP_VS_FWD_METHOD(cp) (cp->flags & IP_VS_CONN_F_FWD_MASK) | ||
961 | |||
962 | extern __inline__ char ip_vs_fwd_tag(struct ip_vs_conn *cp) | ||
963 | { | ||
964 | char fwd; | ||
965 | |||
966 | switch (IP_VS_FWD_METHOD(cp)) { | ||
967 | case IP_VS_CONN_F_MASQ: | ||
968 | fwd = 'M'; break; | ||
969 | case IP_VS_CONN_F_LOCALNODE: | ||
970 | fwd = 'L'; break; | ||
971 | case IP_VS_CONN_F_TUNNEL: | ||
972 | fwd = 'T'; break; | ||
973 | case IP_VS_CONN_F_DROUTE: | ||
974 | fwd = 'R'; break; | ||
975 | case IP_VS_CONN_F_BYPASS: | ||
976 | fwd = 'B'; break; | ||
977 | default: | ||
978 | fwd = '?'; break; | ||
979 | } | ||
980 | return fwd; | ||
981 | } | ||
982 | |||
983 | extern int ip_vs_make_skb_writable(struct sk_buff **pskb, int len); | ||
984 | extern void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp, | ||
985 | struct ip_vs_conn *cp, int dir); | ||
986 | |||
987 | extern u16 ip_vs_checksum_complete(struct sk_buff *skb, int offset); | ||
988 | |||
989 | static inline u16 ip_vs_check_diff(u32 old, u32 new, u16 oldsum) | ||
990 | { | ||
991 | u32 diff[2] = { old, new }; | ||
992 | |||
993 | return csum_fold(csum_partial((char *) diff, sizeof(diff), | ||
994 | oldsum ^ 0xFFFF)); | ||
995 | } | ||
996 | |||
997 | #endif /* __KERNEL__ */ | ||
998 | |||
999 | #endif /* _IP_VS_H */ | ||
diff --git a/include/net/ipcomp.h b/include/net/ipcomp.h new file mode 100644 index 000000000000..e651a57ecdd5 --- /dev/null +++ b/include/net/ipcomp.h | |||
@@ -0,0 +1,11 @@ | |||
1 | #ifndef _NET_IPCOMP_H | ||
2 | #define _NET_IPCOMP_H | ||
3 | |||
4 | #define IPCOMP_SCRATCH_SIZE 65400 | ||
5 | |||
6 | struct ipcomp_data { | ||
7 | u16 threshold; | ||
8 | struct crypto_tfm **tfms; | ||
9 | }; | ||
10 | |||
11 | #endif | ||
diff --git a/include/net/ipconfig.h b/include/net/ipconfig.h new file mode 100644 index 000000000000..2a1fe996fbc6 --- /dev/null +++ b/include/net/ipconfig.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * $Id: ipconfig.h,v 1.4 2001/04/30 04:51:46 davem Exp $ | ||
3 | * | ||
4 | * Copyright (C) 1997 Martin Mares | ||
5 | * | ||
6 | * Automatic IP Layer Configuration | ||
7 | */ | ||
8 | |||
9 | /* The following are initdata: */ | ||
10 | |||
11 | extern int ic_proto_enabled; /* Protocols enabled (see IC_xxx) */ | ||
12 | extern int ic_set_manually; /* IPconfig parameters set manually */ | ||
13 | |||
14 | extern u32 ic_myaddr; /* My IP address */ | ||
15 | extern u32 ic_gateway; /* Gateway IP address */ | ||
16 | |||
17 | extern u32 ic_servaddr; /* Boot server IP address */ | ||
18 | |||
19 | extern u32 root_server_addr; /* Address of NFS server */ | ||
20 | extern u8 root_server_path[]; /* Path to mount as root */ | ||
21 | |||
22 | |||
23 | /* bits in ic_proto_{enabled,used} */ | ||
24 | #define IC_PROTO 0xFF /* Protocols mask: */ | ||
25 | #define IC_BOOTP 0x01 /* BOOTP (or DHCP, see below) */ | ||
26 | #define IC_RARP 0x02 /* RARP */ | ||
27 | #define IC_USE_DHCP 0x100 /* If on, use DHCP instead of BOOTP */ | ||
diff --git a/include/net/ipip.h b/include/net/ipip.h new file mode 100644 index 000000000000..f490c3cbe377 --- /dev/null +++ b/include/net/ipip.h | |||
@@ -0,0 +1,51 @@ | |||
1 | #ifndef __NET_IPIP_H | ||
2 | #define __NET_IPIP_H 1 | ||
3 | |||
4 | #include <linux/if_tunnel.h> | ||
5 | |||
6 | /* Keep error state on tunnel for 30 sec */ | ||
7 | #define IPTUNNEL_ERR_TIMEO (30*HZ) | ||
8 | |||
9 | struct ip_tunnel | ||
10 | { | ||
11 | struct ip_tunnel *next; | ||
12 | struct net_device *dev; | ||
13 | struct net_device_stats stat; | ||
14 | |||
15 | int recursion; /* Depth of hard_start_xmit recursion */ | ||
16 | int err_count; /* Number of arrived ICMP errors */ | ||
17 | unsigned long err_time; /* Time when the last ICMP error arrived */ | ||
18 | |||
19 | /* These four fields used only by GRE */ | ||
20 | __u32 i_seqno; /* The last seen seqno */ | ||
21 | __u32 o_seqno; /* The last output seqno */ | ||
22 | int hlen; /* Precalculated GRE header length */ | ||
23 | int mlink; | ||
24 | |||
25 | struct ip_tunnel_parm parms; | ||
26 | }; | ||
27 | |||
28 | #define IPTUNNEL_XMIT() do { \ | ||
29 | int err; \ | ||
30 | int pkt_len = skb->len; \ | ||
31 | \ | ||
32 | skb->ip_summed = CHECKSUM_NONE; \ | ||
33 | iph->tot_len = htons(skb->len); \ | ||
34 | ip_select_ident(iph, &rt->u.dst, NULL); \ | ||
35 | ip_send_check(iph); \ | ||
36 | \ | ||
37 | err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output);\ | ||
38 | if (err == NET_XMIT_SUCCESS || err == NET_XMIT_CN) { \ | ||
39 | stats->tx_bytes += pkt_len; \ | ||
40 | stats->tx_packets++; \ | ||
41 | } else { \ | ||
42 | stats->tx_errors++; \ | ||
43 | stats->tx_aborted_errors++; \ | ||
44 | } \ | ||
45 | } while (0) | ||
46 | |||
47 | |||
48 | extern int sit_init(void); | ||
49 | extern void sit_cleanup(void); | ||
50 | |||
51 | #endif | ||
diff --git a/include/net/ipv6.h b/include/net/ipv6.h new file mode 100644 index 000000000000..87c45cbfbaf6 --- /dev/null +++ b/include/net/ipv6.h | |||
@@ -0,0 +1,472 @@ | |||
1 | /* | ||
2 | * Linux INET6 implementation | ||
3 | * | ||
4 | * Authors: | ||
5 | * Pedro Roque <roque@di.fc.ul.pt> | ||
6 | * | ||
7 | * $Id: ipv6.h,v 1.1 2002/05/20 15:13:07 jgrimm Exp $ | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | */ | ||
14 | |||
15 | #ifndef _NET_IPV6_H | ||
16 | #define _NET_IPV6_H | ||
17 | |||
18 | #include <linux/ipv6.h> | ||
19 | #include <linux/hardirq.h> | ||
20 | #include <net/ndisc.h> | ||
21 | #include <net/flow.h> | ||
22 | #include <net/snmp.h> | ||
23 | |||
24 | #define SIN6_LEN_RFC2133 24 | ||
25 | |||
26 | #define IPV6_MAXPLEN 65535 | ||
27 | |||
28 | /* | ||
29 | * NextHeader field of IPv6 header | ||
30 | */ | ||
31 | |||
32 | #define NEXTHDR_HOP 0 /* Hop-by-hop option header. */ | ||
33 | #define NEXTHDR_TCP 6 /* TCP segment. */ | ||
34 | #define NEXTHDR_UDP 17 /* UDP message. */ | ||
35 | #define NEXTHDR_IPV6 41 /* IPv6 in IPv6 */ | ||
36 | #define NEXTHDR_ROUTING 43 /* Routing header. */ | ||
37 | #define NEXTHDR_FRAGMENT 44 /* Fragmentation/reassembly header. */ | ||
38 | #define NEXTHDR_ESP 50 /* Encapsulating security payload. */ | ||
39 | #define NEXTHDR_AUTH 51 /* Authentication header. */ | ||
40 | #define NEXTHDR_ICMP 58 /* ICMP for IPv6. */ | ||
41 | #define NEXTHDR_NONE 59 /* No next header */ | ||
42 | #define NEXTHDR_DEST 60 /* Destination options header. */ | ||
43 | |||
44 | #define NEXTHDR_MAX 255 | ||
45 | |||
46 | |||
47 | |||
48 | #define IPV6_DEFAULT_HOPLIMIT 64 | ||
49 | #define IPV6_DEFAULT_MCASTHOPS 1 | ||
50 | |||
51 | /* | ||
52 | * Addr type | ||
53 | * | ||
54 | * type - unicast | multicast | ||
55 | * scope - local | site | global | ||
56 | * v4 - compat | ||
57 | * v4mapped | ||
58 | * any | ||
59 | * loopback | ||
60 | */ | ||
61 | |||
62 | #define IPV6_ADDR_ANY 0x0000U | ||
63 | |||
64 | #define IPV6_ADDR_UNICAST 0x0001U | ||
65 | #define IPV6_ADDR_MULTICAST 0x0002U | ||
66 | |||
67 | #define IPV6_ADDR_LOOPBACK 0x0010U | ||
68 | #define IPV6_ADDR_LINKLOCAL 0x0020U | ||
69 | #define IPV6_ADDR_SITELOCAL 0x0040U | ||
70 | |||
71 | #define IPV6_ADDR_COMPATv4 0x0080U | ||
72 | |||
73 | #define IPV6_ADDR_SCOPE_MASK 0x00f0U | ||
74 | |||
75 | #define IPV6_ADDR_MAPPED 0x1000U | ||
76 | #define IPV6_ADDR_RESERVED 0x2000U /* reserved address space */ | ||
77 | |||
78 | /* | ||
79 | * Addr scopes | ||
80 | */ | ||
81 | #ifdef __KERNEL__ | ||
82 | #define IPV6_ADDR_MC_SCOPE(a) \ | ||
83 | ((a)->s6_addr[1] & 0x0f) /* nonstandard */ | ||
84 | #define __IPV6_ADDR_SCOPE_INVALID -1 | ||
85 | #endif | ||
86 | #define IPV6_ADDR_SCOPE_NODELOCAL 0x01 | ||
87 | #define IPV6_ADDR_SCOPE_LINKLOCAL 0x02 | ||
88 | #define IPV6_ADDR_SCOPE_SITELOCAL 0x05 | ||
89 | #define IPV6_ADDR_SCOPE_ORGLOCAL 0x08 | ||
90 | #define IPV6_ADDR_SCOPE_GLOBAL 0x0e | ||
91 | |||
92 | /* | ||
93 | * fragmentation header | ||
94 | */ | ||
95 | |||
96 | struct frag_hdr { | ||
97 | unsigned char nexthdr; | ||
98 | unsigned char reserved; | ||
99 | unsigned short frag_off; | ||
100 | __u32 identification; | ||
101 | }; | ||
102 | |||
103 | #define IP6_MF 0x0001 | ||
104 | |||
105 | #ifdef __KERNEL__ | ||
106 | |||
107 | #include <net/sock.h> | ||
108 | |||
109 | /* sysctls */ | ||
110 | extern int sysctl_ipv6_bindv6only; | ||
111 | extern int sysctl_mld_max_msf; | ||
112 | |||
113 | /* MIBs */ | ||
114 | DECLARE_SNMP_STAT(struct ipstats_mib, ipv6_statistics); | ||
115 | #define IP6_INC_STATS(field) SNMP_INC_STATS(ipv6_statistics, field) | ||
116 | #define IP6_INC_STATS_BH(field) SNMP_INC_STATS_BH(ipv6_statistics, field) | ||
117 | #define IP6_INC_STATS_USER(field) SNMP_INC_STATS_USER(ipv6_statistics, field) | ||
118 | DECLARE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics); | ||
119 | #define ICMP6_INC_STATS(idev, field) ({ \ | ||
120 | struct inet6_dev *_idev = (idev); \ | ||
121 | if (likely(_idev != NULL)) \ | ||
122 | SNMP_INC_STATS(idev->stats.icmpv6, field); \ | ||
123 | SNMP_INC_STATS(icmpv6_statistics, field); \ | ||
124 | }) | ||
125 | #define ICMP6_INC_STATS_BH(idev, field) ({ \ | ||
126 | struct inet6_dev *_idev = (idev); \ | ||
127 | if (likely(_idev != NULL)) \ | ||
128 | SNMP_INC_STATS_BH((_idev)->stats.icmpv6, field); \ | ||
129 | SNMP_INC_STATS_BH(icmpv6_statistics, field); \ | ||
130 | }) | ||
131 | #define ICMP6_INC_STATS_USER(idev, field) ({ \ | ||
132 | struct inet6_dev *_idev = (idev); \ | ||
133 | if (likely(_idev != NULL)) \ | ||
134 | SNMP_INC_STATS_USER(_idev->stats.icmpv6, field); \ | ||
135 | SNMP_INC_STATS_USER(icmpv6_statistics, field); \ | ||
136 | }) | ||
137 | #define ICMP6_INC_STATS_OFFSET_BH(idev, field, offset) ({ \ | ||
138 | struct inet6_dev *_idev = idev; \ | ||
139 | __typeof__(offset) _offset = (offset); \ | ||
140 | if (likely(_idev != NULL)) \ | ||
141 | SNMP_INC_STATS_OFFSET_BH(_idev->stats.icmpv6, field, _offset); \ | ||
142 | SNMP_INC_STATS_OFFSET_BH(icmpv6_statistics, field, _offset); \ | ||
143 | }) | ||
144 | DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6); | ||
145 | #define UDP6_INC_STATS(field) SNMP_INC_STATS(udp_stats_in6, field) | ||
146 | #define UDP6_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_stats_in6, field) | ||
147 | #define UDP6_INC_STATS_USER(field) SNMP_INC_STATS_USER(udp_stats_in6, field) | ||
148 | extern atomic_t inet6_sock_nr; | ||
149 | |||
150 | int snmp6_register_dev(struct inet6_dev *idev); | ||
151 | int snmp6_unregister_dev(struct inet6_dev *idev); | ||
152 | int snmp6_alloc_dev(struct inet6_dev *idev); | ||
153 | int snmp6_free_dev(struct inet6_dev *idev); | ||
154 | int snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign); | ||
155 | void snmp6_mib_free(void *ptr[2]); | ||
156 | |||
157 | struct ip6_ra_chain | ||
158 | { | ||
159 | struct ip6_ra_chain *next; | ||
160 | struct sock *sk; | ||
161 | int sel; | ||
162 | void (*destructor)(struct sock *); | ||
163 | }; | ||
164 | |||
165 | extern struct ip6_ra_chain *ip6_ra_chain; | ||
166 | extern rwlock_t ip6_ra_lock; | ||
167 | |||
168 | /* | ||
169 | This structure is prepared by protocol, when parsing | ||
170 | ancillary data and passed to IPv6. | ||
171 | */ | ||
172 | |||
173 | struct ipv6_txoptions | ||
174 | { | ||
175 | /* Length of this structure */ | ||
176 | int tot_len; | ||
177 | |||
178 | /* length of extension headers */ | ||
179 | |||
180 | __u16 opt_flen; /* after fragment hdr */ | ||
181 | __u16 opt_nflen; /* before fragment hdr */ | ||
182 | |||
183 | struct ipv6_opt_hdr *hopopt; | ||
184 | struct ipv6_opt_hdr *dst0opt; | ||
185 | struct ipv6_rt_hdr *srcrt; /* Routing Header */ | ||
186 | struct ipv6_opt_hdr *auth; | ||
187 | struct ipv6_opt_hdr *dst1opt; | ||
188 | |||
189 | /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */ | ||
190 | }; | ||
191 | |||
192 | struct ip6_flowlabel | ||
193 | { | ||
194 | struct ip6_flowlabel *next; | ||
195 | u32 label; | ||
196 | struct in6_addr dst; | ||
197 | struct ipv6_txoptions *opt; | ||
198 | atomic_t users; | ||
199 | unsigned long linger; | ||
200 | u8 share; | ||
201 | u32 owner; | ||
202 | unsigned long lastuse; | ||
203 | unsigned long expires; | ||
204 | }; | ||
205 | |||
206 | #define IPV6_FLOWINFO_MASK __constant_htonl(0x0FFFFFFF) | ||
207 | #define IPV6_FLOWLABEL_MASK __constant_htonl(0x000FFFFF) | ||
208 | |||
209 | struct ipv6_fl_socklist | ||
210 | { | ||
211 | struct ipv6_fl_socklist *next; | ||
212 | struct ip6_flowlabel *fl; | ||
213 | }; | ||
214 | |||
215 | extern struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk, u32 label); | ||
216 | extern struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space, | ||
217 | struct ip6_flowlabel * fl, | ||
218 | struct ipv6_txoptions * fopt); | ||
219 | extern void fl6_free_socklist(struct sock *sk); | ||
220 | extern int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen); | ||
221 | extern void ip6_flowlabel_init(void); | ||
222 | extern void ip6_flowlabel_cleanup(void); | ||
223 | |||
224 | static inline void fl6_sock_release(struct ip6_flowlabel *fl) | ||
225 | { | ||
226 | if (fl) | ||
227 | atomic_dec(&fl->users); | ||
228 | } | ||
229 | |||
230 | extern int ip6_ra_control(struct sock *sk, int sel, | ||
231 | void (*destructor)(struct sock *)); | ||
232 | |||
233 | |||
234 | extern int ipv6_parse_hopopts(struct sk_buff *skb, int); | ||
235 | |||
236 | extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt); | ||
237 | |||
238 | extern int ip6_frag_nqueues; | ||
239 | extern atomic_t ip6_frag_mem; | ||
240 | |||
241 | #define IPV6_FRAG_TIMEOUT (60*HZ) /* 60 seconds */ | ||
242 | |||
243 | /* | ||
244 | * Function prototype for build_xmit | ||
245 | */ | ||
246 | |||
247 | typedef int (*inet_getfrag_t) (const void *data, | ||
248 | struct in6_addr *addr, | ||
249 | char *, | ||
250 | unsigned int, unsigned int); | ||
251 | |||
252 | |||
253 | extern int ipv6_addr_type(const struct in6_addr *addr); | ||
254 | |||
255 | static inline int ipv6_addr_scope(const struct in6_addr *addr) | ||
256 | { | ||
257 | return ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK; | ||
258 | } | ||
259 | |||
260 | static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2) | ||
261 | { | ||
262 | return memcmp((const void *) a1, (const void *) a2, sizeof(struct in6_addr)); | ||
263 | } | ||
264 | |||
265 | static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2) | ||
266 | { | ||
267 | memcpy((void *) a1, (const void *) a2, sizeof(struct in6_addr)); | ||
268 | } | ||
269 | |||
270 | static inline void ipv6_addr_prefix(struct in6_addr *pfx, | ||
271 | const struct in6_addr *addr, | ||
272 | int plen) | ||
273 | { | ||
274 | /* caller must guarantee 0 <= plen <= 128 */ | ||
275 | int o = plen >> 3, | ||
276 | b = plen & 0x7; | ||
277 | |||
278 | memcpy(pfx->s6_addr, addr, o); | ||
279 | if (b != 0) { | ||
280 | pfx->s6_addr[o] = addr->s6_addr[o] & (0xff00 >> b); | ||
281 | o++; | ||
282 | } | ||
283 | if (o < 16) | ||
284 | memset(pfx->s6_addr + o, 0, 16 - o); | ||
285 | } | ||
286 | |||
287 | #ifndef __HAVE_ARCH_ADDR_SET | ||
288 | static inline void ipv6_addr_set(struct in6_addr *addr, | ||
289 | __u32 w1, __u32 w2, | ||
290 | __u32 w3, __u32 w4) | ||
291 | { | ||
292 | addr->s6_addr32[0] = w1; | ||
293 | addr->s6_addr32[1] = w2; | ||
294 | addr->s6_addr32[2] = w3; | ||
295 | addr->s6_addr32[3] = w4; | ||
296 | } | ||
297 | #endif | ||
298 | |||
299 | static inline int ipv6_addr_equal(const struct in6_addr *a1, | ||
300 | const struct in6_addr *a2) | ||
301 | { | ||
302 | return (a1->s6_addr32[0] == a2->s6_addr32[0] && | ||
303 | a1->s6_addr32[1] == a2->s6_addr32[1] && | ||
304 | a1->s6_addr32[2] == a2->s6_addr32[2] && | ||
305 | a1->s6_addr32[3] == a2->s6_addr32[3]); | ||
306 | } | ||
307 | |||
308 | static inline int __ipv6_prefix_equal(const u32 *a1, const u32 *a2, | ||
309 | unsigned int prefixlen) | ||
310 | { | ||
311 | unsigned pdw, pbi; | ||
312 | |||
313 | /* check complete u32 in prefix */ | ||
314 | pdw = prefixlen >> 5; | ||
315 | if (pdw && memcmp(a1, a2, pdw << 2)) | ||
316 | return 0; | ||
317 | |||
318 | /* check incomplete u32 in prefix */ | ||
319 | pbi = prefixlen & 0x1f; | ||
320 | if (pbi && ((a1[pdw] ^ a2[pdw]) & htonl((0xffffffff) << (32 - pbi)))) | ||
321 | return 0; | ||
322 | |||
323 | return 1; | ||
324 | } | ||
325 | |||
326 | static inline int ipv6_prefix_equal(const struct in6_addr *a1, | ||
327 | const struct in6_addr *a2, | ||
328 | unsigned int prefixlen) | ||
329 | { | ||
330 | return __ipv6_prefix_equal(a1->s6_addr32, a2->s6_addr32, | ||
331 | prefixlen); | ||
332 | } | ||
333 | |||
334 | static inline int ipv6_addr_any(const struct in6_addr *a) | ||
335 | { | ||
336 | return ((a->s6_addr32[0] | a->s6_addr32[1] | | ||
337 | a->s6_addr32[2] | a->s6_addr32[3] ) == 0); | ||
338 | } | ||
339 | |||
340 | /* | ||
341 | * Prototypes exported by ipv6 | ||
342 | */ | ||
343 | |||
344 | /* | ||
345 | * rcv function (called from netdevice level) | ||
346 | */ | ||
347 | |||
348 | extern int ipv6_rcv(struct sk_buff *skb, | ||
349 | struct net_device *dev, | ||
350 | struct packet_type *pt); | ||
351 | |||
352 | /* | ||
353 | * upper-layer output functions | ||
354 | */ | ||
355 | extern int ip6_xmit(struct sock *sk, | ||
356 | struct sk_buff *skb, | ||
357 | struct flowi *fl, | ||
358 | struct ipv6_txoptions *opt, | ||
359 | int ipfragok); | ||
360 | |||
361 | extern int ip6_nd_hdr(struct sock *sk, | ||
362 | struct sk_buff *skb, | ||
363 | struct net_device *dev, | ||
364 | struct in6_addr *saddr, | ||
365 | struct in6_addr *daddr, | ||
366 | int proto, int len); | ||
367 | |||
368 | extern int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr); | ||
369 | |||
370 | extern int ip6_append_data(struct sock *sk, | ||
371 | int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), | ||
372 | void *from, | ||
373 | int length, | ||
374 | int transhdrlen, | ||
375 | int hlimit, | ||
376 | struct ipv6_txoptions *opt, | ||
377 | struct flowi *fl, | ||
378 | struct rt6_info *rt, | ||
379 | unsigned int flags); | ||
380 | |||
381 | extern int ip6_push_pending_frames(struct sock *sk); | ||
382 | |||
383 | extern void ip6_flush_pending_frames(struct sock *sk); | ||
384 | |||
385 | extern int ip6_dst_lookup(struct sock *sk, | ||
386 | struct dst_entry **dst, | ||
387 | struct flowi *fl); | ||
388 | |||
389 | /* | ||
390 | * skb processing functions | ||
391 | */ | ||
392 | |||
393 | extern int ip6_output(struct sk_buff *skb); | ||
394 | extern int ip6_forward(struct sk_buff *skb); | ||
395 | extern int ip6_input(struct sk_buff *skb); | ||
396 | extern int ip6_mc_input(struct sk_buff *skb); | ||
397 | |||
398 | /* | ||
399 | * Extension header (options) processing | ||
400 | */ | ||
401 | |||
402 | extern u8 * ipv6_build_nfrag_opts(struct sk_buff *skb, | ||
403 | u8 *prev_hdr, | ||
404 | struct ipv6_txoptions *opt, | ||
405 | struct in6_addr *daddr, | ||
406 | u32 jumbolen); | ||
407 | extern u8 * ipv6_build_frag_opts(struct sk_buff *skb, | ||
408 | u8 *prev_hdr, | ||
409 | struct ipv6_txoptions *opt); | ||
410 | extern void ipv6_push_nfrag_opts(struct sk_buff *skb, | ||
411 | struct ipv6_txoptions *opt, | ||
412 | u8 *proto, | ||
413 | struct in6_addr **daddr_p); | ||
414 | extern void ipv6_push_frag_opts(struct sk_buff *skb, | ||
415 | struct ipv6_txoptions *opt, | ||
416 | u8 *proto); | ||
417 | |||
418 | extern int ipv6_skip_exthdr(const struct sk_buff *, int start, | ||
419 | u8 *nexthdrp, int len); | ||
420 | |||
421 | extern int ipv6_ext_hdr(u8 nexthdr); | ||
422 | |||
423 | extern struct ipv6_txoptions * ipv6_invert_rthdr(struct sock *sk, | ||
424 | struct ipv6_rt_hdr *hdr); | ||
425 | |||
426 | |||
427 | /* | ||
428 | * socket options (ipv6_sockglue.c) | ||
429 | */ | ||
430 | |||
431 | extern int ipv6_setsockopt(struct sock *sk, int level, | ||
432 | int optname, | ||
433 | char __user *optval, | ||
434 | int optlen); | ||
435 | extern int ipv6_getsockopt(struct sock *sk, int level, | ||
436 | int optname, | ||
437 | char __user *optval, | ||
438 | int __user *optlen); | ||
439 | |||
440 | extern void ipv6_packet_init(void); | ||
441 | |||
442 | extern void ipv6_packet_cleanup(void); | ||
443 | |||
444 | extern int ip6_datagram_connect(struct sock *sk, | ||
445 | struct sockaddr *addr, int addr_len); | ||
446 | |||
447 | extern int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len); | ||
448 | extern void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, u16 port, | ||
449 | u32 info, u8 *payload); | ||
450 | extern void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info); | ||
451 | |||
452 | extern int inet6_release(struct socket *sock); | ||
453 | extern int inet6_bind(struct socket *sock, struct sockaddr *uaddr, | ||
454 | int addr_len); | ||
455 | extern int inet6_getname(struct socket *sock, struct sockaddr *uaddr, | ||
456 | int *uaddr_len, int peer); | ||
457 | extern int inet6_ioctl(struct socket *sock, unsigned int cmd, | ||
458 | unsigned long arg); | ||
459 | |||
460 | /* | ||
461 | * reassembly.c | ||
462 | */ | ||
463 | extern int sysctl_ip6frag_high_thresh; | ||
464 | extern int sysctl_ip6frag_low_thresh; | ||
465 | extern int sysctl_ip6frag_time; | ||
466 | extern int sysctl_ip6frag_secret_interval; | ||
467 | |||
468 | #endif /* __KERNEL__ */ | ||
469 | #endif /* _NET_IPV6_H */ | ||
470 | |||
471 | |||
472 | |||
diff --git a/include/net/ipx.h b/include/net/ipx.h new file mode 100644 index 000000000000..5c0cf33826c5 --- /dev/null +++ b/include/net/ipx.h | |||
@@ -0,0 +1,161 @@ | |||
1 | #ifndef _NET_INET_IPX_H_ | ||
2 | #define _NET_INET_IPX_H_ | ||
3 | /* | ||
4 | * The following information is in its entirety obtained from: | ||
5 | * | ||
6 | * Novell 'IPX Router Specification' Version 1.10 | ||
7 | * Part No. 107-000029-001 | ||
8 | * | ||
9 | * Which is available from ftp.novell.com | ||
10 | */ | ||
11 | |||
12 | #include <linux/netdevice.h> | ||
13 | #include <net/datalink.h> | ||
14 | #include <linux/ipx.h> | ||
15 | #include <linux/list.h> | ||
16 | |||
17 | struct ipx_address { | ||
18 | __u32 net; | ||
19 | __u8 node[IPX_NODE_LEN]; | ||
20 | __u16 sock; | ||
21 | }; | ||
22 | |||
23 | #define ipx_broadcast_node "\377\377\377\377\377\377" | ||
24 | #define ipx_this_node "\0\0\0\0\0\0" | ||
25 | |||
26 | #define IPX_MAX_PPROP_HOPS 8 | ||
27 | |||
28 | struct ipxhdr { | ||
29 | __u16 ipx_checksum __attribute__ ((packed)); | ||
30 | #define IPX_NO_CHECKSUM 0xFFFF | ||
31 | __u16 ipx_pktsize __attribute__ ((packed)); | ||
32 | __u8 ipx_tctrl; | ||
33 | __u8 ipx_type; | ||
34 | #define IPX_TYPE_UNKNOWN 0x00 | ||
35 | #define IPX_TYPE_RIP 0x01 /* may also be 0 */ | ||
36 | #define IPX_TYPE_SAP 0x04 /* may also be 0 */ | ||
37 | #define IPX_TYPE_SPX 0x05 /* SPX protocol */ | ||
38 | #define IPX_TYPE_NCP 0x11 /* $lots for docs on this (SPIT) */ | ||
39 | #define IPX_TYPE_PPROP 0x14 /* complicated flood fill brdcast */ | ||
40 | struct ipx_address ipx_dest __attribute__ ((packed)); | ||
41 | struct ipx_address ipx_source __attribute__ ((packed)); | ||
42 | }; | ||
43 | |||
44 | static __inline__ struct ipxhdr *ipx_hdr(struct sk_buff *skb) | ||
45 | { | ||
46 | return (struct ipxhdr *)skb->h.raw; | ||
47 | } | ||
48 | |||
49 | struct ipx_interface { | ||
50 | /* IPX address */ | ||
51 | __u32 if_netnum; | ||
52 | unsigned char if_node[IPX_NODE_LEN]; | ||
53 | atomic_t refcnt; | ||
54 | |||
55 | /* physical device info */ | ||
56 | struct net_device *if_dev; | ||
57 | struct datalink_proto *if_dlink; | ||
58 | unsigned short if_dlink_type; | ||
59 | |||
60 | /* socket support */ | ||
61 | unsigned short if_sknum; | ||
62 | struct hlist_head if_sklist; | ||
63 | spinlock_t if_sklist_lock; | ||
64 | |||
65 | /* administrative overhead */ | ||
66 | int if_ipx_offset; | ||
67 | unsigned char if_internal; | ||
68 | unsigned char if_primary; | ||
69 | |||
70 | struct list_head node; /* node in ipx_interfaces list */ | ||
71 | }; | ||
72 | |||
73 | struct ipx_route { | ||
74 | __u32 ir_net; | ||
75 | struct ipx_interface *ir_intrfc; | ||
76 | unsigned char ir_routed; | ||
77 | unsigned char ir_router_node[IPX_NODE_LEN]; | ||
78 | struct list_head node; /* node in ipx_routes list */ | ||
79 | atomic_t refcnt; | ||
80 | }; | ||
81 | |||
82 | #ifdef __KERNEL__ | ||
83 | struct ipx_cb { | ||
84 | u8 ipx_tctrl; | ||
85 | u32 ipx_dest_net; | ||
86 | u32 ipx_source_net; | ||
87 | struct { | ||
88 | u32 netnum; | ||
89 | int index; | ||
90 | } last_hop; | ||
91 | }; | ||
92 | |||
93 | #include <net/sock.h> | ||
94 | |||
95 | struct ipx_sock { | ||
96 | /* struct sock has to be the first member of ipx_sock */ | ||
97 | struct sock sk; | ||
98 | struct ipx_address dest_addr; | ||
99 | struct ipx_interface *intrfc; | ||
100 | unsigned short port; | ||
101 | #ifdef CONFIG_IPX_INTERN | ||
102 | unsigned char node[IPX_NODE_LEN]; | ||
103 | #endif | ||
104 | unsigned short type; | ||
105 | /* | ||
106 | * To handle special ncp connection-handling sockets for mars_nwe, | ||
107 | * the connection number must be stored in the socket. | ||
108 | */ | ||
109 | unsigned short ipx_ncp_conn; | ||
110 | }; | ||
111 | |||
112 | static inline struct ipx_sock *ipx_sk(struct sock *sk) | ||
113 | { | ||
114 | return (struct ipx_sock *)sk; | ||
115 | } | ||
116 | |||
117 | #define IPX_SKB_CB(__skb) ((struct ipx_cb *)&((__skb)->cb[0])) | ||
118 | #endif | ||
119 | |||
120 | #define IPX_MIN_EPHEMERAL_SOCKET 0x4000 | ||
121 | #define IPX_MAX_EPHEMERAL_SOCKET 0x7fff | ||
122 | |||
123 | extern struct list_head ipx_routes; | ||
124 | extern rwlock_t ipx_routes_lock; | ||
125 | |||
126 | extern struct list_head ipx_interfaces; | ||
127 | extern struct ipx_interface *ipx_interfaces_head(void); | ||
128 | extern spinlock_t ipx_interfaces_lock; | ||
129 | |||
130 | extern struct ipx_interface *ipx_primary_net; | ||
131 | |||
132 | extern int ipx_proc_init(void); | ||
133 | extern void ipx_proc_exit(void); | ||
134 | |||
135 | extern const char *ipx_frame_name(unsigned short); | ||
136 | extern const char *ipx_device_name(struct ipx_interface *intrfc); | ||
137 | |||
138 | static __inline__ void ipxitf_hold(struct ipx_interface *intrfc) | ||
139 | { | ||
140 | atomic_inc(&intrfc->refcnt); | ||
141 | } | ||
142 | |||
143 | extern void ipxitf_down(struct ipx_interface *intrfc); | ||
144 | |||
145 | static __inline__ void ipxitf_put(struct ipx_interface *intrfc) | ||
146 | { | ||
147 | if (atomic_dec_and_test(&intrfc->refcnt)) | ||
148 | ipxitf_down(intrfc); | ||
149 | } | ||
150 | |||
151 | static __inline__ void ipxrtr_hold(struct ipx_route *rt) | ||
152 | { | ||
153 | atomic_inc(&rt->refcnt); | ||
154 | } | ||
155 | |||
156 | static __inline__ void ipxrtr_put(struct ipx_route *rt) | ||
157 | { | ||
158 | if (atomic_dec_and_test(&rt->refcnt)) | ||
159 | kfree(rt); | ||
160 | } | ||
161 | #endif /* _NET_INET_IPX_H_ */ | ||
diff --git a/include/net/irda/af_irda.h b/include/net/irda/af_irda.h new file mode 100644 index 000000000000..7a209f61c482 --- /dev/null +++ b/include/net/irda/af_irda.h | |||
@@ -0,0 +1,87 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: af_irda.h | ||
4 | * Version: 1.0 | ||
5 | * Description: IrDA sockets declarations | ||
6 | * Status: Stable | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Tue Dec 9 21:13:12 1997 | ||
9 | * Modified at: Fri Jan 28 13:16:32 2000 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved. | ||
13 | * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com> | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License as | ||
17 | * published by the Free Software Foundation; either version 2 of | ||
18 | * the License, or (at your option) any later version. | ||
19 | * | ||
20 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
21 | * provide warranty for any of this software. This material is | ||
22 | * provided "AS-IS" and at no charge. | ||
23 | * | ||
24 | ********************************************************************/ | ||
25 | |||
26 | #ifndef AF_IRDA_H | ||
27 | #define AF_IRDA_H | ||
28 | |||
29 | #include <linux/irda.h> | ||
30 | #include <net/irda/irda.h> | ||
31 | #include <net/irda/iriap.h> /* struct iriap_cb */ | ||
32 | #include <net/irda/irias_object.h> /* struct ias_value */ | ||
33 | #include <net/irda/irlmp.h> /* struct lsap_cb */ | ||
34 | #include <net/irda/irttp.h> /* struct tsap_cb */ | ||
35 | #include <net/irda/discovery.h> /* struct discovery_t */ | ||
36 | #include <net/sock.h> | ||
37 | |||
38 | /* IrDA Socket */ | ||
39 | struct irda_sock { | ||
40 | /* struct sock has to be the first member of irda_sock */ | ||
41 | struct sock sk; | ||
42 | __u32 saddr; /* my local address */ | ||
43 | __u32 daddr; /* peer address */ | ||
44 | |||
45 | struct lsap_cb *lsap; /* LSAP used by Ultra */ | ||
46 | __u8 pid; /* Protocol IP (PID) used by Ultra */ | ||
47 | |||
48 | struct tsap_cb *tsap; /* TSAP used by this connection */ | ||
49 | __u8 dtsap_sel; /* remote TSAP address */ | ||
50 | __u8 stsap_sel; /* local TSAP address */ | ||
51 | |||
52 | __u32 max_sdu_size_rx; | ||
53 | __u32 max_sdu_size_tx; | ||
54 | __u32 max_data_size; | ||
55 | __u8 max_header_size; | ||
56 | struct qos_info qos_tx; | ||
57 | |||
58 | __u16_host_order mask; /* Hint bits mask */ | ||
59 | __u16_host_order hints; /* Hint bits */ | ||
60 | |||
61 | void *ckey; /* IrLMP client handle */ | ||
62 | void *skey; /* IrLMP service handle */ | ||
63 | |||
64 | struct ias_object *ias_obj; /* Our service name + lsap in IAS */ | ||
65 | struct iriap_cb *iriap; /* Used to query remote IAS */ | ||
66 | struct ias_value *ias_result; /* Result of remote IAS query */ | ||
67 | |||
68 | hashbin_t *cachelog; /* Result of discovery query */ | ||
69 | __u32 cachedaddr; /* Result of selective discovery query */ | ||
70 | |||
71 | int nslots; /* Number of slots to use for discovery */ | ||
72 | |||
73 | int errno; /* status of the IAS query */ | ||
74 | |||
75 | wait_queue_head_t query_wait; /* Wait for the answer to a query */ | ||
76 | struct timer_list watchdog; /* Timeout for discovery */ | ||
77 | |||
78 | LOCAL_FLOW tx_flow; | ||
79 | LOCAL_FLOW rx_flow; | ||
80 | }; | ||
81 | |||
82 | static inline struct irda_sock *irda_sk(struct sock *sk) | ||
83 | { | ||
84 | return (struct irda_sock *)sk; | ||
85 | } | ||
86 | |||
87 | #endif /* AF_IRDA_H */ | ||
diff --git a/include/net/irda/crc.h b/include/net/irda/crc.h new file mode 100644 index 000000000000..f202296df9bb --- /dev/null +++ b/include/net/irda/crc.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: crc.h | ||
4 | * Version: | ||
5 | * Description: CRC routines | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Mon Aug 4 20:40:53 1997 | ||
9 | * Modified at: Sun May 2 20:25:23 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | ********************************************************************/ | ||
13 | |||
14 | #ifndef IRDA_CRC_H | ||
15 | #define IRDA_CRC_H | ||
16 | |||
17 | #include <linux/types.h> | ||
18 | #include <linux/crc-ccitt.h> | ||
19 | |||
20 | #define INIT_FCS 0xffff /* Initial FCS value */ | ||
21 | #define GOOD_FCS 0xf0b8 /* Good final FCS value */ | ||
22 | |||
23 | /* Recompute the FCS with one more character appended. */ | ||
24 | #define irda_fcs(fcs, c) crc_ccitt_byte(fcs, c) | ||
25 | |||
26 | /* Recompute the FCS with len bytes appended. */ | ||
27 | #define irda_calc_crc16(fcs, buf, len) crc_ccitt(fcs, buf, len) | ||
28 | |||
29 | #endif | ||
diff --git a/include/net/irda/discovery.h b/include/net/irda/discovery.h new file mode 100644 index 000000000000..eb0f9de47294 --- /dev/null +++ b/include/net/irda/discovery.h | |||
@@ -0,0 +1,100 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: discovery.h | ||
4 | * Version: | ||
5 | * Description: | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Tue Apr 6 16:53:53 1999 | ||
9 | * Modified at: Tue Oct 5 10:05:10 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1999 Dag Brattli, All Rights Reserved. | ||
13 | * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com> | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License as | ||
17 | * published by the Free Software Foundation; either version 2 of | ||
18 | * the License, or (at your option) any later version. | ||
19 | * | ||
20 | * This program is distributed in the hope that it will be useful, | ||
21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
23 | * GNU General Public License for more details. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License | ||
26 | * along with this program; if not, write to the Free Software | ||
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
28 | * MA 02111-1307 USA | ||
29 | * | ||
30 | ********************************************************************/ | ||
31 | |||
32 | #ifndef DISCOVERY_H | ||
33 | #define DISCOVERY_H | ||
34 | |||
35 | #include <asm/param.h> | ||
36 | |||
37 | #include <net/irda/irda.h> | ||
38 | #include <net/irda/irqueue.h> /* irda_queue_t */ | ||
39 | #include <net/irda/irlap_event.h> /* LAP_REASON */ | ||
40 | |||
41 | #define DISCOVERY_EXPIRE_TIMEOUT (2*sysctl_discovery_timeout*HZ) | ||
42 | #define DISCOVERY_DEFAULT_SLOTS 0 | ||
43 | |||
44 | /* | ||
45 | * This type is used by the protocols that transmit 16 bits words in | ||
46 | * little endian format. A little endian machine stores MSB of word in | ||
47 | * byte[1] and LSB in byte[0]. A big endian machine stores MSB in byte[0] | ||
48 | * and LSB in byte[1]. | ||
49 | * | ||
50 | * This structure is used in the code for things that are endian neutral | ||
51 | * but that fit in a word so that we can manipulate them efficiently. | ||
52 | * By endian neutral, I mean things that are really an array of bytes, | ||
53 | * and always used as such, for example the hint bits. Jean II | ||
54 | */ | ||
55 | typedef union { | ||
56 | __u16 word; | ||
57 | __u8 byte[2]; | ||
58 | } __u16_host_order; | ||
59 | |||
60 | /* Same purpose, different application */ | ||
61 | #define u16ho(array) (* ((__u16 *) array)) | ||
62 | |||
63 | /* Types of discovery */ | ||
64 | typedef enum { | ||
65 | DISCOVERY_LOG, /* What's in our discovery log */ | ||
66 | DISCOVERY_ACTIVE, /* Doing our own discovery on the medium */ | ||
67 | DISCOVERY_PASSIVE, /* Peer doing discovery on the medium */ | ||
68 | EXPIRY_TIMEOUT, /* Entry expired due to timeout */ | ||
69 | } DISCOVERY_MODE; | ||
70 | |||
71 | #define NICKNAME_MAX_LEN 21 | ||
72 | |||
73 | /* Basic discovery information about a peer */ | ||
74 | typedef struct irda_device_info discinfo_t; /* linux/irda.h */ | ||
75 | |||
76 | /* | ||
77 | * The DISCOVERY structure is used for both discovery requests and responses | ||
78 | */ | ||
79 | typedef struct discovery_t { | ||
80 | irda_queue_t q; /* Must be first! */ | ||
81 | |||
82 | discinfo_t data; /* Basic discovery information */ | ||
83 | int name_len; /* Lenght of nickname */ | ||
84 | |||
85 | LAP_REASON condition; /* More info about the discovery */ | ||
86 | int gen_addr_bit; /* Need to generate a new device | ||
87 | * address? */ | ||
88 | int nslots; /* Number of slots to use when | ||
89 | * discovering */ | ||
90 | unsigned long timestamp; /* Last time discovered */ | ||
91 | unsigned long firststamp; /* First time discovered */ | ||
92 | } discovery_t; | ||
93 | |||
94 | void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *discovery); | ||
95 | void irlmp_add_discovery_log(hashbin_t *cachelog, hashbin_t *log); | ||
96 | void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force); | ||
97 | struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn, | ||
98 | __u16 mask, int old_entries); | ||
99 | |||
100 | #endif | ||
diff --git a/include/net/irda/ircomm_core.h b/include/net/irda/ircomm_core.h new file mode 100644 index 000000000000..69b610acd2df --- /dev/null +++ b/include/net/irda/ircomm_core.h | |||
@@ -0,0 +1,108 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: ircomm_core.h | ||
4 | * Version: | ||
5 | * Description: | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Wed Jun 9 08:58:43 1999 | ||
9 | * Modified at: Mon Dec 13 11:52:29 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1999 Dag Brattli, All Rights Reserved. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
27 | * MA 02111-1307 USA | ||
28 | * | ||
29 | ********************************************************************/ | ||
30 | |||
31 | #ifndef IRCOMM_CORE_H | ||
32 | #define IRCOMM_CORE_H | ||
33 | |||
34 | #include <net/irda/irda.h> | ||
35 | #include <net/irda/irqueue.h> | ||
36 | #include <net/irda/ircomm_event.h> | ||
37 | |||
38 | #define IRCOMM_MAGIC 0x98347298 | ||
39 | #define IRCOMM_HEADER_SIZE 1 | ||
40 | |||
41 | struct ircomm_cb; /* Forward decl. */ | ||
42 | |||
43 | /* | ||
44 | * A small call-table, so we don't have to check the service-type whenever | ||
45 | * we want to do something | ||
46 | */ | ||
47 | typedef struct { | ||
48 | int (*data_request)(struct ircomm_cb *, struct sk_buff *, int clen); | ||
49 | int (*connect_request)(struct ircomm_cb *, struct sk_buff *, | ||
50 | struct ircomm_info *); | ||
51 | int (*connect_response)(struct ircomm_cb *, struct sk_buff *); | ||
52 | int (*disconnect_request)(struct ircomm_cb *, struct sk_buff *, | ||
53 | struct ircomm_info *); | ||
54 | } call_t; | ||
55 | |||
56 | struct ircomm_cb { | ||
57 | irda_queue_t queue; | ||
58 | magic_t magic; | ||
59 | |||
60 | notify_t notify; | ||
61 | call_t issue; | ||
62 | |||
63 | int state; | ||
64 | int line; /* Which TTY line we are using */ | ||
65 | |||
66 | struct tsap_cb *tsap; | ||
67 | struct lsap_cb *lsap; | ||
68 | |||
69 | __u8 dlsap_sel; /* Destination LSAP/TSAP selector */ | ||
70 | __u8 slsap_sel; /* Source LSAP/TSAP selector */ | ||
71 | |||
72 | __u32 saddr; /* Source device address (link we are using) */ | ||
73 | __u32 daddr; /* Destination device address */ | ||
74 | |||
75 | int max_header_size; /* Header space we must reserve for each frame */ | ||
76 | int max_data_size; /* The amount of data we can fill in each frame */ | ||
77 | |||
78 | LOCAL_FLOW flow_status; /* Used by ircomm_lmp */ | ||
79 | int pkt_count; /* Number of frames we have sent to IrLAP */ | ||
80 | |||
81 | __u8 service_type; | ||
82 | }; | ||
83 | |||
84 | extern hashbin_t *ircomm; | ||
85 | |||
86 | struct ircomm_cb *ircomm_open(notify_t *notify, __u8 service_type, int line); | ||
87 | int ircomm_close(struct ircomm_cb *self); | ||
88 | |||
89 | int ircomm_data_request(struct ircomm_cb *self, struct sk_buff *skb); | ||
90 | void ircomm_data_indication(struct ircomm_cb *self, struct sk_buff *skb); | ||
91 | void ircomm_process_data(struct ircomm_cb *self, struct sk_buff *skb); | ||
92 | int ircomm_control_request(struct ircomm_cb *self, struct sk_buff *skb); | ||
93 | int ircomm_connect_request(struct ircomm_cb *self, __u8 dlsap_sel, | ||
94 | __u32 saddr, __u32 daddr, struct sk_buff *skb, | ||
95 | __u8 service_type); | ||
96 | void ircomm_connect_indication(struct ircomm_cb *self, struct sk_buff *skb, | ||
97 | struct ircomm_info *info); | ||
98 | void ircomm_connect_confirm(struct ircomm_cb *self, struct sk_buff *skb, | ||
99 | struct ircomm_info *info); | ||
100 | int ircomm_connect_response(struct ircomm_cb *self, struct sk_buff *userdata); | ||
101 | int ircomm_disconnect_request(struct ircomm_cb *self, struct sk_buff *userdata); | ||
102 | void ircomm_disconnect_indication(struct ircomm_cb *self, struct sk_buff *skb, | ||
103 | struct ircomm_info *info); | ||
104 | void ircomm_flow_request(struct ircomm_cb *self, LOCAL_FLOW flow); | ||
105 | |||
106 | #define ircomm_is_connected(self) (self->state == IRCOMM_CONN) | ||
107 | |||
108 | #endif | ||
diff --git a/include/net/irda/ircomm_event.h b/include/net/irda/ircomm_event.h new file mode 100644 index 000000000000..c290447872d1 --- /dev/null +++ b/include/net/irda/ircomm_event.h | |||
@@ -0,0 +1,85 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: ircomm_event.h | ||
4 | * Version: | ||
5 | * Description: | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Sun Jun 6 23:51:13 1999 | ||
9 | * Modified at: Thu Jun 10 08:36:25 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1999 Dag Brattli, All Rights Reserved. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
27 | * MA 02111-1307 USA | ||
28 | * | ||
29 | ********************************************************************/ | ||
30 | |||
31 | #ifndef IRCOMM_EVENT_H | ||
32 | #define IRCOMM_EVENT_H | ||
33 | |||
34 | #include <net/irda/irmod.h> | ||
35 | |||
36 | typedef enum { | ||
37 | IRCOMM_IDLE, | ||
38 | IRCOMM_WAITI, | ||
39 | IRCOMM_WAITR, | ||
40 | IRCOMM_CONN, | ||
41 | } IRCOMM_STATE; | ||
42 | |||
43 | /* IrCOMM Events */ | ||
44 | typedef enum { | ||
45 | IRCOMM_CONNECT_REQUEST, | ||
46 | IRCOMM_CONNECT_RESPONSE, | ||
47 | IRCOMM_TTP_CONNECT_INDICATION, | ||
48 | IRCOMM_LMP_CONNECT_INDICATION, | ||
49 | IRCOMM_TTP_CONNECT_CONFIRM, | ||
50 | IRCOMM_LMP_CONNECT_CONFIRM, | ||
51 | |||
52 | IRCOMM_LMP_DISCONNECT_INDICATION, | ||
53 | IRCOMM_TTP_DISCONNECT_INDICATION, | ||
54 | IRCOMM_DISCONNECT_REQUEST, | ||
55 | |||
56 | IRCOMM_TTP_DATA_INDICATION, | ||
57 | IRCOMM_LMP_DATA_INDICATION, | ||
58 | IRCOMM_DATA_REQUEST, | ||
59 | IRCOMM_CONTROL_REQUEST, | ||
60 | IRCOMM_CONTROL_INDICATION, | ||
61 | } IRCOMM_EVENT; | ||
62 | |||
63 | /* | ||
64 | * Used for passing information through the state-machine | ||
65 | */ | ||
66 | struct ircomm_info { | ||
67 | __u32 saddr; /* Source device address */ | ||
68 | __u32 daddr; /* Destination device address */ | ||
69 | __u8 dlsap_sel; | ||
70 | LM_REASON reason; /* Reason for disconnect */ | ||
71 | __u32 max_data_size; | ||
72 | __u32 max_header_size; | ||
73 | |||
74 | struct qos_info *qos; | ||
75 | }; | ||
76 | |||
77 | extern char *ircomm_state[]; | ||
78 | |||
79 | struct ircomm_cb; /* Forward decl. */ | ||
80 | |||
81 | int ircomm_do_event(struct ircomm_cb *self, IRCOMM_EVENT event, | ||
82 | struct sk_buff *skb, struct ircomm_info *info); | ||
83 | void ircomm_next_state(struct ircomm_cb *self, IRCOMM_STATE state); | ||
84 | |||
85 | #endif | ||
diff --git a/include/net/irda/ircomm_lmp.h b/include/net/irda/ircomm_lmp.h new file mode 100644 index 000000000000..ae02106be590 --- /dev/null +++ b/include/net/irda/ircomm_lmp.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: ircomm_lmp.h | ||
4 | * Version: | ||
5 | * Description: | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Wed Jun 9 10:06:07 1999 | ||
9 | * Modified at: Fri Aug 13 07:32:32 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1999 Dag Brattli, All Rights Reserved. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
27 | * MA 02111-1307 USA | ||
28 | * | ||
29 | ********************************************************************/ | ||
30 | |||
31 | #ifndef IRCOMM_LMP_H | ||
32 | #define IRCOMM_LMP_H | ||
33 | |||
34 | #include <net/irda/ircomm_core.h> | ||
35 | |||
36 | int ircomm_open_lsap(struct ircomm_cb *self); | ||
37 | |||
38 | #endif | ||
diff --git a/include/net/irda/ircomm_param.h b/include/net/irda/ircomm_param.h new file mode 100644 index 000000000000..e6678800c41f --- /dev/null +++ b/include/net/irda/ircomm_param.h | |||
@@ -0,0 +1,149 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: ircomm_param.h | ||
4 | * Version: 1.0 | ||
5 | * Description: Parameter handling for the IrCOMM protocol | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Mon Jun 7 08:47:28 1999 | ||
9 | * Modified at: Wed Aug 25 13:46:33 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1999 Dag Brattli, All Rights Reserved. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
27 | * MA 02111-1307 USA | ||
28 | * | ||
29 | ********************************************************************/ | ||
30 | |||
31 | #ifndef IRCOMM_PARAMS_H | ||
32 | #define IRCOMM_PARAMS_H | ||
33 | |||
34 | #include <net/irda/parameters.h> | ||
35 | |||
36 | /* Parameters common to all service types */ | ||
37 | #define IRCOMM_SERVICE_TYPE 0x00 | ||
38 | #define IRCOMM_PORT_TYPE 0x01 /* Only used in LM-IAS */ | ||
39 | #define IRCOMM_PORT_NAME 0x02 /* Only used in LM-IAS */ | ||
40 | |||
41 | /* Parameters for both 3 wire and 9 wire */ | ||
42 | #define IRCOMM_DATA_RATE 0x10 | ||
43 | #define IRCOMM_DATA_FORMAT 0x11 | ||
44 | #define IRCOMM_FLOW_CONTROL 0x12 | ||
45 | #define IRCOMM_XON_XOFF 0x13 | ||
46 | #define IRCOMM_ENQ_ACK 0x14 | ||
47 | #define IRCOMM_LINE_STATUS 0x15 | ||
48 | #define IRCOMM_BREAK 0x16 | ||
49 | |||
50 | /* Parameters for 9 wire */ | ||
51 | #define IRCOMM_DTE 0x20 | ||
52 | #define IRCOMM_DCE 0x21 | ||
53 | #define IRCOMM_POLL 0x22 | ||
54 | |||
55 | /* Service type (details) */ | ||
56 | #define IRCOMM_3_WIRE_RAW 0x01 | ||
57 | #define IRCOMM_3_WIRE 0x02 | ||
58 | #define IRCOMM_9_WIRE 0x04 | ||
59 | #define IRCOMM_CENTRONICS 0x08 | ||
60 | |||
61 | /* Port type (details) */ | ||
62 | #define IRCOMM_SERIAL 0x00 | ||
63 | #define IRCOMM_PARALLEL 0x01 | ||
64 | |||
65 | /* Data format (details) */ | ||
66 | #define IRCOMM_WSIZE_5 0x00 | ||
67 | #define IRCOMM_WSIZE_6 0x01 | ||
68 | #define IRCOMM_WSIZE_7 0x02 | ||
69 | #define IRCOMM_WSIZE_8 0x03 | ||
70 | |||
71 | #define IRCOMM_1_STOP_BIT 0x00 | ||
72 | #define IRCOMM_2_STOP_BIT 0x04 /* 1.5 if char len 5 */ | ||
73 | |||
74 | #define IRCOMM_PARITY_DISABLE 0x00 | ||
75 | #define IRCOMM_PARITY_ENABLE 0x08 | ||
76 | |||
77 | #define IRCOMM_PARITY_ODD 0x00 | ||
78 | #define IRCOMM_PARITY_EVEN 0x10 | ||
79 | #define IRCOMM_PARITY_MARK 0x20 | ||
80 | #define IRCOMM_PARITY_SPACE 0x30 | ||
81 | |||
82 | /* Flow control */ | ||
83 | #define IRCOMM_XON_XOFF_IN 0x01 | ||
84 | #define IRCOMM_XON_XOFF_OUT 0x02 | ||
85 | #define IRCOMM_RTS_CTS_IN 0x04 | ||
86 | #define IRCOMM_RTS_CTS_OUT 0x08 | ||
87 | #define IRCOMM_DSR_DTR_IN 0x10 | ||
88 | #define IRCOMM_DSR_DTR_OUT 0x20 | ||
89 | #define IRCOMM_ENQ_ACK_IN 0x40 | ||
90 | #define IRCOMM_ENQ_ACK_OUT 0x80 | ||
91 | |||
92 | /* Line status */ | ||
93 | #define IRCOMM_OVERRUN_ERROR 0x02 | ||
94 | #define IRCOMM_PARITY_ERROR 0x04 | ||
95 | #define IRCOMM_FRAMING_ERROR 0x08 | ||
96 | |||
97 | /* DTE (Data terminal equipment) line settings */ | ||
98 | #define IRCOMM_DELTA_DTR 0x01 | ||
99 | #define IRCOMM_DELTA_RTS 0x02 | ||
100 | #define IRCOMM_DTR 0x04 | ||
101 | #define IRCOMM_RTS 0x08 | ||
102 | |||
103 | /* DCE (Data communications equipment) line settings */ | ||
104 | #define IRCOMM_DELTA_CTS 0x01 /* Clear to send has changed */ | ||
105 | #define IRCOMM_DELTA_DSR 0x02 /* Data set ready has changed */ | ||
106 | #define IRCOMM_DELTA_RI 0x04 /* Ring indicator has changed */ | ||
107 | #define IRCOMM_DELTA_CD 0x08 /* Carrier detect has changed */ | ||
108 | #define IRCOMM_CTS 0x10 /* Clear to send is high */ | ||
109 | #define IRCOMM_DSR 0x20 /* Data set ready is high */ | ||
110 | #define IRCOMM_RI 0x40 /* Ring indicator is high */ | ||
111 | #define IRCOMM_CD 0x80 /* Carrier detect is high */ | ||
112 | #define IRCOMM_DCE_DELTA_ANY 0x0f | ||
113 | |||
114 | /* | ||
115 | * Parameter state | ||
116 | */ | ||
117 | struct ircomm_params { | ||
118 | /* General control params */ | ||
119 | __u8 service_type; | ||
120 | __u8 port_type; | ||
121 | char port_name[32]; | ||
122 | |||
123 | /* Control params for 3- and 9-wire service type */ | ||
124 | __u32 data_rate; /* Data rate in bps */ | ||
125 | __u8 data_format; | ||
126 | __u8 flow_control; | ||
127 | char xonxoff[2]; | ||
128 | char enqack[2]; | ||
129 | __u8 line_status; | ||
130 | __u8 _break; | ||
131 | |||
132 | __u8 null_modem; | ||
133 | |||
134 | /* Control params for 9-wire service type */ | ||
135 | __u8 dte; | ||
136 | __u8 dce; | ||
137 | __u8 poll; | ||
138 | |||
139 | /* Control params for Centronics service type */ | ||
140 | }; | ||
141 | |||
142 | struct ircomm_tty_cb; /* Forward decl. */ | ||
143 | |||
144 | int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush); | ||
145 | |||
146 | extern pi_param_info_t ircomm_param_info; | ||
147 | |||
148 | #endif /* IRCOMM_PARAMS_H */ | ||
149 | |||
diff --git a/include/net/irda/ircomm_ttp.h b/include/net/irda/ircomm_ttp.h new file mode 100644 index 000000000000..403081ed725c --- /dev/null +++ b/include/net/irda/ircomm_ttp.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: ircomm_ttp.h | ||
4 | * Version: | ||
5 | * Description: | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Wed Jun 9 10:06:07 1999 | ||
9 | * Modified at: Fri Aug 13 07:32:22 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1999 Dag Brattli, All Rights Reserved. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
27 | * MA 02111-1307 USA | ||
28 | * | ||
29 | ********************************************************************/ | ||
30 | |||
31 | #ifndef IRCOMM_TTP_H | ||
32 | #define IRCOMM_TTP_H | ||
33 | |||
34 | #include <net/irda/ircomm_core.h> | ||
35 | |||
36 | int ircomm_open_tsap(struct ircomm_cb *self); | ||
37 | |||
38 | #endif | ||
39 | |||
diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h new file mode 100644 index 000000000000..87699cb4ef8c --- /dev/null +++ b/include/net/irda/ircomm_tty.h | |||
@@ -0,0 +1,139 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: ircomm_tty.h | ||
4 | * Version: | ||
5 | * Description: | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Sun Jun 6 23:24:22 1999 | ||
9 | * Modified at: Fri Jan 28 13:16:57 2000 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
27 | * MA 02111-1307 USA | ||
28 | * | ||
29 | ********************************************************************/ | ||
30 | |||
31 | #ifndef IRCOMM_TTY_H | ||
32 | #define IRCOMM_TTY_H | ||
33 | |||
34 | #include <linux/serial.h> | ||
35 | #include <linux/termios.h> | ||
36 | #include <linux/timer.h> | ||
37 | #include <linux/tty.h> /* struct tty_struct */ | ||
38 | |||
39 | #include <net/irda/irias_object.h> | ||
40 | #include <net/irda/ircomm_core.h> | ||
41 | #include <net/irda/ircomm_param.h> | ||
42 | |||
43 | #define IRCOMM_TTY_PORTS 32 | ||
44 | #define IRCOMM_TTY_MAGIC 0x3432 | ||
45 | #define IRCOMM_TTY_MAJOR 161 | ||
46 | #define IRCOMM_TTY_MINOR 0 | ||
47 | |||
48 | /* This is used as an initial value to max_header_size before the proper | ||
49 | * value is filled in (5 for ttp, 4 for lmp). This allow us to detect | ||
50 | * the state of the underlying connection. - Jean II */ | ||
51 | #define IRCOMM_TTY_HDR_UNINITIALISED 16 | ||
52 | /* Same for payload size. See qos.c for the smallest max data size */ | ||
53 | #define IRCOMM_TTY_DATA_UNINITIALISED (64 - IRCOMM_TTY_HDR_UNINITIALISED) | ||
54 | |||
55 | /* Those are really defined in include/linux/serial.h - Jean II */ | ||
56 | #define ASYNC_B_INITIALIZED 31 /* Serial port was initialized */ | ||
57 | #define ASYNC_B_NORMAL_ACTIVE 29 /* Normal device is active */ | ||
58 | #define ASYNC_B_CLOSING 27 /* Serial port is closing */ | ||
59 | |||
60 | /* | ||
61 | * IrCOMM TTY driver state | ||
62 | */ | ||
63 | struct ircomm_tty_cb { | ||
64 | irda_queue_t queue; /* Must be first */ | ||
65 | magic_t magic; | ||
66 | |||
67 | int state; /* Connect state */ | ||
68 | |||
69 | struct tty_struct *tty; | ||
70 | struct ircomm_cb *ircomm; /* IrCOMM layer instance */ | ||
71 | |||
72 | struct sk_buff *tx_skb; /* Transmit buffer */ | ||
73 | struct sk_buff *ctrl_skb; /* Control data buffer */ | ||
74 | |||
75 | /* Parameters */ | ||
76 | struct ircomm_params settings; | ||
77 | |||
78 | __u8 service_type; /* The service that we support */ | ||
79 | int client; /* True if we are a client */ | ||
80 | LOCAL_FLOW flow; /* IrTTP flow status */ | ||
81 | |||
82 | int line; | ||
83 | unsigned long flags; | ||
84 | |||
85 | __u8 dlsap_sel; | ||
86 | __u8 slsap_sel; | ||
87 | |||
88 | __u32 saddr; | ||
89 | __u32 daddr; | ||
90 | |||
91 | __u32 max_data_size; /* Max data we can transmit in one packet */ | ||
92 | __u32 max_header_size; /* The amount of header space we must reserve */ | ||
93 | __u32 tx_data_size; /* Max data size of current tx_skb */ | ||
94 | |||
95 | struct iriap_cb *iriap; /* Instance used for querying remote IAS */ | ||
96 | struct ias_object* obj; | ||
97 | void *skey; | ||
98 | void *ckey; | ||
99 | |||
100 | wait_queue_head_t open_wait; | ||
101 | wait_queue_head_t close_wait; | ||
102 | struct timer_list watchdog_timer; | ||
103 | struct work_struct tqueue; | ||
104 | |||
105 | unsigned short close_delay; | ||
106 | unsigned short closing_wait; /* time to wait before closing */ | ||
107 | |||
108 | int open_count; | ||
109 | int blocked_open; /* # of blocked opens */ | ||
110 | |||
111 | /* Protect concurent access to : | ||
112 | * o self->open_count | ||
113 | * o self->ctrl_skb | ||
114 | * o self->tx_skb | ||
115 | * Maybe other things may gain to be protected as well... | ||
116 | * Jean II */ | ||
117 | spinlock_t spinlock; | ||
118 | }; | ||
119 | |||
120 | void ircomm_tty_start(struct tty_struct *tty); | ||
121 | void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self); | ||
122 | |||
123 | extern int ircomm_tty_tiocmget(struct tty_struct *tty, struct file *file); | ||
124 | extern int ircomm_tty_tiocmset(struct tty_struct *tty, struct file *file, | ||
125 | unsigned int set, unsigned int clear); | ||
126 | extern int ircomm_tty_ioctl(struct tty_struct *tty, struct file *file, | ||
127 | unsigned int cmd, unsigned long arg); | ||
128 | extern void ircomm_tty_set_termios(struct tty_struct *tty, | ||
129 | struct termios *old_termios); | ||
130 | extern hashbin_t *ircomm_tty; | ||
131 | |||
132 | #endif | ||
133 | |||
134 | |||
135 | |||
136 | |||
137 | |||
138 | |||
139 | |||
diff --git a/include/net/irda/ircomm_tty_attach.h b/include/net/irda/ircomm_tty_attach.h new file mode 100644 index 000000000000..f91a5695aa44 --- /dev/null +++ b/include/net/irda/ircomm_tty_attach.h | |||
@@ -0,0 +1,94 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: ircomm_tty_attach.h | ||
4 | * Version: | ||
5 | * Description: | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Wed Jun 9 15:55:18 1999 | ||
9 | * Modified at: Fri Dec 10 21:04:55 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1999 Dag Brattli, All Rights Reserved. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
27 | * MA 02111-1307 USA | ||
28 | * | ||
29 | ********************************************************************/ | ||
30 | |||
31 | #ifndef IRCOMM_TTY_ATTACH_H | ||
32 | #define IRCOMM_TTY_ATTACH_H | ||
33 | |||
34 | #include <net/irda/ircomm_tty.h> | ||
35 | |||
36 | typedef enum { | ||
37 | IRCOMM_TTY_IDLE, | ||
38 | IRCOMM_TTY_SEARCH, | ||
39 | IRCOMM_TTY_QUERY_PARAMETERS, | ||
40 | IRCOMM_TTY_QUERY_LSAP_SEL, | ||
41 | IRCOMM_TTY_SETUP, | ||
42 | IRCOMM_TTY_READY, | ||
43 | } IRCOMM_TTY_STATE; | ||
44 | |||
45 | /* IrCOMM TTY Events */ | ||
46 | typedef enum { | ||
47 | IRCOMM_TTY_ATTACH_CABLE, | ||
48 | IRCOMM_TTY_DETACH_CABLE, | ||
49 | IRCOMM_TTY_DATA_REQUEST, | ||
50 | IRCOMM_TTY_DATA_INDICATION, | ||
51 | IRCOMM_TTY_DISCOVERY_REQUEST, | ||
52 | IRCOMM_TTY_DISCOVERY_INDICATION, | ||
53 | IRCOMM_TTY_CONNECT_CONFIRM, | ||
54 | IRCOMM_TTY_CONNECT_INDICATION, | ||
55 | IRCOMM_TTY_DISCONNECT_REQUEST, | ||
56 | IRCOMM_TTY_DISCONNECT_INDICATION, | ||
57 | IRCOMM_TTY_WD_TIMER_EXPIRED, | ||
58 | IRCOMM_TTY_GOT_PARAMETERS, | ||
59 | IRCOMM_TTY_GOT_LSAPSEL, | ||
60 | } IRCOMM_TTY_EVENT; | ||
61 | |||
62 | /* Used for passing information through the state-machine */ | ||
63 | struct ircomm_tty_info { | ||
64 | __u32 saddr; /* Source device address */ | ||
65 | __u32 daddr; /* Destination device address */ | ||
66 | __u8 dlsap_sel; | ||
67 | }; | ||
68 | |||
69 | extern char *ircomm_state[]; | ||
70 | extern char *ircomm_tty_state[]; | ||
71 | |||
72 | int ircomm_tty_do_event(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event, | ||
73 | struct sk_buff *skb, struct ircomm_tty_info *info); | ||
74 | |||
75 | |||
76 | int ircomm_tty_attach_cable(struct ircomm_tty_cb *self); | ||
77 | void ircomm_tty_detach_cable(struct ircomm_tty_cb *self); | ||
78 | void ircomm_tty_connect_confirm(void *instance, void *sap, | ||
79 | struct qos_info *qos, | ||
80 | __u32 max_sdu_size, | ||
81 | __u8 max_header_size, | ||
82 | struct sk_buff *skb); | ||
83 | void ircomm_tty_disconnect_indication(void *instance, void *sap, | ||
84 | LM_REASON reason, | ||
85 | struct sk_buff *skb); | ||
86 | void ircomm_tty_connect_indication(void *instance, void *sap, | ||
87 | struct qos_info *qos, | ||
88 | __u32 max_sdu_size, | ||
89 | __u8 max_header_size, | ||
90 | struct sk_buff *skb); | ||
91 | int ircomm_tty_send_initial_parameters(struct ircomm_tty_cb *self); | ||
92 | void ircomm_tty_link_established(struct ircomm_tty_cb *self); | ||
93 | |||
94 | #endif /* IRCOMM_TTY_ATTACH_H */ | ||
diff --git a/include/net/irda/irda.h b/include/net/irda/irda.h new file mode 100644 index 000000000000..05a840837fe7 --- /dev/null +++ b/include/net/irda/irda.h | |||
@@ -0,0 +1,117 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irda.h | ||
4 | * Version: 1.0 | ||
5 | * Description: IrDA common include file for kernel internal use | ||
6 | * Status: Stable | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Tue Dec 9 21:13:12 1997 | ||
9 | * Modified at: Fri Jan 28 13:16:32 2000 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved. | ||
13 | * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com> | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License as | ||
17 | * published by the Free Software Foundation; either version 2 of | ||
18 | * the License, or (at your option) any later version. | ||
19 | * | ||
20 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
21 | * provide warranty for any of this software. This material is | ||
22 | * provided "AS-IS" and at no charge. | ||
23 | * | ||
24 | ********************************************************************/ | ||
25 | |||
26 | #ifndef NET_IRDA_H | ||
27 | #define NET_IRDA_H | ||
28 | |||
29 | #include <linux/config.h> | ||
30 | #include <linux/skbuff.h> /* struct sk_buff */ | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/if.h> /* sa_family_t in <linux/irda.h> */ | ||
33 | #include <linux/irda.h> | ||
34 | |||
35 | typedef __u32 magic_t; | ||
36 | |||
37 | #ifndef TRUE | ||
38 | #define TRUE 1 | ||
39 | #endif | ||
40 | |||
41 | #ifndef FALSE | ||
42 | #define FALSE 0 | ||
43 | #endif | ||
44 | |||
45 | /* Hack to do small backoff when setting media busy in IrLAP */ | ||
46 | #ifndef SMALL | ||
47 | #define SMALL 5 | ||
48 | #endif | ||
49 | |||
50 | #ifndef IRDA_MIN /* Lets not mix this MIN with other header files */ | ||
51 | #define IRDA_MIN(a, b) (((a) < (b)) ? (a) : (b)) | ||
52 | #endif | ||
53 | |||
54 | #ifndef IRDA_ALIGN | ||
55 | # define IRDA_ALIGN __attribute__((aligned)) | ||
56 | #endif | ||
57 | #ifndef IRDA_PACK | ||
58 | # define IRDA_PACK __attribute__((packed)) | ||
59 | #endif | ||
60 | |||
61 | |||
62 | #ifdef CONFIG_IRDA_DEBUG | ||
63 | |||
64 | extern unsigned int irda_debug; | ||
65 | |||
66 | /* use 0 for production, 1 for verification, >2 for debug */ | ||
67 | #define IRDA_DEBUG_LEVEL 0 | ||
68 | |||
69 | #define IRDA_DEBUG(n, args...) \ | ||
70 | do { if (irda_debug >= (n)) \ | ||
71 | printk(KERN_DEBUG args); \ | ||
72 | } while (0) | ||
73 | #define IRDA_ASSERT(expr, func) \ | ||
74 | do { if(!(expr)) { \ | ||
75 | printk( "Assertion failed! %s:%s:%d %s\n", \ | ||
76 | __FILE__,__FUNCTION__,__LINE__,(#expr) ); \ | ||
77 | func } } while (0) | ||
78 | #define IRDA_ASSERT_LABEL(label) label | ||
79 | #else | ||
80 | #define IRDA_DEBUG(n, args...) do { } while (0) | ||
81 | #define IRDA_ASSERT(expr, func) do { (void)(expr); } while (0) | ||
82 | #define IRDA_ASSERT_LABEL(label) | ||
83 | #endif /* CONFIG_IRDA_DEBUG */ | ||
84 | |||
85 | #define IRDA_WARNING(args...) printk(KERN_WARNING args) | ||
86 | #define IRDA_MESSAGE(args...) printk(KERN_INFO args) | ||
87 | #define IRDA_ERROR(args...) printk(KERN_ERR args) | ||
88 | |||
89 | /* | ||
90 | * Magic numbers used by Linux-IrDA. Random numbers which must be unique to | ||
91 | * give the best protection | ||
92 | */ | ||
93 | |||
94 | #define IRTTY_MAGIC 0x2357 | ||
95 | #define LAP_MAGIC 0x1357 | ||
96 | #define LMP_MAGIC 0x4321 | ||
97 | #define LMP_LSAP_MAGIC 0x69333 | ||
98 | #define LMP_LAP_MAGIC 0x3432 | ||
99 | #define IRDA_DEVICE_MAGIC 0x63454 | ||
100 | #define IAS_MAGIC 0x007 | ||
101 | #define TTP_MAGIC 0x241169 | ||
102 | #define TTP_TSAP_MAGIC 0x4345 | ||
103 | #define IROBEX_MAGIC 0x341324 | ||
104 | #define HB_MAGIC 0x64534 | ||
105 | #define IRLAN_MAGIC 0x754 | ||
106 | #define IAS_OBJECT_MAGIC 0x34234 | ||
107 | #define IAS_ATTRIB_MAGIC 0x45232 | ||
108 | #define IRDA_TASK_MAGIC 0x38423 | ||
109 | |||
110 | #define IAS_DEVICE_ID 0x0000 /* Defined by IrDA, IrLMP section 4.1 (page 68) */ | ||
111 | #define IAS_PNP_ID 0xd342 | ||
112 | #define IAS_OBEX_ID 0x34323 | ||
113 | #define IAS_IRLAN_ID 0x34234 | ||
114 | #define IAS_IRCOMM_ID 0x2343 | ||
115 | #define IAS_IRLPT_ID 0x9876 | ||
116 | |||
117 | #endif /* NET_IRDA_H */ | ||
diff --git a/include/net/irda/irda_device.h b/include/net/irda/irda_device.h new file mode 100644 index 000000000000..3b216f186f18 --- /dev/null +++ b/include/net/irda/irda_device.h | |||
@@ -0,0 +1,301 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irda_device.h | ||
4 | * Version: 0.9 | ||
5 | * Description: Contains various declarations used by the drivers | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Tue Apr 14 12:41:42 1998 | ||
9 | * Modified at: Mon Mar 20 09:08:57 2000 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved. | ||
13 | * Copyright (c) 1998 Thomas Davis, <ratbert@radiks.net>, | ||
14 | * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com> | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or | ||
17 | * modify it under the terms of the GNU General Public License as | ||
18 | * published by the Free Software Foundation; either version 2 of | ||
19 | * the License, or (at your option) any later version. | ||
20 | * | ||
21 | * This program is distributed in the hope that it will be useful, | ||
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
24 | * GNU General Public License for more details. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License | ||
27 | * along with this program; if not, write to the Free Software | ||
28 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
29 | * MA 02111-1307 USA | ||
30 | * | ||
31 | ********************************************************************/ | ||
32 | |||
33 | /* | ||
34 | * This header contains all the IrDA definitions a driver really | ||
35 | * needs, and therefore the driver should not need to include | ||
36 | * any other IrDA headers - Jean II | ||
37 | */ | ||
38 | |||
39 | #ifndef IRDA_DEVICE_H | ||
40 | #define IRDA_DEVICE_H | ||
41 | |||
42 | #include <linux/config.h> | ||
43 | #include <linux/tty.h> | ||
44 | #include <linux/netdevice.h> | ||
45 | #include <linux/spinlock.h> | ||
46 | #include <linux/skbuff.h> /* struct sk_buff */ | ||
47 | #include <linux/irda.h> | ||
48 | #include <linux/types.h> | ||
49 | |||
50 | #include <net/pkt_sched.h> | ||
51 | #include <net/irda/irda.h> | ||
52 | #include <net/irda/qos.h> /* struct qos_info */ | ||
53 | #include <net/irda/irqueue.h> /* irda_queue_t */ | ||
54 | |||
55 | /* A few forward declarations (to make compiler happy) */ | ||
56 | struct irlap_cb; | ||
57 | |||
58 | /* Some non-standard interface flags (should not conflict with any in if.h) */ | ||
59 | #define IFF_SIR 0x0001 /* Supports SIR speeds */ | ||
60 | #define IFF_MIR 0x0002 /* Supports MIR speeds */ | ||
61 | #define IFF_FIR 0x0004 /* Supports FIR speeds */ | ||
62 | #define IFF_VFIR 0x0008 /* Supports VFIR speeds */ | ||
63 | #define IFF_PIO 0x0010 /* Supports PIO transfer of data */ | ||
64 | #define IFF_DMA 0x0020 /* Supports DMA transfer of data */ | ||
65 | #define IFF_SHM 0x0040 /* Supports shared memory data transfers */ | ||
66 | #define IFF_DONGLE 0x0080 /* Interface has a dongle attached */ | ||
67 | #define IFF_AIR 0x0100 /* Supports Advanced IR (AIR) standards */ | ||
68 | |||
69 | #define IO_XMIT 0x01 | ||
70 | #define IO_RECV 0x02 | ||
71 | |||
72 | typedef enum { | ||
73 | IRDA_IRLAP, /* IrDA mode, and deliver to IrLAP */ | ||
74 | IRDA_RAW, /* IrDA mode */ | ||
75 | SHARP_ASK, | ||
76 | TV_REMOTE, /* Also known as Consumer Electronics IR */ | ||
77 | } INFRARED_MODE; | ||
78 | |||
79 | typedef enum { | ||
80 | IRDA_TASK_INIT, /* All tasks are initialized with this state */ | ||
81 | IRDA_TASK_DONE, /* Signals that the task is finished */ | ||
82 | IRDA_TASK_WAIT, | ||
83 | IRDA_TASK_WAIT1, | ||
84 | IRDA_TASK_WAIT2, | ||
85 | IRDA_TASK_WAIT3, | ||
86 | IRDA_TASK_CHILD_INIT, /* Initializing child task */ | ||
87 | IRDA_TASK_CHILD_WAIT, /* Waiting for child task to finish */ | ||
88 | IRDA_TASK_CHILD_DONE /* Child task is finished */ | ||
89 | } IRDA_TASK_STATE; | ||
90 | |||
91 | struct irda_task; | ||
92 | typedef int (*IRDA_TASK_CALLBACK) (struct irda_task *task); | ||
93 | |||
94 | struct irda_task { | ||
95 | irda_queue_t q; | ||
96 | magic_t magic; | ||
97 | |||
98 | IRDA_TASK_STATE state; | ||
99 | IRDA_TASK_CALLBACK function; | ||
100 | IRDA_TASK_CALLBACK finished; | ||
101 | |||
102 | struct irda_task *parent; | ||
103 | struct timer_list timer; | ||
104 | |||
105 | void *instance; /* Instance being called */ | ||
106 | void *param; /* Parameter to be used by instance */ | ||
107 | }; | ||
108 | |||
109 | /* Dongle info */ | ||
110 | struct dongle_reg; | ||
111 | typedef struct { | ||
112 | struct dongle_reg *issue; /* Registration info */ | ||
113 | struct net_device *dev; /* Device we are attached to */ | ||
114 | struct irda_task *speed_task; /* Task handling speed change */ | ||
115 | struct irda_task *reset_task; /* Task handling reset */ | ||
116 | __u32 speed; /* Current speed */ | ||
117 | |||
118 | /* Callbacks to the IrDA device driver */ | ||
119 | int (*set_mode)(struct net_device *, int mode); | ||
120 | int (*read)(struct net_device *dev, __u8 *buf, int len); | ||
121 | int (*write)(struct net_device *dev, __u8 *buf, int len); | ||
122 | int (*set_dtr_rts)(struct net_device *dev, int dtr, int rts); | ||
123 | } dongle_t; | ||
124 | |||
125 | /* Dongle registration info */ | ||
126 | struct dongle_reg { | ||
127 | irda_queue_t q; /* Must be first */ | ||
128 | IRDA_DONGLE type; | ||
129 | |||
130 | void (*open)(dongle_t *dongle, struct qos_info *qos); | ||
131 | void (*close)(dongle_t *dongle); | ||
132 | int (*reset)(struct irda_task *task); | ||
133 | int (*change_speed)(struct irda_task *task); | ||
134 | struct module *owner; | ||
135 | }; | ||
136 | |||
137 | /* | ||
138 | * Per-packet information we need to hide inside sk_buff | ||
139 | * (must not exceed 48 bytes, check with struct sk_buff) | ||
140 | */ | ||
141 | struct irda_skb_cb { | ||
142 | magic_t magic; /* Be sure that we can trust the information */ | ||
143 | __u32 next_speed; /* The Speed to be set *after* this frame */ | ||
144 | __u16 mtt; /* Minimum turn around time */ | ||
145 | __u16 xbofs; /* Number of xbofs required, used by SIR mode */ | ||
146 | __u16 next_xbofs; /* Number of xbofs required *after* this frame */ | ||
147 | void *context; /* May be used by drivers */ | ||
148 | void (*destructor)(struct sk_buff *skb); /* Used for flow control */ | ||
149 | __u16 xbofs_delay; /* Number of xbofs used for generating the mtt */ | ||
150 | __u8 line; /* Used by IrCOMM in IrLPT mode */ | ||
151 | }; | ||
152 | |||
153 | /* Chip specific info */ | ||
154 | typedef struct { | ||
155 | int cfg_base; /* Config register IO base */ | ||
156 | int sir_base; /* SIR IO base */ | ||
157 | int fir_base; /* FIR IO base */ | ||
158 | int mem_base; /* Shared memory base */ | ||
159 | int sir_ext; /* Length of SIR iobase */ | ||
160 | int fir_ext; /* Length of FIR iobase */ | ||
161 | int irq, irq2; /* Interrupts used */ | ||
162 | int dma, dma2; /* DMA channel(s) used */ | ||
163 | int fifo_size; /* FIFO size */ | ||
164 | int irqflags; /* interrupt flags (ie, SA_SHIRQ|SA_INTERRUPT) */ | ||
165 | int direction; /* Link direction, used by some FIR drivers */ | ||
166 | int enabled; /* Powered on? */ | ||
167 | int suspended; /* Suspended by APM */ | ||
168 | __u32 speed; /* Currently used speed */ | ||
169 | __u32 new_speed; /* Speed we must change to when Tx is finished */ | ||
170 | int dongle_id; /* Dongle or transceiver currently used */ | ||
171 | } chipio_t; | ||
172 | |||
173 | /* IO buffer specific info (inspired by struct sk_buff) */ | ||
174 | typedef struct { | ||
175 | int state; /* Receiving state (transmit state not used) */ | ||
176 | int in_frame; /* True if receiving frame */ | ||
177 | |||
178 | __u8 *head; /* start of buffer */ | ||
179 | __u8 *data; /* start of data in buffer */ | ||
180 | |||
181 | int len; /* current length of data */ | ||
182 | int truesize; /* total allocated size of buffer */ | ||
183 | __u16 fcs; | ||
184 | |||
185 | struct sk_buff *skb; /* ZeroCopy Rx in async_unwrap_char() */ | ||
186 | } iobuff_t; | ||
187 | |||
188 | /* Maximum SIR frame (skb) that we expect to receive *unwrapped*. | ||
189 | * Max LAP MTU (I field) is 2048 bytes max (IrLAP 1.1, chapt 6.6.5, p40). | ||
190 | * Max LAP header is 2 bytes (for now). | ||
191 | * Max CRC is 2 bytes at SIR, 4 bytes at FIR. | ||
192 | * Need 1 byte for skb_reserve() to align IP header for IrLAN. | ||
193 | * Add a few extra bytes just to be safe (buffer is power of two anyway) | ||
194 | * Jean II */ | ||
195 | #define IRDA_SKB_MAX_MTU 2064 | ||
196 | /* Maximum SIR frame that we expect to send, wrapped (i.e. with XBOFS | ||
197 | * and escaped characters on top of above). */ | ||
198 | #define IRDA_SIR_MAX_FRAME 4269 | ||
199 | |||
200 | /* The SIR unwrapper async_unwrap_char() will use a Rx-copy-break mechanism | ||
201 | * when using the optional ZeroCopy Rx, where only small frames are memcpy | ||
202 | * to a smaller skb to save memory. This is the threshold under which copy | ||
203 | * will happen (and over which it won't happen). | ||
204 | * Some FIR drivers may use this #define as well... | ||
205 | * This is the same value as various Ethernet drivers. - Jean II */ | ||
206 | #define IRDA_RX_COPY_THRESHOLD 256 | ||
207 | |||
208 | /* Function prototypes */ | ||
209 | int irda_device_init(void); | ||
210 | void irda_device_cleanup(void); | ||
211 | |||
212 | /* IrLAP entry points used by the drivers. | ||
213 | * We declare them here to avoid the driver pulling a whole bunch stack | ||
214 | * headers they don't really need - Jean II */ | ||
215 | struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos, | ||
216 | const char *hw_name); | ||
217 | void irlap_close(struct irlap_cb *self); | ||
218 | |||
219 | /* Interface to be uses by IrLAP */ | ||
220 | void irda_device_set_media_busy(struct net_device *dev, int status); | ||
221 | int irda_device_is_media_busy(struct net_device *dev); | ||
222 | int irda_device_is_receiving(struct net_device *dev); | ||
223 | |||
224 | /* Interface for internal use */ | ||
225 | static inline int irda_device_txqueue_empty(const struct net_device *dev) | ||
226 | { | ||
227 | return (skb_queue_len(&dev->qdisc->q) == 0); | ||
228 | } | ||
229 | int irda_device_set_raw_mode(struct net_device* self, int status); | ||
230 | struct net_device *alloc_irdadev(int sizeof_priv); | ||
231 | |||
232 | /* Dongle interface */ | ||
233 | void irda_device_unregister_dongle(struct dongle_reg *dongle); | ||
234 | int irda_device_register_dongle(struct dongle_reg *dongle); | ||
235 | dongle_t *irda_device_dongle_init(struct net_device *dev, int type); | ||
236 | int irda_device_dongle_cleanup(dongle_t *dongle); | ||
237 | |||
238 | #ifdef CONFIG_ISA | ||
239 | void irda_setup_dma(int channel, dma_addr_t buffer, int count, int mode); | ||
240 | #endif | ||
241 | |||
242 | void irda_task_delete(struct irda_task *task); | ||
243 | struct irda_task *irda_task_execute(void *instance, | ||
244 | IRDA_TASK_CALLBACK function, | ||
245 | IRDA_TASK_CALLBACK finished, | ||
246 | struct irda_task *parent, void *param); | ||
247 | void irda_task_next_state(struct irda_task *task, IRDA_TASK_STATE state); | ||
248 | |||
249 | /* | ||
250 | * Function irda_get_mtt (skb) | ||
251 | * | ||
252 | * Utility function for getting the minimum turnaround time out of | ||
253 | * the skb, where it has been hidden in the cb field. | ||
254 | */ | ||
255 | static inline __u16 irda_get_mtt(const struct sk_buff *skb) | ||
256 | { | ||
257 | const struct irda_skb_cb *cb = (const struct irda_skb_cb *) skb->cb; | ||
258 | return (cb->magic == LAP_MAGIC) ? cb->mtt : 10000; | ||
259 | } | ||
260 | |||
261 | /* | ||
262 | * Function irda_get_next_speed (skb) | ||
263 | * | ||
264 | * Extract the speed that should be set *after* this frame from the skb | ||
265 | * | ||
266 | * Note : return -1 for user space frames | ||
267 | */ | ||
268 | static inline __u32 irda_get_next_speed(const struct sk_buff *skb) | ||
269 | { | ||
270 | const struct irda_skb_cb *cb = (const struct irda_skb_cb *) skb->cb; | ||
271 | return (cb->magic == LAP_MAGIC) ? cb->next_speed : -1; | ||
272 | } | ||
273 | |||
274 | /* | ||
275 | * Function irda_get_next_xbofs (skb) | ||
276 | * | ||
277 | * Extract the xbofs that should be set for this frame from the skb | ||
278 | * | ||
279 | * Note : default to 10 for user space frames | ||
280 | */ | ||
281 | static inline __u16 irda_get_xbofs(const struct sk_buff *skb) | ||
282 | { | ||
283 | const struct irda_skb_cb *cb = (const struct irda_skb_cb *) skb->cb; | ||
284 | return (cb->magic == LAP_MAGIC) ? cb->xbofs : 10; | ||
285 | } | ||
286 | |||
287 | /* | ||
288 | * Function irda_get_next_xbofs (skb) | ||
289 | * | ||
290 | * Extract the xbofs that should be set *after* this frame from the skb | ||
291 | * | ||
292 | * Note : return -1 for user space frames | ||
293 | */ | ||
294 | static inline __u16 irda_get_next_xbofs(const struct sk_buff *skb) | ||
295 | { | ||
296 | const struct irda_skb_cb *cb = (const struct irda_skb_cb *) skb->cb; | ||
297 | return (cb->magic == LAP_MAGIC) ? cb->next_xbofs : -1; | ||
298 | } | ||
299 | #endif /* IRDA_DEVICE_H */ | ||
300 | |||
301 | |||
diff --git a/include/net/irda/iriap.h b/include/net/irda/iriap.h new file mode 100644 index 000000000000..2007c5a0a43f --- /dev/null +++ b/include/net/irda/iriap.h | |||
@@ -0,0 +1,108 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: iriap.h | ||
4 | * Version: 0.5 | ||
5 | * Description: Information Access Protocol (IAP) | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Thu Aug 21 00:02:07 1997 | ||
9 | * Modified at: Sat Dec 25 16:42:09 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1997-1999 Dag Brattli <dagb@cs.uit.no>, | ||
13 | * All Rights Reserved. | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License as | ||
17 | * published by the Free Software Foundation; either version 2 of | ||
18 | * the License, or (at your option) any later version. | ||
19 | * | ||
20 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
21 | * provide warranty for any of this software. This material is | ||
22 | * provided "AS-IS" and at no charge. | ||
23 | * | ||
24 | ********************************************************************/ | ||
25 | |||
26 | #ifndef IRIAP_H | ||
27 | #define IRIAP_H | ||
28 | |||
29 | #include <linux/types.h> | ||
30 | #include <linux/skbuff.h> | ||
31 | |||
32 | #include <net/irda/iriap_event.h> | ||
33 | #include <net/irda/irias_object.h> | ||
34 | #include <net/irda/irqueue.h> /* irda_queue_t */ | ||
35 | #include <net/irda/timer.h> /* struct timer_list */ | ||
36 | |||
37 | #define IAP_LST 0x80 | ||
38 | #define IAP_ACK 0x40 | ||
39 | |||
40 | #define IAS_SERVER 0 | ||
41 | #define IAS_CLIENT 1 | ||
42 | |||
43 | /* IrIAP Op-codes */ | ||
44 | #define GET_INFO_BASE 0x01 | ||
45 | #define GET_OBJECTS 0x02 | ||
46 | #define GET_VALUE 0x03 | ||
47 | #define GET_VALUE_BY_CLASS 0x04 | ||
48 | #define GET_OBJECT_INFO 0x05 | ||
49 | #define GET_ATTRIB_NAMES 0x06 | ||
50 | |||
51 | #define IAS_SUCCESS 0 | ||
52 | #define IAS_CLASS_UNKNOWN 1 | ||
53 | #define IAS_ATTRIB_UNKNOWN 2 | ||
54 | #define IAS_DISCONNECT 10 | ||
55 | |||
56 | typedef void (*CONFIRM_CALLBACK)(int result, __u16 obj_id, | ||
57 | struct ias_value *value, void *priv); | ||
58 | |||
59 | struct iriap_cb { | ||
60 | irda_queue_t q; /* Must be first */ | ||
61 | magic_t magic; /* Magic cookie */ | ||
62 | |||
63 | int mode; /* Client or server */ | ||
64 | |||
65 | __u32 saddr; | ||
66 | __u32 daddr; | ||
67 | __u8 operation; | ||
68 | |||
69 | struct sk_buff *request_skb; | ||
70 | struct lsap_cb *lsap; | ||
71 | __u8 slsap_sel; | ||
72 | |||
73 | /* Client states */ | ||
74 | IRIAP_STATE client_state; | ||
75 | IRIAP_STATE call_state; | ||
76 | |||
77 | /* Server states */ | ||
78 | IRIAP_STATE server_state; | ||
79 | IRIAP_STATE r_connect_state; | ||
80 | |||
81 | CONFIRM_CALLBACK confirm; | ||
82 | void *priv; /* Used to identify client */ | ||
83 | |||
84 | __u8 max_header_size; | ||
85 | __u32 max_data_size; | ||
86 | |||
87 | struct timer_list watchdog_timer; | ||
88 | }; | ||
89 | |||
90 | int iriap_init(void); | ||
91 | void iriap_cleanup(void); | ||
92 | |||
93 | struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv, | ||
94 | CONFIRM_CALLBACK callback); | ||
95 | void iriap_close(struct iriap_cb *self); | ||
96 | |||
97 | int iriap_getvaluebyclass_request(struct iriap_cb *self, | ||
98 | __u32 saddr, __u32 daddr, | ||
99 | char *name, char *attr); | ||
100 | void iriap_connect_request(struct iriap_cb *self); | ||
101 | void iriap_send_ack( struct iriap_cb *self); | ||
102 | void iriap_call_indication(struct iriap_cb *self, struct sk_buff *skb); | ||
103 | |||
104 | void iriap_register_server(void); | ||
105 | |||
106 | #endif | ||
107 | |||
108 | |||
diff --git a/include/net/irda/iriap_event.h b/include/net/irda/iriap_event.h new file mode 100644 index 000000000000..4ca3d2071b03 --- /dev/null +++ b/include/net/irda/iriap_event.h | |||
@@ -0,0 +1,85 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: iriap_event.h | ||
4 | * Version: | ||
5 | * Description: | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Mon Aug 4 20:40:53 1997 | ||
9 | * Modified at: Sun Oct 31 22:02:54 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
20 | * provide warranty for any of this software. This material is | ||
21 | * provided "AS-IS" and at no charge. | ||
22 | * | ||
23 | ********************************************************************/ | ||
24 | |||
25 | #ifndef IRIAP_FSM_H | ||
26 | #define IRIAP_FSM_H | ||
27 | |||
28 | /* Forward because of circular include dependecies */ | ||
29 | struct iriap_cb; | ||
30 | |||
31 | /* IrIAP states */ | ||
32 | typedef enum { | ||
33 | /* Client */ | ||
34 | S_DISCONNECT, | ||
35 | S_CONNECTING, | ||
36 | S_CALL, | ||
37 | |||
38 | /* S-Call */ | ||
39 | S_MAKE_CALL, | ||
40 | S_CALLING, | ||
41 | S_OUTSTANDING, | ||
42 | S_REPLYING, | ||
43 | S_WAIT_FOR_CALL, | ||
44 | S_WAIT_ACTIVE, | ||
45 | |||
46 | /* Server */ | ||
47 | R_DISCONNECT, | ||
48 | R_CALL, | ||
49 | |||
50 | /* R-Connect */ | ||
51 | R_WAITING, | ||
52 | R_WAIT_ACTIVE, | ||
53 | R_RECEIVING, | ||
54 | R_EXECUTE, | ||
55 | R_RETURNING, | ||
56 | } IRIAP_STATE; | ||
57 | |||
58 | typedef enum { | ||
59 | IAP_CALL_REQUEST, | ||
60 | IAP_CALL_REQUEST_GVBC, | ||
61 | IAP_CALL_RESPONSE, | ||
62 | IAP_RECV_F_LST, | ||
63 | IAP_LM_DISCONNECT_INDICATION, | ||
64 | IAP_LM_CONNECT_INDICATION, | ||
65 | IAP_LM_CONNECT_CONFIRM, | ||
66 | } IRIAP_EVENT; | ||
67 | |||
68 | void iriap_next_client_state (struct iriap_cb *self, IRIAP_STATE state); | ||
69 | void iriap_next_call_state (struct iriap_cb *self, IRIAP_STATE state); | ||
70 | void iriap_next_server_state (struct iriap_cb *self, IRIAP_STATE state); | ||
71 | void iriap_next_r_connect_state(struct iriap_cb *self, IRIAP_STATE state); | ||
72 | |||
73 | |||
74 | void iriap_do_client_event(struct iriap_cb *self, IRIAP_EVENT event, | ||
75 | struct sk_buff *skb); | ||
76 | void iriap_do_call_event (struct iriap_cb *self, IRIAP_EVENT event, | ||
77 | struct sk_buff *skb); | ||
78 | |||
79 | void iriap_do_server_event (struct iriap_cb *self, IRIAP_EVENT event, | ||
80 | struct sk_buff *skb); | ||
81 | void iriap_do_r_connect_event(struct iriap_cb *self, IRIAP_EVENT event, | ||
82 | struct sk_buff *skb); | ||
83 | |||
84 | #endif /* IRIAP_FSM_H */ | ||
85 | |||
diff --git a/include/net/irda/irias_object.h b/include/net/irda/irias_object.h new file mode 100644 index 000000000000..c41196b87955 --- /dev/null +++ b/include/net/irda/irias_object.h | |||
@@ -0,0 +1,108 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irias_object.h | ||
4 | * Version: | ||
5 | * Description: | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Thu Oct 1 22:49:50 1998 | ||
9 | * Modified at: Wed Dec 15 11:20:57 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
20 | * provide warranty for any of this software. This material is | ||
21 | * provided "AS-IS" and at no charge. | ||
22 | * | ||
23 | ********************************************************************/ | ||
24 | |||
25 | #ifndef LM_IAS_OBJECT_H | ||
26 | #define LM_IAS_OBJECT_H | ||
27 | |||
28 | #include <net/irda/irda.h> | ||
29 | #include <net/irda/irqueue.h> | ||
30 | |||
31 | /* LM-IAS Attribute types */ | ||
32 | #define IAS_MISSING 0 | ||
33 | #define IAS_INTEGER 1 | ||
34 | #define IAS_OCT_SEQ 2 | ||
35 | #define IAS_STRING 3 | ||
36 | |||
37 | /* Object ownership of attributes (user or kernel) */ | ||
38 | #define IAS_KERNEL_ATTR 0 | ||
39 | #define IAS_USER_ATTR 1 | ||
40 | |||
41 | /* | ||
42 | * LM-IAS Object | ||
43 | */ | ||
44 | struct ias_object { | ||
45 | irda_queue_t q; /* Must be first! */ | ||
46 | magic_t magic; | ||
47 | |||
48 | char *name; | ||
49 | int id; | ||
50 | hashbin_t *attribs; | ||
51 | }; | ||
52 | |||
53 | /* | ||
54 | * Values used by LM-IAS attributes | ||
55 | */ | ||
56 | struct ias_value { | ||
57 | __u8 type; /* Value description */ | ||
58 | __u8 owner; /* Managed from user/kernel space */ | ||
59 | int charset; /* Only used by string type */ | ||
60 | int len; | ||
61 | |||
62 | /* Value */ | ||
63 | union { | ||
64 | int integer; | ||
65 | char *string; | ||
66 | __u8 *oct_seq; | ||
67 | } t; | ||
68 | }; | ||
69 | |||
70 | /* | ||
71 | * Attributes used by LM-IAS objects | ||
72 | */ | ||
73 | struct ias_attrib { | ||
74 | irda_queue_t q; /* Must be first! */ | ||
75 | int magic; | ||
76 | |||
77 | char *name; /* Attribute name */ | ||
78 | struct ias_value *value; /* Attribute value */ | ||
79 | }; | ||
80 | |||
81 | struct ias_object *irias_new_object(char *name, int id); | ||
82 | void irias_insert_object(struct ias_object *obj); | ||
83 | int irias_delete_object(struct ias_object *obj); | ||
84 | int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib, | ||
85 | int cleanobject); | ||
86 | void __irias_delete_object(struct ias_object *obj); | ||
87 | |||
88 | void irias_add_integer_attrib(struct ias_object *obj, char *name, int value, | ||
89 | int user); | ||
90 | void irias_add_string_attrib(struct ias_object *obj, char *name, char *value, | ||
91 | int user); | ||
92 | void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets, | ||
93 | int len, int user); | ||
94 | int irias_object_change_attribute(char *obj_name, char *attrib_name, | ||
95 | struct ias_value *new_value); | ||
96 | struct ias_object *irias_find_object(char *name); | ||
97 | struct ias_attrib *irias_find_attrib(struct ias_object *obj, char *name); | ||
98 | |||
99 | struct ias_value *irias_new_string_value(char *string); | ||
100 | struct ias_value *irias_new_integer_value(int integer); | ||
101 | struct ias_value *irias_new_octseq_value(__u8 *octseq , int len); | ||
102 | struct ias_value *irias_new_missing_value(void); | ||
103 | void irias_delete_value(struct ias_value *value); | ||
104 | |||
105 | extern struct ias_value irias_missing; | ||
106 | extern hashbin_t *irias_objects; | ||
107 | |||
108 | #endif | ||
diff --git a/include/net/irda/irlan_client.h b/include/net/irda/irlan_client.h new file mode 100644 index 000000000000..736dabe211e3 --- /dev/null +++ b/include/net/irda/irlan_client.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irlan_client.h | ||
4 | * Version: 0.3 | ||
5 | * Description: IrDA LAN access layer | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Sun Aug 31 20:14:37 1997 | ||
9 | * Modified at: Thu Apr 22 14:13:34 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
20 | * provide warranty for any of this software. This material is | ||
21 | * provided "AS-IS" and at no charge. | ||
22 | * | ||
23 | ********************************************************************/ | ||
24 | |||
25 | #ifndef IRLAN_CLIENT_H | ||
26 | #define IRLAN_CLIENT_H | ||
27 | |||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/types.h> | ||
30 | #include <linux/skbuff.h> | ||
31 | #include <linux/netdevice.h> | ||
32 | |||
33 | #include <net/irda/irias_object.h> | ||
34 | #include <net/irda/irlan_event.h> | ||
35 | |||
36 | void irlan_client_discovery_indication(discinfo_t *, DISCOVERY_MODE, void *); | ||
37 | void irlan_client_wakeup(struct irlan_cb *self, __u32 saddr, __u32 daddr); | ||
38 | |||
39 | void irlan_client_parse_response(struct irlan_cb *self, struct sk_buff *skb); | ||
40 | void irlan_client_get_value_confirm(int result, __u16 obj_id, | ||
41 | struct ias_value *value, void *priv); | ||
42 | #endif | ||
diff --git a/include/net/irda/irlan_common.h b/include/net/irda/irlan_common.h new file mode 100644 index 000000000000..1c73bdbc3eb3 --- /dev/null +++ b/include/net/irda/irlan_common.h | |||
@@ -0,0 +1,222 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irlan_common.h | ||
4 | * Version: 0.8 | ||
5 | * Description: IrDA LAN access layer | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Sun Aug 31 20:14:37 1997 | ||
9 | * Modified at: Sun Oct 31 19:41:24 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, | ||
13 | * All Rights Reserved. | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License as | ||
17 | * published by the Free Software Foundation; either version 2 of | ||
18 | * the License, or (at your option) any later version. | ||
19 | * | ||
20 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
21 | * provide warranty for any of this software. This material is | ||
22 | * provided "AS-IS" and at no charge. | ||
23 | * | ||
24 | ********************************************************************/ | ||
25 | |||
26 | #ifndef IRLAN_H | ||
27 | #define IRLAN_H | ||
28 | |||
29 | #include <asm/param.h> /* for HZ */ | ||
30 | |||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/types.h> | ||
33 | #include <linux/skbuff.h> | ||
34 | #include <linux/netdevice.h> | ||
35 | |||
36 | #include <net/irda/irttp.h> | ||
37 | |||
38 | #define IRLAN_MTU 1518 | ||
39 | #define IRLAN_TIMEOUT 10*HZ /* 10 seconds */ | ||
40 | |||
41 | /* Command packet types */ | ||
42 | #define CMD_GET_PROVIDER_INFO 0 | ||
43 | #define CMD_GET_MEDIA_CHAR 1 | ||
44 | #define CMD_OPEN_DATA_CHANNEL 2 | ||
45 | #define CMD_CLOSE_DATA_CHAN 3 | ||
46 | #define CMD_RECONNECT_DATA_CHAN 4 | ||
47 | #define CMD_FILTER_OPERATION 5 | ||
48 | |||
49 | /* Some responses */ | ||
50 | #define RSP_SUCCESS 0 | ||
51 | #define RSP_INSUFFICIENT_RESOURCES 1 | ||
52 | #define RSP_INVALID_COMMAND_FORMAT 2 | ||
53 | #define RSP_COMMAND_NOT_SUPPORTED 3 | ||
54 | #define RSP_PARAM_NOT_SUPPORTED 4 | ||
55 | #define RSP_VALUE_NOT_SUPPORTED 5 | ||
56 | #define RSP_NOT_OPEN 6 | ||
57 | #define RSP_AUTHENTICATION_REQUIRED 7 | ||
58 | #define RSP_INVALID_PASSWORD 8 | ||
59 | #define RSP_PROTOCOL_ERROR 9 | ||
60 | #define RSP_ASYNCHRONOUS_ERROR 255 | ||
61 | |||
62 | /* Media types */ | ||
63 | #define MEDIA_802_3 1 | ||
64 | #define MEDIA_802_5 2 | ||
65 | |||
66 | /* Filter parameters */ | ||
67 | #define DATA_CHAN 1 | ||
68 | #define FILTER_TYPE 2 | ||
69 | #define FILTER_MODE 3 | ||
70 | |||
71 | /* Filter types */ | ||
72 | #define IRLAN_DIRECTED 0x01 | ||
73 | #define IRLAN_FUNCTIONAL 0x02 | ||
74 | #define IRLAN_GROUP 0x04 | ||
75 | #define IRLAN_MAC_FRAME 0x08 | ||
76 | #define IRLAN_MULTICAST 0x10 | ||
77 | #define IRLAN_BROADCAST 0x20 | ||
78 | #define IRLAN_IPX_SOCKET 0x40 | ||
79 | |||
80 | /* Filter modes */ | ||
81 | #define ALL 1 | ||
82 | #define FILTER 2 | ||
83 | #define NONE 3 | ||
84 | |||
85 | /* Filter operations */ | ||
86 | #define GET 1 | ||
87 | #define CLEAR 2 | ||
88 | #define ADD 3 | ||
89 | #define REMOVE 4 | ||
90 | #define DYNAMIC 5 | ||
91 | |||
92 | /* Access types */ | ||
93 | #define ACCESS_DIRECT 1 | ||
94 | #define ACCESS_PEER 2 | ||
95 | #define ACCESS_HOSTED 3 | ||
96 | |||
97 | #define IRLAN_BYTE 0 | ||
98 | #define IRLAN_SHORT 1 | ||
99 | #define IRLAN_ARRAY 2 | ||
100 | |||
101 | #define IRLAN_MAX_HEADER (TTP_HEADER+LMP_HEADER+LAP_MAX_HEADER) | ||
102 | |||
103 | /* | ||
104 | * IrLAN client | ||
105 | */ | ||
106 | struct irlan_client_cb { | ||
107 | int state; | ||
108 | |||
109 | int open_retries; | ||
110 | |||
111 | struct tsap_cb *tsap_ctrl; | ||
112 | __u32 max_sdu_size; | ||
113 | __u8 max_header_size; | ||
114 | |||
115 | int access_type; /* Access type of provider */ | ||
116 | __u8 reconnect_key[255]; | ||
117 | __u8 key_len; | ||
118 | |||
119 | __u16 recv_arb_val; | ||
120 | __u16 max_frame; | ||
121 | int filter_type; | ||
122 | |||
123 | int unicast_open; | ||
124 | int broadcast_open; | ||
125 | |||
126 | int tx_busy; | ||
127 | struct sk_buff_head txq; /* Transmit control queue */ | ||
128 | |||
129 | struct iriap_cb *iriap; | ||
130 | |||
131 | struct timer_list kick_timer; | ||
132 | }; | ||
133 | |||
134 | /* | ||
135 | * IrLAN provider | ||
136 | */ | ||
137 | struct irlan_provider_cb { | ||
138 | int state; | ||
139 | |||
140 | struct tsap_cb *tsap_ctrl; | ||
141 | __u32 max_sdu_size; | ||
142 | __u8 max_header_size; | ||
143 | |||
144 | /* | ||
145 | * Store some values here which are used by the provider to parse | ||
146 | * the filter operations | ||
147 | */ | ||
148 | int data_chan; | ||
149 | int filter_type; | ||
150 | int filter_mode; | ||
151 | int filter_operation; | ||
152 | int filter_entry; | ||
153 | int access_type; /* Access type */ | ||
154 | __u16 send_arb_val; | ||
155 | |||
156 | __u8 mac_address[6]; /* Generated MAC address for peer device */ | ||
157 | }; | ||
158 | |||
159 | /* | ||
160 | * IrLAN control block | ||
161 | */ | ||
162 | struct irlan_cb { | ||
163 | int magic; | ||
164 | struct list_head dev_list; | ||
165 | struct net_device *dev; /* Ethernet device structure*/ | ||
166 | struct net_device_stats stats; | ||
167 | |||
168 | __u32 saddr; /* Source device address */ | ||
169 | __u32 daddr; /* Destination device address */ | ||
170 | int disconnect_reason; /* Why we got disconnected */ | ||
171 | |||
172 | int media; /* Media type */ | ||
173 | __u8 version[2]; /* IrLAN version */ | ||
174 | |||
175 | struct tsap_cb *tsap_data; /* Data TSAP */ | ||
176 | |||
177 | int use_udata; /* Use Unit Data transfers */ | ||
178 | |||
179 | __u8 stsap_sel_data; /* Source data TSAP selector */ | ||
180 | __u8 dtsap_sel_data; /* Destination data TSAP selector */ | ||
181 | __u8 dtsap_sel_ctrl; /* Destination ctrl TSAP selector */ | ||
182 | |||
183 | struct irlan_client_cb client; /* Client specific fields */ | ||
184 | struct irlan_provider_cb provider; /* Provider specific fields */ | ||
185 | |||
186 | __u32 max_sdu_size; | ||
187 | __u8 max_header_size; | ||
188 | |||
189 | wait_queue_head_t open_wait; | ||
190 | struct timer_list watchdog_timer; | ||
191 | }; | ||
192 | |||
193 | void irlan_close(struct irlan_cb *self); | ||
194 | void irlan_close_tsaps(struct irlan_cb *self); | ||
195 | |||
196 | int irlan_register_netdev(struct irlan_cb *self); | ||
197 | void irlan_ias_register(struct irlan_cb *self, __u8 tsap_sel); | ||
198 | void irlan_start_watchdog_timer(struct irlan_cb *self, int timeout); | ||
199 | |||
200 | void irlan_open_data_tsap(struct irlan_cb *self); | ||
201 | |||
202 | int irlan_run_ctrl_tx_queue(struct irlan_cb *self); | ||
203 | |||
204 | struct irlan_cb *irlan_get_any(void); | ||
205 | void irlan_get_provider_info(struct irlan_cb *self); | ||
206 | void irlan_get_media_char(struct irlan_cb *self); | ||
207 | void irlan_open_data_channel(struct irlan_cb *self); | ||
208 | void irlan_close_data_channel(struct irlan_cb *self); | ||
209 | void irlan_set_multicast_filter(struct irlan_cb *self, int status); | ||
210 | void irlan_set_broadcast_filter(struct irlan_cb *self, int status); | ||
211 | |||
212 | int irlan_insert_byte_param(struct sk_buff *skb, char *param, __u8 value); | ||
213 | int irlan_insert_short_param(struct sk_buff *skb, char *param, __u16 value); | ||
214 | int irlan_insert_string_param(struct sk_buff *skb, char *param, char *value); | ||
215 | int irlan_insert_array_param(struct sk_buff *skb, char *name, __u8 *value, | ||
216 | __u16 value_len); | ||
217 | |||
218 | int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len); | ||
219 | |||
220 | #endif | ||
221 | |||
222 | |||
diff --git a/include/net/irda/irlan_eth.h b/include/net/irda/irlan_eth.h new file mode 100644 index 000000000000..9a9b3619d305 --- /dev/null +++ b/include/net/irda/irlan_eth.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irlan_eth.h | ||
4 | * Version: | ||
5 | * Description: | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Thu Oct 15 08:36:58 1998 | ||
9 | * Modified at: Fri May 14 23:29:00 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
20 | * provide warranty for any of this software. This material is | ||
21 | * provided "AS-IS" and at no charge. | ||
22 | * | ||
23 | ********************************************************************/ | ||
24 | |||
25 | #ifndef IRLAN_ETH_H | ||
26 | #define IRLAN_ETH_H | ||
27 | |||
28 | struct net_device *alloc_irlandev(const char *name); | ||
29 | int irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb); | ||
30 | |||
31 | void irlan_eth_flow_indication( void *instance, void *sap, LOCAL_FLOW flow); | ||
32 | void irlan_eth_send_gratuitous_arp(struct net_device *dev); | ||
33 | #endif | ||
diff --git a/include/net/irda/irlan_event.h b/include/net/irda/irlan_event.h new file mode 100644 index 000000000000..b9baac9eb8b6 --- /dev/null +++ b/include/net/irda/irlan_event.h | |||
@@ -0,0 +1,81 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irlan_event.h | ||
4 | * Version: | ||
5 | * Description: LAN access | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Sun Aug 31 20:14:37 1997 | ||
9 | * Modified at: Tue Feb 2 09:45:17 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1997 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
20 | * provide warranty for any of this software. This material is | ||
21 | * provided "AS-IS" and at no charge. | ||
22 | * | ||
23 | ********************************************************************/ | ||
24 | |||
25 | #ifndef IRLAN_EVENT_H | ||
26 | #define IRLAN_EVENT_H | ||
27 | |||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/skbuff.h> | ||
30 | |||
31 | #include <net/irda/irlan_common.h> | ||
32 | |||
33 | typedef enum { | ||
34 | IRLAN_IDLE, | ||
35 | IRLAN_QUERY, | ||
36 | IRLAN_CONN, | ||
37 | IRLAN_INFO, | ||
38 | IRLAN_MEDIA, | ||
39 | IRLAN_OPEN, | ||
40 | IRLAN_WAIT, | ||
41 | IRLAN_ARB, | ||
42 | IRLAN_DATA, | ||
43 | IRLAN_CLOSE, | ||
44 | IRLAN_SYNC | ||
45 | } IRLAN_STATE; | ||
46 | |||
47 | typedef enum { | ||
48 | IRLAN_DISCOVERY_INDICATION, | ||
49 | IRLAN_IAS_PROVIDER_AVAIL, | ||
50 | IRLAN_IAS_PROVIDER_NOT_AVAIL, | ||
51 | IRLAN_LAP_DISCONNECT, | ||
52 | IRLAN_LMP_DISCONNECT, | ||
53 | IRLAN_CONNECT_COMPLETE, | ||
54 | IRLAN_DATA_INDICATION, | ||
55 | IRLAN_DATA_CONNECT_INDICATION, | ||
56 | IRLAN_RETRY_CONNECT, | ||
57 | |||
58 | IRLAN_CONNECT_INDICATION, | ||
59 | IRLAN_GET_INFO_CMD, | ||
60 | IRLAN_GET_MEDIA_CMD, | ||
61 | IRLAN_OPEN_DATA_CMD, | ||
62 | IRLAN_FILTER_CONFIG_CMD, | ||
63 | |||
64 | IRLAN_CHECK_CON_ARB, | ||
65 | IRLAN_PROVIDER_SIGNAL, | ||
66 | |||
67 | IRLAN_WATCHDOG_TIMEOUT, | ||
68 | } IRLAN_EVENT; | ||
69 | |||
70 | extern char *irlan_state[]; | ||
71 | |||
72 | void irlan_do_client_event(struct irlan_cb *self, IRLAN_EVENT event, | ||
73 | struct sk_buff *skb); | ||
74 | |||
75 | void irlan_do_provider_event(struct irlan_cb *self, IRLAN_EVENT event, | ||
76 | struct sk_buff *skb); | ||
77 | |||
78 | void irlan_next_client_state(struct irlan_cb *self, IRLAN_STATE state); | ||
79 | void irlan_next_provider_state(struct irlan_cb *self, IRLAN_STATE state); | ||
80 | |||
81 | #endif | ||
diff --git a/include/net/irda/irlan_filter.h b/include/net/irda/irlan_filter.h new file mode 100644 index 000000000000..3afeb6c94ea4 --- /dev/null +++ b/include/net/irda/irlan_filter.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irlan_filter.h | ||
4 | * Version: | ||
5 | * Description: | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Fri Jan 29 15:24:08 1999 | ||
9 | * Modified at: Sun Feb 7 23:35:31 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1998 Dag Brattli, All Rights Reserved. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
20 | * provide warranty for any of this software. This material is | ||
21 | * provided "AS-IS" and at no charge. | ||
22 | * | ||
23 | ********************************************************************/ | ||
24 | |||
25 | #ifndef IRLAN_FILTER_H | ||
26 | #define IRLAN_FILTER_H | ||
27 | |||
28 | void irlan_check_command_param(struct irlan_cb *self, char *param, | ||
29 | char *value); | ||
30 | void irlan_filter_request(struct irlan_cb *self, struct sk_buff *skb); | ||
31 | int irlan_print_filter(struct seq_file *seq, int filter_type); | ||
32 | |||
33 | #endif /* IRLAN_FILTER_H */ | ||
diff --git a/include/net/irda/irlan_provider.h b/include/net/irda/irlan_provider.h new file mode 100644 index 000000000000..ca51d5b7c999 --- /dev/null +++ b/include/net/irda/irlan_provider.h | |||
@@ -0,0 +1,52 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irlan_provider.h | ||
4 | * Version: 0.1 | ||
5 | * Description: IrDA LAN access layer | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Sun Aug 31 20:14:37 1997 | ||
9 | * Modified at: Sun May 9 12:26:11 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
20 | * provide warranty for any of this software. This material is | ||
21 | * provided "AS-IS" and at no charge. | ||
22 | * | ||
23 | ********************************************************************/ | ||
24 | |||
25 | #ifndef IRLAN_SERVER_H | ||
26 | #define IRLAN_SERVER_H | ||
27 | |||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/types.h> | ||
30 | #include <linux/skbuff.h> | ||
31 | #include <linux/netdevice.h> | ||
32 | |||
33 | #include <net/irda/irlan_common.h> | ||
34 | |||
35 | void irlan_provider_ctrl_disconnect_indication(void *instance, void *sap, | ||
36 | LM_REASON reason, | ||
37 | struct sk_buff *skb); | ||
38 | |||
39 | |||
40 | void irlan_provider_connect_response(struct irlan_cb *, struct tsap_cb *); | ||
41 | |||
42 | int irlan_parse_open_data_cmd(struct irlan_cb *self, struct sk_buff *skb); | ||
43 | int irlan_provider_parse_command(struct irlan_cb *self, int cmd, | ||
44 | struct sk_buff *skb); | ||
45 | |||
46 | void irlan_provider_send_reply(struct irlan_cb *self, int command, | ||
47 | int ret_code); | ||
48 | int irlan_provider_open_ctrl_tsap(struct irlan_cb *self); | ||
49 | |||
50 | #endif | ||
51 | |||
52 | |||
diff --git a/include/net/irda/irlap.h b/include/net/irda/irlap.h new file mode 100644 index 000000000000..f55e86e75030 --- /dev/null +++ b/include/net/irda/irlap.h | |||
@@ -0,0 +1,290 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irlap.h | ||
4 | * Version: 0.8 | ||
5 | * Description: An IrDA LAP driver for Linux | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Mon Aug 4 20:40:53 1997 | ||
9 | * Modified at: Fri Dec 10 13:21:17 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, | ||
13 | * All Rights Reserved. | ||
14 | * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com> | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or | ||
17 | * modify it under the terms of the GNU General Public License as | ||
18 | * published by the Free Software Foundation; either version 2 of | ||
19 | * the License, or (at your option) any later version. | ||
20 | * | ||
21 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
22 | * provide warranty for any of this software. This material is | ||
23 | * provided "AS-IS" and at no charge. | ||
24 | * | ||
25 | ********************************************************************/ | ||
26 | |||
27 | #ifndef IRLAP_H | ||
28 | #define IRLAP_H | ||
29 | |||
30 | #include <linux/config.h> | ||
31 | #include <linux/types.h> | ||
32 | #include <linux/skbuff.h> | ||
33 | #include <linux/netdevice.h> | ||
34 | #include <linux/timer.h> | ||
35 | |||
36 | #include <net/irda/irqueue.h> /* irda_queue_t */ | ||
37 | #include <net/irda/qos.h> /* struct qos_info */ | ||
38 | #include <net/irda/discovery.h> /* discovery_t */ | ||
39 | #include <net/irda/irlap_event.h> /* IRLAP_STATE, ... */ | ||
40 | #include <net/irda/irmod.h> /* struct notify_t */ | ||
41 | |||
42 | #define CONFIG_IRDA_DYNAMIC_WINDOW 1 | ||
43 | |||
44 | #define LAP_RELIABLE 1 | ||
45 | #define LAP_UNRELIABLE 0 | ||
46 | |||
47 | #define LAP_ADDR_HEADER 1 /* IrLAP Address Header */ | ||
48 | #define LAP_CTRL_HEADER 1 /* IrLAP Control Header */ | ||
49 | |||
50 | /* May be different when we get VFIR */ | ||
51 | #define LAP_MAX_HEADER (LAP_ADDR_HEADER + LAP_CTRL_HEADER) | ||
52 | |||
53 | #define BROADCAST 0xffffffff /* Broadcast device address */ | ||
54 | #define CBROADCAST 0xfe /* Connection broadcast address */ | ||
55 | #define XID_FORMAT 0x01 /* Discovery XID format */ | ||
56 | |||
57 | /* Nobody seems to use this constant. */ | ||
58 | #define LAP_WINDOW_SIZE 8 | ||
59 | /* We keep the LAP queue very small to minimise the amount of buffering. | ||
60 | * this improve latency and reduce resource consumption. | ||
61 | * This work only because we have synchronous refilling of IrLAP through | ||
62 | * the flow control mechanism (via scheduler and IrTTP). | ||
63 | * 2 buffers is the minimum we can work with, one that we send while polling | ||
64 | * IrTTP, and another to know that we should not send the pf bit. | ||
65 | * Jean II */ | ||
66 | #define LAP_HIGH_THRESHOLD 2 | ||
67 | /* Some rare non TTP clients don't implement flow control, and | ||
68 | * so don't comply with the above limit (and neither with this one). | ||
69 | * For IAP and management, it doesn't matter, because they never transmit much. | ||
70 | *.For IrLPT, this should be fixed. | ||
71 | * - Jean II */ | ||
72 | #define LAP_MAX_QUEUE 10 | ||
73 | /* Please note that all IrDA management frames (LMP/TTP conn req/disc and | ||
74 | * IAS queries) fall in the second category and are sent to LAP even if TTP | ||
75 | * is stopped. This means that those frames will wait only a maximum of | ||
76 | * two (2) data frames before beeing sent on the "wire", which speed up | ||
77 | * new socket setup when the link is saturated. | ||
78 | * Same story for two sockets competing for the medium : if one saturates | ||
79 | * the LAP, when the other want to transmit it only has to wait for | ||
80 | * maximum three (3) packets (2 + one scheduling), which improve performance | ||
81 | * of delay sensitive applications. | ||
82 | * Jean II */ | ||
83 | |||
84 | #define NR_EXPECTED 1 | ||
85 | #define NR_UNEXPECTED 0 | ||
86 | #define NR_INVALID -1 | ||
87 | |||
88 | #define NS_EXPECTED 1 | ||
89 | #define NS_UNEXPECTED 0 | ||
90 | #define NS_INVALID -1 | ||
91 | |||
92 | /* | ||
93 | * Meta information passed within the IrLAP state machine | ||
94 | */ | ||
95 | struct irlap_info { | ||
96 | __u8 caddr; /* Connection address */ | ||
97 | __u8 control; /* Frame type */ | ||
98 | __u8 cmd; | ||
99 | |||
100 | __u32 saddr; | ||
101 | __u32 daddr; | ||
102 | |||
103 | int pf; /* Poll/final bit set */ | ||
104 | |||
105 | __u8 nr; /* Sequence number of next frame expected */ | ||
106 | __u8 ns; /* Sequence number of frame sent */ | ||
107 | |||
108 | int S; /* Number of slots */ | ||
109 | int slot; /* Random chosen slot */ | ||
110 | int s; /* Current slot */ | ||
111 | |||
112 | discovery_t *discovery; /* Discovery information */ | ||
113 | }; | ||
114 | |||
115 | /* Main structure of IrLAP */ | ||
116 | struct irlap_cb { | ||
117 | irda_queue_t q; /* Must be first */ | ||
118 | magic_t magic; | ||
119 | |||
120 | /* Device we are attached to */ | ||
121 | struct net_device *netdev; | ||
122 | char hw_name[2*IFNAMSIZ + 1]; | ||
123 | |||
124 | /* Connection state */ | ||
125 | volatile IRLAP_STATE state; /* Current state */ | ||
126 | |||
127 | /* Timers used by IrLAP */ | ||
128 | struct timer_list query_timer; | ||
129 | struct timer_list slot_timer; | ||
130 | struct timer_list discovery_timer; | ||
131 | struct timer_list final_timer; | ||
132 | struct timer_list poll_timer; | ||
133 | struct timer_list wd_timer; | ||
134 | struct timer_list backoff_timer; | ||
135 | |||
136 | /* Media busy stuff */ | ||
137 | struct timer_list media_busy_timer; | ||
138 | int media_busy; | ||
139 | |||
140 | /* Timeouts which will be different with different turn time */ | ||
141 | int slot_timeout; | ||
142 | int poll_timeout; | ||
143 | int final_timeout; | ||
144 | int wd_timeout; | ||
145 | |||
146 | struct sk_buff_head txq; /* Frames to be transmitted */ | ||
147 | struct sk_buff_head txq_ultra; | ||
148 | |||
149 | __u8 caddr; /* Connection address */ | ||
150 | __u32 saddr; /* Source device address */ | ||
151 | __u32 daddr; /* Destination device address */ | ||
152 | |||
153 | int retry_count; /* Times tried to establish connection */ | ||
154 | int add_wait; /* True if we are waiting for frame */ | ||
155 | |||
156 | __u8 connect_pending; | ||
157 | __u8 disconnect_pending; | ||
158 | |||
159 | /* To send a faster RR if tx queue empty */ | ||
160 | #ifdef CONFIG_IRDA_FAST_RR | ||
161 | int fast_RR_timeout; | ||
162 | int fast_RR; | ||
163 | #endif /* CONFIG_IRDA_FAST_RR */ | ||
164 | |||
165 | int N1; /* N1 * F-timer = Negitiated link disconnect warning threshold */ | ||
166 | int N2; /* N2 * F-timer = Negitiated link disconnect time */ | ||
167 | int N3; /* Connection retry count */ | ||
168 | |||
169 | int local_busy; | ||
170 | int remote_busy; | ||
171 | int xmitflag; | ||
172 | |||
173 | __u8 vs; /* Next frame to be sent */ | ||
174 | __u8 vr; /* Next frame to be received */ | ||
175 | __u8 va; /* Last frame acked */ | ||
176 | int window; /* Nr of I-frames allowed to send */ | ||
177 | int window_size; /* Current negotiated window size */ | ||
178 | |||
179 | #ifdef CONFIG_IRDA_DYNAMIC_WINDOW | ||
180 | __u32 line_capacity; /* Number of bytes allowed to send */ | ||
181 | __u32 bytes_left; /* Number of bytes still allowed to transmit */ | ||
182 | #endif /* CONFIG_IRDA_DYNAMIC_WINDOW */ | ||
183 | |||
184 | struct sk_buff_head wx_list; | ||
185 | |||
186 | __u8 ack_required; | ||
187 | |||
188 | /* XID parameters */ | ||
189 | __u8 S; /* Number of slots */ | ||
190 | __u8 slot; /* Random chosen slot */ | ||
191 | __u8 s; /* Current slot */ | ||
192 | int frame_sent; /* Have we sent reply? */ | ||
193 | |||
194 | hashbin_t *discovery_log; | ||
195 | discovery_t *discovery_cmd; | ||
196 | |||
197 | __u32 speed; /* Link speed */ | ||
198 | |||
199 | struct qos_info qos_tx; /* QoS requested by peer */ | ||
200 | struct qos_info qos_rx; /* QoS requested by self */ | ||
201 | struct qos_info *qos_dev; /* QoS supported by device */ | ||
202 | |||
203 | notify_t notify; /* Callbacks to IrLMP */ | ||
204 | |||
205 | int mtt_required; /* Minumum turnaround time required */ | ||
206 | int xbofs_delay; /* Nr of XBOF's used to MTT */ | ||
207 | int bofs_count; /* Negotiated extra BOFs */ | ||
208 | int next_bofs; /* Negotiated extra BOFs after next frame */ | ||
209 | }; | ||
210 | |||
211 | /* | ||
212 | * Function prototypes | ||
213 | */ | ||
214 | int irlap_init(void); | ||
215 | void irlap_cleanup(void); | ||
216 | |||
217 | struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos, | ||
218 | const char *hw_name); | ||
219 | void irlap_close(struct irlap_cb *self); | ||
220 | |||
221 | void irlap_connect_request(struct irlap_cb *self, __u32 daddr, | ||
222 | struct qos_info *qos, int sniff); | ||
223 | void irlap_connect_response(struct irlap_cb *self, struct sk_buff *skb); | ||
224 | void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb); | ||
225 | void irlap_connect_confirm(struct irlap_cb *, struct sk_buff *skb); | ||
226 | |||
227 | void irlap_data_indication(struct irlap_cb *, struct sk_buff *, int unreliable); | ||
228 | void irlap_data_request(struct irlap_cb *, struct sk_buff *, int unreliable); | ||
229 | |||
230 | #ifdef CONFIG_IRDA_ULTRA | ||
231 | void irlap_unitdata_request(struct irlap_cb *, struct sk_buff *); | ||
232 | void irlap_unitdata_indication(struct irlap_cb *, struct sk_buff *); | ||
233 | #endif /* CONFIG_IRDA_ULTRA */ | ||
234 | |||
235 | void irlap_disconnect_request(struct irlap_cb *); | ||
236 | void irlap_disconnect_indication(struct irlap_cb *, LAP_REASON reason); | ||
237 | |||
238 | void irlap_status_indication(struct irlap_cb *, int quality_of_link); | ||
239 | |||
240 | void irlap_test_request(__u8 *info, int len); | ||
241 | |||
242 | void irlap_discovery_request(struct irlap_cb *, discovery_t *discovery); | ||
243 | void irlap_discovery_confirm(struct irlap_cb *, hashbin_t *discovery_log); | ||
244 | void irlap_discovery_indication(struct irlap_cb *, discovery_t *discovery); | ||
245 | |||
246 | void irlap_reset_indication(struct irlap_cb *self); | ||
247 | void irlap_reset_confirm(void); | ||
248 | |||
249 | void irlap_update_nr_received(struct irlap_cb *, int nr); | ||
250 | int irlap_validate_nr_received(struct irlap_cb *, int nr); | ||
251 | int irlap_validate_ns_received(struct irlap_cb *, int ns); | ||
252 | |||
253 | int irlap_generate_rand_time_slot(int S, int s); | ||
254 | void irlap_initiate_connection_state(struct irlap_cb *); | ||
255 | void irlap_flush_all_queues(struct irlap_cb *); | ||
256 | void irlap_wait_min_turn_around(struct irlap_cb *, struct qos_info *); | ||
257 | |||
258 | void irlap_apply_default_connection_parameters(struct irlap_cb *self); | ||
259 | void irlap_apply_connection_parameters(struct irlap_cb *self, int now); | ||
260 | |||
261 | #define IRLAP_GET_HEADER_SIZE(self) (LAP_MAX_HEADER) | ||
262 | #define IRLAP_GET_TX_QUEUE_LEN(self) skb_queue_len(&self->txq) | ||
263 | |||
264 | /* Return TRUE if the node is in primary mode (i.e. master) | ||
265 | * - Jean II */ | ||
266 | static inline int irlap_is_primary(struct irlap_cb *self) | ||
267 | { | ||
268 | int ret; | ||
269 | switch(self->state) { | ||
270 | case LAP_XMIT_P: | ||
271 | case LAP_NRM_P: | ||
272 | ret = 1; | ||
273 | break; | ||
274 | case LAP_XMIT_S: | ||
275 | case LAP_NRM_S: | ||
276 | ret = 0; | ||
277 | break; | ||
278 | default: | ||
279 | ret = -1; | ||
280 | } | ||
281 | return(ret); | ||
282 | } | ||
283 | |||
284 | /* Clear a pending IrLAP disconnect. - Jean II */ | ||
285 | static inline void irlap_clear_disconnect(struct irlap_cb *self) | ||
286 | { | ||
287 | self->disconnect_pending = FALSE; | ||
288 | } | ||
289 | |||
290 | #endif | ||
diff --git a/include/net/irda/irlap_event.h b/include/net/irda/irlap_event.h new file mode 100644 index 000000000000..2ae2e119ef4b --- /dev/null +++ b/include/net/irda/irlap_event.h | |||
@@ -0,0 +1,131 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * | ||
4 | * Filename: irlap_event.h | ||
5 | * Version: 0.1 | ||
6 | * Description: | ||
7 | * Status: Experimental. | ||
8 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
9 | * Created at: Sat Aug 16 00:59:29 1997 | ||
10 | * Modified at: Tue Dec 21 11:20:30 1999 | ||
11 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
12 | * | ||
13 | * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, | ||
14 | * All Rights Reserved. | ||
15 | * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com> | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or | ||
18 | * modify it under the terms of the GNU General Public License as | ||
19 | * published by the Free Software Foundation; either version 2 of | ||
20 | * the License, or (at your option) any later version. | ||
21 | * | ||
22 | * This program is distributed in the hope that it will be useful, | ||
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
25 | * GNU General Public License for more details. | ||
26 | * | ||
27 | * You should have received a copy of the GNU General Public License | ||
28 | * along with this program; if not, write to the Free Software | ||
29 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
30 | * MA 02111-1307 USA | ||
31 | * | ||
32 | ********************************************************************/ | ||
33 | |||
34 | #ifndef IRLAP_EVENT_H | ||
35 | #define IRLAP_EVENT_H | ||
36 | |||
37 | #include <net/irda/irda.h> | ||
38 | |||
39 | /* A few forward declarations (to make compiler happy) */ | ||
40 | struct irlap_cb; | ||
41 | struct irlap_info; | ||
42 | |||
43 | /* IrLAP States */ | ||
44 | typedef enum { | ||
45 | LAP_NDM, /* Normal disconnected mode */ | ||
46 | LAP_QUERY, | ||
47 | LAP_REPLY, | ||
48 | LAP_CONN, /* Connect indication */ | ||
49 | LAP_SETUP, /* Setting up connection */ | ||
50 | LAP_OFFLINE, /* A really boring state */ | ||
51 | LAP_XMIT_P, | ||
52 | LAP_PCLOSE, | ||
53 | LAP_NRM_P, /* Normal response mode as primary */ | ||
54 | LAP_RESET_WAIT, | ||
55 | LAP_RESET, | ||
56 | LAP_NRM_S, /* Normal response mode as secondary */ | ||
57 | LAP_XMIT_S, | ||
58 | LAP_SCLOSE, | ||
59 | LAP_RESET_CHECK, | ||
60 | } IRLAP_STATE; | ||
61 | |||
62 | /* IrLAP Events */ | ||
63 | typedef enum { | ||
64 | /* Services events */ | ||
65 | DISCOVERY_REQUEST, | ||
66 | CONNECT_REQUEST, | ||
67 | CONNECT_RESPONSE, | ||
68 | DISCONNECT_REQUEST, | ||
69 | DATA_REQUEST, | ||
70 | RESET_REQUEST, | ||
71 | RESET_RESPONSE, | ||
72 | |||
73 | /* Send events */ | ||
74 | SEND_I_CMD, | ||
75 | SEND_UI_FRAME, | ||
76 | |||
77 | /* Receive events */ | ||
78 | RECV_DISCOVERY_XID_CMD, | ||
79 | RECV_DISCOVERY_XID_RSP, | ||
80 | RECV_SNRM_CMD, | ||
81 | RECV_TEST_CMD, | ||
82 | RECV_TEST_RSP, | ||
83 | RECV_UA_RSP, | ||
84 | RECV_DM_RSP, | ||
85 | RECV_RD_RSP, | ||
86 | RECV_I_CMD, | ||
87 | RECV_I_RSP, | ||
88 | RECV_UI_FRAME, | ||
89 | RECV_FRMR_RSP, | ||
90 | RECV_RR_CMD, | ||
91 | RECV_RR_RSP, | ||
92 | RECV_RNR_CMD, | ||
93 | RECV_RNR_RSP, | ||
94 | RECV_REJ_CMD, | ||
95 | RECV_REJ_RSP, | ||
96 | RECV_SREJ_CMD, | ||
97 | RECV_SREJ_RSP, | ||
98 | RECV_DISC_CMD, | ||
99 | |||
100 | /* Timer events */ | ||
101 | SLOT_TIMER_EXPIRED, | ||
102 | QUERY_TIMER_EXPIRED, | ||
103 | FINAL_TIMER_EXPIRED, | ||
104 | POLL_TIMER_EXPIRED, | ||
105 | DISCOVERY_TIMER_EXPIRED, | ||
106 | WD_TIMER_EXPIRED, | ||
107 | BACKOFF_TIMER_EXPIRED, | ||
108 | MEDIA_BUSY_TIMER_EXPIRED, | ||
109 | } IRLAP_EVENT; | ||
110 | |||
111 | /* | ||
112 | * Disconnect reason code | ||
113 | */ | ||
114 | typedef enum { /* FIXME check the two first reason codes */ | ||
115 | LAP_DISC_INDICATION=1, /* Received a disconnect request from peer */ | ||
116 | LAP_NO_RESPONSE, /* To many retransmits without response */ | ||
117 | LAP_RESET_INDICATION, /* To many retransmits, or invalid nr/ns */ | ||
118 | LAP_FOUND_NONE, /* No devices were discovered */ | ||
119 | LAP_MEDIA_BUSY, | ||
120 | LAP_PRIMARY_CONFLICT, | ||
121 | } LAP_REASON; | ||
122 | |||
123 | extern const char *irlap_state[]; | ||
124 | |||
125 | void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event, | ||
126 | struct sk_buff *skb, struct irlap_info *info); | ||
127 | void irlap_print_event(IRLAP_EVENT event); | ||
128 | |||
129 | extern int irlap_qos_negotiate(struct irlap_cb *self, struct sk_buff *skb); | ||
130 | |||
131 | #endif | ||
diff --git a/include/net/irda/irlap_frame.h b/include/net/irda/irlap_frame.h new file mode 100644 index 000000000000..3452ae257c84 --- /dev/null +++ b/include/net/irda/irlap_frame.h | |||
@@ -0,0 +1,142 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irlap_frame.h | ||
4 | * Version: 0.9 | ||
5 | * Description: IrLAP frame declarations | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Tue Aug 19 10:27:26 1997 | ||
9 | * Modified at: Sat Dec 25 21:07:26 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1997-1999 Dag Brattli <dagb@cs.uit.no>, | ||
13 | * All Rights Reserved. | ||
14 | * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com> | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or | ||
17 | * modify it under the terms of the GNU General Public License as | ||
18 | * published by the Free Software Foundation; either version 2 of | ||
19 | * the License, or (at your option) any later version. | ||
20 | * | ||
21 | * This program is distributed in the hope that it will be useful, | ||
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
24 | * GNU General Public License for more details. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License | ||
27 | * along with this program; if not, write to the Free Software | ||
28 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
29 | * MA 02111-1307 USA | ||
30 | * | ||
31 | ********************************************************************/ | ||
32 | |||
33 | #ifndef IRLAP_FRAME_H | ||
34 | #define IRLAP_FRAME_H | ||
35 | |||
36 | #include <linux/skbuff.h> | ||
37 | |||
38 | #include <net/irda/irda.h> | ||
39 | |||
40 | /* A few forward declarations (to make compiler happy) */ | ||
41 | struct irlap_cb; | ||
42 | struct discovery_t; | ||
43 | |||
44 | /* Frame types and templates */ | ||
45 | #define INVALID 0xff | ||
46 | |||
47 | /* Unnumbered (U) commands */ | ||
48 | #define SNRM_CMD 0x83 /* Set Normal Response Mode */ | ||
49 | #define DISC_CMD 0x43 /* Disconnect */ | ||
50 | #define XID_CMD 0x2f /* Exchange Station Identification */ | ||
51 | #define TEST_CMD 0xe3 /* Test */ | ||
52 | |||
53 | /* Unnumbered responses */ | ||
54 | #define RNRM_RSP 0x83 /* Request Normal Response Mode */ | ||
55 | #define UA_RSP 0x63 /* Unnumbered Acknowledgement */ | ||
56 | #define FRMR_RSP 0x87 /* Frame Reject */ | ||
57 | #define DM_RSP 0x0f /* Disconnect Mode */ | ||
58 | #define RD_RSP 0x43 /* Request Disconnection */ | ||
59 | #define XID_RSP 0xaf /* Exchange Station Identification */ | ||
60 | #define TEST_RSP 0xe3 /* Test frame */ | ||
61 | |||
62 | /* Supervisory (S) */ | ||
63 | #define RR 0x01 /* Receive Ready */ | ||
64 | #define REJ 0x09 /* Reject */ | ||
65 | #define RNR 0x05 /* Receive Not Ready */ | ||
66 | #define SREJ 0x0d /* Selective Reject */ | ||
67 | |||
68 | /* Information (I) */ | ||
69 | #define I_FRAME 0x00 /* Information Format */ | ||
70 | #define UI_FRAME 0x03 /* Unnumbered Information */ | ||
71 | |||
72 | #define CMD_FRAME 0x01 | ||
73 | #define RSP_FRAME 0x00 | ||
74 | |||
75 | #define PF_BIT 0x10 /* Poll/final bit */ | ||
76 | |||
77 | struct xid_frame { | ||
78 | __u8 caddr; /* Connection address */ | ||
79 | __u8 control; | ||
80 | __u8 ident; /* Should always be XID_FORMAT */ | ||
81 | __u32 saddr; /* Source device address */ | ||
82 | __u32 daddr; /* Destination device address */ | ||
83 | __u8 flags; /* Discovery flags */ | ||
84 | __u8 slotnr; | ||
85 | __u8 version; | ||
86 | } IRDA_PACK; | ||
87 | |||
88 | struct test_frame { | ||
89 | __u8 caddr; /* Connection address */ | ||
90 | __u8 control; | ||
91 | __u32 saddr; /* Source device address */ | ||
92 | __u32 daddr; /* Destination device address */ | ||
93 | } IRDA_PACK; | ||
94 | |||
95 | struct ua_frame { | ||
96 | __u8 caddr; | ||
97 | __u8 control; | ||
98 | |||
99 | __u32 saddr; /* Source device address */ | ||
100 | __u32 daddr; /* Dest device address */ | ||
101 | } IRDA_PACK; | ||
102 | |||
103 | struct i_frame { | ||
104 | __u8 caddr; | ||
105 | __u8 control; | ||
106 | } IRDA_PACK; | ||
107 | |||
108 | struct snrm_frame { | ||
109 | __u8 caddr; | ||
110 | __u8 control; | ||
111 | __u32 saddr; | ||
112 | __u32 daddr; | ||
113 | __u8 ncaddr; | ||
114 | } IRDA_PACK; | ||
115 | |||
116 | void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb); | ||
117 | void irlap_send_discovery_xid_frame(struct irlap_cb *, int S, __u8 s, | ||
118 | __u8 command, | ||
119 | struct discovery_t *discovery); | ||
120 | void irlap_send_snrm_frame(struct irlap_cb *, struct qos_info *); | ||
121 | void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr, | ||
122 | struct sk_buff *cmd); | ||
123 | void irlap_send_ua_response_frame(struct irlap_cb *, struct qos_info *); | ||
124 | void irlap_send_dm_frame(struct irlap_cb *self); | ||
125 | void irlap_send_rd_frame(struct irlap_cb *self); | ||
126 | void irlap_send_disc_frame(struct irlap_cb *self); | ||
127 | void irlap_send_rr_frame(struct irlap_cb *self, int command); | ||
128 | |||
129 | void irlap_send_data_primary(struct irlap_cb *, struct sk_buff *); | ||
130 | void irlap_send_data_primary_poll(struct irlap_cb *, struct sk_buff *); | ||
131 | void irlap_send_data_secondary(struct irlap_cb *, struct sk_buff *); | ||
132 | void irlap_send_data_secondary_final(struct irlap_cb *, struct sk_buff *); | ||
133 | void irlap_resend_rejected_frames(struct irlap_cb *, int command); | ||
134 | void irlap_resend_rejected_frame(struct irlap_cb *self, int command); | ||
135 | |||
136 | void irlap_send_ui_frame(struct irlap_cb *self, struct sk_buff *skb, | ||
137 | __u8 caddr, int command); | ||
138 | |||
139 | extern int irlap_insert_qos_negotiation_params(struct irlap_cb *self, | ||
140 | struct sk_buff *skb); | ||
141 | |||
142 | #endif | ||
diff --git a/include/net/irda/irlmp.h b/include/net/irda/irlmp.h new file mode 100644 index 000000000000..86aefb1fda5e --- /dev/null +++ b/include/net/irda/irlmp.h | |||
@@ -0,0 +1,295 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irlmp.h | ||
4 | * Version: 0.9 | ||
5 | * Description: IrDA Link Management Protocol (LMP) layer | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Sun Aug 17 20:54:32 1997 | ||
9 | * Modified at: Fri Dec 10 13:23:01 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, | ||
13 | * All Rights Reserved. | ||
14 | * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com> | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or | ||
17 | * modify it under the terms of the GNU General Public License as | ||
18 | * published by the Free Software Foundation; either version 2 of | ||
19 | * the License, or (at your option) any later version. | ||
20 | * | ||
21 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
22 | * provide warranty for any of this software. This material is | ||
23 | * provided "AS-IS" and at no charge. | ||
24 | * | ||
25 | ********************************************************************/ | ||
26 | |||
27 | #ifndef IRLMP_H | ||
28 | #define IRLMP_H | ||
29 | |||
30 | #include <asm/param.h> /* for HZ */ | ||
31 | |||
32 | #include <linux/config.h> | ||
33 | #include <linux/types.h> | ||
34 | |||
35 | #include <net/irda/irda.h> | ||
36 | #include <net/irda/qos.h> | ||
37 | #include <net/irda/irlap.h> /* LAP_MAX_HEADER, ... */ | ||
38 | #include <net/irda/irlmp_event.h> | ||
39 | #include <net/irda/irqueue.h> | ||
40 | #include <net/irda/discovery.h> | ||
41 | |||
42 | /* LSAP-SEL's */ | ||
43 | #define LSAP_MASK 0x7f | ||
44 | #define LSAP_IAS 0x00 | ||
45 | #define LSAP_ANY 0xff | ||
46 | #define LSAP_MAX 0x6f /* 0x70-0x7f are reserved */ | ||
47 | #define LSAP_CONNLESS 0x70 /* Connectionless LSAP, mostly used for Ultra */ | ||
48 | |||
49 | #define DEV_ADDR_ANY 0xffffffff | ||
50 | |||
51 | #define LMP_HEADER 2 /* Dest LSAP + Source LSAP */ | ||
52 | #define LMP_CONTROL_HEADER 4 | ||
53 | #define LMP_PID_HEADER 1 /* Used by Ultra */ | ||
54 | #define LMP_MAX_HEADER (LMP_CONTROL_HEADER+LAP_MAX_HEADER) | ||
55 | |||
56 | #define LM_MAX_CONNECTIONS 10 | ||
57 | |||
58 | #define LM_IDLE_TIMEOUT 2*HZ /* 2 seconds for now */ | ||
59 | |||
60 | typedef enum { | ||
61 | S_PNP = 0, | ||
62 | S_PDA, | ||
63 | S_COMPUTER, | ||
64 | S_PRINTER, | ||
65 | S_MODEM, | ||
66 | S_FAX, | ||
67 | S_LAN, | ||
68 | S_TELEPHONY, | ||
69 | S_COMM, | ||
70 | S_OBEX, | ||
71 | S_ANY, | ||
72 | S_END, | ||
73 | } SERVICE; | ||
74 | |||
75 | /* For selective discovery */ | ||
76 | typedef void (*DISCOVERY_CALLBACK1) (discinfo_t *, DISCOVERY_MODE, void *); | ||
77 | /* For expiry (the same) */ | ||
78 | typedef void (*DISCOVERY_CALLBACK2) (discinfo_t *, DISCOVERY_MODE, void *); | ||
79 | |||
80 | typedef struct { | ||
81 | irda_queue_t queue; /* Must be first */ | ||
82 | |||
83 | __u16_host_order hints; /* Hint bits */ | ||
84 | } irlmp_service_t; | ||
85 | |||
86 | typedef struct { | ||
87 | irda_queue_t queue; /* Must be first */ | ||
88 | |||
89 | __u16_host_order hint_mask; | ||
90 | |||
91 | DISCOVERY_CALLBACK1 disco_callback; /* Selective discovery */ | ||
92 | DISCOVERY_CALLBACK2 expir_callback; /* Selective expiration */ | ||
93 | void *priv; /* Used to identify client */ | ||
94 | } irlmp_client_t; | ||
95 | |||
96 | /* | ||
97 | * Information about each logical LSAP connection | ||
98 | */ | ||
99 | struct lsap_cb { | ||
100 | irda_queue_t queue; /* Must be first */ | ||
101 | magic_t magic; | ||
102 | |||
103 | unsigned long connected; /* set_bit used on this */ | ||
104 | int persistent; | ||
105 | |||
106 | __u8 slsap_sel; /* Source (this) LSAP address */ | ||
107 | __u8 dlsap_sel; /* Destination LSAP address (if connected) */ | ||
108 | #ifdef CONFIG_IRDA_ULTRA | ||
109 | __u8 pid; /* Used by connectionless LSAP */ | ||
110 | #endif /* CONFIG_IRDA_ULTRA */ | ||
111 | struct sk_buff *conn_skb; /* Store skb here while connecting */ | ||
112 | |||
113 | struct timer_list watchdog_timer; | ||
114 | |||
115 | IRLMP_STATE lsap_state; /* Connection state */ | ||
116 | notify_t notify; /* Indication/Confirm entry points */ | ||
117 | struct qos_info qos; /* QoS for this connection */ | ||
118 | |||
119 | struct lap_cb *lap; /* Pointer to LAP connection structure */ | ||
120 | }; | ||
121 | |||
122 | /* | ||
123 | * Used for caching the last slsap->dlsap->handle mapping | ||
124 | * | ||
125 | * We don't need to keep/match the remote address in the cache because | ||
126 | * we are associated with a specific LAP (which implies it). | ||
127 | * Jean II | ||
128 | */ | ||
129 | typedef struct { | ||
130 | int valid; | ||
131 | |||
132 | __u8 slsap_sel; | ||
133 | __u8 dlsap_sel; | ||
134 | struct lsap_cb *lsap; | ||
135 | } CACHE_ENTRY; | ||
136 | |||
137 | /* | ||
138 | * Information about each registred IrLAP layer | ||
139 | */ | ||
140 | struct lap_cb { | ||
141 | irda_queue_t queue; /* Must be first */ | ||
142 | magic_t magic; | ||
143 | |||
144 | int reason; /* LAP disconnect reason */ | ||
145 | |||
146 | IRLMP_STATE lap_state; | ||
147 | |||
148 | struct irlap_cb *irlap; /* Instance of IrLAP layer */ | ||
149 | hashbin_t *lsaps; /* LSAP associated with this link */ | ||
150 | struct lsap_cb *flow_next; /* Next lsap to be polled for Tx */ | ||
151 | |||
152 | __u8 caddr; /* Connection address */ | ||
153 | __u32 saddr; /* Source device address */ | ||
154 | __u32 daddr; /* Destination device address */ | ||
155 | |||
156 | struct qos_info *qos; /* LAP QoS for this session */ | ||
157 | struct timer_list idle_timer; | ||
158 | |||
159 | #ifdef CONFIG_IRDA_CACHE_LAST_LSAP | ||
160 | /* The lsap cache was moved from struct irlmp_cb to here because | ||
161 | * it must be associated with the specific LAP. Also, this | ||
162 | * improves performance. - Jean II */ | ||
163 | CACHE_ENTRY cache; /* Caching last slsap->dlsap->handle mapping */ | ||
164 | #endif | ||
165 | }; | ||
166 | |||
167 | /* | ||
168 | * Main structure for IrLMP | ||
169 | */ | ||
170 | struct irlmp_cb { | ||
171 | magic_t magic; | ||
172 | |||
173 | __u8 conflict_flag; | ||
174 | |||
175 | discovery_t discovery_cmd; /* Discovery command to use by IrLAP */ | ||
176 | discovery_t discovery_rsp; /* Discovery response to use by IrLAP */ | ||
177 | |||
178 | /* Last lsap picked automatically by irlmp_find_free_slsap() */ | ||
179 | int last_lsap_sel; | ||
180 | |||
181 | struct timer_list discovery_timer; | ||
182 | |||
183 | hashbin_t *links; /* IrLAP connection table */ | ||
184 | hashbin_t *unconnected_lsaps; | ||
185 | hashbin_t *clients; | ||
186 | hashbin_t *services; | ||
187 | |||
188 | hashbin_t *cachelog; /* Current discovery log */ | ||
189 | |||
190 | int running; | ||
191 | |||
192 | __u16_host_order hints; /* Hint bits */ | ||
193 | }; | ||
194 | |||
195 | /* Prototype declarations */ | ||
196 | int irlmp_init(void); | ||
197 | void irlmp_cleanup(void); | ||
198 | struct lsap_cb *irlmp_open_lsap(__u8 slsap, notify_t *notify, __u8 pid); | ||
199 | void irlmp_close_lsap( struct lsap_cb *self); | ||
200 | |||
201 | __u16 irlmp_service_to_hint(int service); | ||
202 | void *irlmp_register_service(__u16 hints); | ||
203 | int irlmp_unregister_service(void *handle); | ||
204 | void *irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb, | ||
205 | DISCOVERY_CALLBACK2 expir_clb, void *priv); | ||
206 | int irlmp_unregister_client(void *handle); | ||
207 | int irlmp_update_client(void *handle, __u16 hint_mask, | ||
208 | DISCOVERY_CALLBACK1 disco_clb, | ||
209 | DISCOVERY_CALLBACK2 expir_clb, void *priv); | ||
210 | |||
211 | void irlmp_register_link(struct irlap_cb *, __u32 saddr, notify_t *); | ||
212 | void irlmp_unregister_link(__u32 saddr); | ||
213 | |||
214 | int irlmp_connect_request(struct lsap_cb *, __u8 dlsap_sel, | ||
215 | __u32 saddr, __u32 daddr, | ||
216 | struct qos_info *, struct sk_buff *); | ||
217 | void irlmp_connect_indication(struct lsap_cb *self, struct sk_buff *skb); | ||
218 | int irlmp_connect_response(struct lsap_cb *, struct sk_buff *); | ||
219 | void irlmp_connect_confirm(struct lsap_cb *, struct sk_buff *); | ||
220 | struct lsap_cb *irlmp_dup(struct lsap_cb *self, void *instance); | ||
221 | |||
222 | void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason, | ||
223 | struct sk_buff *userdata); | ||
224 | int irlmp_disconnect_request(struct lsap_cb *, struct sk_buff *userdata); | ||
225 | |||
226 | void irlmp_discovery_confirm(hashbin_t *discovery_log, DISCOVERY_MODE mode); | ||
227 | void irlmp_discovery_request(int nslots); | ||
228 | discinfo_t *irlmp_get_discoveries(int *pn, __u16 mask, int nslots); | ||
229 | void irlmp_do_expiry(void); | ||
230 | void irlmp_do_discovery(int nslots); | ||
231 | discovery_t *irlmp_get_discovery_response(void); | ||
232 | void irlmp_discovery_expiry(discinfo_t *expiry, int number); | ||
233 | |||
234 | int irlmp_data_request(struct lsap_cb *, struct sk_buff *); | ||
235 | void irlmp_data_indication(struct lsap_cb *, struct sk_buff *); | ||
236 | |||
237 | int irlmp_udata_request(struct lsap_cb *, struct sk_buff *); | ||
238 | void irlmp_udata_indication(struct lsap_cb *, struct sk_buff *); | ||
239 | |||
240 | #ifdef CONFIG_IRDA_ULTRA | ||
241 | int irlmp_connless_data_request(struct lsap_cb *, struct sk_buff *, __u8); | ||
242 | void irlmp_connless_data_indication(struct lsap_cb *, struct sk_buff *); | ||
243 | #endif /* CONFIG_IRDA_ULTRA */ | ||
244 | |||
245 | void irlmp_status_indication(struct lap_cb *, LINK_STATUS link, LOCK_STATUS lock); | ||
246 | void irlmp_flow_indication(struct lap_cb *self, LOCAL_FLOW flow); | ||
247 | |||
248 | LM_REASON irlmp_convert_lap_reason(LAP_REASON); | ||
249 | |||
250 | static inline __u32 irlmp_get_saddr(const struct lsap_cb *self) | ||
251 | { | ||
252 | return (self && self->lap) ? self->lap->saddr : 0; | ||
253 | } | ||
254 | |||
255 | static inline __u32 irlmp_get_daddr(const struct lsap_cb *self) | ||
256 | { | ||
257 | return (self && self->lap) ? self->lap->daddr : 0; | ||
258 | } | ||
259 | |||
260 | extern const char *irlmp_reasons[]; | ||
261 | extern int sysctl_discovery_timeout; | ||
262 | extern int sysctl_discovery_slots; | ||
263 | extern int sysctl_discovery; | ||
264 | extern int sysctl_lap_keepalive_time; /* in ms, default is LM_IDLE_TIMEOUT */ | ||
265 | extern struct irlmp_cb *irlmp; | ||
266 | |||
267 | /* Check if LAP queue is full. | ||
268 | * Used by IrTTP for low control, see comments in irlap.h - Jean II */ | ||
269 | static inline int irlmp_lap_tx_queue_full(struct lsap_cb *self) | ||
270 | { | ||
271 | if (self == NULL) | ||
272 | return 0; | ||
273 | if (self->lap == NULL) | ||
274 | return 0; | ||
275 | if (self->lap->irlap == NULL) | ||
276 | return 0; | ||
277 | |||
278 | return(IRLAP_GET_TX_QUEUE_LEN(self->lap->irlap) >= LAP_HIGH_THRESHOLD); | ||
279 | } | ||
280 | |||
281 | /* After doing a irlmp_dup(), this get one of the two socket back into | ||
282 | * a state where it's waiting incomming connections. | ||
283 | * Note : this can be used *only* if the socket is not yet connected | ||
284 | * (i.e. NO irlmp_connect_response() done on this socket). | ||
285 | * - Jean II */ | ||
286 | static inline void irlmp_listen(struct lsap_cb *self) | ||
287 | { | ||
288 | self->dlsap_sel = LSAP_ANY; | ||
289 | self->lap = NULL; | ||
290 | self->lsap_state = LSAP_DISCONNECTED; | ||
291 | /* Started when we received the LM_CONNECT_INDICATION */ | ||
292 | del_timer(&self->watchdog_timer); | ||
293 | } | ||
294 | |||
295 | #endif | ||
diff --git a/include/net/irda/irlmp_event.h b/include/net/irda/irlmp_event.h new file mode 100644 index 000000000000..03c6f81a502a --- /dev/null +++ b/include/net/irda/irlmp_event.h | |||
@@ -0,0 +1,98 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irlmp_event.h | ||
4 | * Version: 0.1 | ||
5 | * Description: IrDA-LMP event handling | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Mon Aug 4 20:40:53 1997 | ||
9 | * Modified at: Thu Jul 8 12:18:54 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, | ||
13 | * All Rights Reserved. | ||
14 | * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com> | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or | ||
17 | * modify it under the terms of the GNU General Public License as | ||
18 | * published by the Free Software Foundation; either version 2 of | ||
19 | * the License, or (at your option) any later version. | ||
20 | * | ||
21 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
22 | * provide warranty for any of this software. This material is | ||
23 | * provided "AS-IS" and at no charge. | ||
24 | * | ||
25 | ********************************************************************/ | ||
26 | |||
27 | #ifndef IRLMP_EVENT_H | ||
28 | #define IRLMP_EVENT_H | ||
29 | |||
30 | /* A few forward declarations (to make compiler happy) */ | ||
31 | struct irlmp_cb; | ||
32 | struct lsap_cb; | ||
33 | struct lap_cb; | ||
34 | struct discovery_t; | ||
35 | |||
36 | /* LAP states */ | ||
37 | typedef enum { | ||
38 | /* IrLAP connection control states */ | ||
39 | LAP_STANDBY, /* No LAP connection */ | ||
40 | LAP_U_CONNECT, /* Starting LAP connection */ | ||
41 | LAP_ACTIVE, /* LAP connection is active */ | ||
42 | } IRLMP_STATE; | ||
43 | |||
44 | /* LSAP connection control states */ | ||
45 | typedef enum { | ||
46 | LSAP_DISCONNECTED, /* No LSAP connection */ | ||
47 | LSAP_CONNECT, /* Connect indication from peer */ | ||
48 | LSAP_CONNECT_PEND, /* Connect request from service user */ | ||
49 | LSAP_DATA_TRANSFER_READY, /* LSAP connection established */ | ||
50 | LSAP_SETUP, /* Trying to set up LSAP connection */ | ||
51 | LSAP_SETUP_PEND, /* Request to start LAP connection */ | ||
52 | } LSAP_STATE; | ||
53 | |||
54 | typedef enum { | ||
55 | /* LSAP events */ | ||
56 | LM_CONNECT_REQUEST, | ||
57 | LM_CONNECT_CONFIRM, | ||
58 | LM_CONNECT_RESPONSE, | ||
59 | LM_CONNECT_INDICATION, | ||
60 | |||
61 | LM_DISCONNECT_INDICATION, | ||
62 | LM_DISCONNECT_REQUEST, | ||
63 | |||
64 | LM_DATA_REQUEST, | ||
65 | LM_UDATA_REQUEST, | ||
66 | LM_DATA_INDICATION, | ||
67 | LM_UDATA_INDICATION, | ||
68 | |||
69 | LM_WATCHDOG_TIMEOUT, | ||
70 | |||
71 | /* IrLAP events */ | ||
72 | LM_LAP_CONNECT_REQUEST, | ||
73 | LM_LAP_CONNECT_INDICATION, | ||
74 | LM_LAP_CONNECT_CONFIRM, | ||
75 | LM_LAP_DISCONNECT_INDICATION, | ||
76 | LM_LAP_DISCONNECT_REQUEST, | ||
77 | LM_LAP_DISCOVERY_REQUEST, | ||
78 | LM_LAP_DISCOVERY_CONFIRM, | ||
79 | LM_LAP_IDLE_TIMEOUT, | ||
80 | } IRLMP_EVENT; | ||
81 | |||
82 | extern const char *irlmp_state[]; | ||
83 | extern const char *irlsap_state[]; | ||
84 | |||
85 | void irlmp_watchdog_timer_expired(void *data); | ||
86 | void irlmp_discovery_timer_expired(void *data); | ||
87 | void irlmp_idle_timer_expired(void *data); | ||
88 | |||
89 | void irlmp_do_lap_event(struct lap_cb *self, IRLMP_EVENT event, | ||
90 | struct sk_buff *skb); | ||
91 | int irlmp_do_lsap_event(struct lsap_cb *self, IRLMP_EVENT event, | ||
92 | struct sk_buff *skb); | ||
93 | |||
94 | #endif /* IRLMP_EVENT_H */ | ||
95 | |||
96 | |||
97 | |||
98 | |||
diff --git a/include/net/irda/irlmp_frame.h b/include/net/irda/irlmp_frame.h new file mode 100644 index 000000000000..eb3ad158c023 --- /dev/null +++ b/include/net/irda/irlmp_frame.h | |||
@@ -0,0 +1,63 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irlmp_frame.h | ||
4 | * Version: 0.9 | ||
5 | * Description: | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Tue Aug 19 02:09:59 1997 | ||
9 | * Modified at: Fri Dec 10 13:21:53 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, | ||
13 | * All Rights Reserved. | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License as | ||
17 | * published by the Free Software Foundation; either version 2 of | ||
18 | * the License, or (at your option) any later version. | ||
19 | * | ||
20 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
21 | * provide warranty for any of this software. This material is | ||
22 | * provided "AS-IS" and at no charge. | ||
23 | * | ||
24 | ********************************************************************/ | ||
25 | |||
26 | #ifndef IRMLP_FRAME_H | ||
27 | #define IRMLP_FRAME_H | ||
28 | |||
29 | #include <linux/config.h> | ||
30 | #include <linux/skbuff.h> | ||
31 | |||
32 | #include <net/irda/discovery.h> | ||
33 | |||
34 | /* IrLMP frame opcodes */ | ||
35 | #define CONNECT_CMD 0x01 | ||
36 | #define CONNECT_CNF 0x81 | ||
37 | #define DISCONNECT 0x02 | ||
38 | #define ACCESSMODE_CMD 0x03 | ||
39 | #define ACCESSMODE_CNF 0x83 | ||
40 | |||
41 | #define CONTROL_BIT 0x80 | ||
42 | |||
43 | void irlmp_send_data_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap, | ||
44 | int expedited, struct sk_buff *skb); | ||
45 | void irlmp_send_lcf_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap, | ||
46 | __u8 opcode, struct sk_buff *skb); | ||
47 | void irlmp_link_data_indication(struct lap_cb *, struct sk_buff *, | ||
48 | int unreliable); | ||
49 | #ifdef CONFIG_IRDA_ULTRA | ||
50 | void irlmp_link_unitdata_indication(struct lap_cb *, struct sk_buff *); | ||
51 | #endif /* CONFIG_IRDA_ULTRA */ | ||
52 | |||
53 | void irlmp_link_connect_indication(struct lap_cb *, __u32 saddr, __u32 daddr, | ||
54 | struct qos_info *qos, struct sk_buff *skb); | ||
55 | void irlmp_link_connect_request(__u32 daddr); | ||
56 | void irlmp_link_connect_confirm(struct lap_cb *self, struct qos_info *qos, | ||
57 | struct sk_buff *skb); | ||
58 | void irlmp_link_disconnect_indication(struct lap_cb *, struct irlap_cb *, | ||
59 | LAP_REASON reason, struct sk_buff *); | ||
60 | void irlmp_link_discovery_confirm(struct lap_cb *self, hashbin_t *log); | ||
61 | void irlmp_link_discovery_indication(struct lap_cb *, discovery_t *discovery); | ||
62 | |||
63 | #endif | ||
diff --git a/include/net/irda/irmod.h b/include/net/irda/irmod.h new file mode 100644 index 000000000000..72b446c1e22c --- /dev/null +++ b/include/net/irda/irmod.h | |||
@@ -0,0 +1,109 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irmod.h | ||
4 | * Version: 0.3 | ||
5 | * Description: IrDA module and utilities functions | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Mon Dec 15 13:58:52 1997 | ||
9 | * Modified at: Fri Jan 28 13:15:24 2000 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved. | ||
13 | * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com> | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License as | ||
17 | * published by the Free Software Foundation; either version 2 of | ||
18 | * the License, or (at your option) any later version. | ||
19 | * | ||
20 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
21 | * provide warranty for any of this software. This material is | ||
22 | * provided "AS-IS" and at no charg. | ||
23 | * | ||
24 | ********************************************************************/ | ||
25 | |||
26 | #ifndef IRMOD_H | ||
27 | #define IRMOD_H | ||
28 | |||
29 | /* Misc status information */ | ||
30 | typedef enum { | ||
31 | STATUS_OK, | ||
32 | STATUS_ABORTED, | ||
33 | STATUS_NO_ACTIVITY, | ||
34 | STATUS_NOISY, | ||
35 | STATUS_REMOTE, | ||
36 | } LINK_STATUS; | ||
37 | |||
38 | typedef enum { | ||
39 | LOCK_NO_CHANGE, | ||
40 | LOCK_LOCKED, | ||
41 | LOCK_UNLOCKED, | ||
42 | } LOCK_STATUS; | ||
43 | |||
44 | typedef enum { FLOW_STOP, FLOW_START } LOCAL_FLOW; | ||
45 | |||
46 | /* | ||
47 | * IrLMP disconnect reasons. The order is very important, since they | ||
48 | * correspond to disconnect reasons sent in IrLMP disconnect frames, so | ||
49 | * please do not touch :-) | ||
50 | */ | ||
51 | typedef enum { | ||
52 | LM_USER_REQUEST = 1, /* User request */ | ||
53 | LM_LAP_DISCONNECT, /* Unexpected IrLAP disconnect */ | ||
54 | LM_CONNECT_FAILURE, /* Failed to establish IrLAP connection */ | ||
55 | LM_LAP_RESET, /* IrLAP reset */ | ||
56 | LM_INIT_DISCONNECT, /* Link Management initiated disconnect */ | ||
57 | LM_LSAP_NOTCONN, /* Data delivered on unconnected LSAP */ | ||
58 | LM_NON_RESP_CLIENT, /* Non responsive LM-MUX client */ | ||
59 | LM_NO_AVAIL_CLIENT, /* No available LM-MUX client */ | ||
60 | LM_CONN_HALF_OPEN, /* Connection is half open */ | ||
61 | LM_BAD_SOURCE_ADDR, /* Illegal source address (i.e 0x00) */ | ||
62 | } LM_REASON; | ||
63 | #define LM_UNKNOWN 0xff /* Unspecified disconnect reason */ | ||
64 | |||
65 | /* A few forward declarations (to make compiler happy) */ | ||
66 | struct qos_info; /* in <net/irda/qos.h> */ | ||
67 | |||
68 | /* | ||
69 | * Notify structure used between transport and link management layers | ||
70 | */ | ||
71 | typedef struct { | ||
72 | int (*data_indication)(void *priv, void *sap, struct sk_buff *skb); | ||
73 | int (*udata_indication)(void *priv, void *sap, struct sk_buff *skb); | ||
74 | void (*connect_confirm)(void *instance, void *sap, | ||
75 | struct qos_info *qos, __u32 max_sdu_size, | ||
76 | __u8 max_header_size, struct sk_buff *skb); | ||
77 | void (*connect_indication)(void *instance, void *sap, | ||
78 | struct qos_info *qos, __u32 max_sdu_size, | ||
79 | __u8 max_header_size, struct sk_buff *skb); | ||
80 | void (*disconnect_indication)(void *instance, void *sap, | ||
81 | LM_REASON reason, struct sk_buff *); | ||
82 | void (*flow_indication)(void *instance, void *sap, LOCAL_FLOW flow); | ||
83 | void (*status_indication)(void *instance, | ||
84 | LINK_STATUS link, LOCK_STATUS lock); | ||
85 | void *instance; /* Layer instance pointer */ | ||
86 | char name[16]; /* Name of layer */ | ||
87 | } notify_t; | ||
88 | |||
89 | #define NOTIFY_MAX_NAME 16 | ||
90 | |||
91 | /* Zero the notify structure */ | ||
92 | void irda_notify_init(notify_t *notify); | ||
93 | |||
94 | /* Locking wrapper - Note the inverted logic on irda_lock(). | ||
95 | * Those function basically return false if the lock is already in the | ||
96 | * position you want to set it. - Jean II */ | ||
97 | #define irda_lock(lock) (! test_and_set_bit(0, (void *) (lock))) | ||
98 | #define irda_unlock(lock) (test_and_clear_bit(0, (void *) (lock))) | ||
99 | |||
100 | #endif /* IRMOD_H */ | ||
101 | |||
102 | |||
103 | |||
104 | |||
105 | |||
106 | |||
107 | |||
108 | |||
109 | |||
diff --git a/include/net/irda/irqueue.h b/include/net/irda/irqueue.h new file mode 100644 index 000000000000..335b0ace9665 --- /dev/null +++ b/include/net/irda/irqueue.h | |||
@@ -0,0 +1,96 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irqueue.h | ||
4 | * Version: 0.3 | ||
5 | * Description: General queue implementation | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Tue Jun 9 13:26:50 1998 | ||
9 | * Modified at: Thu Oct 7 13:25:16 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (C) 1998-1999, Aage Kvalnes <aage@cs.uit.no> | ||
13 | * Copyright (c) 1998, Dag Brattli | ||
14 | * All Rights Reserved. | ||
15 | * | ||
16 | * This code is taken from the Vortex Operating System written by Aage | ||
17 | * Kvalnes and has been ported to Linux and Linux/IR by Dag Brattli | ||
18 | * | ||
19 | * This program is free software; you can redistribute it and/or | ||
20 | * modify it under the terms of the GNU General Public License as | ||
21 | * published by the Free Software Foundation; either version 2 of | ||
22 | * the License, or (at your option) any later version. | ||
23 | * | ||
24 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
25 | * provide warranty for any of this software. This material is | ||
26 | * provided "AS-IS" and at no charge. | ||
27 | * | ||
28 | ********************************************************************/ | ||
29 | |||
30 | #include <linux/types.h> | ||
31 | #include <linux/spinlock.h> | ||
32 | |||
33 | #ifndef IRDA_QUEUE_H | ||
34 | #define IRDA_QUEUE_H | ||
35 | |||
36 | #define NAME_SIZE 32 | ||
37 | |||
38 | /* | ||
39 | * Hash types (some flags can be xored) | ||
40 | * See comments in irqueue.c for which one to use... | ||
41 | */ | ||
42 | #define HB_NOLOCK 0 /* No concurent access prevention */ | ||
43 | #define HB_LOCK 1 /* Prevent concurent write with global lock */ | ||
44 | |||
45 | /* | ||
46 | * Hash defines | ||
47 | */ | ||
48 | #define HASHBIN_SIZE 8 | ||
49 | #define HASHBIN_MASK 0x7 | ||
50 | |||
51 | #ifndef IRDA_ALIGN | ||
52 | #define IRDA_ALIGN __attribute__((aligned)) | ||
53 | #endif | ||
54 | |||
55 | #define Q_NULL { NULL, NULL, "", 0 } | ||
56 | |||
57 | typedef void (*FREE_FUNC)(void *arg); | ||
58 | |||
59 | struct irda_queue { | ||
60 | struct irda_queue *q_next; | ||
61 | struct irda_queue *q_prev; | ||
62 | |||
63 | char q_name[NAME_SIZE]; | ||
64 | long q_hash; /* Must be able to cast a (void *) */ | ||
65 | }; | ||
66 | typedef struct irda_queue irda_queue_t; | ||
67 | |||
68 | typedef struct hashbin_t { | ||
69 | __u32 magic; | ||
70 | int hb_type; | ||
71 | int hb_size; | ||
72 | spinlock_t hb_spinlock; /* HB_LOCK - Can be used by the user */ | ||
73 | |||
74 | irda_queue_t* hb_queue[HASHBIN_SIZE] IRDA_ALIGN; | ||
75 | |||
76 | irda_queue_t* hb_current; | ||
77 | } hashbin_t; | ||
78 | |||
79 | hashbin_t *hashbin_new(int type); | ||
80 | int hashbin_delete(hashbin_t* hashbin, FREE_FUNC func); | ||
81 | int hashbin_clear(hashbin_t* hashbin, FREE_FUNC free_func); | ||
82 | void hashbin_insert(hashbin_t* hashbin, irda_queue_t* entry, long hashv, | ||
83 | const char* name); | ||
84 | void* hashbin_remove(hashbin_t* hashbin, long hashv, const char* name); | ||
85 | void* hashbin_remove_first(hashbin_t *hashbin); | ||
86 | void* hashbin_remove_this( hashbin_t* hashbin, irda_queue_t* entry); | ||
87 | void* hashbin_find(hashbin_t* hashbin, long hashv, const char* name); | ||
88 | void* hashbin_lock_find(hashbin_t* hashbin, long hashv, const char* name); | ||
89 | void* hashbin_find_next(hashbin_t* hashbin, long hashv, const char* name, | ||
90 | void ** pnext); | ||
91 | irda_queue_t *hashbin_get_first(hashbin_t *hashbin); | ||
92 | irda_queue_t *hashbin_get_next(hashbin_t *hashbin); | ||
93 | |||
94 | #define HASHBIN_GET_SIZE(hashbin) hashbin->hb_size | ||
95 | |||
96 | #endif | ||
diff --git a/include/net/irda/irttp.h b/include/net/irda/irttp.h new file mode 100644 index 000000000000..a899e5837be8 --- /dev/null +++ b/include/net/irda/irttp.h | |||
@@ -0,0 +1,210 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irttp.h | ||
4 | * Version: 1.0 | ||
5 | * Description: Tiny Transport Protocol (TTP) definitions | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Sun Aug 31 20:14:31 1997 | ||
9 | * Modified at: Sun Dec 12 13:09:07 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, | ||
13 | * All Rights Reserved. | ||
14 | * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com> | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or | ||
17 | * modify it under the terms of the GNU General Public License as | ||
18 | * published by the Free Software Foundation; either version 2 of | ||
19 | * the License, or (at your option) any later version. | ||
20 | * | ||
21 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
22 | * provide warranty for any of this software. This material is | ||
23 | * provided "AS-IS" and at no charge. | ||
24 | * | ||
25 | ********************************************************************/ | ||
26 | |||
27 | #ifndef IRTTP_H | ||
28 | #define IRTTP_H | ||
29 | |||
30 | #include <linux/types.h> | ||
31 | #include <linux/skbuff.h> | ||
32 | #include <linux/spinlock.h> | ||
33 | |||
34 | #include <net/irda/irda.h> | ||
35 | #include <net/irda/irlmp.h> /* struct lsap_cb */ | ||
36 | #include <net/irda/qos.h> /* struct qos_info */ | ||
37 | #include <net/irda/irqueue.h> | ||
38 | |||
39 | #define TTP_MAX_CONNECTIONS LM_MAX_CONNECTIONS | ||
40 | #define TTP_HEADER 1 | ||
41 | #define TTP_MAX_HEADER (TTP_HEADER + LMP_MAX_HEADER) | ||
42 | #define TTP_SAR_HEADER 5 | ||
43 | #define TTP_PARAMETERS 0x80 | ||
44 | #define TTP_MORE 0x80 | ||
45 | |||
46 | /* Transmission queue sizes */ | ||
47 | /* Worst case scenario, two window of data - Jean II */ | ||
48 | #define TTP_TX_MAX_QUEUE 14 | ||
49 | /* We need to keep at least 5 frames to make sure that we can refill | ||
50 | * appropriately the LAP layer. LAP keeps only two buffers, and we need | ||
51 | * to have 7 to make a full window - Jean II */ | ||
52 | #define TTP_TX_LOW_THRESHOLD 5 | ||
53 | /* Most clients are synchronous with respect to flow control, so we can | ||
54 | * keep a low number of Tx buffers in TTP - Jean II */ | ||
55 | #define TTP_TX_HIGH_THRESHOLD 7 | ||
56 | |||
57 | /* Receive queue sizes */ | ||
58 | /* Minimum of credit that the peer should hold. | ||
59 | * If the peer has less credits than 9 frames, we will explicitely send | ||
60 | * him some credits (through irttp_give_credit() and a specific frame). | ||
61 | * Note that when we give credits it's likely that it won't be sent in | ||
62 | * this LAP window, but in the next one. So, we make sure that the peer | ||
63 | * has something to send while waiting for credits (one LAP window == 7 | ||
64 | * + 1 frames while he process the credits). - Jean II */ | ||
65 | #define TTP_RX_MIN_CREDIT 8 | ||
66 | /* This is the default maximum number of credits held by the peer, so the | ||
67 | * default maximum number of frames he can send us before needing flow | ||
68 | * control answer from us (this may be negociated differently at TSAP setup). | ||
69 | * We want to minimise the number of times we have to explicitely send some | ||
70 | * credit to the peer, hoping we can piggyback it on the return data. In | ||
71 | * particular, it doesn't make sense for us to send credit more than once | ||
72 | * per LAP window. | ||
73 | * Moreover, giving credits has some latency, so we need strictly more than | ||
74 | * a LAP window, otherwise we may already have credits in our Tx queue. | ||
75 | * But on the other hand, we don't want to keep too many Rx buffer here | ||
76 | * before starting to flow control the other end, so make it exactly one | ||
77 | * LAP window + 1 + MIN_CREDITS. - Jean II */ | ||
78 | #define TTP_RX_DEFAULT_CREDIT 16 | ||
79 | /* Maximum number of credits we can allow the peer to have, and therefore | ||
80 | * maximum Rx queue size. | ||
81 | * Note that we try to deliver packets to the higher layer every time we | ||
82 | * receive something, so in normal mode the Rx queue will never contains | ||
83 | * more than one or two packets. - Jean II */ | ||
84 | #define TTP_RX_MAX_CREDIT 21 | ||
85 | |||
86 | /* What clients should use when calling ttp_open_tsap() */ | ||
87 | #define DEFAULT_INITIAL_CREDIT TTP_RX_DEFAULT_CREDIT | ||
88 | |||
89 | /* Some priorities for disconnect requests */ | ||
90 | #define P_NORMAL 0 | ||
91 | #define P_HIGH 1 | ||
92 | |||
93 | #define TTP_SAR_DISABLE 0 | ||
94 | #define TTP_SAR_UNBOUND 0xffffffff | ||
95 | |||
96 | /* Parameters */ | ||
97 | #define TTP_MAX_SDU_SIZE 0x01 | ||
98 | |||
99 | /* | ||
100 | * This structure contains all data assosiated with one instance of a TTP | ||
101 | * connection. | ||
102 | */ | ||
103 | struct tsap_cb { | ||
104 | irda_queue_t q; /* Must be first */ | ||
105 | magic_t magic; /* Just in case */ | ||
106 | |||
107 | __u8 stsap_sel; /* Source TSAP */ | ||
108 | __u8 dtsap_sel; /* Destination TSAP */ | ||
109 | |||
110 | struct lsap_cb *lsap; /* Corresponding LSAP to this TSAP */ | ||
111 | |||
112 | __u8 connected; /* TSAP connected */ | ||
113 | |||
114 | __u8 initial_credit; /* Initial credit to give peer */ | ||
115 | |||
116 | int avail_credit; /* Available credit to return to peer */ | ||
117 | int remote_credit; /* Credit held by peer TTP entity */ | ||
118 | int send_credit; /* Credit held by local TTP entity */ | ||
119 | |||
120 | struct sk_buff_head tx_queue; /* Frames to be transmitted */ | ||
121 | struct sk_buff_head rx_queue; /* Received frames */ | ||
122 | struct sk_buff_head rx_fragments; | ||
123 | int tx_queue_lock; | ||
124 | int rx_queue_lock; | ||
125 | spinlock_t lock; | ||
126 | |||
127 | notify_t notify; /* Callbacks to client layer */ | ||
128 | |||
129 | struct net_device_stats stats; | ||
130 | struct timer_list todo_timer; | ||
131 | |||
132 | __u32 max_seg_size; /* Max data that fit into an IrLAP frame */ | ||
133 | __u8 max_header_size; | ||
134 | |||
135 | int rx_sdu_busy; /* RxSdu.busy */ | ||
136 | __u32 rx_sdu_size; /* Current size of a partially received frame */ | ||
137 | __u32 rx_max_sdu_size; /* Max receive user data size */ | ||
138 | |||
139 | int tx_sdu_busy; /* TxSdu.busy */ | ||
140 | __u32 tx_max_sdu_size; /* Max transmit user data size */ | ||
141 | |||
142 | int close_pend; /* Close, but disconnect_pend */ | ||
143 | unsigned long disconnect_pend; /* Disconnect, but still data to send */ | ||
144 | struct sk_buff *disconnect_skb; | ||
145 | }; | ||
146 | |||
147 | struct irttp_cb { | ||
148 | magic_t magic; | ||
149 | hashbin_t *tsaps; | ||
150 | }; | ||
151 | |||
152 | int irttp_init(void); | ||
153 | void irttp_cleanup(void); | ||
154 | |||
155 | struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify); | ||
156 | int irttp_close_tsap(struct tsap_cb *self); | ||
157 | |||
158 | int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb); | ||
159 | int irttp_udata_request(struct tsap_cb *self, struct sk_buff *skb); | ||
160 | |||
161 | int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel, | ||
162 | __u32 saddr, __u32 daddr, | ||
163 | struct qos_info *qos, __u32 max_sdu_size, | ||
164 | struct sk_buff *userdata); | ||
165 | int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size, | ||
166 | struct sk_buff *userdata); | ||
167 | int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *skb, | ||
168 | int priority); | ||
169 | void irttp_flow_request(struct tsap_cb *self, LOCAL_FLOW flow); | ||
170 | struct tsap_cb *irttp_dup(struct tsap_cb *self, void *instance); | ||
171 | |||
172 | static __inline __u32 irttp_get_saddr(struct tsap_cb *self) | ||
173 | { | ||
174 | return irlmp_get_saddr(self->lsap); | ||
175 | } | ||
176 | |||
177 | static __inline __u32 irttp_get_daddr(struct tsap_cb *self) | ||
178 | { | ||
179 | return irlmp_get_daddr(self->lsap); | ||
180 | } | ||
181 | |||
182 | static __inline __u32 irttp_get_max_seg_size(struct tsap_cb *self) | ||
183 | { | ||
184 | return self->max_seg_size; | ||
185 | } | ||
186 | |||
187 | /* After doing a irttp_dup(), this get one of the two socket back into | ||
188 | * a state where it's waiting incomming connections. | ||
189 | * Note : this can be used *only* if the socket is not yet connected | ||
190 | * (i.e. NO irttp_connect_response() done on this socket). | ||
191 | * - Jean II */ | ||
192 | static inline void irttp_listen(struct tsap_cb *self) | ||
193 | { | ||
194 | irlmp_listen(self->lsap); | ||
195 | self->dtsap_sel = LSAP_ANY; | ||
196 | } | ||
197 | |||
198 | /* Return TRUE if the node is in primary mode (i.e. master) | ||
199 | * - Jean II */ | ||
200 | static inline int irttp_is_primary(struct tsap_cb *self) | ||
201 | { | ||
202 | if ((self == NULL) || | ||
203 | (self->lsap == NULL) || | ||
204 | (self->lsap->lap == NULL) || | ||
205 | (self->lsap->lap->irlap == NULL)) | ||
206 | return -2; | ||
207 | return(irlap_is_primary(self->lsap->lap->irlap)); | ||
208 | } | ||
209 | |||
210 | #endif /* IRTTP_H */ | ||
diff --git a/include/net/irda/parameters.h b/include/net/irda/parameters.h new file mode 100644 index 000000000000..3a605d37ddbf --- /dev/null +++ b/include/net/irda/parameters.h | |||
@@ -0,0 +1,102 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: parameters.h | ||
4 | * Version: 1.0 | ||
5 | * Description: A more general way to handle (pi,pl,pv) parameters | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Mon Jun 7 08:47:28 1999 | ||
9 | * Modified at: Sun Jan 30 14:05:14 2000 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
27 | * MA 02111-1307 USA | ||
28 | * | ||
29 | * Michel Dänzer <daenzer@debian.org>, 10/2001 | ||
30 | * - simplify irda_pv_t to avoid endianness issues | ||
31 | * | ||
32 | ********************************************************************/ | ||
33 | |||
34 | #ifndef IRDA_PARAMS_H | ||
35 | #define IRDA_PARAMS_H | ||
36 | |||
37 | /* | ||
38 | * The currently supported types. Beware not to change the sequence since | ||
39 | * it a good reason why the sized integers has a value equal to their size | ||
40 | */ | ||
41 | typedef enum { | ||
42 | PV_INTEGER, /* Integer of any (pl) length */ | ||
43 | PV_INT_8_BITS, /* Integer of 8 bits in length */ | ||
44 | PV_INT_16_BITS, /* Integer of 16 bits in length */ | ||
45 | PV_STRING, /* \0 terminated string */ | ||
46 | PV_INT_32_BITS, /* Integer of 32 bits in length */ | ||
47 | PV_OCT_SEQ, /* Octet sequence */ | ||
48 | PV_NO_VALUE /* Does not contain any value (pl=0) */ | ||
49 | } PV_TYPE; | ||
50 | |||
51 | /* Bit 7 of type field */ | ||
52 | #define PV_BIG_ENDIAN 0x80 | ||
53 | #define PV_LITTLE_ENDIAN 0x00 | ||
54 | #define PV_MASK 0x7f /* To mask away endian bit */ | ||
55 | |||
56 | #define PV_PUT 0 | ||
57 | #define PV_GET 1 | ||
58 | |||
59 | typedef union { | ||
60 | char *c; | ||
61 | __u32 i; | ||
62 | __u32 *ip; | ||
63 | } irda_pv_t; | ||
64 | |||
65 | typedef struct { | ||
66 | __u8 pi; | ||
67 | __u8 pl; | ||
68 | irda_pv_t pv; | ||
69 | } irda_param_t; | ||
70 | |||
71 | typedef int (*PI_HANDLER)(void *self, irda_param_t *param, int get); | ||
72 | typedef int (*PV_HANDLER)(void *self, __u8 *buf, int len, __u8 pi, | ||
73 | PV_TYPE type, PI_HANDLER func); | ||
74 | |||
75 | typedef struct { | ||
76 | PI_HANDLER func; /* Handler for this parameter identifier */ | ||
77 | PV_TYPE type; /* Data type for this parameter */ | ||
78 | } pi_minor_info_t; | ||
79 | |||
80 | typedef struct { | ||
81 | pi_minor_info_t *pi_minor_call_table; | ||
82 | int len; | ||
83 | } pi_major_info_t; | ||
84 | |||
85 | typedef struct { | ||
86 | pi_major_info_t *tables; | ||
87 | int len; | ||
88 | __u8 pi_mask; | ||
89 | int pi_major_offset; | ||
90 | } pi_param_info_t; | ||
91 | |||
92 | int irda_param_pack(__u8 *buf, char *fmt, ...); | ||
93 | |||
94 | int irda_param_insert(void *self, __u8 pi, __u8 *buf, int len, | ||
95 | pi_param_info_t *info); | ||
96 | int irda_param_extract_all(void *self, __u8 *buf, int len, | ||
97 | pi_param_info_t *info); | ||
98 | |||
99 | #define irda_param_insert_byte(buf,pi,pv) irda_param_pack(buf,"bbb",pi,1,pv) | ||
100 | |||
101 | #endif /* IRDA_PARAMS_H */ | ||
102 | |||
diff --git a/include/net/irda/qos.h b/include/net/irda/qos.h new file mode 100644 index 000000000000..9ae3d6bc2423 --- /dev/null +++ b/include/net/irda/qos.h | |||
@@ -0,0 +1,104 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: qos.h | ||
4 | * Version: 1.0 | ||
5 | * Description: Quality of Service definitions | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Fri Sep 19 23:21:09 1997 | ||
9 | * Modified at: Thu Dec 2 13:51:54 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1999 Dag Brattli, All Rights Reserved. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
27 | * MA 02111-1307 USA | ||
28 | * | ||
29 | ********************************************************************/ | ||
30 | |||
31 | #ifndef IRDA_QOS_H | ||
32 | #define IRDA_QOS_H | ||
33 | |||
34 | #include <linux/config.h> | ||
35 | #include <linux/skbuff.h> | ||
36 | |||
37 | #include <net/irda/parameters.h> | ||
38 | |||
39 | #define PI_BAUD_RATE 0x01 | ||
40 | #define PI_MAX_TURN_TIME 0x82 | ||
41 | #define PI_DATA_SIZE 0x83 | ||
42 | #define PI_WINDOW_SIZE 0x84 | ||
43 | #define PI_ADD_BOFS 0x85 | ||
44 | #define PI_MIN_TURN_TIME 0x86 | ||
45 | #define PI_LINK_DISC 0x08 | ||
46 | |||
47 | #define IR_115200_MAX 0x3f | ||
48 | |||
49 | /* Baud rates (first byte) */ | ||
50 | #define IR_2400 0x01 | ||
51 | #define IR_9600 0x02 | ||
52 | #define IR_19200 0x04 | ||
53 | #define IR_38400 0x08 | ||
54 | #define IR_57600 0x10 | ||
55 | #define IR_115200 0x20 | ||
56 | #define IR_576000 0x40 | ||
57 | #define IR_1152000 0x80 | ||
58 | |||
59 | /* Baud rates (second byte) */ | ||
60 | #define IR_4000000 0x01 | ||
61 | #define IR_16000000 0x02 | ||
62 | |||
63 | /* Quality of Service information */ | ||
64 | typedef struct { | ||
65 | __u32 value; | ||
66 | __u16 bits; /* LSB is first byte, MSB is second byte */ | ||
67 | } qos_value_t; | ||
68 | |||
69 | struct qos_info { | ||
70 | magic_t magic; | ||
71 | |||
72 | qos_value_t baud_rate; /* IR_11520O | ... */ | ||
73 | qos_value_t max_turn_time; | ||
74 | qos_value_t data_size; | ||
75 | qos_value_t window_size; | ||
76 | qos_value_t additional_bofs; | ||
77 | qos_value_t min_turn_time; | ||
78 | qos_value_t link_disc_time; | ||
79 | |||
80 | qos_value_t power; | ||
81 | }; | ||
82 | |||
83 | extern int sysctl_max_baud_rate; | ||
84 | extern int sysctl_max_inactive_time; | ||
85 | |||
86 | void irda_init_max_qos_capabilies(struct qos_info *qos); | ||
87 | void irda_qos_compute_intersection(struct qos_info *, struct qos_info *); | ||
88 | |||
89 | __u32 irlap_max_line_capacity(__u32 speed, __u32 max_turn_time); | ||
90 | |||
91 | void irda_qos_bits_to_value(struct qos_info *qos); | ||
92 | |||
93 | /* So simple, how could we not inline those two ? | ||
94 | * Note : one byte is 10 bits if you include start and stop bits | ||
95 | * Jean II */ | ||
96 | #define irlap_min_turn_time_in_bytes(speed, min_turn_time) ( \ | ||
97 | speed * min_turn_time / 10000000 \ | ||
98 | ) | ||
99 | #define irlap_xbofs_in_usec(speed, xbofs) ( \ | ||
100 | xbofs * 10000000 / speed \ | ||
101 | ) | ||
102 | |||
103 | #endif | ||
104 | |||
diff --git a/include/net/irda/timer.h b/include/net/irda/timer.h new file mode 100644 index 000000000000..2c5d8864ab77 --- /dev/null +++ b/include/net/irda/timer.h | |||
@@ -0,0 +1,104 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: timer.h | ||
4 | * Version: | ||
5 | * Description: | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Sat Aug 16 00:59:29 1997 | ||
9 | * Modified at: Thu Oct 7 12:25:24 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1997, 1998-1999 Dag Brattli <dagb@cs.uit.no>, | ||
13 | * All Rights Reserved. | ||
14 | * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com> | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or | ||
17 | * modify it under the terms of the GNU General Public License as | ||
18 | * published by the Free Software Foundation; either version 2 of | ||
19 | * the License, or (at your option) any later version. | ||
20 | * | ||
21 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
22 | * provide warranty for any of this software. This material is | ||
23 | * provided "AS-IS" and at no charge. | ||
24 | * | ||
25 | ********************************************************************/ | ||
26 | |||
27 | #ifndef TIMER_H | ||
28 | #define TIMER_H | ||
29 | |||
30 | #include <linux/timer.h> | ||
31 | |||
32 | #include <asm/param.h> /* for HZ */ | ||
33 | |||
34 | #include <net/irda/irda.h> | ||
35 | |||
36 | /* A few forward declarations (to make compiler happy) */ | ||
37 | struct irlmp_cb; | ||
38 | struct irlap_cb; | ||
39 | struct lsap_cb; | ||
40 | struct lap_cb; | ||
41 | |||
42 | /* | ||
43 | * Timeout definitions, some defined in IrLAP 6.13.5 - p. 92 | ||
44 | */ | ||
45 | #define POLL_TIMEOUT (450*HZ/1000) /* Must never exceed 500 ms */ | ||
46 | #define FINAL_TIMEOUT (500*HZ/1000) /* Must never exceed 500 ms */ | ||
47 | |||
48 | /* | ||
49 | * Normally twice of p-timer. Note 3, IrLAP 6.3.11.2 - p. 60 suggests | ||
50 | * at least twice duration of the P-timer. | ||
51 | */ | ||
52 | #define WD_TIMEOUT (POLL_TIMEOUT*2) | ||
53 | |||
54 | #define MEDIABUSY_TIMEOUT (500*HZ/1000) /* 500 msec */ | ||
55 | #define SMALLBUSY_TIMEOUT (100*HZ/1000) /* 100 msec - IrLAP 6.13.4 */ | ||
56 | |||
57 | /* | ||
58 | * Slot timer must never exceed 85 ms, and must always be at least 25 ms, | ||
59 | * suggested to 75-85 msec by IrDA lite. This doesn't work with a lot of | ||
60 | * devices, and other stackes uses a lot more, so it's best we do it as well | ||
61 | * (Note : this is the default value and sysctl overides it - Jean II) | ||
62 | */ | ||
63 | #define SLOT_TIMEOUT (90*HZ/1000) | ||
64 | |||
65 | /* | ||
66 | * The latest discovery frame (XID) is longer due to the extra discovery | ||
67 | * information (hints, device name...). This is its extra length. | ||
68 | * We use that when setting the query timeout. Jean II | ||
69 | */ | ||
70 | #define XIDEXTRA_TIMEOUT (34*HZ/1000) /* 34 msec */ | ||
71 | |||
72 | #define WATCHDOG_TIMEOUT (20*HZ) /* 20 sec */ | ||
73 | |||
74 | typedef void (*TIMER_CALLBACK)(void *); | ||
75 | |||
76 | static inline void irda_start_timer(struct timer_list *ptimer, int timeout, | ||
77 | void* data, TIMER_CALLBACK callback) | ||
78 | { | ||
79 | ptimer->function = (void (*)(unsigned long)) callback; | ||
80 | ptimer->data = (unsigned long) data; | ||
81 | |||
82 | /* Set new value for timer (update or add timer). | ||
83 | * We use mod_timer() because it's more efficient and also | ||
84 | * safer with respect to race conditions - Jean II */ | ||
85 | mod_timer(ptimer, jiffies + timeout); | ||
86 | } | ||
87 | |||
88 | |||
89 | void irlap_start_slot_timer(struct irlap_cb *self, int timeout); | ||
90 | void irlap_start_query_timer(struct irlap_cb *self, int S, int s); | ||
91 | void irlap_start_final_timer(struct irlap_cb *self, int timeout); | ||
92 | void irlap_start_wd_timer(struct irlap_cb *self, int timeout); | ||
93 | void irlap_start_backoff_timer(struct irlap_cb *self, int timeout); | ||
94 | |||
95 | void irlap_start_mbusy_timer(struct irlap_cb *self, int timeout); | ||
96 | void irlap_stop_mbusy_timer(struct irlap_cb *); | ||
97 | |||
98 | void irlmp_start_watchdog_timer(struct lsap_cb *, int timeout); | ||
99 | void irlmp_start_discovery_timer(struct irlmp_cb *, int timeout); | ||
100 | void irlmp_start_idle_timer(struct lap_cb *, int timeout); | ||
101 | void irlmp_stop_idle_timer(struct lap_cb *self); | ||
102 | |||
103 | #endif | ||
104 | |||
diff --git a/include/net/irda/wrapper.h b/include/net/irda/wrapper.h new file mode 100644 index 000000000000..98768b3f9e31 --- /dev/null +++ b/include/net/irda/wrapper.h | |||
@@ -0,0 +1,58 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: wrapper.h | ||
4 | * Version: 1.2 | ||
5 | * Description: IrDA SIR async wrapper layer | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Mon Aug 4 20:40:53 1997 | ||
9 | * Modified at: Tue Jan 11 12:37:29 2000 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>, | ||
13 | * All Rights Reserved. | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License as | ||
17 | * published by the Free Software Foundation; either version 2 of | ||
18 | * the License, or (at your option) any later version. | ||
19 | * | ||
20 | * Neither Dag Brattli nor University of Tromsø admit liability nor | ||
21 | * provide warranty for any of this software. This material is | ||
22 | * provided "AS-IS" and at no charge. | ||
23 | * | ||
24 | ********************************************************************/ | ||
25 | |||
26 | #ifndef WRAPPER_H | ||
27 | #define WRAPPER_H | ||
28 | |||
29 | #include <linux/types.h> | ||
30 | #include <linux/skbuff.h> | ||
31 | #include <linux/netdevice.h> | ||
32 | |||
33 | #include <net/irda/irda_device.h> /* iobuff_t */ | ||
34 | |||
35 | #define BOF 0xc0 /* Beginning of frame */ | ||
36 | #define XBOF 0xff | ||
37 | #define EOF 0xc1 /* End of frame */ | ||
38 | #define CE 0x7d /* Control escape */ | ||
39 | |||
40 | #define STA BOF /* Start flag */ | ||
41 | #define STO EOF /* End flag */ | ||
42 | |||
43 | #define IRDA_TRANS 0x20 /* Asynchronous transparency modifier */ | ||
44 | |||
45 | /* States for receving a frame in async mode */ | ||
46 | enum { | ||
47 | OUTSIDE_FRAME, | ||
48 | BEGIN_FRAME, | ||
49 | LINK_ESCAPE, | ||
50 | INSIDE_FRAME | ||
51 | }; | ||
52 | |||
53 | /* Proto definitions */ | ||
54 | int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize); | ||
55 | void async_unwrap_char(struct net_device *dev, struct net_device_stats *stats, | ||
56 | iobuff_t *buf, __u8 byte); | ||
57 | |||
58 | #endif | ||
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h new file mode 100644 index 000000000000..44edd48f1234 --- /dev/null +++ b/include/net/iw_handler.h | |||
@@ -0,0 +1,540 @@ | |||
1 | /* | ||
2 | * This file define the new driver API for Wireless Extensions | ||
3 | * | ||
4 | * Version : 6 21.6.04 | ||
5 | * | ||
6 | * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> | ||
7 | * Copyright (c) 2001-2004 Jean Tourrilhes, All Rights Reserved. | ||
8 | */ | ||
9 | |||
10 | #ifndef _IW_HANDLER_H | ||
11 | #define _IW_HANDLER_H | ||
12 | |||
13 | /************************** DOCUMENTATION **************************/ | ||
14 | /* | ||
15 | * Initial driver API (1996 -> onward) : | ||
16 | * ----------------------------------- | ||
17 | * The initial API just sends the IOCTL request received from user space | ||
18 | * to the driver (via the driver ioctl handler). The driver has to | ||
19 | * handle all the rest... | ||
20 | * | ||
21 | * The initial API also defines a specific handler in struct net_device | ||
22 | * to handle wireless statistics. | ||
23 | * | ||
24 | * The initial APIs served us well and has proven a reasonably good design. | ||
25 | * However, there is a few shortcommings : | ||
26 | * o No events, everything is a request to the driver. | ||
27 | * o Large ioctl function in driver with gigantic switch statement | ||
28 | * (i.e. spaghetti code). | ||
29 | * o Driver has to mess up with copy_to/from_user, and in many cases | ||
30 | * does it unproperly. Common mistakes are : | ||
31 | * * buffer overflows (no checks or off by one checks) | ||
32 | * * call copy_to/from_user with irq disabled | ||
33 | * o The user space interface is tied to ioctl because of the use | ||
34 | * copy_to/from_user. | ||
35 | * | ||
36 | * New driver API (2002 -> onward) : | ||
37 | * ------------------------------- | ||
38 | * The new driver API is just a bunch of standard functions (handlers), | ||
39 | * each handling a specific Wireless Extension. The driver just export | ||
40 | * the list of handler it supports, and those will be called apropriately. | ||
41 | * | ||
42 | * I tried to keep the main advantage of the previous API (simplicity, | ||
43 | * efficiency and light weight), and also I provide a good dose of backward | ||
44 | * compatibility (most structures are the same, driver can use both API | ||
45 | * simultaneously, ...). | ||
46 | * Hopefully, I've also addressed the shortcomming of the initial API. | ||
47 | * | ||
48 | * The advantage of the new API are : | ||
49 | * o Handling of Extensions in driver broken in small contained functions | ||
50 | * o Tighter checks of ioctl before calling the driver | ||
51 | * o Flexible commit strategy (at least, the start of it) | ||
52 | * o Backward compatibility (can be mixed with old API) | ||
53 | * o Driver doesn't have to worry about memory and user-space issues | ||
54 | * The last point is important for the following reasons : | ||
55 | * o You are now able to call the new driver API from any API you | ||
56 | * want (including from within other parts of the kernel). | ||
57 | * o Common mistakes are avoided (buffer overflow, user space copy | ||
58 | * with irq disabled and so on). | ||
59 | * | ||
60 | * The Drawback of the new API are : | ||
61 | * o bloat (especially kernel) | ||
62 | * o need to migrate existing drivers to new API | ||
63 | * My initial testing shows that the new API adds around 3kB to the kernel | ||
64 | * and save between 0 and 5kB from a typical driver. | ||
65 | * Also, as all structures and data types are unchanged, the migration is | ||
66 | * quite straightforward (but tedious). | ||
67 | * | ||
68 | * --- | ||
69 | * | ||
70 | * The new driver API is defined below in this file. User space should | ||
71 | * not be aware of what's happening down there... | ||
72 | * | ||
73 | * A new kernel wrapper is in charge of validating the IOCTLs and calling | ||
74 | * the appropriate driver handler. This is implemented in : | ||
75 | * # net/core/wireless.c | ||
76 | * | ||
77 | * The driver export the list of handlers in : | ||
78 | * # include/linux/netdevice.h (one place) | ||
79 | * | ||
80 | * The new driver API is available for WIRELESS_EXT >= 13. | ||
81 | * Good luck with migration to the new API ;-) | ||
82 | */ | ||
83 | |||
84 | /* ---------------------- THE IMPLEMENTATION ---------------------- */ | ||
85 | /* | ||
86 | * Some of the choice I've made are pretty controversials. Defining an | ||
87 | * API is very much weighting compromises. This goes into some of the | ||
88 | * details and the thinking behind the implementation. | ||
89 | * | ||
90 | * Implementation goals : | ||
91 | * -------------------- | ||
92 | * The implementation goals were as follow : | ||
93 | * o Obvious : you should not need a PhD to understand what's happening, | ||
94 | * the benefit is easier maintainance. | ||
95 | * o Flexible : it should accommodate a wide variety of driver | ||
96 | * implementations and be as flexible as the old API. | ||
97 | * o Lean : it should be efficient memory wise to minimise the impact | ||
98 | * on kernel footprint. | ||
99 | * o Transparent to user space : the large number of user space | ||
100 | * applications that use Wireless Extensions should not need | ||
101 | * any modifications. | ||
102 | * | ||
103 | * Array of functions versus Struct of functions | ||
104 | * --------------------------------------------- | ||
105 | * 1) Having an array of functions allow the kernel code to access the | ||
106 | * handler in a single lookup, which is much more efficient (think hash | ||
107 | * table here). | ||
108 | * 2) The only drawback is that driver writer may put their handler in | ||
109 | * the wrong slot. This is trivial to test (I set the frequency, the | ||
110 | * bitrate changes). Once the handler is in the proper slot, it will be | ||
111 | * there forever, because the array is only extended at the end. | ||
112 | * 3) Backward/forward compatibility : adding new handler just require | ||
113 | * extending the array, so you can put newer driver in older kernel | ||
114 | * without having to patch the kernel code (and vice versa). | ||
115 | * | ||
116 | * All handler are of the same generic type | ||
117 | * ---------------------------------------- | ||
118 | * That's a feature !!! | ||
119 | * 1) Having a generic handler allow to have generic code, which is more | ||
120 | * efficient. If each of the handler was individually typed I would need | ||
121 | * to add a big switch in the kernel (== more bloat). This solution is | ||
122 | * more scalable, adding new Wireless Extensions doesn't add new code. | ||
123 | * 2) You can use the same handler in different slots of the array. For | ||
124 | * hardware, it may be more efficient or logical to handle multiple | ||
125 | * Wireless Extensions with a single function, and the API allow you to | ||
126 | * do that. (An example would be a single record on the card to control | ||
127 | * both bitrate and frequency, the handler would read the old record, | ||
128 | * modify it according to info->cmd and rewrite it). | ||
129 | * | ||
130 | * Functions prototype uses union iwreq_data | ||
131 | * ----------------------------------------- | ||
132 | * Some would have prefered functions defined this way : | ||
133 | * static int mydriver_ioctl_setrate(struct net_device *dev, | ||
134 | * long rate, int auto) | ||
135 | * 1) The kernel code doesn't "validate" the content of iwreq_data, and | ||
136 | * can't do it (different hardware may have different notion of what a | ||
137 | * valid frequency is), so we don't pretend that we do it. | ||
138 | * 2) The above form is not extendable. If I want to add a flag (for | ||
139 | * example to distinguish setting max rate and basic rate), I would | ||
140 | * break the prototype. Using iwreq_data is more flexible. | ||
141 | * 3) Also, the above form is not generic (see above). | ||
142 | * 4) I don't expect driver developper using the wrong field of the | ||
143 | * union (Doh !), so static typechecking doesn't add much value. | ||
144 | * 5) Lastly, you can skip the union by doing : | ||
145 | * static int mydriver_ioctl_setrate(struct net_device *dev, | ||
146 | * struct iw_request_info *info, | ||
147 | * struct iw_param *rrq, | ||
148 | * char *extra) | ||
149 | * And then adding the handler in the array like this : | ||
150 | * (iw_handler) mydriver_ioctl_setrate, // SIOCSIWRATE | ||
151 | * | ||
152 | * Using functions and not a registry | ||
153 | * ---------------------------------- | ||
154 | * Another implementation option would have been for every instance to | ||
155 | * define a registry (a struct containing all the Wireless Extensions) | ||
156 | * and only have a function to commit the registry to the hardware. | ||
157 | * 1) This approach can be emulated by the current code, but not | ||
158 | * vice versa. | ||
159 | * 2) Some drivers don't keep any configuration in the driver, for them | ||
160 | * adding such a registry would be a significant bloat. | ||
161 | * 3) The code to translate from Wireless Extension to native format is | ||
162 | * needed anyway, so it would not reduce significantely the amount of code. | ||
163 | * 4) The current approach only selectively translate Wireless Extensions | ||
164 | * to native format and only selectively set, whereas the registry approach | ||
165 | * would require to translate all WE and set all parameters for any single | ||
166 | * change. | ||
167 | * 5) For many Wireless Extensions, the GET operation return the current | ||
168 | * dynamic value, not the value that was set. | ||
169 | * | ||
170 | * This header is <net/iw_handler.h> | ||
171 | * --------------------------------- | ||
172 | * 1) This header is kernel space only and should not be exported to | ||
173 | * user space. Headers in "include/linux/" are exported, headers in | ||
174 | * "include/net/" are not. | ||
175 | * | ||
176 | * Mixed 32/64 bit issues | ||
177 | * ---------------------- | ||
178 | * The Wireless Extensions are designed to be 64 bit clean, by using only | ||
179 | * datatypes with explicit storage size. | ||
180 | * There are some issues related to kernel and user space using different | ||
181 | * memory model, and in particular 64bit kernel with 32bit user space. | ||
182 | * The problem is related to struct iw_point, that contains a pointer | ||
183 | * that *may* need to be translated. | ||
184 | * This is quite messy. The new API doesn't solve this problem (it can't), | ||
185 | * but is a step in the right direction : | ||
186 | * 1) Meta data about each ioctl is easily available, so we know what type | ||
187 | * of translation is needed. | ||
188 | * 2) The move of data between kernel and user space is only done in a single | ||
189 | * place in the kernel, so adding specific hooks in there is possible. | ||
190 | * 3) In the long term, it allows to move away from using ioctl as the | ||
191 | * user space API. | ||
192 | * | ||
193 | * So many comments and so few code | ||
194 | * -------------------------------- | ||
195 | * That's a feature. Comments won't bloat the resulting kernel binary. | ||
196 | */ | ||
197 | |||
198 | /***************************** INCLUDES *****************************/ | ||
199 | |||
200 | #include <linux/wireless.h> /* IOCTL user space API */ | ||
201 | #include <linux/if_ether.h> | ||
202 | |||
203 | /***************************** VERSION *****************************/ | ||
204 | /* | ||
205 | * This constant is used to know which version of the driver API is | ||
206 | * available. Hopefully, this will be pretty stable and no changes | ||
207 | * will be needed... | ||
208 | * I just plan to increment with each new version. | ||
209 | */ | ||
210 | #define IW_HANDLER_VERSION 6 | ||
211 | |||
212 | /* | ||
213 | * Changes : | ||
214 | * | ||
215 | * V2 to V3 | ||
216 | * -------- | ||
217 | * - Move event definition in <linux/wireless.h> | ||
218 | * - Add Wireless Event support : | ||
219 | * o wireless_send_event() prototype | ||
220 | * o iwe_stream_add_event/point() inline functions | ||
221 | * V3 to V4 | ||
222 | * -------- | ||
223 | * - Reshuffle IW_HEADER_TYPE_XXX to map IW_PRIV_TYPE_XXX changes | ||
224 | * | ||
225 | * V4 to V5 | ||
226 | * -------- | ||
227 | * - Add new spy support : struct iw_spy_data & prototypes | ||
228 | * | ||
229 | * V5 to V6 | ||
230 | * -------- | ||
231 | * - Change the way we get to spy_data method for added safety | ||
232 | * - Remove spy #ifdef, they are always on -> cleaner code | ||
233 | * - Add IW_DESCR_FLAG_NOMAX flag for very large requests | ||
234 | * - Start migrating get_wireless_stats to struct iw_handler_def | ||
235 | */ | ||
236 | |||
237 | /**************************** CONSTANTS ****************************/ | ||
238 | |||
239 | /* Enhanced spy support available */ | ||
240 | #define IW_WIRELESS_SPY | ||
241 | #define IW_WIRELESS_THRSPY | ||
242 | |||
243 | /* Special error message for the driver to indicate that we | ||
244 | * should do a commit after return from the iw_handler */ | ||
245 | #define EIWCOMMIT EINPROGRESS | ||
246 | |||
247 | /* Flags available in struct iw_request_info */ | ||
248 | #define IW_REQUEST_FLAG_NONE 0x0000 /* No flag so far */ | ||
249 | |||
250 | /* Type of headers we know about (basically union iwreq_data) */ | ||
251 | #define IW_HEADER_TYPE_NULL 0 /* Not available */ | ||
252 | #define IW_HEADER_TYPE_CHAR 2 /* char [IFNAMSIZ] */ | ||
253 | #define IW_HEADER_TYPE_UINT 4 /* __u32 */ | ||
254 | #define IW_HEADER_TYPE_FREQ 5 /* struct iw_freq */ | ||
255 | #define IW_HEADER_TYPE_ADDR 6 /* struct sockaddr */ | ||
256 | #define IW_HEADER_TYPE_POINT 8 /* struct iw_point */ | ||
257 | #define IW_HEADER_TYPE_PARAM 9 /* struct iw_param */ | ||
258 | #define IW_HEADER_TYPE_QUAL 10 /* struct iw_quality */ | ||
259 | |||
260 | /* Handling flags */ | ||
261 | /* Most are not implemented. I just use them as a reminder of some | ||
262 | * cool features we might need one day ;-) */ | ||
263 | #define IW_DESCR_FLAG_NONE 0x0000 /* Obvious */ | ||
264 | /* Wrapper level flags */ | ||
265 | #define IW_DESCR_FLAG_DUMP 0x0001 /* Not part of the dump command */ | ||
266 | #define IW_DESCR_FLAG_EVENT 0x0002 /* Generate an event on SET */ | ||
267 | #define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET : request is ROOT only */ | ||
268 | /* SET : Omit payload from generated iwevent */ | ||
269 | #define IW_DESCR_FLAG_NOMAX 0x0008 /* GET : no limit on request size */ | ||
270 | /* Driver level flags */ | ||
271 | #define IW_DESCR_FLAG_WAIT 0x0100 /* Wait for driver event */ | ||
272 | |||
273 | /****************************** TYPES ******************************/ | ||
274 | |||
275 | /* ----------------------- WIRELESS HANDLER ----------------------- */ | ||
276 | /* | ||
277 | * A wireless handler is just a standard function, that looks like the | ||
278 | * ioctl handler. | ||
279 | * We also define there how a handler list look like... As the Wireless | ||
280 | * Extension space is quite dense, we use a simple array, which is faster | ||
281 | * (that's the perfect hash table ;-). | ||
282 | */ | ||
283 | |||
284 | /* | ||
285 | * Meta data about the request passed to the iw_handler. | ||
286 | * Most handlers can safely ignore what's in there. | ||
287 | * The 'cmd' field might come handy if you want to use the same handler | ||
288 | * for multiple command... | ||
289 | * This struct is also my long term insurance. I can add new fields here | ||
290 | * without breaking the prototype of iw_handler... | ||
291 | */ | ||
292 | struct iw_request_info | ||
293 | { | ||
294 | __u16 cmd; /* Wireless Extension command */ | ||
295 | __u16 flags; /* More to come ;-) */ | ||
296 | }; | ||
297 | |||
298 | struct net_device; | ||
299 | |||
300 | /* | ||
301 | * This is how a function handling a Wireless Extension should look | ||
302 | * like (both get and set, standard and private). | ||
303 | */ | ||
304 | typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info, | ||
305 | union iwreq_data *wrqu, char *extra); | ||
306 | |||
307 | /* | ||
308 | * This define all the handler that the driver export. | ||
309 | * As you need only one per driver type, please use a static const | ||
310 | * shared by all driver instances... Same for the members... | ||
311 | * This will be linked from net_device in <linux/netdevice.h> | ||
312 | */ | ||
313 | struct iw_handler_def | ||
314 | { | ||
315 | /* Number of handlers defined (more precisely, index of the | ||
316 | * last defined handler + 1) */ | ||
317 | __u16 num_standard; | ||
318 | __u16 num_private; | ||
319 | /* Number of private arg description */ | ||
320 | __u16 num_private_args; | ||
321 | |||
322 | /* Array of handlers for standard ioctls | ||
323 | * We will call dev->wireless_handlers->standard[ioctl - SIOCSIWNAME] | ||
324 | */ | ||
325 | const iw_handler * standard; | ||
326 | |||
327 | /* Array of handlers for private ioctls | ||
328 | * Will call dev->wireless_handlers->private[ioctl - SIOCIWFIRSTPRIV] | ||
329 | */ | ||
330 | const iw_handler * private; | ||
331 | |||
332 | /* Arguments of private handler. This one is just a list, so you | ||
333 | * can put it in any order you want and should not leave holes... | ||
334 | * We will automatically export that to user space... */ | ||
335 | const struct iw_priv_args * private_args; | ||
336 | |||
337 | /* This field will be *removed* in the next version of WE */ | ||
338 | long spy_offset; /* DO NOT USE */ | ||
339 | |||
340 | /* New location of get_wireless_stats, to de-bloat struct net_device. | ||
341 | * The old pointer in struct net_device will be gradually phased | ||
342 | * out, and drivers are encouraged to use this one... */ | ||
343 | struct iw_statistics* (*get_wireless_stats)(struct net_device *dev); | ||
344 | }; | ||
345 | |||
346 | /* ---------------------- IOCTL DESCRIPTION ---------------------- */ | ||
347 | /* | ||
348 | * One of the main goal of the new interface is to deal entirely with | ||
349 | * user space/kernel space memory move. | ||
350 | * For that, we need to know : | ||
351 | * o if iwreq is a pointer or contain the full data | ||
352 | * o what is the size of the data to copy | ||
353 | * | ||
354 | * For private IOCTLs, we use the same rules as used by iwpriv and | ||
355 | * defined in struct iw_priv_args. | ||
356 | * | ||
357 | * For standard IOCTLs, things are quite different and we need to | ||
358 | * use the stuctures below. Actually, this struct is also more | ||
359 | * efficient, but that's another story... | ||
360 | */ | ||
361 | |||
362 | /* | ||
363 | * Describe how a standard IOCTL looks like. | ||
364 | */ | ||
365 | struct iw_ioctl_description | ||
366 | { | ||
367 | __u8 header_type; /* NULL, iw_point or other */ | ||
368 | __u8 token_type; /* Future */ | ||
369 | __u16 token_size; /* Granularity of payload */ | ||
370 | __u16 min_tokens; /* Min acceptable token number */ | ||
371 | __u16 max_tokens; /* Max acceptable token number */ | ||
372 | __u32 flags; /* Special handling of the request */ | ||
373 | }; | ||
374 | |||
375 | /* Need to think of short header translation table. Later. */ | ||
376 | |||
377 | /* --------------------- ENHANCED SPY SUPPORT --------------------- */ | ||
378 | /* | ||
379 | * In the old days, the driver was handling spy support all by itself. | ||
380 | * Now, the driver can delegate this task to Wireless Extensions. | ||
381 | * It needs to include this struct in its private part and use the | ||
382 | * standard spy iw_handler. | ||
383 | */ | ||
384 | |||
385 | /* | ||
386 | * Instance specific spy data, i.e. addresses spied and quality for them. | ||
387 | */ | ||
388 | struct iw_spy_data | ||
389 | { | ||
390 | /* --- Standard spy support --- */ | ||
391 | int spy_number; | ||
392 | u_char spy_address[IW_MAX_SPY][ETH_ALEN]; | ||
393 | struct iw_quality spy_stat[IW_MAX_SPY]; | ||
394 | /* --- Enhanced spy support (event) */ | ||
395 | struct iw_quality spy_thr_low; /* Low threshold */ | ||
396 | struct iw_quality spy_thr_high; /* High threshold */ | ||
397 | u_char spy_thr_under[IW_MAX_SPY]; | ||
398 | }; | ||
399 | |||
400 | /* --------------------- DEVICE WIRELESS DATA --------------------- */ | ||
401 | /* | ||
402 | * This is all the wireless data specific to a device instance that | ||
403 | * is managed by the core of Wireless Extensions. | ||
404 | * We only keep pointer to those structures, so that a driver is free | ||
405 | * to share them between instances. | ||
406 | * This structure should be initialised before registering the device. | ||
407 | * Access to this data follow the same rules as any other struct net_device | ||
408 | * data (i.e. valid as long as struct net_device exist, same locking rules). | ||
409 | */ | ||
410 | struct iw_public_data { | ||
411 | /* Driver enhanced spy support */ | ||
412 | struct iw_spy_data * spy_data; | ||
413 | }; | ||
414 | |||
415 | /**************************** PROTOTYPES ****************************/ | ||
416 | /* | ||
417 | * Functions part of the Wireless Extensions (defined in net/core/wireless.c). | ||
418 | * Those may be called only within the kernel. | ||
419 | */ | ||
420 | |||
421 | /* First : function strictly used inside the kernel */ | ||
422 | |||
423 | /* Handle /proc/net/wireless, called in net/code/dev.c */ | ||
424 | extern int dev_get_wireless_info(char * buffer, char **start, off_t offset, | ||
425 | int length); | ||
426 | |||
427 | /* Handle IOCTLs, called in net/code/dev.c */ | ||
428 | extern int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd); | ||
429 | |||
430 | /* Second : functions that may be called by driver modules */ | ||
431 | |||
432 | /* Send a single event to user space */ | ||
433 | extern void wireless_send_event(struct net_device * dev, | ||
434 | unsigned int cmd, | ||
435 | union iwreq_data * wrqu, | ||
436 | char * extra); | ||
437 | |||
438 | /* We may need a function to send a stream of events to user space. | ||
439 | * More on that later... */ | ||
440 | |||
441 | /* Standard handler for SIOCSIWSPY */ | ||
442 | extern int iw_handler_set_spy(struct net_device * dev, | ||
443 | struct iw_request_info * info, | ||
444 | union iwreq_data * wrqu, | ||
445 | char * extra); | ||
446 | /* Standard handler for SIOCGIWSPY */ | ||
447 | extern int iw_handler_get_spy(struct net_device * dev, | ||
448 | struct iw_request_info * info, | ||
449 | union iwreq_data * wrqu, | ||
450 | char * extra); | ||
451 | /* Standard handler for SIOCSIWTHRSPY */ | ||
452 | extern int iw_handler_set_thrspy(struct net_device * dev, | ||
453 | struct iw_request_info *info, | ||
454 | union iwreq_data * wrqu, | ||
455 | char * extra); | ||
456 | /* Standard handler for SIOCGIWTHRSPY */ | ||
457 | extern int iw_handler_get_thrspy(struct net_device * dev, | ||
458 | struct iw_request_info *info, | ||
459 | union iwreq_data * wrqu, | ||
460 | char * extra); | ||
461 | /* Driver call to update spy records */ | ||
462 | extern void wireless_spy_update(struct net_device * dev, | ||
463 | unsigned char * address, | ||
464 | struct iw_quality * wstats); | ||
465 | |||
466 | /************************* INLINE FUNTIONS *************************/ | ||
467 | /* | ||
468 | * Function that are so simple that it's more efficient inlining them | ||
469 | */ | ||
470 | |||
471 | /*------------------------------------------------------------------*/ | ||
472 | /* | ||
473 | * Wrapper to add an Wireless Event to a stream of events. | ||
474 | */ | ||
475 | static inline char * | ||
476 | iwe_stream_add_event(char * stream, /* Stream of events */ | ||
477 | char * ends, /* End of stream */ | ||
478 | struct iw_event *iwe, /* Payload */ | ||
479 | int event_len) /* Real size of payload */ | ||
480 | { | ||
481 | /* Check if it's possible */ | ||
482 | if((stream + event_len) < ends) { | ||
483 | iwe->len = event_len; | ||
484 | memcpy(stream, (char *) iwe, event_len); | ||
485 | stream += event_len; | ||
486 | } | ||
487 | return stream; | ||
488 | } | ||
489 | |||
490 | /*------------------------------------------------------------------*/ | ||
491 | /* | ||
492 | * Wrapper to add an short Wireless Event containing a pointer to a | ||
493 | * stream of events. | ||
494 | */ | ||
495 | static inline char * | ||
496 | iwe_stream_add_point(char * stream, /* Stream of events */ | ||
497 | char * ends, /* End of stream */ | ||
498 | struct iw_event *iwe, /* Payload */ | ||
499 | char * extra) | ||
500 | { | ||
501 | int event_len = IW_EV_POINT_LEN + iwe->u.data.length; | ||
502 | /* Check if it's possible */ | ||
503 | if((stream + event_len) < ends) { | ||
504 | iwe->len = event_len; | ||
505 | memcpy(stream, (char *) iwe, IW_EV_POINT_LEN); | ||
506 | memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length); | ||
507 | stream += event_len; | ||
508 | } | ||
509 | return stream; | ||
510 | } | ||
511 | |||
512 | /*------------------------------------------------------------------*/ | ||
513 | /* | ||
514 | * Wrapper to add a value to a Wireless Event in a stream of events. | ||
515 | * Be careful, this one is tricky to use properly : | ||
516 | * At the first run, you need to have (value = event + IW_EV_LCP_LEN). | ||
517 | */ | ||
518 | static inline char * | ||
519 | iwe_stream_add_value(char * event, /* Event in the stream */ | ||
520 | char * value, /* Value in event */ | ||
521 | char * ends, /* End of stream */ | ||
522 | struct iw_event *iwe, /* Payload */ | ||
523 | int event_len) /* Real size of payload */ | ||
524 | { | ||
525 | /* Don't duplicate LCP */ | ||
526 | event_len -= IW_EV_LCP_LEN; | ||
527 | |||
528 | /* Check if it's possible */ | ||
529 | if((value + event_len) < ends) { | ||
530 | /* Add new value */ | ||
531 | memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len); | ||
532 | value += event_len; | ||
533 | /* Patch LCP */ | ||
534 | iwe->len = value - event; | ||
535 | memcpy(event, (char *) iwe, IW_EV_LCP_LEN); | ||
536 | } | ||
537 | return value; | ||
538 | } | ||
539 | |||
540 | #endif /* _IW_HANDLER_H */ | ||
diff --git a/include/net/lapb.h b/include/net/lapb.h new file mode 100644 index 000000000000..96cb5ddaa9f1 --- /dev/null +++ b/include/net/lapb.h | |||
@@ -0,0 +1,152 @@ | |||
1 | #ifndef _LAPB_H | ||
2 | #define _LAPB_H | ||
3 | #include <linux/lapb.h> | ||
4 | |||
5 | #define LAPB_HEADER_LEN 20 /* LAPB over Ethernet + a bit more */ | ||
6 | |||
7 | #define LAPB_ACK_PENDING_CONDITION 0x01 | ||
8 | #define LAPB_REJECT_CONDITION 0x02 | ||
9 | #define LAPB_PEER_RX_BUSY_CONDITION 0x04 | ||
10 | |||
11 | /* Control field templates */ | ||
12 | #define LAPB_I 0x00 /* Information frames */ | ||
13 | #define LAPB_S 0x01 /* Supervisory frames */ | ||
14 | #define LAPB_U 0x03 /* Unnumbered frames */ | ||
15 | |||
16 | #define LAPB_RR 0x01 /* Receiver ready */ | ||
17 | #define LAPB_RNR 0x05 /* Receiver not ready */ | ||
18 | #define LAPB_REJ 0x09 /* Reject */ | ||
19 | |||
20 | #define LAPB_SABM 0x2F /* Set Asynchronous Balanced Mode */ | ||
21 | #define LAPB_SABME 0x6F /* Set Asynchronous Balanced Mode Extended */ | ||
22 | #define LAPB_DISC 0x43 /* Disconnect */ | ||
23 | #define LAPB_DM 0x0F /* Disconnected mode */ | ||
24 | #define LAPB_UA 0x63 /* Unnumbered acknowledge */ | ||
25 | #define LAPB_FRMR 0x87 /* Frame reject */ | ||
26 | |||
27 | #define LAPB_ILLEGAL 0x100 /* Impossible to be a real frame type */ | ||
28 | |||
29 | #define LAPB_SPF 0x10 /* Poll/final bit for standard LAPB */ | ||
30 | #define LAPB_EPF 0x01 /* Poll/final bit for extended LAPB */ | ||
31 | |||
32 | #define LAPB_FRMR_W 0x01 /* Control field invalid */ | ||
33 | #define LAPB_FRMR_X 0x02 /* I field invalid */ | ||
34 | #define LAPB_FRMR_Y 0x04 /* I field too long */ | ||
35 | #define LAPB_FRMR_Z 0x08 /* Invalid N(R) */ | ||
36 | |||
37 | #define LAPB_POLLOFF 0 | ||
38 | #define LAPB_POLLON 1 | ||
39 | |||
40 | /* LAPB C-bit */ | ||
41 | #define LAPB_COMMAND 1 | ||
42 | #define LAPB_RESPONSE 2 | ||
43 | |||
44 | #define LAPB_ADDR_A 0x03 | ||
45 | #define LAPB_ADDR_B 0x01 | ||
46 | #define LAPB_ADDR_C 0x0F | ||
47 | #define LAPB_ADDR_D 0x07 | ||
48 | |||
49 | /* Define Link State constants. */ | ||
50 | enum { | ||
51 | LAPB_STATE_0, /* Disconnected State */ | ||
52 | LAPB_STATE_1, /* Awaiting Connection State */ | ||
53 | LAPB_STATE_2, /* Awaiting Disconnection State */ | ||
54 | LAPB_STATE_3, /* Data Transfer State */ | ||
55 | LAPB_STATE_4 /* Frame Reject State */ | ||
56 | }; | ||
57 | |||
58 | #define LAPB_DEFAULT_MODE (LAPB_STANDARD | LAPB_SLP | LAPB_DTE) | ||
59 | #define LAPB_DEFAULT_WINDOW 7 /* Window=7 */ | ||
60 | #define LAPB_DEFAULT_T1 (5 * HZ) /* T1=5s */ | ||
61 | #define LAPB_DEFAULT_T2 (1 * HZ) /* T2=1s */ | ||
62 | #define LAPB_DEFAULT_N2 20 /* N2=20 */ | ||
63 | |||
64 | #define LAPB_SMODULUS 8 | ||
65 | #define LAPB_EMODULUS 128 | ||
66 | |||
67 | /* | ||
68 | * Information about the current frame. | ||
69 | */ | ||
70 | struct lapb_frame { | ||
71 | unsigned short type; /* Parsed type */ | ||
72 | unsigned short nr, ns; /* N(R), N(S) */ | ||
73 | unsigned char cr; /* Command/Response */ | ||
74 | unsigned char pf; /* Poll/Final */ | ||
75 | unsigned char control[2]; /* Original control data*/ | ||
76 | }; | ||
77 | |||
78 | /* | ||
79 | * The per LAPB connection control structure. | ||
80 | */ | ||
81 | struct lapb_cb { | ||
82 | struct list_head node; | ||
83 | struct net_device *dev; | ||
84 | |||
85 | /* Link status fields */ | ||
86 | unsigned int mode; | ||
87 | unsigned char state; | ||
88 | unsigned short vs, vr, va; | ||
89 | unsigned char condition; | ||
90 | unsigned short n2, n2count; | ||
91 | unsigned short t1, t2; | ||
92 | struct timer_list t1timer, t2timer; | ||
93 | |||
94 | /* Internal control information */ | ||
95 | struct sk_buff_head write_queue; | ||
96 | struct sk_buff_head ack_queue; | ||
97 | unsigned char window; | ||
98 | struct lapb_register_struct callbacks; | ||
99 | |||
100 | /* FRMR control information */ | ||
101 | struct lapb_frame frmr_data; | ||
102 | unsigned char frmr_type; | ||
103 | |||
104 | atomic_t refcnt; | ||
105 | }; | ||
106 | |||
107 | /* lapb_iface.c */ | ||
108 | extern void lapb_connect_confirmation(struct lapb_cb *lapb, int); | ||
109 | extern void lapb_connect_indication(struct lapb_cb *lapb, int); | ||
110 | extern void lapb_disconnect_confirmation(struct lapb_cb *lapb, int); | ||
111 | extern void lapb_disconnect_indication(struct lapb_cb *lapb, int); | ||
112 | extern int lapb_data_indication(struct lapb_cb *lapb, struct sk_buff *); | ||
113 | extern int lapb_data_transmit(struct lapb_cb *lapb, struct sk_buff *); | ||
114 | |||
115 | /* lapb_in.c */ | ||
116 | extern void lapb_data_input(struct lapb_cb *lapb, struct sk_buff *); | ||
117 | |||
118 | /* lapb_out.c */ | ||
119 | extern void lapb_kick(struct lapb_cb *lapb); | ||
120 | extern void lapb_transmit_buffer(struct lapb_cb *lapb, struct sk_buff *, int); | ||
121 | extern void lapb_establish_data_link(struct lapb_cb *lapb); | ||
122 | extern void lapb_enquiry_response(struct lapb_cb *lapb); | ||
123 | extern void lapb_timeout_response(struct lapb_cb *lapb); | ||
124 | extern void lapb_check_iframes_acked(struct lapb_cb *lapb, unsigned short); | ||
125 | extern void lapb_check_need_response(struct lapb_cb *lapb, int, int); | ||
126 | |||
127 | /* lapb_subr.c */ | ||
128 | extern void lapb_clear_queues(struct lapb_cb *lapb); | ||
129 | extern void lapb_frames_acked(struct lapb_cb *lapb, unsigned short); | ||
130 | extern void lapb_requeue_frames(struct lapb_cb *lapb); | ||
131 | extern int lapb_validate_nr(struct lapb_cb *lapb, unsigned short); | ||
132 | extern int lapb_decode(struct lapb_cb *lapb, struct sk_buff *, struct lapb_frame *); | ||
133 | extern void lapb_send_control(struct lapb_cb *lapb, int, int, int); | ||
134 | extern void lapb_transmit_frmr(struct lapb_cb *lapb); | ||
135 | |||
136 | /* lapb_timer.c */ | ||
137 | extern void lapb_start_t1timer(struct lapb_cb *lapb); | ||
138 | extern void lapb_start_t2timer(struct lapb_cb *lapb); | ||
139 | extern void lapb_stop_t1timer(struct lapb_cb *lapb); | ||
140 | extern void lapb_stop_t2timer(struct lapb_cb *lapb); | ||
141 | extern int lapb_t1timer_running(struct lapb_cb *lapb); | ||
142 | |||
143 | /* | ||
144 | * Debug levels. | ||
145 | * 0 = Off | ||
146 | * 1 = State Changes | ||
147 | * 2 = Packets I/O and State Changes | ||
148 | * 3 = Hex dumps, Packets I/O and State Changes. | ||
149 | */ | ||
150 | #define LAPB_DEBUG 0 | ||
151 | |||
152 | #endif | ||
diff --git a/include/net/llc.h b/include/net/llc.h new file mode 100644 index 000000000000..c9aed2a8b4e2 --- /dev/null +++ b/include/net/llc.h | |||
@@ -0,0 +1,99 @@ | |||
1 | #ifndef LLC_H | ||
2 | #define LLC_H | ||
3 | /* | ||
4 | * Copyright (c) 1997 by Procom Technology, Inc. | ||
5 | * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> | ||
6 | * | ||
7 | * This program can be redistributed or modified under the terms of the | ||
8 | * GNU General Public License as published by the Free Software Foundation. | ||
9 | * This program is distributed without any warranty or implied warranty | ||
10 | * of merchantability or fitness for a particular purpose. | ||
11 | * | ||
12 | * See the GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/if.h> | ||
16 | #include <linux/if_ether.h> | ||
17 | #include <linux/list.h> | ||
18 | #include <linux/spinlock.h> | ||
19 | |||
20 | struct net_device; | ||
21 | struct packet_type; | ||
22 | struct sk_buff; | ||
23 | |||
24 | struct llc_addr { | ||
25 | unsigned char lsap; | ||
26 | unsigned char mac[IFHWADDRLEN]; | ||
27 | }; | ||
28 | |||
29 | #define LLC_SAP_STATE_INACTIVE 1 | ||
30 | #define LLC_SAP_STATE_ACTIVE 2 | ||
31 | |||
32 | /** | ||
33 | * struct llc_sap - Defines the SAP component | ||
34 | * | ||
35 | * @station - station this sap belongs to | ||
36 | * @state - sap state | ||
37 | * @p_bit - only lowest-order bit used | ||
38 | * @f_bit - only lowest-order bit used | ||
39 | * @laddr - SAP value in this 'lsap' | ||
40 | * @node - entry in station sap_list | ||
41 | * @sk_list - LLC sockets this one manages | ||
42 | */ | ||
43 | struct llc_sap { | ||
44 | unsigned char state; | ||
45 | unsigned char p_bit; | ||
46 | unsigned char f_bit; | ||
47 | int (*rcv_func)(struct sk_buff *skb, | ||
48 | struct net_device *dev, | ||
49 | struct packet_type *pt); | ||
50 | struct llc_addr laddr; | ||
51 | struct list_head node; | ||
52 | struct { | ||
53 | rwlock_t lock; | ||
54 | struct hlist_head list; | ||
55 | } sk_list; | ||
56 | }; | ||
57 | |||
58 | #define LLC_DEST_INVALID 0 /* Invalid LLC PDU type */ | ||
59 | #define LLC_DEST_SAP 1 /* Type 1 goes here */ | ||
60 | #define LLC_DEST_CONN 2 /* Type 2 goes here */ | ||
61 | |||
62 | extern struct list_head llc_sap_list; | ||
63 | extern rwlock_t llc_sap_list_lock; | ||
64 | extern unsigned char llc_station_mac_sa[ETH_ALEN]; | ||
65 | |||
66 | extern int llc_rcv(struct sk_buff *skb, struct net_device *dev, | ||
67 | struct packet_type *pt); | ||
68 | |||
69 | extern int llc_mac_hdr_init(struct sk_buff *skb, | ||
70 | unsigned char *sa, unsigned char *da); | ||
71 | |||
72 | extern void llc_add_pack(int type, void (*handler)(struct llc_sap *sap, | ||
73 | struct sk_buff *skb)); | ||
74 | extern void llc_remove_pack(int type); | ||
75 | |||
76 | extern void llc_set_station_handler(void (*handler)(struct sk_buff *skb)); | ||
77 | |||
78 | extern struct llc_sap *llc_sap_open(unsigned char lsap, | ||
79 | int (*rcv)(struct sk_buff *skb, | ||
80 | struct net_device *dev, | ||
81 | struct packet_type *pt)); | ||
82 | extern void llc_sap_close(struct llc_sap *sap); | ||
83 | |||
84 | extern struct llc_sap *llc_sap_find(unsigned char sap_value); | ||
85 | |||
86 | extern int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb, | ||
87 | unsigned char *dmac, unsigned char dsap); | ||
88 | |||
89 | extern int llc_station_init(void); | ||
90 | extern void llc_station_exit(void); | ||
91 | |||
92 | #ifdef CONFIG_PROC_FS | ||
93 | extern int llc_proc_init(void); | ||
94 | extern void llc_proc_exit(void); | ||
95 | #else | ||
96 | #define llc_proc_init() (0) | ||
97 | #define llc_proc_exit() do { } while(0) | ||
98 | #endif /* CONFIG_PROC_FS */ | ||
99 | #endif /* LLC_H */ | ||
diff --git a/include/net/llc_c_ac.h b/include/net/llc_c_ac.h new file mode 100644 index 000000000000..df83f69d2de4 --- /dev/null +++ b/include/net/llc_c_ac.h | |||
@@ -0,0 +1,202 @@ | |||
1 | #ifndef LLC_C_AC_H | ||
2 | #define LLC_C_AC_H | ||
3 | /* | ||
4 | * Copyright (c) 1997 by Procom Technology,Inc. | ||
5 | * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> | ||
6 | * | ||
7 | * This program can be redistributed or modified under the terms of the | ||
8 | * GNU General Public License as published by the Free Software Foundation. | ||
9 | * This program is distributed without any warranty or implied warranty | ||
10 | * of merchantability or fitness for a particular purpose. | ||
11 | * | ||
12 | * See the GNU General Public License for more details. | ||
13 | */ | ||
14 | /* Connection component state transition actions */ | ||
15 | /* | ||
16 | * Connection state transition actions | ||
17 | * (Fb = F bit; Pb = P bit; Xb = X bit) | ||
18 | */ | ||
19 | #define LLC_CONN_AC_CLR_REMOTE_BUSY 1 | ||
20 | #define LLC_CONN_AC_CONN_IND 2 | ||
21 | #define LLC_CONN_AC_CONN_CONFIRM 3 | ||
22 | #define LLC_CONN_AC_DATA_IND 4 | ||
23 | #define LLC_CONN_AC_DISC_IND 5 | ||
24 | #define LLC_CONN_AC_RESET_IND 6 | ||
25 | #define LLC_CONN_AC_RESET_CONFIRM 7 | ||
26 | #define LLC_CONN_AC_REPORT_STATUS 8 | ||
27 | #define LLC_CONN_AC_CLR_REMOTE_BUSY_IF_Fb_EQ_1 9 | ||
28 | #define LLC_CONN_AC_STOP_REJ_TMR_IF_DATA_FLAG_EQ_2 10 | ||
29 | #define LLC_CONN_AC_SEND_DISC_CMD_Pb_SET_X 11 | ||
30 | #define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_Pb 12 | ||
31 | #define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_1 13 | ||
32 | #define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_F_FLAG 14 | ||
33 | #define LLC_CONN_AC_SEND_FRMR_RSP_Fb_SET_X 15 | ||
34 | #define LLC_CONN_AC_RESEND_FRMR_RSP_Fb_SET_0 16 | ||
35 | #define LLC_CONN_AC_RESEND_FRMR_RSP_Fb_SET_Pb 17 | ||
36 | #define LLC_CONN_AC_SEND_I_CMD_Pb_SET_1 18 | ||
37 | #define LLC_CONN_AC_RESEND_I_CMD_Pb_SET_1 19 | ||
38 | #define LLC_CONN_AC_RESEND_I_CMD_Pb_SET_1_OR_SEND_RR 20 | ||
39 | #define LLC_CONN_AC_SEND_I_XXX_Xb_SET_0 21 | ||
40 | #define LLC_CONN_AC_RESEND_I_XXX_Xb_SET_0 22 | ||
41 | #define LLC_CONN_AC_RESEND_I_XXX_Xb_SET_0_OR_SEND_RR 23 | ||
42 | #define LLC_CONN_AC_RESEND_I_RSP_Fb_SET_1 24 | ||
43 | #define LLC_CONN_AC_SEND_REJ_CMD_Pb_SET_1 25 | ||
44 | #define LLC_CONN_AC_SEND_REJ_RSP_Fb_SET_1 26 | ||
45 | #define LLC_CONN_AC_SEND_REJ_XXX_Xb_SET_0 27 | ||
46 | #define LLC_CONN_AC_SEND_RNR_CMD_Pb_SET_1 28 | ||
47 | #define LLC_CONN_AC_SEND_RNR_RSP_Fb_SET_1 29 | ||
48 | #define LLC_CONN_AC_SEND_RNR_XXX_Xb_SET_0 30 | ||
49 | #define LLC_CONN_AC_SET_REMOTE_BUSY 31 | ||
50 | #define LLC_CONN_AC_OPTIONAL_SEND_RNR_XXX_Xb_SET_0 32 | ||
51 | #define LLC_CONN_AC_SEND_RR_CMD_Pb_SET_1 33 | ||
52 | #define LLC_CONN_AC_SEND_ACK_CMD_Pb_SET_1 34 | ||
53 | #define LLC_CONN_AC_SEND_RR_RSP_Fb_SET_1 35 | ||
54 | #define LLC_CONN_AC_SEND_ACK_RSP_Fb_SET_1 36 | ||
55 | #define LLC_CONN_AC_SEND_RR_XXX_Xb_SET_0 37 | ||
56 | #define LLC_CONN_AC_SEND_ACK_XXX_Xb_SET_0 38 | ||
57 | #define LLC_CONN_AC_SEND_SABME_CMD_Pb_SET_X 39 | ||
58 | #define LLC_CONN_AC_SEND_UA_RSP_Fb_SET_Pb 40 | ||
59 | #define LLC_CONN_AC_SEND_UA_RSP_Fb_SET_F_FLAG 41 | ||
60 | #define LLC_CONN_AC_S_FLAG_SET_0 42 | ||
61 | #define LLC_CONN_AC_S_FLAG_SET_1 43 | ||
62 | #define LLC_CONN_AC_START_P_TMR 44 | ||
63 | #define LLC_CONN_AC_START_ACK_TMR 45 | ||
64 | #define LLC_CONN_AC_START_REJ_TMR 46 | ||
65 | #define LLC_CONN_AC_START_ACK_TMR_IF_NOT_RUNNING 47 | ||
66 | #define LLC_CONN_AC_STOP_ACK_TMR 48 | ||
67 | #define LLC_CONN_AC_STOP_P_TMR 49 | ||
68 | #define LLC_CONN_AC_STOP_REJ_TMR 50 | ||
69 | #define LLC_CONN_AC_STOP_ALL_TMRS 51 | ||
70 | #define LLC_CONN_AC_STOP_OTHER_TMRS 52 | ||
71 | #define LLC_CONN_AC_UPDATE_Nr_RECEIVED 53 | ||
72 | #define LLC_CONN_AC_UPDATE_P_FLAG 54 | ||
73 | #define LLC_CONN_AC_DATA_FLAG_SET_2 55 | ||
74 | #define LLC_CONN_AC_DATA_FLAG_SET_0 56 | ||
75 | #define LLC_CONN_AC_DATA_FLAG_SET_1 57 | ||
76 | #define LLC_CONN_AC_DATA_FLAG_SET_1_IF_DATA_FLAG_EQ_0 58 | ||
77 | #define LLC_CONN_AC_P_FLAG_SET_0 59 | ||
78 | #define LLC_CONN_AC_P_FLAG_SET_P 60 | ||
79 | #define LLC_CONN_AC_REMOTE_BUSY_SET_0 61 | ||
80 | #define LLC_CONN_AC_RETRY_CNT_SET_0 62 | ||
81 | #define LLC_CONN_AC_RETRY_CNT_INC_BY_1 63 | ||
82 | #define LLC_CONN_AC_Vr_SET_0 64 | ||
83 | #define LLC_CONN_AC_Vr_INC_BY_1 65 | ||
84 | #define LLC_CONN_AC_Vs_SET_0 66 | ||
85 | #define LLC_CONN_AC_Vs_SET_Nr 67 | ||
86 | #define LLC_CONN_AC_F_FLAG_SET_P 68 | ||
87 | #define LLC_CONN_AC_STOP_SENDACK_TMR 70 | ||
88 | #define LLC_CONN_AC_START_SENDACK_TMR_IF_NOT_RUNNING 71 | ||
89 | |||
90 | typedef int (*llc_conn_action_t)(struct sock *sk, struct sk_buff *skb); | ||
91 | |||
92 | extern int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb); | ||
93 | extern int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb); | ||
94 | extern int llc_conn_ac_conn_confirm(struct sock* sk, struct sk_buff *skb); | ||
95 | extern int llc_conn_ac_data_ind(struct sock* sk, struct sk_buff *skb); | ||
96 | extern int llc_conn_ac_disc_ind(struct sock* sk, struct sk_buff *skb); | ||
97 | extern int llc_conn_ac_rst_ind(struct sock* sk, struct sk_buff *skb); | ||
98 | extern int llc_conn_ac_rst_confirm(struct sock* sk, struct sk_buff *skb); | ||
99 | extern int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock* sk, | ||
100 | struct sk_buff *skb); | ||
101 | extern int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock* sk, | ||
102 | struct sk_buff *skb); | ||
103 | extern int llc_conn_ac_send_disc_cmd_p_set_x(struct sock* sk, | ||
104 | struct sk_buff *skb); | ||
105 | extern int llc_conn_ac_send_dm_rsp_f_set_p(struct sock* sk, | ||
106 | struct sk_buff *skb); | ||
107 | extern int llc_conn_ac_send_dm_rsp_f_set_1(struct sock* sk, | ||
108 | struct sk_buff *skb); | ||
109 | extern int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock* sk, | ||
110 | struct sk_buff *skb); | ||
111 | extern int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock* sk, | ||
112 | struct sk_buff *skb); | ||
113 | extern int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock* sk, | ||
114 | struct sk_buff *skb); | ||
115 | extern int llc_conn_ac_send_i_cmd_p_set_1(struct sock* sk, struct sk_buff *skb); | ||
116 | extern int llc_conn_ac_send_i_xxx_x_set_0(struct sock* sk, struct sk_buff *skb); | ||
117 | extern int llc_conn_ac_resend_i_xxx_x_set_0(struct sock* sk, | ||
118 | struct sk_buff *skb); | ||
119 | extern int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock* sk, | ||
120 | struct sk_buff *skb); | ||
121 | extern int llc_conn_ac_resend_i_rsp_f_set_1(struct sock* sk, | ||
122 | struct sk_buff *skb); | ||
123 | extern int llc_conn_ac_send_rej_cmd_p_set_1(struct sock* sk, | ||
124 | struct sk_buff *skb); | ||
125 | extern int llc_conn_ac_send_rej_rsp_f_set_1(struct sock* sk, | ||
126 | struct sk_buff *skb); | ||
127 | extern int llc_conn_ac_send_rej_xxx_x_set_0(struct sock* sk, | ||
128 | struct sk_buff *skb); | ||
129 | extern int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock* sk, | ||
130 | struct sk_buff *skb); | ||
131 | extern int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock* sk, | ||
132 | struct sk_buff *skb); | ||
133 | extern int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock* sk, | ||
134 | struct sk_buff *skb); | ||
135 | extern int llc_conn_ac_set_remote_busy(struct sock* sk, struct sk_buff *skb); | ||
136 | extern int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock* sk, | ||
137 | struct sk_buff *skb); | ||
138 | extern int llc_conn_ac_send_rr_cmd_p_set_1(struct sock* sk, | ||
139 | struct sk_buff *skb); | ||
140 | extern int llc_conn_ac_send_rr_rsp_f_set_1(struct sock* sk, | ||
141 | struct sk_buff *skb); | ||
142 | extern int llc_conn_ac_send_ack_rsp_f_set_1(struct sock* sk, | ||
143 | struct sk_buff *skb); | ||
144 | extern int llc_conn_ac_send_rr_xxx_x_set_0(struct sock* sk, | ||
145 | struct sk_buff *skb); | ||
146 | extern int llc_conn_ac_send_ack_xxx_x_set_0(struct sock* sk, | ||
147 | struct sk_buff *skb); | ||
148 | extern int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock* sk, | ||
149 | struct sk_buff *skb); | ||
150 | extern int llc_conn_ac_send_ua_rsp_f_set_p(struct sock* sk, | ||
151 | struct sk_buff *skb); | ||
152 | extern int llc_conn_ac_set_s_flag_0(struct sock* sk, struct sk_buff *skb); | ||
153 | extern int llc_conn_ac_set_s_flag_1(struct sock* sk, struct sk_buff *skb); | ||
154 | extern int llc_conn_ac_start_p_timer(struct sock* sk, struct sk_buff *skb); | ||
155 | extern int llc_conn_ac_start_ack_timer(struct sock* sk, struct sk_buff *skb); | ||
156 | extern int llc_conn_ac_start_rej_timer(struct sock* sk, struct sk_buff *skb); | ||
157 | extern int llc_conn_ac_start_ack_tmr_if_not_running(struct sock* sk, | ||
158 | struct sk_buff *skb); | ||
159 | extern int llc_conn_ac_stop_ack_timer(struct sock* sk, struct sk_buff *skb); | ||
160 | extern int llc_conn_ac_stop_p_timer(struct sock* sk, struct sk_buff *skb); | ||
161 | extern int llc_conn_ac_stop_rej_timer(struct sock* sk, struct sk_buff *skb); | ||
162 | extern int llc_conn_ac_stop_all_timers(struct sock* sk, struct sk_buff *skb); | ||
163 | extern int llc_conn_ac_stop_other_timers(struct sock* sk, struct sk_buff *skb); | ||
164 | extern int llc_conn_ac_upd_nr_received(struct sock* sk, struct sk_buff *skb); | ||
165 | extern int llc_conn_ac_inc_tx_win_size(struct sock* sk, struct sk_buff *skb); | ||
166 | extern int llc_conn_ac_dec_tx_win_size(struct sock* sk, struct sk_buff *skb); | ||
167 | extern int llc_conn_ac_upd_p_flag(struct sock* sk, struct sk_buff *skb); | ||
168 | extern int llc_conn_ac_set_data_flag_2(struct sock* sk, struct sk_buff *skb); | ||
169 | extern int llc_conn_ac_set_data_flag_0(struct sock* sk, struct sk_buff *skb); | ||
170 | extern int llc_conn_ac_set_data_flag_1(struct sock* sk, struct sk_buff *skb); | ||
171 | extern int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock* sk, | ||
172 | struct sk_buff *skb); | ||
173 | extern int llc_conn_ac_set_p_flag_0(struct sock* sk, struct sk_buff *skb); | ||
174 | extern int llc_conn_ac_set_remote_busy_0(struct sock* sk, struct sk_buff *skb); | ||
175 | extern int llc_conn_ac_set_retry_cnt_0(struct sock* sk, struct sk_buff *skb); | ||
176 | extern int llc_conn_ac_set_cause_flag_0(struct sock* sk, struct sk_buff *skb); | ||
177 | extern int llc_conn_ac_set_cause_flag_1(struct sock* sk, struct sk_buff *skb); | ||
178 | extern int llc_conn_ac_inc_retry_cnt_by_1(struct sock* sk, struct sk_buff *skb); | ||
179 | extern int llc_conn_ac_set_vr_0(struct sock* sk, struct sk_buff *skb); | ||
180 | extern int llc_conn_ac_inc_vr_by_1(struct sock* sk, struct sk_buff *skb); | ||
181 | extern int llc_conn_ac_set_vs_0(struct sock* sk, struct sk_buff *skb); | ||
182 | extern int llc_conn_ac_set_vs_nr(struct sock* sk, struct sk_buff *skb); | ||
183 | extern int llc_conn_ac_rst_vs(struct sock* sk, struct sk_buff *skb); | ||
184 | extern int llc_conn_ac_upd_vs(struct sock* sk, struct sk_buff *skb); | ||
185 | extern int llc_conn_disc(struct sock* sk, struct sk_buff *skb); | ||
186 | extern int llc_conn_reset(struct sock* sk, struct sk_buff *skb); | ||
187 | extern int llc_conn_ac_disc_confirm(struct sock* sk, struct sk_buff *skb); | ||
188 | extern u8 llc_circular_between(u8 a, u8 b, u8 c); | ||
189 | extern int llc_conn_ac_send_ack_if_needed(struct sock* sk, struct sk_buff *skb); | ||
190 | extern int llc_conn_ac_adjust_npta_by_rr(struct sock* sk, struct sk_buff *skb); | ||
191 | extern int llc_conn_ac_adjust_npta_by_rnr(struct sock* sk, struct sk_buff *skb); | ||
192 | extern int llc_conn_ac_rst_sendack_flag(struct sock* sk, struct sk_buff *skb); | ||
193 | extern int llc_conn_ac_send_i_rsp_as_ack(struct sock* sk, struct sk_buff *skb); | ||
194 | extern int llc_conn_ac_send_i_as_ack(struct sock* sk, struct sk_buff *skb); | ||
195 | |||
196 | extern void llc_conn_busy_tmr_cb(unsigned long timeout_data); | ||
197 | extern void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data); | ||
198 | extern void llc_conn_ack_tmr_cb(unsigned long timeout_data); | ||
199 | extern void llc_conn_rej_tmr_cb(unsigned long timeout_data); | ||
200 | |||
201 | extern void llc_conn_set_p_flag(struct sock *sk, u8 value); | ||
202 | #endif /* LLC_C_AC_H */ | ||
diff --git a/include/net/llc_c_ev.h b/include/net/llc_c_ev.h new file mode 100644 index 000000000000..23a409381fa9 --- /dev/null +++ b/include/net/llc_c_ev.h | |||
@@ -0,0 +1,269 @@ | |||
1 | #ifndef LLC_C_EV_H | ||
2 | #define LLC_C_EV_H | ||
3 | /* | ||
4 | * Copyright (c) 1997 by Procom Technology,Inc. | ||
5 | * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> | ||
6 | * | ||
7 | * This program can be redistributed or modified under the terms of the | ||
8 | * GNU General Public License as published by the Free Software Foundation. | ||
9 | * This program is distributed without any warranty or implied warranty | ||
10 | * of merchantability or fitness for a particular purpose. | ||
11 | * | ||
12 | * See the GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <net/sock.h> | ||
16 | |||
17 | /* Connection component state transition event qualifiers */ | ||
18 | /* Types of events (possible values in 'ev->type') */ | ||
19 | #define LLC_CONN_EV_TYPE_SIMPLE 1 | ||
20 | #define LLC_CONN_EV_TYPE_CONDITION 2 | ||
21 | #define LLC_CONN_EV_TYPE_PRIM 3 | ||
22 | #define LLC_CONN_EV_TYPE_PDU 4 /* command/response PDU */ | ||
23 | #define LLC_CONN_EV_TYPE_ACK_TMR 5 | ||
24 | #define LLC_CONN_EV_TYPE_P_TMR 6 | ||
25 | #define LLC_CONN_EV_TYPE_REJ_TMR 7 | ||
26 | #define LLC_CONN_EV_TYPE_BUSY_TMR 8 | ||
27 | #define LLC_CONN_EV_TYPE_RPT_STATUS 9 | ||
28 | #define LLC_CONN_EV_TYPE_SENDACK_TMR 10 | ||
29 | |||
30 | #define NBR_CONN_EV 5 | ||
31 | /* Connection events which cause state transitions when fully qualified */ | ||
32 | |||
33 | #define LLC_CONN_EV_CONN_REQ 1 | ||
34 | #define LLC_CONN_EV_CONN_RESP 2 | ||
35 | #define LLC_CONN_EV_DATA_REQ 3 | ||
36 | #define LLC_CONN_EV_DISC_REQ 4 | ||
37 | #define LLC_CONN_EV_RESET_REQ 5 | ||
38 | #define LLC_CONN_EV_RESET_RESP 6 | ||
39 | #define LLC_CONN_EV_LOCAL_BUSY_DETECTED 7 | ||
40 | #define LLC_CONN_EV_LOCAL_BUSY_CLEARED 8 | ||
41 | #define LLC_CONN_EV_RX_BAD_PDU 9 | ||
42 | #define LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X 10 | ||
43 | #define LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X 11 | ||
44 | #define LLC_CONN_EV_RX_FRMR_RSP_Fbit_SET_X 12 | ||
45 | #define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X 13 | ||
46 | #define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X_UNEXPD_Ns 14 | ||
47 | #define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X_INVAL_Ns 15 | ||
48 | #define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X 16 | ||
49 | #define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_UNEXPD_Ns 17 | ||
50 | #define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_INVAL_Ns 18 | ||
51 | #define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_X 19 | ||
52 | #define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_X 20 | ||
53 | #define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_X 21 | ||
54 | #define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_X 22 | ||
55 | #define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_X 23 | ||
56 | #define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_X 24 | ||
57 | #define LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X 25 | ||
58 | #define LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X 26 | ||
59 | #define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_X 27 | ||
60 | #define LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_X 28 | ||
61 | #define LLC_CONN_EV_RX_XXX_YYY 29 | ||
62 | #define LLC_CONN_EV_RX_ZZZ_CMD_Pbit_SET_X_INVAL_Nr 30 | ||
63 | #define LLC_CONN_EV_RX_ZZZ_RSP_Fbit_SET_X_INVAL_Nr 31 | ||
64 | #define LLC_CONN_EV_P_TMR_EXP 32 | ||
65 | #define LLC_CONN_EV_ACK_TMR_EXP 33 | ||
66 | #define LLC_CONN_EV_REJ_TMR_EXP 34 | ||
67 | #define LLC_CONN_EV_BUSY_TMR_EXP 35 | ||
68 | #define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_1 36 | ||
69 | #define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_0 37 | ||
70 | #define LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns 38 | ||
71 | #define LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns 39 | ||
72 | #define LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns 40 | ||
73 | #define LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns 41 | ||
74 | #define LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 42 | ||
75 | #define LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 43 | ||
76 | #define LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 44 | ||
77 | #define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 45 | ||
78 | #define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 46 | ||
79 | #define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 47 | ||
80 | #define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 48 | ||
81 | #define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 49 | ||
82 | #define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 50 | ||
83 | #define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 51 | ||
84 | #define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 52 | ||
85 | #define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 53 | ||
86 | #define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 54 | ||
87 | #define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 55 | ||
88 | #define LLC_CONN_EV_RX_I_RSP_Fbit_SET_1 56 | ||
89 | #define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_1 57 | ||
90 | #define LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_1 58 | ||
91 | #define LLC_CONN_EV_TX_BUFF_FULL 59 | ||
92 | |||
93 | #define LLC_CONN_EV_INIT_P_F_CYCLE 100 | ||
94 | /* | ||
95 | * Connection event qualifiers; for some events a certain combination of | ||
96 | * these qualifiers must be TRUE before event recognized valid for state; | ||
97 | * these constants act as indexes into the Event Qualifier function | ||
98 | * table | ||
99 | */ | ||
100 | #define LLC_CONN_EV_QFY_DATA_FLAG_EQ_1 1 | ||
101 | #define LLC_CONN_EV_QFY_DATA_FLAG_EQ_0 2 | ||
102 | #define LLC_CONN_EV_QFY_DATA_FLAG_EQ_2 3 | ||
103 | #define LLC_CONN_EV_QFY_P_FLAG_EQ_1 4 | ||
104 | #define LLC_CONN_EV_QFY_P_FLAG_EQ_0 5 | ||
105 | #define LLC_CONN_EV_QFY_P_FLAG_EQ_Fbit 6 | ||
106 | #define LLC_CONN_EV_QFY_REMOTE_BUSY_EQ_0 7 | ||
107 | #define LLC_CONN_EV_QFY_RETRY_CNT_LT_N2 8 | ||
108 | #define LLC_CONN_EV_QFY_RETRY_CNT_GTE_N2 9 | ||
109 | #define LLC_CONN_EV_QFY_S_FLAG_EQ_1 10 | ||
110 | #define LLC_CONN_EV_QFY_S_FLAG_EQ_0 11 | ||
111 | #define LLC_CONN_EV_QFY_INIT_P_F_CYCLE 12 | ||
112 | |||
113 | struct llc_conn_state_ev { | ||
114 | u8 type; | ||
115 | u8 prim; | ||
116 | u8 prim_type; | ||
117 | u8 reason; | ||
118 | u8 status; | ||
119 | u8 ind_prim; | ||
120 | u8 cfm_prim; | ||
121 | }; | ||
122 | |||
123 | static __inline__ struct llc_conn_state_ev *llc_conn_ev(struct sk_buff *skb) | ||
124 | { | ||
125 | return (struct llc_conn_state_ev *)skb->cb; | ||
126 | } | ||
127 | |||
128 | typedef int (*llc_conn_ev_t)(struct sock *sk, struct sk_buff *skb); | ||
129 | typedef int (*llc_conn_ev_qfyr_t)(struct sock *sk, struct sk_buff *skb); | ||
130 | |||
131 | extern int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb); | ||
132 | extern int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb); | ||
133 | extern int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb); | ||
134 | extern int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb); | ||
135 | extern int llc_conn_ev_local_busy_detected(struct sock *sk, | ||
136 | struct sk_buff *skb); | ||
137 | extern int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb); | ||
138 | extern int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb); | ||
139 | extern int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, | ||
140 | struct sk_buff *skb); | ||
141 | extern int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, | ||
142 | struct sk_buff *skb); | ||
143 | extern int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, | ||
144 | struct sk_buff *skb); | ||
145 | extern int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk, | ||
146 | struct sk_buff *skb); | ||
147 | extern int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, | ||
148 | struct sk_buff *skb); | ||
149 | extern int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk, | ||
150 | struct sk_buff *skb); | ||
151 | extern int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk, | ||
152 | struct sk_buff *skb); | ||
153 | extern int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, | ||
154 | struct sk_buff *skb); | ||
155 | extern int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, | ||
156 | struct sk_buff *skb); | ||
157 | extern int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk, | ||
158 | struct sk_buff *skb); | ||
159 | extern int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, | ||
160 | struct sk_buff *skb); | ||
161 | extern int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, | ||
162 | struct sk_buff *skb); | ||
163 | extern int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk, | ||
164 | struct sk_buff *skb); | ||
165 | extern int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk, | ||
166 | struct sk_buff *skb); | ||
167 | extern int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb); | ||
168 | extern int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb); | ||
169 | extern int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb); | ||
170 | extern int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb); | ||
171 | extern int llc_conn_ev_sendack_tmr_exp(struct sock *sk, struct sk_buff *skb); | ||
172 | /* NOT_USED functions and their variations */ | ||
173 | extern int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, | ||
174 | struct sk_buff *skb); | ||
175 | extern int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk, | ||
176 | struct sk_buff *skb); | ||
177 | extern int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk, | ||
178 | struct sk_buff *skb); | ||
179 | extern int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk, | ||
180 | struct sk_buff *skb); | ||
181 | extern int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, | ||
182 | struct sk_buff *skb); | ||
183 | extern int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, | ||
184 | struct sk_buff *skb); | ||
185 | extern int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk, | ||
186 | struct sk_buff *skb); | ||
187 | extern int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk, | ||
188 | struct sk_buff *skb); | ||
189 | extern int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, | ||
190 | struct sk_buff *skb); | ||
191 | extern int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, | ||
192 | struct sk_buff *skb); | ||
193 | extern int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, | ||
194 | struct sk_buff *skb); | ||
195 | extern int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, | ||
196 | struct sk_buff *skb); | ||
197 | extern int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, | ||
198 | struct sk_buff *skb); | ||
199 | extern int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, | ||
200 | struct sk_buff *skb); | ||
201 | extern int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, | ||
202 | struct sk_buff *skb); | ||
203 | extern int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, | ||
204 | struct sk_buff *skb); | ||
205 | extern int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, | ||
206 | struct sk_buff *skb); | ||
207 | extern int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, | ||
208 | struct sk_buff *skb); | ||
209 | extern int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, | ||
210 | struct sk_buff *skb); | ||
211 | extern int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, | ||
212 | struct sk_buff *skb); | ||
213 | extern int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, | ||
214 | struct sk_buff *skb); | ||
215 | extern int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, | ||
216 | struct sk_buff *skb); | ||
217 | extern int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb); | ||
218 | extern int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb); | ||
219 | extern int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb); | ||
220 | |||
221 | /* Available connection action qualifiers */ | ||
222 | extern int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk, | ||
223 | struct sk_buff *skb); | ||
224 | extern int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk, | ||
225 | struct sk_buff *skb); | ||
226 | extern int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk, | ||
227 | struct sk_buff *skb); | ||
228 | extern int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk, struct sk_buff *skb); | ||
229 | extern int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk, | ||
230 | struct sk_buff *skb); | ||
231 | extern int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk, | ||
232 | struct sk_buff *skb); | ||
233 | extern int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk, struct sk_buff *skb); | ||
234 | extern int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, struct sk_buff *skb); | ||
235 | extern int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk, | ||
236 | struct sk_buff *skb); | ||
237 | extern int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk, | ||
238 | struct sk_buff *skb); | ||
239 | extern int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk, | ||
240 | struct sk_buff *skb); | ||
241 | extern int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk, | ||
242 | struct sk_buff *skb); | ||
243 | extern int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk, struct sk_buff *skb); | ||
244 | extern int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk, struct sk_buff *skb); | ||
245 | extern int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk, | ||
246 | struct sk_buff *skb); | ||
247 | extern int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk, | ||
248 | struct sk_buff *skb); | ||
249 | extern int llc_conn_ev_qlfy_set_status_conn(struct sock *sk, | ||
250 | struct sk_buff *skb); | ||
251 | extern int llc_conn_ev_qlfy_set_status_disc(struct sock *sk, | ||
252 | struct sk_buff *skb); | ||
253 | extern int llc_conn_ev_qlfy_set_status_failed(struct sock *sk, | ||
254 | struct sk_buff *skb); | ||
255 | extern int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk, | ||
256 | struct sk_buff *skb); | ||
257 | extern int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk, | ||
258 | struct sk_buff *skb); | ||
259 | extern int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk, | ||
260 | struct sk_buff *skb); | ||
261 | extern int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk, | ||
262 | struct sk_buff *skb); | ||
263 | |||
264 | static __inline__ int llc_conn_space(struct sock *sk, struct sk_buff *skb) | ||
265 | { | ||
266 | return atomic_read(&sk->sk_rmem_alloc) + skb->truesize < | ||
267 | (unsigned)sk->sk_rcvbuf; | ||
268 | } | ||
269 | #endif /* LLC_C_EV_H */ | ||
diff --git a/include/net/llc_c_st.h b/include/net/llc_c_st.h new file mode 100644 index 000000000000..0e79cfba4b3b --- /dev/null +++ b/include/net/llc_c_st.h | |||
@@ -0,0 +1,48 @@ | |||
1 | #ifndef LLC_C_ST_H | ||
2 | #define LLC_C_ST_H | ||
3 | /* | ||
4 | * Copyright (c) 1997 by Procom Technology,Inc. | ||
5 | * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> | ||
6 | * | ||
7 | * This program can be redistributed or modified under the terms of the | ||
8 | * GNU General Public License as published by the Free Software Foundation. | ||
9 | * This program is distributed without any warranty or implied warranty | ||
10 | * of merchantability or fitness for a particular purpose. | ||
11 | * | ||
12 | * See the GNU General Public License for more details. | ||
13 | */ | ||
14 | /* Connection component state management */ | ||
15 | /* connection states */ | ||
16 | #define LLC_CONN_OUT_OF_SVC 0 /* prior to allocation */ | ||
17 | |||
18 | #define LLC_CONN_STATE_ADM 1 /* disc, initial state */ | ||
19 | #define LLC_CONN_STATE_SETUP 2 /* disconnected state */ | ||
20 | #define LLC_CONN_STATE_NORMAL 3 /* connected state */ | ||
21 | #define LLC_CONN_STATE_BUSY 4 /* connected state */ | ||
22 | #define LLC_CONN_STATE_REJ 5 /* connected state */ | ||
23 | #define LLC_CONN_STATE_AWAIT 6 /* connected state */ | ||
24 | #define LLC_CONN_STATE_AWAIT_BUSY 7 /* connected state */ | ||
25 | #define LLC_CONN_STATE_AWAIT_REJ 8 /* connected state */ | ||
26 | #define LLC_CONN_STATE_D_CONN 9 /* disconnected state */ | ||
27 | #define LLC_CONN_STATE_RESET 10 /* disconnected state */ | ||
28 | #define LLC_CONN_STATE_ERROR 11 /* disconnected state */ | ||
29 | #define LLC_CONN_STATE_TEMP 12 /* disconnected state */ | ||
30 | |||
31 | #define NBR_CONN_STATES 12 /* size of state table */ | ||
32 | #define NO_STATE_CHANGE 100 | ||
33 | |||
34 | /* Connection state table structure */ | ||
35 | struct llc_conn_state_trans { | ||
36 | llc_conn_ev_t ev; | ||
37 | u8 next_state; | ||
38 | llc_conn_ev_qfyr_t *ev_qualifiers; | ||
39 | llc_conn_action_t *ev_actions; | ||
40 | }; | ||
41 | |||
42 | struct llc_conn_state { | ||
43 | u8 current_state; | ||
44 | struct llc_conn_state_trans **transitions; | ||
45 | }; | ||
46 | |||
47 | extern struct llc_conn_state llc_conn_state_table[]; | ||
48 | #endif /* LLC_C_ST_H */ | ||
diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h new file mode 100644 index 000000000000..8ad3bc2c23d7 --- /dev/null +++ b/include/net/llc_conn.h | |||
@@ -0,0 +1,119 @@ | |||
1 | #ifndef LLC_CONN_H | ||
2 | #define LLC_CONN_H | ||
3 | /* | ||
4 | * Copyright (c) 1997 by Procom Technology, Inc. | ||
5 | * 2001, 2002 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> | ||
6 | * | ||
7 | * This program can be redistributed or modified under the terms of the | ||
8 | * GNU General Public License as published by the Free Software Foundation. | ||
9 | * This program is distributed without any warranty or implied warranty | ||
10 | * of merchantability or fitness for a particular purpose. | ||
11 | * | ||
12 | * See the GNU General Public License for more details. | ||
13 | */ | ||
14 | #include <linux/timer.h> | ||
15 | #include <net/llc_if.h> | ||
16 | #include <net/sock.h> | ||
17 | #include <linux/llc.h> | ||
18 | |||
19 | #define LLC_EVENT 1 | ||
20 | #define LLC_PACKET 2 | ||
21 | |||
22 | #define LLC_P_TIME 2 | ||
23 | #define LLC_ACK_TIME 1 | ||
24 | #define LLC_REJ_TIME 3 | ||
25 | #define LLC_BUSY_TIME 3 | ||
26 | |||
27 | struct llc_timer { | ||
28 | struct timer_list timer; | ||
29 | u16 expire; /* timer expire time */ | ||
30 | }; | ||
31 | |||
32 | struct llc_sock { | ||
33 | /* struct sock must be the first member of llc_sock */ | ||
34 | struct sock sk; | ||
35 | struct sockaddr_llc addr; /* address sock is bound to */ | ||
36 | u8 state; /* state of connection */ | ||
37 | struct llc_sap *sap; /* pointer to parent SAP */ | ||
38 | struct llc_addr laddr; /* lsap/mac pair */ | ||
39 | struct llc_addr daddr; /* dsap/mac pair */ | ||
40 | struct net_device *dev; /* device to send to remote */ | ||
41 | u8 retry_count; /* number of retries */ | ||
42 | u8 ack_must_be_send; | ||
43 | u8 first_pdu_Ns; | ||
44 | u8 npta; | ||
45 | struct llc_timer ack_timer; | ||
46 | struct llc_timer pf_cycle_timer; | ||
47 | struct llc_timer rej_sent_timer; | ||
48 | struct llc_timer busy_state_timer; /* ind busy clr at remote LLC */ | ||
49 | u8 vS; /* seq# next in-seq I-PDU tx'd*/ | ||
50 | u8 vR; /* seq# next in-seq I-PDU rx'd*/ | ||
51 | u32 n2; /* max nbr re-tx's for timeout*/ | ||
52 | u32 n1; /* max nbr octets in I PDU */ | ||
53 | u8 k; /* tx window size; max = 127 */ | ||
54 | u8 rw; /* rx window size; max = 127 */ | ||
55 | u8 p_flag; /* state flags */ | ||
56 | u8 f_flag; | ||
57 | u8 s_flag; | ||
58 | u8 data_flag; | ||
59 | u8 remote_busy_flag; | ||
60 | u8 cause_flag; | ||
61 | struct sk_buff_head pdu_unack_q; /* PUDs sent/waiting ack */ | ||
62 | u16 link; /* network layer link number */ | ||
63 | u8 X; /* a temporary variable */ | ||
64 | u8 ack_pf; /* this flag indicates what is | ||
65 | the P-bit of acknowledge */ | ||
66 | u8 failed_data_req; /* recognize that already exist a | ||
67 | failed llc_data_req_handler | ||
68 | (tx_buffer_full or unacceptable | ||
69 | state */ | ||
70 | u8 dec_step; | ||
71 | u8 inc_cntr; | ||
72 | u8 dec_cntr; | ||
73 | u8 connect_step; | ||
74 | u8 last_nr; /* NR of last pdu received */ | ||
75 | u32 rx_pdu_hdr; /* used for saving header of last pdu | ||
76 | received and caused sending FRMR. | ||
77 | Used for resending FRMR */ | ||
78 | }; | ||
79 | |||
80 | static inline struct llc_sock *llc_sk(const struct sock *sk) | ||
81 | { | ||
82 | return (struct llc_sock *)sk; | ||
83 | } | ||
84 | |||
85 | static __inline__ void llc_set_backlog_type(struct sk_buff *skb, char type) | ||
86 | { | ||
87 | skb->cb[sizeof(skb->cb) - 1] = type; | ||
88 | } | ||
89 | |||
90 | static __inline__ char llc_backlog_type(struct sk_buff *skb) | ||
91 | { | ||
92 | return skb->cb[sizeof(skb->cb) - 1]; | ||
93 | } | ||
94 | |||
95 | extern struct sock *llc_sk_alloc(int family, int priority, struct proto *prot); | ||
96 | extern void llc_sk_free(struct sock *sk); | ||
97 | |||
98 | extern void llc_sk_reset(struct sock *sk); | ||
99 | |||
100 | /* Access to a connection */ | ||
101 | extern int llc_conn_state_process(struct sock *sk, struct sk_buff *skb); | ||
102 | extern void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb); | ||
103 | extern void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb); | ||
104 | extern void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, | ||
105 | u8 first_p_bit); | ||
106 | extern void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, | ||
107 | u8 first_f_bit); | ||
108 | extern int llc_conn_remove_acked_pdus(struct sock *conn, u8 nr, | ||
109 | u16 *how_many_unacked); | ||
110 | extern struct sock *llc_lookup_established(struct llc_sap *sap, | ||
111 | struct llc_addr *daddr, | ||
112 | struct llc_addr *laddr); | ||
113 | extern void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk); | ||
114 | extern void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk); | ||
115 | |||
116 | extern u8 llc_data_accept_state(u8 state); | ||
117 | extern void llc_build_offset_table(void); | ||
118 | extern int llc_release_sockets(struct llc_sap *sap); | ||
119 | #endif /* LLC_CONN_H */ | ||
diff --git a/include/net/llc_if.h b/include/net/llc_if.h new file mode 100644 index 000000000000..090eaa0d71f9 --- /dev/null +++ b/include/net/llc_if.h | |||
@@ -0,0 +1,101 @@ | |||
1 | #ifndef LLC_IF_H | ||
2 | #define LLC_IF_H | ||
3 | /* | ||
4 | * Copyright (c) 1997 by Procom Technology,Inc. | ||
5 | * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> | ||
6 | * | ||
7 | * This program can be redistributed or modified under the terms of the | ||
8 | * GNU General Public License as published by the Free Software Foundation. | ||
9 | * This program is distributed without any warranty or implied warranty | ||
10 | * of merchantability or fitness for a particular purpose. | ||
11 | * | ||
12 | * See the GNU General Public License for more details. | ||
13 | */ | ||
14 | /* Defines LLC interface to network layer */ | ||
15 | /* Available primitives */ | ||
16 | #include <linux/if.h> | ||
17 | #include <linux/if_arp.h> | ||
18 | #include <linux/llc.h> | ||
19 | #include <net/llc.h> | ||
20 | |||
21 | #define LLC_DATAUNIT_PRIM 1 | ||
22 | #define LLC_CONN_PRIM 2 | ||
23 | #define LLC_DATA_PRIM 3 | ||
24 | #define LLC_DISC_PRIM 4 | ||
25 | #define LLC_RESET_PRIM 5 | ||
26 | #define LLC_FLOWCONTROL_PRIM 6 /* Not supported at this time */ | ||
27 | #define LLC_DISABLE_PRIM 7 | ||
28 | #define LLC_XID_PRIM 8 | ||
29 | #define LLC_TEST_PRIM 9 | ||
30 | #define LLC_SAP_ACTIVATION 10 | ||
31 | #define LLC_SAP_DEACTIVATION 11 | ||
32 | |||
33 | #define LLC_NBR_PRIMITIVES 11 | ||
34 | |||
35 | #define LLC_IND 1 | ||
36 | #define LLC_CONFIRM 2 | ||
37 | |||
38 | /* Primitive type */ | ||
39 | #define LLC_PRIM_TYPE_REQ 1 | ||
40 | #define LLC_PRIM_TYPE_IND 2 | ||
41 | #define LLC_PRIM_TYPE_RESP 3 | ||
42 | #define LLC_PRIM_TYPE_CONFIRM 4 | ||
43 | |||
44 | /* Reset reasons, remote entity or local LLC */ | ||
45 | #define LLC_RESET_REASON_REMOTE 1 | ||
46 | #define LLC_RESET_REASON_LOCAL 2 | ||
47 | |||
48 | /* Disconnect reasons */ | ||
49 | #define LLC_DISC_REASON_RX_DM_RSP_PDU 0 | ||
50 | #define LLC_DISC_REASON_RX_DISC_CMD_PDU 1 | ||
51 | #define LLC_DISC_REASON_ACK_TMR_EXP 2 | ||
52 | |||
53 | /* Confirm reasons */ | ||
54 | #define LLC_STATUS_CONN 0 /* connect confirm & reset confirm */ | ||
55 | #define LLC_STATUS_DISC 1 /* connect confirm & reset confirm */ | ||
56 | #define LLC_STATUS_FAILED 2 /* connect confirm & reset confirm */ | ||
57 | #define LLC_STATUS_IMPOSSIBLE 3 /* connect confirm */ | ||
58 | #define LLC_STATUS_RECEIVED 4 /* data conn */ | ||
59 | #define LLC_STATUS_REMOTE_BUSY 5 /* data conn */ | ||
60 | #define LLC_STATUS_REFUSE 6 /* data conn */ | ||
61 | #define LLC_STATUS_CONFLICT 7 /* disconnect conn */ | ||
62 | #define LLC_STATUS_RESET_DONE 8 /* */ | ||
63 | |||
64 | extern u8 llc_mac_null_var[IFHWADDRLEN]; | ||
65 | |||
66 | /** | ||
67 | * llc_mac_null - determines if a address is a null mac address | ||
68 | * @mac: Mac address to test if null. | ||
69 | * | ||
70 | * Determines if a given address is a null mac address. Returns 0 if the | ||
71 | * address is not a null mac, 1 if the address is a null mac. | ||
72 | */ | ||
73 | static __inline__ int llc_mac_null(u8 *mac) | ||
74 | { | ||
75 | return !memcmp(mac, llc_mac_null_var, IFHWADDRLEN); | ||
76 | } | ||
77 | |||
78 | static __inline__ int llc_addrany(struct llc_addr *addr) | ||
79 | { | ||
80 | return llc_mac_null(addr->mac) && !addr->lsap; | ||
81 | } | ||
82 | |||
83 | /** | ||
84 | * llc_mac_match - determines if two mac addresses are the same | ||
85 | * @mac1: First mac address to compare. | ||
86 | * @mac2: Second mac address to compare. | ||
87 | * | ||
88 | * Determines if two given mac address are the same. Returns 0 if there | ||
89 | * is not a complete match up to len, 1 if a complete match up to len is | ||
90 | * found. | ||
91 | */ | ||
92 | static __inline__ int llc_mac_match(u8 *mac1, u8 *mac2) | ||
93 | { | ||
94 | return !memcmp(mac1, mac2, IFHWADDRLEN); | ||
95 | } | ||
96 | |||
97 | extern int llc_establish_connection(struct sock *sk, u8 *lmac, | ||
98 | u8 *dmac, u8 dsap); | ||
99 | extern int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb); | ||
100 | extern int llc_send_disc(struct sock *sk); | ||
101 | #endif /* LLC_IF_H */ | ||
diff --git a/include/net/llc_pdu.h b/include/net/llc_pdu.h new file mode 100644 index 000000000000..f45c37d89cf7 --- /dev/null +++ b/include/net/llc_pdu.h | |||
@@ -0,0 +1,436 @@ | |||
1 | #ifndef LLC_PDU_H | ||
2 | #define LLC_PDU_H | ||
3 | /* | ||
4 | * Copyright (c) 1997 by Procom Technology,Inc. | ||
5 | * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> | ||
6 | * | ||
7 | * This program can be redistributed or modified under the terms of the | ||
8 | * GNU General Public License as published by the Free Software Foundation. | ||
9 | * This program is distributed without any warranty or implied warranty | ||
10 | * of merchantability or fitness for a particular purpose. | ||
11 | * | ||
12 | * See the GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/if_ether.h> | ||
16 | #include <linux/if_tr.h> | ||
17 | |||
18 | /* Lengths of frame formats */ | ||
19 | #define LLC_PDU_LEN_I 4 /* header and 2 control bytes */ | ||
20 | #define LLC_PDU_LEN_S 4 | ||
21 | #define LLC_PDU_LEN_U 3 /* header and 1 control byte */ | ||
22 | /* Known SAP addresses */ | ||
23 | #define LLC_GLOBAL_SAP 0xFF | ||
24 | #define LLC_NULL_SAP 0x00 /* not network-layer visible */ | ||
25 | #define LLC_MGMT_INDIV 0x02 /* station LLC mgmt indiv addr */ | ||
26 | #define LLC_MGMT_GRP 0x03 /* station LLC mgmt group addr */ | ||
27 | #define LLC_RDE_SAP 0xA6 /* route ... */ | ||
28 | |||
29 | /* SAP field bit masks */ | ||
30 | #define LLC_ISO_RESERVED_SAP 0x02 | ||
31 | #define LLC_SAP_GROUP_DSAP 0x01 | ||
32 | #define LLC_SAP_RESP_SSAP 0x01 | ||
33 | |||
34 | /* Group/individual DSAP indicator is DSAP field */ | ||
35 | #define LLC_PDU_GROUP_DSAP_MASK 0x01 | ||
36 | #define LLC_PDU_IS_GROUP_DSAP(pdu) \ | ||
37 | ((pdu->dsap & LLC_PDU_GROUP_DSAP_MASK) ? 0 : 1) | ||
38 | #define LLC_PDU_IS_INDIV_DSAP(pdu) \ | ||
39 | (!(pdu->dsap & LLC_PDU_GROUP_DSAP_MASK) ? 0 : 1) | ||
40 | |||
41 | /* Command/response PDU indicator in SSAP field */ | ||
42 | #define LLC_PDU_CMD_RSP_MASK 0x01 | ||
43 | #define LLC_PDU_CMD 0 | ||
44 | #define LLC_PDU_RSP 1 | ||
45 | #define LLC_PDU_IS_CMD(pdu) ((pdu->ssap & LLC_PDU_RSP) ? 0 : 1) | ||
46 | #define LLC_PDU_IS_RSP(pdu) ((pdu->ssap & LLC_PDU_RSP) ? 1 : 0) | ||
47 | |||
48 | /* Get PDU type from 2 lowest-order bits of control field first byte */ | ||
49 | #define LLC_PDU_TYPE_I_MASK 0x01 /* 16-bit control field */ | ||
50 | #define LLC_PDU_TYPE_S_MASK 0x03 | ||
51 | #define LLC_PDU_TYPE_U_MASK 0x03 /* 8-bit control field */ | ||
52 | #define LLC_PDU_TYPE_MASK 0x03 | ||
53 | |||
54 | #define LLC_PDU_TYPE_I 0 /* first bit */ | ||
55 | #define LLC_PDU_TYPE_S 1 /* first two bits */ | ||
56 | #define LLC_PDU_TYPE_U 3 /* first two bits */ | ||
57 | |||
58 | #define LLC_PDU_TYPE_IS_I(pdu) \ | ||
59 | ((!(pdu->ctrl_1 & LLC_PDU_TYPE_I_MASK)) ? 1 : 0) | ||
60 | |||
61 | #define LLC_PDU_TYPE_IS_U(pdu) \ | ||
62 | (((pdu->ctrl_1 & LLC_PDU_TYPE_U_MASK) == LLC_PDU_TYPE_U) ? 1 : 0) | ||
63 | |||
64 | #define LLC_PDU_TYPE_IS_S(pdu) \ | ||
65 | (((pdu->ctrl_1 & LLC_PDU_TYPE_S_MASK) == LLC_PDU_TYPE_S) ? 1 : 0) | ||
66 | |||
67 | /* U-format PDU control field masks */ | ||
68 | #define LLC_U_PF_BIT_MASK 0x10 /* P/F bit mask */ | ||
69 | #define LLC_U_PF_IS_1(pdu) ((pdu->ctrl_1 & LLC_U_PF_BIT_MASK) ? 1 : 0) | ||
70 | #define LLC_U_PF_IS_0(pdu) ((!(pdu->ctrl_1 & LLC_U_PF_BIT_MASK)) ? 1 : 0) | ||
71 | |||
72 | #define LLC_U_PDU_CMD_MASK 0xEC /* cmd/rsp mask */ | ||
73 | #define LLC_U_PDU_CMD(pdu) (pdu->ctrl_1 & LLC_U_PDU_CMD_MASK) | ||
74 | #define LLC_U_PDU_RSP(pdu) (pdu->ctrl_1 & LLC_U_PDU_CMD_MASK) | ||
75 | |||
76 | #define LLC_1_PDU_CMD_UI 0x00 /* Type 1 cmds/rsps */ | ||
77 | #define LLC_1_PDU_CMD_XID 0xAC | ||
78 | #define LLC_1_PDU_CMD_TEST 0xE0 | ||
79 | |||
80 | #define LLC_2_PDU_CMD_SABME 0x6C /* Type 2 cmds/rsps */ | ||
81 | #define LLC_2_PDU_CMD_DISC 0x40 | ||
82 | #define LLC_2_PDU_RSP_UA 0x60 | ||
83 | #define LLC_2_PDU_RSP_DM 0x0C | ||
84 | #define LLC_2_PDU_RSP_FRMR 0x84 | ||
85 | |||
86 | /* Type 1 operations */ | ||
87 | |||
88 | /* XID information field bit masks */ | ||
89 | |||
90 | /* LLC format identifier (byte 1) */ | ||
91 | #define LLC_XID_FMT_ID 0x81 /* first byte must be this */ | ||
92 | |||
93 | /* LLC types/classes identifier (byte 2) */ | ||
94 | #define LLC_XID_CLASS_ZEROS_MASK 0xE0 /* these must be zeros */ | ||
95 | #define LLC_XID_CLASS_MASK 0x1F /* AND with byte to get below */ | ||
96 | |||
97 | #define LLC_XID_NULL_CLASS_1 0x01 /* if NULL LSAP...use these */ | ||
98 | #define LLC_XID_NULL_CLASS_2 0x03 | ||
99 | #define LLC_XID_NULL_CLASS_3 0x05 | ||
100 | #define LLC_XID_NULL_CLASS_4 0x07 | ||
101 | |||
102 | #define LLC_XID_NNULL_TYPE_1 0x01 /* if non-NULL LSAP...use these */ | ||
103 | #define LLC_XID_NNULL_TYPE_2 0x02 | ||
104 | #define LLC_XID_NNULL_TYPE_3 0x04 | ||
105 | #define LLC_XID_NNULL_TYPE_1_2 0x03 | ||
106 | #define LLC_XID_NNULL_TYPE_1_3 0x05 | ||
107 | #define LLC_XID_NNULL_TYPE_2_3 0x06 | ||
108 | #define LLC_XID_NNULL_ALL 0x07 | ||
109 | |||
110 | /* Sender Receive Window (byte 3) */ | ||
111 | #define LLC_XID_RW_MASK 0xFE /* AND with value to get below */ | ||
112 | |||
113 | #define LLC_XID_MIN_RW 0x02 /* lowest-order bit always zero */ | ||
114 | |||
115 | /* Type 2 operations */ | ||
116 | |||
117 | #define LLC_2_SEQ_NBR_MODULO ((u8) 128) | ||
118 | |||
119 | /* I-PDU masks ('ctrl' is I-PDU control word) */ | ||
120 | #define LLC_I_GET_NS(pdu) (u8)((pdu->ctrl_1 & 0xFE) >> 1) | ||
121 | #define LLC_I_GET_NR(pdu) (u8)((pdu->ctrl_2 & 0xFE) >> 1) | ||
122 | |||
123 | #define LLC_I_PF_BIT_MASK 0x01 | ||
124 | |||
125 | #define LLC_I_PF_IS_0(pdu) ((!(pdu->ctrl_2 & LLC_I_PF_BIT_MASK)) ? 1 : 0) | ||
126 | #define LLC_I_PF_IS_1(pdu) ((pdu->ctrl_2 & LLC_I_PF_BIT_MASK) ? 1 : 0) | ||
127 | |||
128 | /* S-PDU supervisory commands and responses */ | ||
129 | |||
130 | #define LLC_S_PDU_CMD_MASK 0x0C | ||
131 | #define LLC_S_PDU_CMD(pdu) (pdu->ctrl_1 & LLC_S_PDU_CMD_MASK) | ||
132 | #define LLC_S_PDU_RSP(pdu) (pdu->ctrl_1 & LLC_S_PDU_CMD_MASK) | ||
133 | |||
134 | #define LLC_2_PDU_CMD_RR 0x00 /* rx ready cmd */ | ||
135 | #define LLC_2_PDU_RSP_RR 0x00 /* rx ready rsp */ | ||
136 | #define LLC_2_PDU_CMD_REJ 0x08 /* reject PDU cmd */ | ||
137 | #define LLC_2_PDU_RSP_REJ 0x08 /* reject PDU rsp */ | ||
138 | #define LLC_2_PDU_CMD_RNR 0x04 /* rx not ready cmd */ | ||
139 | #define LLC_2_PDU_RSP_RNR 0x04 /* rx not ready rsp */ | ||
140 | |||
141 | #define LLC_S_PF_BIT_MASK 0x01 | ||
142 | #define LLC_S_PF_IS_0(pdu) ((!(pdu->ctrl_2 & LLC_S_PF_BIT_MASK)) ? 1 : 0) | ||
143 | #define LLC_S_PF_IS_1(pdu) ((pdu->ctrl_2 & LLC_S_PF_BIT_MASK) ? 1 : 0) | ||
144 | |||
145 | #define PDU_SUPV_GET_Nr(pdu) ((pdu->ctrl_2 & 0xFE) >> 1) | ||
146 | #define PDU_GET_NEXT_Vr(sn) (++sn & ~LLC_2_SEQ_NBR_MODULO) | ||
147 | |||
148 | /* FRMR information field macros */ | ||
149 | |||
150 | #define FRMR_INFO_LENGTH 5 /* 5 bytes of information */ | ||
151 | |||
152 | /* | ||
153 | * info is pointer to FRMR info field structure; 'rej_ctrl' is byte pointer | ||
154 | * (if U-PDU) or word pointer to rejected PDU control field | ||
155 | */ | ||
156 | #define FRMR_INFO_SET_REJ_CNTRL(info,rej_ctrl) \ | ||
157 | info->rej_pdu_ctrl = ((*((u8 *) rej_ctrl) & \ | ||
158 | LLC_PDU_TYPE_U) != LLC_PDU_TYPE_U ? \ | ||
159 | (u16)*((u16 *) rej_ctrl) : \ | ||
160 | (((u16) *((u8 *) rej_ctrl)) & 0x00FF)) | ||
161 | |||
162 | /* | ||
163 | * Info is pointer to FRMR info field structure; 'vs' is a byte containing | ||
164 | * send state variable value in low-order 7 bits (insure the lowest-order | ||
165 | * bit remains zero (0)) | ||
166 | */ | ||
167 | #define FRMR_INFO_SET_Vs(info,vs) (info->curr_ssv = (((u8) vs) << 1)) | ||
168 | #define FRMR_INFO_SET_Vr(info,vr) (info->curr_rsv = (((u8) vr) << 1)) | ||
169 | |||
170 | /* | ||
171 | * Info is pointer to FRMR info field structure; 'cr' is a byte containing | ||
172 | * the C/R bit value in the low-order bit | ||
173 | */ | ||
174 | #define FRMR_INFO_SET_C_R_BIT(info, cr) (info->curr_rsv |= (((u8) cr) & 0x01)) | ||
175 | |||
176 | /* | ||
177 | * In the remaining five macros, 'info' is pointer to FRMR info field | ||
178 | * structure; 'ind' is a byte containing the bit value to set in the | ||
179 | * lowest-order bit) | ||
180 | */ | ||
181 | #define FRMR_INFO_SET_INVALID_PDU_CTRL_IND(info, ind) \ | ||
182 | (info->ind_bits = ((info->ind_bits & 0xFE) | (((u8) ind) & 0x01))) | ||
183 | |||
184 | #define FRMR_INFO_SET_INVALID_PDU_INFO_IND(info, ind) \ | ||
185 | (info->ind_bits = ( (info->ind_bits & 0xFD) | (((u8) ind) & 0x02))) | ||
186 | |||
187 | #define FRMR_INFO_SET_PDU_INFO_2LONG_IND(info, ind) \ | ||
188 | (info->ind_bits = ( (info->ind_bits & 0xFB) | (((u8) ind) & 0x04))) | ||
189 | |||
190 | #define FRMR_INFO_SET_PDU_INVALID_Nr_IND(info, ind) \ | ||
191 | (info->ind_bits = ( (info->ind_bits & 0xF7) | (((u8) ind) & 0x08))) | ||
192 | |||
193 | #define FRMR_INFO_SET_PDU_INVALID_Ns_IND(info, ind) \ | ||
194 | (info->ind_bits = ( (info->ind_bits & 0xEF) | (((u8) ind) & 0x10))) | ||
195 | |||
196 | /* Sequence-numbered PDU format (4 bytes in length) */ | ||
197 | struct llc_pdu_sn { | ||
198 | u8 dsap; | ||
199 | u8 ssap; | ||
200 | u8 ctrl_1; | ||
201 | u8 ctrl_2; | ||
202 | }; | ||
203 | |||
204 | static inline struct llc_pdu_sn *llc_pdu_sn_hdr(struct sk_buff *skb) | ||
205 | { | ||
206 | return (struct llc_pdu_sn *)skb->nh.raw; | ||
207 | } | ||
208 | |||
209 | /* Un-numbered PDU format (3 bytes in length) */ | ||
210 | struct llc_pdu_un { | ||
211 | u8 dsap; | ||
212 | u8 ssap; | ||
213 | u8 ctrl_1; | ||
214 | }; | ||
215 | |||
216 | static inline struct llc_pdu_un *llc_pdu_un_hdr(struct sk_buff *skb) | ||
217 | { | ||
218 | return (struct llc_pdu_un *)skb->nh.raw; | ||
219 | } | ||
220 | |||
221 | static inline void *llc_set_pdu_hdr(struct sk_buff *skb, void *ptr) | ||
222 | { | ||
223 | return skb->nh.raw = ptr; | ||
224 | } | ||
225 | |||
226 | /** | ||
227 | * llc_pdu_header_init - initializes pdu header | ||
228 | * @skb: input skb that header must be set into it. | ||
229 | * @type: type of PDU (U, I or S). | ||
230 | * @ssap: source sap. | ||
231 | * @dsap: destination sap. | ||
232 | * @cr: command/response bit (0 or 1). | ||
233 | * | ||
234 | * This function sets DSAP, SSAP and command/Response bit in LLC header. | ||
235 | */ | ||
236 | static inline void llc_pdu_header_init(struct sk_buff *skb, u8 type, | ||
237 | u8 ssap, u8 dsap, u8 cr) | ||
238 | { | ||
239 | const int hlen = type == LLC_PDU_TYPE_U ? 3 : 4; | ||
240 | struct llc_pdu_un *pdu = llc_set_pdu_hdr(skb, skb_push(skb, hlen)); | ||
241 | pdu->dsap = dsap; | ||
242 | pdu->ssap = ssap; | ||
243 | pdu->ssap |= cr; | ||
244 | } | ||
245 | |||
246 | /** | ||
247 | * llc_pdu_decode_sa - extracs source address (MAC) of input frame | ||
248 | * @skb: input skb that source address must be extracted from it. | ||
249 | * @sa: pointer to source address (6 byte array). | ||
250 | * | ||
251 | * This function extracts source address(MAC) of input frame. | ||
252 | */ | ||
253 | static inline void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa) | ||
254 | { | ||
255 | if (skb->protocol == ntohs(ETH_P_802_2)) | ||
256 | memcpy(sa, eth_hdr(skb)->h_source, ETH_ALEN); | ||
257 | else if (skb->protocol == ntohs(ETH_P_TR_802_2)) | ||
258 | memcpy(sa, tr_hdr(skb)->saddr, ETH_ALEN); | ||
259 | } | ||
260 | |||
261 | /** | ||
262 | * llc_pdu_decode_da - extracts dest address of input frame | ||
263 | * @skb: input skb that destination address must be extracted from it | ||
264 | * @sa: pointer to destination address (6 byte array). | ||
265 | * | ||
266 | * This function extracts destination address(MAC) of input frame. | ||
267 | */ | ||
268 | static inline void llc_pdu_decode_da(struct sk_buff *skb, u8 *da) | ||
269 | { | ||
270 | if (skb->protocol == ntohs(ETH_P_802_2)) | ||
271 | memcpy(da, eth_hdr(skb)->h_dest, ETH_ALEN); | ||
272 | else if (skb->protocol == ntohs(ETH_P_TR_802_2)) | ||
273 | memcpy(da, tr_hdr(skb)->daddr, ETH_ALEN); | ||
274 | } | ||
275 | |||
276 | /** | ||
277 | * llc_pdu_decode_ssap - extracts source SAP of input frame | ||
278 | * @skb: input skb that source SAP must be extracted from it. | ||
279 | * @ssap: source SAP (output argument). | ||
280 | * | ||
281 | * This function extracts source SAP of input frame. Right bit of SSAP is | ||
282 | * command/response bit. | ||
283 | */ | ||
284 | static inline void llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap) | ||
285 | { | ||
286 | *ssap = llc_pdu_un_hdr(skb)->ssap & 0xFE; | ||
287 | } | ||
288 | |||
289 | /** | ||
290 | * llc_pdu_decode_dsap - extracts dest SAP of input frame | ||
291 | * @skb: input skb that destination SAP must be extracted from it. | ||
292 | * @dsap: destination SAP (output argument). | ||
293 | * | ||
294 | * This function extracts destination SAP of input frame. right bit of | ||
295 | * DSAP designates individual/group SAP. | ||
296 | */ | ||
297 | static inline void llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap) | ||
298 | { | ||
299 | *dsap = llc_pdu_un_hdr(skb)->dsap & 0xFE; | ||
300 | } | ||
301 | |||
302 | /** | ||
303 | * llc_pdu_init_as_ui_cmd - sets LLC header as UI PDU | ||
304 | * @skb: input skb that header must be set into it. | ||
305 | * | ||
306 | * This function sets third byte of LLC header as a UI PDU. | ||
307 | */ | ||
308 | static inline void llc_pdu_init_as_ui_cmd(struct sk_buff *skb) | ||
309 | { | ||
310 | struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | ||
311 | |||
312 | pdu->ctrl_1 = LLC_PDU_TYPE_U; | ||
313 | pdu->ctrl_1 |= LLC_1_PDU_CMD_UI; | ||
314 | } | ||
315 | |||
316 | /** | ||
317 | * llc_pdu_init_as_test_cmd - sets PDU as TEST | ||
318 | * @skb - Address of the skb to build | ||
319 | * | ||
320 | * Sets a PDU as TEST | ||
321 | */ | ||
322 | static inline void llc_pdu_init_as_test_cmd(struct sk_buff *skb) | ||
323 | { | ||
324 | struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | ||
325 | |||
326 | pdu->ctrl_1 = LLC_PDU_TYPE_U; | ||
327 | pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST; | ||
328 | pdu->ctrl_1 |= LLC_U_PF_BIT_MASK; | ||
329 | } | ||
330 | |||
331 | /** | ||
332 | * llc_pdu_init_as_test_rsp - build TEST response PDU | ||
333 | * @skb: Address of the skb to build | ||
334 | * @ev_skb: The received TEST command PDU frame | ||
335 | * | ||
336 | * Builds a pdu frame as a TEST response. | ||
337 | */ | ||
338 | static inline void llc_pdu_init_as_test_rsp(struct sk_buff *skb, | ||
339 | struct sk_buff *ev_skb) | ||
340 | { | ||
341 | struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | ||
342 | |||
343 | pdu->ctrl_1 = LLC_PDU_TYPE_U; | ||
344 | pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST; | ||
345 | pdu->ctrl_1 |= LLC_U_PF_BIT_MASK; | ||
346 | if (ev_skb->protocol == ntohs(ETH_P_802_2)) { | ||
347 | struct llc_pdu_un *ev_pdu = llc_pdu_un_hdr(ev_skb); | ||
348 | int dsize; | ||
349 | |||
350 | dsize = ntohs(eth_hdr(ev_skb)->h_proto) - 3; | ||
351 | memcpy(((u8 *)pdu) + 3, ((u8 *)ev_pdu) + 3, dsize); | ||
352 | skb_put(skb, dsize); | ||
353 | } | ||
354 | } | ||
355 | |||
356 | /* LLC Type 1 XID command/response information fields format */ | ||
357 | struct llc_xid_info { | ||
358 | u8 fmt_id; /* always 0x18 for LLC */ | ||
359 | u8 type; /* different if NULL/non-NULL LSAP */ | ||
360 | u8 rw; /* sender receive window */ | ||
361 | }; | ||
362 | |||
363 | /** | ||
364 | * llc_pdu_init_as_xid_cmd - sets bytes 3, 4 & 5 of LLC header as XID | ||
365 | * @skb: input skb that header must be set into it. | ||
366 | * | ||
367 | * This function sets third,fourth,fifth and sixth bytes of LLC header as | ||
368 | * a XID PDU. | ||
369 | */ | ||
370 | static inline void llc_pdu_init_as_xid_cmd(struct sk_buff *skb, | ||
371 | u8 svcs_supported, u8 rx_window) | ||
372 | { | ||
373 | struct llc_xid_info *xid_info; | ||
374 | struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | ||
375 | |||
376 | pdu->ctrl_1 = LLC_PDU_TYPE_U; | ||
377 | pdu->ctrl_1 |= LLC_1_PDU_CMD_XID; | ||
378 | pdu->ctrl_1 |= LLC_U_PF_BIT_MASK; | ||
379 | xid_info = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1); | ||
380 | xid_info->fmt_id = LLC_XID_FMT_ID; /* 0x81 */ | ||
381 | xid_info->type = svcs_supported; | ||
382 | xid_info->rw = rx_window << 1; /* size of receive window */ | ||
383 | skb_put(skb, 3); | ||
384 | } | ||
385 | |||
386 | /** | ||
387 | * llc_pdu_init_as_xid_rsp - builds XID response PDU | ||
388 | * @skb: Address of the skb to build | ||
389 | * @svcs_supported: The class of the LLC (I or II) | ||
390 | * @rx_window: The size of the receive window of the LLC | ||
391 | * | ||
392 | * Builds a pdu frame as an XID response. | ||
393 | */ | ||
394 | static inline void llc_pdu_init_as_xid_rsp(struct sk_buff *skb, | ||
395 | u8 svcs_supported, u8 rx_window) | ||
396 | { | ||
397 | struct llc_xid_info *xid_info; | ||
398 | struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | ||
399 | |||
400 | pdu->ctrl_1 = LLC_PDU_TYPE_U; | ||
401 | pdu->ctrl_1 |= LLC_1_PDU_CMD_XID; | ||
402 | pdu->ctrl_1 |= LLC_U_PF_BIT_MASK; | ||
403 | |||
404 | xid_info = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1); | ||
405 | xid_info->fmt_id = LLC_XID_FMT_ID; | ||
406 | xid_info->type = svcs_supported; | ||
407 | xid_info->rw = rx_window << 1; | ||
408 | skb_put(skb, 3); | ||
409 | } | ||
410 | |||
411 | /* LLC Type 2 FRMR response information field format */ | ||
412 | struct llc_frmr_info { | ||
413 | u16 rej_pdu_ctrl; /* bits 1-8 if U-PDU */ | ||
414 | u8 curr_ssv; /* current send state variable val */ | ||
415 | u8 curr_rsv; /* current receive state variable */ | ||
416 | u8 ind_bits; /* indicator bits set with macro */ | ||
417 | }; | ||
418 | |||
419 | extern void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 type); | ||
420 | extern void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value); | ||
421 | extern void llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit); | ||
422 | extern void llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit); | ||
423 | extern void llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr); | ||
424 | extern void llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr); | ||
425 | extern void llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr); | ||
426 | extern void llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr); | ||
427 | extern void llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit); | ||
428 | extern void llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit); | ||
429 | extern void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, | ||
430 | struct llc_pdu_sn *prev_pdu, | ||
431 | u8 f_bit, u8 vs, u8 vr, u8 vzyxw); | ||
432 | extern void llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr); | ||
433 | extern void llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr); | ||
434 | extern void llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr); | ||
435 | extern void llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit); | ||
436 | #endif /* LLC_PDU_H */ | ||
diff --git a/include/net/llc_s_ac.h b/include/net/llc_s_ac.h new file mode 100644 index 000000000000..37a3bbd02394 --- /dev/null +++ b/include/net/llc_s_ac.h | |||
@@ -0,0 +1,39 @@ | |||
1 | #ifndef LLC_S_AC_H | ||
2 | #define LLC_S_AC_H | ||
3 | /* | ||
4 | * Copyright (c) 1997 by Procom Technology,Inc. | ||
5 | * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> | ||
6 | * | ||
7 | * This program can be redistributed or modified under the terms of the | ||
8 | * GNU General Public License as published by the Free Software Foundation. | ||
9 | * This program is distributed without any warranty or implied warranty | ||
10 | * of merchantability or fitness for a particular purpose. | ||
11 | * | ||
12 | * See the GNU General Public License for more details. | ||
13 | */ | ||
14 | /* SAP component actions */ | ||
15 | #define SAP_ACT_UNITDATA_IND 1 | ||
16 | #define SAP_ACT_SEND_UI 2 | ||
17 | #define SAP_ACT_SEND_XID_C 3 | ||
18 | #define SAP_ACT_SEND_XID_R 4 | ||
19 | #define SAP_ACT_SEND_TEST_C 5 | ||
20 | #define SAP_ACT_SEND_TEST_R 6 | ||
21 | #define SAP_ACT_REPORT_STATUS 7 | ||
22 | #define SAP_ACT_XID_IND 8 | ||
23 | #define SAP_ACT_TEST_IND 9 | ||
24 | |||
25 | /* All action functions must look like this */ | ||
26 | typedef int (*llc_sap_action_t)(struct llc_sap *sap, struct sk_buff *skb); | ||
27 | |||
28 | extern int llc_sap_action_unitdata_ind(struct llc_sap *sap, | ||
29 | struct sk_buff *skb); | ||
30 | extern int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb); | ||
31 | extern int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb); | ||
32 | extern int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb); | ||
33 | extern int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb); | ||
34 | extern int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb); | ||
35 | extern int llc_sap_action_report_status(struct llc_sap *sap, | ||
36 | struct sk_buff *skb); | ||
37 | extern int llc_sap_action_xid_ind(struct llc_sap *sap, struct sk_buff *skb); | ||
38 | extern int llc_sap_action_test_ind(struct llc_sap *sap, struct sk_buff *skb); | ||
39 | #endif /* LLC_S_AC_H */ | ||
diff --git a/include/net/llc_s_ev.h b/include/net/llc_s_ev.h new file mode 100644 index 000000000000..e3acb9329e4a --- /dev/null +++ b/include/net/llc_s_ev.h | |||
@@ -0,0 +1,67 @@ | |||
1 | #ifndef LLC_S_EV_H | ||
2 | #define LLC_S_EV_H | ||
3 | /* | ||
4 | * Copyright (c) 1997 by Procom Technology,Inc. | ||
5 | * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> | ||
6 | * | ||
7 | * This program can be redistributed or modified under the terms of the | ||
8 | * GNU General Public License as published by the Free Software Foundation. | ||
9 | * This program is distributed without any warranty or implied warranty | ||
10 | * of merchantability or fitness for a particular purpose. | ||
11 | * | ||
12 | * See the GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/skbuff.h> | ||
16 | |||
17 | /* Defines SAP component events */ | ||
18 | /* Types of events (possible values in 'ev->type') */ | ||
19 | #define LLC_SAP_EV_TYPE_SIMPLE 1 | ||
20 | #define LLC_SAP_EV_TYPE_CONDITION 2 | ||
21 | #define LLC_SAP_EV_TYPE_PRIM 3 | ||
22 | #define LLC_SAP_EV_TYPE_PDU 4 /* command/response PDU */ | ||
23 | #define LLC_SAP_EV_TYPE_ACK_TMR 5 | ||
24 | #define LLC_SAP_EV_TYPE_RPT_STATUS 6 | ||
25 | |||
26 | #define LLC_SAP_EV_ACTIVATION_REQ 1 | ||
27 | #define LLC_SAP_EV_RX_UI 2 | ||
28 | #define LLC_SAP_EV_UNITDATA_REQ 3 | ||
29 | #define LLC_SAP_EV_XID_REQ 4 | ||
30 | #define LLC_SAP_EV_RX_XID_C 5 | ||
31 | #define LLC_SAP_EV_RX_XID_R 6 | ||
32 | #define LLC_SAP_EV_TEST_REQ 7 | ||
33 | #define LLC_SAP_EV_RX_TEST_C 8 | ||
34 | #define LLC_SAP_EV_RX_TEST_R 9 | ||
35 | #define LLC_SAP_EV_DEACTIVATION_REQ 10 | ||
36 | |||
37 | struct llc_sap_state_ev { | ||
38 | u8 prim; | ||
39 | u8 prim_type; | ||
40 | u8 type; | ||
41 | u8 reason; | ||
42 | u8 ind_cfm_flag; | ||
43 | struct llc_addr saddr; | ||
44 | struct llc_addr daddr; | ||
45 | }; | ||
46 | |||
47 | static __inline__ struct llc_sap_state_ev *llc_sap_ev(struct sk_buff *skb) | ||
48 | { | ||
49 | return (struct llc_sap_state_ev *)skb->cb; | ||
50 | } | ||
51 | |||
52 | struct llc_sap; | ||
53 | |||
54 | typedef int (*llc_sap_ev_t)(struct llc_sap *sap, struct sk_buff *skb); | ||
55 | |||
56 | extern int llc_sap_ev_activation_req(struct llc_sap *sap, struct sk_buff *skb); | ||
57 | extern int llc_sap_ev_rx_ui(struct llc_sap *sap, struct sk_buff *skb); | ||
58 | extern int llc_sap_ev_unitdata_req(struct llc_sap *sap, struct sk_buff *skb); | ||
59 | extern int llc_sap_ev_xid_req(struct llc_sap *sap, struct sk_buff *skb); | ||
60 | extern int llc_sap_ev_rx_xid_c(struct llc_sap *sap, struct sk_buff *skb); | ||
61 | extern int llc_sap_ev_rx_xid_r(struct llc_sap *sap, struct sk_buff *skb); | ||
62 | extern int llc_sap_ev_test_req(struct llc_sap *sap, struct sk_buff *skb); | ||
63 | extern int llc_sap_ev_rx_test_c(struct llc_sap *sap, struct sk_buff *skb); | ||
64 | extern int llc_sap_ev_rx_test_r(struct llc_sap *sap, struct sk_buff *skb); | ||
65 | extern int llc_sap_ev_deactivation_req(struct llc_sap *sap, | ||
66 | struct sk_buff *skb); | ||
67 | #endif /* LLC_S_EV_H */ | ||
diff --git a/include/net/llc_s_st.h b/include/net/llc_s_st.h new file mode 100644 index 000000000000..567c681f1f3e --- /dev/null +++ b/include/net/llc_s_st.h | |||
@@ -0,0 +1,32 @@ | |||
1 | #ifndef LLC_S_ST_H | ||
2 | #define LLC_S_ST_H | ||
3 | /* | ||
4 | * Copyright (c) 1997 by Procom Technology,Inc. | ||
5 | * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> | ||
6 | * | ||
7 | * This program can be redistributed or modified under the terms of the | ||
8 | * GNU General Public License as published by the Free Software Foundation. | ||
9 | * This program is distributed without any warranty or implied warranty | ||
10 | * of merchantability or fitness for a particular purpose. | ||
11 | * | ||
12 | * See the GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #define LLC_NR_SAP_STATES 2 /* size of state table */ | ||
16 | |||
17 | /* structures and types */ | ||
18 | /* SAP state table structure */ | ||
19 | struct llc_sap_state_trans { | ||
20 | llc_sap_ev_t ev; | ||
21 | u8 next_state; | ||
22 | llc_sap_action_t *ev_actions; | ||
23 | }; | ||
24 | |||
25 | struct llc_sap_state { | ||
26 | u8 curr_state; | ||
27 | struct llc_sap_state_trans **transitions; | ||
28 | }; | ||
29 | |||
30 | /* only access to SAP state table */ | ||
31 | extern struct llc_sap_state llc_sap_state_table[LLC_NR_SAP_STATES]; | ||
32 | #endif /* LLC_S_ST_H */ | ||
diff --git a/include/net/llc_sap.h b/include/net/llc_sap.h new file mode 100644 index 000000000000..353baaa627f3 --- /dev/null +++ b/include/net/llc_sap.h | |||
@@ -0,0 +1,29 @@ | |||
1 | #ifndef LLC_SAP_H | ||
2 | #define LLC_SAP_H | ||
3 | /* | ||
4 | * Copyright (c) 1997 by Procom Technology,Inc. | ||
5 | * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> | ||
6 | * | ||
7 | * This program can be redistributed or modified under the terms of the | ||
8 | * GNU General Public License as published by the Free Software Foundation. | ||
9 | * This program is distributed without any warranty or implied warranty | ||
10 | * of merchantability or fitness for a particular purpose. | ||
11 | * | ||
12 | * See the GNU General Public License for more details. | ||
13 | */ | ||
14 | struct llc_sap; | ||
15 | struct sk_buff; | ||
16 | |||
17 | extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb); | ||
18 | extern void llc_save_primitive(struct sk_buff* skb, unsigned char prim); | ||
19 | extern struct sk_buff *llc_alloc_frame(void); | ||
20 | |||
21 | extern void llc_build_and_send_test_pkt(struct llc_sap *sap, | ||
22 | struct sk_buff *skb, | ||
23 | unsigned char *dmac, | ||
24 | unsigned char dsap); | ||
25 | extern void llc_build_and_send_xid_pkt(struct llc_sap *sap, | ||
26 | struct sk_buff *skb, | ||
27 | unsigned char *dmac, | ||
28 | unsigned char dsap); | ||
29 | #endif /* LLC_SAP_H */ | ||
diff --git a/include/net/ndisc.h b/include/net/ndisc.h new file mode 100644 index 000000000000..f85d6e4b7442 --- /dev/null +++ b/include/net/ndisc.h | |||
@@ -0,0 +1,135 @@ | |||
1 | #ifndef _NDISC_H | ||
2 | #define _NDISC_H | ||
3 | |||
4 | /* | ||
5 | * ICMP codes for neighbour discovery messages | ||
6 | */ | ||
7 | |||
8 | #define NDISC_ROUTER_SOLICITATION 133 | ||
9 | #define NDISC_ROUTER_ADVERTISEMENT 134 | ||
10 | #define NDISC_NEIGHBOUR_SOLICITATION 135 | ||
11 | #define NDISC_NEIGHBOUR_ADVERTISEMENT 136 | ||
12 | #define NDISC_REDIRECT 137 | ||
13 | |||
14 | /* | ||
15 | * ndisc options | ||
16 | */ | ||
17 | |||
18 | enum { | ||
19 | __ND_OPT_PREFIX_INFO_END = 0, | ||
20 | ND_OPT_SOURCE_LL_ADDR = 1, /* RFC2461 */ | ||
21 | ND_OPT_TARGET_LL_ADDR = 2, /* RFC2461 */ | ||
22 | ND_OPT_PREFIX_INFO = 3, /* RFC2461 */ | ||
23 | ND_OPT_REDIRECT_HDR = 4, /* RFC2461 */ | ||
24 | ND_OPT_MTU = 5, /* RFC2461 */ | ||
25 | __ND_OPT_MAX | ||
26 | }; | ||
27 | |||
28 | #define MAX_RTR_SOLICITATION_DELAY HZ | ||
29 | |||
30 | #define ND_REACHABLE_TIME (30*HZ) | ||
31 | #define ND_RETRANS_TIMER HZ | ||
32 | |||
33 | #define ND_MIN_RANDOM_FACTOR (1/2) | ||
34 | #define ND_MAX_RANDOM_FACTOR (3/2) | ||
35 | |||
36 | #ifdef __KERNEL__ | ||
37 | |||
38 | #include <linux/skbuff.h> | ||
39 | #include <linux/netdevice.h> | ||
40 | #include <linux/icmpv6.h> | ||
41 | #include <net/neighbour.h> | ||
42 | #include <asm/atomic.h> | ||
43 | |||
44 | extern struct neigh_table nd_tbl; | ||
45 | |||
46 | struct nd_msg { | ||
47 | struct icmp6hdr icmph; | ||
48 | struct in6_addr target; | ||
49 | __u8 opt[0]; | ||
50 | }; | ||
51 | |||
52 | struct rs_msg { | ||
53 | struct icmp6hdr icmph; | ||
54 | __u8 opt[0]; | ||
55 | }; | ||
56 | |||
57 | struct ra_msg { | ||
58 | struct icmp6hdr icmph; | ||
59 | __u32 reachable_time; | ||
60 | __u32 retrans_timer; | ||
61 | }; | ||
62 | |||
63 | struct nd_opt_hdr { | ||
64 | __u8 nd_opt_type; | ||
65 | __u8 nd_opt_len; | ||
66 | } __attribute__((__packed__)); | ||
67 | |||
68 | |||
69 | extern int ndisc_init(struct net_proto_family *ops); | ||
70 | |||
71 | extern void ndisc_cleanup(void); | ||
72 | |||
73 | extern int ndisc_rcv(struct sk_buff *skb); | ||
74 | |||
75 | extern void ndisc_send_ns(struct net_device *dev, | ||
76 | struct neighbour *neigh, | ||
77 | struct in6_addr *solicit, | ||
78 | struct in6_addr *daddr, | ||
79 | struct in6_addr *saddr); | ||
80 | |||
81 | extern void ndisc_send_rs(struct net_device *dev, | ||
82 | struct in6_addr *saddr, | ||
83 | struct in6_addr *daddr); | ||
84 | |||
85 | extern void ndisc_forwarding_on(void); | ||
86 | extern void ndisc_forwarding_off(void); | ||
87 | |||
88 | extern void ndisc_send_redirect(struct sk_buff *skb, | ||
89 | struct neighbour *neigh, | ||
90 | struct in6_addr *target); | ||
91 | |||
92 | extern int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir); | ||
93 | |||
94 | |||
95 | struct rt6_info * dflt_rt_lookup(void); | ||
96 | |||
97 | /* | ||
98 | * IGMP | ||
99 | */ | ||
100 | extern int igmp6_init(struct net_proto_family *ops); | ||
101 | |||
102 | extern void igmp6_cleanup(void); | ||
103 | |||
104 | extern int igmp6_event_query(struct sk_buff *skb); | ||
105 | |||
106 | extern int igmp6_event_report(struct sk_buff *skb); | ||
107 | |||
108 | extern void igmp6_cleanup(void); | ||
109 | |||
110 | #ifdef CONFIG_SYSCTL | ||
111 | extern int ndisc_ifinfo_sysctl_change(ctl_table *ctl, | ||
112 | int write, | ||
113 | struct file * filp, | ||
114 | void __user *buffer, | ||
115 | size_t *lenp, | ||
116 | loff_t *ppos); | ||
117 | #endif | ||
118 | |||
119 | extern void inet6_ifinfo_notify(int event, | ||
120 | struct inet6_dev *idev); | ||
121 | |||
122 | static inline struct neighbour * ndisc_get_neigh(struct net_device *dev, struct in6_addr *addr) | ||
123 | { | ||
124 | |||
125 | if (dev) | ||
126 | return __neigh_lookup(&nd_tbl, addr, dev, 1); | ||
127 | |||
128 | return NULL; | ||
129 | } | ||
130 | |||
131 | |||
132 | #endif /* __KERNEL__ */ | ||
133 | |||
134 | |||
135 | #endif | ||
diff --git a/include/net/neighbour.h b/include/net/neighbour.h new file mode 100644 index 000000000000..4f33bbc21e7f --- /dev/null +++ b/include/net/neighbour.h | |||
@@ -0,0 +1,370 @@ | |||
1 | #ifndef _NET_NEIGHBOUR_H | ||
2 | #define _NET_NEIGHBOUR_H | ||
3 | |||
4 | /* | ||
5 | * Generic neighbour manipulation | ||
6 | * | ||
7 | * Authors: | ||
8 | * Pedro Roque <roque@di.fc.ul.pt> | ||
9 | * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> | ||
10 | * | ||
11 | * Changes: | ||
12 | * | ||
13 | * Harald Welte: <laforge@gnumonks.org> | ||
14 | * - Add neighbour cache statistics like rtstat | ||
15 | */ | ||
16 | |||
17 | /* The following flags & states are exported to user space, | ||
18 | so that they should be moved to include/linux/ directory. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | * Neighbor Cache Entry Flags | ||
23 | */ | ||
24 | |||
25 | #define NTF_PROXY 0x08 /* == ATF_PUBL */ | ||
26 | #define NTF_ROUTER 0x80 | ||
27 | |||
28 | /* | ||
29 | * Neighbor Cache Entry States. | ||
30 | */ | ||
31 | |||
32 | #define NUD_INCOMPLETE 0x01 | ||
33 | #define NUD_REACHABLE 0x02 | ||
34 | #define NUD_STALE 0x04 | ||
35 | #define NUD_DELAY 0x08 | ||
36 | #define NUD_PROBE 0x10 | ||
37 | #define NUD_FAILED 0x20 | ||
38 | |||
39 | /* Dummy states */ | ||
40 | #define NUD_NOARP 0x40 | ||
41 | #define NUD_PERMANENT 0x80 | ||
42 | #define NUD_NONE 0x00 | ||
43 | |||
44 | /* NUD_NOARP & NUD_PERMANENT are pseudostates, they never change | ||
45 | and make no address resolution or NUD. | ||
46 | NUD_PERMANENT is also cannot be deleted by garbage collectors. | ||
47 | */ | ||
48 | |||
49 | #ifdef __KERNEL__ | ||
50 | |||
51 | #include <asm/atomic.h> | ||
52 | #include <linux/skbuff.h> | ||
53 | #include <linux/netdevice.h> | ||
54 | #include <linux/rcupdate.h> | ||
55 | #include <linux/seq_file.h> | ||
56 | |||
57 | #include <linux/err.h> | ||
58 | #include <linux/sysctl.h> | ||
59 | |||
60 | #define NUD_IN_TIMER (NUD_INCOMPLETE|NUD_REACHABLE|NUD_DELAY|NUD_PROBE) | ||
61 | #define NUD_VALID (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY) | ||
62 | #define NUD_CONNECTED (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE) | ||
63 | |||
64 | struct neighbour; | ||
65 | |||
66 | struct neigh_parms | ||
67 | { | ||
68 | struct neigh_parms *next; | ||
69 | int (*neigh_setup)(struct neighbour *); | ||
70 | struct neigh_table *tbl; | ||
71 | int entries; | ||
72 | void *priv; | ||
73 | |||
74 | void *sysctl_table; | ||
75 | |||
76 | int dead; | ||
77 | atomic_t refcnt; | ||
78 | struct rcu_head rcu_head; | ||
79 | |||
80 | int base_reachable_time; | ||
81 | int retrans_time; | ||
82 | int gc_staletime; | ||
83 | int reachable_time; | ||
84 | int delay_probe_time; | ||
85 | |||
86 | int queue_len; | ||
87 | int ucast_probes; | ||
88 | int app_probes; | ||
89 | int mcast_probes; | ||
90 | int anycast_delay; | ||
91 | int proxy_delay; | ||
92 | int proxy_qlen; | ||
93 | int locktime; | ||
94 | }; | ||
95 | |||
96 | struct neigh_statistics | ||
97 | { | ||
98 | unsigned long allocs; /* number of allocated neighs */ | ||
99 | unsigned long destroys; /* number of destroyed neighs */ | ||
100 | unsigned long hash_grows; /* number of hash resizes */ | ||
101 | |||
102 | unsigned long res_failed; /* nomber of failed resolutions */ | ||
103 | |||
104 | unsigned long lookups; /* number of lookups */ | ||
105 | unsigned long hits; /* number of hits (among lookups) */ | ||
106 | |||
107 | unsigned long rcv_probes_mcast; /* number of received mcast ipv6 */ | ||
108 | unsigned long rcv_probes_ucast; /* number of received ucast ipv6 */ | ||
109 | |||
110 | unsigned long periodic_gc_runs; /* number of periodic GC runs */ | ||
111 | unsigned long forced_gc_runs; /* number of forced GC runs */ | ||
112 | }; | ||
113 | |||
114 | #define NEIGH_CACHE_STAT_INC(tbl, field) \ | ||
115 | do { \ | ||
116 | preempt_disable(); \ | ||
117 | (per_cpu_ptr((tbl)->stats, smp_processor_id())->field)++; \ | ||
118 | preempt_enable(); \ | ||
119 | } while (0) | ||
120 | |||
121 | struct neighbour | ||
122 | { | ||
123 | struct neighbour *next; | ||
124 | struct neigh_table *tbl; | ||
125 | struct neigh_parms *parms; | ||
126 | struct net_device *dev; | ||
127 | unsigned long used; | ||
128 | unsigned long confirmed; | ||
129 | unsigned long updated; | ||
130 | __u8 flags; | ||
131 | __u8 nud_state; | ||
132 | __u8 type; | ||
133 | __u8 dead; | ||
134 | atomic_t probes; | ||
135 | rwlock_t lock; | ||
136 | unsigned char ha[(MAX_ADDR_LEN+sizeof(unsigned long)-1)&~(sizeof(unsigned long)-1)]; | ||
137 | struct hh_cache *hh; | ||
138 | atomic_t refcnt; | ||
139 | int (*output)(struct sk_buff *skb); | ||
140 | struct sk_buff_head arp_queue; | ||
141 | struct timer_list timer; | ||
142 | struct neigh_ops *ops; | ||
143 | u8 primary_key[0]; | ||
144 | }; | ||
145 | |||
146 | struct neigh_ops | ||
147 | { | ||
148 | int family; | ||
149 | void (*destructor)(struct neighbour *); | ||
150 | void (*solicit)(struct neighbour *, struct sk_buff*); | ||
151 | void (*error_report)(struct neighbour *, struct sk_buff*); | ||
152 | int (*output)(struct sk_buff*); | ||
153 | int (*connected_output)(struct sk_buff*); | ||
154 | int (*hh_output)(struct sk_buff*); | ||
155 | int (*queue_xmit)(struct sk_buff*); | ||
156 | }; | ||
157 | |||
158 | struct pneigh_entry | ||
159 | { | ||
160 | struct pneigh_entry *next; | ||
161 | struct net_device *dev; | ||
162 | u8 key[0]; | ||
163 | }; | ||
164 | |||
165 | /* | ||
166 | * neighbour table manipulation | ||
167 | */ | ||
168 | |||
169 | |||
170 | struct neigh_table | ||
171 | { | ||
172 | struct neigh_table *next; | ||
173 | int family; | ||
174 | int entry_size; | ||
175 | int key_len; | ||
176 | __u32 (*hash)(const void *pkey, const struct net_device *); | ||
177 | int (*constructor)(struct neighbour *); | ||
178 | int (*pconstructor)(struct pneigh_entry *); | ||
179 | void (*pdestructor)(struct pneigh_entry *); | ||
180 | void (*proxy_redo)(struct sk_buff *skb); | ||
181 | char *id; | ||
182 | struct neigh_parms parms; | ||
183 | /* HACK. gc_* shoul follow parms without a gap! */ | ||
184 | int gc_interval; | ||
185 | int gc_thresh1; | ||
186 | int gc_thresh2; | ||
187 | int gc_thresh3; | ||
188 | unsigned long last_flush; | ||
189 | struct timer_list gc_timer; | ||
190 | struct timer_list proxy_timer; | ||
191 | struct sk_buff_head proxy_queue; | ||
192 | atomic_t entries; | ||
193 | rwlock_t lock; | ||
194 | unsigned long last_rand; | ||
195 | struct neigh_parms *parms_list; | ||
196 | kmem_cache_t *kmem_cachep; | ||
197 | struct neigh_statistics *stats; | ||
198 | struct neighbour **hash_buckets; | ||
199 | unsigned int hash_mask; | ||
200 | __u32 hash_rnd; | ||
201 | unsigned int hash_chain_gc; | ||
202 | struct pneigh_entry **phash_buckets; | ||
203 | #ifdef CONFIG_PROC_FS | ||
204 | struct proc_dir_entry *pde; | ||
205 | #endif | ||
206 | }; | ||
207 | |||
208 | /* flags for neigh_update() */ | ||
209 | #define NEIGH_UPDATE_F_OVERRIDE 0x00000001 | ||
210 | #define NEIGH_UPDATE_F_WEAK_OVERRIDE 0x00000002 | ||
211 | #define NEIGH_UPDATE_F_OVERRIDE_ISROUTER 0x00000004 | ||
212 | #define NEIGH_UPDATE_F_ISROUTER 0x40000000 | ||
213 | #define NEIGH_UPDATE_F_ADMIN 0x80000000 | ||
214 | |||
215 | extern void neigh_table_init(struct neigh_table *tbl); | ||
216 | extern int neigh_table_clear(struct neigh_table *tbl); | ||
217 | extern struct neighbour * neigh_lookup(struct neigh_table *tbl, | ||
218 | const void *pkey, | ||
219 | struct net_device *dev); | ||
220 | extern struct neighbour * neigh_lookup_nodev(struct neigh_table *tbl, | ||
221 | const void *pkey); | ||
222 | extern struct neighbour * neigh_create(struct neigh_table *tbl, | ||
223 | const void *pkey, | ||
224 | struct net_device *dev); | ||
225 | extern void neigh_destroy(struct neighbour *neigh); | ||
226 | extern int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb); | ||
227 | extern int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, | ||
228 | u32 flags); | ||
229 | extern void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev); | ||
230 | extern int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev); | ||
231 | extern int neigh_resolve_output(struct sk_buff *skb); | ||
232 | extern int neigh_connected_output(struct sk_buff *skb); | ||
233 | extern int neigh_compat_output(struct sk_buff *skb); | ||
234 | extern struct neighbour *neigh_event_ns(struct neigh_table *tbl, | ||
235 | u8 *lladdr, void *saddr, | ||
236 | struct net_device *dev); | ||
237 | |||
238 | extern struct neigh_parms *neigh_parms_alloc(struct net_device *dev, struct neigh_table *tbl); | ||
239 | extern void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms); | ||
240 | extern void neigh_parms_destroy(struct neigh_parms *parms); | ||
241 | extern unsigned long neigh_rand_reach_time(unsigned long base); | ||
242 | |||
243 | extern void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p, | ||
244 | struct sk_buff *skb); | ||
245 | extern struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, const void *key, struct net_device *dev, int creat); | ||
246 | extern int pneigh_delete(struct neigh_table *tbl, const void *key, struct net_device *dev); | ||
247 | |||
248 | struct netlink_callback; | ||
249 | struct nlmsghdr; | ||
250 | extern int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb); | ||
251 | extern int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); | ||
252 | extern int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); | ||
253 | extern void neigh_app_ns(struct neighbour *n); | ||
254 | |||
255 | extern void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie); | ||
256 | extern void __neigh_for_each_release(struct neigh_table *tbl, int (*cb)(struct neighbour *)); | ||
257 | extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_entry *)); | ||
258 | |||
259 | struct neigh_seq_state { | ||
260 | struct neigh_table *tbl; | ||
261 | void *(*neigh_sub_iter)(struct neigh_seq_state *state, | ||
262 | struct neighbour *n, loff_t *pos); | ||
263 | unsigned int bucket; | ||
264 | unsigned int flags; | ||
265 | #define NEIGH_SEQ_NEIGH_ONLY 0x00000001 | ||
266 | #define NEIGH_SEQ_IS_PNEIGH 0x00000002 | ||
267 | #define NEIGH_SEQ_SKIP_NOARP 0x00000004 | ||
268 | }; | ||
269 | extern void *neigh_seq_start(struct seq_file *, loff_t *, struct neigh_table *, unsigned int); | ||
270 | extern void *neigh_seq_next(struct seq_file *, void *, loff_t *); | ||
271 | extern void neigh_seq_stop(struct seq_file *, void *); | ||
272 | |||
273 | extern int neigh_sysctl_register(struct net_device *dev, | ||
274 | struct neigh_parms *p, | ||
275 | int p_id, int pdev_id, | ||
276 | char *p_name, | ||
277 | proc_handler *proc_handler, | ||
278 | ctl_handler *strategy); | ||
279 | extern void neigh_sysctl_unregister(struct neigh_parms *p); | ||
280 | |||
281 | static inline void __neigh_parms_put(struct neigh_parms *parms) | ||
282 | { | ||
283 | atomic_dec(&parms->refcnt); | ||
284 | } | ||
285 | |||
286 | static inline void neigh_parms_put(struct neigh_parms *parms) | ||
287 | { | ||
288 | if (atomic_dec_and_test(&parms->refcnt)) | ||
289 | neigh_parms_destroy(parms); | ||
290 | } | ||
291 | |||
292 | static inline struct neigh_parms *neigh_parms_clone(struct neigh_parms *parms) | ||
293 | { | ||
294 | atomic_inc(&parms->refcnt); | ||
295 | return parms; | ||
296 | } | ||
297 | |||
298 | /* | ||
299 | * Neighbour references | ||
300 | */ | ||
301 | |||
302 | static inline void neigh_release(struct neighbour *neigh) | ||
303 | { | ||
304 | if (atomic_dec_and_test(&neigh->refcnt)) | ||
305 | neigh_destroy(neigh); | ||
306 | } | ||
307 | |||
308 | static inline struct neighbour * neigh_clone(struct neighbour *neigh) | ||
309 | { | ||
310 | if (neigh) | ||
311 | atomic_inc(&neigh->refcnt); | ||
312 | return neigh; | ||
313 | } | ||
314 | |||
315 | #define neigh_hold(n) atomic_inc(&(n)->refcnt) | ||
316 | |||
317 | static inline void neigh_confirm(struct neighbour *neigh) | ||
318 | { | ||
319 | if (neigh) | ||
320 | neigh->confirmed = jiffies; | ||
321 | } | ||
322 | |||
323 | static inline int neigh_is_connected(struct neighbour *neigh) | ||
324 | { | ||
325 | return neigh->nud_state&NUD_CONNECTED; | ||
326 | } | ||
327 | |||
328 | static inline int neigh_is_valid(struct neighbour *neigh) | ||
329 | { | ||
330 | return neigh->nud_state&NUD_VALID; | ||
331 | } | ||
332 | |||
333 | static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) | ||
334 | { | ||
335 | neigh->used = jiffies; | ||
336 | if (!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE))) | ||
337 | return __neigh_event_send(neigh, skb); | ||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | static inline struct neighbour * | ||
342 | __neigh_lookup(struct neigh_table *tbl, const void *pkey, struct net_device *dev, int creat) | ||
343 | { | ||
344 | struct neighbour *n = neigh_lookup(tbl, pkey, dev); | ||
345 | |||
346 | if (n || !creat) | ||
347 | return n; | ||
348 | |||
349 | n = neigh_create(tbl, pkey, dev); | ||
350 | return IS_ERR(n) ? NULL : n; | ||
351 | } | ||
352 | |||
353 | static inline struct neighbour * | ||
354 | __neigh_lookup_errno(struct neigh_table *tbl, const void *pkey, | ||
355 | struct net_device *dev) | ||
356 | { | ||
357 | struct neighbour *n = neigh_lookup(tbl, pkey, dev); | ||
358 | |||
359 | if (n) | ||
360 | return n; | ||
361 | |||
362 | return neigh_create(tbl, pkey, dev); | ||
363 | } | ||
364 | |||
365 | #define LOCALLY_ENQUEUED -2 | ||
366 | |||
367 | #endif | ||
368 | #endif | ||
369 | |||
370 | |||
diff --git a/include/net/netrom.h b/include/net/netrom.h new file mode 100644 index 000000000000..45f2c7616d8b --- /dev/null +++ b/include/net/netrom.h | |||
@@ -0,0 +1,242 @@ | |||
1 | /* | ||
2 | * Declarations of NET/ROM type objects. | ||
3 | * | ||
4 | * Jonathan Naylor G4KLX 9/4/95 | ||
5 | */ | ||
6 | |||
7 | #ifndef _NETROM_H | ||
8 | #define _NETROM_H | ||
9 | #include <linux/netrom.h> | ||
10 | #include <linux/list.h> | ||
11 | #include <net/sock.h> | ||
12 | |||
13 | #define NR_NETWORK_LEN 15 | ||
14 | #define NR_TRANSPORT_LEN 5 | ||
15 | |||
16 | #define NR_PROTO_IP 0x0C | ||
17 | |||
18 | #define NR_PROTOEXT 0x00 | ||
19 | #define NR_CONNREQ 0x01 | ||
20 | #define NR_CONNACK 0x02 | ||
21 | #define NR_DISCREQ 0x03 | ||
22 | #define NR_DISCACK 0x04 | ||
23 | #define NR_INFO 0x05 | ||
24 | #define NR_INFOACK 0x06 | ||
25 | |||
26 | #define NR_CHOKE_FLAG 0x80 | ||
27 | #define NR_NAK_FLAG 0x40 | ||
28 | #define NR_MORE_FLAG 0x20 | ||
29 | |||
30 | /* Define Link State constants. */ | ||
31 | enum { | ||
32 | NR_STATE_0, | ||
33 | NR_STATE_1, | ||
34 | NR_STATE_2, | ||
35 | NR_STATE_3 | ||
36 | }; | ||
37 | |||
38 | #define NR_COND_ACK_PENDING 0x01 | ||
39 | #define NR_COND_REJECT 0x02 | ||
40 | #define NR_COND_PEER_RX_BUSY 0x04 | ||
41 | #define NR_COND_OWN_RX_BUSY 0x08 | ||
42 | |||
43 | #define NR_DEFAULT_T1 (120 * HZ) /* Outstanding frames - 120 seconds */ | ||
44 | #define NR_DEFAULT_T2 (5 * HZ) /* Response delay - 5 seconds */ | ||
45 | #define NR_DEFAULT_N2 3 /* Number of Retries - 3 */ | ||
46 | #define NR_DEFAULT_T4 (180 * HZ) /* Busy Delay - 180 seconds */ | ||
47 | #define NR_DEFAULT_IDLE (0 * 60 * HZ) /* No Activity Timeout - none */ | ||
48 | #define NR_DEFAULT_WINDOW 4 /* Default Window Size - 4 */ | ||
49 | #define NR_DEFAULT_OBS 6 /* Default Obsolescence Count - 6 */ | ||
50 | #define NR_DEFAULT_QUAL 10 /* Default Neighbour Quality - 10 */ | ||
51 | #define NR_DEFAULT_TTL 16 /* Default Time To Live - 16 */ | ||
52 | #define NR_DEFAULT_ROUTING 1 /* Is routing enabled ? */ | ||
53 | #define NR_DEFAULT_FAILS 2 /* Link fails until route fails */ | ||
54 | |||
55 | #define NR_MODULUS 256 | ||
56 | #define NR_MAX_WINDOW_SIZE 127 /* Maximum Window Allowable - 127 */ | ||
57 | #define NR_MAX_PACKET_SIZE 236 /* Maximum Packet Length - 236 */ | ||
58 | |||
59 | struct nr_sock { | ||
60 | struct sock sock; | ||
61 | ax25_address user_addr, source_addr, dest_addr; | ||
62 | struct net_device *device; | ||
63 | unsigned char my_index, my_id; | ||
64 | unsigned char your_index, your_id; | ||
65 | unsigned char state, condition, bpqext, window; | ||
66 | unsigned short vs, vr, va, vl; | ||
67 | unsigned char n2, n2count; | ||
68 | unsigned long t1, t2, t4, idle; | ||
69 | unsigned short fraglen; | ||
70 | struct timer_list t1timer; | ||
71 | struct timer_list t2timer; | ||
72 | struct timer_list t4timer; | ||
73 | struct timer_list idletimer; | ||
74 | struct sk_buff_head ack_queue; | ||
75 | struct sk_buff_head reseq_queue; | ||
76 | struct sk_buff_head frag_queue; | ||
77 | }; | ||
78 | |||
79 | #define nr_sk(sk) ((struct nr_sock *)(sk)) | ||
80 | |||
81 | struct nr_neigh { | ||
82 | struct hlist_node neigh_node; | ||
83 | ax25_address callsign; | ||
84 | ax25_digi *digipeat; | ||
85 | ax25_cb *ax25; | ||
86 | struct net_device *dev; | ||
87 | unsigned char quality; | ||
88 | unsigned char locked; | ||
89 | unsigned short count; | ||
90 | unsigned int number; | ||
91 | unsigned char failed; | ||
92 | atomic_t refcount; | ||
93 | }; | ||
94 | |||
95 | struct nr_route { | ||
96 | unsigned char quality; | ||
97 | unsigned char obs_count; | ||
98 | struct nr_neigh *neighbour; | ||
99 | }; | ||
100 | |||
101 | struct nr_node { | ||
102 | struct hlist_node node_node; | ||
103 | ax25_address callsign; | ||
104 | char mnemonic[7]; | ||
105 | unsigned char which; | ||
106 | unsigned char count; | ||
107 | struct nr_route routes[3]; | ||
108 | atomic_t refcount; | ||
109 | spinlock_t node_lock; | ||
110 | }; | ||
111 | |||
112 | /********************************************************************* | ||
113 | * nr_node & nr_neigh lists, refcounting and locking | ||
114 | *********************************************************************/ | ||
115 | |||
116 | #define nr_node_hold(__nr_node) \ | ||
117 | atomic_inc(&((__nr_node)->refcount)) | ||
118 | |||
119 | static __inline__ void nr_node_put(struct nr_node *nr_node) | ||
120 | { | ||
121 | if (atomic_dec_and_test(&nr_node->refcount)) { | ||
122 | kfree(nr_node); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | #define nr_neigh_hold(__nr_neigh) \ | ||
127 | atomic_inc(&((__nr_neigh)->refcount)) | ||
128 | |||
129 | static __inline__ void nr_neigh_put(struct nr_neigh *nr_neigh) | ||
130 | { | ||
131 | if (atomic_dec_and_test(&nr_neigh->refcount)) { | ||
132 | if (nr_neigh->digipeat != NULL) | ||
133 | kfree(nr_neigh->digipeat); | ||
134 | kfree(nr_neigh); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | /* nr_node_lock and nr_node_unlock also hold/put the node's refcounter. | ||
139 | */ | ||
140 | static __inline__ void nr_node_lock(struct nr_node *nr_node) | ||
141 | { | ||
142 | nr_node_hold(nr_node); | ||
143 | spin_lock_bh(&nr_node->node_lock); | ||
144 | } | ||
145 | |||
146 | static __inline__ void nr_node_unlock(struct nr_node *nr_node) | ||
147 | { | ||
148 | spin_unlock_bh(&nr_node->node_lock); | ||
149 | nr_node_put(nr_node); | ||
150 | } | ||
151 | |||
152 | #define nr_neigh_for_each(__nr_neigh, node, list) \ | ||
153 | hlist_for_each_entry(__nr_neigh, node, list, neigh_node) | ||
154 | |||
155 | #define nr_neigh_for_each_safe(__nr_neigh, node, node2, list) \ | ||
156 | hlist_for_each_entry_safe(__nr_neigh, node, node2, list, neigh_node) | ||
157 | |||
158 | #define nr_node_for_each(__nr_node, node, list) \ | ||
159 | hlist_for_each_entry(__nr_node, node, list, node_node) | ||
160 | |||
161 | #define nr_node_for_each_safe(__nr_node, node, node2, list) \ | ||
162 | hlist_for_each_entry_safe(__nr_node, node, node2, list, node_node) | ||
163 | |||
164 | |||
165 | /*********************************************************************/ | ||
166 | |||
167 | /* af_netrom.c */ | ||
168 | extern int sysctl_netrom_default_path_quality; | ||
169 | extern int sysctl_netrom_obsolescence_count_initialiser; | ||
170 | extern int sysctl_netrom_network_ttl_initialiser; | ||
171 | extern int sysctl_netrom_transport_timeout; | ||
172 | extern int sysctl_netrom_transport_maximum_tries; | ||
173 | extern int sysctl_netrom_transport_acknowledge_delay; | ||
174 | extern int sysctl_netrom_transport_busy_delay; | ||
175 | extern int sysctl_netrom_transport_requested_window_size; | ||
176 | extern int sysctl_netrom_transport_no_activity_timeout; | ||
177 | extern int sysctl_netrom_routing_control; | ||
178 | extern int sysctl_netrom_link_fails_count; | ||
179 | extern int nr_rx_frame(struct sk_buff *, struct net_device *); | ||
180 | extern void nr_destroy_socket(struct sock *); | ||
181 | |||
182 | /* nr_dev.c */ | ||
183 | extern int nr_rx_ip(struct sk_buff *, struct net_device *); | ||
184 | extern void nr_setup(struct net_device *); | ||
185 | |||
186 | /* nr_in.c */ | ||
187 | extern int nr_process_rx_frame(struct sock *, struct sk_buff *); | ||
188 | |||
189 | /* nr_loopback.c */ | ||
190 | extern void nr_loopback_init(void); | ||
191 | extern void nr_loopback_clear(void); | ||
192 | extern int nr_loopback_queue(struct sk_buff *); | ||
193 | |||
194 | /* nr_out.c */ | ||
195 | extern void nr_output(struct sock *, struct sk_buff *); | ||
196 | extern void nr_send_nak_frame(struct sock *); | ||
197 | extern void nr_kick(struct sock *); | ||
198 | extern void nr_transmit_buffer(struct sock *, struct sk_buff *); | ||
199 | extern void nr_establish_data_link(struct sock *); | ||
200 | extern void nr_enquiry_response(struct sock *); | ||
201 | extern void nr_check_iframes_acked(struct sock *, unsigned short); | ||
202 | |||
203 | /* nr_route.c */ | ||
204 | extern void nr_rt_device_down(struct net_device *); | ||
205 | extern struct net_device *nr_dev_first(void); | ||
206 | extern struct net_device *nr_dev_get(ax25_address *); | ||
207 | extern int nr_rt_ioctl(unsigned int, void __user *); | ||
208 | extern void nr_link_failed(ax25_cb *, int); | ||
209 | extern int nr_route_frame(struct sk_buff *, ax25_cb *); | ||
210 | extern struct file_operations nr_nodes_fops; | ||
211 | extern struct file_operations nr_neigh_fops; | ||
212 | extern void nr_rt_free(void); | ||
213 | |||
214 | /* nr_subr.c */ | ||
215 | extern void nr_clear_queues(struct sock *); | ||
216 | extern void nr_frames_acked(struct sock *, unsigned short); | ||
217 | extern void nr_requeue_frames(struct sock *); | ||
218 | extern int nr_validate_nr(struct sock *, unsigned short); | ||
219 | extern int nr_in_rx_window(struct sock *, unsigned short); | ||
220 | extern void nr_write_internal(struct sock *, int); | ||
221 | extern void nr_transmit_refusal(struct sk_buff *, int); | ||
222 | extern void nr_disconnect(struct sock *, int); | ||
223 | |||
224 | /* nr_timer.c */ | ||
225 | extern void nr_init_timers(struct sock *sk); | ||
226 | extern void nr_start_heartbeat(struct sock *); | ||
227 | extern void nr_start_t1timer(struct sock *); | ||
228 | extern void nr_start_t2timer(struct sock *); | ||
229 | extern void nr_start_t4timer(struct sock *); | ||
230 | extern void nr_start_idletimer(struct sock *); | ||
231 | extern void nr_stop_heartbeat(struct sock *); | ||
232 | extern void nr_stop_t1timer(struct sock *); | ||
233 | extern void nr_stop_t2timer(struct sock *); | ||
234 | extern void nr_stop_t4timer(struct sock *); | ||
235 | extern void nr_stop_idletimer(struct sock *); | ||
236 | extern int nr_t1timer_running(struct sock *); | ||
237 | |||
238 | /* sysctl_net_netrom.c */ | ||
239 | extern void nr_register_sysctl(void); | ||
240 | extern void nr_unregister_sysctl(void); | ||
241 | |||
242 | #endif | ||
diff --git a/include/net/p8022.h b/include/net/p8022.h new file mode 100644 index 000000000000..3c99a86c3581 --- /dev/null +++ b/include/net/p8022.h | |||
@@ -0,0 +1,10 @@ | |||
1 | #ifndef _NET_P8022_H | ||
2 | #define _NET_P8022_H | ||
3 | extern struct datalink_proto * | ||
4 | register_8022_client(unsigned char type, | ||
5 | int (*func)(struct sk_buff *skb, | ||
6 | struct net_device *dev, | ||
7 | struct packet_type *pt)); | ||
8 | extern void unregister_8022_client(struct datalink_proto *proto); | ||
9 | |||
10 | #endif | ||
diff --git a/include/net/pkt_act.h b/include/net/pkt_act.h new file mode 100644 index 000000000000..bd08964b72c0 --- /dev/null +++ b/include/net/pkt_act.h | |||
@@ -0,0 +1,275 @@ | |||
1 | #ifndef __NET_PKT_ACT_H | ||
2 | #define __NET_PKT_ACT_H | ||
3 | |||
4 | #include <asm/uaccess.h> | ||
5 | #include <asm/system.h> | ||
6 | #include <linux/bitops.h> | ||
7 | #include <linux/config.h> | ||
8 | #include <linux/types.h> | ||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/sched.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <linux/mm.h> | ||
13 | #include <linux/socket.h> | ||
14 | #include <linux/sockios.h> | ||
15 | #include <linux/in.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/netdevice.h> | ||
19 | #include <linux/skbuff.h> | ||
20 | #include <linux/rtnetlink.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/proc_fs.h> | ||
24 | #include <net/sock.h> | ||
25 | #include <net/pkt_sched.h> | ||
26 | |||
27 | #define tca_st(val) (struct tcf_##val *) | ||
28 | #define PRIV(a,name) ( tca_st(name) (a)->priv) | ||
29 | |||
30 | #if 0 /* control */ | ||
31 | #define DPRINTK(format,args...) printk(KERN_DEBUG format,##args) | ||
32 | #else | ||
33 | #define DPRINTK(format,args...) | ||
34 | #endif | ||
35 | |||
36 | #if 0 /* data */ | ||
37 | #define D2PRINTK(format,args...) printk(KERN_DEBUG format,##args) | ||
38 | #else | ||
39 | #define D2PRINTK(format,args...) | ||
40 | #endif | ||
41 | |||
42 | static __inline__ unsigned | ||
43 | tcf_hash(u32 index) | ||
44 | { | ||
45 | return index & MY_TAB_MASK; | ||
46 | } | ||
47 | |||
48 | /* probably move this from being inline | ||
49 | * and put into act_generic | ||
50 | */ | ||
51 | static inline void | ||
52 | tcf_hash_destroy(struct tcf_st *p) | ||
53 | { | ||
54 | unsigned h = tcf_hash(p->index); | ||
55 | struct tcf_st **p1p; | ||
56 | |||
57 | for (p1p = &tcf_ht[h]; *p1p; p1p = &(*p1p)->next) { | ||
58 | if (*p1p == p) { | ||
59 | write_lock_bh(&tcf_t_lock); | ||
60 | *p1p = p->next; | ||
61 | write_unlock_bh(&tcf_t_lock); | ||
62 | #ifdef CONFIG_NET_ESTIMATOR | ||
63 | gen_kill_estimator(&p->bstats, &p->rate_est); | ||
64 | #endif | ||
65 | kfree(p); | ||
66 | return; | ||
67 | } | ||
68 | } | ||
69 | BUG_TRAP(0); | ||
70 | } | ||
71 | |||
72 | static inline int | ||
73 | tcf_hash_release(struct tcf_st *p, int bind ) | ||
74 | { | ||
75 | int ret = 0; | ||
76 | if (p) { | ||
77 | if (bind) { | ||
78 | p->bindcnt--; | ||
79 | } | ||
80 | p->refcnt--; | ||
81 | if(p->bindcnt <=0 && p->refcnt <= 0) { | ||
82 | tcf_hash_destroy(p); | ||
83 | ret = 1; | ||
84 | } | ||
85 | } | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | static __inline__ int | ||
90 | tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, | ||
91 | struct tc_action *a) | ||
92 | { | ||
93 | struct tcf_st *p; | ||
94 | int err =0, index = -1,i= 0, s_i = 0, n_i = 0; | ||
95 | struct rtattr *r ; | ||
96 | |||
97 | read_lock(&tcf_t_lock); | ||
98 | |||
99 | s_i = cb->args[0]; | ||
100 | |||
101 | for (i = 0; i < MY_TAB_SIZE; i++) { | ||
102 | p = tcf_ht[tcf_hash(i)]; | ||
103 | |||
104 | for (; p; p = p->next) { | ||
105 | index++; | ||
106 | if (index < s_i) | ||
107 | continue; | ||
108 | a->priv = p; | ||
109 | a->order = n_i; | ||
110 | r = (struct rtattr*) skb->tail; | ||
111 | RTA_PUT(skb, a->order, 0, NULL); | ||
112 | err = tcf_action_dump_1(skb, a, 0, 0); | ||
113 | if (0 > err) { | ||
114 | index--; | ||
115 | skb_trim(skb, (u8*)r - skb->data); | ||
116 | goto done; | ||
117 | } | ||
118 | r->rta_len = skb->tail - (u8*)r; | ||
119 | n_i++; | ||
120 | if (n_i >= TCA_ACT_MAX_PRIO) { | ||
121 | goto done; | ||
122 | } | ||
123 | } | ||
124 | } | ||
125 | done: | ||
126 | read_unlock(&tcf_t_lock); | ||
127 | if (n_i) | ||
128 | cb->args[0] += n_i; | ||
129 | return n_i; | ||
130 | |||
131 | rtattr_failure: | ||
132 | skb_trim(skb, (u8*)r - skb->data); | ||
133 | goto done; | ||
134 | } | ||
135 | |||
136 | static __inline__ int | ||
137 | tcf_del_walker(struct sk_buff *skb, struct tc_action *a) | ||
138 | { | ||
139 | struct tcf_st *p, *s_p; | ||
140 | struct rtattr *r ; | ||
141 | int i= 0, n_i = 0; | ||
142 | |||
143 | r = (struct rtattr*) skb->tail; | ||
144 | RTA_PUT(skb, a->order, 0, NULL); | ||
145 | RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); | ||
146 | for (i = 0; i < MY_TAB_SIZE; i++) { | ||
147 | p = tcf_ht[tcf_hash(i)]; | ||
148 | |||
149 | while (p != NULL) { | ||
150 | s_p = p->next; | ||
151 | if (ACT_P_DELETED == tcf_hash_release(p, 0)) { | ||
152 | module_put(a->ops->owner); | ||
153 | } | ||
154 | n_i++; | ||
155 | p = s_p; | ||
156 | } | ||
157 | } | ||
158 | RTA_PUT(skb, TCA_FCNT, 4, &n_i); | ||
159 | r->rta_len = skb->tail - (u8*)r; | ||
160 | |||
161 | return n_i; | ||
162 | rtattr_failure: | ||
163 | skb_trim(skb, (u8*)r - skb->data); | ||
164 | return -EINVAL; | ||
165 | } | ||
166 | |||
167 | static __inline__ int | ||
168 | tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, int type, | ||
169 | struct tc_action *a) | ||
170 | { | ||
171 | if (type == RTM_DELACTION) { | ||
172 | return tcf_del_walker(skb,a); | ||
173 | } else if (type == RTM_GETACTION) { | ||
174 | return tcf_dump_walker(skb,cb,a); | ||
175 | } else { | ||
176 | printk("tcf_generic_walker: unknown action %d\n",type); | ||
177 | return -EINVAL; | ||
178 | } | ||
179 | } | ||
180 | |||
181 | static __inline__ struct tcf_st * | ||
182 | tcf_hash_lookup(u32 index) | ||
183 | { | ||
184 | struct tcf_st *p; | ||
185 | |||
186 | read_lock(&tcf_t_lock); | ||
187 | for (p = tcf_ht[tcf_hash(index)]; p; p = p->next) { | ||
188 | if (p->index == index) | ||
189 | break; | ||
190 | } | ||
191 | read_unlock(&tcf_t_lock); | ||
192 | return p; | ||
193 | } | ||
194 | |||
195 | static __inline__ u32 | ||
196 | tcf_hash_new_index(void) | ||
197 | { | ||
198 | do { | ||
199 | if (++idx_gen == 0) | ||
200 | idx_gen = 1; | ||
201 | } while (tcf_hash_lookup(idx_gen)); | ||
202 | |||
203 | return idx_gen; | ||
204 | } | ||
205 | |||
206 | |||
207 | static inline int | ||
208 | tcf_hash_search(struct tc_action *a, u32 index) | ||
209 | { | ||
210 | struct tcf_st *p = tcf_hash_lookup(index); | ||
211 | |||
212 | if (p != NULL) { | ||
213 | a->priv = p; | ||
214 | return 1; | ||
215 | } | ||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | #ifdef CONFIG_NET_ACT_INIT | ||
220 | static inline struct tcf_st * | ||
221 | tcf_hash_check(u32 index, struct tc_action *a, int ovr, int bind) | ||
222 | { | ||
223 | struct tcf_st *p = NULL; | ||
224 | if (index && (p = tcf_hash_lookup(index)) != NULL) { | ||
225 | if (bind) { | ||
226 | p->bindcnt++; | ||
227 | p->refcnt++; | ||
228 | } | ||
229 | a->priv = p; | ||
230 | } | ||
231 | return p; | ||
232 | } | ||
233 | |||
234 | static inline struct tcf_st * | ||
235 | tcf_hash_create(u32 index, struct rtattr *est, struct tc_action *a, int size, int ovr, int bind) | ||
236 | { | ||
237 | struct tcf_st *p = NULL; | ||
238 | |||
239 | p = kmalloc(size, GFP_KERNEL); | ||
240 | if (p == NULL) | ||
241 | return p; | ||
242 | |||
243 | memset(p, 0, size); | ||
244 | p->refcnt = 1; | ||
245 | |||
246 | if (bind) { | ||
247 | p->bindcnt = 1; | ||
248 | } | ||
249 | |||
250 | spin_lock_init(&p->lock); | ||
251 | p->stats_lock = &p->lock; | ||
252 | p->index = index ? : tcf_hash_new_index(); | ||
253 | p->tm.install = jiffies; | ||
254 | p->tm.lastuse = jiffies; | ||
255 | #ifdef CONFIG_NET_ESTIMATOR | ||
256 | if (est) | ||
257 | gen_new_estimator(&p->bstats, &p->rate_est, p->stats_lock, est); | ||
258 | #endif | ||
259 | a->priv = (void *) p; | ||
260 | return p; | ||
261 | } | ||
262 | |||
263 | static inline void tcf_hash_insert(struct tcf_st *p) | ||
264 | { | ||
265 | unsigned h = tcf_hash(p->index); | ||
266 | |||
267 | write_lock_bh(&tcf_t_lock); | ||
268 | p->next = tcf_ht[h]; | ||
269 | tcf_ht[h] = p; | ||
270 | write_unlock_bh(&tcf_t_lock); | ||
271 | } | ||
272 | |||
273 | #endif | ||
274 | |||
275 | #endif | ||
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h new file mode 100644 index 000000000000..4abda6aec05a --- /dev/null +++ b/include/net/pkt_cls.h | |||
@@ -0,0 +1,366 @@ | |||
1 | #ifndef __NET_PKT_CLS_H | ||
2 | #define __NET_PKT_CLS_H | ||
3 | |||
4 | #include <linux/pkt_cls.h> | ||
5 | #include <net/sch_generic.h> | ||
6 | #include <net/act_api.h> | ||
7 | |||
8 | /* Basic packet classifier frontend definitions. */ | ||
9 | |||
10 | struct tcf_walker | ||
11 | { | ||
12 | int stop; | ||
13 | int skip; | ||
14 | int count; | ||
15 | int (*fn)(struct tcf_proto *, unsigned long node, struct tcf_walker *); | ||
16 | }; | ||
17 | |||
18 | extern int register_tcf_proto_ops(struct tcf_proto_ops *ops); | ||
19 | extern int unregister_tcf_proto_ops(struct tcf_proto_ops *ops); | ||
20 | |||
21 | static inline unsigned long | ||
22 | __cls_set_class(unsigned long *clp, unsigned long cl) | ||
23 | { | ||
24 | unsigned long old_cl; | ||
25 | |||
26 | old_cl = *clp; | ||
27 | *clp = cl; | ||
28 | return old_cl; | ||
29 | } | ||
30 | |||
31 | static inline unsigned long | ||
32 | cls_set_class(struct tcf_proto *tp, unsigned long *clp, | ||
33 | unsigned long cl) | ||
34 | { | ||
35 | unsigned long old_cl; | ||
36 | |||
37 | tcf_tree_lock(tp); | ||
38 | old_cl = __cls_set_class(clp, cl); | ||
39 | tcf_tree_unlock(tp); | ||
40 | |||
41 | return old_cl; | ||
42 | } | ||
43 | |||
44 | static inline void | ||
45 | tcf_bind_filter(struct tcf_proto *tp, struct tcf_result *r, unsigned long base) | ||
46 | { | ||
47 | unsigned long cl; | ||
48 | |||
49 | cl = tp->q->ops->cl_ops->bind_tcf(tp->q, base, r->classid); | ||
50 | cl = cls_set_class(tp, &r->class, cl); | ||
51 | if (cl) | ||
52 | tp->q->ops->cl_ops->unbind_tcf(tp->q, cl); | ||
53 | } | ||
54 | |||
55 | static inline void | ||
56 | tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r) | ||
57 | { | ||
58 | unsigned long cl; | ||
59 | |||
60 | if ((cl = __cls_set_class(&r->class, 0)) != 0) | ||
61 | tp->q->ops->cl_ops->unbind_tcf(tp->q, cl); | ||
62 | } | ||
63 | |||
64 | struct tcf_exts | ||
65 | { | ||
66 | #ifdef CONFIG_NET_CLS_ACT | ||
67 | struct tc_action *action; | ||
68 | #elif defined CONFIG_NET_CLS_POLICE | ||
69 | struct tcf_police *police; | ||
70 | #endif | ||
71 | }; | ||
72 | |||
73 | /* Map to export classifier specific extension TLV types to the | ||
74 | * generic extensions API. Unsupported extensions must be set to 0. | ||
75 | */ | ||
76 | struct tcf_ext_map | ||
77 | { | ||
78 | int action; | ||
79 | int police; | ||
80 | }; | ||
81 | |||
82 | /** | ||
83 | * tcf_exts_is_predicative - check if a predicative extension is present | ||
84 | * @exts: tc filter extensions handle | ||
85 | * | ||
86 | * Returns 1 if a predicative extension is present, i.e. an extension which | ||
87 | * might cause further actions and thus overrule the regular tcf_result. | ||
88 | */ | ||
89 | static inline int | ||
90 | tcf_exts_is_predicative(struct tcf_exts *exts) | ||
91 | { | ||
92 | #ifdef CONFIG_NET_CLS_ACT | ||
93 | return !!exts->action; | ||
94 | #elif defined CONFIG_NET_CLS_POLICE | ||
95 | return !!exts->police; | ||
96 | #else | ||
97 | return 0; | ||
98 | #endif | ||
99 | } | ||
100 | |||
101 | /** | ||
102 | * tcf_exts_is_available - check if at least one extension is present | ||
103 | * @exts: tc filter extensions handle | ||
104 | * | ||
105 | * Returns 1 if at least one extension is present. | ||
106 | */ | ||
107 | static inline int | ||
108 | tcf_exts_is_available(struct tcf_exts *exts) | ||
109 | { | ||
110 | /* All non-predicative extensions must be added here. */ | ||
111 | return tcf_exts_is_predicative(exts); | ||
112 | } | ||
113 | |||
114 | /** | ||
115 | * tcf_exts_exec - execute tc filter extensions | ||
116 | * @skb: socket buffer | ||
117 | * @exts: tc filter extensions handle | ||
118 | * @res: desired result | ||
119 | * | ||
120 | * Executes all configured extensions. Returns 0 on a normal execution, | ||
121 | * a negative number if the filter must be considered unmatched or | ||
122 | * a positive action code (TC_ACT_*) which must be returned to the | ||
123 | * underlying layer. | ||
124 | */ | ||
125 | static inline int | ||
126 | tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts, | ||
127 | struct tcf_result *res) | ||
128 | { | ||
129 | #ifdef CONFIG_NET_CLS_ACT | ||
130 | if (exts->action) | ||
131 | return tcf_action_exec(skb, exts->action, res); | ||
132 | #elif defined CONFIG_NET_CLS_POLICE | ||
133 | if (exts->police) | ||
134 | return tcf_police(skb, exts->police); | ||
135 | #endif | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | extern int tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb, | ||
141 | struct rtattr *rate_tlv, struct tcf_exts *exts, | ||
142 | struct tcf_ext_map *map); | ||
143 | extern void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts); | ||
144 | extern void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst, | ||
145 | struct tcf_exts *src); | ||
146 | extern int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts, | ||
147 | struct tcf_ext_map *map); | ||
148 | extern int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts, | ||
149 | struct tcf_ext_map *map); | ||
150 | |||
151 | /** | ||
152 | * struct tcf_pkt_info - packet information | ||
153 | */ | ||
154 | struct tcf_pkt_info | ||
155 | { | ||
156 | unsigned char * ptr; | ||
157 | int nexthdr; | ||
158 | }; | ||
159 | |||
160 | #ifdef CONFIG_NET_EMATCH | ||
161 | |||
162 | struct tcf_ematch_ops; | ||
163 | |||
164 | /** | ||
165 | * struct tcf_ematch - extended match (ematch) | ||
166 | * | ||
167 | * @matchid: identifier to allow userspace to reidentify a match | ||
168 | * @flags: flags specifying attributes and the relation to other matches | ||
169 | * @ops: the operations lookup table of the corresponding ematch module | ||
170 | * @datalen: length of the ematch specific configuration data | ||
171 | * @data: ematch specific data | ||
172 | */ | ||
173 | struct tcf_ematch | ||
174 | { | ||
175 | struct tcf_ematch_ops * ops; | ||
176 | unsigned long data; | ||
177 | unsigned int datalen; | ||
178 | u16 matchid; | ||
179 | u16 flags; | ||
180 | }; | ||
181 | |||
182 | static inline int tcf_em_is_container(struct tcf_ematch *em) | ||
183 | { | ||
184 | return !em->ops; | ||
185 | } | ||
186 | |||
187 | static inline int tcf_em_is_simple(struct tcf_ematch *em) | ||
188 | { | ||
189 | return em->flags & TCF_EM_SIMPLE; | ||
190 | } | ||
191 | |||
192 | static inline int tcf_em_is_inverted(struct tcf_ematch *em) | ||
193 | { | ||
194 | return em->flags & TCF_EM_INVERT; | ||
195 | } | ||
196 | |||
197 | static inline int tcf_em_last_match(struct tcf_ematch *em) | ||
198 | { | ||
199 | return (em->flags & TCF_EM_REL_MASK) == TCF_EM_REL_END; | ||
200 | } | ||
201 | |||
202 | static inline int tcf_em_early_end(struct tcf_ematch *em, int result) | ||
203 | { | ||
204 | if (tcf_em_last_match(em)) | ||
205 | return 1; | ||
206 | |||
207 | if (result == 0 && em->flags & TCF_EM_REL_AND) | ||
208 | return 1; | ||
209 | |||
210 | if (result != 0 && em->flags & TCF_EM_REL_OR) | ||
211 | return 1; | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | /** | ||
217 | * struct tcf_ematch_tree - ematch tree handle | ||
218 | * | ||
219 | * @hdr: ematch tree header supplied by userspace | ||
220 | * @matches: array of ematches | ||
221 | */ | ||
222 | struct tcf_ematch_tree | ||
223 | { | ||
224 | struct tcf_ematch_tree_hdr hdr; | ||
225 | struct tcf_ematch * matches; | ||
226 | |||
227 | }; | ||
228 | |||
229 | /** | ||
230 | * struct tcf_ematch_ops - ematch module operations | ||
231 | * | ||
232 | * @kind: identifier (kind) of this ematch module | ||
233 | * @datalen: length of expected configuration data (optional) | ||
234 | * @change: called during validation (optional) | ||
235 | * @match: called during ematch tree evaluation, must return 1/0 | ||
236 | * @destroy: called during destroyage (optional) | ||
237 | * @dump: called during dumping process (optional) | ||
238 | * @owner: owner, must be set to THIS_MODULE | ||
239 | * @link: link to previous/next ematch module (internal use) | ||
240 | */ | ||
241 | struct tcf_ematch_ops | ||
242 | { | ||
243 | int kind; | ||
244 | int datalen; | ||
245 | int (*change)(struct tcf_proto *, void *, | ||
246 | int, struct tcf_ematch *); | ||
247 | int (*match)(struct sk_buff *, struct tcf_ematch *, | ||
248 | struct tcf_pkt_info *); | ||
249 | void (*destroy)(struct tcf_proto *, | ||
250 | struct tcf_ematch *); | ||
251 | int (*dump)(struct sk_buff *, struct tcf_ematch *); | ||
252 | struct module *owner; | ||
253 | struct list_head link; | ||
254 | }; | ||
255 | |||
256 | extern int tcf_em_register(struct tcf_ematch_ops *); | ||
257 | extern int tcf_em_unregister(struct tcf_ematch_ops *); | ||
258 | extern int tcf_em_tree_validate(struct tcf_proto *, struct rtattr *, | ||
259 | struct tcf_ematch_tree *); | ||
260 | extern void tcf_em_tree_destroy(struct tcf_proto *, struct tcf_ematch_tree *); | ||
261 | extern int tcf_em_tree_dump(struct sk_buff *, struct tcf_ematch_tree *, int); | ||
262 | extern int __tcf_em_tree_match(struct sk_buff *, struct tcf_ematch_tree *, | ||
263 | struct tcf_pkt_info *); | ||
264 | |||
265 | /** | ||
266 | * tcf_em_tree_change - replace ematch tree of a running classifier | ||
267 | * | ||
268 | * @tp: classifier kind handle | ||
269 | * @dst: destination ematch tree variable | ||
270 | * @src: source ematch tree (temporary tree from tcf_em_tree_validate) | ||
271 | * | ||
272 | * This functions replaces the ematch tree in @dst with the ematch | ||
273 | * tree in @src. The classifier in charge of the ematch tree may be | ||
274 | * running. | ||
275 | */ | ||
276 | static inline void tcf_em_tree_change(struct tcf_proto *tp, | ||
277 | struct tcf_ematch_tree *dst, | ||
278 | struct tcf_ematch_tree *src) | ||
279 | { | ||
280 | tcf_tree_lock(tp); | ||
281 | memcpy(dst, src, sizeof(*dst)); | ||
282 | tcf_tree_unlock(tp); | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * tcf_em_tree_match - evaulate an ematch tree | ||
287 | * | ||
288 | * @skb: socket buffer of the packet in question | ||
289 | * @tree: ematch tree to be used for evaluation | ||
290 | * @info: packet information examined by classifier | ||
291 | * | ||
292 | * This function matches @skb against the ematch tree in @tree by going | ||
293 | * through all ematches respecting their logic relations returning | ||
294 | * as soon as the result is obvious. | ||
295 | * | ||
296 | * Returns 1 if the ematch tree as-one matches, no ematches are configured | ||
297 | * or ematch is not enabled in the kernel, otherwise 0 is returned. | ||
298 | */ | ||
299 | static inline int tcf_em_tree_match(struct sk_buff *skb, | ||
300 | struct tcf_ematch_tree *tree, | ||
301 | struct tcf_pkt_info *info) | ||
302 | { | ||
303 | if (tree->hdr.nmatches) | ||
304 | return __tcf_em_tree_match(skb, tree, info); | ||
305 | else | ||
306 | return 1; | ||
307 | } | ||
308 | |||
309 | #else /* CONFIG_NET_EMATCH */ | ||
310 | |||
311 | struct tcf_ematch_tree | ||
312 | { | ||
313 | }; | ||
314 | |||
315 | #define tcf_em_tree_validate(tp, tb, t) ((void)(t), 0) | ||
316 | #define tcf_em_tree_destroy(tp, t) do { (void)(t); } while(0) | ||
317 | #define tcf_em_tree_dump(skb, t, tlv) (0) | ||
318 | #define tcf_em_tree_change(tp, dst, src) do { } while(0) | ||
319 | #define tcf_em_tree_match(skb, t, info) ((void)(info), 1) | ||
320 | |||
321 | #endif /* CONFIG_NET_EMATCH */ | ||
322 | |||
323 | static inline unsigned char * tcf_get_base_ptr(struct sk_buff *skb, int layer) | ||
324 | { | ||
325 | switch (layer) { | ||
326 | case TCF_LAYER_LINK: | ||
327 | return skb->data; | ||
328 | case TCF_LAYER_NETWORK: | ||
329 | return skb->nh.raw; | ||
330 | case TCF_LAYER_TRANSPORT: | ||
331 | return skb->h.raw; | ||
332 | } | ||
333 | |||
334 | return NULL; | ||
335 | } | ||
336 | |||
337 | static inline int tcf_valid_offset(struct sk_buff *skb, unsigned char *ptr, | ||
338 | int len) | ||
339 | { | ||
340 | return unlikely((ptr + len) < skb->tail && ptr > skb->head); | ||
341 | } | ||
342 | |||
343 | #ifdef CONFIG_NET_CLS_IND | ||
344 | static inline int | ||
345 | tcf_change_indev(struct tcf_proto *tp, char *indev, struct rtattr *indev_tlv) | ||
346 | { | ||
347 | if (rtattr_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ) | ||
348 | return -EINVAL; | ||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | static inline int | ||
353 | tcf_match_indev(struct sk_buff *skb, char *indev) | ||
354 | { | ||
355 | if (0 != indev[0]) { | ||
356 | if (NULL == skb->input_dev) | ||
357 | return 0; | ||
358 | else if (0 != strcmp(indev, skb->input_dev->name)) | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | return 1; | ||
363 | } | ||
364 | #endif /* CONFIG_NET_CLS_IND */ | ||
365 | |||
366 | #endif | ||
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h new file mode 100644 index 000000000000..87496e3aa330 --- /dev/null +++ b/include/net/pkt_sched.h | |||
@@ -0,0 +1,249 @@ | |||
1 | #ifndef __NET_PKT_SCHED_H | ||
2 | #define __NET_PKT_SCHED_H | ||
3 | |||
4 | #include <net/sch_generic.h> | ||
5 | |||
6 | struct qdisc_walker | ||
7 | { | ||
8 | int stop; | ||
9 | int skip; | ||
10 | int count; | ||
11 | int (*fn)(struct Qdisc *, unsigned long cl, struct qdisc_walker *); | ||
12 | }; | ||
13 | |||
14 | extern rwlock_t qdisc_tree_lock; | ||
15 | |||
16 | #define QDISC_ALIGN 32 | ||
17 | #define QDISC_ALIGN_CONST (QDISC_ALIGN - 1) | ||
18 | |||
19 | static inline void *qdisc_priv(struct Qdisc *q) | ||
20 | { | ||
21 | return (char *)q + ((sizeof(struct Qdisc) + QDISC_ALIGN_CONST) | ||
22 | & ~QDISC_ALIGN_CONST); | ||
23 | } | ||
24 | |||
25 | /* | ||
26 | Timer resolution MUST BE < 10% of min_schedulable_packet_size/bandwidth | ||
27 | |||
28 | Normal IP packet size ~ 512byte, hence: | ||
29 | |||
30 | 0.5Kbyte/1Mbyte/sec = 0.5msec, so that we need 50usec timer for | ||
31 | 10Mbit ethernet. | ||
32 | |||
33 | 10msec resolution -> <50Kbit/sec. | ||
34 | |||
35 | The result: [34]86 is not good choice for QoS router :-( | ||
36 | |||
37 | The things are not so bad, because we may use artifical | ||
38 | clock evaluated by integration of network data flow | ||
39 | in the most critical places. | ||
40 | |||
41 | Note: we do not use fastgettimeofday. | ||
42 | The reason is that, when it is not the same thing as | ||
43 | gettimeofday, it returns invalid timestamp, which is | ||
44 | not updated, when net_bh is active. | ||
45 | */ | ||
46 | |||
47 | /* General note about internal clock. | ||
48 | |||
49 | Any clock source returns time intervals, measured in units | ||
50 | close to 1usec. With source CONFIG_NET_SCH_CLK_GETTIMEOFDAY it is precisely | ||
51 | microseconds, otherwise something close but different chosen to minimize | ||
52 | arithmetic cost. Ratio usec/internal untis in form nominator/denominator | ||
53 | may be read from /proc/net/psched. | ||
54 | */ | ||
55 | |||
56 | |||
57 | #ifdef CONFIG_NET_SCH_CLK_GETTIMEOFDAY | ||
58 | |||
59 | typedef struct timeval psched_time_t; | ||
60 | typedef long psched_tdiff_t; | ||
61 | |||
62 | #define PSCHED_GET_TIME(stamp) do_gettimeofday(&(stamp)) | ||
63 | #define PSCHED_US2JIFFIE(usecs) (((usecs)+(1000000/HZ-1))/(1000000/HZ)) | ||
64 | #define PSCHED_JIFFIE2US(delay) ((delay)*(1000000/HZ)) | ||
65 | |||
66 | #else /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */ | ||
67 | |||
68 | typedef u64 psched_time_t; | ||
69 | typedef long psched_tdiff_t; | ||
70 | |||
71 | #ifdef CONFIG_NET_SCH_CLK_JIFFIES | ||
72 | |||
73 | #if HZ < 96 | ||
74 | #define PSCHED_JSCALE 14 | ||
75 | #elif HZ >= 96 && HZ < 192 | ||
76 | #define PSCHED_JSCALE 13 | ||
77 | #elif HZ >= 192 && HZ < 384 | ||
78 | #define PSCHED_JSCALE 12 | ||
79 | #elif HZ >= 384 && HZ < 768 | ||
80 | #define PSCHED_JSCALE 11 | ||
81 | #elif HZ >= 768 | ||
82 | #define PSCHED_JSCALE 10 | ||
83 | #endif | ||
84 | |||
85 | #define PSCHED_GET_TIME(stamp) ((stamp) = (get_jiffies_64()<<PSCHED_JSCALE)) | ||
86 | #define PSCHED_US2JIFFIE(delay) (((delay)+(1<<PSCHED_JSCALE)-1)>>PSCHED_JSCALE) | ||
87 | #define PSCHED_JIFFIE2US(delay) ((delay)<<PSCHED_JSCALE) | ||
88 | |||
89 | #endif /* CONFIG_NET_SCH_CLK_JIFFIES */ | ||
90 | #ifdef CONFIG_NET_SCH_CLK_CPU | ||
91 | #include <asm/timex.h> | ||
92 | |||
93 | extern psched_tdiff_t psched_clock_per_hz; | ||
94 | extern int psched_clock_scale; | ||
95 | extern psched_time_t psched_time_base; | ||
96 | extern cycles_t psched_time_mark; | ||
97 | |||
98 | #define PSCHED_GET_TIME(stamp) \ | ||
99 | do { \ | ||
100 | cycles_t cur = get_cycles(); \ | ||
101 | if (sizeof(cycles_t) == sizeof(u32)) { \ | ||
102 | if (cur <= psched_time_mark) \ | ||
103 | psched_time_base += 0x100000000ULL; \ | ||
104 | psched_time_mark = cur; \ | ||
105 | (stamp) = (psched_time_base + cur)>>psched_clock_scale; \ | ||
106 | } else { \ | ||
107 | (stamp) = cur>>psched_clock_scale; \ | ||
108 | } \ | ||
109 | } while (0) | ||
110 | #define PSCHED_US2JIFFIE(delay) (((delay)+psched_clock_per_hz-1)/psched_clock_per_hz) | ||
111 | #define PSCHED_JIFFIE2US(delay) ((delay)*psched_clock_per_hz) | ||
112 | |||
113 | #endif /* CONFIG_NET_SCH_CLK_CPU */ | ||
114 | |||
115 | #endif /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */ | ||
116 | |||
117 | #ifdef CONFIG_NET_SCH_CLK_GETTIMEOFDAY | ||
118 | #define PSCHED_TDIFF(tv1, tv2) \ | ||
119 | ({ \ | ||
120 | int __delta_sec = (tv1).tv_sec - (tv2).tv_sec; \ | ||
121 | int __delta = (tv1).tv_usec - (tv2).tv_usec; \ | ||
122 | if (__delta_sec) { \ | ||
123 | switch (__delta_sec) { \ | ||
124 | default: \ | ||
125 | __delta = 0; \ | ||
126 | case 2: \ | ||
127 | __delta += 1000000; \ | ||
128 | case 1: \ | ||
129 | __delta += 1000000; \ | ||
130 | } \ | ||
131 | } \ | ||
132 | __delta; \ | ||
133 | }) | ||
134 | |||
135 | static inline int | ||
136 | psched_tod_diff(int delta_sec, int bound) | ||
137 | { | ||
138 | int delta; | ||
139 | |||
140 | if (bound <= 1000000 || delta_sec > (0x7FFFFFFF/1000000)-1) | ||
141 | return bound; | ||
142 | delta = delta_sec * 1000000; | ||
143 | if (delta > bound) | ||
144 | delta = bound; | ||
145 | return delta; | ||
146 | } | ||
147 | |||
148 | #define PSCHED_TDIFF_SAFE(tv1, tv2, bound) \ | ||
149 | ({ \ | ||
150 | int __delta_sec = (tv1).tv_sec - (tv2).tv_sec; \ | ||
151 | int __delta = (tv1).tv_usec - (tv2).tv_usec; \ | ||
152 | switch (__delta_sec) { \ | ||
153 | default: \ | ||
154 | __delta = psched_tod_diff(__delta_sec, bound); break; \ | ||
155 | case 2: \ | ||
156 | __delta += 1000000; \ | ||
157 | case 1: \ | ||
158 | __delta += 1000000; \ | ||
159 | case 0: ; \ | ||
160 | } \ | ||
161 | __delta; \ | ||
162 | }) | ||
163 | |||
164 | #define PSCHED_TLESS(tv1, tv2) (((tv1).tv_usec < (tv2).tv_usec && \ | ||
165 | (tv1).tv_sec <= (tv2).tv_sec) || \ | ||
166 | (tv1).tv_sec < (tv2).tv_sec) | ||
167 | |||
168 | #define PSCHED_TADD2(tv, delta, tv_res) \ | ||
169 | ({ \ | ||
170 | int __delta = (tv).tv_usec + (delta); \ | ||
171 | (tv_res).tv_sec = (tv).tv_sec; \ | ||
172 | if (__delta > 1000000) { (tv_res).tv_sec++; __delta -= 1000000; } \ | ||
173 | (tv_res).tv_usec = __delta; \ | ||
174 | }) | ||
175 | |||
176 | #define PSCHED_TADD(tv, delta) \ | ||
177 | ({ \ | ||
178 | (tv).tv_usec += (delta); \ | ||
179 | if ((tv).tv_usec > 1000000) { (tv).tv_sec++; \ | ||
180 | (tv).tv_usec -= 1000000; } \ | ||
181 | }) | ||
182 | |||
183 | /* Set/check that time is in the "past perfect"; | ||
184 | it depends on concrete representation of system time | ||
185 | */ | ||
186 | |||
187 | #define PSCHED_SET_PASTPERFECT(t) ((t).tv_sec = 0) | ||
188 | #define PSCHED_IS_PASTPERFECT(t) ((t).tv_sec == 0) | ||
189 | |||
190 | #define PSCHED_AUDIT_TDIFF(t) ({ if ((t) > 2000000) (t) = 2000000; }) | ||
191 | |||
192 | #else /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */ | ||
193 | |||
194 | #define PSCHED_TDIFF(tv1, tv2) (long)((tv1) - (tv2)) | ||
195 | #define PSCHED_TDIFF_SAFE(tv1, tv2, bound) \ | ||
196 | min_t(long long, (tv1) - (tv2), bound) | ||
197 | |||
198 | |||
199 | #define PSCHED_TLESS(tv1, tv2) ((tv1) < (tv2)) | ||
200 | #define PSCHED_TADD2(tv, delta, tv_res) ((tv_res) = (tv) + (delta)) | ||
201 | #define PSCHED_TADD(tv, delta) ((tv) += (delta)) | ||
202 | #define PSCHED_SET_PASTPERFECT(t) ((t) = 0) | ||
203 | #define PSCHED_IS_PASTPERFECT(t) ((t) == 0) | ||
204 | #define PSCHED_AUDIT_TDIFF(t) | ||
205 | |||
206 | #endif /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */ | ||
207 | |||
208 | extern struct Qdisc noop_qdisc; | ||
209 | extern struct Qdisc_ops noop_qdisc_ops; | ||
210 | extern struct Qdisc_ops pfifo_qdisc_ops; | ||
211 | extern struct Qdisc_ops bfifo_qdisc_ops; | ||
212 | |||
213 | extern int register_qdisc(struct Qdisc_ops *qops); | ||
214 | extern int unregister_qdisc(struct Qdisc_ops *qops); | ||
215 | extern struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle); | ||
216 | extern struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle); | ||
217 | extern void dev_init_scheduler(struct net_device *dev); | ||
218 | extern void dev_shutdown(struct net_device *dev); | ||
219 | extern void dev_activate(struct net_device *dev); | ||
220 | extern void dev_deactivate(struct net_device *dev); | ||
221 | extern void qdisc_reset(struct Qdisc *qdisc); | ||
222 | extern void qdisc_destroy(struct Qdisc *qdisc); | ||
223 | extern struct Qdisc * qdisc_create_dflt(struct net_device *dev, | ||
224 | struct Qdisc_ops *ops); | ||
225 | extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, | ||
226 | struct rtattr *tab); | ||
227 | extern void qdisc_put_rtab(struct qdisc_rate_table *tab); | ||
228 | |||
229 | extern int qdisc_restart(struct net_device *dev); | ||
230 | |||
231 | static inline void qdisc_run(struct net_device *dev) | ||
232 | { | ||
233 | while (!netif_queue_stopped(dev) && qdisc_restart(dev) < 0) | ||
234 | /* NOTHING */; | ||
235 | } | ||
236 | |||
237 | extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp, | ||
238 | struct tcf_result *res); | ||
239 | |||
240 | /* Calculate maximal size of packet seen by hard_start_xmit | ||
241 | routine of this device. | ||
242 | */ | ||
243 | static inline unsigned psched_mtu(struct net_device *dev) | ||
244 | { | ||
245 | unsigned mtu = dev->mtu; | ||
246 | return dev->hard_header ? mtu + dev->hard_header_len : mtu; | ||
247 | } | ||
248 | |||
249 | #endif | ||
diff --git a/include/net/protocol.h b/include/net/protocol.h new file mode 100644 index 000000000000..357691f6a45f --- /dev/null +++ b/include/net/protocol.h | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * INET An implementation of the TCP/IP protocol suite for the LINUX | ||
3 | * operating system. INET is implemented using the BSD Socket | ||
4 | * interface as the means of communication with the user level. | ||
5 | * | ||
6 | * Definitions for the protocol dispatcher. | ||
7 | * | ||
8 | * Version: @(#)protocol.h 1.0.2 05/07/93 | ||
9 | * | ||
10 | * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version | ||
15 | * 2 of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * Changes: | ||
18 | * Alan Cox : Added a name field and a frag handler | ||
19 | * field for later. | ||
20 | * Alan Cox : Cleaned up, and sorted types. | ||
21 | * Pedro Roque : inet6 protocols | ||
22 | */ | ||
23 | |||
24 | #ifndef _PROTOCOL_H | ||
25 | #define _PROTOCOL_H | ||
26 | |||
27 | #include <linux/config.h> | ||
28 | #include <linux/in6.h> | ||
29 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | ||
30 | #include <linux/ipv6.h> | ||
31 | #endif | ||
32 | |||
33 | #define MAX_INET_PROTOS 256 /* Must be a power of 2 */ | ||
34 | |||
35 | |||
36 | /* This is used to register protocols. */ | ||
37 | struct net_protocol { | ||
38 | int (*handler)(struct sk_buff *skb); | ||
39 | void (*err_handler)(struct sk_buff *skb, u32 info); | ||
40 | int no_policy; | ||
41 | }; | ||
42 | |||
43 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | ||
44 | struct inet6_protocol | ||
45 | { | ||
46 | int (*handler)(struct sk_buff **skb, unsigned int *nhoffp); | ||
47 | |||
48 | void (*err_handler)(struct sk_buff *skb, | ||
49 | struct inet6_skb_parm *opt, | ||
50 | int type, int code, int offset, | ||
51 | __u32 info); | ||
52 | unsigned int flags; /* INET6_PROTO_xxx */ | ||
53 | }; | ||
54 | |||
55 | #define INET6_PROTO_NOPOLICY 0x1 | ||
56 | #define INET6_PROTO_FINAL 0x2 | ||
57 | #endif | ||
58 | |||
59 | /* This is used to register socket interfaces for IP protocols. */ | ||
60 | struct inet_protosw { | ||
61 | struct list_head list; | ||
62 | |||
63 | /* These two fields form the lookup key. */ | ||
64 | unsigned short type; /* This is the 2nd argument to socket(2). */ | ||
65 | int protocol; /* This is the L4 protocol number. */ | ||
66 | |||
67 | struct proto *prot; | ||
68 | struct proto_ops *ops; | ||
69 | |||
70 | int capability; /* Which (if any) capability do | ||
71 | * we need to use this socket | ||
72 | * interface? | ||
73 | */ | ||
74 | char no_check; /* checksum on rcv/xmit/none? */ | ||
75 | unsigned char flags; /* See INET_PROTOSW_* below. */ | ||
76 | }; | ||
77 | #define INET_PROTOSW_REUSE 0x01 /* Are ports automatically reusable? */ | ||
78 | #define INET_PROTOSW_PERMANENT 0x02 /* Permanent protocols are unremovable. */ | ||
79 | |||
80 | extern struct net_protocol *inet_protocol_base; | ||
81 | extern struct net_protocol *inet_protos[MAX_INET_PROTOS]; | ||
82 | |||
83 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | ||
84 | extern struct inet6_protocol *inet6_protos[MAX_INET_PROTOS]; | ||
85 | #endif | ||
86 | |||
87 | extern int inet_add_protocol(struct net_protocol *prot, unsigned char num); | ||
88 | extern int inet_del_protocol(struct net_protocol *prot, unsigned char num); | ||
89 | extern void inet_register_protosw(struct inet_protosw *p); | ||
90 | extern void inet_unregister_protosw(struct inet_protosw *p); | ||
91 | |||
92 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | ||
93 | extern int inet6_add_protocol(struct inet6_protocol *prot, unsigned char num); | ||
94 | extern int inet6_del_protocol(struct inet6_protocol *prot, unsigned char num); | ||
95 | extern void inet6_register_protosw(struct inet_protosw *p); | ||
96 | extern void inet6_unregister_protosw(struct inet_protosw *p); | ||
97 | #endif | ||
98 | |||
99 | #endif /* _PROTOCOL_H */ | ||
diff --git a/include/net/psnap.h b/include/net/psnap.h new file mode 100644 index 000000000000..9c94e8f98b36 --- /dev/null +++ b/include/net/psnap.h | |||
@@ -0,0 +1,7 @@ | |||
1 | #ifndef _NET_PSNAP_H | ||
2 | #define _NET_PSNAP_H | ||
3 | |||
4 | extern struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct net_device *, struct packet_type *)); | ||
5 | extern void unregister_snap_client(struct datalink_proto *proto); | ||
6 | |||
7 | #endif | ||
diff --git a/include/net/raw.h b/include/net/raw.h new file mode 100644 index 000000000000..1c411c45587a --- /dev/null +++ b/include/net/raw.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * INET An implementation of the TCP/IP protocol suite for the LINUX | ||
3 | * operating system. INET is implemented using the BSD Socket | ||
4 | * interface as the means of communication with the user level. | ||
5 | * | ||
6 | * Definitions for the RAW-IP module. | ||
7 | * | ||
8 | * Version: @(#)raw.h 1.0.2 05/07/93 | ||
9 | * | ||
10 | * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version | ||
15 | * 2 of the License, or (at your option) any later version. | ||
16 | */ | ||
17 | #ifndef _RAW_H | ||
18 | #define _RAW_H | ||
19 | |||
20 | |||
21 | extern struct proto raw_prot; | ||
22 | |||
23 | |||
24 | extern void raw_err(struct sock *, struct sk_buff *, u32 info); | ||
25 | extern int raw_rcv(struct sock *, struct sk_buff *); | ||
26 | |||
27 | /* Note: v4 ICMP wants to get at this stuff, if you change the | ||
28 | * hashing mechanism, make sure you update icmp.c as well. | ||
29 | */ | ||
30 | #define RAWV4_HTABLE_SIZE MAX_INET_PROTOS | ||
31 | extern struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE]; | ||
32 | |||
33 | extern rwlock_t raw_v4_lock; | ||
34 | |||
35 | |||
36 | extern struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, | ||
37 | unsigned long raddr, unsigned long laddr, | ||
38 | int dif); | ||
39 | |||
40 | extern void raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash); | ||
41 | |||
42 | #endif /* _RAW_H */ | ||
diff --git a/include/net/rawv6.h b/include/net/rawv6.h new file mode 100644 index 000000000000..23fd9a6a221a --- /dev/null +++ b/include/net/rawv6.h | |||
@@ -0,0 +1,27 @@ | |||
1 | #ifndef _NET_RAWV6_H | ||
2 | #define _NET_RAWV6_H | ||
3 | |||
4 | #ifdef __KERNEL__ | ||
5 | |||
6 | #define RAWV6_HTABLE_SIZE MAX_INET_PROTOS | ||
7 | extern struct hlist_head raw_v6_htable[RAWV6_HTABLE_SIZE]; | ||
8 | extern rwlock_t raw_v6_lock; | ||
9 | |||
10 | extern void ipv6_raw_deliver(struct sk_buff *skb, int nexthdr); | ||
11 | |||
12 | extern struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num, | ||
13 | struct in6_addr *loc_addr, struct in6_addr *rmt_addr); | ||
14 | |||
15 | extern int rawv6_rcv(struct sock *sk, | ||
16 | struct sk_buff *skb); | ||
17 | |||
18 | |||
19 | extern void rawv6_err(struct sock *sk, | ||
20 | struct sk_buff *skb, | ||
21 | struct inet6_skb_parm *opt, | ||
22 | int type, int code, | ||
23 | int offset, u32 info); | ||
24 | |||
25 | #endif | ||
26 | |||
27 | #endif | ||
diff --git a/include/net/rose.h b/include/net/rose.h new file mode 100644 index 000000000000..3249b979605a --- /dev/null +++ b/include/net/rose.h | |||
@@ -0,0 +1,235 @@ | |||
1 | /* | ||
2 | * Declarations of Rose type objects. | ||
3 | * | ||
4 | * Jonathan Naylor G4KLX 25/8/96 | ||
5 | */ | ||
6 | |||
7 | #ifndef _ROSE_H | ||
8 | #define _ROSE_H | ||
9 | |||
10 | #include <linux/rose.h> | ||
11 | #include <net/sock.h> | ||
12 | |||
13 | #define ROSE_ADDR_LEN 5 | ||
14 | |||
15 | #define ROSE_MIN_LEN 3 | ||
16 | |||
17 | #define ROSE_GFI 0x10 | ||
18 | #define ROSE_Q_BIT 0x80 | ||
19 | #define ROSE_D_BIT 0x40 | ||
20 | #define ROSE_M_BIT 0x10 | ||
21 | |||
22 | #define ROSE_CALL_REQUEST 0x0B | ||
23 | #define ROSE_CALL_ACCEPTED 0x0F | ||
24 | #define ROSE_CLEAR_REQUEST 0x13 | ||
25 | #define ROSE_CLEAR_CONFIRMATION 0x17 | ||
26 | #define ROSE_DATA 0x00 | ||
27 | #define ROSE_INTERRUPT 0x23 | ||
28 | #define ROSE_INTERRUPT_CONFIRMATION 0x27 | ||
29 | #define ROSE_RR 0x01 | ||
30 | #define ROSE_RNR 0x05 | ||
31 | #define ROSE_REJ 0x09 | ||
32 | #define ROSE_RESET_REQUEST 0x1B | ||
33 | #define ROSE_RESET_CONFIRMATION 0x1F | ||
34 | #define ROSE_REGISTRATION_REQUEST 0xF3 | ||
35 | #define ROSE_REGISTRATION_CONFIRMATION 0xF7 | ||
36 | #define ROSE_RESTART_REQUEST 0xFB | ||
37 | #define ROSE_RESTART_CONFIRMATION 0xFF | ||
38 | #define ROSE_DIAGNOSTIC 0xF1 | ||
39 | #define ROSE_ILLEGAL 0xFD | ||
40 | |||
41 | /* Define Link State constants. */ | ||
42 | |||
43 | enum { | ||
44 | ROSE_STATE_0, /* Ready */ | ||
45 | ROSE_STATE_1, /* Awaiting Call Accepted */ | ||
46 | ROSE_STATE_2, /* Awaiting Clear Confirmation */ | ||
47 | ROSE_STATE_3, /* Data Transfer */ | ||
48 | ROSE_STATE_4, /* Awaiting Reset Confirmation */ | ||
49 | ROSE_STATE_5 /* Deferred Call Acceptance */ | ||
50 | }; | ||
51 | |||
52 | #define ROSE_DEFAULT_T0 (180 * HZ) /* Default T10 T20 value */ | ||
53 | #define ROSE_DEFAULT_T1 (200 * HZ) /* Default T11 T21 value */ | ||
54 | #define ROSE_DEFAULT_T2 (180 * HZ) /* Default T12 T22 value */ | ||
55 | #define ROSE_DEFAULT_T3 (180 * HZ) /* Default T13 T23 value */ | ||
56 | #define ROSE_DEFAULT_HB (5 * HZ) /* Default Holdback value */ | ||
57 | #define ROSE_DEFAULT_IDLE (0 * 60 * HZ) /* No Activity Timeout - none */ | ||
58 | #define ROSE_DEFAULT_ROUTING 1 /* Default routing flag */ | ||
59 | #define ROSE_DEFAULT_FAIL_TIMEOUT (120 * HZ) /* Time until link considered usable */ | ||
60 | #define ROSE_DEFAULT_MAXVC 50 /* Maximum number of VCs per neighbour */ | ||
61 | #define ROSE_DEFAULT_WINDOW_SIZE 7 /* Default window size */ | ||
62 | |||
63 | #define ROSE_MODULUS 8 | ||
64 | #define ROSE_MAX_PACKET_SIZE 251 /* Maximum packet size */ | ||
65 | |||
66 | #define ROSE_COND_ACK_PENDING 0x01 | ||
67 | #define ROSE_COND_PEER_RX_BUSY 0x02 | ||
68 | #define ROSE_COND_OWN_RX_BUSY 0x04 | ||
69 | |||
70 | #define FAC_NATIONAL 0x00 | ||
71 | #define FAC_CCITT 0x0F | ||
72 | |||
73 | #define FAC_NATIONAL_RAND 0x7F | ||
74 | #define FAC_NATIONAL_FLAGS 0x3F | ||
75 | #define FAC_NATIONAL_DEST_DIGI 0xE9 | ||
76 | #define FAC_NATIONAL_SRC_DIGI 0xEB | ||
77 | #define FAC_NATIONAL_FAIL_CALL 0xED | ||
78 | #define FAC_NATIONAL_FAIL_ADD 0xEE | ||
79 | #define FAC_NATIONAL_DIGIS 0xEF | ||
80 | |||
81 | #define FAC_CCITT_DEST_NSAP 0xC9 | ||
82 | #define FAC_CCITT_SRC_NSAP 0xCB | ||
83 | |||
84 | struct rose_neigh { | ||
85 | struct rose_neigh *next; | ||
86 | ax25_address callsign; | ||
87 | ax25_digi *digipeat; | ||
88 | ax25_cb *ax25; | ||
89 | struct net_device *dev; | ||
90 | unsigned short count; | ||
91 | unsigned short use; | ||
92 | unsigned int number; | ||
93 | char restarted; | ||
94 | char dce_mode; | ||
95 | char loopback; | ||
96 | struct sk_buff_head queue; | ||
97 | struct timer_list t0timer; | ||
98 | struct timer_list ftimer; | ||
99 | }; | ||
100 | |||
101 | struct rose_node { | ||
102 | struct rose_node *next; | ||
103 | rose_address address; | ||
104 | unsigned short mask; | ||
105 | unsigned char count; | ||
106 | char loopback; | ||
107 | struct rose_neigh *neighbour[3]; | ||
108 | }; | ||
109 | |||
110 | struct rose_route { | ||
111 | struct rose_route *next; | ||
112 | unsigned int lci1, lci2; | ||
113 | rose_address src_addr, dest_addr; | ||
114 | ax25_address src_call, dest_call; | ||
115 | struct rose_neigh *neigh1, *neigh2; | ||
116 | unsigned int rand; | ||
117 | }; | ||
118 | |||
119 | struct rose_sock { | ||
120 | struct sock sock; | ||
121 | rose_address source_addr, dest_addr; | ||
122 | ax25_address source_call, dest_call; | ||
123 | unsigned char source_ndigis, dest_ndigis; | ||
124 | ax25_address source_digis[ROSE_MAX_DIGIS]; | ||
125 | ax25_address dest_digis[ROSE_MAX_DIGIS]; | ||
126 | struct rose_neigh *neighbour; | ||
127 | struct net_device *device; | ||
128 | unsigned int lci, rand; | ||
129 | unsigned char state, condition, qbitincl, defer; | ||
130 | unsigned char cause, diagnostic; | ||
131 | unsigned short vs, vr, va, vl; | ||
132 | unsigned long t1, t2, t3, hb, idle; | ||
133 | #ifdef M_BIT | ||
134 | unsigned short fraglen; | ||
135 | struct sk_buff_head frag_queue; | ||
136 | #endif | ||
137 | struct sk_buff_head ack_queue; | ||
138 | struct rose_facilities_struct facilities; | ||
139 | struct timer_list timer; | ||
140 | struct timer_list idletimer; | ||
141 | }; | ||
142 | |||
143 | #define rose_sk(sk) ((struct rose_sock *)(sk)) | ||
144 | |||
145 | /* af_rose.c */ | ||
146 | extern ax25_address rose_callsign; | ||
147 | extern int sysctl_rose_restart_request_timeout; | ||
148 | extern int sysctl_rose_call_request_timeout; | ||
149 | extern int sysctl_rose_reset_request_timeout; | ||
150 | extern int sysctl_rose_clear_request_timeout; | ||
151 | extern int sysctl_rose_no_activity_timeout; | ||
152 | extern int sysctl_rose_ack_hold_back_timeout; | ||
153 | extern int sysctl_rose_routing_control; | ||
154 | extern int sysctl_rose_link_fail_timeout; | ||
155 | extern int sysctl_rose_maximum_vcs; | ||
156 | extern int sysctl_rose_window_size; | ||
157 | extern int rosecmp(rose_address *, rose_address *); | ||
158 | extern int rosecmpm(rose_address *, rose_address *, unsigned short); | ||
159 | extern const char *rose2asc(const rose_address *); | ||
160 | extern struct sock *rose_find_socket(unsigned int, struct rose_neigh *); | ||
161 | extern void rose_kill_by_neigh(struct rose_neigh *); | ||
162 | extern unsigned int rose_new_lci(struct rose_neigh *); | ||
163 | extern int rose_rx_call_request(struct sk_buff *, struct net_device *, struct rose_neigh *, unsigned int); | ||
164 | extern void rose_destroy_socket(struct sock *); | ||
165 | |||
166 | /* rose_dev.c */ | ||
167 | extern void rose_setup(struct net_device *); | ||
168 | |||
169 | /* rose_in.c */ | ||
170 | extern int rose_process_rx_frame(struct sock *, struct sk_buff *); | ||
171 | |||
172 | /* rose_link.c */ | ||
173 | extern void rose_start_ftimer(struct rose_neigh *); | ||
174 | extern void rose_stop_ftimer(struct rose_neigh *); | ||
175 | extern void rose_stop_t0timer(struct rose_neigh *); | ||
176 | extern int rose_ftimer_running(struct rose_neigh *); | ||
177 | extern void rose_link_rx_restart(struct sk_buff *, struct rose_neigh *, unsigned short); | ||
178 | extern void rose_transmit_clear_request(struct rose_neigh *, unsigned int, unsigned char, unsigned char); | ||
179 | extern void rose_transmit_link(struct sk_buff *, struct rose_neigh *); | ||
180 | |||
181 | /* rose_loopback.c */ | ||
182 | extern void rose_loopback_init(void); | ||
183 | extern void rose_loopback_clear(void); | ||
184 | extern int rose_loopback_queue(struct sk_buff *, struct rose_neigh *); | ||
185 | |||
186 | /* rose_out.c */ | ||
187 | extern void rose_kick(struct sock *); | ||
188 | extern void rose_enquiry_response(struct sock *); | ||
189 | |||
190 | /* rose_route.c */ | ||
191 | extern struct rose_neigh *rose_loopback_neigh; | ||
192 | extern struct file_operations rose_neigh_fops; | ||
193 | extern struct file_operations rose_nodes_fops; | ||
194 | extern struct file_operations rose_routes_fops; | ||
195 | |||
196 | extern int rose_add_loopback_neigh(void); | ||
197 | extern int rose_add_loopback_node(rose_address *); | ||
198 | extern void rose_del_loopback_node(rose_address *); | ||
199 | extern void rose_rt_device_down(struct net_device *); | ||
200 | extern void rose_link_device_down(struct net_device *); | ||
201 | extern struct net_device *rose_dev_first(void); | ||
202 | extern struct net_device *rose_dev_get(rose_address *); | ||
203 | extern struct rose_route *rose_route_free_lci(unsigned int, struct rose_neigh *); | ||
204 | extern struct rose_neigh *rose_get_neigh(rose_address *, unsigned char *, unsigned char *); | ||
205 | extern int rose_rt_ioctl(unsigned int, void __user *); | ||
206 | extern void rose_link_failed(ax25_cb *, int); | ||
207 | extern int rose_route_frame(struct sk_buff *, ax25_cb *); | ||
208 | extern void rose_rt_free(void); | ||
209 | |||
210 | /* rose_subr.c */ | ||
211 | extern void rose_clear_queues(struct sock *); | ||
212 | extern void rose_frames_acked(struct sock *, unsigned short); | ||
213 | extern void rose_requeue_frames(struct sock *); | ||
214 | extern int rose_validate_nr(struct sock *, unsigned short); | ||
215 | extern void rose_write_internal(struct sock *, int); | ||
216 | extern int rose_decode(struct sk_buff *, int *, int *, int *, int *, int *); | ||
217 | extern int rose_parse_facilities(unsigned char *, struct rose_facilities_struct *); | ||
218 | extern void rose_disconnect(struct sock *, int, int, int); | ||
219 | |||
220 | /* rose_timer.c */ | ||
221 | extern void rose_start_heartbeat(struct sock *); | ||
222 | extern void rose_start_t1timer(struct sock *); | ||
223 | extern void rose_start_t2timer(struct sock *); | ||
224 | extern void rose_start_t3timer(struct sock *); | ||
225 | extern void rose_start_hbtimer(struct sock *); | ||
226 | extern void rose_start_idletimer(struct sock *); | ||
227 | extern void rose_stop_heartbeat(struct sock *); | ||
228 | extern void rose_stop_timer(struct sock *); | ||
229 | extern void rose_stop_idletimer(struct sock *); | ||
230 | |||
231 | /* sysctl_net_rose.c */ | ||
232 | extern void rose_register_sysctl(void); | ||
233 | extern void rose_unregister_sysctl(void); | ||
234 | |||
235 | #endif | ||
diff --git a/include/net/route.h b/include/net/route.h new file mode 100644 index 000000000000..22da7579d5de --- /dev/null +++ b/include/net/route.h | |||
@@ -0,0 +1,205 @@ | |||
1 | /* | ||
2 | * INET An implementation of the TCP/IP protocol suite for the LINUX | ||
3 | * operating system. INET is implemented using the BSD Socket | ||
4 | * interface as the means of communication with the user level. | ||
5 | * | ||
6 | * Definitions for the IP router. | ||
7 | * | ||
8 | * Version: @(#)route.h 1.0.4 05/27/93 | ||
9 | * | ||
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | ||
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | ||
12 | * Fixes: | ||
13 | * Alan Cox : Reformatted. Added ip_rt_local() | ||
14 | * Alan Cox : Support for TCP parameters. | ||
15 | * Alexey Kuznetsov: Major changes for new routing code. | ||
16 | * Mike McLagan : Routing by source | ||
17 | * Robert Olsson : Added rt_cache statistics | ||
18 | * | ||
19 | * This program is free software; you can redistribute it and/or | ||
20 | * modify it under the terms of the GNU General Public License | ||
21 | * as published by the Free Software Foundation; either version | ||
22 | * 2 of the License, or (at your option) any later version. | ||
23 | */ | ||
24 | #ifndef _ROUTE_H | ||
25 | #define _ROUTE_H | ||
26 | |||
27 | #include <linux/config.h> | ||
28 | #include <net/dst.h> | ||
29 | #include <net/inetpeer.h> | ||
30 | #include <net/flow.h> | ||
31 | #include <linux/in_route.h> | ||
32 | #include <linux/rtnetlink.h> | ||
33 | #include <linux/route.h> | ||
34 | #include <linux/ip.h> | ||
35 | #include <linux/cache.h> | ||
36 | |||
37 | #ifndef __KERNEL__ | ||
38 | #warning This file is not supposed to be used outside of kernel. | ||
39 | #endif | ||
40 | |||
41 | #define RTO_ONLINK 0x01 | ||
42 | |||
43 | #define RTO_CONN 0 | ||
44 | /* RTO_CONN is not used (being alias for 0), but preserved not to break | ||
45 | * some modules referring to it. */ | ||
46 | |||
47 | #define RT_CONN_FLAGS(sk) (RT_TOS(inet_sk(sk)->tos) | sock_flag(sk, SOCK_LOCALROUTE)) | ||
48 | |||
49 | struct fib_nh; | ||
50 | struct inet_peer; | ||
51 | struct rtable | ||
52 | { | ||
53 | union | ||
54 | { | ||
55 | struct dst_entry dst; | ||
56 | struct rtable *rt_next; | ||
57 | } u; | ||
58 | |||
59 | struct in_device *idev; | ||
60 | |||
61 | unsigned rt_flags; | ||
62 | __u16 rt_type; | ||
63 | __u16 rt_multipath_alg; | ||
64 | |||
65 | __u32 rt_dst; /* Path destination */ | ||
66 | __u32 rt_src; /* Path source */ | ||
67 | int rt_iif; | ||
68 | |||
69 | /* Info on neighbour */ | ||
70 | __u32 rt_gateway; | ||
71 | |||
72 | /* Cache lookup keys */ | ||
73 | struct flowi fl; | ||
74 | |||
75 | /* Miscellaneous cached information */ | ||
76 | __u32 rt_spec_dst; /* RFC1122 specific destination */ | ||
77 | struct inet_peer *peer; /* long-living peer info */ | ||
78 | }; | ||
79 | |||
80 | struct ip_rt_acct | ||
81 | { | ||
82 | __u32 o_bytes; | ||
83 | __u32 o_packets; | ||
84 | __u32 i_bytes; | ||
85 | __u32 i_packets; | ||
86 | }; | ||
87 | |||
88 | struct rt_cache_stat | ||
89 | { | ||
90 | unsigned int in_hit; | ||
91 | unsigned int in_slow_tot; | ||
92 | unsigned int in_slow_mc; | ||
93 | unsigned int in_no_route; | ||
94 | unsigned int in_brd; | ||
95 | unsigned int in_martian_dst; | ||
96 | unsigned int in_martian_src; | ||
97 | unsigned int out_hit; | ||
98 | unsigned int out_slow_tot; | ||
99 | unsigned int out_slow_mc; | ||
100 | unsigned int gc_total; | ||
101 | unsigned int gc_ignored; | ||
102 | unsigned int gc_goal_miss; | ||
103 | unsigned int gc_dst_overflow; | ||
104 | unsigned int in_hlist_search; | ||
105 | unsigned int out_hlist_search; | ||
106 | }; | ||
107 | |||
108 | extern struct rt_cache_stat *rt_cache_stat; | ||
109 | #define RT_CACHE_STAT_INC(field) \ | ||
110 | (per_cpu_ptr(rt_cache_stat, _smp_processor_id())->field++) | ||
111 | |||
112 | extern struct ip_rt_acct *ip_rt_acct; | ||
113 | |||
114 | struct in_device; | ||
115 | extern int ip_rt_init(void); | ||
116 | extern void ip_rt_redirect(u32 old_gw, u32 dst, u32 new_gw, | ||
117 | u32 src, u8 tos, struct net_device *dev); | ||
118 | extern void ip_rt_advice(struct rtable **rp, int advice); | ||
119 | extern void rt_cache_flush(int how); | ||
120 | extern int __ip_route_output_key(struct rtable **, const struct flowi *flp); | ||
121 | extern int ip_route_output_key(struct rtable **, struct flowi *flp); | ||
122 | extern int ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk, int flags); | ||
123 | extern int ip_route_input(struct sk_buff*, u32 dst, u32 src, u8 tos, struct net_device *devin); | ||
124 | extern unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu); | ||
125 | extern void ip_rt_send_redirect(struct sk_buff *skb); | ||
126 | |||
127 | extern unsigned inet_addr_type(u32 addr); | ||
128 | extern void ip_rt_multicast_event(struct in_device *); | ||
129 | extern int ip_rt_ioctl(unsigned int cmd, void __user *arg); | ||
130 | extern void ip_rt_get_source(u8 *src, struct rtable *rt); | ||
131 | extern int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb); | ||
132 | |||
133 | static inline void ip_rt_put(struct rtable * rt) | ||
134 | { | ||
135 | if (rt) | ||
136 | dst_release(&rt->u.dst); | ||
137 | } | ||
138 | |||
139 | #define IPTOS_RT_MASK (IPTOS_TOS_MASK & ~3) | ||
140 | |||
141 | extern __u8 ip_tos2prio[16]; | ||
142 | |||
143 | static inline char rt_tos2priority(u8 tos) | ||
144 | { | ||
145 | return ip_tos2prio[IPTOS_TOS(tos)>>1]; | ||
146 | } | ||
147 | |||
148 | static inline int ip_route_connect(struct rtable **rp, u32 dst, | ||
149 | u32 src, u32 tos, int oif, u8 protocol, | ||
150 | u16 sport, u16 dport, struct sock *sk) | ||
151 | { | ||
152 | struct flowi fl = { .oif = oif, | ||
153 | .nl_u = { .ip4_u = { .daddr = dst, | ||
154 | .saddr = src, | ||
155 | .tos = tos } }, | ||
156 | .proto = protocol, | ||
157 | .uli_u = { .ports = | ||
158 | { .sport = sport, | ||
159 | .dport = dport } } }; | ||
160 | |||
161 | int err; | ||
162 | if (!dst || !src) { | ||
163 | err = __ip_route_output_key(rp, &fl); | ||
164 | if (err) | ||
165 | return err; | ||
166 | fl.fl4_dst = (*rp)->rt_dst; | ||
167 | fl.fl4_src = (*rp)->rt_src; | ||
168 | ip_rt_put(*rp); | ||
169 | *rp = NULL; | ||
170 | } | ||
171 | return ip_route_output_flow(rp, &fl, sk, 0); | ||
172 | } | ||
173 | |||
174 | static inline int ip_route_newports(struct rtable **rp, u16 sport, u16 dport, | ||
175 | struct sock *sk) | ||
176 | { | ||
177 | if (sport != (*rp)->fl.fl_ip_sport || | ||
178 | dport != (*rp)->fl.fl_ip_dport) { | ||
179 | struct flowi fl; | ||
180 | |||
181 | memcpy(&fl, &(*rp)->fl, sizeof(fl)); | ||
182 | fl.fl_ip_sport = sport; | ||
183 | fl.fl_ip_dport = dport; | ||
184 | #if defined(CONFIG_IP_ROUTE_MULTIPATH_CACHED) | ||
185 | fl.flags |= FLOWI_FLAG_MULTIPATHOLDROUTE; | ||
186 | #endif | ||
187 | ip_rt_put(*rp); | ||
188 | *rp = NULL; | ||
189 | return ip_route_output_flow(rp, &fl, sk, 0); | ||
190 | } | ||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | extern void rt_bind_peer(struct rtable *rt, int create); | ||
195 | |||
196 | static inline struct inet_peer *rt_get_peer(struct rtable *rt) | ||
197 | { | ||
198 | if (rt->peer) | ||
199 | return rt->peer; | ||
200 | |||
201 | rt_bind_peer(rt, 0); | ||
202 | return rt->peer; | ||
203 | } | ||
204 | |||
205 | #endif /* _ROUTE_H */ | ||
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h new file mode 100644 index 000000000000..c57504b3b518 --- /dev/null +++ b/include/net/sch_generic.h | |||
@@ -0,0 +1,175 @@ | |||
1 | #ifndef __NET_SCHED_GENERIC_H | ||
2 | #define __NET_SCHED_GENERIC_H | ||
3 | |||
4 | #include <linux/config.h> | ||
5 | #include <linux/netdevice.h> | ||
6 | #include <linux/types.h> | ||
7 | #include <linux/rcupdate.h> | ||
8 | #include <linux/module.h> | ||
9 | #include <linux/rtnetlink.h> | ||
10 | #include <linux/pkt_sched.h> | ||
11 | #include <linux/pkt_cls.h> | ||
12 | #include <net/gen_stats.h> | ||
13 | |||
14 | struct Qdisc_ops; | ||
15 | struct qdisc_walker; | ||
16 | struct tcf_walker; | ||
17 | struct module; | ||
18 | |||
19 | struct qdisc_rate_table | ||
20 | { | ||
21 | struct tc_ratespec rate; | ||
22 | u32 data[256]; | ||
23 | struct qdisc_rate_table *next; | ||
24 | int refcnt; | ||
25 | }; | ||
26 | |||
27 | struct Qdisc | ||
28 | { | ||
29 | int (*enqueue)(struct sk_buff *skb, struct Qdisc *dev); | ||
30 | struct sk_buff * (*dequeue)(struct Qdisc *dev); | ||
31 | unsigned flags; | ||
32 | #define TCQ_F_BUILTIN 1 | ||
33 | #define TCQ_F_THROTTLED 2 | ||
34 | #define TCQ_F_INGRESS 4 | ||
35 | int padded; | ||
36 | struct Qdisc_ops *ops; | ||
37 | u32 handle; | ||
38 | u32 parent; | ||
39 | atomic_t refcnt; | ||
40 | struct sk_buff_head q; | ||
41 | struct net_device *dev; | ||
42 | struct list_head list; | ||
43 | |||
44 | struct gnet_stats_basic bstats; | ||
45 | struct gnet_stats_queue qstats; | ||
46 | struct gnet_stats_rate_est rate_est; | ||
47 | spinlock_t *stats_lock; | ||
48 | struct rcu_head q_rcu; | ||
49 | int (*reshape_fail)(struct sk_buff *skb, | ||
50 | struct Qdisc *q); | ||
51 | |||
52 | /* This field is deprecated, but it is still used by CBQ | ||
53 | * and it will live until better solution will be invented. | ||
54 | */ | ||
55 | struct Qdisc *__parent; | ||
56 | }; | ||
57 | |||
58 | struct Qdisc_class_ops | ||
59 | { | ||
60 | /* Child qdisc manipulation */ | ||
61 | int (*graft)(struct Qdisc *, unsigned long cl, | ||
62 | struct Qdisc *, struct Qdisc **); | ||
63 | struct Qdisc * (*leaf)(struct Qdisc *, unsigned long cl); | ||
64 | |||
65 | /* Class manipulation routines */ | ||
66 | unsigned long (*get)(struct Qdisc *, u32 classid); | ||
67 | void (*put)(struct Qdisc *, unsigned long); | ||
68 | int (*change)(struct Qdisc *, u32, u32, | ||
69 | struct rtattr **, unsigned long *); | ||
70 | int (*delete)(struct Qdisc *, unsigned long); | ||
71 | void (*walk)(struct Qdisc *, struct qdisc_walker * arg); | ||
72 | |||
73 | /* Filter manipulation */ | ||
74 | struct tcf_proto ** (*tcf_chain)(struct Qdisc *, unsigned long); | ||
75 | unsigned long (*bind_tcf)(struct Qdisc *, unsigned long, | ||
76 | u32 classid); | ||
77 | void (*unbind_tcf)(struct Qdisc *, unsigned long); | ||
78 | |||
79 | /* rtnetlink specific */ | ||
80 | int (*dump)(struct Qdisc *, unsigned long, | ||
81 | struct sk_buff *skb, struct tcmsg*); | ||
82 | int (*dump_stats)(struct Qdisc *, unsigned long, | ||
83 | struct gnet_dump *); | ||
84 | }; | ||
85 | |||
86 | struct Qdisc_ops | ||
87 | { | ||
88 | struct Qdisc_ops *next; | ||
89 | struct Qdisc_class_ops *cl_ops; | ||
90 | char id[IFNAMSIZ]; | ||
91 | int priv_size; | ||
92 | |||
93 | int (*enqueue)(struct sk_buff *, struct Qdisc *); | ||
94 | struct sk_buff * (*dequeue)(struct Qdisc *); | ||
95 | int (*requeue)(struct sk_buff *, struct Qdisc *); | ||
96 | unsigned int (*drop)(struct Qdisc *); | ||
97 | |||
98 | int (*init)(struct Qdisc *, struct rtattr *arg); | ||
99 | void (*reset)(struct Qdisc *); | ||
100 | void (*destroy)(struct Qdisc *); | ||
101 | int (*change)(struct Qdisc *, struct rtattr *arg); | ||
102 | |||
103 | int (*dump)(struct Qdisc *, struct sk_buff *); | ||
104 | int (*dump_stats)(struct Qdisc *, struct gnet_dump *); | ||
105 | |||
106 | struct module *owner; | ||
107 | }; | ||
108 | |||
109 | |||
110 | struct tcf_result | ||
111 | { | ||
112 | unsigned long class; | ||
113 | u32 classid; | ||
114 | }; | ||
115 | |||
116 | struct tcf_proto_ops | ||
117 | { | ||
118 | struct tcf_proto_ops *next; | ||
119 | char kind[IFNAMSIZ]; | ||
120 | |||
121 | int (*classify)(struct sk_buff*, struct tcf_proto*, | ||
122 | struct tcf_result *); | ||
123 | int (*init)(struct tcf_proto*); | ||
124 | void (*destroy)(struct tcf_proto*); | ||
125 | |||
126 | unsigned long (*get)(struct tcf_proto*, u32 handle); | ||
127 | void (*put)(struct tcf_proto*, unsigned long); | ||
128 | int (*change)(struct tcf_proto*, unsigned long, | ||
129 | u32 handle, struct rtattr **, | ||
130 | unsigned long *); | ||
131 | int (*delete)(struct tcf_proto*, unsigned long); | ||
132 | void (*walk)(struct tcf_proto*, struct tcf_walker *arg); | ||
133 | |||
134 | /* rtnetlink specific */ | ||
135 | int (*dump)(struct tcf_proto*, unsigned long, | ||
136 | struct sk_buff *skb, struct tcmsg*); | ||
137 | |||
138 | struct module *owner; | ||
139 | }; | ||
140 | |||
141 | struct tcf_proto | ||
142 | { | ||
143 | /* Fast access part */ | ||
144 | struct tcf_proto *next; | ||
145 | void *root; | ||
146 | int (*classify)(struct sk_buff*, struct tcf_proto*, | ||
147 | struct tcf_result *); | ||
148 | u32 protocol; | ||
149 | |||
150 | /* All the rest */ | ||
151 | u32 prio; | ||
152 | u32 classid; | ||
153 | struct Qdisc *q; | ||
154 | void *data; | ||
155 | struct tcf_proto_ops *ops; | ||
156 | }; | ||
157 | |||
158 | |||
159 | extern void qdisc_lock_tree(struct net_device *dev); | ||
160 | extern void qdisc_unlock_tree(struct net_device *dev); | ||
161 | |||
162 | #define sch_tree_lock(q) qdisc_lock_tree((q)->dev) | ||
163 | #define sch_tree_unlock(q) qdisc_unlock_tree((q)->dev) | ||
164 | #define tcf_tree_lock(tp) qdisc_lock_tree((tp)->q->dev) | ||
165 | #define tcf_tree_unlock(tp) qdisc_unlock_tree((tp)->q->dev) | ||
166 | |||
167 | static inline void | ||
168 | tcf_destroy(struct tcf_proto *tp) | ||
169 | { | ||
170 | tp->ops->destroy(tp); | ||
171 | module_put(tp->ops->owner); | ||
172 | kfree(tp); | ||
173 | } | ||
174 | |||
175 | #endif | ||
diff --git a/include/net/scm.h b/include/net/scm.h new file mode 100644 index 000000000000..c3fa3d5ab606 --- /dev/null +++ b/include/net/scm.h | |||
@@ -0,0 +1,71 @@ | |||
1 | #ifndef __LINUX_NET_SCM_H | ||
2 | #define __LINUX_NET_SCM_H | ||
3 | |||
4 | #include <linux/limits.h> | ||
5 | #include <linux/net.h> | ||
6 | |||
7 | /* Well, we should have at least one descriptor open | ||
8 | * to accept passed FDs 8) | ||
9 | */ | ||
10 | #define SCM_MAX_FD (OPEN_MAX-1) | ||
11 | |||
12 | struct scm_fp_list | ||
13 | { | ||
14 | int count; | ||
15 | struct file *fp[SCM_MAX_FD]; | ||
16 | }; | ||
17 | |||
18 | struct scm_cookie | ||
19 | { | ||
20 | struct ucred creds; /* Skb credentials */ | ||
21 | struct scm_fp_list *fp; /* Passed files */ | ||
22 | unsigned long seq; /* Connection seqno */ | ||
23 | }; | ||
24 | |||
25 | extern void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm); | ||
26 | extern void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm); | ||
27 | extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm); | ||
28 | extern void __scm_destroy(struct scm_cookie *scm); | ||
29 | extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl); | ||
30 | |||
31 | static __inline__ void scm_destroy(struct scm_cookie *scm) | ||
32 | { | ||
33 | if (scm && scm->fp) | ||
34 | __scm_destroy(scm); | ||
35 | } | ||
36 | |||
37 | static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, | ||
38 | struct scm_cookie *scm) | ||
39 | { | ||
40 | memset(scm, 0, sizeof(*scm)); | ||
41 | scm->creds.uid = current->uid; | ||
42 | scm->creds.gid = current->gid; | ||
43 | scm->creds.pid = current->tgid; | ||
44 | if (msg->msg_controllen <= 0) | ||
45 | return 0; | ||
46 | return __scm_send(sock, msg, scm); | ||
47 | } | ||
48 | |||
49 | static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg, | ||
50 | struct scm_cookie *scm, int flags) | ||
51 | { | ||
52 | if (!msg->msg_control) | ||
53 | { | ||
54 | if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp) | ||
55 | msg->msg_flags |= MSG_CTRUNC; | ||
56 | scm_destroy(scm); | ||
57 | return; | ||
58 | } | ||
59 | |||
60 | if (test_bit(SOCK_PASSCRED, &sock->flags)) | ||
61 | put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds); | ||
62 | |||
63 | if (!scm->fp) | ||
64 | return; | ||
65 | |||
66 | scm_detach_fds(msg, scm); | ||
67 | } | ||
68 | |||
69 | |||
70 | #endif /* __LINUX_NET_SCM_H */ | ||
71 | |||
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h new file mode 100644 index 000000000000..ebc5282e6d58 --- /dev/null +++ b/include/net/sctp/command.h | |||
@@ -0,0 +1,211 @@ | |||
1 | /* SCTP kernel reference Implementation | ||
2 | * (C) Copyright IBM Corp. 2001, 2004 | ||
3 | * Copyright (C) 1999-2001 Cisco, Motorola | ||
4 | * | ||
5 | * This file is part of the SCTP kernel reference Implementation | ||
6 | * | ||
7 | * These are the definitions needed for the command object. | ||
8 | * | ||
9 | * The SCTP reference implementation is free software; | ||
10 | * you can redistribute it and/or modify it under the terms of | ||
11 | * the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2, or (at your option) | ||
13 | * any later version. | ||
14 | * | ||
15 | * the SCTP reference implementation is distributed in the hope that it | ||
16 | * will be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
17 | * ************************ | ||
18 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
19 | * See the GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with GNU CC; see the file COPYING. If not, write to | ||
23 | * the Free Software Foundation, 59 Temple Place - Suite 330, | ||
24 | * Boston, MA 02111-1307, USA. | ||
25 | * | ||
26 | * Please send any bug reports or fixes you make to one of the | ||
27 | * following email addresses: | ||
28 | * | ||
29 | * La Monte H.P. Yarroll <piggy@acm.org> | ||
30 | * Karl Knutson <karl@athena.chicago.il.us> | ||
31 | * Ardelle Fan <ardelle.fan@intel.com> | ||
32 | * Sridhar Samudrala <sri@us.ibm.com> | ||
33 | * | ||
34 | * Any bugs reported given to us we will try to fix... any fixes shared will | ||
35 | * be incorporated into the next SCTP release. | ||
36 | */ | ||
37 | |||
38 | |||
39 | #ifndef __net_sctp_command_h__ | ||
40 | #define __net_sctp_command_h__ | ||
41 | |||
42 | #include <net/sctp/constants.h> | ||
43 | #include <net/sctp/structs.h> | ||
44 | |||
45 | |||
46 | typedef enum { | ||
47 | SCTP_CMD_NOP = 0, /* Do nothing. */ | ||
48 | SCTP_CMD_NEW_ASOC, /* Register a new association. */ | ||
49 | SCTP_CMD_DELETE_TCB, /* Delete the current association. */ | ||
50 | SCTP_CMD_NEW_STATE, /* Enter a new state. */ | ||
51 | SCTP_CMD_REPORT_TSN, /* Record the arrival of a TSN. */ | ||
52 | SCTP_CMD_GEN_SACK, /* Send a Selective ACK (maybe). */ | ||
53 | SCTP_CMD_PROCESS_SACK, /* Process an inbound SACK. */ | ||
54 | SCTP_CMD_GEN_INIT_ACK, /* Generate an INIT ACK chunk. */ | ||
55 | SCTP_CMD_PEER_INIT, /* Process a INIT from the peer. */ | ||
56 | SCTP_CMD_GEN_COOKIE_ECHO, /* Generate a COOKIE ECHO chunk. */ | ||
57 | SCTP_CMD_CHUNK_ULP, /* Send a chunk to the sockets layer. */ | ||
58 | SCTP_CMD_EVENT_ULP, /* Send a notification to the sockets layer. */ | ||
59 | SCTP_CMD_REPLY, /* Send a chunk to our peer. */ | ||
60 | SCTP_CMD_SEND_PKT, /* Send a full packet to our peer. */ | ||
61 | SCTP_CMD_RETRAN, /* Mark a transport for retransmission. */ | ||
62 | SCTP_CMD_ECN_CE, /* Do delayed CE processing. */ | ||
63 | SCTP_CMD_ECN_ECNE, /* Do delayed ECNE processing. */ | ||
64 | SCTP_CMD_ECN_CWR, /* Do delayed CWR processing. */ | ||
65 | SCTP_CMD_TIMER_START, /* Start a timer. */ | ||
66 | SCTP_CMD_TIMER_RESTART, /* Restart a timer. */ | ||
67 | SCTP_CMD_TIMER_STOP, /* Stop a timer. */ | ||
68 | SCTP_CMD_COUNTER_RESET, /* Reset a counter. */ | ||
69 | SCTP_CMD_COUNTER_INC, /* Increment a counter. */ | ||
70 | SCTP_CMD_INIT_RESTART, /* High level, do init timer work. */ | ||
71 | SCTP_CMD_INIT_FAILED, /* High level, do init failure work. */ | ||
72 | SCTP_CMD_REPORT_DUP, /* Report a duplicate TSN. */ | ||
73 | SCTP_CMD_STRIKE, /* Mark a strike against a transport. */ | ||
74 | SCTP_CMD_TRANSMIT, /* Transmit the outqueue. */ | ||
75 | SCTP_CMD_HB_TIMERS_START, /* Start the heartbeat timers. */ | ||
76 | SCTP_CMD_HB_TIMER_UPDATE, /* Update a heartbeat timers. */ | ||
77 | SCTP_CMD_HB_TIMERS_STOP, /* Stop the heartbeat timers. */ | ||
78 | SCTP_CMD_TRANSPORT_RESET, /* Reset the status of a transport. */ | ||
79 | SCTP_CMD_TRANSPORT_ON, /* Mark the transport as active. */ | ||
80 | SCTP_CMD_REPORT_ERROR, /* Pass this error back out of the sm. */ | ||
81 | SCTP_CMD_REPORT_BAD_TAG, /* Verification tags didn't match. */ | ||
82 | SCTP_CMD_PROCESS_CTSN, /* Sideeffect from shutdown. */ | ||
83 | SCTP_CMD_ASSOC_FAILED, /* Handle association failure. */ | ||
84 | SCTP_CMD_DISCARD_PACKET, /* Discard the whole packet. */ | ||
85 | SCTP_CMD_GEN_SHUTDOWN, /* Generate a SHUTDOWN chunk. */ | ||
86 | SCTP_CMD_UPDATE_ASSOC, /* Update association information. */ | ||
87 | SCTP_CMD_PURGE_OUTQUEUE, /* Purge all data waiting to be sent. */ | ||
88 | SCTP_CMD_SETUP_T2, /* Hi-level, setup T2-shutdown parms. */ | ||
89 | SCTP_CMD_RTO_PENDING, /* Set transport's rto_pending. */ | ||
90 | SCTP_CMD_PART_DELIVER, /* Partial data delivery considerations. */ | ||
91 | SCTP_CMD_RENEGE, /* Renege data on an association. */ | ||
92 | SCTP_CMD_SETUP_T4, /* ADDIP, setup T4 RTO timer parms. */ | ||
93 | SCTP_CMD_PROCESS_OPERR, /* Process an ERROR chunk. */ | ||
94 | SCTP_CMD_REPORT_FWDTSN, /* Report new cumulative TSN Ack. */ | ||
95 | SCTP_CMD_PROCESS_FWDTSN, /* Skips were reported, so process further. */ | ||
96 | SCTP_CMD_CLEAR_INIT_TAG, /* Clears association peer's inittag. */ | ||
97 | SCTP_CMD_DEL_NON_PRIMARY, /* Removes non-primary peer transports. */ | ||
98 | SCTP_CMD_T3_RTX_TIMERS_STOP, /* Stops T3-rtx pending timers */ | ||
99 | SCTP_CMD_FORCE_PRIM_RETRAN, /* Forces retrans. over primary path. */ | ||
100 | SCTP_CMD_LAST | ||
101 | } sctp_verb_t; | ||
102 | |||
103 | #define SCTP_CMD_MAX (SCTP_CMD_LAST - 1) | ||
104 | #define SCTP_CMD_NUM_VERBS (SCTP_CMD_MAX + 1) | ||
105 | |||
106 | /* How many commands can you put in an sctp_cmd_seq_t? | ||
107 | * This is a rather arbitrary number, ideally derived from a careful | ||
108 | * analysis of the state functions, but in reality just taken from | ||
109 | * thin air in the hopes othat we don't trigger a kernel panic. | ||
110 | */ | ||
111 | #define SCTP_MAX_NUM_COMMANDS 14 | ||
112 | |||
113 | typedef union { | ||
114 | __s32 i32; | ||
115 | __u32 u32; | ||
116 | __u16 u16; | ||
117 | __u8 u8; | ||
118 | int error; | ||
119 | sctp_state_t state; | ||
120 | sctp_event_timeout_t to; | ||
121 | sctp_counter_t counter; | ||
122 | void *ptr; | ||
123 | struct sctp_chunk *chunk; | ||
124 | struct sctp_association *asoc; | ||
125 | struct sctp_transport *transport; | ||
126 | struct sctp_bind_addr *bp; | ||
127 | sctp_init_chunk_t *init; | ||
128 | struct sctp_ulpevent *ulpevent; | ||
129 | struct sctp_packet *packet; | ||
130 | sctp_sackhdr_t *sackh; | ||
131 | } sctp_arg_t; | ||
132 | |||
133 | /* We are simulating ML type constructors here. | ||
134 | * | ||
135 | * SCTP_ARG_CONSTRUCTOR(NAME, TYPE, ELT) builds a function called | ||
136 | * SCTP_NAME() which takes an argument of type TYPE and returns an | ||
137 | * sctp_arg_t. It does this by inserting the sole argument into the | ||
138 | * ELT union element of a local sctp_arg_t. | ||
139 | * | ||
140 | * E.g., SCTP_ARG_CONSTRUCTOR(I32, __s32, i32) builds SCTP_I32(arg), | ||
141 | * which takes an __s32 and returns a sctp_arg_t containing the | ||
142 | * __s32. So, after foo = SCTP_I32(arg), foo.i32 == arg. | ||
143 | */ | ||
144 | static inline sctp_arg_t SCTP_NULL(void) | ||
145 | { | ||
146 | sctp_arg_t retval; retval.ptr = NULL; return retval; | ||
147 | } | ||
148 | static inline sctp_arg_t SCTP_NOFORCE(void) | ||
149 | { | ||
150 | sctp_arg_t retval; retval.i32 = 0; return retval; | ||
151 | } | ||
152 | static inline sctp_arg_t SCTP_FORCE(void) | ||
153 | { | ||
154 | sctp_arg_t retval; retval.i32 = 1; return retval; | ||
155 | } | ||
156 | |||
157 | #define SCTP_ARG_CONSTRUCTOR(name, type, elt) \ | ||
158 | static inline sctp_arg_t \ | ||
159 | SCTP_## name (type arg) \ | ||
160 | { sctp_arg_t retval; retval.elt = arg; return retval; } | ||
161 | |||
162 | SCTP_ARG_CONSTRUCTOR(I32, __s32, i32) | ||
163 | SCTP_ARG_CONSTRUCTOR(U32, __u32, u32) | ||
164 | SCTP_ARG_CONSTRUCTOR(U16, __u16, u16) | ||
165 | SCTP_ARG_CONSTRUCTOR(U8, __u8, u8) | ||
166 | SCTP_ARG_CONSTRUCTOR(ERROR, int, error) | ||
167 | SCTP_ARG_CONSTRUCTOR(STATE, sctp_state_t, state) | ||
168 | SCTP_ARG_CONSTRUCTOR(COUNTER, sctp_counter_t, counter) | ||
169 | SCTP_ARG_CONSTRUCTOR(TO, sctp_event_timeout_t, to) | ||
170 | SCTP_ARG_CONSTRUCTOR(PTR, void *, ptr) | ||
171 | SCTP_ARG_CONSTRUCTOR(CHUNK, struct sctp_chunk *, chunk) | ||
172 | SCTP_ARG_CONSTRUCTOR(ASOC, struct sctp_association *, asoc) | ||
173 | SCTP_ARG_CONSTRUCTOR(TRANSPORT, struct sctp_transport *, transport) | ||
174 | SCTP_ARG_CONSTRUCTOR(BA, struct sctp_bind_addr *, bp) | ||
175 | SCTP_ARG_CONSTRUCTOR(PEER_INIT, sctp_init_chunk_t *, init) | ||
176 | SCTP_ARG_CONSTRUCTOR(ULPEVENT, struct sctp_ulpevent *, ulpevent) | ||
177 | SCTP_ARG_CONSTRUCTOR(PACKET, struct sctp_packet *, packet) | ||
178 | SCTP_ARG_CONSTRUCTOR(SACKH, sctp_sackhdr_t *, sackh) | ||
179 | |||
180 | typedef struct { | ||
181 | sctp_arg_t obj; | ||
182 | sctp_verb_t verb; | ||
183 | } sctp_cmd_t; | ||
184 | |||
185 | typedef struct { | ||
186 | sctp_cmd_t cmds[SCTP_MAX_NUM_COMMANDS]; | ||
187 | __u8 next_free_slot; | ||
188 | __u8 next_cmd; | ||
189 | } sctp_cmd_seq_t; | ||
190 | |||
191 | |||
192 | /* Initialize a block of memory as a command sequence. | ||
193 | * Return 0 if the initialization fails. | ||
194 | */ | ||
195 | int sctp_init_cmd_seq(sctp_cmd_seq_t *seq); | ||
196 | |||
197 | /* Add a command to an sctp_cmd_seq_t. | ||
198 | * Return 0 if the command sequence is full. | ||
199 | * | ||
200 | * Use the SCTP_* constructors defined by SCTP_ARG_CONSTRUCTOR() above | ||
201 | * to wrap data which goes in the obj argument. | ||
202 | */ | ||
203 | int sctp_add_cmd(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_arg_t obj); | ||
204 | |||
205 | /* Return the next command structure in an sctp_cmd_seq. | ||
206 | * Return NULL at the end of the sequence. | ||
207 | */ | ||
208 | sctp_cmd_t *sctp_next_cmd(sctp_cmd_seq_t *seq); | ||
209 | |||
210 | #endif /* __net_sctp_command_h__ */ | ||
211 | |||
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h new file mode 100644 index 000000000000..2b76c0f4babc --- /dev/null +++ b/include/net/sctp/constants.h | |||
@@ -0,0 +1,432 @@ | |||
1 | /* SCTP kernel reference Implementation | ||
2 | * (C) Copyright IBM Corp. 2001, 2004 | ||
3 | * Copyright (c) 1999-2000 Cisco, Inc. | ||
4 | * Copyright (c) 1999-2001 Motorola, Inc. | ||
5 | * Copyright (c) 2001 Intel Corp. | ||
6 | * | ||
7 | * This file is part of the SCTP kernel reference Implementation | ||
8 | * | ||
9 | * The SCTP reference implementation is free software; | ||
10 | * you can redistribute it and/or modify it under the terms of | ||
11 | * the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2, or (at your option) | ||
13 | * any later version. | ||
14 | * | ||
15 | * The SCTP reference implementation is distributed in the hope that it | ||
16 | * will be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
17 | * ************************ | ||
18 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
19 | * See the GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with GNU CC; see the file COPYING. If not, write to | ||
23 | * the Free Software Foundation, 59 Temple Place - Suite 330, | ||
24 | * Boston, MA 02111-1307, USA. | ||
25 | * | ||
26 | * Please send any bug reports or fixes you make to the | ||
27 | * email address(es): | ||
28 | * lksctp developers <lksctp-developers@lists.sourceforge.net> | ||
29 | * | ||
30 | * Or submit a bug report through the following website: | ||
31 | * http://www.sf.net/projects/lksctp | ||
32 | * | ||
33 | * Written or modified by: | ||
34 | * La Monte H.P. Yarroll <piggy@acm.org> | ||
35 | * Karl Knutson <karl@athena.chicago.il.us> | ||
36 | * Randall Stewart <randall@stewart.chicago.il.us> | ||
37 | * Ken Morneau <kmorneau@cisco.com> | ||
38 | * Qiaobing Xie <qxie1@motorola.com> | ||
39 | * Xingang Guo <xingang.guo@intel.com> | ||
40 | * Sridhar Samudrala <samudrala@us.ibm.com> | ||
41 | * Daisy Chang <daisyc@us.ibm.com> | ||
42 | * | ||
43 | * Any bugs reported given to us we will try to fix... any fixes shared will | ||
44 | * be incorporated into the next SCTP release. | ||
45 | */ | ||
46 | |||
47 | #ifndef __sctp_constants_h__ | ||
48 | #define __sctp_constants_h__ | ||
49 | |||
50 | #include <linux/tcp.h> /* For TCP states used in sctp_sock_state_t */ | ||
51 | #include <linux/sctp.h> | ||
52 | #include <linux/ipv6.h> /* For ipv6hdr. */ | ||
53 | #include <net/sctp/user.h> | ||
54 | |||
55 | /* Value used for stream negotiation. */ | ||
56 | enum { SCTP_MAX_STREAM = 0xffff }; | ||
57 | enum { SCTP_DEFAULT_OUTSTREAMS = 10 }; | ||
58 | enum { SCTP_DEFAULT_INSTREAMS = SCTP_MAX_STREAM }; | ||
59 | |||
60 | /* Since CIDs are sparse, we need all four of the following | ||
61 | * symbols. CIDs are dense through SCTP_CID_BASE_MAX. | ||
62 | */ | ||
63 | #define SCTP_CID_BASE_MAX SCTP_CID_SHUTDOWN_COMPLETE | ||
64 | #define SCTP_CID_MAX SCTP_CID_ASCONF_ACK | ||
65 | |||
66 | #define SCTP_NUM_BASE_CHUNK_TYPES (SCTP_CID_BASE_MAX + 1) | ||
67 | #define SCTP_NUM_CHUNK_TYPES (SCTP_NUM_BASE_CHUNKTYPES + 2) | ||
68 | |||
69 | #define SCTP_NUM_ADDIP_CHUNK_TYPES 2 | ||
70 | |||
71 | #define SCTP_NUM_PRSCTP_CHUNK_TYPES 1 | ||
72 | |||
73 | /* These are the different flavours of event. */ | ||
74 | typedef enum { | ||
75 | |||
76 | SCTP_EVENT_T_CHUNK = 1, | ||
77 | SCTP_EVENT_T_TIMEOUT, | ||
78 | SCTP_EVENT_T_OTHER, | ||
79 | SCTP_EVENT_T_PRIMITIVE | ||
80 | |||
81 | } sctp_event_t; | ||
82 | |||
83 | #define SCTP_EVENT_T_MAX SCTP_EVENT_T_PRIMITIVE | ||
84 | #define SCTP_EVENT_T_NUM (SCTP_EVENT_T_MAX + 1) | ||
85 | |||
86 | /* As a convenience for the state machine, we append SCTP_EVENT_* and | ||
87 | * SCTP_ULP_* to the list of possible chunks. | ||
88 | */ | ||
89 | |||
90 | typedef enum { | ||
91 | SCTP_EVENT_TIMEOUT_NONE = 0, | ||
92 | SCTP_EVENT_TIMEOUT_T1_COOKIE, | ||
93 | SCTP_EVENT_TIMEOUT_T1_INIT, | ||
94 | SCTP_EVENT_TIMEOUT_T2_SHUTDOWN, | ||
95 | SCTP_EVENT_TIMEOUT_T3_RTX, | ||
96 | SCTP_EVENT_TIMEOUT_T4_RTO, | ||
97 | SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD, | ||
98 | SCTP_EVENT_TIMEOUT_HEARTBEAT, | ||
99 | SCTP_EVENT_TIMEOUT_SACK, | ||
100 | SCTP_EVENT_TIMEOUT_AUTOCLOSE, | ||
101 | } sctp_event_timeout_t; | ||
102 | |||
103 | #define SCTP_EVENT_TIMEOUT_MAX SCTP_EVENT_TIMEOUT_AUTOCLOSE | ||
104 | #define SCTP_NUM_TIMEOUT_TYPES (SCTP_EVENT_TIMEOUT_MAX + 1) | ||
105 | |||
106 | typedef enum { | ||
107 | SCTP_EVENT_NO_PENDING_TSN = 0, | ||
108 | SCTP_EVENT_ICMP_PROTO_UNREACH, | ||
109 | } sctp_event_other_t; | ||
110 | |||
111 | #define SCTP_EVENT_OTHER_MAX SCTP_EVENT_ICMP_PROTO_UNREACH | ||
112 | #define SCTP_NUM_OTHER_TYPES (SCTP_EVENT_OTHER_MAX + 1) | ||
113 | |||
114 | /* These are primitive requests from the ULP. */ | ||
115 | typedef enum { | ||
116 | SCTP_PRIMITIVE_ASSOCIATE = 0, | ||
117 | SCTP_PRIMITIVE_SHUTDOWN, | ||
118 | SCTP_PRIMITIVE_ABORT, | ||
119 | SCTP_PRIMITIVE_SEND, | ||
120 | SCTP_PRIMITIVE_REQUESTHEARTBEAT, | ||
121 | SCTP_PRIMITIVE_ASCONF, | ||
122 | } sctp_event_primitive_t; | ||
123 | |||
124 | #define SCTP_EVENT_PRIMITIVE_MAX SCTP_PRIMITIVE_ASCONF | ||
125 | #define SCTP_NUM_PRIMITIVE_TYPES (SCTP_EVENT_PRIMITIVE_MAX + 1) | ||
126 | |||
127 | /* We define here a utility type for manipulating subtypes. | ||
128 | * The subtype constructors all work like this: | ||
129 | * | ||
130 | * sctp_subtype_t foo = SCTP_ST_CHUNK(SCTP_CID_INIT); | ||
131 | */ | ||
132 | |||
133 | typedef union { | ||
134 | sctp_cid_t chunk; | ||
135 | sctp_event_timeout_t timeout; | ||
136 | sctp_event_other_t other; | ||
137 | sctp_event_primitive_t primitive; | ||
138 | } sctp_subtype_t; | ||
139 | |||
140 | #define SCTP_SUBTYPE_CONSTRUCTOR(_name, _type, _elt) \ | ||
141 | static inline sctp_subtype_t \ | ||
142 | SCTP_ST_## _name (_type _arg) \ | ||
143 | { sctp_subtype_t _retval; _retval._elt = _arg; return _retval; } | ||
144 | |||
145 | SCTP_SUBTYPE_CONSTRUCTOR(CHUNK, sctp_cid_t, chunk) | ||
146 | SCTP_SUBTYPE_CONSTRUCTOR(TIMEOUT, sctp_event_timeout_t, timeout) | ||
147 | SCTP_SUBTYPE_CONSTRUCTOR(OTHER, sctp_event_other_t, other) | ||
148 | SCTP_SUBTYPE_CONSTRUCTOR(PRIMITIVE, sctp_event_primitive_t, primitive) | ||
149 | |||
150 | |||
151 | #define sctp_chunk_is_control(a) (a->chunk_hdr->type != SCTP_CID_DATA) | ||
152 | #define sctp_chunk_is_data(a) (a->chunk_hdr->type == SCTP_CID_DATA) | ||
153 | |||
154 | /* Calculate the actual data size in a data chunk */ | ||
155 | #define SCTP_DATA_SNDSIZE(c) ((int)((unsigned long)(c->chunk_end)\ | ||
156 | - (unsigned long)(c->chunk_hdr)\ | ||
157 | - sizeof(sctp_data_chunk_t))) | ||
158 | |||
159 | #define SCTP_MAX_ERROR_CAUSE SCTP_ERROR_NONEXIST_IP | ||
160 | #define SCTP_NUM_ERROR_CAUSE 10 | ||
161 | |||
162 | /* Internal error codes */ | ||
163 | typedef enum { | ||
164 | |||
165 | SCTP_IERROR_NO_ERROR = 0, | ||
166 | SCTP_IERROR_BASE = 1000, | ||
167 | SCTP_IERROR_NO_COOKIE, | ||
168 | SCTP_IERROR_BAD_SIG, | ||
169 | SCTP_IERROR_STALE_COOKIE, | ||
170 | SCTP_IERROR_NOMEM, | ||
171 | SCTP_IERROR_MALFORMED, | ||
172 | SCTP_IERROR_BAD_TAG, | ||
173 | SCTP_IERROR_BIG_GAP, | ||
174 | SCTP_IERROR_DUP_TSN, | ||
175 | SCTP_IERROR_HIGH_TSN, | ||
176 | SCTP_IERROR_IGNORE_TSN, | ||
177 | SCTP_IERROR_NO_DATA, | ||
178 | SCTP_IERROR_BAD_STREAM, | ||
179 | SCTP_IERROR_BAD_PORTS, | ||
180 | |||
181 | } sctp_ierror_t; | ||
182 | |||
183 | |||
184 | |||
185 | /* SCTP state defines for internal state machine */ | ||
186 | typedef enum { | ||
187 | |||
188 | SCTP_STATE_EMPTY = 0, | ||
189 | SCTP_STATE_CLOSED = 1, | ||
190 | SCTP_STATE_COOKIE_WAIT = 2, | ||
191 | SCTP_STATE_COOKIE_ECHOED = 3, | ||
192 | SCTP_STATE_ESTABLISHED = 4, | ||
193 | SCTP_STATE_SHUTDOWN_PENDING = 5, | ||
194 | SCTP_STATE_SHUTDOWN_SENT = 6, | ||
195 | SCTP_STATE_SHUTDOWN_RECEIVED = 7, | ||
196 | SCTP_STATE_SHUTDOWN_ACK_SENT = 8, | ||
197 | |||
198 | } sctp_state_t; | ||
199 | |||
200 | #define SCTP_STATE_MAX SCTP_STATE_SHUTDOWN_ACK_SENT | ||
201 | #define SCTP_STATE_NUM_STATES (SCTP_STATE_MAX + 1) | ||
202 | |||
203 | /* These are values for sk->state. | ||
204 | * For a UDP-style SCTP socket, the states are defined as follows | ||
205 | * - A socket in SCTP_SS_CLOSED state indicates that it is not willing to | ||
206 | * accept new associations, but it can initiate the creation of new ones. | ||
207 | * - A socket in SCTP_SS_LISTENING state indicates that it is willing to | ||
208 | * accept new associations and can initiate the creation of new ones. | ||
209 | * - A socket in SCTP_SS_ESTABLISHED state indicates that it is a peeled off | ||
210 | * socket with one association. | ||
211 | * For a TCP-style SCTP socket, the states are defined as follows | ||
212 | * - A socket in SCTP_SS_CLOSED state indicates that it is not willing to | ||
213 | * accept new associations, but it can initiate the creation of new ones. | ||
214 | * - A socket in SCTP_SS_LISTENING state indicates that it is willing to | ||
215 | * accept new associations, but cannot initiate the creation of new ones. | ||
216 | * - A socket in SCTP_SS_ESTABLISHED state indicates that it has a single | ||
217 | * association. | ||
218 | */ | ||
219 | typedef enum { | ||
220 | SCTP_SS_CLOSED = TCP_CLOSE, | ||
221 | SCTP_SS_LISTENING = TCP_LISTEN, | ||
222 | SCTP_SS_ESTABLISHING = TCP_SYN_SENT, | ||
223 | SCTP_SS_ESTABLISHED = TCP_ESTABLISHED, | ||
224 | SCTP_SS_DISCONNECTING = TCP_CLOSING, | ||
225 | } sctp_sock_state_t; | ||
226 | |||
227 | /* These functions map various type to printable names. */ | ||
228 | const char *sctp_cname(const sctp_subtype_t); /* chunk types */ | ||
229 | const char *sctp_oname(const sctp_subtype_t); /* other events */ | ||
230 | const char *sctp_tname(const sctp_subtype_t); /* timeouts */ | ||
231 | const char *sctp_pname(const sctp_subtype_t); /* primitives */ | ||
232 | |||
233 | /* This is a table of printable names of sctp_state_t's. */ | ||
234 | extern const char *sctp_state_tbl[], *sctp_evttype_tbl[], *sctp_status_tbl[]; | ||
235 | |||
236 | /* Maximum chunk length considering padding requirements. */ | ||
237 | enum { SCTP_MAX_CHUNK_LEN = ((1<<16) - sizeof(__u32)) }; | ||
238 | |||
239 | /* Encourage Cookie-Echo bundling by pre-fragmenting chunks a little | ||
240 | * harder (until reaching ESTABLISHED state). | ||
241 | */ | ||
242 | enum { SCTP_ARBITRARY_COOKIE_ECHO_LEN = 200 }; | ||
243 | |||
244 | /* Guess at how big to make the TSN mapping array. | ||
245 | * We guarantee that we can handle at least this big a gap between the | ||
246 | * cumulative ACK and the highest TSN. In practice, we can often | ||
247 | * handle up to twice this value. | ||
248 | * | ||
249 | * NEVER make this more than 32767 (2^15-1). The Gap Ack Blocks in a | ||
250 | * SACK (see section 3.3.4) are only 16 bits, so 2*SCTP_TSN_MAP_SIZE | ||
251 | * must be less than 65535 (2^16 - 1), or we will have overflow | ||
252 | * problems creating SACK's. | ||
253 | */ | ||
254 | #define SCTP_TSN_MAP_SIZE 2048 | ||
255 | #define SCTP_TSN_MAX_GAP 65535 | ||
256 | |||
257 | /* We will not record more than this many duplicate TSNs between two | ||
258 | * SACKs. The minimum PMTU is 576. Remove all the headers and there | ||
259 | * is enough room for 131 duplicate reports. Round down to the | ||
260 | * nearest power of 2. | ||
261 | */ | ||
262 | enum { SCTP_MIN_PMTU = 576 }; | ||
263 | enum { SCTP_MAX_DUP_TSNS = 16 }; | ||
264 | enum { SCTP_MAX_GABS = 16 }; | ||
265 | |||
266 | typedef enum { | ||
267 | SCTP_COUNTER_INIT_ERROR, | ||
268 | } sctp_counter_t; | ||
269 | |||
270 | /* How many counters does an association need? */ | ||
271 | #define SCTP_NUMBER_COUNTERS 5 | ||
272 | |||
273 | /* Here we define the default timers. */ | ||
274 | |||
275 | /* cookie timer def = ? seconds */ | ||
276 | #define SCTP_DEFAULT_TIMEOUT_T1_COOKIE (3 * HZ) | ||
277 | |||
278 | /* init timer def = 3 seconds */ | ||
279 | #define SCTP_DEFAULT_TIMEOUT_T1_INIT (3 * HZ) | ||
280 | |||
281 | /* shutdown timer def = 300 ms */ | ||
282 | #define SCTP_DEFAULT_TIMEOUT_T2_SHUTDOWN ((300 * HZ) / 1000) | ||
283 | |||
284 | /* 0 seconds + RTO */ | ||
285 | #define SCTP_DEFAULT_TIMEOUT_HEARTBEAT (10 * HZ) | ||
286 | |||
287 | /* recv timer def = 200ms (in usec) */ | ||
288 | #define SCTP_DEFAULT_TIMEOUT_SACK ((200 * HZ) / 1000) | ||
289 | #define SCTP_DEFAULT_TIMEOUT_SACK_MAX ((500 * HZ) / 1000) /* 500 ms */ | ||
290 | |||
291 | /* RTO.Initial - 3 seconds | ||
292 | * RTO.Min - 1 second | ||
293 | * RTO.Max - 60 seconds | ||
294 | * RTO.Alpha - 1/8 | ||
295 | * RTO.Beta - 1/4 | ||
296 | */ | ||
297 | #define SCTP_RTO_INITIAL (3 * HZ) | ||
298 | #define SCTP_RTO_MIN (1 * HZ) | ||
299 | #define SCTP_RTO_MAX (60 * HZ) | ||
300 | |||
301 | #define SCTP_RTO_ALPHA 3 /* 1/8 when converted to right shifts. */ | ||
302 | #define SCTP_RTO_BETA 2 /* 1/4 when converted to right shifts. */ | ||
303 | |||
304 | /* Maximum number of new data packets that can be sent in a burst. */ | ||
305 | #define SCTP_MAX_BURST 4 | ||
306 | |||
307 | #define SCTP_CLOCK_GRANULARITY 1 /* 1 jiffy */ | ||
308 | |||
309 | #define SCTP_DEF_MAX_INIT 6 | ||
310 | #define SCTP_DEF_MAX_SEND 10 | ||
311 | |||
312 | #define SCTP_DEFAULT_COOKIE_LIFE_SEC 60 /* seconds */ | ||
313 | #define SCTP_DEFAULT_COOKIE_LIFE_USEC 0 /* microseconds */ | ||
314 | |||
315 | #define SCTP_DEFAULT_MINWINDOW 1500 /* default minimum rwnd size */ | ||
316 | #define SCTP_DEFAULT_MAXWINDOW 65535 /* default rwnd size */ | ||
317 | #define SCTP_DEFAULT_MAXSEGMENT 1500 /* MTU size, this is the limit | ||
318 | * to which we will raise the P-MTU. | ||
319 | */ | ||
320 | #define SCTP_DEFAULT_MINSEGMENT 512 /* MTU size ... if no mtu disc */ | ||
321 | #define SCTP_HOW_MANY_SECRETS 2 /* How many secrets I keep */ | ||
322 | #define SCTP_HOW_LONG_COOKIE_LIVE 3600 /* How many seconds the current | ||
323 | * secret will live? | ||
324 | */ | ||
325 | #define SCTP_SECRET_SIZE 32 /* Number of octets in a 256 bits. */ | ||
326 | |||
327 | #define SCTP_SIGNATURE_SIZE 20 /* size of a SLA-1 signature */ | ||
328 | |||
329 | #define SCTP_COOKIE_MULTIPLE 32 /* Pad out our cookie to make our hash | ||
330 | * functions simpler to write. | ||
331 | */ | ||
332 | |||
333 | #if defined (CONFIG_SCTP_HMAC_MD5) | ||
334 | #define SCTP_COOKIE_HMAC_ALG "md5" | ||
335 | #elif defined (CONFIG_SCTP_HMAC_SHA1) | ||
336 | #define SCTP_COOKIE_HMAC_ALG "sha1" | ||
337 | #else | ||
338 | #define SCTP_COOKIE_HMAC_ALG NULL | ||
339 | #endif | ||
340 | |||
341 | /* These return values describe the success or failure of a number of | ||
342 | * routines which form the lower interface to SCTP_outqueue. | ||
343 | */ | ||
344 | typedef enum { | ||
345 | SCTP_XMIT_OK, | ||
346 | SCTP_XMIT_PMTU_FULL, | ||
347 | SCTP_XMIT_RWND_FULL, | ||
348 | SCTP_XMIT_NAGLE_DELAY, | ||
349 | } sctp_xmit_t; | ||
350 | |||
351 | /* These are the commands for manipulating transports. */ | ||
352 | typedef enum { | ||
353 | SCTP_TRANSPORT_UP, | ||
354 | SCTP_TRANSPORT_DOWN, | ||
355 | } sctp_transport_cmd_t; | ||
356 | |||
357 | /* These are the address scopes defined mainly for IPv4 addresses | ||
358 | * based on draft of SCTP IPv4 scoping <draft-stewart-tsvwg-sctp-ipv4-00.txt>. | ||
359 | * These scopes are hopefully generic enough to be used on scoping both | ||
360 | * IPv4 and IPv6 addresses in SCTP. | ||
361 | * At this point, the IPv6 scopes will be mapped to these internal scopes | ||
362 | * as much as possible. | ||
363 | */ | ||
364 | typedef enum { | ||
365 | SCTP_SCOPE_GLOBAL, /* IPv4 global addresses */ | ||
366 | SCTP_SCOPE_PRIVATE, /* IPv4 private addresses */ | ||
367 | SCTP_SCOPE_LINK, /* IPv4 link local address */ | ||
368 | SCTP_SCOPE_LOOPBACK, /* IPv4 loopback address */ | ||
369 | SCTP_SCOPE_UNUSABLE, /* IPv4 unusable addresses */ | ||
370 | } sctp_scope_t; | ||
371 | |||
372 | /* Based on IPv4 scoping <draft-stewart-tsvwg-sctp-ipv4-00.txt>, | ||
373 | * SCTP IPv4 unusable addresses: 0.0.0.0/8, 224.0.0.0/4, 198.18.0.0/24, | ||
374 | * 192.88.99.0/24. | ||
375 | * Also, RFC 8.4, non-unicast addresses are not considered valid SCTP | ||
376 | * addresses. | ||
377 | */ | ||
378 | #define IS_IPV4_UNUSABLE_ADDRESS(a) \ | ||
379 | ((INADDR_BROADCAST == *a) || \ | ||
380 | (MULTICAST(*a)) || \ | ||
381 | (((unsigned char *)(a))[0] == 0) || \ | ||
382 | ((((unsigned char *)(a))[0] == 198) && \ | ||
383 | (((unsigned char *)(a))[1] == 18) && \ | ||
384 | (((unsigned char *)(a))[2] == 0)) || \ | ||
385 | ((((unsigned char *)(a))[0] == 192) && \ | ||
386 | (((unsigned char *)(a))[1] == 88) && \ | ||
387 | (((unsigned char *)(a))[2] == 99))) | ||
388 | |||
389 | /* IPv4 Link-local addresses: 169.254.0.0/16. */ | ||
390 | #define IS_IPV4_LINK_ADDRESS(a) \ | ||
391 | ((((unsigned char *)(a))[0] == 169) && \ | ||
392 | (((unsigned char *)(a))[1] == 254)) | ||
393 | |||
394 | /* RFC 1918 "Address Allocation for Private Internets" defines the IPv4 | ||
395 | * private address space as the following: | ||
396 | * | ||
397 | * 10.0.0.0 - 10.255.255.255 (10/8 prefix) | ||
398 | * 172.16.0.0.0 - 172.31.255.255 (172.16/12 prefix) | ||
399 | * 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) | ||
400 | */ | ||
401 | #define IS_IPV4_PRIVATE_ADDRESS(a) \ | ||
402 | ((((unsigned char *)(a))[0] == 10) || \ | ||
403 | ((((unsigned char *)(a))[0] == 172) && \ | ||
404 | (((unsigned char *)(a))[1] >= 16) && \ | ||
405 | (((unsigned char *)(a))[1] < 32)) || \ | ||
406 | ((((unsigned char *)(a))[0] == 192) && \ | ||
407 | (((unsigned char *)(a))[1] == 168))) | ||
408 | |||
409 | /* Flags used for the bind address copy functions. */ | ||
410 | #define SCTP_ADDR6_ALLOWED 0x00000001 /* IPv6 address is allowed by | ||
411 | local sock family */ | ||
412 | #define SCTP_ADDR4_PEERSUPP 0x00000002 /* IPv4 address is supported by | ||
413 | peer */ | ||
414 | #define SCTP_ADDR6_PEERSUPP 0x00000004 /* IPv6 address is supported by | ||
415 | peer */ | ||
416 | |||
417 | /* Reasons to retransmit. */ | ||
418 | typedef enum { | ||
419 | SCTP_RTXR_T3_RTX, | ||
420 | SCTP_RTXR_FAST_RTX, | ||
421 | SCTP_RTXR_PMTUD, | ||
422 | } sctp_retransmit_reason_t; | ||
423 | |||
424 | /* Reasons to lower cwnd. */ | ||
425 | typedef enum { | ||
426 | SCTP_LOWER_CWND_T3_RTX, | ||
427 | SCTP_LOWER_CWND_FAST_RTX, | ||
428 | SCTP_LOWER_CWND_ECNE, | ||
429 | SCTP_LOWER_CWND_INACTIVE, | ||
430 | } sctp_lower_cwnd_t; | ||
431 | |||
432 | #endif /* __sctp_constants_h__ */ | ||
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h new file mode 100644 index 000000000000..960abfa48d68 --- /dev/null +++ b/include/net/sctp/sctp.h | |||
@@ -0,0 +1,620 @@ | |||
1 | /* SCTP kernel reference Implementation | ||
2 | * (C) Copyright IBM Corp. 2001, 2004 | ||
3 | * Copyright (c) 1999-2000 Cisco, Inc. | ||
4 | * Copyright (c) 1999-2001 Motorola, Inc. | ||
5 | * Copyright (c) 2001-2003 Intel Corp. | ||
6 | * | ||
7 | * This file is part of the SCTP kernel reference Implementation | ||
8 | * | ||
9 | * The base lksctp header. | ||
10 | * | ||
11 | * The SCTP reference implementation is free software; | ||
12 | * you can redistribute it and/or modify it under the terms of | ||
13 | * the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2, or (at your option) | ||
15 | * any later version. | ||
16 | * | ||
17 | * The SCTP reference implementation is distributed in the hope that it | ||
18 | * will be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
19 | * ************************ | ||
20 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
21 | * See the GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with GNU CC; see the file COPYING. If not, write to | ||
25 | * the Free Software Foundation, 59 Temple Place - Suite 330, | ||
26 | * Boston, MA 02111-1307, USA. | ||
27 | * | ||
28 | * Please send any bug reports or fixes you make to the | ||
29 | * email address(es): | ||
30 | * lksctp developers <lksctp-developers@lists.sourceforge.net> | ||
31 | * | ||
32 | * Or submit a bug report through the following website: | ||
33 | * http://www.sf.net/projects/lksctp | ||
34 | * | ||
35 | * Written or modified by: | ||
36 | * La Monte H.P. Yarroll <piggy@acm.org> | ||
37 | * Xingang Guo <xingang.guo@intel.com> | ||
38 | * Jon Grimm <jgrimm@us.ibm.com> | ||
39 | * Daisy Chang <daisyc@us.ibm.com> | ||
40 | * Sridhar Samudrala <sri@us.ibm.com> | ||
41 | * Ardelle Fan <ardelle.fan@intel.com> | ||
42 | * Ryan Layer <rmlayer@us.ibm.com> | ||
43 | * Kevin Gao <kevin.gao@intel.com> | ||
44 | * | ||
45 | * Any bugs reported given to us we will try to fix... any fixes shared will | ||
46 | * be incorporated into the next SCTP release. | ||
47 | */ | ||
48 | |||
49 | #ifndef __net_sctp_h__ | ||
50 | #define __net_sctp_h__ | ||
51 | |||
52 | /* Header Strategy. | ||
53 | * Start getting some control over the header file depencies: | ||
54 | * includes | ||
55 | * constants | ||
56 | * structs | ||
57 | * prototypes | ||
58 | * macros, externs, and inlines | ||
59 | * | ||
60 | * Move test_frame specific items out of the kernel headers | ||
61 | * and into the test frame headers. This is not perfect in any sense | ||
62 | * and will continue to evolve. | ||
63 | */ | ||
64 | |||
65 | |||
66 | #include <linux/config.h> | ||
67 | |||
68 | #ifdef TEST_FRAME | ||
69 | #undef CONFIG_PROC_FS | ||
70 | #undef CONFIG_SCTP_DBG_OBJCNT | ||
71 | #undef CONFIG_SYSCTL | ||
72 | #endif /* TEST_FRAME */ | ||
73 | |||
74 | #include <linux/types.h> | ||
75 | #include <linux/slab.h> | ||
76 | #include <linux/in.h> | ||
77 | #include <linux/tty.h> | ||
78 | #include <linux/proc_fs.h> | ||
79 | #include <linux/spinlock.h> | ||
80 | #include <linux/jiffies.h> | ||
81 | #include <linux/idr.h> | ||
82 | |||
83 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
84 | #include <net/ipv6.h> | ||
85 | #include <net/ip6_route.h> | ||
86 | #endif | ||
87 | |||
88 | #include <asm/uaccess.h> | ||
89 | #include <asm/page.h> | ||
90 | #include <net/sock.h> | ||
91 | #include <net/snmp.h> | ||
92 | #include <net/sctp/structs.h> | ||
93 | #include <net/sctp/constants.h> | ||
94 | |||
95 | |||
96 | /* Set SCTP_DEBUG flag via config if not already set. */ | ||
97 | #ifndef SCTP_DEBUG | ||
98 | #ifdef CONFIG_SCTP_DBG_MSG | ||
99 | #define SCTP_DEBUG 1 | ||
100 | #else | ||
101 | #define SCTP_DEBUG 0 | ||
102 | #endif /* CONFIG_SCTP_DBG */ | ||
103 | #endif /* SCTP_DEBUG */ | ||
104 | |||
105 | #ifdef CONFIG_IP_SCTP_MODULE | ||
106 | #define SCTP_PROTOSW_FLAG 0 | ||
107 | #else /* static! */ | ||
108 | #define SCTP_PROTOSW_FLAG INET_PROTOSW_PERMANENT | ||
109 | #endif | ||
110 | |||
111 | |||
112 | /* Certain internal static functions need to be exported when | ||
113 | * compiled into the test frame. | ||
114 | */ | ||
115 | #ifndef SCTP_STATIC | ||
116 | #define SCTP_STATIC static | ||
117 | #endif | ||
118 | |||
119 | /* | ||
120 | * Function declarations. | ||
121 | */ | ||
122 | |||
123 | /* | ||
124 | * sctp/protocol.c | ||
125 | */ | ||
126 | extern struct sock *sctp_get_ctl_sock(void); | ||
127 | extern int sctp_copy_local_addr_list(struct sctp_bind_addr *, | ||
128 | sctp_scope_t, int gfp, int flags); | ||
129 | extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family); | ||
130 | extern int sctp_register_pf(struct sctp_pf *, sa_family_t); | ||
131 | |||
132 | /* | ||
133 | * sctp/socket.c | ||
134 | */ | ||
135 | int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb); | ||
136 | int sctp_inet_listen(struct socket *sock, int backlog); | ||
137 | void sctp_write_space(struct sock *sk); | ||
138 | unsigned int sctp_poll(struct file *file, struct socket *sock, | ||
139 | poll_table *wait); | ||
140 | |||
141 | /* | ||
142 | * sctp/primitive.c | ||
143 | */ | ||
144 | int sctp_primitive_ASSOCIATE(struct sctp_association *, void *arg); | ||
145 | int sctp_primitive_SHUTDOWN(struct sctp_association *, void *arg); | ||
146 | int sctp_primitive_ABORT(struct sctp_association *, void *arg); | ||
147 | int sctp_primitive_SEND(struct sctp_association *, void *arg); | ||
148 | int sctp_primitive_REQUESTHEARTBEAT(struct sctp_association *, void *arg); | ||
149 | int sctp_primitive_ASCONF(struct sctp_association *, void *arg); | ||
150 | |||
151 | /* | ||
152 | * sctp/crc32c.c | ||
153 | */ | ||
154 | __u32 sctp_start_cksum(__u8 *ptr, __u16 count); | ||
155 | __u32 sctp_update_cksum(__u8 *ptr, __u16 count, __u32 cksum); | ||
156 | __u32 sctp_end_cksum(__u32 cksum); | ||
157 | __u32 sctp_update_copy_cksum(__u8 *, __u8 *, __u16 count, __u32 cksum); | ||
158 | |||
159 | /* | ||
160 | * sctp/input.c | ||
161 | */ | ||
162 | int sctp_rcv(struct sk_buff *skb); | ||
163 | void sctp_v4_err(struct sk_buff *skb, u32 info); | ||
164 | void sctp_hash_established(struct sctp_association *); | ||
165 | void sctp_unhash_established(struct sctp_association *); | ||
166 | void sctp_hash_endpoint(struct sctp_endpoint *); | ||
167 | void sctp_unhash_endpoint(struct sctp_endpoint *); | ||
168 | struct sock *sctp_err_lookup(int family, struct sk_buff *, | ||
169 | struct sctphdr *, struct sctp_endpoint **, | ||
170 | struct sctp_association **, | ||
171 | struct sctp_transport **); | ||
172 | void sctp_err_finish(struct sock *, struct sctp_endpoint *, | ||
173 | struct sctp_association *); | ||
174 | void sctp_icmp_frag_needed(struct sock *, struct sctp_association *, | ||
175 | struct sctp_transport *t, __u32 pmtu); | ||
176 | void sctp_icmp_proto_unreachable(struct sock *sk, | ||
177 | struct sctp_endpoint *ep, | ||
178 | struct sctp_association *asoc, | ||
179 | struct sctp_transport *t); | ||
180 | |||
181 | /* | ||
182 | * Section: Macros, externs, and inlines | ||
183 | */ | ||
184 | |||
185 | |||
186 | #ifdef TEST_FRAME | ||
187 | #include <test_frame.h> | ||
188 | #else | ||
189 | |||
190 | /* spin lock wrappers. */ | ||
191 | #define sctp_spin_lock_irqsave(lock, flags) spin_lock_irqsave(lock, flags) | ||
192 | #define sctp_spin_unlock_irqrestore(lock, flags) \ | ||
193 | spin_unlock_irqrestore(lock, flags) | ||
194 | #define sctp_local_bh_disable() local_bh_disable() | ||
195 | #define sctp_local_bh_enable() local_bh_enable() | ||
196 | #define sctp_spin_lock(lock) spin_lock(lock) | ||
197 | #define sctp_spin_unlock(lock) spin_unlock(lock) | ||
198 | #define sctp_write_lock(lock) write_lock(lock) | ||
199 | #define sctp_write_unlock(lock) write_unlock(lock) | ||
200 | #define sctp_read_lock(lock) read_lock(lock) | ||
201 | #define sctp_read_unlock(lock) read_unlock(lock) | ||
202 | |||
203 | /* sock lock wrappers. */ | ||
204 | #define sctp_lock_sock(sk) lock_sock(sk) | ||
205 | #define sctp_release_sock(sk) release_sock(sk) | ||
206 | #define sctp_bh_lock_sock(sk) bh_lock_sock(sk) | ||
207 | #define sctp_bh_unlock_sock(sk) bh_unlock_sock(sk) | ||
208 | #define SCTP_SOCK_SLEEP_PRE(sk) SOCK_SLEEP_PRE(sk) | ||
209 | #define SCTP_SOCK_SLEEP_POST(sk) SOCK_SLEEP_POST(sk) | ||
210 | |||
211 | /* SCTP SNMP MIB stats handlers */ | ||
212 | DECLARE_SNMP_STAT(struct sctp_mib, sctp_statistics); | ||
213 | #define SCTP_INC_STATS(field) SNMP_INC_STATS(sctp_statistics, field) | ||
214 | #define SCTP_INC_STATS_BH(field) SNMP_INC_STATS_BH(sctp_statistics, field) | ||
215 | #define SCTP_INC_STATS_USER(field) SNMP_INC_STATS_USER(sctp_statistics, field) | ||
216 | #define SCTP_DEC_STATS(field) SNMP_DEC_STATS(sctp_statistics, field) | ||
217 | |||
218 | #endif /* !TEST_FRAME */ | ||
219 | |||
220 | |||
221 | /* Print debugging messages. */ | ||
222 | #if SCTP_DEBUG | ||
223 | extern int sctp_debug_flag; | ||
224 | #define SCTP_DEBUG_PRINTK(whatever...) \ | ||
225 | ((void) (sctp_debug_flag && printk(KERN_DEBUG whatever))) | ||
226 | #define SCTP_ENABLE_DEBUG { sctp_debug_flag = 1; } | ||
227 | #define SCTP_DISABLE_DEBUG { sctp_debug_flag = 0; } | ||
228 | |||
229 | #define SCTP_ASSERT(expr, str, func) \ | ||
230 | if (!(expr)) { \ | ||
231 | SCTP_DEBUG_PRINTK("Assertion Failed: %s(%s) at %s:%s:%d\n", \ | ||
232 | str, (#expr), __FILE__, __FUNCTION__, __LINE__); \ | ||
233 | func; \ | ||
234 | } | ||
235 | |||
236 | #else /* SCTP_DEBUG */ | ||
237 | |||
238 | #define SCTP_DEBUG_PRINTK(whatever...) | ||
239 | #define SCTP_ENABLE_DEBUG | ||
240 | #define SCTP_DISABLE_DEBUG | ||
241 | #define SCTP_ASSERT(expr, str, func) | ||
242 | |||
243 | #endif /* SCTP_DEBUG */ | ||
244 | |||
245 | |||
246 | /* | ||
247 | * Macros for keeping a global reference of object allocations. | ||
248 | */ | ||
249 | #ifdef CONFIG_SCTP_DBG_OBJCNT | ||
250 | |||
251 | extern atomic_t sctp_dbg_objcnt_sock; | ||
252 | extern atomic_t sctp_dbg_objcnt_ep; | ||
253 | extern atomic_t sctp_dbg_objcnt_assoc; | ||
254 | extern atomic_t sctp_dbg_objcnt_transport; | ||
255 | extern atomic_t sctp_dbg_objcnt_chunk; | ||
256 | extern atomic_t sctp_dbg_objcnt_bind_addr; | ||
257 | extern atomic_t sctp_dbg_objcnt_bind_bucket; | ||
258 | extern atomic_t sctp_dbg_objcnt_addr; | ||
259 | extern atomic_t sctp_dbg_objcnt_ssnmap; | ||
260 | extern atomic_t sctp_dbg_objcnt_datamsg; | ||
261 | |||
262 | /* Macros to atomically increment/decrement objcnt counters. */ | ||
263 | #define SCTP_DBG_OBJCNT_INC(name) \ | ||
264 | atomic_inc(&sctp_dbg_objcnt_## name) | ||
265 | #define SCTP_DBG_OBJCNT_DEC(name) \ | ||
266 | atomic_dec(&sctp_dbg_objcnt_## name) | ||
267 | #define SCTP_DBG_OBJCNT(name) \ | ||
268 | atomic_t sctp_dbg_objcnt_## name = ATOMIC_INIT(0) | ||
269 | |||
270 | /* Macro to help create new entries in in the global array of | ||
271 | * objcnt counters. | ||
272 | */ | ||
273 | #define SCTP_DBG_OBJCNT_ENTRY(name) \ | ||
274 | {.label= #name, .counter= &sctp_dbg_objcnt_## name} | ||
275 | |||
276 | void sctp_dbg_objcnt_init(void); | ||
277 | void sctp_dbg_objcnt_exit(void); | ||
278 | |||
279 | #else | ||
280 | |||
281 | #define SCTP_DBG_OBJCNT_INC(name) | ||
282 | #define SCTP_DBG_OBJCNT_DEC(name) | ||
283 | |||
284 | static inline void sctp_dbg_objcnt_init(void) { return; } | ||
285 | static inline void sctp_dbg_objcnt_exit(void) { return; } | ||
286 | |||
287 | #endif /* CONFIG_SCTP_DBG_OBJCOUNT */ | ||
288 | |||
289 | #if defined CONFIG_SYSCTL | ||
290 | void sctp_sysctl_register(void); | ||
291 | void sctp_sysctl_unregister(void); | ||
292 | #else | ||
293 | static inline void sctp_sysctl_register(void) { return; } | ||
294 | static inline void sctp_sysctl_unregister(void) { return; } | ||
295 | static inline int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen, | ||
296 | void __user *oldval, size_t __user *oldlenp, | ||
297 | void __user *newval, size_t newlen, void **context) { | ||
298 | return -ENOSYS; | ||
299 | } | ||
300 | #endif | ||
301 | |||
302 | /* Size of Supported Address Parameter for 'x' address types. */ | ||
303 | #define SCTP_SAT_LEN(x) (sizeof(struct sctp_paramhdr) + (x) * sizeof(__u16)) | ||
304 | |||
305 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
306 | |||
307 | int sctp_v6_init(void); | ||
308 | void sctp_v6_exit(void); | ||
309 | |||
310 | #else /* #ifdef defined(CONFIG_IPV6) */ | ||
311 | |||
312 | static inline int sctp_v6_init(void) { return 0; } | ||
313 | static inline void sctp_v6_exit(void) { return; } | ||
314 | |||
315 | #endif /* #if defined(CONFIG_IPV6) */ | ||
316 | |||
317 | /* Some wrappers, in case crypto not available. */ | ||
318 | #if defined (CONFIG_CRYPTO_HMAC) | ||
319 | #define sctp_crypto_alloc_tfm crypto_alloc_tfm | ||
320 | #define sctp_crypto_free_tfm crypto_free_tfm | ||
321 | #define sctp_crypto_hmac crypto_hmac | ||
322 | #else | ||
323 | #define sctp_crypto_alloc_tfm(x...) NULL | ||
324 | #define sctp_crypto_free_tfm(x...) | ||
325 | #define sctp_crypto_hmac(x...) | ||
326 | #endif | ||
327 | |||
328 | |||
329 | /* Map an association to an assoc_id. */ | ||
330 | static inline sctp_assoc_t sctp_assoc2id(const struct sctp_association *asoc) | ||
331 | { | ||
332 | return (asoc?asoc->assoc_id:0); | ||
333 | } | ||
334 | |||
335 | /* Look up the association by its id. */ | ||
336 | struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id); | ||
337 | |||
338 | |||
339 | /* A macro to walk a list of skbs. */ | ||
340 | #define sctp_skb_for_each(pos, head, tmp) \ | ||
341 | for (pos = (head)->next;\ | ||
342 | tmp = (pos)->next, pos != ((struct sk_buff *)(head));\ | ||
343 | pos = tmp) | ||
344 | |||
345 | |||
346 | /* A helper to append an entire skb list (list) to another (head). */ | ||
347 | static inline void sctp_skb_list_tail(struct sk_buff_head *list, | ||
348 | struct sk_buff_head *head) | ||
349 | { | ||
350 | unsigned long flags; | ||
351 | |||
352 | sctp_spin_lock_irqsave(&head->lock, flags); | ||
353 | sctp_spin_lock(&list->lock); | ||
354 | |||
355 | list_splice((struct list_head *)list, (struct list_head *)head->prev); | ||
356 | |||
357 | head->qlen += list->qlen; | ||
358 | list->qlen = 0; | ||
359 | |||
360 | sctp_spin_unlock(&list->lock); | ||
361 | sctp_spin_unlock_irqrestore(&head->lock, flags); | ||
362 | } | ||
363 | |||
364 | /** | ||
365 | * sctp_list_dequeue - remove from the head of the queue | ||
366 | * @list: list to dequeue from | ||
367 | * | ||
368 | * Remove the head of the list. The head item is | ||
369 | * returned or %NULL if the list is empty. | ||
370 | */ | ||
371 | |||
372 | static inline struct list_head *sctp_list_dequeue(struct list_head *list) | ||
373 | { | ||
374 | struct list_head *result = NULL; | ||
375 | |||
376 | if (list->next != list) { | ||
377 | result = list->next; | ||
378 | list->next = result->next; | ||
379 | list->next->prev = list; | ||
380 | INIT_LIST_HEAD(result); | ||
381 | } | ||
382 | return result; | ||
383 | } | ||
384 | |||
385 | /* Tests if the list has one and only one entry. */ | ||
386 | static inline int sctp_list_single_entry(struct list_head *head) | ||
387 | { | ||
388 | return ((head->next != head) && (head->next == head->prev)); | ||
389 | } | ||
390 | |||
391 | /* Calculate the size (in bytes) occupied by the data of an iovec. */ | ||
392 | static inline size_t get_user_iov_size(struct iovec *iov, int iovlen) | ||
393 | { | ||
394 | size_t retval = 0; | ||
395 | |||
396 | for (; iovlen > 0; --iovlen) { | ||
397 | retval += iov->iov_len; | ||
398 | iov++; | ||
399 | } | ||
400 | |||
401 | return retval; | ||
402 | } | ||
403 | |||
404 | /* Generate a random jitter in the range of -50% ~ +50% of input RTO. */ | ||
405 | static inline __s32 sctp_jitter(__u32 rto) | ||
406 | { | ||
407 | static __u32 sctp_rand; | ||
408 | __s32 ret; | ||
409 | |||
410 | /* Avoid divide by zero. */ | ||
411 | if (!rto) | ||
412 | rto = 1; | ||
413 | |||
414 | sctp_rand += jiffies; | ||
415 | sctp_rand ^= (sctp_rand << 12); | ||
416 | sctp_rand ^= (sctp_rand >> 20); | ||
417 | |||
418 | /* Choose random number from 0 to rto, then move to -50% ~ +50% | ||
419 | * of rto. | ||
420 | */ | ||
421 | ret = sctp_rand % rto - (rto >> 1); | ||
422 | return ret; | ||
423 | } | ||
424 | |||
425 | /* Break down data chunks at this point. */ | ||
426 | static inline int sctp_frag_point(const struct sctp_sock *sp, int pmtu) | ||
427 | { | ||
428 | int frag = pmtu; | ||
429 | |||
430 | frag -= sp->pf->af->net_header_len; | ||
431 | frag -= sizeof(struct sctphdr) + sizeof(struct sctp_data_chunk); | ||
432 | |||
433 | if (sp->user_frag) | ||
434 | frag = min_t(int, frag, sp->user_frag); | ||
435 | |||
436 | frag = min_t(int, frag, SCTP_MAX_CHUNK_LEN); | ||
437 | |||
438 | return frag; | ||
439 | } | ||
440 | |||
441 | /* Walk through a list of TLV parameters. Don't trust the | ||
442 | * individual parameter lengths and instead depend on | ||
443 | * the chunk length to indicate when to stop. Make sure | ||
444 | * there is room for a param header too. | ||
445 | */ | ||
446 | #define sctp_walk_params(pos, chunk, member)\ | ||
447 | _sctp_walk_params((pos), (chunk), WORD_ROUND(ntohs((chunk)->chunk_hdr.length)), member) | ||
448 | |||
449 | #define _sctp_walk_params(pos, chunk, end, member)\ | ||
450 | for (pos.v = chunk->member;\ | ||
451 | pos.v <= (void *)chunk + end - sizeof(sctp_paramhdr_t) &&\ | ||
452 | pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)) &&\ | ||
453 | ntohs(pos.p->length) >= sizeof(sctp_paramhdr_t);\ | ||
454 | pos.v += WORD_ROUND(ntohs(pos.p->length))) | ||
455 | |||
456 | #define sctp_walk_errors(err, chunk_hdr)\ | ||
457 | _sctp_walk_errors((err), (chunk_hdr), ntohs((chunk_hdr)->length)) | ||
458 | |||
459 | #define _sctp_walk_errors(err, chunk_hdr, end)\ | ||
460 | for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \ | ||
461 | sizeof(sctp_chunkhdr_t));\ | ||
462 | (void *)err <= (void *)chunk_hdr + end - sizeof(sctp_errhdr_t) &&\ | ||
463 | (void *)err <= (void *)chunk_hdr + end - WORD_ROUND(ntohs(err->length)) &&\ | ||
464 | ntohs(err->length) >= sizeof(sctp_errhdr_t); \ | ||
465 | err = (sctp_errhdr_t *)((void *)err + WORD_ROUND(ntohs(err->length)))) | ||
466 | |||
467 | #define sctp_walk_fwdtsn(pos, chunk)\ | ||
468 | _sctp_walk_fwdtsn((pos), (chunk), ntohs((chunk)->chunk_hdr->length) - sizeof(struct sctp_fwdtsn_chunk)) | ||
469 | |||
470 | #define _sctp_walk_fwdtsn(pos, chunk, end)\ | ||
471 | for (pos = chunk->subh.fwdtsn_hdr->skip;\ | ||
472 | (void *)pos <= (void *)chunk->subh.fwdtsn_hdr->skip + end - sizeof(struct sctp_fwdtsn_skip);\ | ||
473 | pos++) | ||
474 | |||
475 | /* Round an int up to the next multiple of 4. */ | ||
476 | #define WORD_ROUND(s) (((s)+3)&~3) | ||
477 | |||
478 | /* Make a new instance of type. */ | ||
479 | #define t_new(type, flags) (type *)kmalloc(sizeof(type), flags) | ||
480 | |||
481 | /* Compare two timevals. */ | ||
482 | #define tv_lt(s, t) \ | ||
483 | (s.tv_sec < t.tv_sec || (s.tv_sec == t.tv_sec && s.tv_usec < t.tv_usec)) | ||
484 | |||
485 | /* Add tv1 to tv2. */ | ||
486 | #define TIMEVAL_ADD(tv1, tv2) \ | ||
487 | ({ \ | ||
488 | suseconds_t usecs = (tv2).tv_usec + (tv1).tv_usec; \ | ||
489 | time_t secs = (tv2).tv_sec + (tv1).tv_sec; \ | ||
490 | \ | ||
491 | if (usecs >= 1000000) { \ | ||
492 | usecs -= 1000000; \ | ||
493 | secs++; \ | ||
494 | } \ | ||
495 | (tv2).tv_sec = secs; \ | ||
496 | (tv2).tv_usec = usecs; \ | ||
497 | }) | ||
498 | |||
499 | /* External references. */ | ||
500 | |||
501 | extern struct proto sctp_prot; | ||
502 | extern struct proto sctpv6_prot; | ||
503 | extern struct proc_dir_entry *proc_net_sctp; | ||
504 | void sctp_put_port(struct sock *sk); | ||
505 | |||
506 | extern struct idr sctp_assocs_id; | ||
507 | extern spinlock_t sctp_assocs_id_lock; | ||
508 | |||
509 | /* Static inline functions. */ | ||
510 | |||
511 | /* Convert from an IP version number to an Address Family symbol. */ | ||
512 | static inline int ipver2af(__u8 ipver) | ||
513 | { | ||
514 | switch (ipver) { | ||
515 | case 4: | ||
516 | return AF_INET; | ||
517 | case 6: | ||
518 | return AF_INET6; | ||
519 | default: | ||
520 | return 0; | ||
521 | }; | ||
522 | } | ||
523 | |||
524 | /* Convert from an address parameter type to an address family. */ | ||
525 | static inline int param_type2af(__u16 type) | ||
526 | { | ||
527 | switch (type) { | ||
528 | case SCTP_PARAM_IPV4_ADDRESS: | ||
529 | return AF_INET; | ||
530 | case SCTP_PARAM_IPV6_ADDRESS: | ||
531 | return AF_INET6; | ||
532 | default: | ||
533 | return 0; | ||
534 | }; | ||
535 | } | ||
536 | |||
537 | /* Perform some sanity checks. */ | ||
538 | static inline int sctp_sanity_check(void) | ||
539 | { | ||
540 | SCTP_ASSERT(sizeof(struct sctp_ulpevent) <= | ||
541 | sizeof(((struct sk_buff *)0)->cb), | ||
542 | "SCTP: ulpevent does not fit in skb!\n", return 0); | ||
543 | |||
544 | return 1; | ||
545 | } | ||
546 | |||
547 | /* Warning: The following hash functions assume a power of two 'size'. */ | ||
548 | /* This is the hash function for the SCTP port hash table. */ | ||
549 | static inline int sctp_phashfn(__u16 lport) | ||
550 | { | ||
551 | return (lport & (sctp_port_hashsize - 1)); | ||
552 | } | ||
553 | |||
554 | /* This is the hash function for the endpoint hash table. */ | ||
555 | static inline int sctp_ep_hashfn(__u16 lport) | ||
556 | { | ||
557 | return (lport & (sctp_ep_hashsize - 1)); | ||
558 | } | ||
559 | |||
560 | /* This is the hash function for the association hash table. */ | ||
561 | static inline int sctp_assoc_hashfn(__u16 lport, __u16 rport) | ||
562 | { | ||
563 | int h = (lport << 16) + rport; | ||
564 | h ^= h>>8; | ||
565 | return (h & (sctp_assoc_hashsize - 1)); | ||
566 | } | ||
567 | |||
568 | /* This is the hash function for the association hash table. This is | ||
569 | * not used yet, but could be used as a better hash function when | ||
570 | * we have a vtag. | ||
571 | */ | ||
572 | static inline int sctp_vtag_hashfn(__u16 lport, __u16 rport, __u32 vtag) | ||
573 | { | ||
574 | int h = (lport << 16) + rport; | ||
575 | h ^= vtag; | ||
576 | return (h & (sctp_assoc_hashsize-1)); | ||
577 | } | ||
578 | |||
579 | /* Is a socket of this style? */ | ||
580 | #define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style)) | ||
581 | static inline int __sctp_style(const struct sock *sk, sctp_socket_type_t style) | ||
582 | { | ||
583 | return sctp_sk(sk)->type == style; | ||
584 | } | ||
585 | |||
586 | /* Is the association in this state? */ | ||
587 | #define sctp_state(asoc, state) __sctp_state((asoc), (SCTP_STATE_##state)) | ||
588 | static inline int __sctp_state(const struct sctp_association *asoc, | ||
589 | sctp_state_t state) | ||
590 | { | ||
591 | return asoc->state == state; | ||
592 | } | ||
593 | |||
594 | /* Is the socket in this state? */ | ||
595 | #define sctp_sstate(sk, state) __sctp_sstate((sk), (SCTP_SS_##state)) | ||
596 | static inline int __sctp_sstate(const struct sock *sk, sctp_sock_state_t state) | ||
597 | { | ||
598 | return sk->sk_state == state; | ||
599 | } | ||
600 | |||
601 | /* Map v4-mapped v6 address back to v4 address */ | ||
602 | static inline void sctp_v6_map_v4(union sctp_addr *addr) | ||
603 | { | ||
604 | addr->v4.sin_family = AF_INET; | ||
605 | addr->v4.sin_port = addr->v6.sin6_port; | ||
606 | addr->v4.sin_addr.s_addr = addr->v6.sin6_addr.s6_addr32[3]; | ||
607 | } | ||
608 | |||
609 | /* Map v4 address to v4-mapped v6 address */ | ||
610 | static inline void sctp_v4_map_v6(union sctp_addr *addr) | ||
611 | { | ||
612 | addr->v6.sin6_family = AF_INET6; | ||
613 | addr->v6.sin6_port = addr->v4.sin_port; | ||
614 | addr->v6.sin6_addr.s6_addr32[3] = addr->v4.sin_addr.s_addr; | ||
615 | addr->v6.sin6_addr.s6_addr32[0] = 0; | ||
616 | addr->v6.sin6_addr.s6_addr32[1] = 0; | ||
617 | addr->v6.sin6_addr.s6_addr32[2] = htonl(0x0000ffff); | ||
618 | } | ||
619 | |||
620 | #endif /* __net_sctp_h__ */ | ||
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h new file mode 100644 index 000000000000..5576db56324d --- /dev/null +++ b/include/net/sctp/sm.h | |||
@@ -0,0 +1,442 @@ | |||
1 | /* SCTP kernel reference Implementation | ||
2 | * (C) Copyright IBM Corp. 2001, 2004 | ||
3 | * Copyright (c) 1999-2000 Cisco, Inc. | ||
4 | * Copyright (c) 1999-2001 Motorola, Inc. | ||
5 | * Copyright (c) 2001 Intel Corp. | ||
6 | * | ||
7 | * This file is part of the SCTP kernel reference Implementation | ||
8 | * | ||
9 | * These are definitions needed by the state machine. | ||
10 | * | ||
11 | * The SCTP reference implementation is free software; | ||
12 | * you can redistribute it and/or modify it under the terms of | ||
13 | * the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2, or (at your option) | ||
15 | * any later version. | ||
16 | * | ||
17 | * The SCTP reference implementation is distributed in the hope that it | ||
18 | * will be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
19 | * ************************ | ||
20 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
21 | * See the GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with GNU CC; see the file COPYING. If not, write to | ||
25 | * the Free Software Foundation, 59 Temple Place - Suite 330, | ||
26 | * Boston, MA 02111-1307, USA. | ||
27 | * | ||
28 | * Please send any bug reports or fixes you make to the | ||
29 | * email addresses: | ||
30 | * lksctp developers <lksctp-developers@lists.sourceforge.net> | ||
31 | * | ||
32 | * Or submit a bug report through the following website: | ||
33 | * http://www.sf.net/projects/lksctp | ||
34 | * | ||
35 | * Written or modified by: | ||
36 | * La Monte H.P. Yarroll <piggy@acm.org> | ||
37 | * Karl Knutson <karl@athena.chicago.il.us> | ||
38 | * Xingang Guo <xingang.guo@intel.com> | ||
39 | * Jon Grimm <jgrimm@us.ibm.com> | ||
40 | * Dajiang Zhang <dajiang.zhang@nokia.com> | ||
41 | * Sridhar Samudrala <sri@us.ibm.com> | ||
42 | * Daisy Chang <daisyc@us.ibm.com> | ||
43 | * Ardelle Fan <ardelle.fan@intel.com> | ||
44 | * Kevin Gao <kevin.gao@intel.com> | ||
45 | * | ||
46 | * Any bugs reported given to us we will try to fix... any fixes shared will | ||
47 | * be incorporated into the next SCTP release. | ||
48 | */ | ||
49 | |||
50 | #include <linux/types.h> | ||
51 | #include <linux/compiler.h> | ||
52 | #include <linux/slab.h> | ||
53 | #include <linux/in.h> | ||
54 | #include <net/sctp/command.h> | ||
55 | #include <net/sctp/sctp.h> | ||
56 | |||
57 | #ifndef __sctp_sm_h__ | ||
58 | #define __sctp_sm_h__ | ||
59 | |||
60 | /* | ||
61 | * Possible values for the disposition are: | ||
62 | */ | ||
63 | typedef enum { | ||
64 | SCTP_DISPOSITION_DISCARD, /* No further processing. */ | ||
65 | SCTP_DISPOSITION_CONSUME, /* Process return values normally. */ | ||
66 | SCTP_DISPOSITION_NOMEM, /* We ran out of memory--recover. */ | ||
67 | SCTP_DISPOSITION_DELETE_TCB, /* Close the association. */ | ||
68 | SCTP_DISPOSITION_ABORT, /* Close the association NOW. */ | ||
69 | SCTP_DISPOSITION_VIOLATION, /* The peer is misbehaving. */ | ||
70 | SCTP_DISPOSITION_NOT_IMPL, /* This entry is not implemented. */ | ||
71 | SCTP_DISPOSITION_ERROR, /* This is plain old user error. */ | ||
72 | SCTP_DISPOSITION_BUG, /* This is a bug. */ | ||
73 | } sctp_disposition_t; | ||
74 | |||
75 | typedef struct { | ||
76 | int name; | ||
77 | int action; | ||
78 | } sctp_sm_command_t; | ||
79 | |||
80 | typedef sctp_disposition_t (sctp_state_fn_t) (const struct sctp_endpoint *, | ||
81 | const struct sctp_association *, | ||
82 | const sctp_subtype_t type, | ||
83 | void *arg, | ||
84 | sctp_cmd_seq_t *); | ||
85 | typedef void (sctp_timer_event_t) (unsigned long); | ||
86 | typedef struct { | ||
87 | sctp_state_fn_t *fn; | ||
88 | const char *name; | ||
89 | } sctp_sm_table_entry_t; | ||
90 | |||
91 | /* A naming convention of "sctp_sf_xxx" applies to all the state functions | ||
92 | * currently in use. | ||
93 | */ | ||
94 | |||
95 | /* Prototypes for generic state functions. */ | ||
96 | sctp_state_fn_t sctp_sf_not_impl; | ||
97 | sctp_state_fn_t sctp_sf_bug; | ||
98 | |||
99 | /* Prototypes for gener timer state functions. */ | ||
100 | sctp_state_fn_t sctp_sf_timer_ignore; | ||
101 | |||
102 | /* Prototypes for chunk state functions. */ | ||
103 | sctp_state_fn_t sctp_sf_do_9_1_abort; | ||
104 | sctp_state_fn_t sctp_sf_cookie_wait_abort; | ||
105 | sctp_state_fn_t sctp_sf_cookie_echoed_abort; | ||
106 | sctp_state_fn_t sctp_sf_shutdown_pending_abort; | ||
107 | sctp_state_fn_t sctp_sf_shutdown_sent_abort; | ||
108 | sctp_state_fn_t sctp_sf_shutdown_ack_sent_abort; | ||
109 | sctp_state_fn_t sctp_sf_do_5_1B_init; | ||
110 | sctp_state_fn_t sctp_sf_do_5_1C_ack; | ||
111 | sctp_state_fn_t sctp_sf_do_5_1D_ce; | ||
112 | sctp_state_fn_t sctp_sf_do_5_1E_ca; | ||
113 | sctp_state_fn_t sctp_sf_do_4_C; | ||
114 | sctp_state_fn_t sctp_sf_eat_data_6_2; | ||
115 | sctp_state_fn_t sctp_sf_eat_data_fast_4_4; | ||
116 | sctp_state_fn_t sctp_sf_eat_sack_6_2; | ||
117 | sctp_state_fn_t sctp_sf_tabort_8_4_8; | ||
118 | sctp_state_fn_t sctp_sf_operr_notify; | ||
119 | sctp_state_fn_t sctp_sf_t1_timer_expire; | ||
120 | sctp_state_fn_t sctp_sf_t2_timer_expire; | ||
121 | sctp_state_fn_t sctp_sf_t4_timer_expire; | ||
122 | sctp_state_fn_t sctp_sf_t5_timer_expire; | ||
123 | sctp_state_fn_t sctp_sf_sendbeat_8_3; | ||
124 | sctp_state_fn_t sctp_sf_beat_8_3; | ||
125 | sctp_state_fn_t sctp_sf_backbeat_8_3; | ||
126 | sctp_state_fn_t sctp_sf_do_9_2_final; | ||
127 | sctp_state_fn_t sctp_sf_do_9_2_shutdown; | ||
128 | sctp_state_fn_t sctp_sf_do_ecn_cwr; | ||
129 | sctp_state_fn_t sctp_sf_do_ecne; | ||
130 | sctp_state_fn_t sctp_sf_ootb; | ||
131 | sctp_state_fn_t sctp_sf_pdiscard; | ||
132 | sctp_state_fn_t sctp_sf_violation; | ||
133 | sctp_state_fn_t sctp_sf_violation_chunklen; | ||
134 | sctp_state_fn_t sctp_sf_discard_chunk; | ||
135 | sctp_state_fn_t sctp_sf_do_5_2_1_siminit; | ||
136 | sctp_state_fn_t sctp_sf_do_5_2_2_dupinit; | ||
137 | sctp_state_fn_t sctp_sf_do_5_2_4_dupcook; | ||
138 | sctp_state_fn_t sctp_sf_unk_chunk; | ||
139 | sctp_state_fn_t sctp_sf_do_8_5_1_E_sa; | ||
140 | sctp_state_fn_t sctp_sf_cookie_echoed_err; | ||
141 | sctp_state_fn_t sctp_sf_do_asconf; | ||
142 | sctp_state_fn_t sctp_sf_do_asconf_ack; | ||
143 | sctp_state_fn_t sctp_sf_do_9_2_reshutack; | ||
144 | sctp_state_fn_t sctp_sf_eat_fwd_tsn; | ||
145 | sctp_state_fn_t sctp_sf_eat_fwd_tsn_fast; | ||
146 | |||
147 | /* Prototypes for primitive event state functions. */ | ||
148 | sctp_state_fn_t sctp_sf_do_prm_asoc; | ||
149 | sctp_state_fn_t sctp_sf_do_prm_send; | ||
150 | sctp_state_fn_t sctp_sf_do_9_2_prm_shutdown; | ||
151 | sctp_state_fn_t sctp_sf_cookie_wait_prm_shutdown; | ||
152 | sctp_state_fn_t sctp_sf_cookie_echoed_prm_shutdown; | ||
153 | sctp_state_fn_t sctp_sf_do_9_1_prm_abort; | ||
154 | sctp_state_fn_t sctp_sf_cookie_wait_prm_abort; | ||
155 | sctp_state_fn_t sctp_sf_cookie_echoed_prm_abort; | ||
156 | sctp_state_fn_t sctp_sf_shutdown_pending_prm_abort; | ||
157 | sctp_state_fn_t sctp_sf_shutdown_sent_prm_abort; | ||
158 | sctp_state_fn_t sctp_sf_shutdown_ack_sent_prm_abort; | ||
159 | sctp_state_fn_t sctp_sf_error_closed; | ||
160 | sctp_state_fn_t sctp_sf_error_shutdown; | ||
161 | sctp_state_fn_t sctp_sf_ignore_primitive; | ||
162 | sctp_state_fn_t sctp_sf_do_prm_requestheartbeat; | ||
163 | sctp_state_fn_t sctp_sf_do_prm_asconf; | ||
164 | |||
165 | /* Prototypes for other event state functions. */ | ||
166 | sctp_state_fn_t sctp_sf_do_9_2_start_shutdown; | ||
167 | sctp_state_fn_t sctp_sf_do_9_2_shutdown_ack; | ||
168 | sctp_state_fn_t sctp_sf_ignore_other; | ||
169 | sctp_state_fn_t sctp_sf_cookie_wait_icmp_abort; | ||
170 | |||
171 | /* Prototypes for timeout event state functions. */ | ||
172 | sctp_state_fn_t sctp_sf_do_6_3_3_rtx; | ||
173 | sctp_state_fn_t sctp_sf_do_6_2_sack; | ||
174 | sctp_state_fn_t sctp_sf_autoclose_timer_expire; | ||
175 | |||
176 | /* Prototypes for utility support functions. */ | ||
177 | __u8 sctp_get_chunk_type(struct sctp_chunk *chunk); | ||
178 | const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t, | ||
179 | sctp_state_t, | ||
180 | sctp_subtype_t); | ||
181 | int sctp_chunk_iif(const struct sctp_chunk *); | ||
182 | struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *, | ||
183 | struct sctp_chunk *, | ||
184 | int gfp); | ||
185 | __u32 sctp_generate_verification_tag(void); | ||
186 | void sctp_populate_tie_tags(__u8 *cookie, __u32 curTag, __u32 hisTag); | ||
187 | |||
188 | /* Prototypes for chunk-building functions. */ | ||
189 | struct sctp_chunk *sctp_make_init(const struct sctp_association *, | ||
190 | const struct sctp_bind_addr *, | ||
191 | int gfp, int vparam_len); | ||
192 | struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *, | ||
193 | const struct sctp_chunk *, | ||
194 | const int gfp, | ||
195 | const int unkparam_len); | ||
196 | struct sctp_chunk *sctp_make_cookie_echo(const struct sctp_association *, | ||
197 | const struct sctp_chunk *); | ||
198 | struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *, | ||
199 | const struct sctp_chunk *); | ||
200 | struct sctp_chunk *sctp_make_cwr(const struct sctp_association *, | ||
201 | const __u32 lowest_tsn, | ||
202 | const struct sctp_chunk *); | ||
203 | struct sctp_chunk * sctp_make_datafrag_empty(struct sctp_association *, | ||
204 | const struct sctp_sndrcvinfo *sinfo, | ||
205 | int len, const __u8 flags, | ||
206 | __u16 ssn); | ||
207 | struct sctp_chunk *sctp_make_ecne(const struct sctp_association *, | ||
208 | const __u32); | ||
209 | struct sctp_chunk *sctp_make_sack(const struct sctp_association *); | ||
210 | struct sctp_chunk *sctp_make_shutdown(const struct sctp_association *asoc, | ||
211 | const struct sctp_chunk *chunk); | ||
212 | struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc, | ||
213 | const struct sctp_chunk *); | ||
214 | struct sctp_chunk *sctp_make_shutdown_complete(const struct sctp_association *, | ||
215 | const struct sctp_chunk *); | ||
216 | void sctp_init_cause(struct sctp_chunk *, __u16 cause, const void *, size_t); | ||
217 | struct sctp_chunk *sctp_make_abort(const struct sctp_association *, | ||
218 | const struct sctp_chunk *, | ||
219 | const size_t hint); | ||
220 | struct sctp_chunk *sctp_make_abort_no_data(const struct sctp_association *, | ||
221 | const struct sctp_chunk *, | ||
222 | __u32 tsn); | ||
223 | struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *, | ||
224 | const struct sctp_chunk *, | ||
225 | const struct msghdr *); | ||
226 | struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *, | ||
227 | const struct sctp_chunk *, | ||
228 | const __u8 *, | ||
229 | const size_t ); | ||
230 | struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *, | ||
231 | const struct sctp_transport *, | ||
232 | const void *payload, | ||
233 | const size_t paylen); | ||
234 | struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *, | ||
235 | const struct sctp_chunk *, | ||
236 | const void *payload, | ||
237 | const size_t paylen); | ||
238 | struct sctp_chunk *sctp_make_op_error(const struct sctp_association *, | ||
239 | const struct sctp_chunk *chunk, | ||
240 | __u16 cause_code, | ||
241 | const void *payload, | ||
242 | size_t paylen); | ||
243 | |||
244 | struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *, | ||
245 | union sctp_addr *, | ||
246 | struct sockaddr *, | ||
247 | int, __u16); | ||
248 | struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc, | ||
249 | union sctp_addr *addr); | ||
250 | struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, | ||
251 | struct sctp_chunk *asconf); | ||
252 | int sctp_process_asconf_ack(struct sctp_association *asoc, | ||
253 | struct sctp_chunk *asconf_ack); | ||
254 | struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc, | ||
255 | __u32 new_cum_tsn, size_t nstreams, | ||
256 | struct sctp_fwdtsn_skip *skiplist); | ||
257 | |||
258 | void sctp_chunk_assign_tsn(struct sctp_chunk *); | ||
259 | void sctp_chunk_assign_ssn(struct sctp_chunk *); | ||
260 | |||
261 | void sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, __u16 error); | ||
262 | |||
263 | /* Prototypes for statetable processing. */ | ||
264 | |||
265 | int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype, | ||
266 | sctp_state_t state, | ||
267 | struct sctp_endpoint *, | ||
268 | struct sctp_association *asoc, | ||
269 | void *event_arg, | ||
270 | int gfp); | ||
271 | |||
272 | /* 2nd level prototypes */ | ||
273 | void sctp_generate_t3_rtx_event(unsigned long peer); | ||
274 | void sctp_generate_heartbeat_event(unsigned long peer); | ||
275 | |||
276 | void sctp_ootb_pkt_free(struct sctp_packet *); | ||
277 | |||
278 | struct sctp_association *sctp_unpack_cookie(const struct sctp_endpoint *, | ||
279 | const struct sctp_association *, | ||
280 | struct sctp_chunk *, int gfp, int *err, | ||
281 | struct sctp_chunk **err_chk_p); | ||
282 | int sctp_addip_addr_config(struct sctp_association *, sctp_param_t, | ||
283 | struct sockaddr_storage*, int); | ||
284 | |||
285 | /* 3rd level prototypes */ | ||
286 | __u32 sctp_generate_tag(const struct sctp_endpoint *); | ||
287 | __u32 sctp_generate_tsn(const struct sctp_endpoint *); | ||
288 | |||
289 | /* Extern declarations for major data structures. */ | ||
290 | extern sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES]; | ||
291 | |||
292 | |||
293 | /* Get the size of a DATA chunk payload. */ | ||
294 | static inline __u16 sctp_data_size(struct sctp_chunk *chunk) | ||
295 | { | ||
296 | __u16 size; | ||
297 | |||
298 | size = ntohs(chunk->chunk_hdr->length); | ||
299 | size -= sizeof(sctp_data_chunk_t); | ||
300 | |||
301 | return size; | ||
302 | } | ||
303 | |||
304 | /* Compare two TSNs */ | ||
305 | |||
306 | /* RFC 1982 - Serial Number Arithmetic | ||
307 | * | ||
308 | * 2. Comparison | ||
309 | * Then, s1 is said to be equal to s2 if and only if i1 is equal to i2, | ||
310 | * in all other cases, s1 is not equal to s2. | ||
311 | * | ||
312 | * s1 is said to be less than s2 if, and only if, s1 is not equal to s2, | ||
313 | * and | ||
314 | * | ||
315 | * (i1 < i2 and i2 - i1 < 2^(SERIAL_BITS - 1)) or | ||
316 | * (i1 > i2 and i1 - i2 > 2^(SERIAL_BITS - 1)) | ||
317 | * | ||
318 | * s1 is said to be greater than s2 if, and only if, s1 is not equal to | ||
319 | * s2, and | ||
320 | * | ||
321 | * (i1 < i2 and i2 - i1 > 2^(SERIAL_BITS - 1)) or | ||
322 | * (i1 > i2 and i1 - i2 < 2^(SERIAL_BITS - 1)) | ||
323 | */ | ||
324 | |||
325 | /* | ||
326 | * RFC 2960 | ||
327 | * 1.6 Serial Number Arithmetic | ||
328 | * | ||
329 | * Comparisons and arithmetic on TSNs in this document SHOULD use Serial | ||
330 | * Number Arithmetic as defined in [RFC1982] where SERIAL_BITS = 32. | ||
331 | */ | ||
332 | |||
333 | enum { | ||
334 | TSN_SIGN_BIT = (1<<31) | ||
335 | }; | ||
336 | |||
337 | static inline int TSN_lt(__u32 s, __u32 t) | ||
338 | { | ||
339 | return (((s) - (t)) & TSN_SIGN_BIT); | ||
340 | } | ||
341 | |||
342 | static inline int TSN_lte(__u32 s, __u32 t) | ||
343 | { | ||
344 | return (((s) == (t)) || (((s) - (t)) & TSN_SIGN_BIT)); | ||
345 | } | ||
346 | |||
347 | /* Compare two SSNs */ | ||
348 | |||
349 | /* | ||
350 | * RFC 2960 | ||
351 | * 1.6 Serial Number Arithmetic | ||
352 | * | ||
353 | * Comparisons and arithmetic on Stream Sequence Numbers in this document | ||
354 | * SHOULD use Serial Number Arithmetic as defined in [RFC1982] where | ||
355 | * SERIAL_BITS = 16. | ||
356 | */ | ||
357 | enum { | ||
358 | SSN_SIGN_BIT = (1<<15) | ||
359 | }; | ||
360 | |||
361 | static inline int SSN_lt(__u16 s, __u16 t) | ||
362 | { | ||
363 | return (((s) - (t)) & SSN_SIGN_BIT); | ||
364 | } | ||
365 | |||
366 | static inline int SSN_lte(__u16 s, __u16 t) | ||
367 | { | ||
368 | return (((s) == (t)) || (((s) - (t)) & SSN_SIGN_BIT)); | ||
369 | } | ||
370 | |||
371 | /* | ||
372 | * ADDIP 3.1.1 | ||
373 | * The valid range of Serial Number is from 0 to 4294967295 (2**32 - 1). Serial | ||
374 | * Numbers wrap back to 0 after reaching 4294967295. | ||
375 | */ | ||
376 | enum { | ||
377 | ADDIP_SERIAL_SIGN_BIT = (1<<31) | ||
378 | }; | ||
379 | |||
380 | static inline int ADDIP_SERIAL_gte(__u16 s, __u16 t) | ||
381 | { | ||
382 | return (((s) == (t)) || (((t) - (s)) & ADDIP_SERIAL_SIGN_BIT)); | ||
383 | } | ||
384 | |||
385 | |||
386 | /* Run sctp_add_cmd() generating a BUG() if there is a failure. */ | ||
387 | static inline void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_arg_t obj) | ||
388 | { | ||
389 | if (unlikely(!sctp_add_cmd(seq, verb, obj))) | ||
390 | BUG(); | ||
391 | } | ||
392 | |||
393 | /* Check VTAG of the packet matches the sender's own tag. */ | ||
394 | static inline int | ||
395 | sctp_vtag_verify(const struct sctp_chunk *chunk, | ||
396 | const struct sctp_association *asoc) | ||
397 | { | ||
398 | /* RFC 2960 Sec 8.5 When receiving an SCTP packet, the endpoint | ||
399 | * MUST ensure that the value in the Verification Tag field of | ||
400 | * the received SCTP packet matches its own Tag. If the received | ||
401 | * Verification Tag value does not match the receiver's own | ||
402 | * tag value, the receiver shall silently discard the packet... | ||
403 | */ | ||
404 | if (ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag) | ||
405 | return 1; | ||
406 | |||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | /* Check VTAG of the packet matches the sender's own tag OR its peer's | ||
411 | * tag and the T bit is set in the Chunk Flags. | ||
412 | */ | ||
413 | static inline int | ||
414 | sctp_vtag_verify_either(const struct sctp_chunk *chunk, | ||
415 | const struct sctp_association *asoc) | ||
416 | { | ||
417 | /* RFC 2960 Section 8.5.1, sctpimpguide-06 Section 2.13.2 | ||
418 | * | ||
419 | * B) The receiver of a ABORT shall accept the packet if the | ||
420 | * Verification Tag field of the packet matches its own tag OR it | ||
421 | * is set to its peer's tag and the T bit is set in the Chunk | ||
422 | * Flags. Otherwise, the receiver MUST silently discard the packet | ||
423 | * and take no further action. | ||
424 | * | ||
425 | * (C) The receiver of a SHUTDOWN COMPLETE shall accept the | ||
426 | * packet if the Verification Tag field of the packet | ||
427 | * matches its own tag OR it is set to its peer's tag and | ||
428 | * the T bit is set in the Chunk Flags. Otherwise, the | ||
429 | * receiver MUST silently discard the packet and take no | ||
430 | * further action.... | ||
431 | * | ||
432 | */ | ||
433 | if ((ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag) || | ||
434 | (sctp_test_T_bit(chunk) && (ntohl(chunk->sctp_hdr->vtag) | ||
435 | == asoc->c.peer_vtag))) { | ||
436 | return 1; | ||
437 | } | ||
438 | |||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | #endif /* __sctp_sm_h__ */ | ||
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h new file mode 100644 index 000000000000..7e64cf6bda1e --- /dev/null +++ b/include/net/sctp/structs.h | |||
@@ -0,0 +1,1752 @@ | |||
1 | /* SCTP kernel reference Implementation | ||
2 | * (C) Copyright IBM Corp. 2001, 2004 | ||
3 | * Copyright (c) 1999-2000 Cisco, Inc. | ||
4 | * Copyright (c) 1999-2001 Motorola, Inc. | ||
5 | * Copyright (c) 2001 Intel Corp. | ||
6 | * | ||
7 | * This file is part of the SCTP kernel reference Implementation | ||
8 | * | ||
9 | * The SCTP reference implementation is free software; | ||
10 | * you can redistribute it and/or modify it under the terms of | ||
11 | * the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2, or (at your option) | ||
13 | * any later version. | ||
14 | * | ||
15 | * The SCTP reference implementation is distributed in the hope that it | ||
16 | * will be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
17 | * ************************ | ||
18 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
19 | * See the GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with GNU CC; see the file COPYING. If not, write to | ||
23 | * the Free Software Foundation, 59 Temple Place - Suite 330, | ||
24 | * Boston, MA 02111-1307, USA. | ||
25 | * | ||
26 | * Please send any bug reports or fixes you make to the | ||
27 | * email addresses: | ||
28 | * lksctp developers <lksctp-developers@lists.sourceforge.net> | ||
29 | * | ||
30 | * Or submit a bug report through the following website: | ||
31 | * http://www.sf.net/projects/lksctp | ||
32 | * | ||
33 | * Written or modified by: | ||
34 | * Randall Stewart <randall@sctp.chicago.il.us> | ||
35 | * Ken Morneau <kmorneau@cisco.com> | ||
36 | * Qiaobing Xie <qxie1@email.mot.com> | ||
37 | * La Monte H.P. Yarroll <piggy@acm.org> | ||
38 | * Karl Knutson <karl@athena.chicago.il.us> | ||
39 | * Jon Grimm <jgrimm@us.ibm.com> | ||
40 | * Xingang Guo <xingang.guo@intel.com> | ||
41 | * Hui Huang <hui.huang@nokia.com> | ||
42 | * Sridhar Samudrala <sri@us.ibm.com> | ||
43 | * Daisy Chang <daisyc@us.ibm.com> | ||
44 | * Dajiang Zhang <dajiang.zhang@nokia.com> | ||
45 | * Ardelle Fan <ardelle.fan@intel.com> | ||
46 | * Ryan Layer <rmlayer@us.ibm.com> | ||
47 | * Anup Pemmaiah <pemmaiah@cc.usu.edu> | ||
48 | * Kevin Gao <kevin.gao@intel.com> | ||
49 | * | ||
50 | * Any bugs reported given to us we will try to fix... any fixes shared will | ||
51 | * be incorporated into the next SCTP release. | ||
52 | */ | ||
53 | |||
54 | #ifndef __sctp_structs_h__ | ||
55 | #define __sctp_structs_h__ | ||
56 | |||
57 | #include <linux/time.h> /* We get struct timespec. */ | ||
58 | #include <linux/socket.h> /* linux/in.h needs this!! */ | ||
59 | #include <linux/in.h> /* We get struct sockaddr_in. */ | ||
60 | #include <linux/in6.h> /* We get struct in6_addr */ | ||
61 | #include <linux/ipv6.h> | ||
62 | #include <asm/param.h> /* We get MAXHOSTNAMELEN. */ | ||
63 | #include <asm/atomic.h> /* This gets us atomic counters. */ | ||
64 | #include <linux/skbuff.h> /* We need sk_buff_head. */ | ||
65 | #include <linux/workqueue.h> /* We need tq_struct. */ | ||
66 | #include <linux/sctp.h> /* We need sctp* header structs. */ | ||
67 | |||
68 | /* A convenience structure for handling sockaddr structures. | ||
69 | * We should wean ourselves off this. | ||
70 | */ | ||
71 | union sctp_addr { | ||
72 | struct sockaddr_in v4; | ||
73 | struct sockaddr_in6 v6; | ||
74 | struct sockaddr sa; | ||
75 | }; | ||
76 | |||
77 | /* Forward declarations for data structures. */ | ||
78 | struct sctp_globals; | ||
79 | struct sctp_endpoint; | ||
80 | struct sctp_association; | ||
81 | struct sctp_transport; | ||
82 | struct sctp_packet; | ||
83 | struct sctp_chunk; | ||
84 | struct sctp_inq; | ||
85 | struct sctp_outq; | ||
86 | struct sctp_bind_addr; | ||
87 | struct sctp_ulpq; | ||
88 | struct sctp_ep_common; | ||
89 | struct sctp_ssnmap; | ||
90 | |||
91 | |||
92 | #include <net/sctp/tsnmap.h> | ||
93 | #include <net/sctp/ulpevent.h> | ||
94 | #include <net/sctp/ulpqueue.h> | ||
95 | |||
96 | /* Structures useful for managing bind/connect. */ | ||
97 | |||
98 | struct sctp_bind_bucket { | ||
99 | unsigned short port; | ||
100 | unsigned short fastreuse; | ||
101 | struct sctp_bind_bucket *next; | ||
102 | struct sctp_bind_bucket **pprev; | ||
103 | struct hlist_head owner; | ||
104 | }; | ||
105 | |||
106 | struct sctp_bind_hashbucket { | ||
107 | spinlock_t lock; | ||
108 | struct sctp_bind_bucket *chain; | ||
109 | }; | ||
110 | |||
111 | /* Used for hashing all associations. */ | ||
112 | struct sctp_hashbucket { | ||
113 | rwlock_t lock; | ||
114 | struct sctp_ep_common *chain; | ||
115 | } __attribute__((__aligned__(8))); | ||
116 | |||
117 | |||
118 | /* The SCTP globals structure. */ | ||
119 | extern struct sctp_globals { | ||
120 | /* RFC2960 Section 14. Suggested SCTP Protocol Parameter Values | ||
121 | * | ||
122 | * The following protocol parameters are RECOMMENDED: | ||
123 | * | ||
124 | * RTO.Initial - 3 seconds | ||
125 | * RTO.Min - 1 second | ||
126 | * RTO.Max - 60 seconds | ||
127 | * RTO.Alpha - 1/8 (3 when converted to right shifts.) | ||
128 | * RTO.Beta - 1/4 (2 when converted to right shifts.) | ||
129 | */ | ||
130 | __u32 rto_initial; | ||
131 | __u32 rto_min; | ||
132 | __u32 rto_max; | ||
133 | |||
134 | /* Note: rto_alpha and rto_beta are really defined as inverse | ||
135 | * powers of two to facilitate integer operations. | ||
136 | */ | ||
137 | int rto_alpha; | ||
138 | int rto_beta; | ||
139 | |||
140 | /* Max.Burst - 4 */ | ||
141 | int max_burst; | ||
142 | |||
143 | /* Valid.Cookie.Life - 60 seconds */ | ||
144 | int valid_cookie_life; | ||
145 | |||
146 | /* Whether Cookie Preservative is enabled(1) or not(0) */ | ||
147 | int cookie_preserve_enable; | ||
148 | |||
149 | /* Association.Max.Retrans - 10 attempts | ||
150 | * Path.Max.Retrans - 5 attempts (per destination address) | ||
151 | * Max.Init.Retransmits - 8 attempts | ||
152 | */ | ||
153 | int max_retrans_association; | ||
154 | int max_retrans_path; | ||
155 | int max_retrans_init; | ||
156 | |||
157 | /* HB.interval - 30 seconds */ | ||
158 | int hb_interval; | ||
159 | |||
160 | /* The following variables are implementation specific. */ | ||
161 | |||
162 | /* Default initialization values to be applied to new associations. */ | ||
163 | __u16 max_instreams; | ||
164 | __u16 max_outstreams; | ||
165 | |||
166 | /* This is a list of groups of functions for each address | ||
167 | * family that we support. | ||
168 | */ | ||
169 | struct list_head address_families; | ||
170 | |||
171 | /* This is the hash of all endpoints. */ | ||
172 | int ep_hashsize; | ||
173 | struct sctp_hashbucket *ep_hashtable; | ||
174 | |||
175 | /* This is the hash of all associations. */ | ||
176 | int assoc_hashsize; | ||
177 | struct sctp_hashbucket *assoc_hashtable; | ||
178 | |||
179 | /* This is the sctp port control hash. */ | ||
180 | int port_hashsize; | ||
181 | int port_rover; | ||
182 | spinlock_t port_alloc_lock; /* Protects port_rover. */ | ||
183 | struct sctp_bind_hashbucket *port_hashtable; | ||
184 | |||
185 | /* This is the global local address list. | ||
186 | * We actively maintain this complete list of interfaces on | ||
187 | * the system by catching routing events. | ||
188 | * | ||
189 | * It is a list of sctp_sockaddr_entry. | ||
190 | */ | ||
191 | struct list_head local_addr_list; | ||
192 | spinlock_t local_addr_lock; | ||
193 | |||
194 | /* Flag to indicate if addip is enabled. */ | ||
195 | int addip_enable; | ||
196 | |||
197 | /* Flag to indicate if PR-SCTP is enabled. */ | ||
198 | int prsctp_enable; | ||
199 | } sctp_globals; | ||
200 | |||
201 | #define sctp_rto_initial (sctp_globals.rto_initial) | ||
202 | #define sctp_rto_min (sctp_globals.rto_min) | ||
203 | #define sctp_rto_max (sctp_globals.rto_max) | ||
204 | #define sctp_rto_alpha (sctp_globals.rto_alpha) | ||
205 | #define sctp_rto_beta (sctp_globals.rto_beta) | ||
206 | #define sctp_max_burst (sctp_globals.max_burst) | ||
207 | #define sctp_valid_cookie_life (sctp_globals.valid_cookie_life) | ||
208 | #define sctp_cookie_preserve_enable (sctp_globals.cookie_preserve_enable) | ||
209 | #define sctp_max_retrans_association (sctp_globals.max_retrans_association) | ||
210 | #define sctp_max_retrans_path (sctp_globals.max_retrans_path) | ||
211 | #define sctp_max_retrans_init (sctp_globals.max_retrans_init) | ||
212 | #define sctp_hb_interval (sctp_globals.hb_interval) | ||
213 | #define sctp_max_instreams (sctp_globals.max_instreams) | ||
214 | #define sctp_max_outstreams (sctp_globals.max_outstreams) | ||
215 | #define sctp_address_families (sctp_globals.address_families) | ||
216 | #define sctp_ep_hashsize (sctp_globals.ep_hashsize) | ||
217 | #define sctp_ep_hashtable (sctp_globals.ep_hashtable) | ||
218 | #define sctp_assoc_hashsize (sctp_globals.assoc_hashsize) | ||
219 | #define sctp_assoc_hashtable (sctp_globals.assoc_hashtable) | ||
220 | #define sctp_port_hashsize (sctp_globals.port_hashsize) | ||
221 | #define sctp_port_rover (sctp_globals.port_rover) | ||
222 | #define sctp_port_alloc_lock (sctp_globals.port_alloc_lock) | ||
223 | #define sctp_port_hashtable (sctp_globals.port_hashtable) | ||
224 | #define sctp_local_addr_list (sctp_globals.local_addr_list) | ||
225 | #define sctp_local_addr_lock (sctp_globals.local_addr_lock) | ||
226 | #define sctp_addip_enable (sctp_globals.addip_enable) | ||
227 | #define sctp_prsctp_enable (sctp_globals.prsctp_enable) | ||
228 | |||
229 | /* SCTP Socket type: UDP or TCP style. */ | ||
230 | typedef enum { | ||
231 | SCTP_SOCKET_UDP = 0, | ||
232 | SCTP_SOCKET_UDP_HIGH_BANDWIDTH, | ||
233 | SCTP_SOCKET_TCP | ||
234 | } sctp_socket_type_t; | ||
235 | |||
236 | /* Per socket SCTP information. */ | ||
237 | struct sctp_sock { | ||
238 | /* inet_sock has to be the first member of sctp_sock */ | ||
239 | struct inet_sock inet; | ||
240 | /* What kind of a socket is this? */ | ||
241 | sctp_socket_type_t type; | ||
242 | |||
243 | /* PF_ family specific functions. */ | ||
244 | struct sctp_pf *pf; | ||
245 | |||
246 | /* Access to HMAC transform. */ | ||
247 | struct crypto_tfm *hmac; | ||
248 | |||
249 | /* What is our base endpointer? */ | ||
250 | struct sctp_endpoint *ep; | ||
251 | |||
252 | struct sctp_bind_bucket *bind_hash; | ||
253 | /* Various Socket Options. */ | ||
254 | __u16 default_stream; | ||
255 | __u32 default_ppid; | ||
256 | __u16 default_flags; | ||
257 | __u32 default_context; | ||
258 | __u32 default_timetolive; | ||
259 | |||
260 | struct sctp_initmsg initmsg; | ||
261 | struct sctp_rtoinfo rtoinfo; | ||
262 | struct sctp_paddrparams paddrparam; | ||
263 | struct sctp_event_subscribe subscribe; | ||
264 | struct sctp_assocparams assocparams; | ||
265 | int user_frag; | ||
266 | __u32 autoclose; | ||
267 | __u8 nodelay; | ||
268 | __u8 disable_fragments; | ||
269 | __u8 pd_mode; | ||
270 | __u8 v4mapped; | ||
271 | __u32 adaption_ind; | ||
272 | |||
273 | /* Receive to here while partial delivery is in effect. */ | ||
274 | struct sk_buff_head pd_lobby; | ||
275 | }; | ||
276 | |||
277 | static inline struct sctp_sock *sctp_sk(const struct sock *sk) | ||
278 | { | ||
279 | return (struct sctp_sock *)sk; | ||
280 | } | ||
281 | |||
282 | static inline struct sock *sctp_opt2sk(const struct sctp_sock *sp) | ||
283 | { | ||
284 | return (struct sock *)sp; | ||
285 | } | ||
286 | |||
287 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
288 | struct sctp6_sock { | ||
289 | struct sctp_sock sctp; | ||
290 | struct ipv6_pinfo inet6; | ||
291 | }; | ||
292 | #endif /* CONFIG_IPV6 */ | ||
293 | |||
294 | |||
295 | /* This is our APPLICATION-SPECIFIC state cookie. | ||
296 | * THIS IS NOT DICTATED BY THE SPECIFICATION. | ||
297 | */ | ||
298 | /* These are the parts of an association which we send in the cookie. | ||
299 | * Most of these are straight out of: | ||
300 | * RFC2960 12.2 Parameters necessary per association (i.e. the TCB) | ||
301 | * | ||
302 | */ | ||
303 | |||
304 | struct sctp_cookie { | ||
305 | |||
306 | /* My : Tag expected in every inbound packet and sent | ||
307 | * Verification: in the INIT or INIT ACK chunk. | ||
308 | * Tag : | ||
309 | */ | ||
310 | __u32 my_vtag; | ||
311 | |||
312 | /* Peer's : Tag expected in every outbound packet except | ||
313 | * Verification: in the INIT chunk. | ||
314 | * Tag : | ||
315 | */ | ||
316 | __u32 peer_vtag; | ||
317 | |||
318 | /* The rest of these are not from the spec, but really need to | ||
319 | * be in the cookie. | ||
320 | */ | ||
321 | |||
322 | /* My Tie Tag : Assist in discovering a restarting association. */ | ||
323 | __u32 my_ttag; | ||
324 | |||
325 | /* Peer's Tie Tag: Assist in discovering a restarting association. */ | ||
326 | __u32 peer_ttag; | ||
327 | |||
328 | /* When does this cookie expire? */ | ||
329 | struct timeval expiration; | ||
330 | |||
331 | /* Number of inbound/outbound streams which are set | ||
332 | * and negotiated during the INIT process. | ||
333 | */ | ||
334 | __u16 sinit_num_ostreams; | ||
335 | __u16 sinit_max_instreams; | ||
336 | |||
337 | /* This is the first sequence number I used. */ | ||
338 | __u32 initial_tsn; | ||
339 | |||
340 | /* This holds the originating address of the INIT packet. */ | ||
341 | union sctp_addr peer_addr; | ||
342 | |||
343 | /* IG Section 2.35.3 | ||
344 | * Include the source port of the INIT-ACK | ||
345 | */ | ||
346 | __u16 my_port; | ||
347 | |||
348 | __u8 prsctp_capable; | ||
349 | |||
350 | /* Padding for future use */ | ||
351 | __u8 padding; | ||
352 | |||
353 | __u32 adaption_ind; | ||
354 | |||
355 | |||
356 | /* This is a shim for my peer's INIT packet, followed by | ||
357 | * a copy of the raw address list of the association. | ||
358 | * The length of the raw address list is saved in the | ||
359 | * raw_addr_list_len field, which will be used at the time when | ||
360 | * the association TCB is re-constructed from the cookie. | ||
361 | */ | ||
362 | __u32 raw_addr_list_len; | ||
363 | struct sctp_init_chunk peer_init[0]; | ||
364 | }; | ||
365 | |||
366 | |||
367 | /* The format of our cookie that we send to our peer. */ | ||
368 | struct sctp_signed_cookie { | ||
369 | __u8 signature[SCTP_SECRET_SIZE]; | ||
370 | struct sctp_cookie c; | ||
371 | }; | ||
372 | |||
373 | /* This is another convenience type to allocate memory for address | ||
374 | * params for the maximum size and pass such structures around | ||
375 | * internally. | ||
376 | */ | ||
377 | union sctp_addr_param { | ||
378 | struct sctp_ipv4addr_param v4; | ||
379 | struct sctp_ipv6addr_param v6; | ||
380 | }; | ||
381 | |||
382 | /* A convenience type to allow walking through the various | ||
383 | * parameters and avoid casting all over the place. | ||
384 | */ | ||
385 | union sctp_params { | ||
386 | void *v; | ||
387 | struct sctp_paramhdr *p; | ||
388 | struct sctp_cookie_preserve_param *life; | ||
389 | struct sctp_hostname_param *dns; | ||
390 | struct sctp_cookie_param *cookie; | ||
391 | struct sctp_supported_addrs_param *sat; | ||
392 | struct sctp_ipv4addr_param *v4; | ||
393 | struct sctp_ipv6addr_param *v6; | ||
394 | union sctp_addr_param *addr; | ||
395 | struct sctp_adaption_ind_param *aind; | ||
396 | }; | ||
397 | |||
398 | /* RFC 2960. Section 3.3.5 Heartbeat. | ||
399 | * Heartbeat Information: variable length | ||
400 | * The Sender-specific Heartbeat Info field should normally include | ||
401 | * information about the sender's current time when this HEARTBEAT | ||
402 | * chunk is sent and the destination transport address to which this | ||
403 | * HEARTBEAT is sent (see Section 8.3). | ||
404 | */ | ||
405 | typedef struct sctp_sender_hb_info { | ||
406 | struct sctp_paramhdr param_hdr; | ||
407 | union sctp_addr daddr; | ||
408 | unsigned long sent_at; | ||
409 | } __attribute__((packed)) sctp_sender_hb_info_t; | ||
410 | |||
411 | /* | ||
412 | * RFC 2960 1.3.2 Sequenced Delivery within Streams | ||
413 | * | ||
414 | * The term "stream" is used in SCTP to refer to a sequence of user | ||
415 | * messages that are to be delivered to the upper-layer protocol in | ||
416 | * order with respect to other messages within the same stream. This is | ||
417 | * in contrast to its usage in TCP, where it refers to a sequence of | ||
418 | * bytes (in this document a byte is assumed to be eight bits). | ||
419 | * ... | ||
420 | * | ||
421 | * This is the structure we use to track both our outbound and inbound | ||
422 | * SSN, or Stream Sequence Numbers. | ||
423 | */ | ||
424 | |||
425 | struct sctp_stream { | ||
426 | __u16 *ssn; | ||
427 | unsigned int len; | ||
428 | }; | ||
429 | |||
430 | struct sctp_ssnmap { | ||
431 | struct sctp_stream in; | ||
432 | struct sctp_stream out; | ||
433 | int malloced; | ||
434 | }; | ||
435 | |||
436 | struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, int gfp); | ||
437 | void sctp_ssnmap_free(struct sctp_ssnmap *map); | ||
438 | void sctp_ssnmap_clear(struct sctp_ssnmap *map); | ||
439 | |||
440 | /* What is the current SSN number for this stream? */ | ||
441 | static inline __u16 sctp_ssn_peek(struct sctp_stream *stream, __u16 id) | ||
442 | { | ||
443 | return stream->ssn[id]; | ||
444 | } | ||
445 | |||
446 | /* Return the next SSN number for this stream. */ | ||
447 | static inline __u16 sctp_ssn_next(struct sctp_stream *stream, __u16 id) | ||
448 | { | ||
449 | return stream->ssn[id]++; | ||
450 | } | ||
451 | |||
452 | /* Skip over this ssn and all below. */ | ||
453 | static inline void sctp_ssn_skip(struct sctp_stream *stream, __u16 id, | ||
454 | __u16 ssn) | ||
455 | { | ||
456 | stream->ssn[id] = ssn+1; | ||
457 | } | ||
458 | |||
459 | /* | ||
460 | * Pointers to address related SCTP functions. | ||
461 | * (i.e. things that depend on the address family.) | ||
462 | */ | ||
463 | struct sctp_af { | ||
464 | int (*sctp_xmit) (struct sk_buff *skb, | ||
465 | struct sctp_transport *, | ||
466 | int ipfragok); | ||
467 | int (*setsockopt) (struct sock *sk, | ||
468 | int level, | ||
469 | int optname, | ||
470 | char __user *optval, | ||
471 | int optlen); | ||
472 | int (*getsockopt) (struct sock *sk, | ||
473 | int level, | ||
474 | int optname, | ||
475 | char __user *optval, | ||
476 | int __user *optlen); | ||
477 | struct dst_entry *(*get_dst) (struct sctp_association *asoc, | ||
478 | union sctp_addr *daddr, | ||
479 | union sctp_addr *saddr); | ||
480 | void (*get_saddr) (struct sctp_association *asoc, | ||
481 | struct dst_entry *dst, | ||
482 | union sctp_addr *daddr, | ||
483 | union sctp_addr *saddr); | ||
484 | void (*copy_addrlist) (struct list_head *, | ||
485 | struct net_device *); | ||
486 | void (*dst_saddr) (union sctp_addr *saddr, | ||
487 | struct dst_entry *dst, | ||
488 | unsigned short port); | ||
489 | int (*cmp_addr) (const union sctp_addr *addr1, | ||
490 | const union sctp_addr *addr2); | ||
491 | void (*addr_copy) (union sctp_addr *dst, | ||
492 | union sctp_addr *src); | ||
493 | void (*from_skb) (union sctp_addr *, | ||
494 | struct sk_buff *skb, | ||
495 | int saddr); | ||
496 | void (*from_sk) (union sctp_addr *, | ||
497 | struct sock *sk); | ||
498 | void (*to_sk_saddr) (union sctp_addr *, | ||
499 | struct sock *sk); | ||
500 | void (*to_sk_daddr) (union sctp_addr *, | ||
501 | struct sock *sk); | ||
502 | void (*from_addr_param) (union sctp_addr *, | ||
503 | union sctp_addr_param *, | ||
504 | __u16 port, int iif); | ||
505 | int (*to_addr_param) (const union sctp_addr *, | ||
506 | union sctp_addr_param *); | ||
507 | int (*addr_valid) (union sctp_addr *, | ||
508 | struct sctp_sock *); | ||
509 | sctp_scope_t (*scope) (union sctp_addr *); | ||
510 | void (*inaddr_any) (union sctp_addr *, unsigned short); | ||
511 | int (*is_any) (const union sctp_addr *); | ||
512 | int (*available) (union sctp_addr *, | ||
513 | struct sctp_sock *); | ||
514 | int (*skb_iif) (const struct sk_buff *sk); | ||
515 | int (*is_ce) (const struct sk_buff *sk); | ||
516 | void (*seq_dump_addr)(struct seq_file *seq, | ||
517 | union sctp_addr *addr); | ||
518 | __u16 net_header_len; | ||
519 | int sockaddr_len; | ||
520 | sa_family_t sa_family; | ||
521 | struct list_head list; | ||
522 | }; | ||
523 | |||
524 | struct sctp_af *sctp_get_af_specific(sa_family_t); | ||
525 | int sctp_register_af(struct sctp_af *); | ||
526 | |||
527 | /* Protocol family functions. */ | ||
528 | struct sctp_pf { | ||
529 | void (*event_msgname)(struct sctp_ulpevent *, char *, int *); | ||
530 | void (*skb_msgname) (struct sk_buff *, char *, int *); | ||
531 | int (*af_supported) (sa_family_t, struct sctp_sock *); | ||
532 | int (*cmp_addr) (const union sctp_addr *, | ||
533 | const union sctp_addr *, | ||
534 | struct sctp_sock *); | ||
535 | int (*bind_verify) (struct sctp_sock *, union sctp_addr *); | ||
536 | int (*send_verify) (struct sctp_sock *, union sctp_addr *); | ||
537 | int (*supported_addrs)(const struct sctp_sock *, __u16 *); | ||
538 | struct sock *(*create_accept_sk) (struct sock *sk, | ||
539 | struct sctp_association *asoc); | ||
540 | void (*addr_v4map) (struct sctp_sock *, union sctp_addr *); | ||
541 | struct sctp_af *af; | ||
542 | }; | ||
543 | |||
544 | |||
545 | /* Structure to track chunk fragments that have been acked, but peer | ||
546 | * fragments of the same message have not. | ||
547 | */ | ||
548 | struct sctp_datamsg { | ||
549 | /* Chunks waiting to be submitted to lower layer. */ | ||
550 | struct list_head chunks; | ||
551 | /* Chunks that have been transmitted. */ | ||
552 | struct list_head track; | ||
553 | /* Reference counting. */ | ||
554 | atomic_t refcnt; | ||
555 | /* When is this message no longer interesting to the peer? */ | ||
556 | unsigned long expires_at; | ||
557 | /* Did the messenge fail to send? */ | ||
558 | int send_error; | ||
559 | char send_failed; | ||
560 | /* Control whether chunks from this message can be abandoned. */ | ||
561 | char can_abandon; | ||
562 | }; | ||
563 | |||
564 | struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *, | ||
565 | struct sctp_sndrcvinfo *, | ||
566 | struct msghdr *, int len); | ||
567 | void sctp_datamsg_put(struct sctp_datamsg *); | ||
568 | void sctp_datamsg_free(struct sctp_datamsg *); | ||
569 | void sctp_datamsg_track(struct sctp_chunk *); | ||
570 | void sctp_chunk_fail(struct sctp_chunk *, int error); | ||
571 | int sctp_chunk_abandoned(struct sctp_chunk *); | ||
572 | |||
573 | |||
574 | /* RFC2960 1.4 Key Terms | ||
575 | * | ||
576 | * o Chunk: A unit of information within an SCTP packet, consisting of | ||
577 | * a chunk header and chunk-specific content. | ||
578 | * | ||
579 | * As a matter of convenience, we remember the SCTP common header for | ||
580 | * each chunk as well as a few other header pointers... | ||
581 | */ | ||
582 | struct sctp_chunk { | ||
583 | /* These first three elements MUST PRECISELY match the first | ||
584 | * three elements of struct sk_buff. This allows us to reuse | ||
585 | * all the skb_* queue management functions. | ||
586 | */ | ||
587 | struct sctp_chunk *next; | ||
588 | struct sctp_chunk *prev; | ||
589 | struct sk_buff_head *list; | ||
590 | atomic_t refcnt; | ||
591 | |||
592 | /* This is our link to the per-transport transmitted list. */ | ||
593 | struct list_head transmitted_list; | ||
594 | |||
595 | /* This field is used by chunks that hold fragmented data. | ||
596 | * For the first fragment this is the list that holds the rest of | ||
597 | * fragments. For the remaining fragments, this is the link to the | ||
598 | * frag_list maintained in the first fragment. | ||
599 | */ | ||
600 | struct list_head frag_list; | ||
601 | |||
602 | /* This points to the sk_buff containing the actual data. */ | ||
603 | struct sk_buff *skb; | ||
604 | |||
605 | /* These are the SCTP headers by reverse order in a packet. | ||
606 | * Note that some of these may happen more than once. In that | ||
607 | * case, we point at the "current" one, whatever that means | ||
608 | * for that level of header. | ||
609 | */ | ||
610 | |||
611 | /* We point this at the FIRST TLV parameter to chunk_hdr. */ | ||
612 | union sctp_params param_hdr; | ||
613 | union { | ||
614 | __u8 *v; | ||
615 | struct sctp_datahdr *data_hdr; | ||
616 | struct sctp_inithdr *init_hdr; | ||
617 | struct sctp_sackhdr *sack_hdr; | ||
618 | struct sctp_heartbeathdr *hb_hdr; | ||
619 | struct sctp_sender_hb_info *hbs_hdr; | ||
620 | struct sctp_shutdownhdr *shutdown_hdr; | ||
621 | struct sctp_signed_cookie *cookie_hdr; | ||
622 | struct sctp_ecnehdr *ecne_hdr; | ||
623 | struct sctp_cwrhdr *ecn_cwr_hdr; | ||
624 | struct sctp_errhdr *err_hdr; | ||
625 | struct sctp_addiphdr *addip_hdr; | ||
626 | struct sctp_fwdtsn_hdr *fwdtsn_hdr; | ||
627 | } subh; | ||
628 | |||
629 | __u8 *chunk_end; | ||
630 | |||
631 | struct sctp_chunkhdr *chunk_hdr; | ||
632 | struct sctphdr *sctp_hdr; | ||
633 | |||
634 | /* This needs to be recoverable for SCTP_SEND_FAILED events. */ | ||
635 | struct sctp_sndrcvinfo sinfo; | ||
636 | |||
637 | /* Which association does this belong to? */ | ||
638 | struct sctp_association *asoc; | ||
639 | |||
640 | /* What endpoint received this chunk? */ | ||
641 | struct sctp_ep_common *rcvr; | ||
642 | |||
643 | /* We fill this in if we are calculating RTT. */ | ||
644 | unsigned long sent_at; | ||
645 | |||
646 | /* What is the origin IP address for this chunk? */ | ||
647 | union sctp_addr source; | ||
648 | /* Destination address for this chunk. */ | ||
649 | union sctp_addr dest; | ||
650 | |||
651 | /* For outbound message, track all fragments for SEND_FAILED. */ | ||
652 | struct sctp_datamsg *msg; | ||
653 | |||
654 | /* For an inbound chunk, this tells us where it came from. | ||
655 | * For an outbound chunk, it tells us where we'd like it to | ||
656 | * go. It is NULL if we have no preference. | ||
657 | */ | ||
658 | struct sctp_transport *transport; | ||
659 | |||
660 | __u8 rtt_in_progress; /* Is this chunk used for RTT calculation? */ | ||
661 | __u8 resent; /* Has this chunk ever been retransmitted. */ | ||
662 | __u8 has_tsn; /* Does this chunk have a TSN yet? */ | ||
663 | __u8 has_ssn; /* Does this chunk have a SSN yet? */ | ||
664 | __u8 singleton; /* Was this the only chunk in the packet? */ | ||
665 | __u8 end_of_packet; /* Was this the last chunk in the packet? */ | ||
666 | __u8 ecn_ce_done; /* Have we processed the ECN CE bit? */ | ||
667 | __u8 pdiscard; /* Discard the whole packet now? */ | ||
668 | __u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */ | ||
669 | __u8 fast_retransmit; /* Is this chunk fast retransmitted? */ | ||
670 | __u8 tsn_missing_report; /* Data chunk missing counter. */ | ||
671 | }; | ||
672 | |||
673 | void sctp_chunk_hold(struct sctp_chunk *); | ||
674 | void sctp_chunk_put(struct sctp_chunk *); | ||
675 | int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len, | ||
676 | struct iovec *data); | ||
677 | void sctp_chunk_free(struct sctp_chunk *); | ||
678 | void *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data); | ||
679 | struct sctp_chunk *sctp_chunkify(struct sk_buff *, | ||
680 | const struct sctp_association *, | ||
681 | struct sock *); | ||
682 | void sctp_init_addrs(struct sctp_chunk *, union sctp_addr *, | ||
683 | union sctp_addr *); | ||
684 | const union sctp_addr *sctp_source(const struct sctp_chunk *chunk); | ||
685 | |||
686 | /* This is a structure for holding either an IPv6 or an IPv4 address. */ | ||
687 | /* sin_family -- AF_INET or AF_INET6 | ||
688 | * sin_port -- ordinary port number | ||
689 | * sin_addr -- cast to either (struct in_addr) or (struct in6_addr) | ||
690 | */ | ||
691 | struct sctp_sockaddr_entry { | ||
692 | struct list_head list; | ||
693 | union sctp_addr a; | ||
694 | }; | ||
695 | |||
696 | typedef struct sctp_chunk *(sctp_packet_phandler_t)(struct sctp_association *); | ||
697 | |||
698 | /* This structure holds lists of chunks as we are assembling for | ||
699 | * transmission. | ||
700 | */ | ||
701 | struct sctp_packet { | ||
702 | /* These are the SCTP header values (host order) for the packet. */ | ||
703 | __u16 source_port; | ||
704 | __u16 destination_port; | ||
705 | __u32 vtag; | ||
706 | |||
707 | /* This contains the payload chunks. */ | ||
708 | struct sk_buff_head chunks; | ||
709 | |||
710 | /* This is the overhead of the sctp and ip headers. */ | ||
711 | size_t overhead; | ||
712 | /* This is the total size of all chunks INCLUDING padding. */ | ||
713 | size_t size; | ||
714 | |||
715 | /* The packet is destined for this transport address. | ||
716 | * The function we finally use to pass down to the next lower | ||
717 | * layer lives in the transport structure. | ||
718 | */ | ||
719 | struct sctp_transport *transport; | ||
720 | |||
721 | /* This packet contains a COOKIE-ECHO chunk. */ | ||
722 | char has_cookie_echo; | ||
723 | |||
724 | /* This packet containsa SACK chunk. */ | ||
725 | char has_sack; | ||
726 | |||
727 | /* SCTP cannot fragment this packet. So let ip fragment it. */ | ||
728 | char ipfragok; | ||
729 | |||
730 | int malloced; | ||
731 | }; | ||
732 | |||
733 | struct sctp_packet *sctp_packet_init(struct sctp_packet *, | ||
734 | struct sctp_transport *, | ||
735 | __u16 sport, __u16 dport); | ||
736 | struct sctp_packet *sctp_packet_config(struct sctp_packet *, __u32 vtag, int); | ||
737 | sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *, | ||
738 | struct sctp_chunk *); | ||
739 | sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *, | ||
740 | struct sctp_chunk *); | ||
741 | int sctp_packet_transmit(struct sctp_packet *); | ||
742 | void sctp_packet_free(struct sctp_packet *); | ||
743 | |||
744 | static inline int sctp_packet_empty(struct sctp_packet *packet) | ||
745 | { | ||
746 | return (packet->size == packet->overhead); | ||
747 | } | ||
748 | |||
749 | /* This represents a remote transport address. | ||
750 | * For local transport addresses, we just use union sctp_addr. | ||
751 | * | ||
752 | * RFC2960 Section 1.4 Key Terms | ||
753 | * | ||
754 | * o Transport address: A Transport Address is traditionally defined | ||
755 | * by Network Layer address, Transport Layer protocol and Transport | ||
756 | * Layer port number. In the case of SCTP running over IP, a | ||
757 | * transport address is defined by the combination of an IP address | ||
758 | * and an SCTP port number (where SCTP is the Transport protocol). | ||
759 | * | ||
760 | * RFC2960 Section 7.1 SCTP Differences from TCP Congestion control | ||
761 | * | ||
762 | * o The sender keeps a separate congestion control parameter set for | ||
763 | * each of the destination addresses it can send to (not each | ||
764 | * source-destination pair but for each destination). The parameters | ||
765 | * should decay if the address is not used for a long enough time | ||
766 | * period. | ||
767 | * | ||
768 | */ | ||
769 | struct sctp_transport { | ||
770 | /* A list of transports. */ | ||
771 | struct list_head transports; | ||
772 | |||
773 | /* Reference counting. */ | ||
774 | atomic_t refcnt; | ||
775 | int dead; | ||
776 | |||
777 | /* This is the peer's IP address and port. */ | ||
778 | union sctp_addr ipaddr; | ||
779 | |||
780 | /* These are the functions we call to handle LLP stuff. */ | ||
781 | struct sctp_af *af_specific; | ||
782 | |||
783 | /* Which association do we belong to? */ | ||
784 | struct sctp_association *asoc; | ||
785 | |||
786 | /* RFC2960 | ||
787 | * | ||
788 | * 12.3 Per Transport Address Data | ||
789 | * | ||
790 | * For each destination transport address in the peer's | ||
791 | * address list derived from the INIT or INIT ACK chunk, a | ||
792 | * number of data elements needs to be maintained including: | ||
793 | */ | ||
794 | __u32 rtt; /* This is the most recent RTT. */ | ||
795 | |||
796 | /* RTO : The current retransmission timeout value. */ | ||
797 | __u32 rto; | ||
798 | |||
799 | /* RTTVAR : The current RTT variation. */ | ||
800 | __u32 rttvar; | ||
801 | |||
802 | /* SRTT : The current smoothed round trip time. */ | ||
803 | __u32 srtt; | ||
804 | |||
805 | /* RTO-Pending : A flag used to track if one of the DATA | ||
806 | * chunks sent to this address is currently being | ||
807 | * used to compute a RTT. If this flag is 0, | ||
808 | * the next DATA chunk sent to this destination | ||
809 | * should be used to compute a RTT and this flag | ||
810 | * should be set. Every time the RTT | ||
811 | * calculation completes (i.e. the DATA chunk | ||
812 | * is SACK'd) clear this flag. | ||
813 | */ | ||
814 | int rto_pending; | ||
815 | |||
816 | /* | ||
817 | * These are the congestion stats. | ||
818 | */ | ||
819 | /* cwnd : The current congestion window. */ | ||
820 | __u32 cwnd; /* This is the actual cwnd. */ | ||
821 | |||
822 | /* ssthresh : The current slow start threshold value. */ | ||
823 | __u32 ssthresh; | ||
824 | |||
825 | /* partial : The tracking method for increase of cwnd when in | ||
826 | * bytes acked : congestion avoidance mode (see Section 6.2.2) | ||
827 | */ | ||
828 | __u32 partial_bytes_acked; | ||
829 | |||
830 | /* Data that has been sent, but not acknowledged. */ | ||
831 | __u32 flight_size; | ||
832 | |||
833 | /* PMTU : The current known path MTU. */ | ||
834 | __u32 pmtu; | ||
835 | |||
836 | /* Destination */ | ||
837 | struct dst_entry *dst; | ||
838 | /* Source address. */ | ||
839 | union sctp_addr saddr; | ||
840 | |||
841 | /* When was the last time(in jiffies) that a data packet was sent on | ||
842 | * this transport? This is used to adjust the cwnd when the transport | ||
843 | * becomes inactive. | ||
844 | */ | ||
845 | unsigned long last_time_used; | ||
846 | |||
847 | /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to | ||
848 | * the destination address every heartbeat interval. | ||
849 | */ | ||
850 | int hb_interval; | ||
851 | |||
852 | /* When was the last time (in jiffies) that we heard from this | ||
853 | * transport? We use this to pick new active and retran paths. | ||
854 | */ | ||
855 | unsigned long last_time_heard; | ||
856 | |||
857 | /* Last time(in jiffies) when cwnd is reduced due to the congestion | ||
858 | * indication based on ECNE chunk. | ||
859 | */ | ||
860 | unsigned long last_time_ecne_reduced; | ||
861 | |||
862 | /* active : The current active state of this destination, | ||
863 | * : i.e. DOWN, UP, etc. | ||
864 | */ | ||
865 | int active; | ||
866 | |||
867 | /* hb_allowed : The current heartbeat state of this destination, | ||
868 | * : i.e. ALLOW-HB, NO-HEARTBEAT, etc. | ||
869 | */ | ||
870 | int hb_allowed; | ||
871 | |||
872 | /* These are the error stats for this destination. */ | ||
873 | |||
874 | /* Error count : The current error count for this destination. */ | ||
875 | unsigned short error_count; | ||
876 | |||
877 | /* This is the max_retrans value for the transport and will | ||
878 | * be initialized to proto.max_retrans.path. This can be changed | ||
879 | * using SCTP_SET_PEER_ADDR_PARAMS socket option. | ||
880 | */ | ||
881 | int max_retrans; | ||
882 | |||
883 | /* Per : A timer used by each destination. | ||
884 | * Destination : | ||
885 | * Timer : | ||
886 | * | ||
887 | * [Everywhere else in the text this is called T3-rtx. -ed] | ||
888 | */ | ||
889 | struct timer_list T3_rtx_timer; | ||
890 | |||
891 | /* Heartbeat timer is per destination. */ | ||
892 | struct timer_list hb_timer; | ||
893 | |||
894 | /* Since we're using per-destination retransmission timers | ||
895 | * (see above), we're also using per-destination "transmitted" | ||
896 | * queues. This probably ought to be a private struct | ||
897 | * accessible only within the outqueue, but it's not, yet. | ||
898 | */ | ||
899 | struct list_head transmitted; | ||
900 | |||
901 | /* We build bundle-able packets for this transport here. */ | ||
902 | struct sctp_packet packet; | ||
903 | |||
904 | /* This is the list of transports that have chunks to send. */ | ||
905 | struct list_head send_ready; | ||
906 | |||
907 | int malloced; /* Is this structure kfree()able? */ | ||
908 | |||
909 | /* State information saved for SFR_CACC algorithm. The key | ||
910 | * idea in SFR_CACC is to maintain state at the sender on a | ||
911 | * per-destination basis when a changeover happens. | ||
912 | * char changeover_active; | ||
913 | * char cycling_changeover; | ||
914 | * __u32 next_tsn_at_change; | ||
915 | * char cacc_saw_newack; | ||
916 | */ | ||
917 | struct { | ||
918 | /* An unsigned integer, which stores the next TSN to be | ||
919 | * used by the sender, at the moment of changeover. | ||
920 | */ | ||
921 | __u32 next_tsn_at_change; | ||
922 | |||
923 | /* A flag which indicates the occurrence of a changeover */ | ||
924 | char changeover_active; | ||
925 | |||
926 | /* A flag which indicates whether the change of primary is | ||
927 | * the first switch to this destination address during an | ||
928 | * active switch. | ||
929 | */ | ||
930 | char cycling_changeover; | ||
931 | |||
932 | /* A temporary flag, which is used during the processing of | ||
933 | * a SACK to estimate the causative TSN(s)'s group. | ||
934 | */ | ||
935 | char cacc_saw_newack; | ||
936 | } cacc; | ||
937 | }; | ||
938 | |||
939 | struct sctp_transport *sctp_transport_new(const union sctp_addr *, int); | ||
940 | void sctp_transport_set_owner(struct sctp_transport *, | ||
941 | struct sctp_association *); | ||
942 | void sctp_transport_route(struct sctp_transport *, union sctp_addr *, | ||
943 | struct sctp_sock *); | ||
944 | void sctp_transport_pmtu(struct sctp_transport *); | ||
945 | void sctp_transport_free(struct sctp_transport *); | ||
946 | void sctp_transport_reset_timers(struct sctp_transport *); | ||
947 | void sctp_transport_hold(struct sctp_transport *); | ||
948 | void sctp_transport_put(struct sctp_transport *); | ||
949 | void sctp_transport_update_rto(struct sctp_transport *, __u32); | ||
950 | void sctp_transport_raise_cwnd(struct sctp_transport *, __u32, __u32); | ||
951 | void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t); | ||
952 | unsigned long sctp_transport_timeout(struct sctp_transport *); | ||
953 | |||
954 | |||
955 | /* This is the structure we use to queue packets as they come into | ||
956 | * SCTP. We write packets to it and read chunks from it. | ||
957 | */ | ||
958 | struct sctp_inq { | ||
959 | /* This is actually a queue of sctp_chunk each | ||
960 | * containing a partially decoded packet. | ||
961 | */ | ||
962 | struct sk_buff_head in; | ||
963 | /* This is the packet which is currently off the in queue and is | ||
964 | * being worked on through the inbound chunk processing. | ||
965 | */ | ||
966 | struct sctp_chunk *in_progress; | ||
967 | |||
968 | /* This is the delayed task to finish delivering inbound | ||
969 | * messages. | ||
970 | */ | ||
971 | struct work_struct immediate; | ||
972 | |||
973 | int malloced; /* Is this structure kfree()able? */ | ||
974 | }; | ||
975 | |||
976 | void sctp_inq_init(struct sctp_inq *); | ||
977 | void sctp_inq_free(struct sctp_inq *); | ||
978 | void sctp_inq_push(struct sctp_inq *, struct sctp_chunk *packet); | ||
979 | struct sctp_chunk *sctp_inq_pop(struct sctp_inq *); | ||
980 | void sctp_inq_set_th_handler(struct sctp_inq *, void (*)(void *), void *); | ||
981 | |||
982 | /* This is the structure we use to hold outbound chunks. You push | ||
983 | * chunks in and they automatically pop out the other end as bundled | ||
984 | * packets (it calls (*output_handler)()). | ||
985 | * | ||
986 | * This structure covers sections 6.3, 6.4, 6.7, 6.8, 6.10, 7., 8.1, | ||
987 | * and 8.2 of the v13 draft. | ||
988 | * | ||
989 | * It handles retransmissions. The connection to the timeout portion | ||
990 | * of the state machine is through sctp_..._timeout() and timeout_handler. | ||
991 | * | ||
992 | * If you feed it SACKs, it will eat them. | ||
993 | * | ||
994 | * If you give it big chunks, it will fragment them. | ||
995 | * | ||
996 | * It assigns TSN's to data chunks. This happens at the last possible | ||
997 | * instant before transmission. | ||
998 | * | ||
999 | * When free()'d, it empties itself out via output_handler(). | ||
1000 | */ | ||
1001 | struct sctp_outq { | ||
1002 | struct sctp_association *asoc; | ||
1003 | |||
1004 | /* Data pending that has never been transmitted. */ | ||
1005 | struct sk_buff_head out; | ||
1006 | |||
1007 | unsigned out_qlen; /* Total length of queued data chunks. */ | ||
1008 | |||
1009 | /* Error of send failed, may used in SCTP_SEND_FAILED event. */ | ||
1010 | unsigned error; | ||
1011 | |||
1012 | /* These are control chunks we want to send. */ | ||
1013 | struct sk_buff_head control; | ||
1014 | |||
1015 | /* These are chunks that have been sacked but are above the | ||
1016 | * CTSN, or cumulative tsn ack point. | ||
1017 | */ | ||
1018 | struct list_head sacked; | ||
1019 | |||
1020 | /* Put chunks on this list to schedule them for | ||
1021 | * retransmission. | ||
1022 | */ | ||
1023 | struct list_head retransmit; | ||
1024 | |||
1025 | /* Put chunks on this list to save them for FWD TSN processing as | ||
1026 | * they were abandoned. | ||
1027 | */ | ||
1028 | struct list_head abandoned; | ||
1029 | |||
1030 | /* How many unackd bytes do we have in-flight? */ | ||
1031 | __u32 outstanding_bytes; | ||
1032 | |||
1033 | /* Corked? */ | ||
1034 | char cork; | ||
1035 | |||
1036 | /* Is this structure empty? */ | ||
1037 | char empty; | ||
1038 | |||
1039 | /* Are we kfree()able? */ | ||
1040 | char malloced; | ||
1041 | }; | ||
1042 | |||
1043 | void sctp_outq_init(struct sctp_association *, struct sctp_outq *); | ||
1044 | void sctp_outq_teardown(struct sctp_outq *); | ||
1045 | void sctp_outq_free(struct sctp_outq*); | ||
1046 | int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk); | ||
1047 | int sctp_outq_flush(struct sctp_outq *, int); | ||
1048 | int sctp_outq_sack(struct sctp_outq *, struct sctp_sackhdr *); | ||
1049 | int sctp_outq_is_empty(const struct sctp_outq *); | ||
1050 | void sctp_outq_restart(struct sctp_outq *); | ||
1051 | |||
1052 | void sctp_retransmit(struct sctp_outq *, struct sctp_transport *, | ||
1053 | sctp_retransmit_reason_t); | ||
1054 | void sctp_retransmit_mark(struct sctp_outq *, struct sctp_transport *, __u8); | ||
1055 | int sctp_outq_uncork(struct sctp_outq *); | ||
1056 | /* Uncork and flush an outqueue. */ | ||
1057 | static inline void sctp_outq_cork(struct sctp_outq *q) | ||
1058 | { | ||
1059 | q->cork = 1; | ||
1060 | } | ||
1061 | |||
1062 | /* These bind address data fields common between endpoints and associations */ | ||
1063 | struct sctp_bind_addr { | ||
1064 | |||
1065 | /* RFC 2960 12.1 Parameters necessary for the SCTP instance | ||
1066 | * | ||
1067 | * SCTP Port: The local SCTP port number the endpoint is | ||
1068 | * bound to. | ||
1069 | */ | ||
1070 | __u16 port; | ||
1071 | |||
1072 | /* RFC 2960 12.1 Parameters necessary for the SCTP instance | ||
1073 | * | ||
1074 | * Address List: The list of IP addresses that this instance | ||
1075 | * has bound. This information is passed to one's | ||
1076 | * peer(s) in INIT and INIT ACK chunks. | ||
1077 | */ | ||
1078 | struct list_head address_list; | ||
1079 | |||
1080 | int malloced; /* Are we kfree()able? */ | ||
1081 | }; | ||
1082 | |||
1083 | void sctp_bind_addr_init(struct sctp_bind_addr *, __u16 port); | ||
1084 | void sctp_bind_addr_free(struct sctp_bind_addr *); | ||
1085 | int sctp_bind_addr_copy(struct sctp_bind_addr *dest, | ||
1086 | const struct sctp_bind_addr *src, | ||
1087 | sctp_scope_t scope, int gfp,int flags); | ||
1088 | int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *, | ||
1089 | int gfp); | ||
1090 | int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *); | ||
1091 | int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *, | ||
1092 | struct sctp_sock *); | ||
1093 | union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr *bp, | ||
1094 | const union sctp_addr *addrs, | ||
1095 | int addrcnt, | ||
1096 | struct sctp_sock *opt); | ||
1097 | union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp, | ||
1098 | int *addrs_len, int gfp); | ||
1099 | int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw, int len, | ||
1100 | __u16 port, int gfp); | ||
1101 | |||
1102 | sctp_scope_t sctp_scope(const union sctp_addr *); | ||
1103 | int sctp_in_scope(const union sctp_addr *addr, const sctp_scope_t scope); | ||
1104 | int sctp_is_any(const union sctp_addr *addr); | ||
1105 | int sctp_addr_is_valid(const union sctp_addr *addr); | ||
1106 | |||
1107 | |||
1108 | /* What type of endpoint? */ | ||
1109 | typedef enum { | ||
1110 | SCTP_EP_TYPE_SOCKET, | ||
1111 | SCTP_EP_TYPE_ASSOCIATION, | ||
1112 | } sctp_endpoint_type_t; | ||
1113 | |||
1114 | /* | ||
1115 | * A common base class to bridge the implmentation view of a | ||
1116 | * socket (usually listening) endpoint versus an association's | ||
1117 | * local endpoint. | ||
1118 | * This common structure is useful for several purposes: | ||
1119 | * 1) Common interface for lookup routines. | ||
1120 | * a) Subfunctions work for either endpoint or association | ||
1121 | * b) Single interface to lookup allows hiding the lookup lock rather | ||
1122 | * than acquiring it externally. | ||
1123 | * 2) Common interface for the inbound chunk handling/state machine. | ||
1124 | * 3) Common object handling routines for reference counting, etc. | ||
1125 | * 4) Disentangle association lookup from endpoint lookup, where we | ||
1126 | * do not have to find our endpoint to find our association. | ||
1127 | * | ||
1128 | */ | ||
1129 | |||
1130 | struct sctp_ep_common { | ||
1131 | /* Fields to help us manage our entries in the hash tables. */ | ||
1132 | struct sctp_ep_common *next; | ||
1133 | struct sctp_ep_common **pprev; | ||
1134 | int hashent; | ||
1135 | |||
1136 | /* Runtime type information. What kind of endpoint is this? */ | ||
1137 | sctp_endpoint_type_t type; | ||
1138 | |||
1139 | /* Some fields to help us manage this object. | ||
1140 | * refcnt - Reference count access to this object. | ||
1141 | * dead - Do not attempt to use this object. | ||
1142 | * malloced - Do we need to kfree this object? | ||
1143 | */ | ||
1144 | atomic_t refcnt; | ||
1145 | char dead; | ||
1146 | char malloced; | ||
1147 | |||
1148 | /* What socket does this endpoint belong to? */ | ||
1149 | struct sock *sk; | ||
1150 | |||
1151 | /* This is where we receive inbound chunks. */ | ||
1152 | struct sctp_inq inqueue; | ||
1153 | |||
1154 | /* This substructure includes the defining parameters of the | ||
1155 | * endpoint: | ||
1156 | * bind_addr.port is our shared port number. | ||
1157 | * bind_addr.address_list is our set of local IP addresses. | ||
1158 | */ | ||
1159 | struct sctp_bind_addr bind_addr; | ||
1160 | |||
1161 | /* Protection during address list comparisons. */ | ||
1162 | rwlock_t addr_lock; | ||
1163 | }; | ||
1164 | |||
1165 | |||
1166 | /* RFC Section 1.4 Key Terms | ||
1167 | * | ||
1168 | * o SCTP endpoint: The logical sender/receiver of SCTP packets. On a | ||
1169 | * multi-homed host, an SCTP endpoint is represented to its peers as a | ||
1170 | * combination of a set of eligible destination transport addresses to | ||
1171 | * which SCTP packets can be sent and a set of eligible source | ||
1172 | * transport addresses from which SCTP packets can be received. | ||
1173 | * All transport addresses used by an SCTP endpoint must use the | ||
1174 | * same port number, but can use multiple IP addresses. A transport | ||
1175 | * address used by an SCTP endpoint must not be used by another | ||
1176 | * SCTP endpoint. In other words, a transport address is unique | ||
1177 | * to an SCTP endpoint. | ||
1178 | * | ||
1179 | * From an implementation perspective, each socket has one of these. | ||
1180 | * A TCP-style socket will have exactly one association on one of | ||
1181 | * these. An UDP-style socket will have multiple associations hanging | ||
1182 | * off one of these. | ||
1183 | */ | ||
1184 | |||
1185 | struct sctp_endpoint { | ||
1186 | /* Common substructure for endpoint and association. */ | ||
1187 | struct sctp_ep_common base; | ||
1188 | |||
1189 | /* Associations: A list of current associations and mappings | ||
1190 | * to the data consumers for each association. This | ||
1191 | * may be in the form of a hash table or other | ||
1192 | * implementation dependent structure. The data | ||
1193 | * consumers may be process identification | ||
1194 | * information such as file descriptors, named pipe | ||
1195 | * pointer, or table pointers dependent on how SCTP | ||
1196 | * is implemented. | ||
1197 | */ | ||
1198 | /* This is really a list of struct sctp_association entries. */ | ||
1199 | struct list_head asocs; | ||
1200 | |||
1201 | /* Secret Key: A secret key used by this endpoint to compute | ||
1202 | * the MAC. This SHOULD be a cryptographic quality | ||
1203 | * random number with a sufficient length. | ||
1204 | * Discussion in [RFC1750] can be helpful in | ||
1205 | * selection of the key. | ||
1206 | */ | ||
1207 | __u8 secret_key[SCTP_HOW_MANY_SECRETS][SCTP_SECRET_SIZE]; | ||
1208 | int current_key; | ||
1209 | int last_key; | ||
1210 | int key_changed_at; | ||
1211 | |||
1212 | /* Default timeouts. */ | ||
1213 | int timeouts[SCTP_NUM_TIMEOUT_TYPES]; | ||
1214 | |||
1215 | /* Various thresholds. */ | ||
1216 | |||
1217 | /* Name for debugging output... */ | ||
1218 | char *debug_name; | ||
1219 | }; | ||
1220 | |||
1221 | /* Recover the outter endpoint structure. */ | ||
1222 | static inline struct sctp_endpoint *sctp_ep(struct sctp_ep_common *base) | ||
1223 | { | ||
1224 | struct sctp_endpoint *ep; | ||
1225 | |||
1226 | ep = container_of(base, struct sctp_endpoint, base); | ||
1227 | return ep; | ||
1228 | } | ||
1229 | |||
1230 | /* These are function signatures for manipulating endpoints. */ | ||
1231 | struct sctp_endpoint *sctp_endpoint_new(struct sock *, int); | ||
1232 | void sctp_endpoint_free(struct sctp_endpoint *); | ||
1233 | void sctp_endpoint_put(struct sctp_endpoint *); | ||
1234 | void sctp_endpoint_hold(struct sctp_endpoint *); | ||
1235 | void sctp_endpoint_add_asoc(struct sctp_endpoint *, struct sctp_association *); | ||
1236 | struct sctp_association *sctp_endpoint_lookup_assoc( | ||
1237 | const struct sctp_endpoint *ep, | ||
1238 | const union sctp_addr *paddr, | ||
1239 | struct sctp_transport **); | ||
1240 | int sctp_endpoint_is_peeled_off(struct sctp_endpoint *, | ||
1241 | const union sctp_addr *); | ||
1242 | struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *, | ||
1243 | const union sctp_addr *); | ||
1244 | int sctp_has_association(const union sctp_addr *laddr, | ||
1245 | const union sctp_addr *paddr); | ||
1246 | |||
1247 | int sctp_verify_init(const struct sctp_association *asoc, sctp_cid_t, | ||
1248 | sctp_init_chunk_t *peer_init, struct sctp_chunk *chunk, | ||
1249 | struct sctp_chunk **err_chunk); | ||
1250 | int sctp_process_init(struct sctp_association *, sctp_cid_t cid, | ||
1251 | const union sctp_addr *peer, | ||
1252 | sctp_init_chunk_t *init, int gfp); | ||
1253 | __u32 sctp_generate_tag(const struct sctp_endpoint *); | ||
1254 | __u32 sctp_generate_tsn(const struct sctp_endpoint *); | ||
1255 | |||
1256 | |||
1257 | /* RFC2960 | ||
1258 | * | ||
1259 | * 12. Recommended Transmission Control Block (TCB) Parameters | ||
1260 | * | ||
1261 | * This section details a recommended set of parameters that should | ||
1262 | * be contained within the TCB for an implementation. This section is | ||
1263 | * for illustrative purposes and should not be deemed as requirements | ||
1264 | * on an implementation or as an exhaustive list of all parameters | ||
1265 | * inside an SCTP TCB. Each implementation may need its own additional | ||
1266 | * parameters for optimization. | ||
1267 | */ | ||
1268 | |||
1269 | |||
1270 | /* Here we have information about each individual association. */ | ||
1271 | struct sctp_association { | ||
1272 | |||
1273 | /* A base structure common to endpoint and association. | ||
1274 | * In this context, it represents the associations's view | ||
1275 | * of the local endpoint of the association. | ||
1276 | */ | ||
1277 | struct sctp_ep_common base; | ||
1278 | |||
1279 | /* Associations on the same socket. */ | ||
1280 | struct list_head asocs; | ||
1281 | |||
1282 | /* association id. */ | ||
1283 | sctp_assoc_t assoc_id; | ||
1284 | |||
1285 | /* This is our parent endpoint. */ | ||
1286 | struct sctp_endpoint *ep; | ||
1287 | |||
1288 | /* These are those association elements needed in the cookie. */ | ||
1289 | struct sctp_cookie c; | ||
1290 | |||
1291 | /* This is all information about our peer. */ | ||
1292 | struct { | ||
1293 | /* rwnd | ||
1294 | * | ||
1295 | * Peer Rwnd : Current calculated value of the peer's rwnd. | ||
1296 | */ | ||
1297 | __u32 rwnd; | ||
1298 | |||
1299 | /* transport_addr_list | ||
1300 | * | ||
1301 | * Peer : A list of SCTP transport addresses that the | ||
1302 | * Transport : peer is bound to. This information is derived | ||
1303 | * Address : from the INIT or INIT ACK and is used to | ||
1304 | * List : associate an inbound packet with a given | ||
1305 | * : association. Normally this information is | ||
1306 | * : hashed or keyed for quick lookup and access | ||
1307 | * : of the TCB. | ||
1308 | * | ||
1309 | * It is a list of SCTP_transport's. | ||
1310 | */ | ||
1311 | struct list_head transport_addr_list; | ||
1312 | |||
1313 | /* port | ||
1314 | * The transport layer port number. | ||
1315 | */ | ||
1316 | __u16 port; | ||
1317 | |||
1318 | /* primary_path | ||
1319 | * | ||
1320 | * Primary : This is the current primary destination | ||
1321 | * Path : transport address of the peer endpoint. It | ||
1322 | * : may also specify a source transport address | ||
1323 | * : on this endpoint. | ||
1324 | * | ||
1325 | * All of these paths live on transport_addr_list. | ||
1326 | * | ||
1327 | * At the bakeoffs, we discovered that the intent of | ||
1328 | * primaryPath is that it only changes when the ULP | ||
1329 | * asks to have it changed. We add the activePath to | ||
1330 | * designate the connection we are currently using to | ||
1331 | * transmit new data and most control chunks. | ||
1332 | */ | ||
1333 | struct sctp_transport *primary_path; | ||
1334 | |||
1335 | /* Cache the primary path address here, when we | ||
1336 | * need a an address for msg_name. | ||
1337 | */ | ||
1338 | union sctp_addr primary_addr; | ||
1339 | |||
1340 | /* active_path | ||
1341 | * The path that we are currently using to | ||
1342 | * transmit new data and most control chunks. | ||
1343 | */ | ||
1344 | struct sctp_transport *active_path; | ||
1345 | |||
1346 | /* retran_path | ||
1347 | * | ||
1348 | * RFC2960 6.4 Multi-homed SCTP Endpoints | ||
1349 | * ... | ||
1350 | * Furthermore, when its peer is multi-homed, an | ||
1351 | * endpoint SHOULD try to retransmit a chunk to an | ||
1352 | * active destination transport address that is | ||
1353 | * different from the last destination address to | ||
1354 | * which the DATA chunk was sent. | ||
1355 | */ | ||
1356 | struct sctp_transport *retran_path; | ||
1357 | |||
1358 | /* Pointer to last transport I have sent on. */ | ||
1359 | struct sctp_transport *last_sent_to; | ||
1360 | |||
1361 | /* This is the last transport I have received DATA on. */ | ||
1362 | struct sctp_transport *last_data_from; | ||
1363 | |||
1364 | /* | ||
1365 | * Mapping An array of bits or bytes indicating which out of | ||
1366 | * Array order TSN's have been received (relative to the | ||
1367 | * Last Rcvd TSN). If no gaps exist, i.e. no out of | ||
1368 | * order packets have been received, this array | ||
1369 | * will be set to all zero. This structure may be | ||
1370 | * in the form of a circular buffer or bit array. | ||
1371 | * | ||
1372 | * Last Rcvd : This is the last TSN received in | ||
1373 | * TSN : sequence. This value is set initially by | ||
1374 | * : taking the peer's Initial TSN, received in | ||
1375 | * : the INIT or INIT ACK chunk, and subtracting | ||
1376 | * : one from it. | ||
1377 | * | ||
1378 | * Throughout most of the specification this is called the | ||
1379 | * "Cumulative TSN ACK Point". In this case, we | ||
1380 | * ignore the advice in 12.2 in favour of the term | ||
1381 | * used in the bulk of the text. This value is hidden | ||
1382 | * in tsn_map--we get it by calling sctp_tsnmap_get_ctsn(). | ||
1383 | */ | ||
1384 | struct sctp_tsnmap tsn_map; | ||
1385 | __u8 _map[sctp_tsnmap_storage_size(SCTP_TSN_MAP_SIZE)]; | ||
1386 | |||
1387 | /* Ack State : This flag indicates if the next received | ||
1388 | * : packet is to be responded to with a | ||
1389 | * : SACK. This is initializedto 0. When a packet | ||
1390 | * : is received it is incremented. If this value | ||
1391 | * : reaches 2 or more, a SACK is sent and the | ||
1392 | * : value is reset to 0. Note: This is used only | ||
1393 | * : when no DATA chunks are received out of | ||
1394 | * : order. When DATA chunks are out of order, | ||
1395 | * : SACK's are not delayed (see Section 6). | ||
1396 | */ | ||
1397 | __u8 sack_needed; /* Do we need to sack the peer? */ | ||
1398 | |||
1399 | /* These are capabilities which our peer advertised. */ | ||
1400 | __u8 ecn_capable; /* Can peer do ECN? */ | ||
1401 | __u8 ipv4_address; /* Peer understands IPv4 addresses? */ | ||
1402 | __u8 ipv6_address; /* Peer understands IPv6 addresses? */ | ||
1403 | __u8 hostname_address;/* Peer understands DNS addresses? */ | ||
1404 | __u8 asconf_capable; /* Does peer support ADDIP? */ | ||
1405 | __u8 prsctp_capable; /* Can peer do PR-SCTP? */ | ||
1406 | |||
1407 | __u32 adaption_ind; /* Adaption Code point. */ | ||
1408 | |||
1409 | /* This mask is used to disable sending the ASCONF chunk | ||
1410 | * with specified parameter to peer. | ||
1411 | */ | ||
1412 | __u16 addip_disabled_mask; | ||
1413 | |||
1414 | struct sctp_inithdr i; | ||
1415 | int cookie_len; | ||
1416 | void *cookie; | ||
1417 | |||
1418 | /* ADDIP Section 4.2 Upon reception of an ASCONF Chunk. | ||
1419 | * C1) ... "Peer-Serial-Number'. This value MUST be initialized to the | ||
1420 | * Initial TSN Value minus 1 | ||
1421 | */ | ||
1422 | __u32 addip_serial; | ||
1423 | } peer; | ||
1424 | |||
1425 | /* State : A state variable indicating what state the | ||
1426 | * : association is in, i.e. COOKIE-WAIT, | ||
1427 | * : COOKIE-ECHOED, ESTABLISHED, SHUTDOWN-PENDING, | ||
1428 | * : SHUTDOWN-SENT, SHUTDOWN-RECEIVED, SHUTDOWN-ACK-SENT. | ||
1429 | * | ||
1430 | * Note: No "CLOSED" state is illustrated since if a | ||
1431 | * association is "CLOSED" its TCB SHOULD be removed. | ||
1432 | * | ||
1433 | * In this implementation we DO have a CLOSED | ||
1434 | * state which is used during initiation and shutdown. | ||
1435 | * | ||
1436 | * State takes values from SCTP_STATE_*. | ||
1437 | */ | ||
1438 | sctp_state_t state; | ||
1439 | |||
1440 | /* The cookie life I award for any cookie. */ | ||
1441 | struct timeval cookie_life; | ||
1442 | |||
1443 | /* Overall : The overall association error count. | ||
1444 | * Error Count : [Clear this any time I get something.] | ||
1445 | */ | ||
1446 | int overall_error_count; | ||
1447 | |||
1448 | /* These are the association's initial, max, and min RTO values. | ||
1449 | * These values will be initialized by system defaults, but can | ||
1450 | * be modified via the SCTP_RTOINFO socket option. | ||
1451 | */ | ||
1452 | __u32 rto_initial; | ||
1453 | __u32 rto_max; | ||
1454 | __u32 rto_min; | ||
1455 | |||
1456 | /* Maximum number of new data packets that can be sent in a burst. */ | ||
1457 | int max_burst; | ||
1458 | |||
1459 | /* This is the max_retrans value for the association. This value will | ||
1460 | * be initialized initialized from system defaults, but can be | ||
1461 | * modified by the SCTP_ASSOCINFO socket option. | ||
1462 | */ | ||
1463 | int max_retrans; | ||
1464 | |||
1465 | /* Maximum number of times the endpoint will retransmit INIT */ | ||
1466 | __u16 max_init_attempts; | ||
1467 | |||
1468 | /* How many times have we resent an INIT? */ | ||
1469 | __u16 init_retries; | ||
1470 | |||
1471 | /* The largest timeout or RTO value to use in attempting an INIT */ | ||
1472 | __u16 max_init_timeo; | ||
1473 | |||
1474 | int timeouts[SCTP_NUM_TIMEOUT_TYPES]; | ||
1475 | struct timer_list timers[SCTP_NUM_TIMEOUT_TYPES]; | ||
1476 | |||
1477 | /* Transport to which SHUTDOWN chunk was last sent. */ | ||
1478 | struct sctp_transport *shutdown_last_sent_to; | ||
1479 | |||
1480 | /* Next TSN : The next TSN number to be assigned to a new | ||
1481 | * : DATA chunk. This is sent in the INIT or INIT | ||
1482 | * : ACK chunk to the peer and incremented each | ||
1483 | * : time a DATA chunk is assigned a TSN | ||
1484 | * : (normally just prior to transmit or during | ||
1485 | * : fragmentation). | ||
1486 | */ | ||
1487 | __u32 next_tsn; | ||
1488 | |||
1489 | /* | ||
1490 | * Last Rcvd : This is the last TSN received in sequence. This value | ||
1491 | * TSN : is set initially by taking the peer's Initial TSN, | ||
1492 | * : received in the INIT or INIT ACK chunk, and | ||
1493 | * : subtracting one from it. | ||
1494 | * | ||
1495 | * Most of RFC 2960 refers to this as the Cumulative TSN Ack Point. | ||
1496 | */ | ||
1497 | |||
1498 | __u32 ctsn_ack_point; | ||
1499 | |||
1500 | /* PR-SCTP Advanced.Peer.Ack.Point */ | ||
1501 | __u32 adv_peer_ack_point; | ||
1502 | |||
1503 | /* Highest TSN that is acknowledged by incoming SACKs. */ | ||
1504 | __u32 highest_sacked; | ||
1505 | |||
1506 | /* The number of unacknowledged data chunks. Reported through | ||
1507 | * the SCTP_STATUS sockopt. | ||
1508 | */ | ||
1509 | __u16 unack_data; | ||
1510 | |||
1511 | /* This is the association's receive buffer space. This value is used | ||
1512 | * to set a_rwnd field in an INIT or a SACK chunk. | ||
1513 | */ | ||
1514 | __u32 rwnd; | ||
1515 | |||
1516 | /* This is the last advertised value of rwnd over a SACK chunk. */ | ||
1517 | __u32 a_rwnd; | ||
1518 | |||
1519 | /* Number of bytes by which the rwnd has slopped. The rwnd is allowed | ||
1520 | * to slop over a maximum of the association's frag_point. | ||
1521 | */ | ||
1522 | __u32 rwnd_over; | ||
1523 | |||
1524 | /* This is the sndbuf size in use for the association. | ||
1525 | * This corresponds to the sndbuf size for the association, | ||
1526 | * as specified in the sk->sndbuf. | ||
1527 | */ | ||
1528 | int sndbuf_used; | ||
1529 | |||
1530 | /* This is the wait queue head for send requests waiting on | ||
1531 | * the association sndbuf space. | ||
1532 | */ | ||
1533 | wait_queue_head_t wait; | ||
1534 | |||
1535 | /* Association : The smallest PMTU discovered for all of the | ||
1536 | * PMTU : peer's transport addresses. | ||
1537 | */ | ||
1538 | __u32 pmtu; | ||
1539 | |||
1540 | /* The message size at which SCTP fragmentation will occur. */ | ||
1541 | __u32 frag_point; | ||
1542 | |||
1543 | /* Currently only one counter is used to count INIT errors. */ | ||
1544 | int counters[SCTP_NUMBER_COUNTERS]; | ||
1545 | |||
1546 | /* Default send parameters. */ | ||
1547 | __u16 default_stream; | ||
1548 | __u16 default_flags; | ||
1549 | __u32 default_ppid; | ||
1550 | __u32 default_context; | ||
1551 | __u32 default_timetolive; | ||
1552 | |||
1553 | /* This tracks outbound ssn for a given stream. */ | ||
1554 | struct sctp_ssnmap *ssnmap; | ||
1555 | |||
1556 | /* All outbound chunks go through this structure. */ | ||
1557 | struct sctp_outq outqueue; | ||
1558 | |||
1559 | /* A smart pipe that will handle reordering and fragmentation, | ||
1560 | * as well as handle passing events up to the ULP. | ||
1561 | */ | ||
1562 | struct sctp_ulpq ulpq; | ||
1563 | |||
1564 | /* Last TSN that caused an ECNE Chunk to be sent. */ | ||
1565 | __u32 last_ecne_tsn; | ||
1566 | |||
1567 | /* Last TSN that caused a CWR Chunk to be sent. */ | ||
1568 | __u32 last_cwr_tsn; | ||
1569 | |||
1570 | /* How many duplicated TSNs have we seen? */ | ||
1571 | int numduptsns; | ||
1572 | |||
1573 | /* Number of seconds of idle time before an association is closed. */ | ||
1574 | __u32 autoclose; | ||
1575 | |||
1576 | /* These are to support | ||
1577 | * "SCTP Extensions for Dynamic Reconfiguration of IP Addresses | ||
1578 | * and Enforcement of Flow and Message Limits" | ||
1579 | * <draft-ietf-tsvwg-addip-sctp-02.txt> | ||
1580 | * or "ADDIP" for short. | ||
1581 | */ | ||
1582 | |||
1583 | |||
1584 | |||
1585 | /* ADDIP Section 4.1.1 Congestion Control of ASCONF Chunks | ||
1586 | * | ||
1587 | * R1) One and only one ASCONF Chunk MAY be in transit and | ||
1588 | * unacknowledged at any one time. If a sender, after sending | ||
1589 | * an ASCONF chunk, decides it needs to transfer another | ||
1590 | * ASCONF Chunk, it MUST wait until the ASCONF-ACK Chunk | ||
1591 | * returns from the previous ASCONF Chunk before sending a | ||
1592 | * subsequent ASCONF. Note this restriction binds each side, | ||
1593 | * so at any time two ASCONF may be in-transit on any given | ||
1594 | * association (one sent from each endpoint). | ||
1595 | * | ||
1596 | * [This is our one-and-only-one ASCONF in flight. If we do | ||
1597 | * not have an ASCONF in flight, this is NULL.] | ||
1598 | */ | ||
1599 | struct sctp_chunk *addip_last_asconf; | ||
1600 | |||
1601 | /* ADDIP Section 4.2 Upon reception of an ASCONF Chunk. | ||
1602 | * | ||
1603 | * IMPLEMENTATION NOTE: As an optimization a receiver may wish | ||
1604 | * to save the last ASCONF-ACK for some predetermined period | ||
1605 | * of time and instead of re-processing the ASCONF (with the | ||
1606 | * same serial number) it may just re-transmit the | ||
1607 | * ASCONF-ACK. It may wish to use the arrival of a new serial | ||
1608 | * number to discard the previously saved ASCONF-ACK or any | ||
1609 | * other means it may choose to expire the saved ASCONF-ACK. | ||
1610 | * | ||
1611 | * [This is our saved ASCONF-ACK. We invalidate it when a new | ||
1612 | * ASCONF serial number arrives.] | ||
1613 | */ | ||
1614 | struct sctp_chunk *addip_last_asconf_ack; | ||
1615 | |||
1616 | /* These ASCONF chunks are waiting to be sent. | ||
1617 | * | ||
1618 | * These chunaks can't be pushed to outqueue until receiving | ||
1619 | * ASCONF_ACK for the previous ASCONF indicated by | ||
1620 | * addip_last_asconf, so as to guarantee that only one ASCONF | ||
1621 | * is in flight at any time. | ||
1622 | * | ||
1623 | * ADDIP Section 4.1.1 Congestion Control of ASCONF Chunks | ||
1624 | * | ||
1625 | * In defining the ASCONF Chunk transfer procedures, it is | ||
1626 | * essential that these transfers MUST NOT cause congestion | ||
1627 | * within the network. To achieve this, we place these | ||
1628 | * restrictions on the transfer of ASCONF Chunks: | ||
1629 | * | ||
1630 | * R1) One and only one ASCONF Chunk MAY be in transit and | ||
1631 | * unacknowledged at any one time. If a sender, after sending | ||
1632 | * an ASCONF chunk, decides it needs to transfer another | ||
1633 | * ASCONF Chunk, it MUST wait until the ASCONF-ACK Chunk | ||
1634 | * returns from the previous ASCONF Chunk before sending a | ||
1635 | * subsequent ASCONF. Note this restriction binds each side, | ||
1636 | * so at any time two ASCONF may be in-transit on any given | ||
1637 | * association (one sent from each endpoint). | ||
1638 | * | ||
1639 | * | ||
1640 | * [I really think this is EXACTLY the sort of intelligence | ||
1641 | * which already resides in sctp_outq. Please move this | ||
1642 | * queue and its supporting logic down there. --piggy] | ||
1643 | */ | ||
1644 | struct sk_buff_head addip_chunks; | ||
1645 | |||
1646 | /* ADDIP Section 4.1 ASCONF Chunk Procedures | ||
1647 | * | ||
1648 | * A2) A serial number should be assigned to the Chunk. The | ||
1649 | * serial number SHOULD be a monotonically increasing | ||
1650 | * number. The serial number SHOULD be initialized at | ||
1651 | * the start of the association to the same value as the | ||
1652 | * Initial TSN and every time a new ASCONF chunk is created | ||
1653 | * it is incremented by one after assigning the serial number | ||
1654 | * to the newly created chunk. | ||
1655 | * | ||
1656 | * ADDIP | ||
1657 | * 3.1.1 Address/Stream Configuration Change Chunk (ASCONF) | ||
1658 | * | ||
1659 | * Serial Number : 32 bits (unsigned integer) | ||
1660 | * | ||
1661 | * This value represents a Serial Number for the ASCONF | ||
1662 | * Chunk. The valid range of Serial Number is from 0 to | ||
1663 | * 4294967295 (2^32 - 1). Serial Numbers wrap back to 0 | ||
1664 | * after reaching 4294967295. | ||
1665 | */ | ||
1666 | __u32 addip_serial; | ||
1667 | |||
1668 | /* Need to send an ECNE Chunk? */ | ||
1669 | char need_ecne; | ||
1670 | |||
1671 | /* Is it a temporary association? */ | ||
1672 | char temp; | ||
1673 | }; | ||
1674 | |||
1675 | |||
1676 | /* An eyecatcher for determining if we are really looking at an | ||
1677 | * association data structure. | ||
1678 | */ | ||
1679 | enum { | ||
1680 | SCTP_ASSOC_EYECATCHER = 0xa550c123, | ||
1681 | }; | ||
1682 | |||
1683 | /* Recover the outter association structure. */ | ||
1684 | static inline struct sctp_association *sctp_assoc(struct sctp_ep_common *base) | ||
1685 | { | ||
1686 | struct sctp_association *asoc; | ||
1687 | |||
1688 | asoc = container_of(base, struct sctp_association, base); | ||
1689 | return asoc; | ||
1690 | } | ||
1691 | |||
1692 | /* These are function signatures for manipulating associations. */ | ||
1693 | |||
1694 | |||
1695 | struct sctp_association * | ||
1696 | sctp_association_new(const struct sctp_endpoint *, const struct sock *, | ||
1697 | sctp_scope_t scope, int gfp); | ||
1698 | void sctp_association_free(struct sctp_association *); | ||
1699 | void sctp_association_put(struct sctp_association *); | ||
1700 | void sctp_association_hold(struct sctp_association *); | ||
1701 | |||
1702 | struct sctp_transport *sctp_assoc_choose_shutdown_transport( | ||
1703 | struct sctp_association *); | ||
1704 | void sctp_assoc_update_retran_path(struct sctp_association *); | ||
1705 | struct sctp_transport *sctp_assoc_lookup_paddr(const struct sctp_association *, | ||
1706 | const union sctp_addr *); | ||
1707 | int sctp_assoc_lookup_laddr(struct sctp_association *asoc, | ||
1708 | const union sctp_addr *laddr); | ||
1709 | struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *, | ||
1710 | const union sctp_addr *address, | ||
1711 | const int gfp); | ||
1712 | void sctp_assoc_del_peer(struct sctp_association *asoc, | ||
1713 | const union sctp_addr *addr); | ||
1714 | void sctp_assoc_control_transport(struct sctp_association *, | ||
1715 | struct sctp_transport *, | ||
1716 | sctp_transport_cmd_t, sctp_sn_error_t); | ||
1717 | struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *, __u32); | ||
1718 | struct sctp_transport *sctp_assoc_is_match(struct sctp_association *, | ||
1719 | const union sctp_addr *, | ||
1720 | const union sctp_addr *); | ||
1721 | void sctp_assoc_migrate(struct sctp_association *, struct sock *); | ||
1722 | void sctp_assoc_update(struct sctp_association *old, | ||
1723 | struct sctp_association *new); | ||
1724 | |||
1725 | __u32 sctp_association_get_next_tsn(struct sctp_association *); | ||
1726 | |||
1727 | void sctp_assoc_sync_pmtu(struct sctp_association *); | ||
1728 | void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned); | ||
1729 | void sctp_assoc_rwnd_decrease(struct sctp_association *, unsigned); | ||
1730 | void sctp_assoc_set_primary(struct sctp_association *, | ||
1731 | struct sctp_transport *); | ||
1732 | int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *, int); | ||
1733 | int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *, | ||
1734 | struct sctp_cookie*, int gfp); | ||
1735 | |||
1736 | int sctp_cmp_addr_exact(const union sctp_addr *ss1, | ||
1737 | const union sctp_addr *ss2); | ||
1738 | struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc); | ||
1739 | |||
1740 | /* A convenience structure to parse out SCTP specific CMSGs. */ | ||
1741 | typedef struct sctp_cmsgs { | ||
1742 | struct sctp_initmsg *init; | ||
1743 | struct sctp_sndrcvinfo *info; | ||
1744 | } sctp_cmsgs_t; | ||
1745 | |||
1746 | /* Structure for tracking memory objects */ | ||
1747 | typedef struct { | ||
1748 | char *label; | ||
1749 | atomic_t *counter; | ||
1750 | } sctp_dbg_objcnt_entry_t; | ||
1751 | |||
1752 | #endif /* __sctp_structs_h__ */ | ||
diff --git a/include/net/sctp/tsnmap.h b/include/net/sctp/tsnmap.h new file mode 100644 index 000000000000..021947da70ea --- /dev/null +++ b/include/net/sctp/tsnmap.h | |||
@@ -0,0 +1,207 @@ | |||
1 | /* SCTP kernel reference Implementation | ||
2 | * (C) Copyright IBM Corp. 2001, 2004 | ||
3 | * Copyright (c) 1999-2000 Cisco, Inc. | ||
4 | * Copyright (c) 1999-2001 Motorola, Inc. | ||
5 | * Copyright (c) 2001 Intel Corp. | ||
6 | * | ||
7 | * This file is part of the SCTP kernel reference Implementation | ||
8 | * | ||
9 | * These are the definitions needed for the tsnmap type. The tsnmap is used | ||
10 | * to track out of order TSNs received. | ||
11 | * | ||
12 | * The SCTP reference implementation is free software; | ||
13 | * you can redistribute it and/or modify it under the terms of | ||
14 | * the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2, or (at your option) | ||
16 | * any later version. | ||
17 | * | ||
18 | * The SCTP reference implementation is distributed in the hope that it | ||
19 | * will be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
20 | * ************************ | ||
21 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
22 | * See the GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with GNU CC; see the file COPYING. If not, write to | ||
26 | * the Free Software Foundation, 59 Temple Place - Suite 330, | ||
27 | * Boston, MA 02111-1307, USA. | ||
28 | * | ||
29 | * Please send any bug reports or fixes you make to the | ||
30 | * email address(es): | ||
31 | * lksctp developers <lksctp-developers@lists.sourceforge.net> | ||
32 | * | ||
33 | * Or submit a bug report through the following website: | ||
34 | * http://www.sf.net/projects/lksctp | ||
35 | * | ||
36 | * Written or modified by: | ||
37 | * Jon Grimm <jgrimm@us.ibm.com> | ||
38 | * La Monte H.P. Yarroll <piggy@acm.org> | ||
39 | * Karl Knutson <karl@athena.chicago.il.us> | ||
40 | * Sridhar Samudrala <sri@us.ibm.com> | ||
41 | * | ||
42 | * Any bugs reported given to us we will try to fix... any fixes shared will | ||
43 | * be incorporated into the next SCTP release. | ||
44 | */ | ||
45 | #include <net/sctp/constants.h> | ||
46 | |||
47 | #ifndef __sctp_tsnmap_h__ | ||
48 | #define __sctp_tsnmap_h__ | ||
49 | |||
50 | /* RFC 2960 12.2 Parameters necessary per association (i.e. the TCB) | ||
51 | * Mapping An array of bits or bytes indicating which out of | ||
52 | * Array order TSN's have been received (relative to the | ||
53 | * Last Rcvd TSN). If no gaps exist, i.e. no out of | ||
54 | * order packets have been received, this array | ||
55 | * will be set to all zero. This structure may be | ||
56 | * in the form of a circular buffer or bit array. | ||
57 | */ | ||
58 | struct sctp_tsnmap { | ||
59 | /* This array counts the number of chunks with each TSN. | ||
60 | * It points at one of the two buffers with which we will | ||
61 | * ping-pong between. | ||
62 | */ | ||
63 | __u8 *tsn_map; | ||
64 | |||
65 | /* This marks the tsn which overflows the tsn_map, when the | ||
66 | * cumulative ack point reaches this point we know we can switch | ||
67 | * maps (tsn_map and overflow_map swap). | ||
68 | */ | ||
69 | __u32 overflow_tsn; | ||
70 | |||
71 | /* This is the overflow array for tsn_map. | ||
72 | * It points at one of the other ping-pong buffers. | ||
73 | */ | ||
74 | __u8 *overflow_map; | ||
75 | |||
76 | /* This is the TSN at tsn_map[0]. */ | ||
77 | __u32 base_tsn; | ||
78 | |||
79 | /* Last Rcvd : This is the last TSN received in | ||
80 | * TSN : sequence. This value is set initially by | ||
81 | * : taking the peer's Initial TSN, received in | ||
82 | * : the INIT or INIT ACK chunk, and subtracting | ||
83 | * : one from it. | ||
84 | * | ||
85 | * Throughout most of the specification this is called the | ||
86 | * "Cumulative TSN ACK Point". In this case, we | ||
87 | * ignore the advice in 12.2 in favour of the term | ||
88 | * used in the bulk of the text. | ||
89 | */ | ||
90 | __u32 cumulative_tsn_ack_point; | ||
91 | |||
92 | /* This is the minimum number of TSNs we can track. This corresponds | ||
93 | * to the size of tsn_map. Note: the overflow_map allows us to | ||
94 | * potentially track more than this quantity. | ||
95 | */ | ||
96 | __u16 len; | ||
97 | |||
98 | /* This is the highest TSN we've marked. */ | ||
99 | __u32 max_tsn_seen; | ||
100 | |||
101 | /* Data chunks pending receipt. used by SCTP_STATUS sockopt */ | ||
102 | __u16 pending_data; | ||
103 | |||
104 | /* Record duplicate TSNs here. We clear this after | ||
105 | * every SACK. Store up to SCTP_MAX_DUP_TSNS worth of | ||
106 | * information. | ||
107 | */ | ||
108 | __u32 dup_tsns[SCTP_MAX_DUP_TSNS]; | ||
109 | __u16 num_dup_tsns; | ||
110 | |||
111 | /* Record gap ack block information here. */ | ||
112 | struct sctp_gap_ack_block gabs[SCTP_MAX_GABS]; | ||
113 | |||
114 | int malloced; | ||
115 | |||
116 | __u8 raw_map[0]; | ||
117 | }; | ||
118 | |||
119 | struct sctp_tsnmap_iter { | ||
120 | __u32 start; | ||
121 | }; | ||
122 | |||
123 | /* This macro assists in creation of external storage for variable length | ||
124 | * internal buffers. We double allocate so the overflow map works. | ||
125 | */ | ||
126 | #define sctp_tsnmap_storage_size(count) (sizeof(__u8) * (count) * 2) | ||
127 | |||
128 | /* Initialize a block of memory as a tsnmap. */ | ||
129 | struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *, __u16 len, | ||
130 | __u32 initial_tsn); | ||
131 | |||
132 | /* Test the tracking state of this TSN. | ||
133 | * Returns: | ||
134 | * 0 if the TSN has not yet been seen | ||
135 | * >0 if the TSN has been seen (duplicate) | ||
136 | * <0 if the TSN is invalid (too large to track) | ||
137 | */ | ||
138 | int sctp_tsnmap_check(const struct sctp_tsnmap *, __u32 tsn); | ||
139 | |||
140 | /* Mark this TSN as seen. */ | ||
141 | void sctp_tsnmap_mark(struct sctp_tsnmap *, __u32 tsn); | ||
142 | |||
143 | /* Mark this TSN and all lower as seen. */ | ||
144 | void sctp_tsnmap_skip(struct sctp_tsnmap *map, __u32 tsn); | ||
145 | |||
146 | /* Retrieve the Cumulative TSN ACK Point. */ | ||
147 | static inline __u32 sctp_tsnmap_get_ctsn(const struct sctp_tsnmap *map) | ||
148 | { | ||
149 | return map->cumulative_tsn_ack_point; | ||
150 | } | ||
151 | |||
152 | /* Retrieve the highest TSN we've seen. */ | ||
153 | static inline __u32 sctp_tsnmap_get_max_tsn_seen(const struct sctp_tsnmap *map) | ||
154 | { | ||
155 | return map->max_tsn_seen; | ||
156 | } | ||
157 | |||
158 | /* How many duplicate TSNs are stored? */ | ||
159 | static inline __u16 sctp_tsnmap_num_dups(struct sctp_tsnmap *map) | ||
160 | { | ||
161 | return map->num_dup_tsns; | ||
162 | } | ||
163 | |||
164 | /* Return pointer to duplicate tsn array as needed by SACK. */ | ||
165 | static inline __u32 *sctp_tsnmap_get_dups(struct sctp_tsnmap *map) | ||
166 | { | ||
167 | map->num_dup_tsns = 0; | ||
168 | return map->dup_tsns; | ||
169 | } | ||
170 | |||
171 | /* How many gap ack blocks do we have recorded? */ | ||
172 | __u16 sctp_tsnmap_num_gabs(struct sctp_tsnmap *map); | ||
173 | |||
174 | /* Refresh the count on pending data. */ | ||
175 | __u16 sctp_tsnmap_pending(struct sctp_tsnmap *map); | ||
176 | |||
177 | /* Return pointer to gap ack blocks as needed by SACK. */ | ||
178 | static inline struct sctp_gap_ack_block *sctp_tsnmap_get_gabs(struct sctp_tsnmap *map) | ||
179 | { | ||
180 | return map->gabs; | ||
181 | } | ||
182 | |||
183 | /* Is there a gap in the TSN map? */ | ||
184 | static inline int sctp_tsnmap_has_gap(const struct sctp_tsnmap *map) | ||
185 | { | ||
186 | int has_gap; | ||
187 | |||
188 | has_gap = (map->cumulative_tsn_ack_point != map->max_tsn_seen); | ||
189 | return has_gap; | ||
190 | } | ||
191 | |||
192 | /* Mark a duplicate TSN. Note: limit the storage of duplicate TSN | ||
193 | * information. | ||
194 | */ | ||
195 | static inline void sctp_tsnmap_mark_dup(struct sctp_tsnmap *map, __u32 tsn) | ||
196 | { | ||
197 | if (map->num_dup_tsns < SCTP_MAX_DUP_TSNS) | ||
198 | map->dup_tsns[map->num_dup_tsns++] = htonl(tsn); | ||
199 | } | ||
200 | |||
201 | /* Renege a TSN that was seen. */ | ||
202 | void sctp_tsnmap_renege(struct sctp_tsnmap *, __u32 tsn); | ||
203 | |||
204 | /* Is there a gap in the TSN map? */ | ||
205 | int sctp_tsnmap_has_gap(const struct sctp_tsnmap *); | ||
206 | |||
207 | #endif /* __sctp_tsnmap_h__ */ | ||
diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h new file mode 100644 index 000000000000..1019d83a580a --- /dev/null +++ b/include/net/sctp/ulpevent.h | |||
@@ -0,0 +1,162 @@ | |||
1 | /* SCTP kernel reference Implementation | ||
2 | * (C) Copyright IBM Corp. 2001, 2004 | ||
3 | * Copyright (c) 1999-2000 Cisco, Inc. | ||
4 | * Copyright (c) 1999-2001 Motorola, Inc. | ||
5 | * Copyright (c) 2001 Intel Corp. | ||
6 | * Copyright (c) 2001 Nokia, Inc. | ||
7 | * Copyright (c) 2001 La Monte H.P. Yarroll | ||
8 | * | ||
9 | * These are the definitions needed for the sctp_ulpevent type. The | ||
10 | * sctp_ulpevent type is used to carry information from the state machine | ||
11 | * upwards to the ULP. | ||
12 | * | ||
13 | * This file is part of the SCTP kernel reference Implementation | ||
14 | * | ||
15 | * The SCTP reference implementation is free software; | ||
16 | * you can redistribute it and/or modify it under the terms of | ||
17 | * the GNU General Public License as published by | ||
18 | * the Free Software Foundation; either version 2, or (at your option) | ||
19 | * any later version. | ||
20 | * | ||
21 | * The SCTP reference implementation is distributed in the hope that it | ||
22 | * will be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
23 | * ************************ | ||
24 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
25 | * See the GNU General Public License for more details. | ||
26 | * | ||
27 | * You should have received a copy of the GNU General Public License | ||
28 | * along with GNU CC; see the file COPYING. If not, write to | ||
29 | * the Free Software Foundation, 59 Temple Place - Suite 330, | ||
30 | * Boston, MA 02111-1307, USA. | ||
31 | * | ||
32 | * Please send any bug reports or fixes you make to the | ||
33 | * email address(es): | ||
34 | * lksctp developers <lksctp-developers@lists.sourceforge.net> | ||
35 | * | ||
36 | * Or submit a bug report through the following website: | ||
37 | * http://www.sf.net/projects/lksctp | ||
38 | * | ||
39 | * Written or modified by: | ||
40 | * Jon Grimm <jgrimm@us.ibm.com> | ||
41 | * La Monte H.P. Yarroll <piggy@acm.org> | ||
42 | * Karl Knutson <karl@athena.chicago.il.us> | ||
43 | * Sridhar Samudrala <sri@us.ibm.com> | ||
44 | * | ||
45 | * Any bugs reported given to us we will try to fix... any fixes shared will | ||
46 | * be incorporated into the next SCTP release. | ||
47 | */ | ||
48 | |||
49 | #ifndef __sctp_ulpevent_h__ | ||
50 | #define __sctp_ulpevent_h__ | ||
51 | |||
52 | /* A structure to carry information to the ULP (e.g. Sockets API) */ | ||
53 | /* Warning: This sits inside an skb.cb[] area. Be very careful of | ||
54 | * growing this structure as it is at the maximum limit now. | ||
55 | */ | ||
56 | struct sctp_ulpevent { | ||
57 | struct sctp_association *asoc; | ||
58 | __u16 stream; | ||
59 | __u16 ssn; | ||
60 | __u16 flags; | ||
61 | __u32 ppid; | ||
62 | __u32 tsn; | ||
63 | __u32 cumtsn; | ||
64 | int msg_flags; | ||
65 | int iif; | ||
66 | }; | ||
67 | |||
68 | /* Retrieve the skb this event sits inside of. */ | ||
69 | static inline struct sk_buff *sctp_event2skb(struct sctp_ulpevent *ev) | ||
70 | { | ||
71 | return container_of((void *)ev, struct sk_buff, cb); | ||
72 | } | ||
73 | |||
74 | /* Retrieve & cast the event sitting inside the skb. */ | ||
75 | static inline struct sctp_ulpevent *sctp_skb2event(struct sk_buff *skb) | ||
76 | { | ||
77 | return (struct sctp_ulpevent *)skb->cb; | ||
78 | } | ||
79 | |||
80 | void sctp_ulpevent_free(struct sctp_ulpevent *); | ||
81 | int sctp_ulpevent_is_notification(const struct sctp_ulpevent *); | ||
82 | void sctp_queue_purge_ulpevents(struct sk_buff_head *list); | ||
83 | |||
84 | struct sctp_ulpevent *sctp_ulpevent_make_assoc_change( | ||
85 | const struct sctp_association *asoc, | ||
86 | __u16 flags, | ||
87 | __u16 state, | ||
88 | __u16 error, | ||
89 | __u16 outbound, | ||
90 | __u16 inbound, | ||
91 | int gfp); | ||
92 | |||
93 | struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change( | ||
94 | const struct sctp_association *asoc, | ||
95 | const struct sockaddr_storage *aaddr, | ||
96 | int flags, | ||
97 | int state, | ||
98 | int error, | ||
99 | int gfp); | ||
100 | |||
101 | struct sctp_ulpevent *sctp_ulpevent_make_remote_error( | ||
102 | const struct sctp_association *asoc, | ||
103 | struct sctp_chunk *chunk, | ||
104 | __u16 flags, | ||
105 | int gfp); | ||
106 | struct sctp_ulpevent *sctp_ulpevent_make_send_failed( | ||
107 | const struct sctp_association *asoc, | ||
108 | struct sctp_chunk *chunk, | ||
109 | __u16 flags, | ||
110 | __u32 error, | ||
111 | int gfp); | ||
112 | |||
113 | struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event( | ||
114 | const struct sctp_association *asoc, | ||
115 | __u16 flags, | ||
116 | int gfp); | ||
117 | |||
118 | struct sctp_ulpevent *sctp_ulpevent_make_pdapi( | ||
119 | const struct sctp_association *asoc, | ||
120 | __u32 indication, int gfp); | ||
121 | |||
122 | struct sctp_ulpevent *sctp_ulpevent_make_adaption_indication( | ||
123 | const struct sctp_association *asoc, int gfp); | ||
124 | |||
125 | struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, | ||
126 | struct sctp_chunk *chunk, | ||
127 | int gfp); | ||
128 | |||
129 | void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, | ||
130 | struct msghdr *); | ||
131 | __u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event); | ||
132 | |||
133 | /* Is this event type enabled? */ | ||
134 | static inline int sctp_ulpevent_type_enabled(__u16 sn_type, | ||
135 | struct sctp_event_subscribe *mask) | ||
136 | { | ||
137 | char *amask = (char *) mask; | ||
138 | return amask[sn_type - SCTP_SN_TYPE_BASE]; | ||
139 | } | ||
140 | |||
141 | /* Given an event subscription, is this event enabled? */ | ||
142 | static inline int sctp_ulpevent_is_enabled(const struct sctp_ulpevent *event, | ||
143 | struct sctp_event_subscribe *mask) | ||
144 | { | ||
145 | __u16 sn_type; | ||
146 | int enabled = 1; | ||
147 | |||
148 | if (sctp_ulpevent_is_notification(event)) { | ||
149 | sn_type = sctp_ulpevent_get_notification_type(event); | ||
150 | enabled = sctp_ulpevent_type_enabled(sn_type, mask); | ||
151 | } | ||
152 | return enabled; | ||
153 | } | ||
154 | |||
155 | #endif /* __sctp_ulpevent_h__ */ | ||
156 | |||
157 | |||
158 | |||
159 | |||
160 | |||
161 | |||
162 | |||
diff --git a/include/net/sctp/ulpqueue.h b/include/net/sctp/ulpqueue.h new file mode 100644 index 000000000000..961736d29d21 --- /dev/null +++ b/include/net/sctp/ulpqueue.h | |||
@@ -0,0 +1,92 @@ | |||
1 | /* SCTP kernel reference Implementation | ||
2 | * (C) Copyright IBM Corp. 2001, 2004 | ||
3 | * Copyright (c) 1999-2000 Cisco, Inc. | ||
4 | * Copyright (c) 1999-2001 Motorola, Inc. | ||
5 | * Copyright (c) 2001 Intel Corp. | ||
6 | * Copyright (c) 2001 Nokia, Inc. | ||
7 | * Copyright (c) 2001 La Monte H.P. Yarroll | ||
8 | * | ||
9 | * These are the definitions needed for the sctp_ulpq type. The | ||
10 | * sctp_ulpq is the interface between the Upper Layer Protocol, or ULP, | ||
11 | * and the core SCTP state machine. This is the component which handles | ||
12 | * reassembly and ordering. | ||
13 | * | ||
14 | * The SCTP reference implementation is free software; | ||
15 | * you can redistribute it and/or modify it under the terms of | ||
16 | * the GNU General Public License as published by | ||
17 | * the Free Software Foundation; either version 2, or (at your option) | ||
18 | * any later version. | ||
19 | * | ||
20 | * the SCTP reference implementation is distributed in the hope that it | ||
21 | * will be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
22 | * ************************ | ||
23 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
24 | * See the GNU General Public License for more details. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License | ||
27 | * along with GNU CC; see the file COPYING. If not, write to | ||
28 | * the Free Software Foundation, 59 Temple Place - Suite 330, | ||
29 | * Boston, MA 02111-1307, USA. | ||
30 | * | ||
31 | * Please send any bug reports or fixes you make to the | ||
32 | * email addresses: | ||
33 | * lksctp developers <lksctp-developers@lists.sourceforge.net> | ||
34 | * | ||
35 | * Or submit a bug report through the following website: | ||
36 | * http://www.sf.net/projects/lksctp | ||
37 | * | ||
38 | * Written or modified by: | ||
39 | * Jon Grimm <jgrimm@us.ibm.com> | ||
40 | * La Monte H.P. Yarroll <piggy@acm.org> | ||
41 | * Sridhar Samudrala <sri@us.ibm.com> | ||
42 | * | ||
43 | * Any bugs reported given to us we will try to fix... any fixes shared will | ||
44 | * be incorporated into the next SCTP release. | ||
45 | */ | ||
46 | |||
47 | #ifndef __sctp_ulpqueue_h__ | ||
48 | #define __sctp_ulpqueue_h__ | ||
49 | |||
50 | /* A structure to carry information to the ULP (e.g. Sockets API) */ | ||
51 | struct sctp_ulpq { | ||
52 | char malloced; | ||
53 | char pd_mode; | ||
54 | struct sctp_association *asoc; | ||
55 | struct sk_buff_head reasm; | ||
56 | struct sk_buff_head lobby; | ||
57 | }; | ||
58 | |||
59 | /* Prototypes. */ | ||
60 | struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *, | ||
61 | struct sctp_association *); | ||
62 | void sctp_ulpq_free(struct sctp_ulpq *); | ||
63 | |||
64 | /* Add a new DATA chunk for processing. */ | ||
65 | int sctp_ulpq_tail_data(struct sctp_ulpq *, struct sctp_chunk *, int); | ||
66 | |||
67 | /* Add a new event for propagation to the ULP. */ | ||
68 | int sctp_ulpq_tail_event(struct sctp_ulpq *, struct sctp_ulpevent *ev); | ||
69 | |||
70 | /* Renege previously received chunks. */ | ||
71 | void sctp_ulpq_renege(struct sctp_ulpq *, struct sctp_chunk *, int); | ||
72 | |||
73 | /* Perform partial delivery. */ | ||
74 | void sctp_ulpq_partial_delivery(struct sctp_ulpq *, struct sctp_chunk *, int); | ||
75 | |||
76 | /* Abort the partial delivery. */ | ||
77 | void sctp_ulpq_abort_pd(struct sctp_ulpq *, int); | ||
78 | |||
79 | /* Clear the partial data delivery condition on this socket. */ | ||
80 | int sctp_clear_pd(struct sock *sk); | ||
81 | |||
82 | /* Skip over an SSN. */ | ||
83 | void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn); | ||
84 | |||
85 | #endif /* __sctp_ulpqueue_h__ */ | ||
86 | |||
87 | |||
88 | |||
89 | |||
90 | |||
91 | |||
92 | |||
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h new file mode 100644 index 000000000000..2758e8ce4f25 --- /dev/null +++ b/include/net/sctp/user.h | |||
@@ -0,0 +1,589 @@ | |||
1 | /* SCTP kernel reference Implementation | ||
2 | * (C) Copyright IBM Corp. 2001, 2004 | ||
3 | * Copyright (c) 1999-2000 Cisco, Inc. | ||
4 | * Copyright (c) 1999-2001 Motorola, Inc. | ||
5 | * Copyright (c) 2002 Intel Corp. | ||
6 | * | ||
7 | * This file is part of the SCTP kernel reference Implementation | ||
8 | * | ||
9 | * This header represents the structures and constants needed to support | ||
10 | * the SCTP Extension to the Sockets API. | ||
11 | * | ||
12 | * The SCTP reference implementation is free software; | ||
13 | * you can redistribute it and/or modify it under the terms of | ||
14 | * the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2, or (at your option) | ||
16 | * any later version. | ||
17 | * | ||
18 | * The SCTP reference implementation is distributed in the hope that it | ||
19 | * will be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
20 | * ************************ | ||
21 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
22 | * See the GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with GNU CC; see the file COPYING. If not, write to | ||
26 | * the Free Software Foundation, 59 Temple Place - Suite 330, | ||
27 | * Boston, MA 02111-1307, USA. | ||
28 | * | ||
29 | * Please send any bug reports or fixes you make to the | ||
30 | * email address(es): | ||
31 | * lksctp developers <lksctp-developers@lists.sourceforge.net> | ||
32 | * | ||
33 | * Or submit a bug report through the following website: | ||
34 | * http://www.sf.net/projects/lksctp | ||
35 | * | ||
36 | * Written or modified by: | ||
37 | * La Monte H.P. Yarroll <piggy@acm.org> | ||
38 | * R. Stewart <randall@sctp.chicago.il.us> | ||
39 | * K. Morneau <kmorneau@cisco.com> | ||
40 | * Q. Xie <qxie1@email.mot.com> | ||
41 | * Karl Knutson <karl@athena.chicago.il.us> | ||
42 | * Jon Grimm <jgrimm@us.ibm.com> | ||
43 | * Daisy Chang <daisyc@us.ibm.com> | ||
44 | * Ryan Layer <rmlayer@us.ibm.com> | ||
45 | * Ardelle Fan <ardelle.fan@intel.com> | ||
46 | * Sridhar Samudrala <sri@us.ibm.com> | ||
47 | * | ||
48 | * Any bugs reported given to us we will try to fix... any fixes shared will | ||
49 | * be incorporated into the next SCTP release. | ||
50 | */ | ||
51 | |||
52 | #ifndef __net_sctp_user_h__ | ||
53 | #define __net_sctp_user_h__ | ||
54 | |||
55 | #include <linux/types.h> | ||
56 | #include <linux/socket.h> | ||
57 | |||
58 | typedef __s32 sctp_assoc_t; | ||
59 | |||
60 | /* The following symbols come from the Sockets API Extensions for | ||
61 | * SCTP <draft-ietf-tsvwg-sctpsocket-07.txt>. | ||
62 | */ | ||
63 | enum sctp_optname { | ||
64 | SCTP_RTOINFO, | ||
65 | #define SCTP_RTOINFO SCTP_RTOINFO | ||
66 | SCTP_ASSOCINFO, | ||
67 | #define SCTP_ASSOCINFO SCTP_ASSOCINFO | ||
68 | SCTP_INITMSG, | ||
69 | #define SCTP_INITMSG SCTP_INITMSG | ||
70 | SCTP_NODELAY, /* Get/set nodelay option. */ | ||
71 | #define SCTP_NODELAY SCTP_NODELAY | ||
72 | SCTP_AUTOCLOSE, | ||
73 | #define SCTP_AUTOCLOSE SCTP_AUTOCLOSE | ||
74 | SCTP_SET_PEER_PRIMARY_ADDR, | ||
75 | #define SCTP_SET_PEER_PRIMARY_ADDR SCTP_SET_PEER_PRIMARY_ADDR | ||
76 | SCTP_PRIMARY_ADDR, | ||
77 | #define SCTP_PRIMARY_ADDR SCTP_PRIMARY_ADDR | ||
78 | SCTP_ADAPTION_LAYER, | ||
79 | #define SCTP_ADAPTION_LAYER SCTP_ADAPTION_LAYER | ||
80 | SCTP_DISABLE_FRAGMENTS, | ||
81 | #define SCTP_DISABLE_FRAGMENTS SCTP_DISABLE_FRAGMENTS | ||
82 | SCTP_PEER_ADDR_PARAMS, | ||
83 | #define SCTP_PEER_ADDR_PARAMS SCTP_PEER_ADDR_PARAMS | ||
84 | SCTP_DEFAULT_SEND_PARAM, | ||
85 | #define SCTP_DEFAULT_SEND_PARAM SCTP_DEFAULT_SEND_PARAM | ||
86 | SCTP_EVENTS, | ||
87 | #define SCTP_EVENTS SCTP_EVENTS | ||
88 | SCTP_I_WANT_MAPPED_V4_ADDR, /* Turn on/off mapped v4 addresses */ | ||
89 | #define SCTP_I_WANT_MAPPED_V4_ADDR SCTP_I_WANT_MAPPED_V4_ADDR | ||
90 | SCTP_MAXSEG, /* Get/set maximum fragment. */ | ||
91 | #define SCTP_MAXSEG SCTP_MAXSEG | ||
92 | SCTP_STATUS, | ||
93 | #define SCTP_STATUS SCTP_STATUS | ||
94 | SCTP_GET_PEER_ADDR_INFO, | ||
95 | #define SCTP_GET_PEER_ADDR_INFO SCTP_GET_PEER_ADDR_INFO | ||
96 | |||
97 | /* Internal Socket Options. Some of the sctp library functions are | ||
98 | * implemented using these socket options. | ||
99 | */ | ||
100 | SCTP_SOCKOPT_BINDX_ADD = 100,/* BINDX requests for adding addresses. */ | ||
101 | #define SCTP_SOCKOPT_BINDX_ADD SCTP_SOCKOPT_BINDX_ADD | ||
102 | SCTP_SOCKOPT_BINDX_REM, /* BINDX requests for removing addresses. */ | ||
103 | #define SCTP_SOCKOPT_BINDX_REM SCTP_SOCKOPT_BINDX_REM | ||
104 | SCTP_SOCKOPT_PEELOFF, /* peel off association. */ | ||
105 | #define SCTP_SOCKOPT_PEELOFF SCTP_SOCKOPT_PEELOFF | ||
106 | SCTP_GET_PEER_ADDRS_NUM, /* Get number of peer addresss. */ | ||
107 | #define SCTP_GET_PEER_ADDRS_NUM SCTP_GET_PEER_ADDRS_NUM | ||
108 | SCTP_GET_PEER_ADDRS, /* Get all peer addresss. */ | ||
109 | #define SCTP_GET_PEER_ADDRS SCTP_GET_PEER_ADDRS | ||
110 | SCTP_GET_LOCAL_ADDRS_NUM, /* Get number of local addresss. */ | ||
111 | #define SCTP_GET_LOCAL_ADDRS_NUM SCTP_GET_LOCAL_ADDRS_NUM | ||
112 | SCTP_GET_LOCAL_ADDRS, /* Get all local addresss. */ | ||
113 | #define SCTP_GET_LOCAL_ADDRS SCTP_GET_LOCAL_ADDRS | ||
114 | }; | ||
115 | |||
116 | /* | ||
117 | * 5.2.1 SCTP Initiation Structure (SCTP_INIT) | ||
118 | * | ||
119 | * This cmsghdr structure provides information for initializing new | ||
120 | * SCTP associations with sendmsg(). The SCTP_INITMSG socket option | ||
121 | * uses this same data structure. This structure is not used for | ||
122 | * recvmsg(). | ||
123 | * | ||
124 | * cmsg_level cmsg_type cmsg_data[] | ||
125 | * ------------ ------------ ---------------------- | ||
126 | * IPPROTO_SCTP SCTP_INIT struct sctp_initmsg | ||
127 | * | ||
128 | */ | ||
129 | struct sctp_initmsg { | ||
130 | __u16 sinit_num_ostreams; | ||
131 | __u16 sinit_max_instreams; | ||
132 | __u16 sinit_max_attempts; | ||
133 | __u16 sinit_max_init_timeo; | ||
134 | }; | ||
135 | |||
136 | /* | ||
137 | * 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV) | ||
138 | * | ||
139 | * This cmsghdr structure specifies SCTP options for sendmsg() and | ||
140 | * describes SCTP header information about a received message through | ||
141 | * recvmsg(). | ||
142 | * | ||
143 | * cmsg_level cmsg_type cmsg_data[] | ||
144 | * ------------ ------------ ---------------------- | ||
145 | * IPPROTO_SCTP SCTP_SNDRCV struct sctp_sndrcvinfo | ||
146 | * | ||
147 | */ | ||
148 | struct sctp_sndrcvinfo { | ||
149 | __u16 sinfo_stream; | ||
150 | __u16 sinfo_ssn; | ||
151 | __u16 sinfo_flags; | ||
152 | __u32 sinfo_ppid; | ||
153 | __u32 sinfo_context; | ||
154 | __u32 sinfo_timetolive; | ||
155 | __u32 sinfo_tsn; | ||
156 | __u32 sinfo_cumtsn; | ||
157 | sctp_assoc_t sinfo_assoc_id; | ||
158 | }; | ||
159 | |||
160 | /* | ||
161 | * sinfo_flags: 16 bits (unsigned integer) | ||
162 | * | ||
163 | * This field may contain any of the following flags and is composed of | ||
164 | * a bitwise OR of these values. | ||
165 | */ | ||
166 | |||
167 | enum sctp_sinfo_flags { | ||
168 | MSG_UNORDERED = 1, /* Send/receive message unordered. */ | ||
169 | MSG_ADDR_OVER = 2, /* Override the primary destination. */ | ||
170 | MSG_ABORT=4, /* Send an ABORT message to the peer. */ | ||
171 | /* MSG_EOF is already defined per socket.h */ | ||
172 | }; | ||
173 | |||
174 | |||
175 | typedef union { | ||
176 | __u8 raw; | ||
177 | struct sctp_initmsg init; | ||
178 | struct sctp_sndrcvinfo sndrcv; | ||
179 | } sctp_cmsg_data_t; | ||
180 | |||
181 | /* These are cmsg_types. */ | ||
182 | typedef enum sctp_cmsg_type { | ||
183 | SCTP_INIT, /* 5.2.1 SCTP Initiation Structure */ | ||
184 | SCTP_SNDRCV, /* 5.2.2 SCTP Header Information Structure */ | ||
185 | } sctp_cmsg_t; | ||
186 | |||
187 | |||
188 | /* | ||
189 | * 5.3.1.1 SCTP_ASSOC_CHANGE | ||
190 | * | ||
191 | * Communication notifications inform the ULP that an SCTP association | ||
192 | * has either begun or ended. The identifier for a new association is | ||
193 | * provided by this notificaion. The notification information has the | ||
194 | * following format: | ||
195 | * | ||
196 | */ | ||
197 | struct sctp_assoc_change { | ||
198 | __u16 sac_type; | ||
199 | __u16 sac_flags; | ||
200 | __u32 sac_length; | ||
201 | __u16 sac_state; | ||
202 | __u16 sac_error; | ||
203 | __u16 sac_outbound_streams; | ||
204 | __u16 sac_inbound_streams; | ||
205 | sctp_assoc_t sac_assoc_id; | ||
206 | }; | ||
207 | |||
208 | /* | ||
209 | * sac_state: 32 bits (signed integer) | ||
210 | * | ||
211 | * This field holds one of a number of values that communicate the | ||
212 | * event that happened to the association. They include: | ||
213 | * | ||
214 | * Note: The following state names deviate from the API draft as | ||
215 | * the names clash too easily with other kernel symbols. | ||
216 | */ | ||
217 | enum sctp_sac_state { | ||
218 | SCTP_COMM_UP, | ||
219 | SCTP_COMM_LOST, | ||
220 | SCTP_RESTART, | ||
221 | SCTP_SHUTDOWN_COMP, | ||
222 | SCTP_CANT_STR_ASSOC, | ||
223 | }; | ||
224 | |||
225 | /* | ||
226 | * 5.3.1.2 SCTP_PEER_ADDR_CHANGE | ||
227 | * | ||
228 | * When a destination address on a multi-homed peer encounters a change | ||
229 | * an interface details event is sent. The information has the | ||
230 | * following structure: | ||
231 | */ | ||
232 | struct sctp_paddr_change { | ||
233 | __u16 spc_type; | ||
234 | __u16 spc_flags; | ||
235 | __u32 spc_length; | ||
236 | struct sockaddr_storage spc_aaddr; | ||
237 | int spc_state; | ||
238 | int spc_error; | ||
239 | sctp_assoc_t spc_assoc_id; | ||
240 | }; | ||
241 | |||
242 | /* | ||
243 | * spc_state: 32 bits (signed integer) | ||
244 | * | ||
245 | * This field holds one of a number of values that communicate the | ||
246 | * event that happened to the address. They include: | ||
247 | */ | ||
248 | enum sctp_spc_state { | ||
249 | SCTP_ADDR_AVAILABLE, | ||
250 | SCTP_ADDR_UNREACHABLE, | ||
251 | SCTP_ADDR_REMOVED, | ||
252 | SCTP_ADDR_ADDED, | ||
253 | SCTP_ADDR_MADE_PRIM, | ||
254 | }; | ||
255 | |||
256 | |||
257 | /* | ||
258 | * 5.3.1.3 SCTP_REMOTE_ERROR | ||
259 | * | ||
260 | * A remote peer may send an Operational Error message to its peer. | ||
261 | * This message indicates a variety of error conditions on an | ||
262 | * association. The entire error TLV as it appears on the wire is | ||
263 | * included in a SCTP_REMOTE_ERROR event. Please refer to the SCTP | ||
264 | * specification [SCTP] and any extensions for a list of possible | ||
265 | * error formats. SCTP error TLVs have the format: | ||
266 | */ | ||
267 | struct sctp_remote_error { | ||
268 | __u16 sre_type; | ||
269 | __u16 sre_flags; | ||
270 | __u32 sre_length; | ||
271 | __u16 sre_error; | ||
272 | sctp_assoc_t sre_assoc_id; | ||
273 | __u8 sre_data[0]; | ||
274 | }; | ||
275 | |||
276 | |||
277 | /* | ||
278 | * 5.3.1.4 SCTP_SEND_FAILED | ||
279 | * | ||
280 | * If SCTP cannot deliver a message it may return the message as a | ||
281 | * notification. | ||
282 | */ | ||
283 | struct sctp_send_failed { | ||
284 | __u16 ssf_type; | ||
285 | __u16 ssf_flags; | ||
286 | __u32 ssf_length; | ||
287 | __u32 ssf_error; | ||
288 | struct sctp_sndrcvinfo ssf_info; | ||
289 | sctp_assoc_t ssf_assoc_id; | ||
290 | __u8 ssf_data[0]; | ||
291 | }; | ||
292 | |||
293 | /* | ||
294 | * ssf_flags: 16 bits (unsigned integer) | ||
295 | * | ||
296 | * The flag value will take one of the following values | ||
297 | * | ||
298 | * SCTP_DATA_UNSENT - Indicates that the data was never put on | ||
299 | * the wire. | ||
300 | * | ||
301 | * SCTP_DATA_SENT - Indicates that the data was put on the wire. | ||
302 | * Note that this does not necessarily mean that the | ||
303 | * data was (or was not) successfully delivered. | ||
304 | */ | ||
305 | enum sctp_ssf_flags { | ||
306 | SCTP_DATA_UNSENT, | ||
307 | SCTP_DATA_SENT, | ||
308 | }; | ||
309 | |||
310 | /* | ||
311 | * 5.3.1.5 SCTP_SHUTDOWN_EVENT | ||
312 | * | ||
313 | * When a peer sends a SHUTDOWN, SCTP delivers this notification to | ||
314 | * inform the application that it should cease sending data. | ||
315 | */ | ||
316 | struct sctp_shutdown_event { | ||
317 | __u16 sse_type; | ||
318 | __u16 sse_flags; | ||
319 | __u32 sse_length; | ||
320 | sctp_assoc_t sse_assoc_id; | ||
321 | }; | ||
322 | |||
323 | /* | ||
324 | * 5.3.1.6 SCTP_ADAPTION_INDICATION | ||
325 | * | ||
326 | * When a peer sends a Adaption Layer Indication parameter , SCTP | ||
327 | * delivers this notification to inform the application | ||
328 | * that of the peers requested adaption layer. | ||
329 | */ | ||
330 | struct sctp_adaption_event { | ||
331 | __u16 sai_type; | ||
332 | __u16 sai_flags; | ||
333 | __u32 sai_length; | ||
334 | __u32 sai_adaption_ind; | ||
335 | sctp_assoc_t sai_assoc_id; | ||
336 | }; | ||
337 | |||
338 | /* | ||
339 | * 5.3.1.7 SCTP_PARTIAL_DELIVERY_EVENT | ||
340 | * | ||
341 | * When a receiver is engaged in a partial delivery of a | ||
342 | * message this notification will be used to indicate | ||
343 | * various events. | ||
344 | */ | ||
345 | struct sctp_pdapi_event { | ||
346 | __u16 pdapi_type; | ||
347 | __u16 pdapi_flags; | ||
348 | __u32 pdapi_length; | ||
349 | __u32 pdapi_indication; | ||
350 | sctp_assoc_t pdapi_assoc_id; | ||
351 | }; | ||
352 | |||
353 | enum { SCTP_PARTIAL_DELIVERY_ABORTED=0, }; | ||
354 | |||
355 | /* | ||
356 | * Described in Section 7.3 | ||
357 | * Ancillary Data and Notification Interest Options | ||
358 | */ | ||
359 | struct sctp_event_subscribe { | ||
360 | __u8 sctp_data_io_event; | ||
361 | __u8 sctp_association_event; | ||
362 | __u8 sctp_address_event; | ||
363 | __u8 sctp_send_failure_event; | ||
364 | __u8 sctp_peer_error_event; | ||
365 | __u8 sctp_shutdown_event; | ||
366 | __u8 sctp_partial_delivery_event; | ||
367 | __u8 sctp_adaption_layer_event; | ||
368 | }; | ||
369 | |||
370 | /* | ||
371 | * 5.3.1 SCTP Notification Structure | ||
372 | * | ||
373 | * The notification structure is defined as the union of all | ||
374 | * notification types. | ||
375 | * | ||
376 | */ | ||
377 | union sctp_notification { | ||
378 | struct { | ||
379 | __u16 sn_type; /* Notification type. */ | ||
380 | __u16 sn_flags; | ||
381 | __u32 sn_length; | ||
382 | } sn_header; | ||
383 | struct sctp_assoc_change sn_assoc_change; | ||
384 | struct sctp_paddr_change sn_paddr_change; | ||
385 | struct sctp_remote_error sn_remote_error; | ||
386 | struct sctp_send_failed sn_send_failed; | ||
387 | struct sctp_shutdown_event sn_shutdown_event; | ||
388 | struct sctp_adaption_event sn_adaption_event; | ||
389 | struct sctp_pdapi_event sn_pdapi_event; | ||
390 | }; | ||
391 | |||
392 | /* Section 5.3.1 | ||
393 | * All standard values for sn_type flags are greater than 2^15. | ||
394 | * Values from 2^15 and down are reserved. | ||
395 | */ | ||
396 | |||
397 | enum sctp_sn_type { | ||
398 | SCTP_SN_TYPE_BASE = (1<<15), | ||
399 | SCTP_ASSOC_CHANGE, | ||
400 | SCTP_PEER_ADDR_CHANGE, | ||
401 | SCTP_SEND_FAILED, | ||
402 | SCTP_REMOTE_ERROR, | ||
403 | SCTP_SHUTDOWN_EVENT, | ||
404 | SCTP_PARTIAL_DELIVERY_EVENT, | ||
405 | SCTP_ADAPTION_INDICATION, | ||
406 | }; | ||
407 | |||
408 | /* Notification error codes used to fill up the error fields in some | ||
409 | * notifications. | ||
410 | * SCTP_PEER_ADDRESS_CHAGE : spc_error | ||
411 | * SCTP_ASSOC_CHANGE : sac_error | ||
412 | * These names should be potentially included in the draft 04 of the SCTP | ||
413 | * sockets API specification. | ||
414 | */ | ||
415 | typedef enum sctp_sn_error { | ||
416 | SCTP_FAILED_THRESHOLD, | ||
417 | SCTP_RECEIVED_SACK, | ||
418 | SCTP_HEARTBEAT_SUCCESS, | ||
419 | SCTP_RESPONSE_TO_USER_REQ, | ||
420 | SCTP_INTERNAL_ERROR, | ||
421 | SCTP_SHUTDOWN_GUARD_EXPIRES, | ||
422 | SCTP_PEER_FAULTY, | ||
423 | } sctp_sn_error_t; | ||
424 | |||
425 | /* | ||
426 | * 7.1.1 Retransmission Timeout Parameters (SCTP_RTOINFO) | ||
427 | * | ||
428 | * The protocol parameters used to initialize and bound retransmission | ||
429 | * timeout (RTO) are tunable. See [SCTP] for more information on how | ||
430 | * these parameters are used in RTO calculation. | ||
431 | */ | ||
432 | struct sctp_rtoinfo { | ||
433 | sctp_assoc_t srto_assoc_id; | ||
434 | __u32 srto_initial; | ||
435 | __u32 srto_max; | ||
436 | __u32 srto_min; | ||
437 | }; | ||
438 | |||
439 | /* | ||
440 | * 7.1.2 Association Parameters (SCTP_ASSOCINFO) | ||
441 | * | ||
442 | * This option is used to both examine and set various association and | ||
443 | * endpoint parameters. | ||
444 | */ | ||
445 | struct sctp_assocparams { | ||
446 | sctp_assoc_t sasoc_assoc_id; | ||
447 | __u16 sasoc_asocmaxrxt; | ||
448 | __u16 sasoc_number_peer_destinations; | ||
449 | __u32 sasoc_peer_rwnd; | ||
450 | __u32 sasoc_local_rwnd; | ||
451 | __u32 sasoc_cookie_life; | ||
452 | }; | ||
453 | |||
454 | /* | ||
455 | * 7.1.9 Set Peer Primary Address (SCTP_SET_PEER_PRIMARY_ADDR) | ||
456 | * | ||
457 | * Requests that the peer mark the enclosed address as the association | ||
458 | * primary. The enclosed address must be one of the association's | ||
459 | * locally bound addresses. The following structure is used to make a | ||
460 | * set primary request: | ||
461 | */ | ||
462 | struct sctp_setpeerprim { | ||
463 | sctp_assoc_t sspp_assoc_id; | ||
464 | struct sockaddr_storage sspp_addr; | ||
465 | }; | ||
466 | |||
467 | /* | ||
468 | * 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR) | ||
469 | * | ||
470 | * Requests that the local SCTP stack use the enclosed peer address as | ||
471 | * the association primary. The enclosed address must be one of the | ||
472 | * association peer's addresses. The following structure is used to | ||
473 | * make a set peer primary request: | ||
474 | */ | ||
475 | struct sctp_prim { | ||
476 | sctp_assoc_t ssp_assoc_id; | ||
477 | struct sockaddr_storage ssp_addr; | ||
478 | }; | ||
479 | |||
480 | /* | ||
481 | * 7.1.11 Set Adaption Layer Indicator (SCTP_ADAPTION_LAYER) | ||
482 | * | ||
483 | * Requests that the local endpoint set the specified Adaption Layer | ||
484 | * Indication parameter for all future INIT and INIT-ACK exchanges. | ||
485 | */ | ||
486 | struct sctp_setadaption { | ||
487 | __u32 ssb_adaption_ind; | ||
488 | }; | ||
489 | |||
490 | /* | ||
491 | * 7.1.13 Peer Address Parameters (SCTP_PEER_ADDR_PARAMS) | ||
492 | * | ||
493 | * Applications can enable or disable heartbeats for any peer address | ||
494 | * of an association, modify an address's heartbeat interval, force a | ||
495 | * heartbeat to be sent immediately, and adjust the address's maximum | ||
496 | * number of retransmissions sent before an address is considered | ||
497 | * unreachable. The following structure is used to access and modify an | ||
498 | * address's parameters: | ||
499 | */ | ||
500 | struct sctp_paddrparams { | ||
501 | sctp_assoc_t spp_assoc_id; | ||
502 | struct sockaddr_storage spp_address; | ||
503 | __u32 spp_hbinterval; | ||
504 | __u16 spp_pathmaxrxt; | ||
505 | }; | ||
506 | |||
507 | /* | ||
508 | * 7.2.2 Peer Address Information | ||
509 | * | ||
510 | * Applications can retrieve information about a specific peer address | ||
511 | * of an association, including its reachability state, congestion | ||
512 | * window, and retransmission timer values. This information is | ||
513 | * read-only. The following structure is used to access this | ||
514 | * information: | ||
515 | */ | ||
516 | struct sctp_paddrinfo { | ||
517 | sctp_assoc_t spinfo_assoc_id; | ||
518 | struct sockaddr_storage spinfo_address; | ||
519 | __s32 spinfo_state; | ||
520 | __u32 spinfo_cwnd; | ||
521 | __u32 spinfo_srtt; | ||
522 | __u32 spinfo_rto; | ||
523 | __u32 spinfo_mtu; | ||
524 | }; | ||
525 | |||
526 | /* Peer addresses's state. */ | ||
527 | enum sctp_spinfo_state { | ||
528 | SCTP_INACTIVE, | ||
529 | SCTP_ACTIVE, | ||
530 | }; | ||
531 | |||
532 | /* | ||
533 | * 7.2.1 Association Status (SCTP_STATUS) | ||
534 | * | ||
535 | * Applications can retrieve current status information about an | ||
536 | * association, including association state, peer receiver window size, | ||
537 | * number of unacked data chunks, and number of data chunks pending | ||
538 | * receipt. This information is read-only. The following structure is | ||
539 | * used to access this information: | ||
540 | */ | ||
541 | struct sctp_status { | ||
542 | sctp_assoc_t sstat_assoc_id; | ||
543 | __s32 sstat_state; | ||
544 | __u32 sstat_rwnd; | ||
545 | __u16 sstat_unackdata; | ||
546 | __u16 sstat_penddata; | ||
547 | __u16 sstat_instrms; | ||
548 | __u16 sstat_outstrms; | ||
549 | __u32 sstat_fragmentation_point; | ||
550 | struct sctp_paddrinfo sstat_primary; | ||
551 | }; | ||
552 | |||
553 | /* | ||
554 | * 8.3, 8.5 get all peer/local addresses in an association. | ||
555 | * This parameter struct is used by SCTP_GET_PEER_ADDRS and | ||
556 | * SCTP_GET_LOCAL_ADDRS socket options used internally to implement | ||
557 | * sctp_getpaddrs() and sctp_getladdrs() API. | ||
558 | */ | ||
559 | struct sctp_getaddrs { | ||
560 | sctp_assoc_t assoc_id; | ||
561 | int addr_num; | ||
562 | struct sockaddr __user *addrs; | ||
563 | }; | ||
564 | |||
565 | /* These are bit fields for msghdr->msg_flags. See section 5.1. */ | ||
566 | /* On user space Linux, these live in <bits/socket.h> as an enum. */ | ||
567 | enum sctp_msg_flags { | ||
568 | MSG_NOTIFICATION = 0x8000, | ||
569 | #define MSG_NOTIFICATION MSG_NOTIFICATION | ||
570 | }; | ||
571 | |||
572 | /* | ||
573 | * 8.1 sctp_bindx() | ||
574 | * | ||
575 | * The flags parameter is formed from the bitwise OR of zero or more of the | ||
576 | * following currently defined flags: | ||
577 | */ | ||
578 | #define SCTP_BINDX_ADD_ADDR 0x01 | ||
579 | #define SCTP_BINDX_REM_ADDR 0x02 | ||
580 | |||
581 | /* This is the structure that is passed as an argument(optval) to | ||
582 | * getsockopt(SCTP_SOCKOPT_PEELOFF). | ||
583 | */ | ||
584 | typedef struct { | ||
585 | sctp_assoc_t associd; | ||
586 | int sd; | ||
587 | } sctp_peeloff_arg_t; | ||
588 | |||
589 | #endif /* __net_sctp_user_h__ */ | ||
diff --git a/include/net/slhc_vj.h b/include/net/slhc_vj.h new file mode 100644 index 000000000000..0b2c2784f333 --- /dev/null +++ b/include/net/slhc_vj.h | |||
@@ -0,0 +1,188 @@ | |||
1 | #ifndef _SLHC_H | ||
2 | #define _SLHC_H | ||
3 | /* | ||
4 | * Definitions for tcp compression routines. | ||
5 | * | ||
6 | * $Header: slcompress.h,v 1.10 89/12/31 08:53:02 van Exp $ | ||
7 | * | ||
8 | * Copyright (c) 1989 Regents of the University of California. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms are permitted | ||
12 | * provided that the above copyright notice and this paragraph are | ||
13 | * duplicated in all such forms and that any documentation, | ||
14 | * advertising materials, and other materials related to such | ||
15 | * distribution and use acknowledge that the software was developed | ||
16 | * by the University of California, Berkeley. The name of the | ||
17 | * University may not be used to endorse or promote products derived | ||
18 | * from this software without specific prior written permission. | ||
19 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
20 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
22 | * | ||
23 | * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: | ||
24 | * - Initial distribution. | ||
25 | * | ||
26 | * | ||
27 | * modified for KA9Q Internet Software Package by | ||
28 | * Katie Stevens (dkstevens@ucdavis.edu) | ||
29 | * University of California, Davis | ||
30 | * Computing Services | ||
31 | * - 01-31-90 initial adaptation | ||
32 | * | ||
33 | * - Feb 1991 Bill_Simpson@um.cc.umich.edu | ||
34 | * variable number of conversation slots | ||
35 | * allow zero or one slots | ||
36 | * separate routines | ||
37 | * status display | ||
38 | */ | ||
39 | |||
40 | /* | ||
41 | * Compressed packet format: | ||
42 | * | ||
43 | * The first octet contains the packet type (top 3 bits), TCP | ||
44 | * 'push' bit, and flags that indicate which of the 4 TCP sequence | ||
45 | * numbers have changed (bottom 5 bits). The next octet is a | ||
46 | * conversation number that associates a saved IP/TCP header with | ||
47 | * the compressed packet. The next two octets are the TCP checksum | ||
48 | * from the original datagram. The next 0 to 15 octets are | ||
49 | * sequence number changes, one change per bit set in the header | ||
50 | * (there may be no changes and there are two special cases where | ||
51 | * the receiver implicitly knows what changed -- see below). | ||
52 | * | ||
53 | * There are 5 numbers which can change (they are always inserted | ||
54 | * in the following order): TCP urgent pointer, window, | ||
55 | * acknowledgment, sequence number and IP ID. (The urgent pointer | ||
56 | * is different from the others in that its value is sent, not the | ||
57 | * change in value.) Since typical use of SLIP links is biased | ||
58 | * toward small packets (see comments on MTU/MSS below), changes | ||
59 | * use a variable length coding with one octet for numbers in the | ||
60 | * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the | ||
61 | * range 256 - 65535 or 0. (If the change in sequence number or | ||
62 | * ack is more than 65535, an uncompressed packet is sent.) | ||
63 | */ | ||
64 | |||
65 | /* | ||
66 | * Packet types (must not conflict with IP protocol version) | ||
67 | * | ||
68 | * The top nibble of the first octet is the packet type. There are | ||
69 | * three possible types: IP (not proto TCP or tcp with one of the | ||
70 | * control flags set); uncompressed TCP (a normal IP/TCP packet but | ||
71 | * with the 8-bit protocol field replaced by an 8-bit connection id -- | ||
72 | * this type of packet syncs the sender & receiver); and compressed | ||
73 | * TCP (described above). | ||
74 | * | ||
75 | * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and | ||
76 | * is logically part of the 4-bit "changes" field that follows. Top | ||
77 | * three bits are actual packet type. For backward compatibility | ||
78 | * and in the interest of conserving bits, numbers are chosen so the | ||
79 | * IP protocol version number (4) which normally appears in this nibble | ||
80 | * means "IP packet". | ||
81 | */ | ||
82 | |||
83 | |||
84 | #include <linux/ip.h> | ||
85 | #include <linux/tcp.h> | ||
86 | |||
87 | /* SLIP compression masks for len/vers byte */ | ||
88 | #define SL_TYPE_IP 0x40 | ||
89 | #define SL_TYPE_UNCOMPRESSED_TCP 0x70 | ||
90 | #define SL_TYPE_COMPRESSED_TCP 0x80 | ||
91 | #define SL_TYPE_ERROR 0x00 | ||
92 | |||
93 | /* Bits in first octet of compressed packet */ | ||
94 | #define NEW_C 0x40 /* flag bits for what changed in a packet */ | ||
95 | #define NEW_I 0x20 | ||
96 | #define NEW_S 0x08 | ||
97 | #define NEW_A 0x04 | ||
98 | #define NEW_W 0x02 | ||
99 | #define NEW_U 0x01 | ||
100 | |||
101 | /* reserved, special-case values of above */ | ||
102 | #define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ | ||
103 | #define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ | ||
104 | #define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) | ||
105 | |||
106 | #define TCP_PUSH_BIT 0x10 | ||
107 | |||
108 | /* | ||
109 | * data type and sizes conversion assumptions: | ||
110 | * | ||
111 | * VJ code KA9Q style generic | ||
112 | * u_char byte_t unsigned char 8 bits | ||
113 | * u_short int16 unsigned short 16 bits | ||
114 | * u_int int16 unsigned short 16 bits | ||
115 | * u_long unsigned long unsigned long 32 bits | ||
116 | * int int32 long 32 bits | ||
117 | */ | ||
118 | |||
119 | typedef __u8 byte_t; | ||
120 | typedef __u32 int32; | ||
121 | |||
122 | /* | ||
123 | * "state" data for each active tcp conversation on the wire. This is | ||
124 | * basically a copy of the entire IP/TCP header from the last packet | ||
125 | * we saw from the conversation together with a small identifier | ||
126 | * the transmit & receive ends of the line use to locate saved header. | ||
127 | */ | ||
128 | struct cstate { | ||
129 | byte_t cs_this; /* connection id number (xmit) */ | ||
130 | struct cstate *next; /* next in ring (xmit) */ | ||
131 | struct iphdr cs_ip; /* ip/tcp hdr from most recent packet */ | ||
132 | struct tcphdr cs_tcp; | ||
133 | unsigned char cs_ipopt[64]; | ||
134 | unsigned char cs_tcpopt[64]; | ||
135 | int cs_hsize; | ||
136 | }; | ||
137 | #define NULLSLSTATE (struct cstate *)0 | ||
138 | |||
139 | /* | ||
140 | * all the state data for one serial line (we need one of these per line). | ||
141 | */ | ||
142 | struct slcompress { | ||
143 | struct cstate *tstate; /* transmit connection states (array)*/ | ||
144 | struct cstate *rstate; /* receive connection states (array)*/ | ||
145 | |||
146 | byte_t tslot_limit; /* highest transmit slot id (0-l)*/ | ||
147 | byte_t rslot_limit; /* highest receive slot id (0-l)*/ | ||
148 | |||
149 | byte_t xmit_oldest; /* oldest xmit in ring */ | ||
150 | byte_t xmit_current; /* most recent xmit id */ | ||
151 | byte_t recv_current; /* most recent rcvd id */ | ||
152 | |||
153 | byte_t flags; | ||
154 | #define SLF_TOSS 0x01 /* tossing rcvd frames until id received */ | ||
155 | |||
156 | int32 sls_o_nontcp; /* outbound non-TCP packets */ | ||
157 | int32 sls_o_tcp; /* outbound TCP packets */ | ||
158 | int32 sls_o_uncompressed; /* outbound uncompressed packets */ | ||
159 | int32 sls_o_compressed; /* outbound compressed packets */ | ||
160 | int32 sls_o_searches; /* searches for connection state */ | ||
161 | int32 sls_o_misses; /* times couldn't find conn. state */ | ||
162 | |||
163 | int32 sls_i_uncompressed; /* inbound uncompressed packets */ | ||
164 | int32 sls_i_compressed; /* inbound compressed packets */ | ||
165 | int32 sls_i_error; /* inbound error packets */ | ||
166 | int32 sls_i_tossed; /* inbound packets tossed because of error */ | ||
167 | |||
168 | int32 sls_i_runt; | ||
169 | int32 sls_i_badcheck; | ||
170 | }; | ||
171 | #define NULLSLCOMPR (struct slcompress *)0 | ||
172 | |||
173 | #define __ARGS(x) x | ||
174 | |||
175 | /* In slhc.c: */ | ||
176 | struct slcompress *slhc_init __ARGS((int rslots, int tslots)); | ||
177 | void slhc_free __ARGS((struct slcompress *comp)); | ||
178 | |||
179 | int slhc_compress __ARGS((struct slcompress *comp, unsigned char *icp, | ||
180 | int isize, unsigned char *ocp, unsigned char **cpp, | ||
181 | int compress_cid)); | ||
182 | int slhc_uncompress __ARGS((struct slcompress *comp, unsigned char *icp, | ||
183 | int isize)); | ||
184 | int slhc_remember __ARGS((struct slcompress *comp, unsigned char *icp, | ||
185 | int isize)); | ||
186 | int slhc_toss __ARGS((struct slcompress *comp)); | ||
187 | |||
188 | #endif /* _SLHC_H */ | ||
diff --git a/include/net/snmp.h b/include/net/snmp.h new file mode 100644 index 000000000000..a15ab256276e --- /dev/null +++ b/include/net/snmp.h | |||
@@ -0,0 +1,145 @@ | |||
1 | /* | ||
2 | * | ||
3 | * SNMP MIB entries for the IP subsystem. | ||
4 | * | ||
5 | * Alan Cox <gw4pts@gw4pts.ampr.org> | ||
6 | * | ||
7 | * We don't chose to implement SNMP in the kernel (this would | ||
8 | * be silly as SNMP is a pain in the backside in places). We do | ||
9 | * however need to collect the MIB statistics and export them | ||
10 | * out of /proc (eventually) | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version | ||
15 | * 2 of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * $Id: snmp.h,v 1.19 2001/06/14 13:40:46 davem Exp $ | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #ifndef _SNMP_H | ||
22 | #define _SNMP_H | ||
23 | |||
24 | #include <linux/cache.h> | ||
25 | #include <linux/snmp.h> | ||
26 | |||
27 | /* | ||
28 | * Mibs are stored in array of unsigned long. | ||
29 | */ | ||
30 | /* | ||
31 | * struct snmp_mib{} | ||
32 | * - list of entries for particular API (such as /proc/net/snmp) | ||
33 | * - name of entries. | ||
34 | */ | ||
35 | struct snmp_mib { | ||
36 | char *name; | ||
37 | int entry; | ||
38 | }; | ||
39 | |||
40 | #define SNMP_MIB_ITEM(_name,_entry) { \ | ||
41 | .name = _name, \ | ||
42 | .entry = _entry, \ | ||
43 | } | ||
44 | |||
45 | #define SNMP_MIB_SENTINEL { \ | ||
46 | .name = NULL, \ | ||
47 | .entry = 0, \ | ||
48 | } | ||
49 | |||
50 | /* | ||
51 | * We use all unsigned longs. Linux will soon be so reliable that even | ||
52 | * these will rapidly get too small 8-). Seriously consider the IpInReceives | ||
53 | * count on the 20Gb/s + networks people expect in a few years time! | ||
54 | */ | ||
55 | |||
56 | /* | ||
57 | * The rule for padding: | ||
58 | * Best is power of two because then the right structure can be found by a | ||
59 | * simple shift. The structure should be always cache line aligned. | ||
60 | * gcc needs n=alignto(cachelinesize, popcnt(sizeof(bla_mib))) shift/add | ||
61 | * instructions to emulate multiply in case it is not power-of-two. | ||
62 | * Currently n is always <=3 for all sizes so simple cache line alignment | ||
63 | * is enough. | ||
64 | * | ||
65 | * The best solution would be a global CPU local area , especially on 64 | ||
66 | * and 128byte cacheline machine it makes a *lot* of sense -AK | ||
67 | */ | ||
68 | |||
69 | #define __SNMP_MIB_ALIGN__ ____cacheline_aligned | ||
70 | |||
71 | /* IPstats */ | ||
72 | #define IPSTATS_MIB_MAX __IPSTATS_MIB_MAX | ||
73 | struct ipstats_mib { | ||
74 | unsigned long mibs[IPSTATS_MIB_MAX]; | ||
75 | } __SNMP_MIB_ALIGN__; | ||
76 | |||
77 | /* ICMP */ | ||
78 | #define ICMP_MIB_DUMMY __ICMP_MIB_MAX | ||
79 | #define ICMP_MIB_MAX (__ICMP_MIB_MAX + 1) | ||
80 | |||
81 | struct icmp_mib { | ||
82 | unsigned long mibs[ICMP_MIB_MAX]; | ||
83 | } __SNMP_MIB_ALIGN__; | ||
84 | |||
85 | /* ICMP6 (IPv6-ICMP) */ | ||
86 | #define ICMP6_MIB_MAX __ICMP6_MIB_MAX | ||
87 | struct icmpv6_mib { | ||
88 | unsigned long mibs[ICMP6_MIB_MAX]; | ||
89 | } __SNMP_MIB_ALIGN__; | ||
90 | |||
91 | /* TCP */ | ||
92 | #define TCP_MIB_MAX __TCP_MIB_MAX | ||
93 | struct tcp_mib { | ||
94 | unsigned long mibs[TCP_MIB_MAX]; | ||
95 | } __SNMP_MIB_ALIGN__; | ||
96 | |||
97 | /* UDP */ | ||
98 | #define UDP_MIB_MAX __UDP_MIB_MAX | ||
99 | struct udp_mib { | ||
100 | unsigned long mibs[UDP_MIB_MAX]; | ||
101 | } __SNMP_MIB_ALIGN__; | ||
102 | |||
103 | /* SCTP */ | ||
104 | #define SCTP_MIB_MAX __SCTP_MIB_MAX | ||
105 | struct sctp_mib { | ||
106 | unsigned long mibs[SCTP_MIB_MAX]; | ||
107 | } __SNMP_MIB_ALIGN__; | ||
108 | |||
109 | /* Linux */ | ||
110 | #define LINUX_MIB_MAX __LINUX_MIB_MAX | ||
111 | struct linux_mib { | ||
112 | unsigned long mibs[LINUX_MIB_MAX]; | ||
113 | }; | ||
114 | |||
115 | |||
116 | /* | ||
117 | * FIXME: On x86 and some other CPUs the split into user and softirq parts | ||
118 | * is not needed because addl $1,memory is atomic against interrupts (but | ||
119 | * atomic_inc would be overkill because of the lock cycles). Wants new | ||
120 | * nonlocked_atomic_inc() primitives -AK | ||
121 | */ | ||
122 | #define DEFINE_SNMP_STAT(type, name) \ | ||
123 | __typeof__(type) *name[2] | ||
124 | #define DECLARE_SNMP_STAT(type, name) \ | ||
125 | extern __typeof__(type) *name[2] | ||
126 | |||
127 | #define SNMP_STAT_BHPTR(name) (name[0]) | ||
128 | #define SNMP_STAT_USRPTR(name) (name[1]) | ||
129 | |||
130 | #define SNMP_INC_STATS_BH(mib, field) \ | ||
131 | (per_cpu_ptr(mib[0], _smp_processor_id())->mibs[field]++) | ||
132 | #define SNMP_INC_STATS_OFFSET_BH(mib, field, offset) \ | ||
133 | (per_cpu_ptr(mib[0], _smp_processor_id())->mibs[field + (offset)]++) | ||
134 | #define SNMP_INC_STATS_USER(mib, field) \ | ||
135 | (per_cpu_ptr(mib[1], _smp_processor_id())->mibs[field]++) | ||
136 | #define SNMP_INC_STATS(mib, field) \ | ||
137 | (per_cpu_ptr(mib[!in_softirq()], _smp_processor_id())->mibs[field]++) | ||
138 | #define SNMP_DEC_STATS(mib, field) \ | ||
139 | (per_cpu_ptr(mib[!in_softirq()], _smp_processor_id())->mibs[field]--) | ||
140 | #define SNMP_ADD_STATS_BH(mib, field, addend) \ | ||
141 | (per_cpu_ptr(mib[0], _smp_processor_id())->mibs[field] += addend) | ||
142 | #define SNMP_ADD_STATS_USER(mib, field, addend) \ | ||
143 | (per_cpu_ptr(mib[1], _smp_processor_id())->mibs[field] += addend) | ||
144 | |||
145 | #endif | ||
diff --git a/include/net/sock.h b/include/net/sock.h new file mode 100644 index 000000000000..be81cabd0da3 --- /dev/null +++ b/include/net/sock.h | |||
@@ -0,0 +1,1297 @@ | |||
1 | /* | ||
2 | * INET An implementation of the TCP/IP protocol suite for the LINUX | ||
3 | * operating system. INET is implemented using the BSD Socket | ||
4 | * interface as the means of communication with the user level. | ||
5 | * | ||
6 | * Definitions for the AF_INET socket handler. | ||
7 | * | ||
8 | * Version: @(#)sock.h 1.0.4 05/13/93 | ||
9 | * | ||
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | ||
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | ||
12 | * Corey Minyard <wf-rch!minyard@relay.EU.net> | ||
13 | * Florian La Roche <flla@stud.uni-sb.de> | ||
14 | * | ||
15 | * Fixes: | ||
16 | * Alan Cox : Volatiles in skbuff pointers. See | ||
17 | * skbuff comments. May be overdone, | ||
18 | * better to prove they can be removed | ||
19 | * than the reverse. | ||
20 | * Alan Cox : Added a zapped field for tcp to note | ||
21 | * a socket is reset and must stay shut up | ||
22 | * Alan Cox : New fields for options | ||
23 | * Pauline Middelink : identd support | ||
24 | * Alan Cox : Eliminate low level recv/recvfrom | ||
25 | * David S. Miller : New socket lookup architecture. | ||
26 | * Steve Whitehouse: Default routines for sock_ops | ||
27 | * Arnaldo C. Melo : removed net_pinfo, tp_pinfo and made | ||
28 | * protinfo be just a void pointer, as the | ||
29 | * protocol specific parts were moved to | ||
30 | * respective headers and ipv4/v6, etc now | ||
31 | * use private slabcaches for its socks | ||
32 | * Pedro Hortas : New flags field for socket options | ||
33 | * | ||
34 | * | ||
35 | * This program is free software; you can redistribute it and/or | ||
36 | * modify it under the terms of the GNU General Public License | ||
37 | * as published by the Free Software Foundation; either version | ||
38 | * 2 of the License, or (at your option) any later version. | ||
39 | */ | ||
40 | #ifndef _SOCK_H | ||
41 | #define _SOCK_H | ||
42 | |||
43 | #include <linux/config.h> | ||
44 | #include <linux/list.h> | ||
45 | #include <linux/timer.h> | ||
46 | #include <linux/cache.h> | ||
47 | #include <linux/module.h> | ||
48 | #include <linux/netdevice.h> | ||
49 | #include <linux/skbuff.h> /* struct sk_buff */ | ||
50 | #include <linux/security.h> | ||
51 | |||
52 | #include <linux/filter.h> | ||
53 | |||
54 | #include <asm/atomic.h> | ||
55 | #include <net/dst.h> | ||
56 | #include <net/checksum.h> | ||
57 | |||
58 | /* | ||
59 | * This structure really needs to be cleaned up. | ||
60 | * Most of it is for TCP, and not used by any of | ||
61 | * the other protocols. | ||
62 | */ | ||
63 | |||
64 | /* Define this to get the SOCK_DBG debugging facility. */ | ||
65 | #define SOCK_DEBUGGING | ||
66 | #ifdef SOCK_DEBUGGING | ||
67 | #define SOCK_DEBUG(sk, msg...) do { if ((sk) && sock_flag((sk), SOCK_DBG)) \ | ||
68 | printk(KERN_DEBUG msg); } while (0) | ||
69 | #else | ||
70 | #define SOCK_DEBUG(sk, msg...) do { } while (0) | ||
71 | #endif | ||
72 | |||
73 | /* This is the per-socket lock. The spinlock provides a synchronization | ||
74 | * between user contexts and software interrupt processing, whereas the | ||
75 | * mini-semaphore synchronizes multiple users amongst themselves. | ||
76 | */ | ||
77 | struct sock_iocb; | ||
78 | typedef struct { | ||
79 | spinlock_t slock; | ||
80 | struct sock_iocb *owner; | ||
81 | wait_queue_head_t wq; | ||
82 | } socket_lock_t; | ||
83 | |||
84 | #define sock_lock_init(__sk) \ | ||
85 | do { spin_lock_init(&((__sk)->sk_lock.slock)); \ | ||
86 | (__sk)->sk_lock.owner = NULL; \ | ||
87 | init_waitqueue_head(&((__sk)->sk_lock.wq)); \ | ||
88 | } while(0) | ||
89 | |||
90 | struct sock; | ||
91 | |||
92 | /** | ||
93 | * struct sock_common - minimal network layer representation of sockets | ||
94 | * @skc_family - network address family | ||
95 | * @skc_state - Connection state | ||
96 | * @skc_reuse - %SO_REUSEADDR setting | ||
97 | * @skc_bound_dev_if - bound device index if != 0 | ||
98 | * @skc_node - main hash linkage for various protocol lookup tables | ||
99 | * @skc_bind_node - bind hash linkage for various protocol lookup tables | ||
100 | * @skc_refcnt - reference count | ||
101 | * | ||
102 | * This is the minimal network layer representation of sockets, the header | ||
103 | * for struct sock and struct tcp_tw_bucket. | ||
104 | */ | ||
105 | struct sock_common { | ||
106 | unsigned short skc_family; | ||
107 | volatile unsigned char skc_state; | ||
108 | unsigned char skc_reuse; | ||
109 | int skc_bound_dev_if; | ||
110 | struct hlist_node skc_node; | ||
111 | struct hlist_node skc_bind_node; | ||
112 | atomic_t skc_refcnt; | ||
113 | }; | ||
114 | |||
115 | /** | ||
116 | * struct sock - network layer representation of sockets | ||
117 | * @__sk_common - shared layout with tcp_tw_bucket | ||
118 | * @sk_shutdown - mask of %SEND_SHUTDOWN and/or %RCV_SHUTDOWN | ||
119 | * @sk_userlocks - %SO_SNDBUF and %SO_RCVBUF settings | ||
120 | * @sk_lock - synchronizer | ||
121 | * @sk_rcvbuf - size of receive buffer in bytes | ||
122 | * @sk_sleep - sock wait queue | ||
123 | * @sk_dst_cache - destination cache | ||
124 | * @sk_dst_lock - destination cache lock | ||
125 | * @sk_policy - flow policy | ||
126 | * @sk_rmem_alloc - receive queue bytes committed | ||
127 | * @sk_receive_queue - incoming packets | ||
128 | * @sk_wmem_alloc - transmit queue bytes committed | ||
129 | * @sk_write_queue - Packet sending queue | ||
130 | * @sk_omem_alloc - "o" is "option" or "other" | ||
131 | * @sk_wmem_queued - persistent queue size | ||
132 | * @sk_forward_alloc - space allocated forward | ||
133 | * @sk_allocation - allocation mode | ||
134 | * @sk_sndbuf - size of send buffer in bytes | ||
135 | * @sk_flags - %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE, %SO_OOBINLINE settings | ||
136 | * @sk_no_check - %SO_NO_CHECK setting, wether or not checkup packets | ||
137 | * @sk_route_caps - route capabilities (e.g. %NETIF_F_TSO) | ||
138 | * @sk_lingertime - %SO_LINGER l_linger setting | ||
139 | * @sk_hashent - hash entry in several tables (e.g. tcp_ehash) | ||
140 | * @sk_backlog - always used with the per-socket spinlock held | ||
141 | * @sk_callback_lock - used with the callbacks in the end of this struct | ||
142 | * @sk_error_queue - rarely used | ||
143 | * @sk_prot - protocol handlers inside a network family | ||
144 | * @sk_err - last error | ||
145 | * @sk_err_soft - errors that don't cause failure but are the cause of a persistent failure not just 'timed out' | ||
146 | * @sk_ack_backlog - current listen backlog | ||
147 | * @sk_max_ack_backlog - listen backlog set in listen() | ||
148 | * @sk_priority - %SO_PRIORITY setting | ||
149 | * @sk_type - socket type (%SOCK_STREAM, etc) | ||
150 | * @sk_protocol - which protocol this socket belongs in this network family | ||
151 | * @sk_peercred - %SO_PEERCRED setting | ||
152 | * @sk_rcvlowat - %SO_RCVLOWAT setting | ||
153 | * @sk_rcvtimeo - %SO_RCVTIMEO setting | ||
154 | * @sk_sndtimeo - %SO_SNDTIMEO setting | ||
155 | * @sk_filter - socket filtering instructions | ||
156 | * @sk_protinfo - private area, net family specific, when not using slab | ||
157 | * @sk_timer - sock cleanup timer | ||
158 | * @sk_stamp - time stamp of last packet received | ||
159 | * @sk_socket - Identd and reporting IO signals | ||
160 | * @sk_user_data - RPC layer private data | ||
161 | * @sk_sndmsg_page - cached page for sendmsg | ||
162 | * @sk_sndmsg_off - cached offset for sendmsg | ||
163 | * @sk_send_head - front of stuff to transmit | ||
164 | * @sk_write_pending - a write to stream socket waits to start | ||
165 | * @sk_state_change - callback to indicate change in the state of the sock | ||
166 | * @sk_data_ready - callback to indicate there is data to be processed | ||
167 | * @sk_write_space - callback to indicate there is bf sending space available | ||
168 | * @sk_error_report - callback to indicate errors (e.g. %MSG_ERRQUEUE) | ||
169 | * @sk_backlog_rcv - callback to process the backlog | ||
170 | * @sk_destruct - called at sock freeing time, i.e. when all refcnt == 0 | ||
171 | */ | ||
172 | struct sock { | ||
173 | /* | ||
174 | * Now struct tcp_tw_bucket also uses sock_common, so please just | ||
175 | * don't add nothing before this first member (__sk_common) --acme | ||
176 | */ | ||
177 | struct sock_common __sk_common; | ||
178 | #define sk_family __sk_common.skc_family | ||
179 | #define sk_state __sk_common.skc_state | ||
180 | #define sk_reuse __sk_common.skc_reuse | ||
181 | #define sk_bound_dev_if __sk_common.skc_bound_dev_if | ||
182 | #define sk_node __sk_common.skc_node | ||
183 | #define sk_bind_node __sk_common.skc_bind_node | ||
184 | #define sk_refcnt __sk_common.skc_refcnt | ||
185 | unsigned char sk_shutdown : 2, | ||
186 | sk_no_check : 2, | ||
187 | sk_userlocks : 4; | ||
188 | unsigned char sk_protocol; | ||
189 | unsigned short sk_type; | ||
190 | int sk_rcvbuf; | ||
191 | socket_lock_t sk_lock; | ||
192 | wait_queue_head_t *sk_sleep; | ||
193 | struct dst_entry *sk_dst_cache; | ||
194 | struct xfrm_policy *sk_policy[2]; | ||
195 | rwlock_t sk_dst_lock; | ||
196 | atomic_t sk_rmem_alloc; | ||
197 | atomic_t sk_wmem_alloc; | ||
198 | atomic_t sk_omem_alloc; | ||
199 | struct sk_buff_head sk_receive_queue; | ||
200 | struct sk_buff_head sk_write_queue; | ||
201 | int sk_wmem_queued; | ||
202 | int sk_forward_alloc; | ||
203 | unsigned int sk_allocation; | ||
204 | int sk_sndbuf; | ||
205 | int sk_route_caps; | ||
206 | int sk_hashent; | ||
207 | unsigned long sk_flags; | ||
208 | unsigned long sk_lingertime; | ||
209 | /* | ||
210 | * The backlog queue is special, it is always used with | ||
211 | * the per-socket spinlock held and requires low latency | ||
212 | * access. Therefore we special case it's implementation. | ||
213 | */ | ||
214 | struct { | ||
215 | struct sk_buff *head; | ||
216 | struct sk_buff *tail; | ||
217 | } sk_backlog; | ||
218 | struct sk_buff_head sk_error_queue; | ||
219 | struct proto *sk_prot; | ||
220 | rwlock_t sk_callback_lock; | ||
221 | int sk_err, | ||
222 | sk_err_soft; | ||
223 | unsigned short sk_ack_backlog; | ||
224 | unsigned short sk_max_ack_backlog; | ||
225 | __u32 sk_priority; | ||
226 | struct ucred sk_peercred; | ||
227 | int sk_rcvlowat; | ||
228 | long sk_rcvtimeo; | ||
229 | long sk_sndtimeo; | ||
230 | struct sk_filter *sk_filter; | ||
231 | void *sk_protinfo; | ||
232 | struct timer_list sk_timer; | ||
233 | struct timeval sk_stamp; | ||
234 | struct socket *sk_socket; | ||
235 | void *sk_user_data; | ||
236 | struct page *sk_sndmsg_page; | ||
237 | struct sk_buff *sk_send_head; | ||
238 | __u32 sk_sndmsg_off; | ||
239 | int sk_write_pending; | ||
240 | void *sk_security; | ||
241 | void (*sk_state_change)(struct sock *sk); | ||
242 | void (*sk_data_ready)(struct sock *sk, int bytes); | ||
243 | void (*sk_write_space)(struct sock *sk); | ||
244 | void (*sk_error_report)(struct sock *sk); | ||
245 | int (*sk_backlog_rcv)(struct sock *sk, | ||
246 | struct sk_buff *skb); | ||
247 | void (*sk_destruct)(struct sock *sk); | ||
248 | }; | ||
249 | |||
250 | /* | ||
251 | * Hashed lists helper routines | ||
252 | */ | ||
253 | static inline struct sock *__sk_head(struct hlist_head *head) | ||
254 | { | ||
255 | return hlist_entry(head->first, struct sock, sk_node); | ||
256 | } | ||
257 | |||
258 | static inline struct sock *sk_head(struct hlist_head *head) | ||
259 | { | ||
260 | return hlist_empty(head) ? NULL : __sk_head(head); | ||
261 | } | ||
262 | |||
263 | static inline struct sock *sk_next(struct sock *sk) | ||
264 | { | ||
265 | return sk->sk_node.next ? | ||
266 | hlist_entry(sk->sk_node.next, struct sock, sk_node) : NULL; | ||
267 | } | ||
268 | |||
269 | static inline int sk_unhashed(struct sock *sk) | ||
270 | { | ||
271 | return hlist_unhashed(&sk->sk_node); | ||
272 | } | ||
273 | |||
274 | static inline int sk_hashed(struct sock *sk) | ||
275 | { | ||
276 | return sk->sk_node.pprev != NULL; | ||
277 | } | ||
278 | |||
279 | static __inline__ void sk_node_init(struct hlist_node *node) | ||
280 | { | ||
281 | node->pprev = NULL; | ||
282 | } | ||
283 | |||
284 | static __inline__ void __sk_del_node(struct sock *sk) | ||
285 | { | ||
286 | __hlist_del(&sk->sk_node); | ||
287 | } | ||
288 | |||
289 | static __inline__ int __sk_del_node_init(struct sock *sk) | ||
290 | { | ||
291 | if (sk_hashed(sk)) { | ||
292 | __sk_del_node(sk); | ||
293 | sk_node_init(&sk->sk_node); | ||
294 | return 1; | ||
295 | } | ||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | /* Grab socket reference count. This operation is valid only | ||
300 | when sk is ALREADY grabbed f.e. it is found in hash table | ||
301 | or a list and the lookup is made under lock preventing hash table | ||
302 | modifications. | ||
303 | */ | ||
304 | |||
305 | static inline void sock_hold(struct sock *sk) | ||
306 | { | ||
307 | atomic_inc(&sk->sk_refcnt); | ||
308 | } | ||
309 | |||
310 | /* Ungrab socket in the context, which assumes that socket refcnt | ||
311 | cannot hit zero, f.e. it is true in context of any socketcall. | ||
312 | */ | ||
313 | static inline void __sock_put(struct sock *sk) | ||
314 | { | ||
315 | atomic_dec(&sk->sk_refcnt); | ||
316 | } | ||
317 | |||
318 | static __inline__ int sk_del_node_init(struct sock *sk) | ||
319 | { | ||
320 | int rc = __sk_del_node_init(sk); | ||
321 | |||
322 | if (rc) { | ||
323 | /* paranoid for a while -acme */ | ||
324 | WARN_ON(atomic_read(&sk->sk_refcnt) == 1); | ||
325 | __sock_put(sk); | ||
326 | } | ||
327 | return rc; | ||
328 | } | ||
329 | |||
330 | static __inline__ void __sk_add_node(struct sock *sk, struct hlist_head *list) | ||
331 | { | ||
332 | hlist_add_head(&sk->sk_node, list); | ||
333 | } | ||
334 | |||
335 | static __inline__ void sk_add_node(struct sock *sk, struct hlist_head *list) | ||
336 | { | ||
337 | sock_hold(sk); | ||
338 | __sk_add_node(sk, list); | ||
339 | } | ||
340 | |||
341 | static __inline__ void __sk_del_bind_node(struct sock *sk) | ||
342 | { | ||
343 | __hlist_del(&sk->sk_bind_node); | ||
344 | } | ||
345 | |||
346 | static __inline__ void sk_add_bind_node(struct sock *sk, | ||
347 | struct hlist_head *list) | ||
348 | { | ||
349 | hlist_add_head(&sk->sk_bind_node, list); | ||
350 | } | ||
351 | |||
352 | #define sk_for_each(__sk, node, list) \ | ||
353 | hlist_for_each_entry(__sk, node, list, sk_node) | ||
354 | #define sk_for_each_from(__sk, node) \ | ||
355 | if (__sk && ({ node = &(__sk)->sk_node; 1; })) \ | ||
356 | hlist_for_each_entry_from(__sk, node, sk_node) | ||
357 | #define sk_for_each_continue(__sk, node) \ | ||
358 | if (__sk && ({ node = &(__sk)->sk_node; 1; })) \ | ||
359 | hlist_for_each_entry_continue(__sk, node, sk_node) | ||
360 | #define sk_for_each_safe(__sk, node, tmp, list) \ | ||
361 | hlist_for_each_entry_safe(__sk, node, tmp, list, sk_node) | ||
362 | #define sk_for_each_bound(__sk, node, list) \ | ||
363 | hlist_for_each_entry(__sk, node, list, sk_bind_node) | ||
364 | |||
365 | /* Sock flags */ | ||
366 | enum sock_flags { | ||
367 | SOCK_DEAD, | ||
368 | SOCK_DONE, | ||
369 | SOCK_URGINLINE, | ||
370 | SOCK_KEEPOPEN, | ||
371 | SOCK_LINGER, | ||
372 | SOCK_DESTROY, | ||
373 | SOCK_BROADCAST, | ||
374 | SOCK_TIMESTAMP, | ||
375 | SOCK_ZAPPED, | ||
376 | SOCK_USE_WRITE_QUEUE, /* whether to call sk->sk_write_space in sock_wfree */ | ||
377 | SOCK_DBG, /* %SO_DEBUG setting */ | ||
378 | SOCK_RCVTSTAMP, /* %SO_TIMESTAMP setting */ | ||
379 | SOCK_NO_LARGESEND, /* whether to sent large segments or not */ | ||
380 | SOCK_LOCALROUTE, /* route locally only, %SO_DONTROUTE setting */ | ||
381 | SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */ | ||
382 | }; | ||
383 | |||
384 | static inline void sock_set_flag(struct sock *sk, enum sock_flags flag) | ||
385 | { | ||
386 | __set_bit(flag, &sk->sk_flags); | ||
387 | } | ||
388 | |||
389 | static inline void sock_reset_flag(struct sock *sk, enum sock_flags flag) | ||
390 | { | ||
391 | __clear_bit(flag, &sk->sk_flags); | ||
392 | } | ||
393 | |||
394 | static inline int sock_flag(struct sock *sk, enum sock_flags flag) | ||
395 | { | ||
396 | return test_bit(flag, &sk->sk_flags); | ||
397 | } | ||
398 | |||
399 | static inline void sk_acceptq_removed(struct sock *sk) | ||
400 | { | ||
401 | sk->sk_ack_backlog--; | ||
402 | } | ||
403 | |||
404 | static inline void sk_acceptq_added(struct sock *sk) | ||
405 | { | ||
406 | sk->sk_ack_backlog++; | ||
407 | } | ||
408 | |||
409 | static inline int sk_acceptq_is_full(struct sock *sk) | ||
410 | { | ||
411 | return sk->sk_ack_backlog > sk->sk_max_ack_backlog; | ||
412 | } | ||
413 | |||
414 | /* | ||
415 | * Compute minimal free write space needed to queue new packets. | ||
416 | */ | ||
417 | static inline int sk_stream_min_wspace(struct sock *sk) | ||
418 | { | ||
419 | return sk->sk_wmem_queued / 2; | ||
420 | } | ||
421 | |||
422 | static inline int sk_stream_wspace(struct sock *sk) | ||
423 | { | ||
424 | return sk->sk_sndbuf - sk->sk_wmem_queued; | ||
425 | } | ||
426 | |||
427 | extern void sk_stream_write_space(struct sock *sk); | ||
428 | |||
429 | static inline int sk_stream_memory_free(struct sock *sk) | ||
430 | { | ||
431 | return sk->sk_wmem_queued < sk->sk_sndbuf; | ||
432 | } | ||
433 | |||
434 | extern void sk_stream_rfree(struct sk_buff *skb); | ||
435 | |||
436 | static inline void sk_stream_set_owner_r(struct sk_buff *skb, struct sock *sk) | ||
437 | { | ||
438 | skb->sk = sk; | ||
439 | skb->destructor = sk_stream_rfree; | ||
440 | atomic_add(skb->truesize, &sk->sk_rmem_alloc); | ||
441 | sk->sk_forward_alloc -= skb->truesize; | ||
442 | } | ||
443 | |||
444 | static inline void sk_stream_free_skb(struct sock *sk, struct sk_buff *skb) | ||
445 | { | ||
446 | sock_set_flag(sk, SOCK_QUEUE_SHRUNK); | ||
447 | sk->sk_wmem_queued -= skb->truesize; | ||
448 | sk->sk_forward_alloc += skb->truesize; | ||
449 | __kfree_skb(skb); | ||
450 | } | ||
451 | |||
452 | /* The per-socket spinlock must be held here. */ | ||
453 | #define sk_add_backlog(__sk, __skb) \ | ||
454 | do { if (!(__sk)->sk_backlog.tail) { \ | ||
455 | (__sk)->sk_backlog.head = \ | ||
456 | (__sk)->sk_backlog.tail = (__skb); \ | ||
457 | } else { \ | ||
458 | ((__sk)->sk_backlog.tail)->next = (__skb); \ | ||
459 | (__sk)->sk_backlog.tail = (__skb); \ | ||
460 | } \ | ||
461 | (__skb)->next = NULL; \ | ||
462 | } while(0) | ||
463 | |||
464 | #define sk_wait_event(__sk, __timeo, __condition) \ | ||
465 | ({ int rc; \ | ||
466 | release_sock(__sk); \ | ||
467 | rc = __condition; \ | ||
468 | if (!rc) { \ | ||
469 | *(__timeo) = schedule_timeout(*(__timeo)); \ | ||
470 | rc = __condition; \ | ||
471 | } \ | ||
472 | lock_sock(__sk); \ | ||
473 | rc; \ | ||
474 | }) | ||
475 | |||
476 | extern int sk_stream_wait_connect(struct sock *sk, long *timeo_p); | ||
477 | extern int sk_stream_wait_memory(struct sock *sk, long *timeo_p); | ||
478 | extern void sk_stream_wait_close(struct sock *sk, long timeo_p); | ||
479 | extern int sk_stream_error(struct sock *sk, int flags, int err); | ||
480 | extern void sk_stream_kill_queues(struct sock *sk); | ||
481 | |||
482 | extern int sk_wait_data(struct sock *sk, long *timeo); | ||
483 | |||
484 | /* Networking protocol blocks we attach to sockets. | ||
485 | * socket layer -> transport layer interface | ||
486 | * transport -> network interface is defined by struct inet_proto | ||
487 | */ | ||
488 | struct proto { | ||
489 | void (*close)(struct sock *sk, | ||
490 | long timeout); | ||
491 | int (*connect)(struct sock *sk, | ||
492 | struct sockaddr *uaddr, | ||
493 | int addr_len); | ||
494 | int (*disconnect)(struct sock *sk, int flags); | ||
495 | |||
496 | struct sock * (*accept) (struct sock *sk, int flags, int *err); | ||
497 | |||
498 | int (*ioctl)(struct sock *sk, int cmd, | ||
499 | unsigned long arg); | ||
500 | int (*init)(struct sock *sk); | ||
501 | int (*destroy)(struct sock *sk); | ||
502 | void (*shutdown)(struct sock *sk, int how); | ||
503 | int (*setsockopt)(struct sock *sk, int level, | ||
504 | int optname, char __user *optval, | ||
505 | int optlen); | ||
506 | int (*getsockopt)(struct sock *sk, int level, | ||
507 | int optname, char __user *optval, | ||
508 | int __user *option); | ||
509 | int (*sendmsg)(struct kiocb *iocb, struct sock *sk, | ||
510 | struct msghdr *msg, size_t len); | ||
511 | int (*recvmsg)(struct kiocb *iocb, struct sock *sk, | ||
512 | struct msghdr *msg, | ||
513 | size_t len, int noblock, int flags, | ||
514 | int *addr_len); | ||
515 | int (*sendpage)(struct sock *sk, struct page *page, | ||
516 | int offset, size_t size, int flags); | ||
517 | int (*bind)(struct sock *sk, | ||
518 | struct sockaddr *uaddr, int addr_len); | ||
519 | |||
520 | int (*backlog_rcv) (struct sock *sk, | ||
521 | struct sk_buff *skb); | ||
522 | |||
523 | /* Keeping track of sk's, looking them up, and port selection methods. */ | ||
524 | void (*hash)(struct sock *sk); | ||
525 | void (*unhash)(struct sock *sk); | ||
526 | int (*get_port)(struct sock *sk, unsigned short snum); | ||
527 | |||
528 | /* Memory pressure */ | ||
529 | void (*enter_memory_pressure)(void); | ||
530 | atomic_t *memory_allocated; /* Current allocated memory. */ | ||
531 | atomic_t *sockets_allocated; /* Current number of sockets. */ | ||
532 | /* | ||
533 | * Pressure flag: try to collapse. | ||
534 | * Technical note: it is used by multiple contexts non atomically. | ||
535 | * All the sk_stream_mem_schedule() is of this nature: accounting | ||
536 | * is strict, actions are advisory and have some latency. | ||
537 | */ | ||
538 | int *memory_pressure; | ||
539 | int *sysctl_mem; | ||
540 | int *sysctl_wmem; | ||
541 | int *sysctl_rmem; | ||
542 | int max_header; | ||
543 | |||
544 | kmem_cache_t *slab; | ||
545 | unsigned int obj_size; | ||
546 | |||
547 | struct module *owner; | ||
548 | |||
549 | char name[32]; | ||
550 | |||
551 | struct list_head node; | ||
552 | |||
553 | struct { | ||
554 | int inuse; | ||
555 | u8 __pad[SMP_CACHE_BYTES - sizeof(int)]; | ||
556 | } stats[NR_CPUS]; | ||
557 | }; | ||
558 | |||
559 | extern int proto_register(struct proto *prot, int alloc_slab); | ||
560 | extern void proto_unregister(struct proto *prot); | ||
561 | |||
562 | /* Called with local bh disabled */ | ||
563 | static __inline__ void sock_prot_inc_use(struct proto *prot) | ||
564 | { | ||
565 | prot->stats[smp_processor_id()].inuse++; | ||
566 | } | ||
567 | |||
568 | static __inline__ void sock_prot_dec_use(struct proto *prot) | ||
569 | { | ||
570 | prot->stats[smp_processor_id()].inuse--; | ||
571 | } | ||
572 | |||
573 | /* About 10 seconds */ | ||
574 | #define SOCK_DESTROY_TIME (10*HZ) | ||
575 | |||
576 | /* Sockets 0-1023 can't be bound to unless you are superuser */ | ||
577 | #define PROT_SOCK 1024 | ||
578 | |||
579 | #define SHUTDOWN_MASK 3 | ||
580 | #define RCV_SHUTDOWN 1 | ||
581 | #define SEND_SHUTDOWN 2 | ||
582 | |||
583 | #define SOCK_SNDBUF_LOCK 1 | ||
584 | #define SOCK_RCVBUF_LOCK 2 | ||
585 | #define SOCK_BINDADDR_LOCK 4 | ||
586 | #define SOCK_BINDPORT_LOCK 8 | ||
587 | |||
588 | /* sock_iocb: used to kick off async processing of socket ios */ | ||
589 | struct sock_iocb { | ||
590 | struct list_head list; | ||
591 | |||
592 | int flags; | ||
593 | int size; | ||
594 | struct socket *sock; | ||
595 | struct sock *sk; | ||
596 | struct scm_cookie *scm; | ||
597 | struct msghdr *msg, async_msg; | ||
598 | struct iovec async_iov; | ||
599 | struct kiocb *kiocb; | ||
600 | }; | ||
601 | |||
602 | static inline struct sock_iocb *kiocb_to_siocb(struct kiocb *iocb) | ||
603 | { | ||
604 | return (struct sock_iocb *)iocb->private; | ||
605 | } | ||
606 | |||
607 | static inline struct kiocb *siocb_to_kiocb(struct sock_iocb *si) | ||
608 | { | ||
609 | return si->kiocb; | ||
610 | } | ||
611 | |||
612 | struct socket_alloc { | ||
613 | struct socket socket; | ||
614 | struct inode vfs_inode; | ||
615 | }; | ||
616 | |||
617 | static inline struct socket *SOCKET_I(struct inode *inode) | ||
618 | { | ||
619 | return &container_of(inode, struct socket_alloc, vfs_inode)->socket; | ||
620 | } | ||
621 | |||
622 | static inline struct inode *SOCK_INODE(struct socket *socket) | ||
623 | { | ||
624 | return &container_of(socket, struct socket_alloc, socket)->vfs_inode; | ||
625 | } | ||
626 | |||
627 | extern void __sk_stream_mem_reclaim(struct sock *sk); | ||
628 | extern int sk_stream_mem_schedule(struct sock *sk, int size, int kind); | ||
629 | |||
630 | #define SK_STREAM_MEM_QUANTUM ((int)PAGE_SIZE) | ||
631 | |||
632 | static inline int sk_stream_pages(int amt) | ||
633 | { | ||
634 | return (amt + SK_STREAM_MEM_QUANTUM - 1) / SK_STREAM_MEM_QUANTUM; | ||
635 | } | ||
636 | |||
637 | static inline void sk_stream_mem_reclaim(struct sock *sk) | ||
638 | { | ||
639 | if (sk->sk_forward_alloc >= SK_STREAM_MEM_QUANTUM) | ||
640 | __sk_stream_mem_reclaim(sk); | ||
641 | } | ||
642 | |||
643 | static inline void sk_stream_writequeue_purge(struct sock *sk) | ||
644 | { | ||
645 | struct sk_buff *skb; | ||
646 | |||
647 | while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) | ||
648 | sk_stream_free_skb(sk, skb); | ||
649 | sk_stream_mem_reclaim(sk); | ||
650 | } | ||
651 | |||
652 | static inline int sk_stream_rmem_schedule(struct sock *sk, struct sk_buff *skb) | ||
653 | { | ||
654 | return (int)skb->truesize <= sk->sk_forward_alloc || | ||
655 | sk_stream_mem_schedule(sk, skb->truesize, 1); | ||
656 | } | ||
657 | |||
658 | /* Used by processes to "lock" a socket state, so that | ||
659 | * interrupts and bottom half handlers won't change it | ||
660 | * from under us. It essentially blocks any incoming | ||
661 | * packets, so that we won't get any new data or any | ||
662 | * packets that change the state of the socket. | ||
663 | * | ||
664 | * While locked, BH processing will add new packets to | ||
665 | * the backlog queue. This queue is processed by the | ||
666 | * owner of the socket lock right before it is released. | ||
667 | * | ||
668 | * Since ~2.3.5 it is also exclusive sleep lock serializing | ||
669 | * accesses from user process context. | ||
670 | */ | ||
671 | #define sock_owned_by_user(sk) ((sk)->sk_lock.owner) | ||
672 | |||
673 | extern void FASTCALL(lock_sock(struct sock *sk)); | ||
674 | extern void FASTCALL(release_sock(struct sock *sk)); | ||
675 | |||
676 | /* BH context may only use the following locking interface. */ | ||
677 | #define bh_lock_sock(__sk) spin_lock(&((__sk)->sk_lock.slock)) | ||
678 | #define bh_unlock_sock(__sk) spin_unlock(&((__sk)->sk_lock.slock)) | ||
679 | |||
680 | extern struct sock *sk_alloc(int family, int priority, | ||
681 | struct proto *prot, int zero_it); | ||
682 | extern void sk_free(struct sock *sk); | ||
683 | |||
684 | extern struct sk_buff *sock_wmalloc(struct sock *sk, | ||
685 | unsigned long size, int force, | ||
686 | int priority); | ||
687 | extern struct sk_buff *sock_rmalloc(struct sock *sk, | ||
688 | unsigned long size, int force, | ||
689 | int priority); | ||
690 | extern void sock_wfree(struct sk_buff *skb); | ||
691 | extern void sock_rfree(struct sk_buff *skb); | ||
692 | |||
693 | extern int sock_setsockopt(struct socket *sock, int level, | ||
694 | int op, char __user *optval, | ||
695 | int optlen); | ||
696 | |||
697 | extern int sock_getsockopt(struct socket *sock, int level, | ||
698 | int op, char __user *optval, | ||
699 | int __user *optlen); | ||
700 | extern struct sk_buff *sock_alloc_send_skb(struct sock *sk, | ||
701 | unsigned long size, | ||
702 | int noblock, | ||
703 | int *errcode); | ||
704 | extern void *sock_kmalloc(struct sock *sk, int size, int priority); | ||
705 | extern void sock_kfree_s(struct sock *sk, void *mem, int size); | ||
706 | extern void sk_send_sigurg(struct sock *sk); | ||
707 | |||
708 | /* | ||
709 | * Functions to fill in entries in struct proto_ops when a protocol | ||
710 | * does not implement a particular function. | ||
711 | */ | ||
712 | extern int sock_no_bind(struct socket *, | ||
713 | struct sockaddr *, int); | ||
714 | extern int sock_no_connect(struct socket *, | ||
715 | struct sockaddr *, int, int); | ||
716 | extern int sock_no_socketpair(struct socket *, | ||
717 | struct socket *); | ||
718 | extern int sock_no_accept(struct socket *, | ||
719 | struct socket *, int); | ||
720 | extern int sock_no_getname(struct socket *, | ||
721 | struct sockaddr *, int *, int); | ||
722 | extern unsigned int sock_no_poll(struct file *, struct socket *, | ||
723 | struct poll_table_struct *); | ||
724 | extern int sock_no_ioctl(struct socket *, unsigned int, | ||
725 | unsigned long); | ||
726 | extern int sock_no_listen(struct socket *, int); | ||
727 | extern int sock_no_shutdown(struct socket *, int); | ||
728 | extern int sock_no_getsockopt(struct socket *, int , int, | ||
729 | char __user *, int __user *); | ||
730 | extern int sock_no_setsockopt(struct socket *, int, int, | ||
731 | char __user *, int); | ||
732 | extern int sock_no_sendmsg(struct kiocb *, struct socket *, | ||
733 | struct msghdr *, size_t); | ||
734 | extern int sock_no_recvmsg(struct kiocb *, struct socket *, | ||
735 | struct msghdr *, size_t, int); | ||
736 | extern int sock_no_mmap(struct file *file, | ||
737 | struct socket *sock, | ||
738 | struct vm_area_struct *vma); | ||
739 | extern ssize_t sock_no_sendpage(struct socket *sock, | ||
740 | struct page *page, | ||
741 | int offset, size_t size, | ||
742 | int flags); | ||
743 | |||
744 | /* | ||
745 | * Functions to fill in entries in struct proto_ops when a protocol | ||
746 | * uses the inet style. | ||
747 | */ | ||
748 | extern int sock_common_getsockopt(struct socket *sock, int level, int optname, | ||
749 | char __user *optval, int __user *optlen); | ||
750 | extern int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock, | ||
751 | struct msghdr *msg, size_t size, int flags); | ||
752 | extern int sock_common_setsockopt(struct socket *sock, int level, int optname, | ||
753 | char __user *optval, int optlen); | ||
754 | |||
755 | extern void sk_common_release(struct sock *sk); | ||
756 | |||
757 | /* | ||
758 | * Default socket callbacks and setup code | ||
759 | */ | ||
760 | |||
761 | /* Initialise core socket variables */ | ||
762 | extern void sock_init_data(struct socket *sock, struct sock *sk); | ||
763 | |||
764 | /** | ||
765 | * sk_filter - run a packet through a socket filter | ||
766 | * @sk: sock associated with &sk_buff | ||
767 | * @skb: buffer to filter | ||
768 | * @needlock: set to 1 if the sock is not locked by caller. | ||
769 | * | ||
770 | * Run the filter code and then cut skb->data to correct size returned by | ||
771 | * sk_run_filter. If pkt_len is 0 we toss packet. If skb->len is smaller | ||
772 | * than pkt_len we keep whole skb->data. This is the socket level | ||
773 | * wrapper to sk_run_filter. It returns 0 if the packet should | ||
774 | * be accepted or -EPERM if the packet should be tossed. | ||
775 | * | ||
776 | */ | ||
777 | |||
778 | static inline int sk_filter(struct sock *sk, struct sk_buff *skb, int needlock) | ||
779 | { | ||
780 | int err; | ||
781 | |||
782 | err = security_sock_rcv_skb(sk, skb); | ||
783 | if (err) | ||
784 | return err; | ||
785 | |||
786 | if (sk->sk_filter) { | ||
787 | struct sk_filter *filter; | ||
788 | |||
789 | if (needlock) | ||
790 | bh_lock_sock(sk); | ||
791 | |||
792 | filter = sk->sk_filter; | ||
793 | if (filter) { | ||
794 | int pkt_len = sk_run_filter(skb, filter->insns, | ||
795 | filter->len); | ||
796 | if (!pkt_len) | ||
797 | err = -EPERM; | ||
798 | else | ||
799 | skb_trim(skb, pkt_len); | ||
800 | } | ||
801 | |||
802 | if (needlock) | ||
803 | bh_unlock_sock(sk); | ||
804 | } | ||
805 | return err; | ||
806 | } | ||
807 | |||
808 | /** | ||
809 | * sk_filter_release: Release a socket filter | ||
810 | * @sk: socket | ||
811 | * @fp: filter to remove | ||
812 | * | ||
813 | * Remove a filter from a socket and release its resources. | ||
814 | */ | ||
815 | |||
816 | static inline void sk_filter_release(struct sock *sk, struct sk_filter *fp) | ||
817 | { | ||
818 | unsigned int size = sk_filter_len(fp); | ||
819 | |||
820 | atomic_sub(size, &sk->sk_omem_alloc); | ||
821 | |||
822 | if (atomic_dec_and_test(&fp->refcnt)) | ||
823 | kfree(fp); | ||
824 | } | ||
825 | |||
826 | static inline void sk_filter_charge(struct sock *sk, struct sk_filter *fp) | ||
827 | { | ||
828 | atomic_inc(&fp->refcnt); | ||
829 | atomic_add(sk_filter_len(fp), &sk->sk_omem_alloc); | ||
830 | } | ||
831 | |||
832 | /* | ||
833 | * Socket reference counting postulates. | ||
834 | * | ||
835 | * * Each user of socket SHOULD hold a reference count. | ||
836 | * * Each access point to socket (an hash table bucket, reference from a list, | ||
837 | * running timer, skb in flight MUST hold a reference count. | ||
838 | * * When reference count hits 0, it means it will never increase back. | ||
839 | * * When reference count hits 0, it means that no references from | ||
840 | * outside exist to this socket and current process on current CPU | ||
841 | * is last user and may/should destroy this socket. | ||
842 | * * sk_free is called from any context: process, BH, IRQ. When | ||
843 | * it is called, socket has no references from outside -> sk_free | ||
844 | * may release descendant resources allocated by the socket, but | ||
845 | * to the time when it is called, socket is NOT referenced by any | ||
846 | * hash tables, lists etc. | ||
847 | * * Packets, delivered from outside (from network or from another process) | ||
848 | * and enqueued on receive/error queues SHOULD NOT grab reference count, | ||
849 | * when they sit in queue. Otherwise, packets will leak to hole, when | ||
850 | * socket is looked up by one cpu and unhasing is made by another CPU. | ||
851 | * It is true for udp/raw, netlink (leak to receive and error queues), tcp | ||
852 | * (leak to backlog). Packet socket does all the processing inside | ||
853 | * BR_NETPROTO_LOCK, so that it has not this race condition. UNIX sockets | ||
854 | * use separate SMP lock, so that they are prone too. | ||
855 | */ | ||
856 | |||
857 | /* Ungrab socket and destroy it, if it was the last reference. */ | ||
858 | static inline void sock_put(struct sock *sk) | ||
859 | { | ||
860 | if (atomic_dec_and_test(&sk->sk_refcnt)) | ||
861 | sk_free(sk); | ||
862 | } | ||
863 | |||
864 | /* Detach socket from process context. | ||
865 | * Announce socket dead, detach it from wait queue and inode. | ||
866 | * Note that parent inode held reference count on this struct sock, | ||
867 | * we do not release it in this function, because protocol | ||
868 | * probably wants some additional cleanups or even continuing | ||
869 | * to work with this socket (TCP). | ||
870 | */ | ||
871 | static inline void sock_orphan(struct sock *sk) | ||
872 | { | ||
873 | write_lock_bh(&sk->sk_callback_lock); | ||
874 | sock_set_flag(sk, SOCK_DEAD); | ||
875 | sk->sk_socket = NULL; | ||
876 | sk->sk_sleep = NULL; | ||
877 | write_unlock_bh(&sk->sk_callback_lock); | ||
878 | } | ||
879 | |||
880 | static inline void sock_graft(struct sock *sk, struct socket *parent) | ||
881 | { | ||
882 | write_lock_bh(&sk->sk_callback_lock); | ||
883 | sk->sk_sleep = &parent->wait; | ||
884 | parent->sk = sk; | ||
885 | sk->sk_socket = parent; | ||
886 | write_unlock_bh(&sk->sk_callback_lock); | ||
887 | } | ||
888 | |||
889 | extern int sock_i_uid(struct sock *sk); | ||
890 | extern unsigned long sock_i_ino(struct sock *sk); | ||
891 | |||
892 | static inline struct dst_entry * | ||
893 | __sk_dst_get(struct sock *sk) | ||
894 | { | ||
895 | return sk->sk_dst_cache; | ||
896 | } | ||
897 | |||
898 | static inline struct dst_entry * | ||
899 | sk_dst_get(struct sock *sk) | ||
900 | { | ||
901 | struct dst_entry *dst; | ||
902 | |||
903 | read_lock(&sk->sk_dst_lock); | ||
904 | dst = sk->sk_dst_cache; | ||
905 | if (dst) | ||
906 | dst_hold(dst); | ||
907 | read_unlock(&sk->sk_dst_lock); | ||
908 | return dst; | ||
909 | } | ||
910 | |||
911 | static inline void | ||
912 | __sk_dst_set(struct sock *sk, struct dst_entry *dst) | ||
913 | { | ||
914 | struct dst_entry *old_dst; | ||
915 | |||
916 | old_dst = sk->sk_dst_cache; | ||
917 | sk->sk_dst_cache = dst; | ||
918 | dst_release(old_dst); | ||
919 | } | ||
920 | |||
921 | static inline void | ||
922 | sk_dst_set(struct sock *sk, struct dst_entry *dst) | ||
923 | { | ||
924 | write_lock(&sk->sk_dst_lock); | ||
925 | __sk_dst_set(sk, dst); | ||
926 | write_unlock(&sk->sk_dst_lock); | ||
927 | } | ||
928 | |||
929 | static inline void | ||
930 | __sk_dst_reset(struct sock *sk) | ||
931 | { | ||
932 | struct dst_entry *old_dst; | ||
933 | |||
934 | old_dst = sk->sk_dst_cache; | ||
935 | sk->sk_dst_cache = NULL; | ||
936 | dst_release(old_dst); | ||
937 | } | ||
938 | |||
939 | static inline void | ||
940 | sk_dst_reset(struct sock *sk) | ||
941 | { | ||
942 | write_lock(&sk->sk_dst_lock); | ||
943 | __sk_dst_reset(sk); | ||
944 | write_unlock(&sk->sk_dst_lock); | ||
945 | } | ||
946 | |||
947 | static inline struct dst_entry * | ||
948 | __sk_dst_check(struct sock *sk, u32 cookie) | ||
949 | { | ||
950 | struct dst_entry *dst = sk->sk_dst_cache; | ||
951 | |||
952 | if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) { | ||
953 | sk->sk_dst_cache = NULL; | ||
954 | dst_release(dst); | ||
955 | return NULL; | ||
956 | } | ||
957 | |||
958 | return dst; | ||
959 | } | ||
960 | |||
961 | static inline struct dst_entry * | ||
962 | sk_dst_check(struct sock *sk, u32 cookie) | ||
963 | { | ||
964 | struct dst_entry *dst = sk_dst_get(sk); | ||
965 | |||
966 | if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) { | ||
967 | sk_dst_reset(sk); | ||
968 | dst_release(dst); | ||
969 | return NULL; | ||
970 | } | ||
971 | |||
972 | return dst; | ||
973 | } | ||
974 | |||
975 | static inline void sk_charge_skb(struct sock *sk, struct sk_buff *skb) | ||
976 | { | ||
977 | sk->sk_wmem_queued += skb->truesize; | ||
978 | sk->sk_forward_alloc -= skb->truesize; | ||
979 | } | ||
980 | |||
981 | static inline int skb_copy_to_page(struct sock *sk, char __user *from, | ||
982 | struct sk_buff *skb, struct page *page, | ||
983 | int off, int copy) | ||
984 | { | ||
985 | if (skb->ip_summed == CHECKSUM_NONE) { | ||
986 | int err = 0; | ||
987 | unsigned int csum = csum_and_copy_from_user(from, | ||
988 | page_address(page) + off, | ||
989 | copy, 0, &err); | ||
990 | if (err) | ||
991 | return err; | ||
992 | skb->csum = csum_block_add(skb->csum, csum, skb->len); | ||
993 | } else if (copy_from_user(page_address(page) + off, from, copy)) | ||
994 | return -EFAULT; | ||
995 | |||
996 | skb->len += copy; | ||
997 | skb->data_len += copy; | ||
998 | skb->truesize += copy; | ||
999 | sk->sk_wmem_queued += copy; | ||
1000 | sk->sk_forward_alloc -= copy; | ||
1001 | return 0; | ||
1002 | } | ||
1003 | |||
1004 | /* | ||
1005 | * Queue a received datagram if it will fit. Stream and sequenced | ||
1006 | * protocols can't normally use this as they need to fit buffers in | ||
1007 | * and play with them. | ||
1008 | * | ||
1009 | * Inlined as it's very short and called for pretty much every | ||
1010 | * packet ever received. | ||
1011 | */ | ||
1012 | |||
1013 | static inline void skb_set_owner_w(struct sk_buff *skb, struct sock *sk) | ||
1014 | { | ||
1015 | sock_hold(sk); | ||
1016 | skb->sk = sk; | ||
1017 | skb->destructor = sock_wfree; | ||
1018 | atomic_add(skb->truesize, &sk->sk_wmem_alloc); | ||
1019 | } | ||
1020 | |||
1021 | static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk) | ||
1022 | { | ||
1023 | skb->sk = sk; | ||
1024 | skb->destructor = sock_rfree; | ||
1025 | atomic_add(skb->truesize, &sk->sk_rmem_alloc); | ||
1026 | } | ||
1027 | |||
1028 | extern void sk_reset_timer(struct sock *sk, struct timer_list* timer, | ||
1029 | unsigned long expires); | ||
1030 | |||
1031 | extern void sk_stop_timer(struct sock *sk, struct timer_list* timer); | ||
1032 | |||
1033 | static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | ||
1034 | { | ||
1035 | int err = 0; | ||
1036 | int skb_len; | ||
1037 | |||
1038 | /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces | ||
1039 | number of warnings when compiling with -W --ANK | ||
1040 | */ | ||
1041 | if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= | ||
1042 | (unsigned)sk->sk_rcvbuf) { | ||
1043 | err = -ENOMEM; | ||
1044 | goto out; | ||
1045 | } | ||
1046 | |||
1047 | /* It would be deadlock, if sock_queue_rcv_skb is used | ||
1048 | with socket lock! We assume that users of this | ||
1049 | function are lock free. | ||
1050 | */ | ||
1051 | err = sk_filter(sk, skb, 1); | ||
1052 | if (err) | ||
1053 | goto out; | ||
1054 | |||
1055 | skb->dev = NULL; | ||
1056 | skb_set_owner_r(skb, sk); | ||
1057 | |||
1058 | /* Cache the SKB length before we tack it onto the receive | ||
1059 | * queue. Once it is added it no longer belongs to us and | ||
1060 | * may be freed by other threads of control pulling packets | ||
1061 | * from the queue. | ||
1062 | */ | ||
1063 | skb_len = skb->len; | ||
1064 | |||
1065 | skb_queue_tail(&sk->sk_receive_queue, skb); | ||
1066 | |||
1067 | if (!sock_flag(sk, SOCK_DEAD)) | ||
1068 | sk->sk_data_ready(sk, skb_len); | ||
1069 | out: | ||
1070 | return err; | ||
1071 | } | ||
1072 | |||
1073 | static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb) | ||
1074 | { | ||
1075 | /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces | ||
1076 | number of warnings when compiling with -W --ANK | ||
1077 | */ | ||
1078 | if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= | ||
1079 | (unsigned)sk->sk_rcvbuf) | ||
1080 | return -ENOMEM; | ||
1081 | skb_set_owner_r(skb, sk); | ||
1082 | skb_queue_tail(&sk->sk_error_queue, skb); | ||
1083 | if (!sock_flag(sk, SOCK_DEAD)) | ||
1084 | sk->sk_data_ready(sk, skb->len); | ||
1085 | return 0; | ||
1086 | } | ||
1087 | |||
1088 | /* | ||
1089 | * Recover an error report and clear atomically | ||
1090 | */ | ||
1091 | |||
1092 | static inline int sock_error(struct sock *sk) | ||
1093 | { | ||
1094 | int err = xchg(&sk->sk_err, 0); | ||
1095 | return -err; | ||
1096 | } | ||
1097 | |||
1098 | static inline unsigned long sock_wspace(struct sock *sk) | ||
1099 | { | ||
1100 | int amt = 0; | ||
1101 | |||
1102 | if (!(sk->sk_shutdown & SEND_SHUTDOWN)) { | ||
1103 | amt = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | ||
1104 | if (amt < 0) | ||
1105 | amt = 0; | ||
1106 | } | ||
1107 | return amt; | ||
1108 | } | ||
1109 | |||
1110 | static inline void sk_wake_async(struct sock *sk, int how, int band) | ||
1111 | { | ||
1112 | if (sk->sk_socket && sk->sk_socket->fasync_list) | ||
1113 | sock_wake_async(sk->sk_socket, how, band); | ||
1114 | } | ||
1115 | |||
1116 | #define SOCK_MIN_SNDBUF 2048 | ||
1117 | #define SOCK_MIN_RCVBUF 256 | ||
1118 | |||
1119 | static inline void sk_stream_moderate_sndbuf(struct sock *sk) | ||
1120 | { | ||
1121 | if (!(sk->sk_userlocks & SOCK_SNDBUF_LOCK)) { | ||
1122 | sk->sk_sndbuf = min(sk->sk_sndbuf, sk->sk_wmem_queued / 2); | ||
1123 | sk->sk_sndbuf = max(sk->sk_sndbuf, SOCK_MIN_SNDBUF); | ||
1124 | } | ||
1125 | } | ||
1126 | |||
1127 | static inline struct sk_buff *sk_stream_alloc_pskb(struct sock *sk, | ||
1128 | int size, int mem, int gfp) | ||
1129 | { | ||
1130 | struct sk_buff *skb = alloc_skb(size + sk->sk_prot->max_header, gfp); | ||
1131 | |||
1132 | if (skb) { | ||
1133 | skb->truesize += mem; | ||
1134 | if (sk->sk_forward_alloc >= (int)skb->truesize || | ||
1135 | sk_stream_mem_schedule(sk, skb->truesize, 0)) { | ||
1136 | skb_reserve(skb, sk->sk_prot->max_header); | ||
1137 | return skb; | ||
1138 | } | ||
1139 | __kfree_skb(skb); | ||
1140 | } else { | ||
1141 | sk->sk_prot->enter_memory_pressure(); | ||
1142 | sk_stream_moderate_sndbuf(sk); | ||
1143 | } | ||
1144 | return NULL; | ||
1145 | } | ||
1146 | |||
1147 | static inline struct sk_buff *sk_stream_alloc_skb(struct sock *sk, | ||
1148 | int size, int gfp) | ||
1149 | { | ||
1150 | return sk_stream_alloc_pskb(sk, size, 0, gfp); | ||
1151 | } | ||
1152 | |||
1153 | static inline struct page *sk_stream_alloc_page(struct sock *sk) | ||
1154 | { | ||
1155 | struct page *page = NULL; | ||
1156 | |||
1157 | if (sk->sk_forward_alloc >= (int)PAGE_SIZE || | ||
1158 | sk_stream_mem_schedule(sk, PAGE_SIZE, 0)) | ||
1159 | page = alloc_pages(sk->sk_allocation, 0); | ||
1160 | else { | ||
1161 | sk->sk_prot->enter_memory_pressure(); | ||
1162 | sk_stream_moderate_sndbuf(sk); | ||
1163 | } | ||
1164 | return page; | ||
1165 | } | ||
1166 | |||
1167 | #define sk_stream_for_retrans_queue(skb, sk) \ | ||
1168 | for (skb = (sk)->sk_write_queue.next; \ | ||
1169 | (skb != (sk)->sk_send_head) && \ | ||
1170 | (skb != (struct sk_buff *)&(sk)->sk_write_queue); \ | ||
1171 | skb = skb->next) | ||
1172 | |||
1173 | /* | ||
1174 | * Default write policy as shown to user space via poll/select/SIGIO | ||
1175 | */ | ||
1176 | static inline int sock_writeable(const struct sock *sk) | ||
1177 | { | ||
1178 | return atomic_read(&sk->sk_wmem_alloc) < (sk->sk_sndbuf / 2); | ||
1179 | } | ||
1180 | |||
1181 | static inline int gfp_any(void) | ||
1182 | { | ||
1183 | return in_softirq() ? GFP_ATOMIC : GFP_KERNEL; | ||
1184 | } | ||
1185 | |||
1186 | static inline long sock_rcvtimeo(const struct sock *sk, int noblock) | ||
1187 | { | ||
1188 | return noblock ? 0 : sk->sk_rcvtimeo; | ||
1189 | } | ||
1190 | |||
1191 | static inline long sock_sndtimeo(const struct sock *sk, int noblock) | ||
1192 | { | ||
1193 | return noblock ? 0 : sk->sk_sndtimeo; | ||
1194 | } | ||
1195 | |||
1196 | static inline int sock_rcvlowat(const struct sock *sk, int waitall, int len) | ||
1197 | { | ||
1198 | return (waitall ? len : min_t(int, sk->sk_rcvlowat, len)) ? : 1; | ||
1199 | } | ||
1200 | |||
1201 | /* Alas, with timeout socket operations are not restartable. | ||
1202 | * Compare this to poll(). | ||
1203 | */ | ||
1204 | static inline int sock_intr_errno(long timeo) | ||
1205 | { | ||
1206 | return timeo == MAX_SCHEDULE_TIMEOUT ? -ERESTARTSYS : -EINTR; | ||
1207 | } | ||
1208 | |||
1209 | static __inline__ void | ||
1210 | sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) | ||
1211 | { | ||
1212 | struct timeval *stamp = &skb->stamp; | ||
1213 | if (sock_flag(sk, SOCK_RCVTSTAMP)) { | ||
1214 | /* Race occurred between timestamp enabling and packet | ||
1215 | receiving. Fill in the current time for now. */ | ||
1216 | if (stamp->tv_sec == 0) | ||
1217 | do_gettimeofday(stamp); | ||
1218 | put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP, sizeof(struct timeval), | ||
1219 | stamp); | ||
1220 | } else | ||
1221 | sk->sk_stamp = *stamp; | ||
1222 | } | ||
1223 | |||
1224 | /** | ||
1225 | * sk_eat_skb - Release a skb if it is no longer needed | ||
1226 | * @sk - socket to eat this skb from | ||
1227 | * @skb - socket buffer to eat | ||
1228 | * | ||
1229 | * This routine must be called with interrupts disabled or with the socket | ||
1230 | * locked so that the sk_buff queue operation is ok. | ||
1231 | */ | ||
1232 | static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb) | ||
1233 | { | ||
1234 | __skb_unlink(skb, &sk->sk_receive_queue); | ||
1235 | __kfree_skb(skb); | ||
1236 | } | ||
1237 | |||
1238 | extern void sock_enable_timestamp(struct sock *sk); | ||
1239 | extern int sock_get_timestamp(struct sock *, struct timeval __user *); | ||
1240 | |||
1241 | /* | ||
1242 | * Enable debug/info messages | ||
1243 | */ | ||
1244 | |||
1245 | #if 0 | ||
1246 | #define NETDEBUG(x) do { } while (0) | ||
1247 | #define LIMIT_NETDEBUG(x) do {} while(0) | ||
1248 | #else | ||
1249 | #define NETDEBUG(x) do { x; } while (0) | ||
1250 | #define LIMIT_NETDEBUG(x) do { if (net_ratelimit()) { x; } } while(0) | ||
1251 | #endif | ||
1252 | |||
1253 | /* | ||
1254 | * Macros for sleeping on a socket. Use them like this: | ||
1255 | * | ||
1256 | * SOCK_SLEEP_PRE(sk) | ||
1257 | * if (condition) | ||
1258 | * schedule(); | ||
1259 | * SOCK_SLEEP_POST(sk) | ||
1260 | * | ||
1261 | * N.B. These are now obsolete and were, afaik, only ever used in DECnet | ||
1262 | * and when the last use of them in DECnet has gone, I'm intending to | ||
1263 | * remove them. | ||
1264 | */ | ||
1265 | |||
1266 | #define SOCK_SLEEP_PRE(sk) { struct task_struct *tsk = current; \ | ||
1267 | DECLARE_WAITQUEUE(wait, tsk); \ | ||
1268 | tsk->state = TASK_INTERRUPTIBLE; \ | ||
1269 | add_wait_queue((sk)->sk_sleep, &wait); \ | ||
1270 | release_sock(sk); | ||
1271 | |||
1272 | #define SOCK_SLEEP_POST(sk) tsk->state = TASK_RUNNING; \ | ||
1273 | remove_wait_queue((sk)->sk_sleep, &wait); \ | ||
1274 | lock_sock(sk); \ | ||
1275 | } | ||
1276 | |||
1277 | static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool) | ||
1278 | { | ||
1279 | if (valbool) | ||
1280 | sock_set_flag(sk, bit); | ||
1281 | else | ||
1282 | sock_reset_flag(sk, bit); | ||
1283 | } | ||
1284 | |||
1285 | extern __u32 sysctl_wmem_max; | ||
1286 | extern __u32 sysctl_rmem_max; | ||
1287 | |||
1288 | #ifdef CONFIG_NET | ||
1289 | int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); | ||
1290 | #else | ||
1291 | static inline int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
1292 | { | ||
1293 | return -ENODEV; | ||
1294 | } | ||
1295 | #endif | ||
1296 | |||
1297 | #endif /* _SOCK_H */ | ||
diff --git a/include/net/syncppp.h b/include/net/syncppp.h new file mode 100644 index 000000000000..614cb6ba564e --- /dev/null +++ b/include/net/syncppp.h | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | * Defines for synchronous PPP/Cisco link level subroutines. | ||
3 | * | ||
4 | * Copyright (C) 1994 Cronyx Ltd. | ||
5 | * Author: Serge Vakulenko, <vak@zebub.msk.su> | ||
6 | * | ||
7 | * This software is distributed with NO WARRANTIES, not even the implied | ||
8 | * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
9 | * | ||
10 | * Authors grant any other persons or organizations permission to use | ||
11 | * or modify this software as long as this message is kept with the software, | ||
12 | * all derivative works or modified versions. | ||
13 | * | ||
14 | * Version 1.7, Wed Jun 7 22:12:02 MSD 1995 | ||
15 | * | ||
16 | * | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #ifndef _SYNCPPP_H_ | ||
21 | #define _SYNCPPP_H_ 1 | ||
22 | |||
23 | #ifdef __KERNEL__ | ||
24 | struct slcp { | ||
25 | u16 state; /* state machine */ | ||
26 | u32 magic; /* local magic number */ | ||
27 | u_char echoid; /* id of last keepalive echo request */ | ||
28 | u_char confid; /* id of last configuration request */ | ||
29 | }; | ||
30 | |||
31 | struct sipcp { | ||
32 | u16 state; /* state machine */ | ||
33 | u_char confid; /* id of last configuration request */ | ||
34 | }; | ||
35 | |||
36 | struct sppp | ||
37 | { | ||
38 | struct sppp * pp_next; /* next interface in keepalive list */ | ||
39 | u32 pp_flags; /* use Cisco protocol instead of PPP */ | ||
40 | u16 pp_alivecnt; /* keepalive packets counter */ | ||
41 | u16 pp_loopcnt; /* loopback detection counter */ | ||
42 | u32 pp_seq; /* local sequence number */ | ||
43 | u32 pp_rseq; /* remote sequence number */ | ||
44 | struct slcp lcp; /* LCP params */ | ||
45 | struct sipcp ipcp; /* IPCP params */ | ||
46 | u32 ibytes,obytes; /* Bytes in/out */ | ||
47 | u32 ipkts,opkts; /* Packets in/out */ | ||
48 | struct timer_list pp_timer; | ||
49 | struct net_device *pp_if; | ||
50 | char pp_link_state; /* Link status */ | ||
51 | spinlock_t lock; | ||
52 | }; | ||
53 | |||
54 | struct ppp_device | ||
55 | { | ||
56 | struct net_device *dev; /* Network device pointer */ | ||
57 | struct sppp sppp; /* Synchronous PPP */ | ||
58 | }; | ||
59 | |||
60 | static inline struct sppp *sppp_of(struct net_device *dev) | ||
61 | { | ||
62 | struct ppp_device **ppp = dev->priv; | ||
63 | BUG_ON((*ppp)->dev != dev); | ||
64 | return &(*ppp)->sppp; | ||
65 | } | ||
66 | |||
67 | #define PP_KEEPALIVE 0x01 /* use keepalive protocol */ | ||
68 | #define PP_CISCO 0x02 /* use Cisco protocol instead of PPP */ | ||
69 | #define PP_TIMO 0x04 /* cp_timeout routine active */ | ||
70 | #define PP_DEBUG 0x08 | ||
71 | |||
72 | #define PPP_MTU 1500 /* max. transmit unit */ | ||
73 | |||
74 | #define LCP_STATE_CLOSED 0 /* LCP state: closed (conf-req sent) */ | ||
75 | #define LCP_STATE_ACK_RCVD 1 /* LCP state: conf-ack received */ | ||
76 | #define LCP_STATE_ACK_SENT 2 /* LCP state: conf-ack sent */ | ||
77 | #define LCP_STATE_OPENED 3 /* LCP state: opened */ | ||
78 | |||
79 | #define IPCP_STATE_CLOSED 0 /* IPCP state: closed (conf-req sent) */ | ||
80 | #define IPCP_STATE_ACK_RCVD 1 /* IPCP state: conf-ack received */ | ||
81 | #define IPCP_STATE_ACK_SENT 2 /* IPCP state: conf-ack sent */ | ||
82 | #define IPCP_STATE_OPENED 3 /* IPCP state: opened */ | ||
83 | |||
84 | #define SPPP_LINK_DOWN 0 /* link down - no keepalive */ | ||
85 | #define SPPP_LINK_UP 1 /* link is up - keepalive ok */ | ||
86 | |||
87 | void sppp_attach (struct ppp_device *pd); | ||
88 | void sppp_detach (struct net_device *dev); | ||
89 | void sppp_input (struct net_device *dev, struct sk_buff *m); | ||
90 | int sppp_do_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd); | ||
91 | struct sk_buff *sppp_dequeue (struct net_device *dev); | ||
92 | int sppp_isempty (struct net_device *dev); | ||
93 | void sppp_flush (struct net_device *dev); | ||
94 | int sppp_open (struct net_device *dev); | ||
95 | int sppp_reopen (struct net_device *dev); | ||
96 | int sppp_close (struct net_device *dev); | ||
97 | #endif | ||
98 | |||
99 | #define SPPPIOCCISCO (SIOCDEVPRIVATE) | ||
100 | #define SPPPIOCPPP (SIOCDEVPRIVATE+1) | ||
101 | #define SPPPIOCDEBUG (SIOCDEVPRIVATE+2) | ||
102 | #define SPPPIOCSFLAGS (SIOCDEVPRIVATE+3) | ||
103 | #define SPPPIOCGFLAGS (SIOCDEVPRIVATE+4) | ||
104 | |||
105 | #endif /* _SYNCPPP_H_ */ | ||
diff --git a/include/net/tc_act/tc_gact.h b/include/net/tc_act/tc_gact.h new file mode 100644 index 000000000000..59f0d9628ad1 --- /dev/null +++ b/include/net/tc_act/tc_gact.h | |||
@@ -0,0 +1,17 @@ | |||
1 | #ifndef __NET_TC_GACT_H | ||
2 | #define __NET_TC_GACT_H | ||
3 | |||
4 | #include <net/act_api.h> | ||
5 | |||
6 | struct tcf_gact | ||
7 | { | ||
8 | tca_gen(gact); | ||
9 | #ifdef CONFIG_GACT_PROB | ||
10 | u16 ptype; | ||
11 | u16 pval; | ||
12 | int paction; | ||
13 | #endif | ||
14 | |||
15 | }; | ||
16 | |||
17 | #endif | ||
diff --git a/include/net/tc_act/tc_ipt.h b/include/net/tc_act/tc_ipt.h new file mode 100644 index 000000000000..02eccebd55ae --- /dev/null +++ b/include/net/tc_act/tc_ipt.h | |||
@@ -0,0 +1,16 @@ | |||
1 | #ifndef __NET_TC_IPT_H | ||
2 | #define __NET_TC_IPT_H | ||
3 | |||
4 | #include <net/act_api.h> | ||
5 | |||
6 | struct ipt_entry_target; | ||
7 | |||
8 | struct tcf_ipt | ||
9 | { | ||
10 | tca_gen(ipt); | ||
11 | u32 hook; | ||
12 | char *tname; | ||
13 | struct ipt_entry_target *t; | ||
14 | }; | ||
15 | |||
16 | #endif | ||
diff --git a/include/net/tc_act/tc_mirred.h b/include/net/tc_act/tc_mirred.h new file mode 100644 index 000000000000..b5c32f65c12c --- /dev/null +++ b/include/net/tc_act/tc_mirred.h | |||
@@ -0,0 +1,15 @@ | |||
1 | #ifndef __NET_TC_MIR_H | ||
2 | #define __NET_TC_MIR_H | ||
3 | |||
4 | #include <net/act_api.h> | ||
5 | |||
6 | struct tcf_mirred | ||
7 | { | ||
8 | tca_gen(mirred); | ||
9 | int eaction; | ||
10 | int ifindex; | ||
11 | int ok_push; | ||
12 | struct net_device *dev; | ||
13 | }; | ||
14 | |||
15 | #endif | ||
diff --git a/include/net/tc_act/tc_pedit.h b/include/net/tc_act/tc_pedit.h new file mode 100644 index 000000000000..eb21689d759d --- /dev/null +++ b/include/net/tc_act/tc_pedit.h | |||
@@ -0,0 +1,14 @@ | |||
1 | #ifndef __NET_TC_PED_H | ||
2 | #define __NET_TC_PED_H | ||
3 | |||
4 | #include <net/act_api.h> | ||
5 | |||
6 | struct tcf_pedit | ||
7 | { | ||
8 | tca_gen(pedit); | ||
9 | unsigned char nkeys; | ||
10 | unsigned char flags; | ||
11 | struct tc_pedit_key *keys; | ||
12 | }; | ||
13 | |||
14 | #endif | ||
diff --git a/include/net/tcp.h b/include/net/tcp.h new file mode 100644 index 000000000000..503810a70e21 --- /dev/null +++ b/include/net/tcp.h | |||
@@ -0,0 +1,2022 @@ | |||
1 | /* | ||
2 | * INET An implementation of the TCP/IP protocol suite for the LINUX | ||
3 | * operating system. INET is implemented using the BSD Socket | ||
4 | * interface as the means of communication with the user level. | ||
5 | * | ||
6 | * Definitions for the TCP module. | ||
7 | * | ||
8 | * Version: @(#)tcp.h 1.0.5 05/23/93 | ||
9 | * | ||
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | ||
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version | ||
16 | * 2 of the License, or (at your option) any later version. | ||
17 | */ | ||
18 | #ifndef _TCP_H | ||
19 | #define _TCP_H | ||
20 | |||
21 | #define TCP_DEBUG 1 | ||
22 | #define FASTRETRANS_DEBUG 1 | ||
23 | |||
24 | /* Cancel timers, when they are not required. */ | ||
25 | #undef TCP_CLEAR_TIMERS | ||
26 | |||
27 | #include <linux/config.h> | ||
28 | #include <linux/list.h> | ||
29 | #include <linux/tcp.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/cache.h> | ||
32 | #include <linux/percpu.h> | ||
33 | #include <net/checksum.h> | ||
34 | #include <net/sock.h> | ||
35 | #include <net/snmp.h> | ||
36 | #include <net/ip.h> | ||
37 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | ||
38 | #include <linux/ipv6.h> | ||
39 | #endif | ||
40 | #include <linux/seq_file.h> | ||
41 | |||
42 | /* This is for all connections with a full identity, no wildcards. | ||
43 | * New scheme, half the table is for TIME_WAIT, the other half is | ||
44 | * for the rest. I'll experiment with dynamic table growth later. | ||
45 | */ | ||
46 | struct tcp_ehash_bucket { | ||
47 | rwlock_t lock; | ||
48 | struct hlist_head chain; | ||
49 | } __attribute__((__aligned__(8))); | ||
50 | |||
51 | /* This is for listening sockets, thus all sockets which possess wildcards. */ | ||
52 | #define TCP_LHTABLE_SIZE 32 /* Yes, really, this is all you need. */ | ||
53 | |||
54 | /* There are a few simple rules, which allow for local port reuse by | ||
55 | * an application. In essence: | ||
56 | * | ||
57 | * 1) Sockets bound to different interfaces may share a local port. | ||
58 | * Failing that, goto test 2. | ||
59 | * 2) If all sockets have sk->sk_reuse set, and none of them are in | ||
60 | * TCP_LISTEN state, the port may be shared. | ||
61 | * Failing that, goto test 3. | ||
62 | * 3) If all sockets are bound to a specific inet_sk(sk)->rcv_saddr local | ||
63 | * address, and none of them are the same, the port may be | ||
64 | * shared. | ||
65 | * Failing this, the port cannot be shared. | ||
66 | * | ||
67 | * The interesting point, is test #2. This is what an FTP server does | ||
68 | * all day. To optimize this case we use a specific flag bit defined | ||
69 | * below. As we add sockets to a bind bucket list, we perform a | ||
70 | * check of: (newsk->sk_reuse && (newsk->sk_state != TCP_LISTEN)) | ||
71 | * As long as all sockets added to a bind bucket pass this test, | ||
72 | * the flag bit will be set. | ||
73 | * The resulting situation is that tcp_v[46]_verify_bind() can just check | ||
74 | * for this flag bit, if it is set and the socket trying to bind has | ||
75 | * sk->sk_reuse set, we don't even have to walk the owners list at all, | ||
76 | * we return that it is ok to bind this socket to the requested local port. | ||
77 | * | ||
78 | * Sounds like a lot of work, but it is worth it. In a more naive | ||
79 | * implementation (ie. current FreeBSD etc.) the entire list of ports | ||
80 | * must be walked for each data port opened by an ftp server. Needless | ||
81 | * to say, this does not scale at all. With a couple thousand FTP | ||
82 | * users logged onto your box, isn't it nice to know that new data | ||
83 | * ports are created in O(1) time? I thought so. ;-) -DaveM | ||
84 | */ | ||
85 | struct tcp_bind_bucket { | ||
86 | unsigned short port; | ||
87 | signed short fastreuse; | ||
88 | struct hlist_node node; | ||
89 | struct hlist_head owners; | ||
90 | }; | ||
91 | |||
92 | #define tb_for_each(tb, node, head) hlist_for_each_entry(tb, node, head, node) | ||
93 | |||
94 | struct tcp_bind_hashbucket { | ||
95 | spinlock_t lock; | ||
96 | struct hlist_head chain; | ||
97 | }; | ||
98 | |||
99 | static inline struct tcp_bind_bucket *__tb_head(struct tcp_bind_hashbucket *head) | ||
100 | { | ||
101 | return hlist_entry(head->chain.first, struct tcp_bind_bucket, node); | ||
102 | } | ||
103 | |||
104 | static inline struct tcp_bind_bucket *tb_head(struct tcp_bind_hashbucket *head) | ||
105 | { | ||
106 | return hlist_empty(&head->chain) ? NULL : __tb_head(head); | ||
107 | } | ||
108 | |||
109 | extern struct tcp_hashinfo { | ||
110 | /* This is for sockets with full identity only. Sockets here will | ||
111 | * always be without wildcards and will have the following invariant: | ||
112 | * | ||
113 | * TCP_ESTABLISHED <= sk->sk_state < TCP_CLOSE | ||
114 | * | ||
115 | * First half of the table is for sockets not in TIME_WAIT, second half | ||
116 | * is for TIME_WAIT sockets only. | ||
117 | */ | ||
118 | struct tcp_ehash_bucket *__tcp_ehash; | ||
119 | |||
120 | /* Ok, let's try this, I give up, we do need a local binding | ||
121 | * TCP hash as well as the others for fast bind/connect. | ||
122 | */ | ||
123 | struct tcp_bind_hashbucket *__tcp_bhash; | ||
124 | |||
125 | int __tcp_bhash_size; | ||
126 | int __tcp_ehash_size; | ||
127 | |||
128 | /* All sockets in TCP_LISTEN state will be in here. This is the only | ||
129 | * table where wildcard'd TCP sockets can exist. Hash function here | ||
130 | * is just local port number. | ||
131 | */ | ||
132 | struct hlist_head __tcp_listening_hash[TCP_LHTABLE_SIZE]; | ||
133 | |||
134 | /* All the above members are written once at bootup and | ||
135 | * never written again _or_ are predominantly read-access. | ||
136 | * | ||
137 | * Now align to a new cache line as all the following members | ||
138 | * are often dirty. | ||
139 | */ | ||
140 | rwlock_t __tcp_lhash_lock ____cacheline_aligned; | ||
141 | atomic_t __tcp_lhash_users; | ||
142 | wait_queue_head_t __tcp_lhash_wait; | ||
143 | spinlock_t __tcp_portalloc_lock; | ||
144 | } tcp_hashinfo; | ||
145 | |||
146 | #define tcp_ehash (tcp_hashinfo.__tcp_ehash) | ||
147 | #define tcp_bhash (tcp_hashinfo.__tcp_bhash) | ||
148 | #define tcp_ehash_size (tcp_hashinfo.__tcp_ehash_size) | ||
149 | #define tcp_bhash_size (tcp_hashinfo.__tcp_bhash_size) | ||
150 | #define tcp_listening_hash (tcp_hashinfo.__tcp_listening_hash) | ||
151 | #define tcp_lhash_lock (tcp_hashinfo.__tcp_lhash_lock) | ||
152 | #define tcp_lhash_users (tcp_hashinfo.__tcp_lhash_users) | ||
153 | #define tcp_lhash_wait (tcp_hashinfo.__tcp_lhash_wait) | ||
154 | #define tcp_portalloc_lock (tcp_hashinfo.__tcp_portalloc_lock) | ||
155 | |||
156 | extern kmem_cache_t *tcp_bucket_cachep; | ||
157 | extern struct tcp_bind_bucket *tcp_bucket_create(struct tcp_bind_hashbucket *head, | ||
158 | unsigned short snum); | ||
159 | extern void tcp_bucket_destroy(struct tcp_bind_bucket *tb); | ||
160 | extern void tcp_bucket_unlock(struct sock *sk); | ||
161 | extern int tcp_port_rover; | ||
162 | |||
163 | /* These are AF independent. */ | ||
164 | static __inline__ int tcp_bhashfn(__u16 lport) | ||
165 | { | ||
166 | return (lport & (tcp_bhash_size - 1)); | ||
167 | } | ||
168 | |||
169 | extern void tcp_bind_hash(struct sock *sk, struct tcp_bind_bucket *tb, | ||
170 | unsigned short snum); | ||
171 | |||
172 | #if (BITS_PER_LONG == 64) | ||
173 | #define TCP_ADDRCMP_ALIGN_BYTES 8 | ||
174 | #else | ||
175 | #define TCP_ADDRCMP_ALIGN_BYTES 4 | ||
176 | #endif | ||
177 | |||
178 | /* This is a TIME_WAIT bucket. It works around the memory consumption | ||
179 | * problems of sockets in such a state on heavily loaded servers, but | ||
180 | * without violating the protocol specification. | ||
181 | */ | ||
182 | struct tcp_tw_bucket { | ||
183 | /* | ||
184 | * Now struct sock also uses sock_common, so please just | ||
185 | * don't add nothing before this first member (__tw_common) --acme | ||
186 | */ | ||
187 | struct sock_common __tw_common; | ||
188 | #define tw_family __tw_common.skc_family | ||
189 | #define tw_state __tw_common.skc_state | ||
190 | #define tw_reuse __tw_common.skc_reuse | ||
191 | #define tw_bound_dev_if __tw_common.skc_bound_dev_if | ||
192 | #define tw_node __tw_common.skc_node | ||
193 | #define tw_bind_node __tw_common.skc_bind_node | ||
194 | #define tw_refcnt __tw_common.skc_refcnt | ||
195 | volatile unsigned char tw_substate; | ||
196 | unsigned char tw_rcv_wscale; | ||
197 | __u16 tw_sport; | ||
198 | /* Socket demultiplex comparisons on incoming packets. */ | ||
199 | /* these five are in inet_sock */ | ||
200 | __u32 tw_daddr | ||
201 | __attribute__((aligned(TCP_ADDRCMP_ALIGN_BYTES))); | ||
202 | __u32 tw_rcv_saddr; | ||
203 | __u16 tw_dport; | ||
204 | __u16 tw_num; | ||
205 | /* And these are ours. */ | ||
206 | int tw_hashent; | ||
207 | int tw_timeout; | ||
208 | __u32 tw_rcv_nxt; | ||
209 | __u32 tw_snd_nxt; | ||
210 | __u32 tw_rcv_wnd; | ||
211 | __u32 tw_ts_recent; | ||
212 | long tw_ts_recent_stamp; | ||
213 | unsigned long tw_ttd; | ||
214 | struct tcp_bind_bucket *tw_tb; | ||
215 | struct hlist_node tw_death_node; | ||
216 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
217 | struct in6_addr tw_v6_daddr; | ||
218 | struct in6_addr tw_v6_rcv_saddr; | ||
219 | int tw_v6_ipv6only; | ||
220 | #endif | ||
221 | }; | ||
222 | |||
223 | static __inline__ void tw_add_node(struct tcp_tw_bucket *tw, | ||
224 | struct hlist_head *list) | ||
225 | { | ||
226 | hlist_add_head(&tw->tw_node, list); | ||
227 | } | ||
228 | |||
229 | static __inline__ void tw_add_bind_node(struct tcp_tw_bucket *tw, | ||
230 | struct hlist_head *list) | ||
231 | { | ||
232 | hlist_add_head(&tw->tw_bind_node, list); | ||
233 | } | ||
234 | |||
235 | static inline int tw_dead_hashed(struct tcp_tw_bucket *tw) | ||
236 | { | ||
237 | return tw->tw_death_node.pprev != NULL; | ||
238 | } | ||
239 | |||
240 | static __inline__ void tw_dead_node_init(struct tcp_tw_bucket *tw) | ||
241 | { | ||
242 | tw->tw_death_node.pprev = NULL; | ||
243 | } | ||
244 | |||
245 | static __inline__ void __tw_del_dead_node(struct tcp_tw_bucket *tw) | ||
246 | { | ||
247 | __hlist_del(&tw->tw_death_node); | ||
248 | tw_dead_node_init(tw); | ||
249 | } | ||
250 | |||
251 | static __inline__ int tw_del_dead_node(struct tcp_tw_bucket *tw) | ||
252 | { | ||
253 | if (tw_dead_hashed(tw)) { | ||
254 | __tw_del_dead_node(tw); | ||
255 | return 1; | ||
256 | } | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | #define tw_for_each(tw, node, head) \ | ||
261 | hlist_for_each_entry(tw, node, head, tw_node) | ||
262 | |||
263 | #define tw_for_each_inmate(tw, node, jail) \ | ||
264 | hlist_for_each_entry(tw, node, jail, tw_death_node) | ||
265 | |||
266 | #define tw_for_each_inmate_safe(tw, node, safe, jail) \ | ||
267 | hlist_for_each_entry_safe(tw, node, safe, jail, tw_death_node) | ||
268 | |||
269 | #define tcptw_sk(__sk) ((struct tcp_tw_bucket *)(__sk)) | ||
270 | |||
271 | static inline u32 tcp_v4_rcv_saddr(const struct sock *sk) | ||
272 | { | ||
273 | return likely(sk->sk_state != TCP_TIME_WAIT) ? | ||
274 | inet_sk(sk)->rcv_saddr : tcptw_sk(sk)->tw_rcv_saddr; | ||
275 | } | ||
276 | |||
277 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
278 | static inline struct in6_addr *__tcp_v6_rcv_saddr(const struct sock *sk) | ||
279 | { | ||
280 | return likely(sk->sk_state != TCP_TIME_WAIT) ? | ||
281 | &inet6_sk(sk)->rcv_saddr : &tcptw_sk(sk)->tw_v6_rcv_saddr; | ||
282 | } | ||
283 | |||
284 | static inline struct in6_addr *tcp_v6_rcv_saddr(const struct sock *sk) | ||
285 | { | ||
286 | return sk->sk_family == AF_INET6 ? __tcp_v6_rcv_saddr(sk) : NULL; | ||
287 | } | ||
288 | |||
289 | #define tcptw_sk_ipv6only(__sk) (tcptw_sk(__sk)->tw_v6_ipv6only) | ||
290 | |||
291 | static inline int tcp_v6_ipv6only(const struct sock *sk) | ||
292 | { | ||
293 | return likely(sk->sk_state != TCP_TIME_WAIT) ? | ||
294 | ipv6_only_sock(sk) : tcptw_sk_ipv6only(sk); | ||
295 | } | ||
296 | #else | ||
297 | # define __tcp_v6_rcv_saddr(__sk) NULL | ||
298 | # define tcp_v6_rcv_saddr(__sk) NULL | ||
299 | # define tcptw_sk_ipv6only(__sk) 0 | ||
300 | # define tcp_v6_ipv6only(__sk) 0 | ||
301 | #endif | ||
302 | |||
303 | extern kmem_cache_t *tcp_timewait_cachep; | ||
304 | |||
305 | static inline void tcp_tw_put(struct tcp_tw_bucket *tw) | ||
306 | { | ||
307 | if (atomic_dec_and_test(&tw->tw_refcnt)) { | ||
308 | #ifdef INET_REFCNT_DEBUG | ||
309 | printk(KERN_DEBUG "tw_bucket %p released\n", tw); | ||
310 | #endif | ||
311 | kmem_cache_free(tcp_timewait_cachep, tw); | ||
312 | } | ||
313 | } | ||
314 | |||
315 | extern atomic_t tcp_orphan_count; | ||
316 | extern int tcp_tw_count; | ||
317 | extern void tcp_time_wait(struct sock *sk, int state, int timeo); | ||
318 | extern void tcp_tw_deschedule(struct tcp_tw_bucket *tw); | ||
319 | |||
320 | |||
321 | /* Socket demux engine toys. */ | ||
322 | #ifdef __BIG_ENDIAN | ||
323 | #define TCP_COMBINED_PORTS(__sport, __dport) \ | ||
324 | (((__u32)(__sport)<<16) | (__u32)(__dport)) | ||
325 | #else /* __LITTLE_ENDIAN */ | ||
326 | #define TCP_COMBINED_PORTS(__sport, __dport) \ | ||
327 | (((__u32)(__dport)<<16) | (__u32)(__sport)) | ||
328 | #endif | ||
329 | |||
330 | #if (BITS_PER_LONG == 64) | ||
331 | #ifdef __BIG_ENDIAN | ||
332 | #define TCP_V4_ADDR_COOKIE(__name, __saddr, __daddr) \ | ||
333 | __u64 __name = (((__u64)(__saddr))<<32)|((__u64)(__daddr)); | ||
334 | #else /* __LITTLE_ENDIAN */ | ||
335 | #define TCP_V4_ADDR_COOKIE(__name, __saddr, __daddr) \ | ||
336 | __u64 __name = (((__u64)(__daddr))<<32)|((__u64)(__saddr)); | ||
337 | #endif /* __BIG_ENDIAN */ | ||
338 | #define TCP_IPV4_MATCH(__sk, __cookie, __saddr, __daddr, __ports, __dif)\ | ||
339 | (((*((__u64 *)&(inet_sk(__sk)->daddr)))== (__cookie)) && \ | ||
340 | ((*((__u32 *)&(inet_sk(__sk)->dport)))== (__ports)) && \ | ||
341 | (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) | ||
342 | #define TCP_IPV4_TW_MATCH(__sk, __cookie, __saddr, __daddr, __ports, __dif)\ | ||
343 | (((*((__u64 *)&(tcptw_sk(__sk)->tw_daddr))) == (__cookie)) && \ | ||
344 | ((*((__u32 *)&(tcptw_sk(__sk)->tw_dport))) == (__ports)) && \ | ||
345 | (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) | ||
346 | #else /* 32-bit arch */ | ||
347 | #define TCP_V4_ADDR_COOKIE(__name, __saddr, __daddr) | ||
348 | #define TCP_IPV4_MATCH(__sk, __cookie, __saddr, __daddr, __ports, __dif)\ | ||
349 | ((inet_sk(__sk)->daddr == (__saddr)) && \ | ||
350 | (inet_sk(__sk)->rcv_saddr == (__daddr)) && \ | ||
351 | ((*((__u32 *)&(inet_sk(__sk)->dport)))== (__ports)) && \ | ||
352 | (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) | ||
353 | #define TCP_IPV4_TW_MATCH(__sk, __cookie, __saddr, __daddr, __ports, __dif)\ | ||
354 | ((tcptw_sk(__sk)->tw_daddr == (__saddr)) && \ | ||
355 | (tcptw_sk(__sk)->tw_rcv_saddr == (__daddr)) && \ | ||
356 | ((*((__u32 *)&(tcptw_sk(__sk)->tw_dport))) == (__ports)) && \ | ||
357 | (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) | ||
358 | #endif /* 64-bit arch */ | ||
359 | |||
360 | #define TCP_IPV6_MATCH(__sk, __saddr, __daddr, __ports, __dif) \ | ||
361 | (((*((__u32 *)&(inet_sk(__sk)->dport)))== (__ports)) && \ | ||
362 | ((__sk)->sk_family == AF_INET6) && \ | ||
363 | ipv6_addr_equal(&inet6_sk(__sk)->daddr, (__saddr)) && \ | ||
364 | ipv6_addr_equal(&inet6_sk(__sk)->rcv_saddr, (__daddr)) && \ | ||
365 | (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) | ||
366 | |||
367 | /* These can have wildcards, don't try too hard. */ | ||
368 | static __inline__ int tcp_lhashfn(unsigned short num) | ||
369 | { | ||
370 | return num & (TCP_LHTABLE_SIZE - 1); | ||
371 | } | ||
372 | |||
373 | static __inline__ int tcp_sk_listen_hashfn(struct sock *sk) | ||
374 | { | ||
375 | return tcp_lhashfn(inet_sk(sk)->num); | ||
376 | } | ||
377 | |||
378 | #define MAX_TCP_HEADER (128 + MAX_HEADER) | ||
379 | |||
380 | /* | ||
381 | * Never offer a window over 32767 without using window scaling. Some | ||
382 | * poor stacks do signed 16bit maths! | ||
383 | */ | ||
384 | #define MAX_TCP_WINDOW 32767U | ||
385 | |||
386 | /* Minimal accepted MSS. It is (60+60+8) - (20+20). */ | ||
387 | #define TCP_MIN_MSS 88U | ||
388 | |||
389 | /* Minimal RCV_MSS. */ | ||
390 | #define TCP_MIN_RCVMSS 536U | ||
391 | |||
392 | /* After receiving this amount of duplicate ACKs fast retransmit starts. */ | ||
393 | #define TCP_FASTRETRANS_THRESH 3 | ||
394 | |||
395 | /* Maximal reordering. */ | ||
396 | #define TCP_MAX_REORDERING 127 | ||
397 | |||
398 | /* Maximal number of ACKs sent quickly to accelerate slow-start. */ | ||
399 | #define TCP_MAX_QUICKACKS 16U | ||
400 | |||
401 | /* urg_data states */ | ||
402 | #define TCP_URG_VALID 0x0100 | ||
403 | #define TCP_URG_NOTYET 0x0200 | ||
404 | #define TCP_URG_READ 0x0400 | ||
405 | |||
406 | #define TCP_RETR1 3 /* | ||
407 | * This is how many retries it does before it | ||
408 | * tries to figure out if the gateway is | ||
409 | * down. Minimal RFC value is 3; it corresponds | ||
410 | * to ~3sec-8min depending on RTO. | ||
411 | */ | ||
412 | |||
413 | #define TCP_RETR2 15 /* | ||
414 | * This should take at least | ||
415 | * 90 minutes to time out. | ||
416 | * RFC1122 says that the limit is 100 sec. | ||
417 | * 15 is ~13-30min depending on RTO. | ||
418 | */ | ||
419 | |||
420 | #define TCP_SYN_RETRIES 5 /* number of times to retry active opening a | ||
421 | * connection: ~180sec is RFC minumum */ | ||
422 | |||
423 | #define TCP_SYNACK_RETRIES 5 /* number of times to retry passive opening a | ||
424 | * connection: ~180sec is RFC minumum */ | ||
425 | |||
426 | |||
427 | #define TCP_ORPHAN_RETRIES 7 /* number of times to retry on an orphaned | ||
428 | * socket. 7 is ~50sec-16min. | ||
429 | */ | ||
430 | |||
431 | |||
432 | #define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT | ||
433 | * state, about 60 seconds */ | ||
434 | #define TCP_FIN_TIMEOUT TCP_TIMEWAIT_LEN | ||
435 | /* BSD style FIN_WAIT2 deadlock breaker. | ||
436 | * It used to be 3min, new value is 60sec, | ||
437 | * to combine FIN-WAIT-2 timeout with | ||
438 | * TIME-WAIT timer. | ||
439 | */ | ||
440 | |||
441 | #define TCP_DELACK_MAX ((unsigned)(HZ/5)) /* maximal time to delay before sending an ACK */ | ||
442 | #if HZ >= 100 | ||
443 | #define TCP_DELACK_MIN ((unsigned)(HZ/25)) /* minimal time to delay before sending an ACK */ | ||
444 | #define TCP_ATO_MIN ((unsigned)(HZ/25)) | ||
445 | #else | ||
446 | #define TCP_DELACK_MIN 4U | ||
447 | #define TCP_ATO_MIN 4U | ||
448 | #endif | ||
449 | #define TCP_RTO_MAX ((unsigned)(120*HZ)) | ||
450 | #define TCP_RTO_MIN ((unsigned)(HZ/5)) | ||
451 | #define TCP_TIMEOUT_INIT ((unsigned)(3*HZ)) /* RFC 1122 initial RTO value */ | ||
452 | |||
453 | #define TCP_RESOURCE_PROBE_INTERVAL ((unsigned)(HZ/2U)) /* Maximal interval between probes | ||
454 | * for local resources. | ||
455 | */ | ||
456 | |||
457 | #define TCP_KEEPALIVE_TIME (120*60*HZ) /* two hours */ | ||
458 | #define TCP_KEEPALIVE_PROBES 9 /* Max of 9 keepalive probes */ | ||
459 | #define TCP_KEEPALIVE_INTVL (75*HZ) | ||
460 | |||
461 | #define MAX_TCP_KEEPIDLE 32767 | ||
462 | #define MAX_TCP_KEEPINTVL 32767 | ||
463 | #define MAX_TCP_KEEPCNT 127 | ||
464 | #define MAX_TCP_SYNCNT 127 | ||
465 | |||
466 | #define TCP_SYNQ_INTERVAL (HZ/5) /* Period of SYNACK timer */ | ||
467 | #define TCP_SYNQ_HSIZE 512 /* Size of SYNACK hash table */ | ||
468 | |||
469 | #define TCP_PAWS_24DAYS (60 * 60 * 24 * 24) | ||
470 | #define TCP_PAWS_MSL 60 /* Per-host timestamps are invalidated | ||
471 | * after this time. It should be equal | ||
472 | * (or greater than) TCP_TIMEWAIT_LEN | ||
473 | * to provide reliability equal to one | ||
474 | * provided by timewait state. | ||
475 | */ | ||
476 | #define TCP_PAWS_WINDOW 1 /* Replay window for per-host | ||
477 | * timestamps. It must be less than | ||
478 | * minimal timewait lifetime. | ||
479 | */ | ||
480 | |||
481 | #define TCP_TW_RECYCLE_SLOTS_LOG 5 | ||
482 | #define TCP_TW_RECYCLE_SLOTS (1<<TCP_TW_RECYCLE_SLOTS_LOG) | ||
483 | |||
484 | /* If time > 4sec, it is "slow" path, no recycling is required, | ||
485 | so that we select tick to get range about 4 seconds. | ||
486 | */ | ||
487 | |||
488 | #if HZ <= 16 || HZ > 4096 | ||
489 | # error Unsupported: HZ <= 16 or HZ > 4096 | ||
490 | #elif HZ <= 32 | ||
491 | # define TCP_TW_RECYCLE_TICK (5+2-TCP_TW_RECYCLE_SLOTS_LOG) | ||
492 | #elif HZ <= 64 | ||
493 | # define TCP_TW_RECYCLE_TICK (6+2-TCP_TW_RECYCLE_SLOTS_LOG) | ||
494 | #elif HZ <= 128 | ||
495 | # define TCP_TW_RECYCLE_TICK (7+2-TCP_TW_RECYCLE_SLOTS_LOG) | ||
496 | #elif HZ <= 256 | ||
497 | # define TCP_TW_RECYCLE_TICK (8+2-TCP_TW_RECYCLE_SLOTS_LOG) | ||
498 | #elif HZ <= 512 | ||
499 | # define TCP_TW_RECYCLE_TICK (9+2-TCP_TW_RECYCLE_SLOTS_LOG) | ||
500 | #elif HZ <= 1024 | ||
501 | # define TCP_TW_RECYCLE_TICK (10+2-TCP_TW_RECYCLE_SLOTS_LOG) | ||
502 | #elif HZ <= 2048 | ||
503 | # define TCP_TW_RECYCLE_TICK (11+2-TCP_TW_RECYCLE_SLOTS_LOG) | ||
504 | #else | ||
505 | # define TCP_TW_RECYCLE_TICK (12+2-TCP_TW_RECYCLE_SLOTS_LOG) | ||
506 | #endif | ||
507 | |||
508 | #define BICTCP_BETA_SCALE 1024 /* Scale factor beta calculation | ||
509 | * max_cwnd = snd_cwnd * beta | ||
510 | */ | ||
511 | #define BICTCP_MAX_INCREMENT 32 /* | ||
512 | * Limit on the amount of | ||
513 | * increment allowed during | ||
514 | * binary search. | ||
515 | */ | ||
516 | #define BICTCP_FUNC_OF_MIN_INCR 11 /* | ||
517 | * log(B/Smin)/log(B/(B-1))+1, | ||
518 | * Smin:min increment | ||
519 | * B:log factor | ||
520 | */ | ||
521 | #define BICTCP_B 4 /* | ||
522 | * In binary search, | ||
523 | * go to point (max+min)/N | ||
524 | */ | ||
525 | |||
526 | /* | ||
527 | * TCP option | ||
528 | */ | ||
529 | |||
530 | #define TCPOPT_NOP 1 /* Padding */ | ||
531 | #define TCPOPT_EOL 0 /* End of options */ | ||
532 | #define TCPOPT_MSS 2 /* Segment size negotiating */ | ||
533 | #define TCPOPT_WINDOW 3 /* Window scaling */ | ||
534 | #define TCPOPT_SACK_PERM 4 /* SACK Permitted */ | ||
535 | #define TCPOPT_SACK 5 /* SACK Block */ | ||
536 | #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ | ||
537 | |||
538 | /* | ||
539 | * TCP option lengths | ||
540 | */ | ||
541 | |||
542 | #define TCPOLEN_MSS 4 | ||
543 | #define TCPOLEN_WINDOW 3 | ||
544 | #define TCPOLEN_SACK_PERM 2 | ||
545 | #define TCPOLEN_TIMESTAMP 10 | ||
546 | |||
547 | /* But this is what stacks really send out. */ | ||
548 | #define TCPOLEN_TSTAMP_ALIGNED 12 | ||
549 | #define TCPOLEN_WSCALE_ALIGNED 4 | ||
550 | #define TCPOLEN_SACKPERM_ALIGNED 4 | ||
551 | #define TCPOLEN_SACK_BASE 2 | ||
552 | #define TCPOLEN_SACK_BASE_ALIGNED 4 | ||
553 | #define TCPOLEN_SACK_PERBLOCK 8 | ||
554 | |||
555 | #define TCP_TIME_RETRANS 1 /* Retransmit timer */ | ||
556 | #define TCP_TIME_DACK 2 /* Delayed ack timer */ | ||
557 | #define TCP_TIME_PROBE0 3 /* Zero window probe timer */ | ||
558 | #define TCP_TIME_KEEPOPEN 4 /* Keepalive timer */ | ||
559 | |||
560 | /* Flags in tp->nonagle */ | ||
561 | #define TCP_NAGLE_OFF 1 /* Nagle's algo is disabled */ | ||
562 | #define TCP_NAGLE_CORK 2 /* Socket is corked */ | ||
563 | #define TCP_NAGLE_PUSH 4 /* Cork is overriden for already queued data */ | ||
564 | |||
565 | /* sysctl variables for tcp */ | ||
566 | extern int sysctl_max_syn_backlog; | ||
567 | extern int sysctl_tcp_timestamps; | ||
568 | extern int sysctl_tcp_window_scaling; | ||
569 | extern int sysctl_tcp_sack; | ||
570 | extern int sysctl_tcp_fin_timeout; | ||
571 | extern int sysctl_tcp_tw_recycle; | ||
572 | extern int sysctl_tcp_keepalive_time; | ||
573 | extern int sysctl_tcp_keepalive_probes; | ||
574 | extern int sysctl_tcp_keepalive_intvl; | ||
575 | extern int sysctl_tcp_syn_retries; | ||
576 | extern int sysctl_tcp_synack_retries; | ||
577 | extern int sysctl_tcp_retries1; | ||
578 | extern int sysctl_tcp_retries2; | ||
579 | extern int sysctl_tcp_orphan_retries; | ||
580 | extern int sysctl_tcp_syncookies; | ||
581 | extern int sysctl_tcp_retrans_collapse; | ||
582 | extern int sysctl_tcp_stdurg; | ||
583 | extern int sysctl_tcp_rfc1337; | ||
584 | extern int sysctl_tcp_abort_on_overflow; | ||
585 | extern int sysctl_tcp_max_orphans; | ||
586 | extern int sysctl_tcp_max_tw_buckets; | ||
587 | extern int sysctl_tcp_fack; | ||
588 | extern int sysctl_tcp_reordering; | ||
589 | extern int sysctl_tcp_ecn; | ||
590 | extern int sysctl_tcp_dsack; | ||
591 | extern int sysctl_tcp_mem[3]; | ||
592 | extern int sysctl_tcp_wmem[3]; | ||
593 | extern int sysctl_tcp_rmem[3]; | ||
594 | extern int sysctl_tcp_app_win; | ||
595 | extern int sysctl_tcp_adv_win_scale; | ||
596 | extern int sysctl_tcp_tw_reuse; | ||
597 | extern int sysctl_tcp_frto; | ||
598 | extern int sysctl_tcp_low_latency; | ||
599 | extern int sysctl_tcp_westwood; | ||
600 | extern int sysctl_tcp_vegas_cong_avoid; | ||
601 | extern int sysctl_tcp_vegas_alpha; | ||
602 | extern int sysctl_tcp_vegas_beta; | ||
603 | extern int sysctl_tcp_vegas_gamma; | ||
604 | extern int sysctl_tcp_nometrics_save; | ||
605 | extern int sysctl_tcp_bic; | ||
606 | extern int sysctl_tcp_bic_fast_convergence; | ||
607 | extern int sysctl_tcp_bic_low_window; | ||
608 | extern int sysctl_tcp_bic_beta; | ||
609 | extern int sysctl_tcp_moderate_rcvbuf; | ||
610 | extern int sysctl_tcp_tso_win_divisor; | ||
611 | |||
612 | extern atomic_t tcp_memory_allocated; | ||
613 | extern atomic_t tcp_sockets_allocated; | ||
614 | extern int tcp_memory_pressure; | ||
615 | |||
616 | struct open_request; | ||
617 | |||
618 | struct or_calltable { | ||
619 | int family; | ||
620 | int (*rtx_syn_ack) (struct sock *sk, struct open_request *req, struct dst_entry*); | ||
621 | void (*send_ack) (struct sk_buff *skb, struct open_request *req); | ||
622 | void (*destructor) (struct open_request *req); | ||
623 | void (*send_reset) (struct sk_buff *skb); | ||
624 | }; | ||
625 | |||
626 | struct tcp_v4_open_req { | ||
627 | __u32 loc_addr; | ||
628 | __u32 rmt_addr; | ||
629 | struct ip_options *opt; | ||
630 | }; | ||
631 | |||
632 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | ||
633 | struct tcp_v6_open_req { | ||
634 | struct in6_addr loc_addr; | ||
635 | struct in6_addr rmt_addr; | ||
636 | struct sk_buff *pktopts; | ||
637 | int iif; | ||
638 | }; | ||
639 | #endif | ||
640 | |||
641 | /* this structure is too big */ | ||
642 | struct open_request { | ||
643 | struct open_request *dl_next; /* Must be first member! */ | ||
644 | __u32 rcv_isn; | ||
645 | __u32 snt_isn; | ||
646 | __u16 rmt_port; | ||
647 | __u16 mss; | ||
648 | __u8 retrans; | ||
649 | __u8 __pad; | ||
650 | __u16 snd_wscale : 4, | ||
651 | rcv_wscale : 4, | ||
652 | tstamp_ok : 1, | ||
653 | sack_ok : 1, | ||
654 | wscale_ok : 1, | ||
655 | ecn_ok : 1, | ||
656 | acked : 1; | ||
657 | /* The following two fields can be easily recomputed I think -AK */ | ||
658 | __u32 window_clamp; /* window clamp at creation time */ | ||
659 | __u32 rcv_wnd; /* rcv_wnd offered first time */ | ||
660 | __u32 ts_recent; | ||
661 | unsigned long expires; | ||
662 | struct or_calltable *class; | ||
663 | struct sock *sk; | ||
664 | union { | ||
665 | struct tcp_v4_open_req v4_req; | ||
666 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | ||
667 | struct tcp_v6_open_req v6_req; | ||
668 | #endif | ||
669 | } af; | ||
670 | }; | ||
671 | |||
672 | /* SLAB cache for open requests. */ | ||
673 | extern kmem_cache_t *tcp_openreq_cachep; | ||
674 | |||
675 | #define tcp_openreq_alloc() kmem_cache_alloc(tcp_openreq_cachep, SLAB_ATOMIC) | ||
676 | #define tcp_openreq_fastfree(req) kmem_cache_free(tcp_openreq_cachep, req) | ||
677 | |||
678 | static inline void tcp_openreq_free(struct open_request *req) | ||
679 | { | ||
680 | req->class->destructor(req); | ||
681 | tcp_openreq_fastfree(req); | ||
682 | } | ||
683 | |||
684 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
685 | #define TCP_INET_FAMILY(fam) ((fam) == AF_INET) | ||
686 | #else | ||
687 | #define TCP_INET_FAMILY(fam) 1 | ||
688 | #endif | ||
689 | |||
690 | /* | ||
691 | * Pointers to address related TCP functions | ||
692 | * (i.e. things that depend on the address family) | ||
693 | */ | ||
694 | |||
695 | struct tcp_func { | ||
696 | int (*queue_xmit) (struct sk_buff *skb, | ||
697 | int ipfragok); | ||
698 | |||
699 | void (*send_check) (struct sock *sk, | ||
700 | struct tcphdr *th, | ||
701 | int len, | ||
702 | struct sk_buff *skb); | ||
703 | |||
704 | int (*rebuild_header) (struct sock *sk); | ||
705 | |||
706 | int (*conn_request) (struct sock *sk, | ||
707 | struct sk_buff *skb); | ||
708 | |||
709 | struct sock * (*syn_recv_sock) (struct sock *sk, | ||
710 | struct sk_buff *skb, | ||
711 | struct open_request *req, | ||
712 | struct dst_entry *dst); | ||
713 | |||
714 | int (*remember_stamp) (struct sock *sk); | ||
715 | |||
716 | __u16 net_header_len; | ||
717 | |||
718 | int (*setsockopt) (struct sock *sk, | ||
719 | int level, | ||
720 | int optname, | ||
721 | char __user *optval, | ||
722 | int optlen); | ||
723 | |||
724 | int (*getsockopt) (struct sock *sk, | ||
725 | int level, | ||
726 | int optname, | ||
727 | char __user *optval, | ||
728 | int __user *optlen); | ||
729 | |||
730 | |||
731 | void (*addr2sockaddr) (struct sock *sk, | ||
732 | struct sockaddr *); | ||
733 | |||
734 | int sockaddr_len; | ||
735 | }; | ||
736 | |||
737 | /* | ||
738 | * The next routines deal with comparing 32 bit unsigned ints | ||
739 | * and worry about wraparound (automatic with unsigned arithmetic). | ||
740 | */ | ||
741 | |||
742 | static inline int before(__u32 seq1, __u32 seq2) | ||
743 | { | ||
744 | return (__s32)(seq1-seq2) < 0; | ||
745 | } | ||
746 | |||
747 | static inline int after(__u32 seq1, __u32 seq2) | ||
748 | { | ||
749 | return (__s32)(seq2-seq1) < 0; | ||
750 | } | ||
751 | |||
752 | |||
753 | /* is s2<=s1<=s3 ? */ | ||
754 | static inline int between(__u32 seq1, __u32 seq2, __u32 seq3) | ||
755 | { | ||
756 | return seq3 - seq2 >= seq1 - seq2; | ||
757 | } | ||
758 | |||
759 | |||
760 | extern struct proto tcp_prot; | ||
761 | |||
762 | DECLARE_SNMP_STAT(struct tcp_mib, tcp_statistics); | ||
763 | #define TCP_INC_STATS(field) SNMP_INC_STATS(tcp_statistics, field) | ||
764 | #define TCP_INC_STATS_BH(field) SNMP_INC_STATS_BH(tcp_statistics, field) | ||
765 | #define TCP_INC_STATS_USER(field) SNMP_INC_STATS_USER(tcp_statistics, field) | ||
766 | #define TCP_DEC_STATS(field) SNMP_DEC_STATS(tcp_statistics, field) | ||
767 | #define TCP_ADD_STATS_BH(field, val) SNMP_ADD_STATS_BH(tcp_statistics, field, val) | ||
768 | #define TCP_ADD_STATS_USER(field, val) SNMP_ADD_STATS_USER(tcp_statistics, field, val) | ||
769 | |||
770 | extern void tcp_put_port(struct sock *sk); | ||
771 | extern void tcp_inherit_port(struct sock *sk, struct sock *child); | ||
772 | |||
773 | extern void tcp_v4_err(struct sk_buff *skb, u32); | ||
774 | |||
775 | extern void tcp_shutdown (struct sock *sk, int how); | ||
776 | |||
777 | extern int tcp_v4_rcv(struct sk_buff *skb); | ||
778 | |||
779 | extern int tcp_v4_remember_stamp(struct sock *sk); | ||
780 | |||
781 | extern int tcp_v4_tw_remember_stamp(struct tcp_tw_bucket *tw); | ||
782 | |||
783 | extern int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, | ||
784 | struct msghdr *msg, size_t size); | ||
785 | extern ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags); | ||
786 | |||
787 | extern int tcp_ioctl(struct sock *sk, | ||
788 | int cmd, | ||
789 | unsigned long arg); | ||
790 | |||
791 | extern int tcp_rcv_state_process(struct sock *sk, | ||
792 | struct sk_buff *skb, | ||
793 | struct tcphdr *th, | ||
794 | unsigned len); | ||
795 | |||
796 | extern int tcp_rcv_established(struct sock *sk, | ||
797 | struct sk_buff *skb, | ||
798 | struct tcphdr *th, | ||
799 | unsigned len); | ||
800 | |||
801 | extern void tcp_rcv_space_adjust(struct sock *sk); | ||
802 | |||
803 | enum tcp_ack_state_t | ||
804 | { | ||
805 | TCP_ACK_SCHED = 1, | ||
806 | TCP_ACK_TIMER = 2, | ||
807 | TCP_ACK_PUSHED= 4 | ||
808 | }; | ||
809 | |||
810 | static inline void tcp_schedule_ack(struct tcp_sock *tp) | ||
811 | { | ||
812 | tp->ack.pending |= TCP_ACK_SCHED; | ||
813 | } | ||
814 | |||
815 | static inline int tcp_ack_scheduled(struct tcp_sock *tp) | ||
816 | { | ||
817 | return tp->ack.pending&TCP_ACK_SCHED; | ||
818 | } | ||
819 | |||
820 | static __inline__ void tcp_dec_quickack_mode(struct tcp_sock *tp) | ||
821 | { | ||
822 | if (tp->ack.quick && --tp->ack.quick == 0) { | ||
823 | /* Leaving quickack mode we deflate ATO. */ | ||
824 | tp->ack.ato = TCP_ATO_MIN; | ||
825 | } | ||
826 | } | ||
827 | |||
828 | extern void tcp_enter_quickack_mode(struct tcp_sock *tp); | ||
829 | |||
830 | static __inline__ void tcp_delack_init(struct tcp_sock *tp) | ||
831 | { | ||
832 | memset(&tp->ack, 0, sizeof(tp->ack)); | ||
833 | } | ||
834 | |||
835 | static inline void tcp_clear_options(struct tcp_options_received *rx_opt) | ||
836 | { | ||
837 | rx_opt->tstamp_ok = rx_opt->sack_ok = rx_opt->wscale_ok = rx_opt->snd_wscale = 0; | ||
838 | } | ||
839 | |||
840 | enum tcp_tw_status | ||
841 | { | ||
842 | TCP_TW_SUCCESS = 0, | ||
843 | TCP_TW_RST = 1, | ||
844 | TCP_TW_ACK = 2, | ||
845 | TCP_TW_SYN = 3 | ||
846 | }; | ||
847 | |||
848 | |||
849 | extern enum tcp_tw_status tcp_timewait_state_process(struct tcp_tw_bucket *tw, | ||
850 | struct sk_buff *skb, | ||
851 | struct tcphdr *th, | ||
852 | unsigned len); | ||
853 | |||
854 | extern struct sock * tcp_check_req(struct sock *sk,struct sk_buff *skb, | ||
855 | struct open_request *req, | ||
856 | struct open_request **prev); | ||
857 | extern int tcp_child_process(struct sock *parent, | ||
858 | struct sock *child, | ||
859 | struct sk_buff *skb); | ||
860 | extern void tcp_enter_frto(struct sock *sk); | ||
861 | extern void tcp_enter_loss(struct sock *sk, int how); | ||
862 | extern void tcp_clear_retrans(struct tcp_sock *tp); | ||
863 | extern void tcp_update_metrics(struct sock *sk); | ||
864 | |||
865 | extern void tcp_close(struct sock *sk, | ||
866 | long timeout); | ||
867 | extern struct sock * tcp_accept(struct sock *sk, int flags, int *err); | ||
868 | extern unsigned int tcp_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait); | ||
869 | |||
870 | extern int tcp_getsockopt(struct sock *sk, int level, | ||
871 | int optname, | ||
872 | char __user *optval, | ||
873 | int __user *optlen); | ||
874 | extern int tcp_setsockopt(struct sock *sk, int level, | ||
875 | int optname, char __user *optval, | ||
876 | int optlen); | ||
877 | extern void tcp_set_keepalive(struct sock *sk, int val); | ||
878 | extern int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, | ||
879 | struct msghdr *msg, | ||
880 | size_t len, int nonblock, | ||
881 | int flags, int *addr_len); | ||
882 | |||
883 | extern int tcp_listen_start(struct sock *sk); | ||
884 | |||
885 | extern void tcp_parse_options(struct sk_buff *skb, | ||
886 | struct tcp_options_received *opt_rx, | ||
887 | int estab); | ||
888 | |||
889 | /* | ||
890 | * TCP v4 functions exported for the inet6 API | ||
891 | */ | ||
892 | |||
893 | extern int tcp_v4_rebuild_header(struct sock *sk); | ||
894 | |||
895 | extern int tcp_v4_build_header(struct sock *sk, | ||
896 | struct sk_buff *skb); | ||
897 | |||
898 | extern void tcp_v4_send_check(struct sock *sk, | ||
899 | struct tcphdr *th, int len, | ||
900 | struct sk_buff *skb); | ||
901 | |||
902 | extern int tcp_v4_conn_request(struct sock *sk, | ||
903 | struct sk_buff *skb); | ||
904 | |||
905 | extern struct sock * tcp_create_openreq_child(struct sock *sk, | ||
906 | struct open_request *req, | ||
907 | struct sk_buff *skb); | ||
908 | |||
909 | extern struct sock * tcp_v4_syn_recv_sock(struct sock *sk, | ||
910 | struct sk_buff *skb, | ||
911 | struct open_request *req, | ||
912 | struct dst_entry *dst); | ||
913 | |||
914 | extern int tcp_v4_do_rcv(struct sock *sk, | ||
915 | struct sk_buff *skb); | ||
916 | |||
917 | extern int tcp_v4_connect(struct sock *sk, | ||
918 | struct sockaddr *uaddr, | ||
919 | int addr_len); | ||
920 | |||
921 | extern int tcp_connect(struct sock *sk); | ||
922 | |||
923 | extern struct sk_buff * tcp_make_synack(struct sock *sk, | ||
924 | struct dst_entry *dst, | ||
925 | struct open_request *req); | ||
926 | |||
927 | extern int tcp_disconnect(struct sock *sk, int flags); | ||
928 | |||
929 | extern void tcp_unhash(struct sock *sk); | ||
930 | |||
931 | extern int tcp_v4_hash_connecting(struct sock *sk); | ||
932 | |||
933 | |||
934 | /* From syncookies.c */ | ||
935 | extern struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | ||
936 | struct ip_options *opt); | ||
937 | extern __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, | ||
938 | __u16 *mss); | ||
939 | |||
940 | /* tcp_output.c */ | ||
941 | |||
942 | extern int tcp_write_xmit(struct sock *, int nonagle); | ||
943 | extern int tcp_retransmit_skb(struct sock *, struct sk_buff *); | ||
944 | extern void tcp_xmit_retransmit_queue(struct sock *); | ||
945 | extern void tcp_simple_retransmit(struct sock *); | ||
946 | extern int tcp_trim_head(struct sock *, struct sk_buff *, u32); | ||
947 | |||
948 | extern void tcp_send_probe0(struct sock *); | ||
949 | extern void tcp_send_partial(struct sock *); | ||
950 | extern int tcp_write_wakeup(struct sock *); | ||
951 | extern void tcp_send_fin(struct sock *sk); | ||
952 | extern void tcp_send_active_reset(struct sock *sk, int priority); | ||
953 | extern int tcp_send_synack(struct sock *); | ||
954 | extern void tcp_push_one(struct sock *, unsigned mss_now); | ||
955 | extern void tcp_send_ack(struct sock *sk); | ||
956 | extern void tcp_send_delayed_ack(struct sock *sk); | ||
957 | |||
958 | /* tcp_timer.c */ | ||
959 | extern void tcp_init_xmit_timers(struct sock *); | ||
960 | extern void tcp_clear_xmit_timers(struct sock *); | ||
961 | |||
962 | extern void tcp_delete_keepalive_timer(struct sock *); | ||
963 | extern void tcp_reset_keepalive_timer(struct sock *, unsigned long); | ||
964 | extern unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu); | ||
965 | extern unsigned int tcp_current_mss(struct sock *sk, int large); | ||
966 | |||
967 | #ifdef TCP_DEBUG | ||
968 | extern const char tcp_timer_bug_msg[]; | ||
969 | #endif | ||
970 | |||
971 | /* tcp_diag.c */ | ||
972 | extern void tcp_get_info(struct sock *, struct tcp_info *); | ||
973 | |||
974 | /* Read 'sendfile()'-style from a TCP socket */ | ||
975 | typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *, | ||
976 | unsigned int, size_t); | ||
977 | extern int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, | ||
978 | sk_read_actor_t recv_actor); | ||
979 | |||
980 | static inline void tcp_clear_xmit_timer(struct sock *sk, int what) | ||
981 | { | ||
982 | struct tcp_sock *tp = tcp_sk(sk); | ||
983 | |||
984 | switch (what) { | ||
985 | case TCP_TIME_RETRANS: | ||
986 | case TCP_TIME_PROBE0: | ||
987 | tp->pending = 0; | ||
988 | |||
989 | #ifdef TCP_CLEAR_TIMERS | ||
990 | sk_stop_timer(sk, &tp->retransmit_timer); | ||
991 | #endif | ||
992 | break; | ||
993 | case TCP_TIME_DACK: | ||
994 | tp->ack.blocked = 0; | ||
995 | tp->ack.pending = 0; | ||
996 | |||
997 | #ifdef TCP_CLEAR_TIMERS | ||
998 | sk_stop_timer(sk, &tp->delack_timer); | ||
999 | #endif | ||
1000 | break; | ||
1001 | default: | ||
1002 | #ifdef TCP_DEBUG | ||
1003 | printk(tcp_timer_bug_msg); | ||
1004 | #endif | ||
1005 | return; | ||
1006 | }; | ||
1007 | |||
1008 | } | ||
1009 | |||
1010 | /* | ||
1011 | * Reset the retransmission timer | ||
1012 | */ | ||
1013 | static inline void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long when) | ||
1014 | { | ||
1015 | struct tcp_sock *tp = tcp_sk(sk); | ||
1016 | |||
1017 | if (when > TCP_RTO_MAX) { | ||
1018 | #ifdef TCP_DEBUG | ||
1019 | printk(KERN_DEBUG "reset_xmit_timer sk=%p %d when=0x%lx, caller=%p\n", sk, what, when, current_text_addr()); | ||
1020 | #endif | ||
1021 | when = TCP_RTO_MAX; | ||
1022 | } | ||
1023 | |||
1024 | switch (what) { | ||
1025 | case TCP_TIME_RETRANS: | ||
1026 | case TCP_TIME_PROBE0: | ||
1027 | tp->pending = what; | ||
1028 | tp->timeout = jiffies+when; | ||
1029 | sk_reset_timer(sk, &tp->retransmit_timer, tp->timeout); | ||
1030 | break; | ||
1031 | |||
1032 | case TCP_TIME_DACK: | ||
1033 | tp->ack.pending |= TCP_ACK_TIMER; | ||
1034 | tp->ack.timeout = jiffies+when; | ||
1035 | sk_reset_timer(sk, &tp->delack_timer, tp->ack.timeout); | ||
1036 | break; | ||
1037 | |||
1038 | default: | ||
1039 | #ifdef TCP_DEBUG | ||
1040 | printk(tcp_timer_bug_msg); | ||
1041 | #endif | ||
1042 | return; | ||
1043 | }; | ||
1044 | } | ||
1045 | |||
1046 | /* Initialize RCV_MSS value. | ||
1047 | * RCV_MSS is an our guess about MSS used by the peer. | ||
1048 | * We haven't any direct information about the MSS. | ||
1049 | * It's better to underestimate the RCV_MSS rather than overestimate. | ||
1050 | * Overestimations make us ACKing less frequently than needed. | ||
1051 | * Underestimations are more easy to detect and fix by tcp_measure_rcv_mss(). | ||
1052 | */ | ||
1053 | |||
1054 | static inline void tcp_initialize_rcv_mss(struct sock *sk) | ||
1055 | { | ||
1056 | struct tcp_sock *tp = tcp_sk(sk); | ||
1057 | unsigned int hint = min(tp->advmss, tp->mss_cache_std); | ||
1058 | |||
1059 | hint = min(hint, tp->rcv_wnd/2); | ||
1060 | hint = min(hint, TCP_MIN_RCVMSS); | ||
1061 | hint = max(hint, TCP_MIN_MSS); | ||
1062 | |||
1063 | tp->ack.rcv_mss = hint; | ||
1064 | } | ||
1065 | |||
1066 | static __inline__ void __tcp_fast_path_on(struct tcp_sock *tp, u32 snd_wnd) | ||
1067 | { | ||
1068 | tp->pred_flags = htonl((tp->tcp_header_len << 26) | | ||
1069 | ntohl(TCP_FLAG_ACK) | | ||
1070 | snd_wnd); | ||
1071 | } | ||
1072 | |||
1073 | static __inline__ void tcp_fast_path_on(struct tcp_sock *tp) | ||
1074 | { | ||
1075 | __tcp_fast_path_on(tp, tp->snd_wnd >> tp->rx_opt.snd_wscale); | ||
1076 | } | ||
1077 | |||
1078 | static inline void tcp_fast_path_check(struct sock *sk, struct tcp_sock *tp) | ||
1079 | { | ||
1080 | if (skb_queue_len(&tp->out_of_order_queue) == 0 && | ||
1081 | tp->rcv_wnd && | ||
1082 | atomic_read(&sk->sk_rmem_alloc) < sk->sk_rcvbuf && | ||
1083 | !tp->urg_data) | ||
1084 | tcp_fast_path_on(tp); | ||
1085 | } | ||
1086 | |||
1087 | /* Compute the actual receive window we are currently advertising. | ||
1088 | * Rcv_nxt can be after the window if our peer push more data | ||
1089 | * than the offered window. | ||
1090 | */ | ||
1091 | static __inline__ u32 tcp_receive_window(const struct tcp_sock *tp) | ||
1092 | { | ||
1093 | s32 win = tp->rcv_wup + tp->rcv_wnd - tp->rcv_nxt; | ||
1094 | |||
1095 | if (win < 0) | ||
1096 | win = 0; | ||
1097 | return (u32) win; | ||
1098 | } | ||
1099 | |||
1100 | /* Choose a new window, without checks for shrinking, and without | ||
1101 | * scaling applied to the result. The caller does these things | ||
1102 | * if necessary. This is a "raw" window selection. | ||
1103 | */ | ||
1104 | extern u32 __tcp_select_window(struct sock *sk); | ||
1105 | |||
1106 | /* TCP timestamps are only 32-bits, this causes a slight | ||
1107 | * complication on 64-bit systems since we store a snapshot | ||
1108 | * of jiffies in the buffer control blocks below. We decidely | ||
1109 | * only use of the low 32-bits of jiffies and hide the ugly | ||
1110 | * casts with the following macro. | ||
1111 | */ | ||
1112 | #define tcp_time_stamp ((__u32)(jiffies)) | ||
1113 | |||
1114 | /* This is what the send packet queueing engine uses to pass | ||
1115 | * TCP per-packet control information to the transmission | ||
1116 | * code. We also store the host-order sequence numbers in | ||
1117 | * here too. This is 36 bytes on 32-bit architectures, | ||
1118 | * 40 bytes on 64-bit machines, if this grows please adjust | ||
1119 | * skbuff.h:skbuff->cb[xxx] size appropriately. | ||
1120 | */ | ||
1121 | struct tcp_skb_cb { | ||
1122 | union { | ||
1123 | struct inet_skb_parm h4; | ||
1124 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | ||
1125 | struct inet6_skb_parm h6; | ||
1126 | #endif | ||
1127 | } header; /* For incoming frames */ | ||
1128 | __u32 seq; /* Starting sequence number */ | ||
1129 | __u32 end_seq; /* SEQ + FIN + SYN + datalen */ | ||
1130 | __u32 when; /* used to compute rtt's */ | ||
1131 | __u8 flags; /* TCP header flags. */ | ||
1132 | |||
1133 | /* NOTE: These must match up to the flags byte in a | ||
1134 | * real TCP header. | ||
1135 | */ | ||
1136 | #define TCPCB_FLAG_FIN 0x01 | ||
1137 | #define TCPCB_FLAG_SYN 0x02 | ||
1138 | #define TCPCB_FLAG_RST 0x04 | ||
1139 | #define TCPCB_FLAG_PSH 0x08 | ||
1140 | #define TCPCB_FLAG_ACK 0x10 | ||
1141 | #define TCPCB_FLAG_URG 0x20 | ||
1142 | #define TCPCB_FLAG_ECE 0x40 | ||
1143 | #define TCPCB_FLAG_CWR 0x80 | ||
1144 | |||
1145 | __u8 sacked; /* State flags for SACK/FACK. */ | ||
1146 | #define TCPCB_SACKED_ACKED 0x01 /* SKB ACK'd by a SACK block */ | ||
1147 | #define TCPCB_SACKED_RETRANS 0x02 /* SKB retransmitted */ | ||
1148 | #define TCPCB_LOST 0x04 /* SKB is lost */ | ||
1149 | #define TCPCB_TAGBITS 0x07 /* All tag bits */ | ||
1150 | |||
1151 | #define TCPCB_EVER_RETRANS 0x80 /* Ever retransmitted frame */ | ||
1152 | #define TCPCB_RETRANS (TCPCB_SACKED_RETRANS|TCPCB_EVER_RETRANS) | ||
1153 | |||
1154 | #define TCPCB_URG 0x20 /* Urgent pointer advenced here */ | ||
1155 | |||
1156 | #define TCPCB_AT_TAIL (TCPCB_URG) | ||
1157 | |||
1158 | __u16 urg_ptr; /* Valid w/URG flags is set. */ | ||
1159 | __u32 ack_seq; /* Sequence number ACK'd */ | ||
1160 | }; | ||
1161 | |||
1162 | #define TCP_SKB_CB(__skb) ((struct tcp_skb_cb *)&((__skb)->cb[0])) | ||
1163 | |||
1164 | #include <net/tcp_ecn.h> | ||
1165 | |||
1166 | /* Due to TSO, an SKB can be composed of multiple actual | ||
1167 | * packets. To keep these tracked properly, we use this. | ||
1168 | */ | ||
1169 | static inline int tcp_skb_pcount(const struct sk_buff *skb) | ||
1170 | { | ||
1171 | return skb_shinfo(skb)->tso_segs; | ||
1172 | } | ||
1173 | |||
1174 | /* This is valid iff tcp_skb_pcount() > 1. */ | ||
1175 | static inline int tcp_skb_mss(const struct sk_buff *skb) | ||
1176 | { | ||
1177 | return skb_shinfo(skb)->tso_size; | ||
1178 | } | ||
1179 | |||
1180 | static inline void tcp_dec_pcount_approx(__u32 *count, | ||
1181 | const struct sk_buff *skb) | ||
1182 | { | ||
1183 | if (*count) { | ||
1184 | *count -= tcp_skb_pcount(skb); | ||
1185 | if ((int)*count < 0) | ||
1186 | *count = 0; | ||
1187 | } | ||
1188 | } | ||
1189 | |||
1190 | static inline void tcp_packets_out_inc(struct sock *sk, | ||
1191 | struct tcp_sock *tp, | ||
1192 | const struct sk_buff *skb) | ||
1193 | { | ||
1194 | int orig = tp->packets_out; | ||
1195 | |||
1196 | tp->packets_out += tcp_skb_pcount(skb); | ||
1197 | if (!orig) | ||
1198 | tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto); | ||
1199 | } | ||
1200 | |||
1201 | static inline void tcp_packets_out_dec(struct tcp_sock *tp, | ||
1202 | const struct sk_buff *skb) | ||
1203 | { | ||
1204 | tp->packets_out -= tcp_skb_pcount(skb); | ||
1205 | } | ||
1206 | |||
1207 | /* This determines how many packets are "in the network" to the best | ||
1208 | * of our knowledge. In many cases it is conservative, but where | ||
1209 | * detailed information is available from the receiver (via SACK | ||
1210 | * blocks etc.) we can make more aggressive calculations. | ||
1211 | * | ||
1212 | * Use this for decisions involving congestion control, use just | ||
1213 | * tp->packets_out to determine if the send queue is empty or not. | ||
1214 | * | ||
1215 | * Read this equation as: | ||
1216 | * | ||
1217 | * "Packets sent once on transmission queue" MINUS | ||
1218 | * "Packets left network, but not honestly ACKed yet" PLUS | ||
1219 | * "Packets fast retransmitted" | ||
1220 | */ | ||
1221 | static __inline__ unsigned int tcp_packets_in_flight(const struct tcp_sock *tp) | ||
1222 | { | ||
1223 | return (tp->packets_out - tp->left_out + tp->retrans_out); | ||
1224 | } | ||
1225 | |||
1226 | /* | ||
1227 | * Which congestion algorithim is in use on the connection. | ||
1228 | */ | ||
1229 | #define tcp_is_vegas(__tp) ((__tp)->adv_cong == TCP_VEGAS) | ||
1230 | #define tcp_is_westwood(__tp) ((__tp)->adv_cong == TCP_WESTWOOD) | ||
1231 | #define tcp_is_bic(__tp) ((__tp)->adv_cong == TCP_BIC) | ||
1232 | |||
1233 | /* Recalculate snd_ssthresh, we want to set it to: | ||
1234 | * | ||
1235 | * Reno: | ||
1236 | * one half the current congestion window, but no | ||
1237 | * less than two segments | ||
1238 | * | ||
1239 | * BIC: | ||
1240 | * behave like Reno until low_window is reached, | ||
1241 | * then increase congestion window slowly | ||
1242 | */ | ||
1243 | static inline __u32 tcp_recalc_ssthresh(struct tcp_sock *tp) | ||
1244 | { | ||
1245 | if (tcp_is_bic(tp)) { | ||
1246 | if (sysctl_tcp_bic_fast_convergence && | ||
1247 | tp->snd_cwnd < tp->bictcp.last_max_cwnd) | ||
1248 | tp->bictcp.last_max_cwnd = (tp->snd_cwnd * | ||
1249 | (BICTCP_BETA_SCALE | ||
1250 | + sysctl_tcp_bic_beta)) | ||
1251 | / (2 * BICTCP_BETA_SCALE); | ||
1252 | else | ||
1253 | tp->bictcp.last_max_cwnd = tp->snd_cwnd; | ||
1254 | |||
1255 | if (tp->snd_cwnd > sysctl_tcp_bic_low_window) | ||
1256 | return max((tp->snd_cwnd * sysctl_tcp_bic_beta) | ||
1257 | / BICTCP_BETA_SCALE, 2U); | ||
1258 | } | ||
1259 | |||
1260 | return max(tp->snd_cwnd >> 1U, 2U); | ||
1261 | } | ||
1262 | |||
1263 | /* Stop taking Vegas samples for now. */ | ||
1264 | #define tcp_vegas_disable(__tp) ((__tp)->vegas.doing_vegas_now = 0) | ||
1265 | |||
1266 | static inline void tcp_vegas_enable(struct tcp_sock *tp) | ||
1267 | { | ||
1268 | /* There are several situations when we must "re-start" Vegas: | ||
1269 | * | ||
1270 | * o when a connection is established | ||
1271 | * o after an RTO | ||
1272 | * o after fast recovery | ||
1273 | * o when we send a packet and there is no outstanding | ||
1274 | * unacknowledged data (restarting an idle connection) | ||
1275 | * | ||
1276 | * In these circumstances we cannot do a Vegas calculation at the | ||
1277 | * end of the first RTT, because any calculation we do is using | ||
1278 | * stale info -- both the saved cwnd and congestion feedback are | ||
1279 | * stale. | ||
1280 | * | ||
1281 | * Instead we must wait until the completion of an RTT during | ||
1282 | * which we actually receive ACKs. | ||
1283 | */ | ||
1284 | |||
1285 | /* Begin taking Vegas samples next time we send something. */ | ||
1286 | tp->vegas.doing_vegas_now = 1; | ||
1287 | |||
1288 | /* Set the beginning of the next send window. */ | ||
1289 | tp->vegas.beg_snd_nxt = tp->snd_nxt; | ||
1290 | |||
1291 | tp->vegas.cntRTT = 0; | ||
1292 | tp->vegas.minRTT = 0x7fffffff; | ||
1293 | } | ||
1294 | |||
1295 | /* Should we be taking Vegas samples right now? */ | ||
1296 | #define tcp_vegas_enabled(__tp) ((__tp)->vegas.doing_vegas_now) | ||
1297 | |||
1298 | extern void tcp_ca_init(struct tcp_sock *tp); | ||
1299 | |||
1300 | static inline void tcp_set_ca_state(struct tcp_sock *tp, u8 ca_state) | ||
1301 | { | ||
1302 | if (tcp_is_vegas(tp)) { | ||
1303 | if (ca_state == TCP_CA_Open) | ||
1304 | tcp_vegas_enable(tp); | ||
1305 | else | ||
1306 | tcp_vegas_disable(tp); | ||
1307 | } | ||
1308 | tp->ca_state = ca_state; | ||
1309 | } | ||
1310 | |||
1311 | /* If cwnd > ssthresh, we may raise ssthresh to be half-way to cwnd. | ||
1312 | * The exception is rate halving phase, when cwnd is decreasing towards | ||
1313 | * ssthresh. | ||
1314 | */ | ||
1315 | static inline __u32 tcp_current_ssthresh(struct tcp_sock *tp) | ||
1316 | { | ||
1317 | if ((1<<tp->ca_state)&(TCPF_CA_CWR|TCPF_CA_Recovery)) | ||
1318 | return tp->snd_ssthresh; | ||
1319 | else | ||
1320 | return max(tp->snd_ssthresh, | ||
1321 | ((tp->snd_cwnd >> 1) + | ||
1322 | (tp->snd_cwnd >> 2))); | ||
1323 | } | ||
1324 | |||
1325 | static inline void tcp_sync_left_out(struct tcp_sock *tp) | ||
1326 | { | ||
1327 | if (tp->rx_opt.sack_ok && | ||
1328 | (tp->sacked_out >= tp->packets_out - tp->lost_out)) | ||
1329 | tp->sacked_out = tp->packets_out - tp->lost_out; | ||
1330 | tp->left_out = tp->sacked_out + tp->lost_out; | ||
1331 | } | ||
1332 | |||
1333 | extern void tcp_cwnd_application_limited(struct sock *sk); | ||
1334 | |||
1335 | /* Congestion window validation. (RFC2861) */ | ||
1336 | |||
1337 | static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp) | ||
1338 | { | ||
1339 | __u32 packets_out = tp->packets_out; | ||
1340 | |||
1341 | if (packets_out >= tp->snd_cwnd) { | ||
1342 | /* Network is feed fully. */ | ||
1343 | tp->snd_cwnd_used = 0; | ||
1344 | tp->snd_cwnd_stamp = tcp_time_stamp; | ||
1345 | } else { | ||
1346 | /* Network starves. */ | ||
1347 | if (tp->packets_out > tp->snd_cwnd_used) | ||
1348 | tp->snd_cwnd_used = tp->packets_out; | ||
1349 | |||
1350 | if ((s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= tp->rto) | ||
1351 | tcp_cwnd_application_limited(sk); | ||
1352 | } | ||
1353 | } | ||
1354 | |||
1355 | /* Set slow start threshould and cwnd not falling to slow start */ | ||
1356 | static inline void __tcp_enter_cwr(struct tcp_sock *tp) | ||
1357 | { | ||
1358 | tp->undo_marker = 0; | ||
1359 | tp->snd_ssthresh = tcp_recalc_ssthresh(tp); | ||
1360 | tp->snd_cwnd = min(tp->snd_cwnd, | ||
1361 | tcp_packets_in_flight(tp) + 1U); | ||
1362 | tp->snd_cwnd_cnt = 0; | ||
1363 | tp->high_seq = tp->snd_nxt; | ||
1364 | tp->snd_cwnd_stamp = tcp_time_stamp; | ||
1365 | TCP_ECN_queue_cwr(tp); | ||
1366 | } | ||
1367 | |||
1368 | static inline void tcp_enter_cwr(struct tcp_sock *tp) | ||
1369 | { | ||
1370 | tp->prior_ssthresh = 0; | ||
1371 | if (tp->ca_state < TCP_CA_CWR) { | ||
1372 | __tcp_enter_cwr(tp); | ||
1373 | tcp_set_ca_state(tp, TCP_CA_CWR); | ||
1374 | } | ||
1375 | } | ||
1376 | |||
1377 | extern __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst); | ||
1378 | |||
1379 | /* Slow start with delack produces 3 packets of burst, so that | ||
1380 | * it is safe "de facto". | ||
1381 | */ | ||
1382 | static __inline__ __u32 tcp_max_burst(const struct tcp_sock *tp) | ||
1383 | { | ||
1384 | return 3; | ||
1385 | } | ||
1386 | |||
1387 | static __inline__ int tcp_minshall_check(const struct tcp_sock *tp) | ||
1388 | { | ||
1389 | return after(tp->snd_sml,tp->snd_una) && | ||
1390 | !after(tp->snd_sml, tp->snd_nxt); | ||
1391 | } | ||
1392 | |||
1393 | static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss, | ||
1394 | const struct sk_buff *skb) | ||
1395 | { | ||
1396 | if (skb->len < mss) | ||
1397 | tp->snd_sml = TCP_SKB_CB(skb)->end_seq; | ||
1398 | } | ||
1399 | |||
1400 | /* Return 0, if packet can be sent now without violation Nagle's rules: | ||
1401 | 1. It is full sized. | ||
1402 | 2. Or it contains FIN. | ||
1403 | 3. Or TCP_NODELAY was set. | ||
1404 | 4. Or TCP_CORK is not set, and all sent packets are ACKed. | ||
1405 | With Minshall's modification: all sent small packets are ACKed. | ||
1406 | */ | ||
1407 | |||
1408 | static __inline__ int | ||
1409 | tcp_nagle_check(const struct tcp_sock *tp, const struct sk_buff *skb, | ||
1410 | unsigned mss_now, int nonagle) | ||
1411 | { | ||
1412 | return (skb->len < mss_now && | ||
1413 | !(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) && | ||
1414 | ((nonagle&TCP_NAGLE_CORK) || | ||
1415 | (!nonagle && | ||
1416 | tp->packets_out && | ||
1417 | tcp_minshall_check(tp)))); | ||
1418 | } | ||
1419 | |||
1420 | extern void tcp_set_skb_tso_segs(struct sk_buff *, unsigned int); | ||
1421 | |||
1422 | /* This checks if the data bearing packet SKB (usually sk->sk_send_head) | ||
1423 | * should be put on the wire right now. | ||
1424 | */ | ||
1425 | static __inline__ int tcp_snd_test(const struct tcp_sock *tp, | ||
1426 | struct sk_buff *skb, | ||
1427 | unsigned cur_mss, int nonagle) | ||
1428 | { | ||
1429 | int pkts = tcp_skb_pcount(skb); | ||
1430 | |||
1431 | if (!pkts) { | ||
1432 | tcp_set_skb_tso_segs(skb, tp->mss_cache_std); | ||
1433 | pkts = tcp_skb_pcount(skb); | ||
1434 | } | ||
1435 | |||
1436 | /* RFC 1122 - section 4.2.3.4 | ||
1437 | * | ||
1438 | * We must queue if | ||
1439 | * | ||
1440 | * a) The right edge of this frame exceeds the window | ||
1441 | * b) There are packets in flight and we have a small segment | ||
1442 | * [SWS avoidance and Nagle algorithm] | ||
1443 | * (part of SWS is done on packetization) | ||
1444 | * Minshall version sounds: there are no _small_ | ||
1445 | * segments in flight. (tcp_nagle_check) | ||
1446 | * c) We have too many packets 'in flight' | ||
1447 | * | ||
1448 | * Don't use the nagle rule for urgent data (or | ||
1449 | * for the final FIN -DaveM). | ||
1450 | * | ||
1451 | * Also, Nagle rule does not apply to frames, which | ||
1452 | * sit in the middle of queue (they have no chances | ||
1453 | * to get new data) and if room at tail of skb is | ||
1454 | * not enough to save something seriously (<32 for now). | ||
1455 | */ | ||
1456 | |||
1457 | /* Don't be strict about the congestion window for the | ||
1458 | * final FIN frame. -DaveM | ||
1459 | */ | ||
1460 | return (((nonagle&TCP_NAGLE_PUSH) || tp->urg_mode | ||
1461 | || !tcp_nagle_check(tp, skb, cur_mss, nonagle)) && | ||
1462 | (((tcp_packets_in_flight(tp) + (pkts-1)) < tp->snd_cwnd) || | ||
1463 | (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) && | ||
1464 | !after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd)); | ||
1465 | } | ||
1466 | |||
1467 | static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp) | ||
1468 | { | ||
1469 | if (!tp->packets_out && !tp->pending) | ||
1470 | tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, tp->rto); | ||
1471 | } | ||
1472 | |||
1473 | static __inline__ int tcp_skb_is_last(const struct sock *sk, | ||
1474 | const struct sk_buff *skb) | ||
1475 | { | ||
1476 | return skb->next == (struct sk_buff *)&sk->sk_write_queue; | ||
1477 | } | ||
1478 | |||
1479 | /* Push out any pending frames which were held back due to | ||
1480 | * TCP_CORK or attempt at coalescing tiny packets. | ||
1481 | * The socket must be locked by the caller. | ||
1482 | */ | ||
1483 | static __inline__ void __tcp_push_pending_frames(struct sock *sk, | ||
1484 | struct tcp_sock *tp, | ||
1485 | unsigned cur_mss, | ||
1486 | int nonagle) | ||
1487 | { | ||
1488 | struct sk_buff *skb = sk->sk_send_head; | ||
1489 | |||
1490 | if (skb) { | ||
1491 | if (!tcp_skb_is_last(sk, skb)) | ||
1492 | nonagle = TCP_NAGLE_PUSH; | ||
1493 | if (!tcp_snd_test(tp, skb, cur_mss, nonagle) || | ||
1494 | tcp_write_xmit(sk, nonagle)) | ||
1495 | tcp_check_probe_timer(sk, tp); | ||
1496 | } | ||
1497 | tcp_cwnd_validate(sk, tp); | ||
1498 | } | ||
1499 | |||
1500 | static __inline__ void tcp_push_pending_frames(struct sock *sk, | ||
1501 | struct tcp_sock *tp) | ||
1502 | { | ||
1503 | __tcp_push_pending_frames(sk, tp, tcp_current_mss(sk, 1), tp->nonagle); | ||
1504 | } | ||
1505 | |||
1506 | static __inline__ int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp) | ||
1507 | { | ||
1508 | struct sk_buff *skb = sk->sk_send_head; | ||
1509 | |||
1510 | return (skb && | ||
1511 | tcp_snd_test(tp, skb, tcp_current_mss(sk, 1), | ||
1512 | tcp_skb_is_last(sk, skb) ? TCP_NAGLE_PUSH : tp->nonagle)); | ||
1513 | } | ||
1514 | |||
1515 | static __inline__ void tcp_init_wl(struct tcp_sock *tp, u32 ack, u32 seq) | ||
1516 | { | ||
1517 | tp->snd_wl1 = seq; | ||
1518 | } | ||
1519 | |||
1520 | static __inline__ void tcp_update_wl(struct tcp_sock *tp, u32 ack, u32 seq) | ||
1521 | { | ||
1522 | tp->snd_wl1 = seq; | ||
1523 | } | ||
1524 | |||
1525 | extern void tcp_destroy_sock(struct sock *sk); | ||
1526 | |||
1527 | |||
1528 | /* | ||
1529 | * Calculate(/check) TCP checksum | ||
1530 | */ | ||
1531 | static __inline__ u16 tcp_v4_check(struct tcphdr *th, int len, | ||
1532 | unsigned long saddr, unsigned long daddr, | ||
1533 | unsigned long base) | ||
1534 | { | ||
1535 | return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base); | ||
1536 | } | ||
1537 | |||
1538 | static __inline__ int __tcp_checksum_complete(struct sk_buff *skb) | ||
1539 | { | ||
1540 | return (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)); | ||
1541 | } | ||
1542 | |||
1543 | static __inline__ int tcp_checksum_complete(struct sk_buff *skb) | ||
1544 | { | ||
1545 | return skb->ip_summed != CHECKSUM_UNNECESSARY && | ||
1546 | __tcp_checksum_complete(skb); | ||
1547 | } | ||
1548 | |||
1549 | /* Prequeue for VJ style copy to user, combined with checksumming. */ | ||
1550 | |||
1551 | static __inline__ void tcp_prequeue_init(struct tcp_sock *tp) | ||
1552 | { | ||
1553 | tp->ucopy.task = NULL; | ||
1554 | tp->ucopy.len = 0; | ||
1555 | tp->ucopy.memory = 0; | ||
1556 | skb_queue_head_init(&tp->ucopy.prequeue); | ||
1557 | } | ||
1558 | |||
1559 | /* Packet is added to VJ-style prequeue for processing in process | ||
1560 | * context, if a reader task is waiting. Apparently, this exciting | ||
1561 | * idea (VJ's mail "Re: query about TCP header on tcp-ip" of 07 Sep 93) | ||
1562 | * failed somewhere. Latency? Burstiness? Well, at least now we will | ||
1563 | * see, why it failed. 8)8) --ANK | ||
1564 | * | ||
1565 | * NOTE: is this not too big to inline? | ||
1566 | */ | ||
1567 | static __inline__ int tcp_prequeue(struct sock *sk, struct sk_buff *skb) | ||
1568 | { | ||
1569 | struct tcp_sock *tp = tcp_sk(sk); | ||
1570 | |||
1571 | if (!sysctl_tcp_low_latency && tp->ucopy.task) { | ||
1572 | __skb_queue_tail(&tp->ucopy.prequeue, skb); | ||
1573 | tp->ucopy.memory += skb->truesize; | ||
1574 | if (tp->ucopy.memory > sk->sk_rcvbuf) { | ||
1575 | struct sk_buff *skb1; | ||
1576 | |||
1577 | BUG_ON(sock_owned_by_user(sk)); | ||
1578 | |||
1579 | while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) { | ||
1580 | sk->sk_backlog_rcv(sk, skb1); | ||
1581 | NET_INC_STATS_BH(LINUX_MIB_TCPPREQUEUEDROPPED); | ||
1582 | } | ||
1583 | |||
1584 | tp->ucopy.memory = 0; | ||
1585 | } else if (skb_queue_len(&tp->ucopy.prequeue) == 1) { | ||
1586 | wake_up_interruptible(sk->sk_sleep); | ||
1587 | if (!tcp_ack_scheduled(tp)) | ||
1588 | tcp_reset_xmit_timer(sk, TCP_TIME_DACK, (3*TCP_RTO_MIN)/4); | ||
1589 | } | ||
1590 | return 1; | ||
1591 | } | ||
1592 | return 0; | ||
1593 | } | ||
1594 | |||
1595 | |||
1596 | #undef STATE_TRACE | ||
1597 | |||
1598 | #ifdef STATE_TRACE | ||
1599 | static const char *statename[]={ | ||
1600 | "Unused","Established","Syn Sent","Syn Recv", | ||
1601 | "Fin Wait 1","Fin Wait 2","Time Wait", "Close", | ||
1602 | "Close Wait","Last ACK","Listen","Closing" | ||
1603 | }; | ||
1604 | #endif | ||
1605 | |||
1606 | static __inline__ void tcp_set_state(struct sock *sk, int state) | ||
1607 | { | ||
1608 | int oldstate = sk->sk_state; | ||
1609 | |||
1610 | switch (state) { | ||
1611 | case TCP_ESTABLISHED: | ||
1612 | if (oldstate != TCP_ESTABLISHED) | ||
1613 | TCP_INC_STATS(TCP_MIB_CURRESTAB); | ||
1614 | break; | ||
1615 | |||
1616 | case TCP_CLOSE: | ||
1617 | if (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED) | ||
1618 | TCP_INC_STATS(TCP_MIB_ESTABRESETS); | ||
1619 | |||
1620 | sk->sk_prot->unhash(sk); | ||
1621 | if (tcp_sk(sk)->bind_hash && | ||
1622 | !(sk->sk_userlocks & SOCK_BINDPORT_LOCK)) | ||
1623 | tcp_put_port(sk); | ||
1624 | /* fall through */ | ||
1625 | default: | ||
1626 | if (oldstate==TCP_ESTABLISHED) | ||
1627 | TCP_DEC_STATS(TCP_MIB_CURRESTAB); | ||
1628 | } | ||
1629 | |||
1630 | /* Change state AFTER socket is unhashed to avoid closed | ||
1631 | * socket sitting in hash tables. | ||
1632 | */ | ||
1633 | sk->sk_state = state; | ||
1634 | |||
1635 | #ifdef STATE_TRACE | ||
1636 | SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]); | ||
1637 | #endif | ||
1638 | } | ||
1639 | |||
1640 | static __inline__ void tcp_done(struct sock *sk) | ||
1641 | { | ||
1642 | tcp_set_state(sk, TCP_CLOSE); | ||
1643 | tcp_clear_xmit_timers(sk); | ||
1644 | |||
1645 | sk->sk_shutdown = SHUTDOWN_MASK; | ||
1646 | |||
1647 | if (!sock_flag(sk, SOCK_DEAD)) | ||
1648 | sk->sk_state_change(sk); | ||
1649 | else | ||
1650 | tcp_destroy_sock(sk); | ||
1651 | } | ||
1652 | |||
1653 | static __inline__ void tcp_sack_reset(struct tcp_options_received *rx_opt) | ||
1654 | { | ||
1655 | rx_opt->dsack = 0; | ||
1656 | rx_opt->eff_sacks = 0; | ||
1657 | rx_opt->num_sacks = 0; | ||
1658 | } | ||
1659 | |||
1660 | static __inline__ void tcp_build_and_update_options(__u32 *ptr, struct tcp_sock *tp, __u32 tstamp) | ||
1661 | { | ||
1662 | if (tp->rx_opt.tstamp_ok) { | ||
1663 | *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | | ||
1664 | (TCPOPT_NOP << 16) | | ||
1665 | (TCPOPT_TIMESTAMP << 8) | | ||
1666 | TCPOLEN_TIMESTAMP); | ||
1667 | *ptr++ = htonl(tstamp); | ||
1668 | *ptr++ = htonl(tp->rx_opt.ts_recent); | ||
1669 | } | ||
1670 | if (tp->rx_opt.eff_sacks) { | ||
1671 | struct tcp_sack_block *sp = tp->rx_opt.dsack ? tp->duplicate_sack : tp->selective_acks; | ||
1672 | int this_sack; | ||
1673 | |||
1674 | *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | | ||
1675 | (TCPOPT_NOP << 16) | | ||
1676 | (TCPOPT_SACK << 8) | | ||
1677 | (TCPOLEN_SACK_BASE + | ||
1678 | (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK))); | ||
1679 | for(this_sack = 0; this_sack < tp->rx_opt.eff_sacks; this_sack++) { | ||
1680 | *ptr++ = htonl(sp[this_sack].start_seq); | ||
1681 | *ptr++ = htonl(sp[this_sack].end_seq); | ||
1682 | } | ||
1683 | if (tp->rx_opt.dsack) { | ||
1684 | tp->rx_opt.dsack = 0; | ||
1685 | tp->rx_opt.eff_sacks--; | ||
1686 | } | ||
1687 | } | ||
1688 | } | ||
1689 | |||
1690 | /* Construct a tcp options header for a SYN or SYN_ACK packet. | ||
1691 | * If this is every changed make sure to change the definition of | ||
1692 | * MAX_SYN_SIZE to match the new maximum number of options that you | ||
1693 | * can generate. | ||
1694 | */ | ||
1695 | static inline void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack, | ||
1696 | int offer_wscale, int wscale, __u32 tstamp, __u32 ts_recent) | ||
1697 | { | ||
1698 | /* We always get an MSS option. | ||
1699 | * The option bytes which will be seen in normal data | ||
1700 | * packets should timestamps be used, must be in the MSS | ||
1701 | * advertised. But we subtract them from tp->mss_cache so | ||
1702 | * that calculations in tcp_sendmsg are simpler etc. | ||
1703 | * So account for this fact here if necessary. If we | ||
1704 | * don't do this correctly, as a receiver we won't | ||
1705 | * recognize data packets as being full sized when we | ||
1706 | * should, and thus we won't abide by the delayed ACK | ||
1707 | * rules correctly. | ||
1708 | * SACKs don't matter, we never delay an ACK when we | ||
1709 | * have any of those going out. | ||
1710 | */ | ||
1711 | *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss); | ||
1712 | if (ts) { | ||
1713 | if(sack) | ||
1714 | *ptr++ = __constant_htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) | | ||
1715 | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); | ||
1716 | else | ||
1717 | *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | | ||
1718 | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); | ||
1719 | *ptr++ = htonl(tstamp); /* TSVAL */ | ||
1720 | *ptr++ = htonl(ts_recent); /* TSECR */ | ||
1721 | } else if(sack) | ||
1722 | *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | | ||
1723 | (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM); | ||
1724 | if (offer_wscale) | ||
1725 | *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale)); | ||
1726 | } | ||
1727 | |||
1728 | /* Determine a window scaling and initial window to offer. */ | ||
1729 | extern void tcp_select_initial_window(int __space, __u32 mss, | ||
1730 | __u32 *rcv_wnd, __u32 *window_clamp, | ||
1731 | int wscale_ok, __u8 *rcv_wscale); | ||
1732 | |||
1733 | static inline int tcp_win_from_space(int space) | ||
1734 | { | ||
1735 | return sysctl_tcp_adv_win_scale<=0 ? | ||
1736 | (space>>(-sysctl_tcp_adv_win_scale)) : | ||
1737 | space - (space>>sysctl_tcp_adv_win_scale); | ||
1738 | } | ||
1739 | |||
1740 | /* Note: caller must be prepared to deal with negative returns */ | ||
1741 | static inline int tcp_space(const struct sock *sk) | ||
1742 | { | ||
1743 | return tcp_win_from_space(sk->sk_rcvbuf - | ||
1744 | atomic_read(&sk->sk_rmem_alloc)); | ||
1745 | } | ||
1746 | |||
1747 | static inline int tcp_full_space(const struct sock *sk) | ||
1748 | { | ||
1749 | return tcp_win_from_space(sk->sk_rcvbuf); | ||
1750 | } | ||
1751 | |||
1752 | static inline void tcp_acceptq_queue(struct sock *sk, struct open_request *req, | ||
1753 | struct sock *child) | ||
1754 | { | ||
1755 | struct tcp_sock *tp = tcp_sk(sk); | ||
1756 | |||
1757 | req->sk = child; | ||
1758 | sk_acceptq_added(sk); | ||
1759 | |||
1760 | if (!tp->accept_queue_tail) { | ||
1761 | tp->accept_queue = req; | ||
1762 | } else { | ||
1763 | tp->accept_queue_tail->dl_next = req; | ||
1764 | } | ||
1765 | tp->accept_queue_tail = req; | ||
1766 | req->dl_next = NULL; | ||
1767 | } | ||
1768 | |||
1769 | struct tcp_listen_opt | ||
1770 | { | ||
1771 | u8 max_qlen_log; /* log_2 of maximal queued SYNs */ | ||
1772 | int qlen; | ||
1773 | int qlen_young; | ||
1774 | int clock_hand; | ||
1775 | u32 hash_rnd; | ||
1776 | struct open_request *syn_table[TCP_SYNQ_HSIZE]; | ||
1777 | }; | ||
1778 | |||
1779 | static inline void | ||
1780 | tcp_synq_removed(struct sock *sk, struct open_request *req) | ||
1781 | { | ||
1782 | struct tcp_listen_opt *lopt = tcp_sk(sk)->listen_opt; | ||
1783 | |||
1784 | if (--lopt->qlen == 0) | ||
1785 | tcp_delete_keepalive_timer(sk); | ||
1786 | if (req->retrans == 0) | ||
1787 | lopt->qlen_young--; | ||
1788 | } | ||
1789 | |||
1790 | static inline void tcp_synq_added(struct sock *sk) | ||
1791 | { | ||
1792 | struct tcp_listen_opt *lopt = tcp_sk(sk)->listen_opt; | ||
1793 | |||
1794 | if (lopt->qlen++ == 0) | ||
1795 | tcp_reset_keepalive_timer(sk, TCP_TIMEOUT_INIT); | ||
1796 | lopt->qlen_young++; | ||
1797 | } | ||
1798 | |||
1799 | static inline int tcp_synq_len(struct sock *sk) | ||
1800 | { | ||
1801 | return tcp_sk(sk)->listen_opt->qlen; | ||
1802 | } | ||
1803 | |||
1804 | static inline int tcp_synq_young(struct sock *sk) | ||
1805 | { | ||
1806 | return tcp_sk(sk)->listen_opt->qlen_young; | ||
1807 | } | ||
1808 | |||
1809 | static inline int tcp_synq_is_full(struct sock *sk) | ||
1810 | { | ||
1811 | return tcp_synq_len(sk) >> tcp_sk(sk)->listen_opt->max_qlen_log; | ||
1812 | } | ||
1813 | |||
1814 | static inline void tcp_synq_unlink(struct tcp_sock *tp, struct open_request *req, | ||
1815 | struct open_request **prev) | ||
1816 | { | ||
1817 | write_lock(&tp->syn_wait_lock); | ||
1818 | *prev = req->dl_next; | ||
1819 | write_unlock(&tp->syn_wait_lock); | ||
1820 | } | ||
1821 | |||
1822 | static inline void tcp_synq_drop(struct sock *sk, struct open_request *req, | ||
1823 | struct open_request **prev) | ||
1824 | { | ||
1825 | tcp_synq_unlink(tcp_sk(sk), req, prev); | ||
1826 | tcp_synq_removed(sk, req); | ||
1827 | tcp_openreq_free(req); | ||
1828 | } | ||
1829 | |||
1830 | static __inline__ void tcp_openreq_init(struct open_request *req, | ||
1831 | struct tcp_options_received *rx_opt, | ||
1832 | struct sk_buff *skb) | ||
1833 | { | ||
1834 | req->rcv_wnd = 0; /* So that tcp_send_synack() knows! */ | ||
1835 | req->rcv_isn = TCP_SKB_CB(skb)->seq; | ||
1836 | req->mss = rx_opt->mss_clamp; | ||
1837 | req->ts_recent = rx_opt->saw_tstamp ? rx_opt->rcv_tsval : 0; | ||
1838 | req->tstamp_ok = rx_opt->tstamp_ok; | ||
1839 | req->sack_ok = rx_opt->sack_ok; | ||
1840 | req->snd_wscale = rx_opt->snd_wscale; | ||
1841 | req->wscale_ok = rx_opt->wscale_ok; | ||
1842 | req->acked = 0; | ||
1843 | req->ecn_ok = 0; | ||
1844 | req->rmt_port = skb->h.th->source; | ||
1845 | } | ||
1846 | |||
1847 | extern void tcp_enter_memory_pressure(void); | ||
1848 | |||
1849 | extern void tcp_listen_wlock(void); | ||
1850 | |||
1851 | /* - We may sleep inside this lock. | ||
1852 | * - If sleeping is not required (or called from BH), | ||
1853 | * use plain read_(un)lock(&tcp_lhash_lock). | ||
1854 | */ | ||
1855 | |||
1856 | static inline void tcp_listen_lock(void) | ||
1857 | { | ||
1858 | /* read_lock synchronizes to candidates to writers */ | ||
1859 | read_lock(&tcp_lhash_lock); | ||
1860 | atomic_inc(&tcp_lhash_users); | ||
1861 | read_unlock(&tcp_lhash_lock); | ||
1862 | } | ||
1863 | |||
1864 | static inline void tcp_listen_unlock(void) | ||
1865 | { | ||
1866 | if (atomic_dec_and_test(&tcp_lhash_users)) | ||
1867 | wake_up(&tcp_lhash_wait); | ||
1868 | } | ||
1869 | |||
1870 | static inline int keepalive_intvl_when(const struct tcp_sock *tp) | ||
1871 | { | ||
1872 | return tp->keepalive_intvl ? : sysctl_tcp_keepalive_intvl; | ||
1873 | } | ||
1874 | |||
1875 | static inline int keepalive_time_when(const struct tcp_sock *tp) | ||
1876 | { | ||
1877 | return tp->keepalive_time ? : sysctl_tcp_keepalive_time; | ||
1878 | } | ||
1879 | |||
1880 | static inline int tcp_fin_time(const struct tcp_sock *tp) | ||
1881 | { | ||
1882 | int fin_timeout = tp->linger2 ? : sysctl_tcp_fin_timeout; | ||
1883 | |||
1884 | if (fin_timeout < (tp->rto<<2) - (tp->rto>>1)) | ||
1885 | fin_timeout = (tp->rto<<2) - (tp->rto>>1); | ||
1886 | |||
1887 | return fin_timeout; | ||
1888 | } | ||
1889 | |||
1890 | static inline int tcp_paws_check(const struct tcp_options_received *rx_opt, int rst) | ||
1891 | { | ||
1892 | if ((s32)(rx_opt->rcv_tsval - rx_opt->ts_recent) >= 0) | ||
1893 | return 0; | ||
1894 | if (xtime.tv_sec >= rx_opt->ts_recent_stamp + TCP_PAWS_24DAYS) | ||
1895 | return 0; | ||
1896 | |||
1897 | /* RST segments are not recommended to carry timestamp, | ||
1898 | and, if they do, it is recommended to ignore PAWS because | ||
1899 | "their cleanup function should take precedence over timestamps." | ||
1900 | Certainly, it is mistake. It is necessary to understand the reasons | ||
1901 | of this constraint to relax it: if peer reboots, clock may go | ||
1902 | out-of-sync and half-open connections will not be reset. | ||
1903 | Actually, the problem would be not existing if all | ||
1904 | the implementations followed draft about maintaining clock | ||
1905 | via reboots. Linux-2.2 DOES NOT! | ||
1906 | |||
1907 | However, we can relax time bounds for RST segments to MSL. | ||
1908 | */ | ||
1909 | if (rst && xtime.tv_sec >= rx_opt->ts_recent_stamp + TCP_PAWS_MSL) | ||
1910 | return 0; | ||
1911 | return 1; | ||
1912 | } | ||
1913 | |||
1914 | static inline void tcp_v4_setup_caps(struct sock *sk, struct dst_entry *dst) | ||
1915 | { | ||
1916 | sk->sk_route_caps = dst->dev->features; | ||
1917 | if (sk->sk_route_caps & NETIF_F_TSO) { | ||
1918 | if (sock_flag(sk, SOCK_NO_LARGESEND) || dst->header_len) | ||
1919 | sk->sk_route_caps &= ~NETIF_F_TSO; | ||
1920 | } | ||
1921 | } | ||
1922 | |||
1923 | #define TCP_CHECK_TIMER(sk) do { } while (0) | ||
1924 | |||
1925 | static inline int tcp_use_frto(const struct sock *sk) | ||
1926 | { | ||
1927 | const struct tcp_sock *tp = tcp_sk(sk); | ||
1928 | |||
1929 | /* F-RTO must be activated in sysctl and there must be some | ||
1930 | * unsent new data, and the advertised window should allow | ||
1931 | * sending it. | ||
1932 | */ | ||
1933 | return (sysctl_tcp_frto && sk->sk_send_head && | ||
1934 | !after(TCP_SKB_CB(sk->sk_send_head)->end_seq, | ||
1935 | tp->snd_una + tp->snd_wnd)); | ||
1936 | } | ||
1937 | |||
1938 | static inline void tcp_mib_init(void) | ||
1939 | { | ||
1940 | /* See RFC 2012 */ | ||
1941 | TCP_ADD_STATS_USER(TCP_MIB_RTOALGORITHM, 1); | ||
1942 | TCP_ADD_STATS_USER(TCP_MIB_RTOMIN, TCP_RTO_MIN*1000/HZ); | ||
1943 | TCP_ADD_STATS_USER(TCP_MIB_RTOMAX, TCP_RTO_MAX*1000/HZ); | ||
1944 | TCP_ADD_STATS_USER(TCP_MIB_MAXCONN, -1); | ||
1945 | } | ||
1946 | |||
1947 | /* /proc */ | ||
1948 | enum tcp_seq_states { | ||
1949 | TCP_SEQ_STATE_LISTENING, | ||
1950 | TCP_SEQ_STATE_OPENREQ, | ||
1951 | TCP_SEQ_STATE_ESTABLISHED, | ||
1952 | TCP_SEQ_STATE_TIME_WAIT, | ||
1953 | }; | ||
1954 | |||
1955 | struct tcp_seq_afinfo { | ||
1956 | struct module *owner; | ||
1957 | char *name; | ||
1958 | sa_family_t family; | ||
1959 | int (*seq_show) (struct seq_file *m, void *v); | ||
1960 | struct file_operations *seq_fops; | ||
1961 | }; | ||
1962 | |||
1963 | struct tcp_iter_state { | ||
1964 | sa_family_t family; | ||
1965 | enum tcp_seq_states state; | ||
1966 | struct sock *syn_wait_sk; | ||
1967 | int bucket, sbucket, num, uid; | ||
1968 | struct seq_operations seq_ops; | ||
1969 | }; | ||
1970 | |||
1971 | extern int tcp_proc_register(struct tcp_seq_afinfo *afinfo); | ||
1972 | extern void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo); | ||
1973 | |||
1974 | /* TCP Westwood functions and constants */ | ||
1975 | |||
1976 | #define TCP_WESTWOOD_INIT_RTT (20*HZ) /* maybe too conservative?! */ | ||
1977 | #define TCP_WESTWOOD_RTT_MIN (HZ/20) /* 50ms */ | ||
1978 | |||
1979 | static inline void tcp_westwood_update_rtt(struct tcp_sock *tp, __u32 rtt_seq) | ||
1980 | { | ||
1981 | if (tcp_is_westwood(tp)) | ||
1982 | tp->westwood.rtt = rtt_seq; | ||
1983 | } | ||
1984 | |||
1985 | static inline __u32 __tcp_westwood_bw_rttmin(const struct tcp_sock *tp) | ||
1986 | { | ||
1987 | return max((tp->westwood.bw_est) * (tp->westwood.rtt_min) / | ||
1988 | (__u32) (tp->mss_cache_std), | ||
1989 | 2U); | ||
1990 | } | ||
1991 | |||
1992 | static inline __u32 tcp_westwood_bw_rttmin(const struct tcp_sock *tp) | ||
1993 | { | ||
1994 | return tcp_is_westwood(tp) ? __tcp_westwood_bw_rttmin(tp) : 0; | ||
1995 | } | ||
1996 | |||
1997 | static inline int tcp_westwood_ssthresh(struct tcp_sock *tp) | ||
1998 | { | ||
1999 | __u32 ssthresh = 0; | ||
2000 | |||
2001 | if (tcp_is_westwood(tp)) { | ||
2002 | ssthresh = __tcp_westwood_bw_rttmin(tp); | ||
2003 | if (ssthresh) | ||
2004 | tp->snd_ssthresh = ssthresh; | ||
2005 | } | ||
2006 | |||
2007 | return (ssthresh != 0); | ||
2008 | } | ||
2009 | |||
2010 | static inline int tcp_westwood_cwnd(struct tcp_sock *tp) | ||
2011 | { | ||
2012 | __u32 cwnd = 0; | ||
2013 | |||
2014 | if (tcp_is_westwood(tp)) { | ||
2015 | cwnd = __tcp_westwood_bw_rttmin(tp); | ||
2016 | if (cwnd) | ||
2017 | tp->snd_cwnd = cwnd; | ||
2018 | } | ||
2019 | |||
2020 | return (cwnd != 0); | ||
2021 | } | ||
2022 | #endif /* _TCP_H */ | ||
diff --git a/include/net/tcp_ecn.h b/include/net/tcp_ecn.h new file mode 100644 index 000000000000..dc1456389a97 --- /dev/null +++ b/include/net/tcp_ecn.h | |||
@@ -0,0 +1,126 @@ | |||
1 | #ifndef _NET_TCP_ECN_H_ | ||
2 | #define _NET_TCP_ECN_H_ 1 | ||
3 | |||
4 | #include <net/inet_ecn.h> | ||
5 | |||
6 | #define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH)) | ||
7 | |||
8 | #define TCP_ECN_OK 1 | ||
9 | #define TCP_ECN_QUEUE_CWR 2 | ||
10 | #define TCP_ECN_DEMAND_CWR 4 | ||
11 | |||
12 | static inline void TCP_ECN_queue_cwr(struct tcp_sock *tp) | ||
13 | { | ||
14 | if (tp->ecn_flags&TCP_ECN_OK) | ||
15 | tp->ecn_flags |= TCP_ECN_QUEUE_CWR; | ||
16 | } | ||
17 | |||
18 | |||
19 | /* Output functions */ | ||
20 | |||
21 | static inline void TCP_ECN_send_synack(struct tcp_sock *tp, | ||
22 | struct sk_buff *skb) | ||
23 | { | ||
24 | TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_CWR; | ||
25 | if (!(tp->ecn_flags&TCP_ECN_OK)) | ||
26 | TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_ECE; | ||
27 | } | ||
28 | |||
29 | static inline void TCP_ECN_send_syn(struct sock *sk, struct tcp_sock *tp, | ||
30 | struct sk_buff *skb) | ||
31 | { | ||
32 | tp->ecn_flags = 0; | ||
33 | if (sysctl_tcp_ecn && !(sk->sk_route_caps & NETIF_F_TSO)) { | ||
34 | TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_ECE|TCPCB_FLAG_CWR; | ||
35 | tp->ecn_flags = TCP_ECN_OK; | ||
36 | sock_set_flag(sk, SOCK_NO_LARGESEND); | ||
37 | } | ||
38 | } | ||
39 | |||
40 | static __inline__ void | ||
41 | TCP_ECN_make_synack(struct open_request *req, struct tcphdr *th) | ||
42 | { | ||
43 | if (req->ecn_ok) | ||
44 | th->ece = 1; | ||
45 | } | ||
46 | |||
47 | static inline void TCP_ECN_send(struct sock *sk, struct tcp_sock *tp, | ||
48 | struct sk_buff *skb, int tcp_header_len) | ||
49 | { | ||
50 | if (tp->ecn_flags & TCP_ECN_OK) { | ||
51 | /* Not-retransmitted data segment: set ECT and inject CWR. */ | ||
52 | if (skb->len != tcp_header_len && | ||
53 | !before(TCP_SKB_CB(skb)->seq, tp->snd_nxt)) { | ||
54 | INET_ECN_xmit(sk); | ||
55 | if (tp->ecn_flags&TCP_ECN_QUEUE_CWR) { | ||
56 | tp->ecn_flags &= ~TCP_ECN_QUEUE_CWR; | ||
57 | skb->h.th->cwr = 1; | ||
58 | } | ||
59 | } else { | ||
60 | /* ACK or retransmitted segment: clear ECT|CE */ | ||
61 | INET_ECN_dontxmit(sk); | ||
62 | } | ||
63 | if (tp->ecn_flags & TCP_ECN_DEMAND_CWR) | ||
64 | skb->h.th->ece = 1; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | /* Input functions */ | ||
69 | |||
70 | static inline void TCP_ECN_accept_cwr(struct tcp_sock *tp, struct sk_buff *skb) | ||
71 | { | ||
72 | if (skb->h.th->cwr) | ||
73 | tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR; | ||
74 | } | ||
75 | |||
76 | static inline void TCP_ECN_withdraw_cwr(struct tcp_sock *tp) | ||
77 | { | ||
78 | tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR; | ||
79 | } | ||
80 | |||
81 | static inline void TCP_ECN_check_ce(struct tcp_sock *tp, struct sk_buff *skb) | ||
82 | { | ||
83 | if (tp->ecn_flags&TCP_ECN_OK) { | ||
84 | if (INET_ECN_is_ce(TCP_SKB_CB(skb)->flags)) | ||
85 | tp->ecn_flags |= TCP_ECN_DEMAND_CWR; | ||
86 | /* Funny extension: if ECT is not set on a segment, | ||
87 | * it is surely retransmit. It is not in ECN RFC, | ||
88 | * but Linux follows this rule. */ | ||
89 | else if (INET_ECN_is_not_ect((TCP_SKB_CB(skb)->flags))) | ||
90 | tcp_enter_quickack_mode(tp); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | static inline void TCP_ECN_rcv_synack(struct tcp_sock *tp, struct tcphdr *th) | ||
95 | { | ||
96 | if ((tp->ecn_flags&TCP_ECN_OK) && (!th->ece || th->cwr)) | ||
97 | tp->ecn_flags &= ~TCP_ECN_OK; | ||
98 | } | ||
99 | |||
100 | static inline void TCP_ECN_rcv_syn(struct tcp_sock *tp, struct tcphdr *th) | ||
101 | { | ||
102 | if ((tp->ecn_flags&TCP_ECN_OK) && (!th->ece || !th->cwr)) | ||
103 | tp->ecn_flags &= ~TCP_ECN_OK; | ||
104 | } | ||
105 | |||
106 | static inline int TCP_ECN_rcv_ecn_echo(struct tcp_sock *tp, struct tcphdr *th) | ||
107 | { | ||
108 | if (th->ece && !th->syn && (tp->ecn_flags&TCP_ECN_OK)) | ||
109 | return 1; | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static inline void TCP_ECN_openreq_child(struct tcp_sock *tp, | ||
114 | struct open_request *req) | ||
115 | { | ||
116 | tp->ecn_flags = req->ecn_ok ? TCP_ECN_OK : 0; | ||
117 | } | ||
118 | |||
119 | static __inline__ void | ||
120 | TCP_ECN_create_request(struct open_request *req, struct tcphdr *th) | ||
121 | { | ||
122 | if (sysctl_tcp_ecn && th->ece && th->cwr) | ||
123 | req->ecn_ok = 1; | ||
124 | } | ||
125 | |||
126 | #endif | ||
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h new file mode 100644 index 000000000000..8b075ab7a26c --- /dev/null +++ b/include/net/transp_v6.h | |||
@@ -0,0 +1,53 @@ | |||
1 | #ifndef _TRANSP_V6_H | ||
2 | #define _TRANSP_V6_H | ||
3 | |||
4 | #include <net/checksum.h> | ||
5 | |||
6 | /* | ||
7 | * IPv6 transport protocols | ||
8 | */ | ||
9 | |||
10 | #ifdef __KERNEL__ | ||
11 | |||
12 | extern struct proto rawv6_prot; | ||
13 | extern struct proto udpv6_prot; | ||
14 | extern struct proto tcpv6_prot; | ||
15 | |||
16 | struct flowi; | ||
17 | |||
18 | /* extention headers */ | ||
19 | extern void ipv6_rthdr_init(void); | ||
20 | extern void ipv6_frag_init(void); | ||
21 | extern void ipv6_nodata_init(void); | ||
22 | extern void ipv6_destopt_init(void); | ||
23 | |||
24 | /* transport protocols */ | ||
25 | extern void rawv6_init(void); | ||
26 | extern void udpv6_init(void); | ||
27 | extern void tcpv6_init(void); | ||
28 | |||
29 | extern int udpv6_connect(struct sock *sk, | ||
30 | struct sockaddr *uaddr, | ||
31 | int addr_len); | ||
32 | |||
33 | extern int datagram_recv_ctl(struct sock *sk, | ||
34 | struct msghdr *msg, | ||
35 | struct sk_buff *skb); | ||
36 | |||
37 | extern int datagram_send_ctl(struct msghdr *msg, | ||
38 | struct flowi *fl, | ||
39 | struct ipv6_txoptions *opt, | ||
40 | int *hlimit); | ||
41 | |||
42 | #define LOOPBACK4_IPV6 __constant_htonl(0x7f000006) | ||
43 | |||
44 | /* | ||
45 | * address family specific functions | ||
46 | */ | ||
47 | extern struct tcp_func ipv4_specific; | ||
48 | |||
49 | extern int inet6_destroy_sock(struct sock *sk); | ||
50 | |||
51 | #endif | ||
52 | |||
53 | #endif | ||
diff --git a/include/net/udp.h b/include/net/udp.h new file mode 100644 index 000000000000..c496d10101db --- /dev/null +++ b/include/net/udp.h | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * INET An implementation of the TCP/IP protocol suite for the LINUX | ||
3 | * operating system. INET is implemented using the BSD Socket | ||
4 | * interface as the means of communication with the user level. | ||
5 | * | ||
6 | * Definitions for the UDP module. | ||
7 | * | ||
8 | * Version: @(#)udp.h 1.0.2 05/07/93 | ||
9 | * | ||
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | ||
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | ||
12 | * | ||
13 | * Fixes: | ||
14 | * Alan Cox : Turned on udp checksums. I don't want to | ||
15 | * chase 'memory corruption' bugs that aren't! | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or | ||
18 | * modify it under the terms of the GNU General Public License | ||
19 | * as published by the Free Software Foundation; either version | ||
20 | * 2 of the License, or (at your option) any later version. | ||
21 | */ | ||
22 | #ifndef _UDP_H | ||
23 | #define _UDP_H | ||
24 | |||
25 | #include <linux/udp.h> | ||
26 | #include <linux/ip.h> | ||
27 | #include <linux/list.h> | ||
28 | #include <net/sock.h> | ||
29 | #include <net/snmp.h> | ||
30 | #include <linux/seq_file.h> | ||
31 | |||
32 | #define UDP_HTABLE_SIZE 128 | ||
33 | |||
34 | /* udp.c: This needs to be shared by v4 and v6 because the lookup | ||
35 | * and hashing code needs to work with different AF's yet | ||
36 | * the port space is shared. | ||
37 | */ | ||
38 | extern struct hlist_head udp_hash[UDP_HTABLE_SIZE]; | ||
39 | extern rwlock_t udp_hash_lock; | ||
40 | |||
41 | extern int udp_port_rover; | ||
42 | |||
43 | static inline int udp_lport_inuse(u16 num) | ||
44 | { | ||
45 | struct sock *sk; | ||
46 | struct hlist_node *node; | ||
47 | |||
48 | sk_for_each(sk, node, &udp_hash[num & (UDP_HTABLE_SIZE - 1)]) | ||
49 | if (inet_sk(sk)->num == num) | ||
50 | return 1; | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | /* Note: this must match 'valbool' in sock_setsockopt */ | ||
55 | #define UDP_CSUM_NOXMIT 1 | ||
56 | |||
57 | /* Used by SunRPC/xprt layer. */ | ||
58 | #define UDP_CSUM_NORCV 2 | ||
59 | |||
60 | /* Default, as per the RFC, is to always do csums. */ | ||
61 | #define UDP_CSUM_DEFAULT 0 | ||
62 | |||
63 | extern struct proto udp_prot; | ||
64 | |||
65 | |||
66 | extern void udp_err(struct sk_buff *, u32); | ||
67 | |||
68 | extern int udp_sendmsg(struct kiocb *iocb, struct sock *sk, | ||
69 | struct msghdr *msg, size_t len); | ||
70 | |||
71 | extern int udp_rcv(struct sk_buff *skb); | ||
72 | extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg); | ||
73 | extern int udp_disconnect(struct sock *sk, int flags); | ||
74 | extern unsigned int udp_poll(struct file *file, struct socket *sock, | ||
75 | poll_table *wait); | ||
76 | |||
77 | DECLARE_SNMP_STAT(struct udp_mib, udp_statistics); | ||
78 | #define UDP_INC_STATS(field) SNMP_INC_STATS(udp_statistics, field) | ||
79 | #define UDP_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_statistics, field) | ||
80 | #define UDP_INC_STATS_USER(field) SNMP_INC_STATS_USER(udp_statistics, field) | ||
81 | |||
82 | /* /proc */ | ||
83 | struct udp_seq_afinfo { | ||
84 | struct module *owner; | ||
85 | char *name; | ||
86 | sa_family_t family; | ||
87 | int (*seq_show) (struct seq_file *m, void *v); | ||
88 | struct file_operations *seq_fops; | ||
89 | }; | ||
90 | |||
91 | struct udp_iter_state { | ||
92 | sa_family_t family; | ||
93 | int bucket; | ||
94 | struct seq_operations seq_ops; | ||
95 | }; | ||
96 | |||
97 | extern int udp_proc_register(struct udp_seq_afinfo *afinfo); | ||
98 | extern void udp_proc_unregister(struct udp_seq_afinfo *afinfo); | ||
99 | #endif /* _UDP_H */ | ||
diff --git a/include/net/x25.h b/include/net/x25.h new file mode 100644 index 000000000000..7a1ba5bbb868 --- /dev/null +++ b/include/net/x25.h | |||
@@ -0,0 +1,273 @@ | |||
1 | /* | ||
2 | * Declarations of X.25 Packet Layer type objects. | ||
3 | * | ||
4 | * History | ||
5 | * nov/17/96 Jonathan Naylor Initial version. | ||
6 | * mar/20/00 Daniela Squassoni Disabling/enabling of facilities | ||
7 | * negotiation. | ||
8 | */ | ||
9 | |||
10 | #ifndef _X25_H | ||
11 | #define _X25_H | ||
12 | #include <linux/x25.h> | ||
13 | #include <net/sock.h> | ||
14 | |||
15 | #define X25_ADDR_LEN 16 | ||
16 | |||
17 | #define X25_MAX_L2_LEN 18 /* 802.2 LLC */ | ||
18 | |||
19 | #define X25_STD_MIN_LEN 3 | ||
20 | #define X25_EXT_MIN_LEN 4 | ||
21 | |||
22 | #define X25_GFI_SEQ_MASK 0x30 | ||
23 | #define X25_GFI_STDSEQ 0x10 | ||
24 | #define X25_GFI_EXTSEQ 0x20 | ||
25 | |||
26 | #define X25_Q_BIT 0x80 | ||
27 | #define X25_D_BIT 0x40 | ||
28 | #define X25_STD_M_BIT 0x10 | ||
29 | #define X25_EXT_M_BIT 0x01 | ||
30 | |||
31 | #define X25_CALL_REQUEST 0x0B | ||
32 | #define X25_CALL_ACCEPTED 0x0F | ||
33 | #define X25_CLEAR_REQUEST 0x13 | ||
34 | #define X25_CLEAR_CONFIRMATION 0x17 | ||
35 | #define X25_DATA 0x00 | ||
36 | #define X25_INTERRUPT 0x23 | ||
37 | #define X25_INTERRUPT_CONFIRMATION 0x27 | ||
38 | #define X25_RR 0x01 | ||
39 | #define X25_RNR 0x05 | ||
40 | #define X25_REJ 0x09 | ||
41 | #define X25_RESET_REQUEST 0x1B | ||
42 | #define X25_RESET_CONFIRMATION 0x1F | ||
43 | #define X25_REGISTRATION_REQUEST 0xF3 | ||
44 | #define X25_REGISTRATION_CONFIRMATION 0xF7 | ||
45 | #define X25_RESTART_REQUEST 0xFB | ||
46 | #define X25_RESTART_CONFIRMATION 0xFF | ||
47 | #define X25_DIAGNOSTIC 0xF1 | ||
48 | #define X25_ILLEGAL 0xFD | ||
49 | |||
50 | /* Define the various conditions that may exist */ | ||
51 | |||
52 | #define X25_COND_ACK_PENDING 0x01 | ||
53 | #define X25_COND_OWN_RX_BUSY 0x02 | ||
54 | #define X25_COND_PEER_RX_BUSY 0x04 | ||
55 | |||
56 | /* Define Link State constants. */ | ||
57 | enum { | ||
58 | X25_STATE_0, /* Ready */ | ||
59 | X25_STATE_1, /* Awaiting Call Accepted */ | ||
60 | X25_STATE_2, /* Awaiting Clear Confirmation */ | ||
61 | X25_STATE_3, /* Data Transfer */ | ||
62 | X25_STATE_4 /* Awaiting Reset Confirmation */ | ||
63 | }; | ||
64 | |||
65 | enum { | ||
66 | X25_LINK_STATE_0, | ||
67 | X25_LINK_STATE_1, | ||
68 | X25_LINK_STATE_2, | ||
69 | X25_LINK_STATE_3 | ||
70 | }; | ||
71 | |||
72 | #define X25_DEFAULT_T20 (180 * HZ) /* Default T20 value */ | ||
73 | #define X25_DEFAULT_T21 (200 * HZ) /* Default T21 value */ | ||
74 | #define X25_DEFAULT_T22 (180 * HZ) /* Default T22 value */ | ||
75 | #define X25_DEFAULT_T23 (180 * HZ) /* Default T23 value */ | ||
76 | #define X25_DEFAULT_T2 (3 * HZ) /* Default ack holdback value */ | ||
77 | |||
78 | #define X25_DEFAULT_WINDOW_SIZE 2 /* Default Window Size */ | ||
79 | #define X25_DEFAULT_PACKET_SIZE X25_PS128 /* Default Packet Size */ | ||
80 | #define X25_DEFAULT_THROUGHPUT 0x0A /* Deafult Throughput */ | ||
81 | #define X25_DEFAULT_REVERSE 0x00 /* Default Reverse Charging */ | ||
82 | |||
83 | #define X25_SMODULUS 8 | ||
84 | #define X25_EMODULUS 128 | ||
85 | |||
86 | /* | ||
87 | * X.25 Facilities constants. | ||
88 | */ | ||
89 | |||
90 | #define X25_FAC_CLASS_MASK 0xC0 | ||
91 | |||
92 | #define X25_FAC_CLASS_A 0x00 | ||
93 | #define X25_FAC_CLASS_B 0x40 | ||
94 | #define X25_FAC_CLASS_C 0x80 | ||
95 | #define X25_FAC_CLASS_D 0xC0 | ||
96 | |||
97 | #define X25_FAC_REVERSE 0x01 | ||
98 | #define X25_FAC_THROUGHPUT 0x02 | ||
99 | #define X25_FAC_PACKET_SIZE 0x42 | ||
100 | #define X25_FAC_WINDOW_SIZE 0x43 | ||
101 | |||
102 | #define X25_MAX_FAC_LEN 20 /* Plenty to spare */ | ||
103 | #define X25_MAX_CUD_LEN 128 | ||
104 | |||
105 | /** | ||
106 | * struct x25_route - x25 routing entry | ||
107 | * @node - entry in x25_list_lock | ||
108 | * @address - Start of address range | ||
109 | * @sigdigits - Number of sig digits | ||
110 | * @dev - More than one for MLP | ||
111 | * @refcnt - reference counter | ||
112 | */ | ||
113 | struct x25_route { | ||
114 | struct list_head node; | ||
115 | struct x25_address address; | ||
116 | unsigned int sigdigits; | ||
117 | struct net_device *dev; | ||
118 | atomic_t refcnt; | ||
119 | }; | ||
120 | |||
121 | struct x25_neigh { | ||
122 | struct list_head node; | ||
123 | struct net_device *dev; | ||
124 | unsigned int state; | ||
125 | unsigned int extended; | ||
126 | struct sk_buff_head queue; | ||
127 | unsigned long t20; | ||
128 | struct timer_list t20timer; | ||
129 | unsigned long global_facil_mask; | ||
130 | atomic_t refcnt; | ||
131 | }; | ||
132 | |||
133 | struct x25_sock { | ||
134 | struct sock sk; | ||
135 | struct x25_address source_addr, dest_addr; | ||
136 | struct x25_neigh *neighbour; | ||
137 | unsigned int lci; | ||
138 | unsigned char state, condition, qbitincl, intflag; | ||
139 | unsigned short vs, vr, va, vl; | ||
140 | unsigned long t2, t21, t22, t23; | ||
141 | unsigned short fraglen; | ||
142 | struct sk_buff_head ack_queue; | ||
143 | struct sk_buff_head fragment_queue; | ||
144 | struct sk_buff_head interrupt_in_queue; | ||
145 | struct sk_buff_head interrupt_out_queue; | ||
146 | struct timer_list timer; | ||
147 | struct x25_causediag causediag; | ||
148 | struct x25_facilities facilities; | ||
149 | struct x25_calluserdata calluserdata; | ||
150 | unsigned long vc_facil_mask; /* inc_call facilities mask */ | ||
151 | }; | ||
152 | |||
153 | static inline struct x25_sock *x25_sk(const struct sock *sk) | ||
154 | { | ||
155 | return (struct x25_sock *)sk; | ||
156 | } | ||
157 | |||
158 | /* af_x25.c */ | ||
159 | extern int sysctl_x25_restart_request_timeout; | ||
160 | extern int sysctl_x25_call_request_timeout; | ||
161 | extern int sysctl_x25_reset_request_timeout; | ||
162 | extern int sysctl_x25_clear_request_timeout; | ||
163 | extern int sysctl_x25_ack_holdback_timeout; | ||
164 | |||
165 | extern int x25_addr_ntoa(unsigned char *, struct x25_address *, | ||
166 | struct x25_address *); | ||
167 | extern int x25_addr_aton(unsigned char *, struct x25_address *, | ||
168 | struct x25_address *); | ||
169 | extern struct sock *x25_find_socket(unsigned int, struct x25_neigh *); | ||
170 | extern void x25_destroy_socket(struct sock *); | ||
171 | extern int x25_rx_call_request(struct sk_buff *, struct x25_neigh *, unsigned int); | ||
172 | extern void x25_kill_by_neigh(struct x25_neigh *); | ||
173 | |||
174 | /* x25_dev.c */ | ||
175 | extern void x25_send_frame(struct sk_buff *, struct x25_neigh *); | ||
176 | extern int x25_lapb_receive_frame(struct sk_buff *, struct net_device *, struct packet_type *); | ||
177 | extern void x25_establish_link(struct x25_neigh *); | ||
178 | extern void x25_terminate_link(struct x25_neigh *); | ||
179 | |||
180 | /* x25_facilities.c */ | ||
181 | extern int x25_parse_facilities(struct sk_buff *, struct x25_facilities *, unsigned long *); | ||
182 | extern int x25_create_facilities(unsigned char *, struct x25_facilities *, unsigned long); | ||
183 | extern int x25_negotiate_facilities(struct sk_buff *, struct sock *, struct x25_facilities *); | ||
184 | extern void x25_limit_facilities(struct x25_facilities *, struct x25_neigh *); | ||
185 | |||
186 | /* x25_in.c */ | ||
187 | extern int x25_process_rx_frame(struct sock *, struct sk_buff *); | ||
188 | extern int x25_backlog_rcv(struct sock *, struct sk_buff *); | ||
189 | |||
190 | /* x25_link.c */ | ||
191 | extern void x25_link_control(struct sk_buff *, struct x25_neigh *, unsigned short); | ||
192 | extern void x25_link_device_up(struct net_device *); | ||
193 | extern void x25_link_device_down(struct net_device *); | ||
194 | extern void x25_link_established(struct x25_neigh *); | ||
195 | extern void x25_link_terminated(struct x25_neigh *); | ||
196 | extern void x25_transmit_clear_request(struct x25_neigh *, unsigned int, unsigned char); | ||
197 | extern void x25_transmit_link(struct sk_buff *, struct x25_neigh *); | ||
198 | extern int x25_subscr_ioctl(unsigned int, void __user *); | ||
199 | extern struct x25_neigh *x25_get_neigh(struct net_device *); | ||
200 | extern void x25_link_free(void); | ||
201 | |||
202 | /* x25_neigh.c */ | ||
203 | static __inline__ void x25_neigh_hold(struct x25_neigh *nb) | ||
204 | { | ||
205 | atomic_inc(&nb->refcnt); | ||
206 | } | ||
207 | |||
208 | static __inline__ void x25_neigh_put(struct x25_neigh *nb) | ||
209 | { | ||
210 | if (atomic_dec_and_test(&nb->refcnt)) | ||
211 | kfree(nb); | ||
212 | } | ||
213 | |||
214 | /* x25_out.c */ | ||
215 | extern int x25_output(struct sock *, struct sk_buff *); | ||
216 | extern void x25_kick(struct sock *); | ||
217 | extern void x25_enquiry_response(struct sock *); | ||
218 | |||
219 | /* x25_route.c */ | ||
220 | extern struct x25_route *x25_get_route(struct x25_address *addr); | ||
221 | extern struct net_device *x25_dev_get(char *); | ||
222 | extern void x25_route_device_down(struct net_device *dev); | ||
223 | extern int x25_route_ioctl(unsigned int, void __user *); | ||
224 | extern void x25_route_free(void); | ||
225 | |||
226 | static __inline__ void x25_route_hold(struct x25_route *rt) | ||
227 | { | ||
228 | atomic_inc(&rt->refcnt); | ||
229 | } | ||
230 | |||
231 | static __inline__ void x25_route_put(struct x25_route *rt) | ||
232 | { | ||
233 | if (atomic_dec_and_test(&rt->refcnt)) | ||
234 | kfree(rt); | ||
235 | } | ||
236 | |||
237 | /* x25_subr.c */ | ||
238 | extern void x25_clear_queues(struct sock *); | ||
239 | extern void x25_frames_acked(struct sock *, unsigned short); | ||
240 | extern void x25_requeue_frames(struct sock *); | ||
241 | extern int x25_validate_nr(struct sock *, unsigned short); | ||
242 | extern void x25_write_internal(struct sock *, int); | ||
243 | extern int x25_decode(struct sock *, struct sk_buff *, int *, int *, int *, int *, int *); | ||
244 | extern void x25_disconnect(struct sock *, int, unsigned char, unsigned char); | ||
245 | extern int x25_check_calluserdata(struct x25_calluserdata *,struct x25_calluserdata *); | ||
246 | |||
247 | /* x25_timer.c */ | ||
248 | extern void x25_start_heartbeat(struct sock *); | ||
249 | extern void x25_start_t2timer(struct sock *); | ||
250 | extern void x25_start_t21timer(struct sock *); | ||
251 | extern void x25_start_t22timer(struct sock *); | ||
252 | extern void x25_start_t23timer(struct sock *); | ||
253 | extern void x25_stop_heartbeat(struct sock *); | ||
254 | extern void x25_stop_timer(struct sock *); | ||
255 | extern unsigned long x25_display_timer(struct sock *); | ||
256 | extern void x25_check_rbuf(struct sock *); | ||
257 | |||
258 | /* sysctl_net_x25.c */ | ||
259 | extern void x25_register_sysctl(void); | ||
260 | extern void x25_unregister_sysctl(void); | ||
261 | struct x25_skb_cb { | ||
262 | unsigned flags; | ||
263 | }; | ||
264 | #define X25_SKB_CB(s) ((struct x25_skb_cb *) ((s)->cb)) | ||
265 | |||
266 | extern struct hlist_head x25_list; | ||
267 | extern rwlock_t x25_list_lock; | ||
268 | extern struct list_head x25_route_list; | ||
269 | extern rwlock_t x25_route_list_lock; | ||
270 | |||
271 | extern int x25_proc_init(void); | ||
272 | extern void x25_proc_exit(void); | ||
273 | #endif | ||
diff --git a/include/net/x25device.h b/include/net/x25device.h new file mode 100644 index 000000000000..cf36a20ea3c5 --- /dev/null +++ b/include/net/x25device.h | |||
@@ -0,0 +1,17 @@ | |||
1 | #ifndef _X25DEVICE_H | ||
2 | #define _X25DEVICE_H | ||
3 | |||
4 | #include <linux/if_ether.h> | ||
5 | #include <linux/if_packet.h> | ||
6 | #include <linux/skbuff.h> | ||
7 | |||
8 | static inline unsigned short x25_type_trans(struct sk_buff *skb, | ||
9 | struct net_device *dev) | ||
10 | { | ||
11 | skb->mac.raw = skb->data; | ||
12 | skb->input_dev = skb->dev = dev; | ||
13 | skb->pkt_type = PACKET_HOST; | ||
14 | |||
15 | return htons(ETH_P_X25); | ||
16 | } | ||
17 | #endif | ||
diff --git a/include/net/xfrm.h b/include/net/xfrm.h new file mode 100644 index 000000000000..73e9a8ca3d3b --- /dev/null +++ b/include/net/xfrm.h | |||
@@ -0,0 +1,905 @@ | |||
1 | #ifndef _NET_XFRM_H | ||
2 | #define _NET_XFRM_H | ||
3 | |||
4 | #include <linux/xfrm.h> | ||
5 | #include <linux/spinlock.h> | ||
6 | #include <linux/list.h> | ||
7 | #include <linux/skbuff.h> | ||
8 | #include <linux/netdevice.h> | ||
9 | #include <linux/crypto.h> | ||
10 | #include <linux/pfkeyv2.h> | ||
11 | #include <linux/in6.h> | ||
12 | |||
13 | #include <net/sock.h> | ||
14 | #include <net/dst.h> | ||
15 | #include <net/route.h> | ||
16 | #include <net/ipv6.h> | ||
17 | #include <net/ip6_fib.h> | ||
18 | |||
19 | #define XFRM_ALIGN8(len) (((len) + 7) & ~7) | ||
20 | |||
21 | extern struct semaphore xfrm_cfg_sem; | ||
22 | |||
23 | /* Organization of SPD aka "XFRM rules" | ||
24 | ------------------------------------ | ||
25 | |||
26 | Basic objects: | ||
27 | - policy rule, struct xfrm_policy (=SPD entry) | ||
28 | - bundle of transformations, struct dst_entry == struct xfrm_dst (=SA bundle) | ||
29 | - instance of a transformer, struct xfrm_state (=SA) | ||
30 | - template to clone xfrm_state, struct xfrm_tmpl | ||
31 | |||
32 | SPD is plain linear list of xfrm_policy rules, ordered by priority. | ||
33 | (To be compatible with existing pfkeyv2 implementations, | ||
34 | many rules with priority of 0x7fffffff are allowed to exist and | ||
35 | such rules are ordered in an unpredictable way, thanks to bsd folks.) | ||
36 | |||
37 | Lookup is plain linear search until the first match with selector. | ||
38 | |||
39 | If "action" is "block", then we prohibit the flow, otherwise: | ||
40 | if "xfrms_nr" is zero, the flow passes untransformed. Otherwise, | ||
41 | policy entry has list of up to XFRM_MAX_DEPTH transformations, | ||
42 | described by templates xfrm_tmpl. Each template is resolved | ||
43 | to a complete xfrm_state (see below) and we pack bundle of transformations | ||
44 | to a dst_entry returned to requestor. | ||
45 | |||
46 | dst -. xfrm .-> xfrm_state #1 | ||
47 | |---. child .-> dst -. xfrm .-> xfrm_state #2 | ||
48 | |---. child .-> dst -. xfrm .-> xfrm_state #3 | ||
49 | |---. child .-> NULL | ||
50 | |||
51 | Bundles are cached at xrfm_policy struct (field ->bundles). | ||
52 | |||
53 | |||
54 | Resolution of xrfm_tmpl | ||
55 | ----------------------- | ||
56 | Template contains: | ||
57 | 1. ->mode Mode: transport or tunnel | ||
58 | 2. ->id.proto Protocol: AH/ESP/IPCOMP | ||
59 | 3. ->id.daddr Remote tunnel endpoint, ignored for transport mode. | ||
60 | Q: allow to resolve security gateway? | ||
61 | 4. ->id.spi If not zero, static SPI. | ||
62 | 5. ->saddr Local tunnel endpoint, ignored for transport mode. | ||
63 | 6. ->algos List of allowed algos. Plain bitmask now. | ||
64 | Q: ealgos, aalgos, calgos. What a mess... | ||
65 | 7. ->share Sharing mode. | ||
66 | Q: how to implement private sharing mode? To add struct sock* to | ||
67 | flow id? | ||
68 | |||
69 | Having this template we search through SAD searching for entries | ||
70 | with appropriate mode/proto/algo, permitted by selector. | ||
71 | If no appropriate entry found, it is requested from key manager. | ||
72 | |||
73 | PROBLEMS: | ||
74 | Q: How to find all the bundles referring to a physical path for | ||
75 | PMTU discovery? Seems, dst should contain list of all parents... | ||
76 | and enter to infinite locking hierarchy disaster. | ||
77 | No! It is easier, we will not search for them, let them find us. | ||
78 | We add genid to each dst plus pointer to genid of raw IP route, | ||
79 | pmtu disc will update pmtu on raw IP route and increase its genid. | ||
80 | dst_check() will see this for top level and trigger resyncing | ||
81 | metrics. Plus, it will be made via sk->sk_dst_cache. Solved. | ||
82 | */ | ||
83 | |||
84 | /* Full description of state of transformer. */ | ||
85 | struct xfrm_state | ||
86 | { | ||
87 | /* Note: bydst is re-used during gc */ | ||
88 | struct list_head bydst; | ||
89 | struct list_head byspi; | ||
90 | |||
91 | atomic_t refcnt; | ||
92 | spinlock_t lock; | ||
93 | |||
94 | struct xfrm_id id; | ||
95 | struct xfrm_selector sel; | ||
96 | |||
97 | /* Key manger bits */ | ||
98 | struct { | ||
99 | u8 state; | ||
100 | u8 dying; | ||
101 | u32 seq; | ||
102 | } km; | ||
103 | |||
104 | /* Parameters of this state. */ | ||
105 | struct { | ||
106 | u32 reqid; | ||
107 | u8 mode; | ||
108 | u8 replay_window; | ||
109 | u8 aalgo, ealgo, calgo; | ||
110 | u8 flags; | ||
111 | u16 family; | ||
112 | xfrm_address_t saddr; | ||
113 | int header_len; | ||
114 | int trailer_len; | ||
115 | } props; | ||
116 | |||
117 | struct xfrm_lifetime_cfg lft; | ||
118 | |||
119 | /* Data for transformer */ | ||
120 | struct xfrm_algo *aalg; | ||
121 | struct xfrm_algo *ealg; | ||
122 | struct xfrm_algo *calg; | ||
123 | |||
124 | /* Data for encapsulator */ | ||
125 | struct xfrm_encap_tmpl *encap; | ||
126 | |||
127 | /* IPComp needs an IPIP tunnel for handling uncompressed packets */ | ||
128 | struct xfrm_state *tunnel; | ||
129 | |||
130 | /* If a tunnel, number of users + 1 */ | ||
131 | atomic_t tunnel_users; | ||
132 | |||
133 | /* State for replay detection */ | ||
134 | struct xfrm_replay_state replay; | ||
135 | |||
136 | /* Statistics */ | ||
137 | struct xfrm_stats stats; | ||
138 | |||
139 | struct xfrm_lifetime_cur curlft; | ||
140 | struct timer_list timer; | ||
141 | |||
142 | /* Reference to data common to all the instances of this | ||
143 | * transformer. */ | ||
144 | struct xfrm_type *type; | ||
145 | |||
146 | /* Private data of this transformer, format is opaque, | ||
147 | * interpreted by xfrm_type methods. */ | ||
148 | void *data; | ||
149 | }; | ||
150 | |||
151 | enum { | ||
152 | XFRM_STATE_VOID, | ||
153 | XFRM_STATE_ACQ, | ||
154 | XFRM_STATE_VALID, | ||
155 | XFRM_STATE_ERROR, | ||
156 | XFRM_STATE_EXPIRED, | ||
157 | XFRM_STATE_DEAD | ||
158 | }; | ||
159 | |||
160 | struct xfrm_type; | ||
161 | struct xfrm_dst; | ||
162 | struct xfrm_policy_afinfo { | ||
163 | unsigned short family; | ||
164 | rwlock_t lock; | ||
165 | struct xfrm_type_map *type_map; | ||
166 | struct dst_ops *dst_ops; | ||
167 | void (*garbage_collect)(void); | ||
168 | int (*dst_lookup)(struct xfrm_dst **dst, struct flowi *fl); | ||
169 | struct dst_entry *(*find_bundle)(struct flowi *fl, struct xfrm_policy *policy); | ||
170 | int (*bundle_create)(struct xfrm_policy *policy, | ||
171 | struct xfrm_state **xfrm, | ||
172 | int nx, | ||
173 | struct flowi *fl, | ||
174 | struct dst_entry **dst_p); | ||
175 | void (*decode_session)(struct sk_buff *skb, | ||
176 | struct flowi *fl); | ||
177 | }; | ||
178 | |||
179 | extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo); | ||
180 | extern int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo); | ||
181 | |||
182 | #define XFRM_ACQ_EXPIRES 30 | ||
183 | |||
184 | struct xfrm_tmpl; | ||
185 | struct xfrm_state_afinfo { | ||
186 | unsigned short family; | ||
187 | rwlock_t lock; | ||
188 | struct list_head *state_bydst; | ||
189 | struct list_head *state_byspi; | ||
190 | void (*init_tempsel)(struct xfrm_state *x, struct flowi *fl, | ||
191 | struct xfrm_tmpl *tmpl, | ||
192 | xfrm_address_t *daddr, xfrm_address_t *saddr); | ||
193 | struct xfrm_state *(*state_lookup)(xfrm_address_t *daddr, u32 spi, u8 proto); | ||
194 | struct xfrm_state *(*find_acq)(u8 mode, u32 reqid, u8 proto, | ||
195 | xfrm_address_t *daddr, xfrm_address_t *saddr, | ||
196 | int create); | ||
197 | }; | ||
198 | |||
199 | extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo); | ||
200 | extern int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo); | ||
201 | |||
202 | extern void xfrm_state_delete_tunnel(struct xfrm_state *x); | ||
203 | |||
204 | struct xfrm_decap_state; | ||
205 | struct xfrm_type | ||
206 | { | ||
207 | char *description; | ||
208 | struct module *owner; | ||
209 | __u8 proto; | ||
210 | |||
211 | int (*init_state)(struct xfrm_state *x, void *args); | ||
212 | void (*destructor)(struct xfrm_state *); | ||
213 | int (*input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb); | ||
214 | int (*post_input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb); | ||
215 | int (*output)(struct xfrm_state *, struct sk_buff *pskb); | ||
216 | /* Estimate maximal size of result of transformation of a dgram */ | ||
217 | u32 (*get_max_size)(struct xfrm_state *, int size); | ||
218 | }; | ||
219 | |||
220 | struct xfrm_type_map { | ||
221 | rwlock_t lock; | ||
222 | struct xfrm_type *map[256]; | ||
223 | }; | ||
224 | |||
225 | extern int xfrm_register_type(struct xfrm_type *type, unsigned short family); | ||
226 | extern int xfrm_unregister_type(struct xfrm_type *type, unsigned short family); | ||
227 | extern struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family); | ||
228 | extern void xfrm_put_type(struct xfrm_type *type); | ||
229 | |||
230 | struct xfrm_tmpl | ||
231 | { | ||
232 | /* id in template is interpreted as: | ||
233 | * daddr - destination of tunnel, may be zero for transport mode. | ||
234 | * spi - zero to acquire spi. Not zero if spi is static, then | ||
235 | * daddr must be fixed too. | ||
236 | * proto - AH/ESP/IPCOMP | ||
237 | */ | ||
238 | struct xfrm_id id; | ||
239 | |||
240 | /* Source address of tunnel. Ignored, if it is not a tunnel. */ | ||
241 | xfrm_address_t saddr; | ||
242 | |||
243 | __u32 reqid; | ||
244 | |||
245 | /* Mode: transport/tunnel */ | ||
246 | __u8 mode; | ||
247 | |||
248 | /* Sharing mode: unique, this session only, this user only etc. */ | ||
249 | __u8 share; | ||
250 | |||
251 | /* May skip this transfomration if no SA is found */ | ||
252 | __u8 optional; | ||
253 | |||
254 | /* Bit mask of algos allowed for acquisition */ | ||
255 | __u32 aalgos; | ||
256 | __u32 ealgos; | ||
257 | __u32 calgos; | ||
258 | }; | ||
259 | |||
260 | #define XFRM_MAX_DEPTH 4 | ||
261 | |||
262 | struct xfrm_policy | ||
263 | { | ||
264 | struct xfrm_policy *next; | ||
265 | struct list_head list; | ||
266 | |||
267 | /* This lock only affects elements except for entry. */ | ||
268 | rwlock_t lock; | ||
269 | atomic_t refcnt; | ||
270 | struct timer_list timer; | ||
271 | |||
272 | u32 priority; | ||
273 | u32 index; | ||
274 | struct xfrm_selector selector; | ||
275 | struct xfrm_lifetime_cfg lft; | ||
276 | struct xfrm_lifetime_cur curlft; | ||
277 | struct dst_entry *bundles; | ||
278 | __u16 family; | ||
279 | __u8 action; | ||
280 | __u8 flags; | ||
281 | __u8 dead; | ||
282 | __u8 xfrm_nr; | ||
283 | struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH]; | ||
284 | }; | ||
285 | |||
286 | #define XFRM_KM_TIMEOUT 30 | ||
287 | |||
288 | struct xfrm_mgr | ||
289 | { | ||
290 | struct list_head list; | ||
291 | char *id; | ||
292 | int (*notify)(struct xfrm_state *x, int event); | ||
293 | int (*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp, int dir); | ||
294 | struct xfrm_policy *(*compile_policy)(u16 family, int opt, u8 *data, int len, int *dir); | ||
295 | int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport); | ||
296 | int (*notify_policy)(struct xfrm_policy *x, int dir, int event); | ||
297 | }; | ||
298 | |||
299 | extern int xfrm_register_km(struct xfrm_mgr *km); | ||
300 | extern int xfrm_unregister_km(struct xfrm_mgr *km); | ||
301 | |||
302 | |||
303 | extern struct xfrm_policy *xfrm_policy_list[XFRM_POLICY_MAX*2]; | ||
304 | |||
305 | static inline void xfrm_pol_hold(struct xfrm_policy *policy) | ||
306 | { | ||
307 | if (likely(policy != NULL)) | ||
308 | atomic_inc(&policy->refcnt); | ||
309 | } | ||
310 | |||
311 | extern void __xfrm_policy_destroy(struct xfrm_policy *policy); | ||
312 | |||
313 | static inline void xfrm_pol_put(struct xfrm_policy *policy) | ||
314 | { | ||
315 | if (atomic_dec_and_test(&policy->refcnt)) | ||
316 | __xfrm_policy_destroy(policy); | ||
317 | } | ||
318 | |||
319 | #define XFRM_DST_HSIZE 1024 | ||
320 | |||
321 | static __inline__ | ||
322 | unsigned __xfrm4_dst_hash(xfrm_address_t *addr) | ||
323 | { | ||
324 | unsigned h; | ||
325 | h = ntohl(addr->a4); | ||
326 | h = (h ^ (h>>16)) % XFRM_DST_HSIZE; | ||
327 | return h; | ||
328 | } | ||
329 | |||
330 | static __inline__ | ||
331 | unsigned __xfrm6_dst_hash(xfrm_address_t *addr) | ||
332 | { | ||
333 | unsigned h; | ||
334 | h = ntohl(addr->a6[2]^addr->a6[3]); | ||
335 | h = (h ^ (h>>16)) % XFRM_DST_HSIZE; | ||
336 | return h; | ||
337 | } | ||
338 | |||
339 | static __inline__ | ||
340 | unsigned xfrm_dst_hash(xfrm_address_t *addr, unsigned short family) | ||
341 | { | ||
342 | switch (family) { | ||
343 | case AF_INET: | ||
344 | return __xfrm4_dst_hash(addr); | ||
345 | case AF_INET6: | ||
346 | return __xfrm6_dst_hash(addr); | ||
347 | } | ||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static __inline__ | ||
352 | unsigned __xfrm4_spi_hash(xfrm_address_t *addr, u32 spi, u8 proto) | ||
353 | { | ||
354 | unsigned h; | ||
355 | h = ntohl(addr->a4^spi^proto); | ||
356 | h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE; | ||
357 | return h; | ||
358 | } | ||
359 | |||
360 | static __inline__ | ||
361 | unsigned __xfrm6_spi_hash(xfrm_address_t *addr, u32 spi, u8 proto) | ||
362 | { | ||
363 | unsigned h; | ||
364 | h = ntohl(addr->a6[2]^addr->a6[3]^spi^proto); | ||
365 | h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE; | ||
366 | return h; | ||
367 | } | ||
368 | |||
369 | static __inline__ | ||
370 | unsigned xfrm_spi_hash(xfrm_address_t *addr, u32 spi, u8 proto, unsigned short family) | ||
371 | { | ||
372 | switch (family) { | ||
373 | case AF_INET: | ||
374 | return __xfrm4_spi_hash(addr, spi, proto); | ||
375 | case AF_INET6: | ||
376 | return __xfrm6_spi_hash(addr, spi, proto); | ||
377 | } | ||
378 | return 0; /*XXX*/ | ||
379 | } | ||
380 | |||
381 | extern void __xfrm_state_destroy(struct xfrm_state *); | ||
382 | |||
383 | static inline void xfrm_state_put(struct xfrm_state *x) | ||
384 | { | ||
385 | if (atomic_dec_and_test(&x->refcnt)) | ||
386 | __xfrm_state_destroy(x); | ||
387 | } | ||
388 | |||
389 | static inline void xfrm_state_hold(struct xfrm_state *x) | ||
390 | { | ||
391 | atomic_inc(&x->refcnt); | ||
392 | } | ||
393 | |||
394 | static __inline__ int addr_match(void *token1, void *token2, int prefixlen) | ||
395 | { | ||
396 | __u32 *a1 = token1; | ||
397 | __u32 *a2 = token2; | ||
398 | int pdw; | ||
399 | int pbi; | ||
400 | |||
401 | pdw = prefixlen >> 5; /* num of whole __u32 in prefix */ | ||
402 | pbi = prefixlen & 0x1f; /* num of bits in incomplete u32 in prefix */ | ||
403 | |||
404 | if (pdw) | ||
405 | if (memcmp(a1, a2, pdw << 2)) | ||
406 | return 0; | ||
407 | |||
408 | if (pbi) { | ||
409 | __u32 mask; | ||
410 | |||
411 | mask = htonl((0xffffffff) << (32 - pbi)); | ||
412 | |||
413 | if ((a1[pdw] ^ a2[pdw]) & mask) | ||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | return 1; | ||
418 | } | ||
419 | |||
420 | static __inline__ | ||
421 | u16 xfrm_flowi_sport(struct flowi *fl) | ||
422 | { | ||
423 | u16 port; | ||
424 | switch(fl->proto) { | ||
425 | case IPPROTO_TCP: | ||
426 | case IPPROTO_UDP: | ||
427 | case IPPROTO_SCTP: | ||
428 | port = fl->fl_ip_sport; | ||
429 | break; | ||
430 | case IPPROTO_ICMP: | ||
431 | case IPPROTO_ICMPV6: | ||
432 | port = htons(fl->fl_icmp_type); | ||
433 | break; | ||
434 | default: | ||
435 | port = 0; /*XXX*/ | ||
436 | } | ||
437 | return port; | ||
438 | } | ||
439 | |||
440 | static __inline__ | ||
441 | u16 xfrm_flowi_dport(struct flowi *fl) | ||
442 | { | ||
443 | u16 port; | ||
444 | switch(fl->proto) { | ||
445 | case IPPROTO_TCP: | ||
446 | case IPPROTO_UDP: | ||
447 | case IPPROTO_SCTP: | ||
448 | port = fl->fl_ip_dport; | ||
449 | break; | ||
450 | case IPPROTO_ICMP: | ||
451 | case IPPROTO_ICMPV6: | ||
452 | port = htons(fl->fl_icmp_code); | ||
453 | break; | ||
454 | default: | ||
455 | port = 0; /*XXX*/ | ||
456 | } | ||
457 | return port; | ||
458 | } | ||
459 | |||
460 | static inline int | ||
461 | __xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl) | ||
462 | { | ||
463 | return addr_match(&fl->fl4_dst, &sel->daddr, sel->prefixlen_d) && | ||
464 | addr_match(&fl->fl4_src, &sel->saddr, sel->prefixlen_s) && | ||
465 | !((xfrm_flowi_dport(fl) ^ sel->dport) & sel->dport_mask) && | ||
466 | !((xfrm_flowi_sport(fl) ^ sel->sport) & sel->sport_mask) && | ||
467 | (fl->proto == sel->proto || !sel->proto) && | ||
468 | (fl->oif == sel->ifindex || !sel->ifindex); | ||
469 | } | ||
470 | |||
471 | static inline int | ||
472 | __xfrm6_selector_match(struct xfrm_selector *sel, struct flowi *fl) | ||
473 | { | ||
474 | return addr_match(&fl->fl6_dst, &sel->daddr, sel->prefixlen_d) && | ||
475 | addr_match(&fl->fl6_src, &sel->saddr, sel->prefixlen_s) && | ||
476 | !((xfrm_flowi_dport(fl) ^ sel->dport) & sel->dport_mask) && | ||
477 | !((xfrm_flowi_sport(fl) ^ sel->sport) & sel->sport_mask) && | ||
478 | (fl->proto == sel->proto || !sel->proto) && | ||
479 | (fl->oif == sel->ifindex || !sel->ifindex); | ||
480 | } | ||
481 | |||
482 | static inline int | ||
483 | xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl, | ||
484 | unsigned short family) | ||
485 | { | ||
486 | switch (family) { | ||
487 | case AF_INET: | ||
488 | return __xfrm4_selector_match(sel, fl); | ||
489 | case AF_INET6: | ||
490 | return __xfrm6_selector_match(sel, fl); | ||
491 | } | ||
492 | return 0; | ||
493 | } | ||
494 | |||
495 | /* A struct encoding bundle of transformations to apply to some set of flow. | ||
496 | * | ||
497 | * dst->child points to the next element of bundle. | ||
498 | * dst->xfrm points to an instanse of transformer. | ||
499 | * | ||
500 | * Due to unfortunate limitations of current routing cache, which we | ||
501 | * have no time to fix, it mirrors struct rtable and bound to the same | ||
502 | * routing key, including saddr,daddr. However, we can have many of | ||
503 | * bundles differing by session id. All the bundles grow from a parent | ||
504 | * policy rule. | ||
505 | */ | ||
506 | struct xfrm_dst | ||
507 | { | ||
508 | union { | ||
509 | struct xfrm_dst *next; | ||
510 | struct dst_entry dst; | ||
511 | struct rtable rt; | ||
512 | struct rt6_info rt6; | ||
513 | } u; | ||
514 | struct dst_entry *route; | ||
515 | u32 route_mtu_cached; | ||
516 | u32 child_mtu_cached; | ||
517 | }; | ||
518 | |||
519 | /* Decapsulation state, used by the input to store data during | ||
520 | * decapsulation procedure, to be used later (during the policy | ||
521 | * check | ||
522 | */ | ||
523 | struct xfrm_decap_state { | ||
524 | char decap_data[20]; | ||
525 | __u16 decap_type; | ||
526 | }; | ||
527 | |||
528 | struct sec_decap_state { | ||
529 | struct xfrm_state *xvec; | ||
530 | struct xfrm_decap_state decap; | ||
531 | }; | ||
532 | |||
533 | struct sec_path | ||
534 | { | ||
535 | atomic_t refcnt; | ||
536 | int len; | ||
537 | struct sec_decap_state x[XFRM_MAX_DEPTH]; | ||
538 | }; | ||
539 | |||
540 | static inline struct sec_path * | ||
541 | secpath_get(struct sec_path *sp) | ||
542 | { | ||
543 | if (sp) | ||
544 | atomic_inc(&sp->refcnt); | ||
545 | return sp; | ||
546 | } | ||
547 | |||
548 | extern void __secpath_destroy(struct sec_path *sp); | ||
549 | |||
550 | static inline void | ||
551 | secpath_put(struct sec_path *sp) | ||
552 | { | ||
553 | if (sp && atomic_dec_and_test(&sp->refcnt)) | ||
554 | __secpath_destroy(sp); | ||
555 | } | ||
556 | |||
557 | extern struct sec_path *secpath_dup(struct sec_path *src); | ||
558 | |||
559 | static inline void | ||
560 | secpath_reset(struct sk_buff *skb) | ||
561 | { | ||
562 | #ifdef CONFIG_XFRM | ||
563 | secpath_put(skb->sp); | ||
564 | skb->sp = NULL; | ||
565 | #endif | ||
566 | } | ||
567 | |||
568 | static inline int | ||
569 | __xfrm4_state_addr_cmp(struct xfrm_tmpl *tmpl, struct xfrm_state *x) | ||
570 | { | ||
571 | return (tmpl->saddr.a4 && | ||
572 | tmpl->saddr.a4 != x->props.saddr.a4); | ||
573 | } | ||
574 | |||
575 | static inline int | ||
576 | __xfrm6_state_addr_cmp(struct xfrm_tmpl *tmpl, struct xfrm_state *x) | ||
577 | { | ||
578 | return (!ipv6_addr_any((struct in6_addr*)&tmpl->saddr) && | ||
579 | ipv6_addr_cmp((struct in6_addr *)&tmpl->saddr, (struct in6_addr*)&x->props.saddr)); | ||
580 | } | ||
581 | |||
582 | static inline int | ||
583 | xfrm_state_addr_cmp(struct xfrm_tmpl *tmpl, struct xfrm_state *x, unsigned short family) | ||
584 | { | ||
585 | switch (family) { | ||
586 | case AF_INET: | ||
587 | return __xfrm4_state_addr_cmp(tmpl, x); | ||
588 | case AF_INET6: | ||
589 | return __xfrm6_state_addr_cmp(tmpl, x); | ||
590 | } | ||
591 | return !0; | ||
592 | } | ||
593 | |||
594 | #ifdef CONFIG_XFRM | ||
595 | |||
596 | extern int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb, unsigned short family); | ||
597 | |||
598 | static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family) | ||
599 | { | ||
600 | if (sk && sk->sk_policy[XFRM_POLICY_IN]) | ||
601 | return __xfrm_policy_check(sk, dir, skb, family); | ||
602 | |||
603 | return (!xfrm_policy_list[dir] && !skb->sp) || | ||
604 | (skb->dst->flags & DST_NOPOLICY) || | ||
605 | __xfrm_policy_check(sk, dir, skb, family); | ||
606 | } | ||
607 | |||
608 | static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb) | ||
609 | { | ||
610 | return xfrm_policy_check(sk, dir, skb, AF_INET); | ||
611 | } | ||
612 | |||
613 | static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) | ||
614 | { | ||
615 | return xfrm_policy_check(sk, dir, skb, AF_INET6); | ||
616 | } | ||
617 | |||
618 | |||
619 | extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family); | ||
620 | |||
621 | static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family) | ||
622 | { | ||
623 | return !xfrm_policy_list[XFRM_POLICY_OUT] || | ||
624 | (skb->dst->flags & DST_NOXFRM) || | ||
625 | __xfrm_route_forward(skb, family); | ||
626 | } | ||
627 | |||
628 | static inline int xfrm4_route_forward(struct sk_buff *skb) | ||
629 | { | ||
630 | return xfrm_route_forward(skb, AF_INET); | ||
631 | } | ||
632 | |||
633 | static inline int xfrm6_route_forward(struct sk_buff *skb) | ||
634 | { | ||
635 | return xfrm_route_forward(skb, AF_INET6); | ||
636 | } | ||
637 | |||
638 | extern int __xfrm_sk_clone_policy(struct sock *sk); | ||
639 | |||
640 | static inline int xfrm_sk_clone_policy(struct sock *sk) | ||
641 | { | ||
642 | if (unlikely(sk->sk_policy[0] || sk->sk_policy[1])) | ||
643 | return __xfrm_sk_clone_policy(sk); | ||
644 | return 0; | ||
645 | } | ||
646 | |||
647 | extern void xfrm_policy_delete(struct xfrm_policy *pol, int dir); | ||
648 | |||
649 | static inline void xfrm_sk_free_policy(struct sock *sk) | ||
650 | { | ||
651 | if (unlikely(sk->sk_policy[0] != NULL)) { | ||
652 | xfrm_policy_delete(sk->sk_policy[0], XFRM_POLICY_MAX); | ||
653 | sk->sk_policy[0] = NULL; | ||
654 | } | ||
655 | if (unlikely(sk->sk_policy[1] != NULL)) { | ||
656 | xfrm_policy_delete(sk->sk_policy[1], XFRM_POLICY_MAX+1); | ||
657 | sk->sk_policy[1] = NULL; | ||
658 | } | ||
659 | } | ||
660 | |||
661 | #else | ||
662 | |||
663 | static inline void xfrm_sk_free_policy(struct sock *sk) {} | ||
664 | static inline int xfrm_sk_clone_policy(struct sock *sk) { return 0; } | ||
665 | static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; } | ||
666 | static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; } | ||
667 | static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) | ||
668 | { | ||
669 | return 1; | ||
670 | } | ||
671 | static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb) | ||
672 | { | ||
673 | return 1; | ||
674 | } | ||
675 | static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family) | ||
676 | { | ||
677 | return 1; | ||
678 | } | ||
679 | #endif | ||
680 | |||
681 | static __inline__ | ||
682 | xfrm_address_t *xfrm_flowi_daddr(struct flowi *fl, unsigned short family) | ||
683 | { | ||
684 | switch (family){ | ||
685 | case AF_INET: | ||
686 | return (xfrm_address_t *)&fl->fl4_dst; | ||
687 | case AF_INET6: | ||
688 | return (xfrm_address_t *)&fl->fl6_dst; | ||
689 | } | ||
690 | return NULL; | ||
691 | } | ||
692 | |||
693 | static __inline__ | ||
694 | xfrm_address_t *xfrm_flowi_saddr(struct flowi *fl, unsigned short family) | ||
695 | { | ||
696 | switch (family){ | ||
697 | case AF_INET: | ||
698 | return (xfrm_address_t *)&fl->fl4_src; | ||
699 | case AF_INET6: | ||
700 | return (xfrm_address_t *)&fl->fl6_src; | ||
701 | } | ||
702 | return NULL; | ||
703 | } | ||
704 | |||
705 | static __inline__ int | ||
706 | __xfrm4_state_addr_check(struct xfrm_state *x, | ||
707 | xfrm_address_t *daddr, xfrm_address_t *saddr) | ||
708 | { | ||
709 | if (daddr->a4 == x->id.daddr.a4 && | ||
710 | (saddr->a4 == x->props.saddr.a4 || !saddr->a4 || !x->props.saddr.a4)) | ||
711 | return 1; | ||
712 | return 0; | ||
713 | } | ||
714 | |||
715 | static __inline__ int | ||
716 | __xfrm6_state_addr_check(struct xfrm_state *x, | ||
717 | xfrm_address_t *daddr, xfrm_address_t *saddr) | ||
718 | { | ||
719 | if (!ipv6_addr_cmp((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) && | ||
720 | (!ipv6_addr_cmp((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr)|| | ||
721 | ipv6_addr_any((struct in6_addr *)saddr) || | ||
722 | ipv6_addr_any((struct in6_addr *)&x->props.saddr))) | ||
723 | return 1; | ||
724 | return 0; | ||
725 | } | ||
726 | |||
727 | static __inline__ int | ||
728 | xfrm_state_addr_check(struct xfrm_state *x, | ||
729 | xfrm_address_t *daddr, xfrm_address_t *saddr, | ||
730 | unsigned short family) | ||
731 | { | ||
732 | switch (family) { | ||
733 | case AF_INET: | ||
734 | return __xfrm4_state_addr_check(x, daddr, saddr); | ||
735 | case AF_INET6: | ||
736 | return __xfrm6_state_addr_check(x, daddr, saddr); | ||
737 | } | ||
738 | return 0; | ||
739 | } | ||
740 | |||
741 | static inline int xfrm_state_kern(struct xfrm_state *x) | ||
742 | { | ||
743 | return atomic_read(&x->tunnel_users); | ||
744 | } | ||
745 | |||
746 | /* | ||
747 | * xfrm algorithm information | ||
748 | */ | ||
749 | struct xfrm_algo_auth_info { | ||
750 | u16 icv_truncbits; | ||
751 | u16 icv_fullbits; | ||
752 | }; | ||
753 | |||
754 | struct xfrm_algo_encr_info { | ||
755 | u16 blockbits; | ||
756 | u16 defkeybits; | ||
757 | }; | ||
758 | |||
759 | struct xfrm_algo_comp_info { | ||
760 | u16 threshold; | ||
761 | }; | ||
762 | |||
763 | struct xfrm_algo_desc { | ||
764 | char *name; | ||
765 | u8 available:1; | ||
766 | union { | ||
767 | struct xfrm_algo_auth_info auth; | ||
768 | struct xfrm_algo_encr_info encr; | ||
769 | struct xfrm_algo_comp_info comp; | ||
770 | } uinfo; | ||
771 | struct sadb_alg desc; | ||
772 | }; | ||
773 | |||
774 | /* XFRM tunnel handlers. */ | ||
775 | struct xfrm_tunnel { | ||
776 | int (*handler)(struct sk_buff *skb); | ||
777 | void (*err_handler)(struct sk_buff *skb, void *info); | ||
778 | }; | ||
779 | |||
780 | struct xfrm6_tunnel { | ||
781 | int (*handler)(struct sk_buff **pskb, unsigned int *nhoffp); | ||
782 | void (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt, | ||
783 | int type, int code, int offset, __u32 info); | ||
784 | }; | ||
785 | |||
786 | extern void xfrm_init(void); | ||
787 | extern void xfrm4_init(void); | ||
788 | extern void xfrm6_init(void); | ||
789 | extern void xfrm6_fini(void); | ||
790 | extern void xfrm_state_init(void); | ||
791 | extern void xfrm4_state_init(void); | ||
792 | extern void xfrm4_state_fini(void); | ||
793 | extern void xfrm6_state_init(void); | ||
794 | extern void xfrm6_state_fini(void); | ||
795 | |||
796 | extern int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*), void *); | ||
797 | extern struct xfrm_state *xfrm_state_alloc(void); | ||
798 | extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | ||
799 | struct flowi *fl, struct xfrm_tmpl *tmpl, | ||
800 | struct xfrm_policy *pol, int *err, | ||
801 | unsigned short family); | ||
802 | extern int xfrm_state_check_expire(struct xfrm_state *x); | ||
803 | extern void xfrm_state_insert(struct xfrm_state *x); | ||
804 | extern int xfrm_state_add(struct xfrm_state *x); | ||
805 | extern int xfrm_state_update(struct xfrm_state *x); | ||
806 | extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family); | ||
807 | extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); | ||
808 | extern void xfrm_state_delete(struct xfrm_state *x); | ||
809 | extern void xfrm_state_flush(u8 proto); | ||
810 | extern int xfrm_replay_check(struct xfrm_state *x, u32 seq); | ||
811 | extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq); | ||
812 | extern int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb); | ||
813 | extern int xfrm_state_mtu(struct xfrm_state *x, int mtu); | ||
814 | extern int xfrm4_rcv(struct sk_buff *skb); | ||
815 | extern int xfrm4_output(struct sk_buff *skb); | ||
816 | extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler); | ||
817 | extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler); | ||
818 | extern int xfrm6_rcv_spi(struct sk_buff **pskb, unsigned int *nhoffp, u32 spi); | ||
819 | extern int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp); | ||
820 | extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler); | ||
821 | extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler); | ||
822 | extern u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr); | ||
823 | extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr); | ||
824 | extern u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr); | ||
825 | extern int xfrm6_output(struct sk_buff *skb); | ||
826 | |||
827 | #ifdef CONFIG_XFRM | ||
828 | extern int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type); | ||
829 | extern int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen); | ||
830 | extern int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family); | ||
831 | #else | ||
832 | static inline int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen) | ||
833 | { | ||
834 | return -ENOPROTOOPT; | ||
835 | } | ||
836 | |||
837 | static inline int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) | ||
838 | { | ||
839 | /* should not happen */ | ||
840 | kfree_skb(skb); | ||
841 | return 0; | ||
842 | } | ||
843 | static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family) | ||
844 | { | ||
845 | return -EINVAL; | ||
846 | } | ||
847 | #endif | ||
848 | |||
849 | struct xfrm_policy *xfrm_policy_alloc(int gfp); | ||
850 | extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *); | ||
851 | int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); | ||
852 | struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel, | ||
853 | int delete); | ||
854 | struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete); | ||
855 | void xfrm_policy_flush(void); | ||
856 | u32 xfrm_get_acqseq(void); | ||
857 | void xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi); | ||
858 | struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, | ||
859 | xfrm_address_t *daddr, xfrm_address_t *saddr, | ||
860 | int create, unsigned short family); | ||
861 | extern void xfrm_policy_flush(void); | ||
862 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); | ||
863 | extern int xfrm_flush_bundles(void); | ||
864 | extern int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl, int family); | ||
865 | extern void xfrm_init_pmtu(struct dst_entry *dst); | ||
866 | |||
867 | extern wait_queue_head_t km_waitq; | ||
868 | extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport); | ||
869 | extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard); | ||
870 | |||
871 | extern void xfrm_input_init(void); | ||
872 | extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq); | ||
873 | |||
874 | extern void xfrm_probe_algs(void); | ||
875 | extern int xfrm_count_auth_supported(void); | ||
876 | extern int xfrm_count_enc_supported(void); | ||
877 | extern struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx); | ||
878 | extern struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx); | ||
879 | extern struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id); | ||
880 | extern struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id); | ||
881 | extern struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id); | ||
882 | extern struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe); | ||
883 | extern struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe); | ||
884 | extern struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe); | ||
885 | |||
886 | struct crypto_tfm; | ||
887 | typedef void (icv_update_fn_t)(struct crypto_tfm *, struct scatterlist *, unsigned int); | ||
888 | |||
889 | extern void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm, | ||
890 | int offset, int len, icv_update_fn_t icv_update); | ||
891 | |||
892 | static inline int xfrm_addr_cmp(xfrm_address_t *a, xfrm_address_t *b, | ||
893 | int family) | ||
894 | { | ||
895 | switch (family) { | ||
896 | default: | ||
897 | case AF_INET: | ||
898 | return a->a4 - b->a4; | ||
899 | case AF_INET6: | ||
900 | return ipv6_addr_cmp((struct in6_addr *)a, | ||
901 | (struct in6_addr *)b); | ||
902 | } | ||
903 | } | ||
904 | |||
905 | #endif /* _NET_XFRM_H */ | ||