Blame view
net/l2tp/l2tp_core.h
10.1 KB
fd558d186
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/* * L2TP internal definitions. * * Copyright (c) 2008,2009 Katalix Systems Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #ifndef _L2TP_CORE_H_ #define _L2TP_CORE_H_ /* Just some random numbers */ #define L2TP_TUNNEL_MAGIC 0x42114DDA #define L2TP_SESSION_MAGIC 0x0C04EB7D |
f7faffa3f
|
17 |
/* Per tunnel, session hash table size */ |
fd558d186
|
18 19 |
#define L2TP_HASH_BITS 4 #define L2TP_HASH_SIZE (1 << L2TP_HASH_BITS) |
f7faffa3f
|
20 21 22 |
/* System-wide, session hash table size */ #define L2TP_HASH_BITS_2 8 #define L2TP_HASH_SIZE_2 (1 << L2TP_HASH_BITS_2) |
fd558d186
|
23 24 25 26 27 28 29 30 31 32 33 34 35 |
/* Debug message categories for the DEBUG socket option */ enum { L2TP_MSG_DEBUG = (1 << 0), /* verbose debug (if * compiled in) */ L2TP_MSG_CONTROL = (1 << 1), /* userspace - kernel * interface */ L2TP_MSG_SEQ = (1 << 2), /* sequence numbers */ L2TP_MSG_DATA = (1 << 3), /* data packets */ }; struct sk_buff; struct l2tp_stats { |
7b7c0719c
|
36 37 38 39 40 41 42 43 44 |
atomic_long_t tx_packets; atomic_long_t tx_bytes; atomic_long_t tx_errors; atomic_long_t rx_packets; atomic_long_t rx_bytes; atomic_long_t rx_seq_discards; atomic_long_t rx_oos_packets; atomic_long_t rx_errors; atomic_long_t rx_cookie_discards; |
fd558d186
|
45 46 47 48 49 50 51 52 |
}; struct l2tp_tunnel; /* Describes a session. Contains information to determine incoming * packets and transmit outgoing ones. */ struct l2tp_session_cfg { |
f7faffa3f
|
53 |
enum l2tp_pwtype pw_type; |
95c961747
|
54 |
unsigned int data_seq:2; /* data sequencing level |
fd558d186
|
55 56 57 |
* 0 => none, 1 => IP only, * 2 => all */ |
95c961747
|
58 |
unsigned int recv_seq:1; /* expect receive packets with |
fd558d186
|
59 |
* sequence numbers? */ |
95c961747
|
60 |
unsigned int send_seq:1; /* send packets with sequence |
fd558d186
|
61 |
* numbers? */ |
95c961747
|
62 |
unsigned int lns_mode:1; /* behave as LNS? LAC enables |
fd558d186
|
63 64 65 66 |
* sequence numbers under * control of LNS. */ int debug; /* bitmask of debug message * categories */ |
309795f4b
|
67 |
u16 vlan_id; /* VLAN pseudowire only */ |
f7faffa3f
|
68 69 70 71 72 73 74 |
u16 offset; /* offset to payload */ u16 l2specific_len; /* Layer 2 specific length */ u16 l2specific_type; /* Layer 2 specific type */ u8 cookie[8]; /* optional cookie */ int cookie_len; /* 0, 4 or 8 bytes */ u8 peer_cookie[8]; /* peer's cookie */ int peer_cookie_len; /* 0, 4 or 8 bytes */ |
fd558d186
|
75 76 77 78 |
int reorder_timeout; /* configured reorder timeout * (in jiffies) */ int mtu; int mru; |
309795f4b
|
79 |
char *ifname; |
fd558d186
|
80 81 82 83 84 85 86 87 88 89 |
}; struct l2tp_session { int magic; /* should be * L2TP_SESSION_MAGIC */ struct l2tp_tunnel *tunnel; /* back pointer to tunnel * context */ u32 session_id; u32 peer_session_id; |
f7faffa3f
|
90 91 92 93 94 95 96 97 98 99 100 |
u8 cookie[8]; int cookie_len; u8 peer_cookie[8]; int peer_cookie_len; u16 offset; /* offset from end of L2TP header to beginning of data */ u16 l2specific_len; u16 l2specific_type; u16 hdr_len; u32 nr; /* session NR state (receive) */ u32 ns; /* session NR state (send) */ |
fd558d186
|
101 |
struct sk_buff_head reorder_q; /* receive reorder queue */ |
8a1631d58
|
102 103 |
u32 nr_max; /* max NR. Depends on tunnel */ u32 nr_window_size; /* NR window size */ |
a0dbd8222
|
104 105 106 |
u32 nr_oos; /* NR of last OOS packet */ int nr_oos_count; /* For OOS recovery */ int nr_oos_count_max; |
fd558d186
|
107 108 109 110 |
struct hlist_node hlist; /* Hash list node */ atomic_t ref_count; char name[32]; /* for logging */ |
309795f4b
|
111 |
char ifname[IFNAMSIZ]; |
95c961747
|
112 |
unsigned int data_seq:2; /* data sequencing level |
fd558d186
|
113 114 115 |
* 0 => none, 1 => IP only, * 2 => all */ |
95c961747
|
116 |
unsigned int recv_seq:1; /* expect receive packets with |
fd558d186
|
117 |
* sequence numbers? */ |
95c961747
|
118 |
unsigned int send_seq:1; /* send packets with sequence |
fd558d186
|
119 |
* numbers? */ |
95c961747
|
120 |
unsigned int lns_mode:1; /* behave as LNS? LAC enables |
fd558d186
|
121 122 123 124 125 126 |
* sequence numbers under * control of LNS. */ int debug; /* bitmask of debug message * categories */ int reorder_timeout; /* configured reorder timeout * (in jiffies) */ |
38d40b3f4
|
127 |
int reorder_skip; /* set if skip to next nr */ |
fd558d186
|
128 129 |
int mtu; int mru; |
f7faffa3f
|
130 |
enum l2tp_pwtype pwtype; |
fd558d186
|
131 |
struct l2tp_stats stats; |
f7faffa3f
|
132 |
struct hlist_node global_hlist; /* Global hash list node */ |
fd558d186
|
133 |
|
f7faffa3f
|
134 |
int (*build_header)(struct l2tp_session *session, void *buf); |
fd558d186
|
135 136 137 138 |
void (*recv_skb)(struct l2tp_session *session, struct sk_buff *skb, int data_len); void (*session_close)(struct l2tp_session *session); void (*ref)(struct l2tp_session *session); void (*deref)(struct l2tp_session *session); |
9dd79945b
|
139 |
#if IS_ENABLED(CONFIG_L2TP_DEBUGFS) |
0ad661404
|
140 141 |
void (*show)(struct seq_file *m, void *priv); #endif |
fd558d186
|
142 143 144 145 146 147 148 149 150 |
uint8_t priv[0]; /* private data */ }; /* Describes the tunnel. It contains info to track all the associated * sessions so incoming packets can be sorted out */ struct l2tp_tunnel_cfg { int debug; /* bitmask of debug message * categories */ |
0d76751fa
|
151 |
enum l2tp_encap_type encap; |
789a4a2c6
|
152 153 154 155 |
/* Used only for kernel-created sockets */ struct in_addr local_ip; struct in_addr peer_ip; |
f9bac8df9
|
156 157 158 159 |
#if IS_ENABLED(CONFIG_IPV6) struct in6_addr *local_ip6; struct in6_addr *peer_ip6; #endif |
789a4a2c6
|
160 161 |
u16 local_udp_port; u16 peer_udp_port; |
6b649feaf
|
162 163 164 |
unsigned int use_udp_checksums:1, udp6_zero_tx_checksums:1, udp6_zero_rx_checksums:1; |
fd558d186
|
165 166 167 168 |
}; struct l2tp_tunnel { int magic; /* Should be L2TP_TUNNEL_MAGIC */ |
b4a9b12d9
|
169 170 |
unsigned long dead; |
99469c32f
|
171 |
struct rcu_head rcu; |
fd558d186
|
172 173 174 175 176 177 178 179 180 181 182 |
rwlock_t hlist_lock; /* protect session_hlist */ struct hlist_head session_hlist[L2TP_HASH_SIZE]; /* hashed list of sessions, * hashed by id */ u32 tunnel_id; u32 peer_tunnel_id; int version; /* 2=>L2TPv2, 3=>L2TPv3 */ char name[20]; /* for logging */ int debug; /* bitmask of debug message * categories */ |
0d76751fa
|
183 |
enum l2tp_encap_type encap; |
fd558d186
|
184 185 186 187 188 189 |
struct l2tp_stats stats; struct list_head list; /* Keep a list of all tunnels */ struct net *l2tp_net; /* the net we belong to */ atomic_t ref_count; |
0ad661404
|
190 191 192 |
#ifdef CONFIG_DEBUG_FS void (*show)(struct seq_file *m, void *arg); #endif |
fd558d186
|
193 194 195 |
int (*recv_payload_hook)(struct sk_buff *skb); void (*old_sk_destruct)(struct sock *); struct sock *sock; /* Parent socket */ |
80d84ef3f
|
196 197 |
int fd; /* Parent fd, if tunnel socket * was created by userspace */ |
e18503f41
|
198 199 200 |
#if IS_ENABLED(CONFIG_IPV6) bool v4mapped; #endif |
fd558d186
|
201 |
|
f8ccac0e4
|
202 |
struct work_struct del_work; |
fd558d186
|
203 204 |
uint8_t priv[0]; /* private data */ }; |
309795f4b
|
205 206 207 208 |
struct l2tp_nl_cmd_ops { int (*session_create)(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg); int (*session_delete)(struct l2tp_session *session); }; |
fd558d186
|
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
static inline void *l2tp_tunnel_priv(struct l2tp_tunnel *tunnel) { return &tunnel->priv[0]; } static inline void *l2tp_session_priv(struct l2tp_session *session) { return &session->priv[0]; } static inline struct l2tp_tunnel *l2tp_sock_to_tunnel(struct sock *sk) { struct l2tp_tunnel *tunnel; if (sk == NULL) return NULL; sock_hold(sk); tunnel = (struct l2tp_tunnel *)(sk->sk_user_data); if (tunnel == NULL) { sock_put(sk); goto out; } BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC); out: return tunnel; } |
6539c4f99
|
238 239 240 |
struct l2tp_session *l2tp_session_get(struct net *net, struct l2tp_tunnel *tunnel, u32 session_id, bool do_ref); |
c1b1203d6
|
241 242 243 |
struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunnel, u32 session_id); |
b79026076
|
244 245 |
struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth, bool do_ref); |
08cb8e5f8
|
246 247 |
struct l2tp_session *l2tp_session_get_by_ifname(struct net *net, char *ifname, bool do_ref); |
c1b1203d6
|
248 249 250 251 252 253 254 |
struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id); struct l2tp_tunnel *l2tp_tunnel_find_nth(struct net *net, int nth); int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, struct l2tp_tunnel **tunnelp); void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel); |
b4a9b12d9
|
255 |
void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel); |
c1b1203d6
|
256 257 258 259 260 261 262 263 264 265 266 267 |
struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg); void __l2tp_session_unhash(struct l2tp_session *session); int l2tp_session_delete(struct l2tp_session *session); void l2tp_session_free(struct l2tp_session *session); void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, unsigned char *ptr, unsigned char *optr, u16 hdrflags, int length, int (*payload_hook)(struct sk_buff *skb)); int l2tp_session_queue_purge(struct l2tp_session *session); int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb); |
bb5016eac
|
268 |
void l2tp_session_set_header_len(struct l2tp_session *session, int version); |
c1b1203d6
|
269 270 271 272 273 274 275 |
int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len); int l2tp_nl_register_ops(enum l2tp_pwtype pw_type, const struct l2tp_nl_cmd_ops *ops); void l2tp_nl_unregister_ops(enum l2tp_pwtype pw_type); |
5b1bb4cbd
|
276 |
int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg); |
309795f4b
|
277 |
|
fd558d186
|
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
/* Session reference counts. Incremented when code obtains a reference * to a session. */ static inline void l2tp_session_inc_refcount_1(struct l2tp_session *session) { atomic_inc(&session->ref_count); } static inline void l2tp_session_dec_refcount_1(struct l2tp_session *session) { if (atomic_dec_and_test(&session->ref_count)) l2tp_session_free(session); } #ifdef L2TP_REFCNT_DEBUG |
a4ca44fa5
|
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
#define l2tp_session_inc_refcount(_s) \ do { \ pr_debug("l2tp_session_inc_refcount: %s:%d %s: cnt=%d ", \ __func__, __LINE__, (_s)->name, \ atomic_read(&_s->ref_count)); \ l2tp_session_inc_refcount_1(_s); \ } while (0) #define l2tp_session_dec_refcount(_s) \ do { \ pr_debug("l2tp_session_dec_refcount: %s:%d %s: cnt=%d ", \ __func__, __LINE__, (_s)->name, \ atomic_read(&_s->ref_count)); \ l2tp_session_dec_refcount_1(_s); \ } while (0) |
fd558d186
|
309 310 311 312 |
#else #define l2tp_session_inc_refcount(s) l2tp_session_inc_refcount_1(s) #define l2tp_session_dec_refcount(s) l2tp_session_dec_refcount_1(s) #endif |
a4ca44fa5
|
313 314 315 316 317 318 319 320 321 322 323 324 |
#define l2tp_printk(ptr, type, func, fmt, ...) \ do { \ if (((ptr)->debug) & (type)) \ func(fmt, ##__VA_ARGS__); \ } while (0) #define l2tp_warn(ptr, type, fmt, ...) \ l2tp_printk(ptr, type, pr_warn, fmt, ##__VA_ARGS__) #define l2tp_info(ptr, type, fmt, ...) \ l2tp_printk(ptr, type, pr_info, fmt, ##__VA_ARGS__) #define l2tp_dbg(ptr, type, fmt, ...) \ l2tp_printk(ptr, type, pr_debug, fmt, ##__VA_ARGS__) |
f1f39f911
|
325 326 |
#define MODULE_ALIAS_L2TP_PWTYPE(type) \ MODULE_ALIAS("net-l2tp-type-" __stringify(type)) |
fd558d186
|
327 |
#endif /* _L2TP_CORE_H_ */ |