Blame view

net/l2tp/l2tp_core.h 10.1 KB
fd558d186   James Chapman   l2tp: Split pppol...
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   James Chapman   l2tp: Add L2TPv3 ...
17
  /* Per tunnel, session hash table size */
fd558d186   James Chapman   l2tp: Split pppol...
18
19
  #define L2TP_HASH_BITS	4
  #define L2TP_HASH_SIZE	(1 << L2TP_HASH_BITS)
f7faffa3f   James Chapman   l2tp: Add L2TPv3 ...
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   James Chapman   l2tp: Split pppol...
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   Tom Parkin   l2tp: avoid deadl...
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   James Chapman   l2tp: Split pppol...
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   James Chapman   l2tp: Add L2TPv3 ...
53
  	enum l2tp_pwtype	pw_type;
95c961747   Eric Dumazet   net: cleanup unsi...
54
  	unsigned int		data_seq:2;	/* data sequencing level
fd558d186   James Chapman   l2tp: Split pppol...
55
56
57
  						 * 0 => none, 1 => IP only,
  						 * 2 => all
  						 */
95c961747   Eric Dumazet   net: cleanup unsi...
58
  	unsigned int		recv_seq:1;	/* expect receive packets with
fd558d186   James Chapman   l2tp: Split pppol...
59
  						 * sequence numbers? */
95c961747   Eric Dumazet   net: cleanup unsi...
60
  	unsigned int		send_seq:1;	/* send packets with sequence
fd558d186   James Chapman   l2tp: Split pppol...
61
  						 * numbers? */
95c961747   Eric Dumazet   net: cleanup unsi...
62
  	unsigned int		lns_mode:1;	/* behave as LNS? LAC enables
fd558d186   James Chapman   l2tp: Split pppol...
63
64
65
66
  						 * sequence numbers under
  						 * control of LNS. */
  	int			debug;		/* bitmask of debug message
  						 * categories */
309795f4b   James Chapman   l2tp: Add netlink...
67
  	u16			vlan_id;	/* VLAN pseudowire only */
f7faffa3f   James Chapman   l2tp: Add L2TPv3 ...
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   James Chapman   l2tp: Split pppol...
75
76
77
78
  	int			reorder_timeout; /* configured reorder timeout
  						  * (in jiffies) */
  	int			mtu;
  	int			mru;
309795f4b   James Chapman   l2tp: Add netlink...
79
  	char			*ifname;
fd558d186   James Chapman   l2tp: Split pppol...
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   James Chapman   l2tp: Add L2TPv3 ...
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   James Chapman   l2tp: Split pppol...
101
  	struct sk_buff_head	reorder_q;	/* receive reorder queue */
8a1631d58   James Chapman   l2tp: make datapa...
102
103
  	u32			nr_max;		/* max NR. Depends on tunnel */
  	u32			nr_window_size;	/* NR window size */
a0dbd8222   James Chapman   l2tp: make datapa...
104
105
106
  	u32			nr_oos;		/* NR of last OOS packet */
  	int			nr_oos_count;	/* For OOS recovery */
  	int			nr_oos_count_max;
fd558d186   James Chapman   l2tp: Split pppol...
107
108
109
110
  	struct hlist_node	hlist;		/* Hash list node */
  	atomic_t		ref_count;
  
  	char			name[32];	/* for logging */
309795f4b   James Chapman   l2tp: Add netlink...
111
  	char			ifname[IFNAMSIZ];
95c961747   Eric Dumazet   net: cleanup unsi...
112
  	unsigned int		data_seq:2;	/* data sequencing level
fd558d186   James Chapman   l2tp: Split pppol...
113
114
115
  						 * 0 => none, 1 => IP only,
  						 * 2 => all
  						 */
95c961747   Eric Dumazet   net: cleanup unsi...
116
  	unsigned int		recv_seq:1;	/* expect receive packets with
fd558d186   James Chapman   l2tp: Split pppol...
117
  						 * sequence numbers? */
95c961747   Eric Dumazet   net: cleanup unsi...
118
  	unsigned int		send_seq:1;	/* send packets with sequence
fd558d186   James Chapman   l2tp: Split pppol...
119
  						 * numbers? */
95c961747   Eric Dumazet   net: cleanup unsi...
120
  	unsigned int		lns_mode:1;	/* behave as LNS? LAC enables
fd558d186   James Chapman   l2tp: Split pppol...
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   James Chapman   l2tp: fix reorder...
127
  	int			reorder_skip;	/* set if skip to next nr */
fd558d186   James Chapman   l2tp: Split pppol...
128
129
  	int			mtu;
  	int			mru;
f7faffa3f   James Chapman   l2tp: Add L2TPv3 ...
130
  	enum l2tp_pwtype	pwtype;
fd558d186   James Chapman   l2tp: Split pppol...
131
  	struct l2tp_stats	stats;
f7faffa3f   James Chapman   l2tp: Add L2TPv3 ...
132
  	struct hlist_node	global_hlist;	/* Global hash list node */
fd558d186   James Chapman   l2tp: Split pppol...
133

f7faffa3f   James Chapman   l2tp: Add L2TPv3 ...
134
  	int (*build_header)(struct l2tp_session *session, void *buf);
fd558d186   James Chapman   l2tp: Split pppol...
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   Javier Martinez Canillas   l2tp: use IS_ENAB...
139
  #if IS_ENABLED(CONFIG_L2TP_DEBUGFS)
0ad661404   James Chapman   l2tp: Add debugfs...
140
141
  	void (*show)(struct seq_file *m, void *priv);
  #endif
fd558d186   James Chapman   l2tp: Split pppol...
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   James Chapman   l2tp: Add L2TPv3 ...
151
  	enum l2tp_encap_type	encap;
789a4a2c6   James Chapman   l2tp: Add support...
152
153
154
155
  
  	/* Used only for kernel-created sockets */
  	struct in_addr		local_ip;
  	struct in_addr		peer_ip;
f9bac8df9   Chris Elston   l2tp: netlink api...
156
157
158
159
  #if IS_ENABLED(CONFIG_IPV6)
  	struct in6_addr		*local_ip6;
  	struct in6_addr		*peer_ip6;
  #endif
789a4a2c6   James Chapman   l2tp: Add support...
160
161
  	u16			local_udp_port;
  	u16			peer_udp_port;
6b649feaf   Tom Herbert   l2tp: Add support...
162
163
164
  	unsigned int		use_udp_checksums:1,
  				udp6_zero_tx_checksums:1,
  				udp6_zero_rx_checksums:1;
fd558d186   James Chapman   l2tp: Split pppol...
165
166
167
168
  };
  
  struct l2tp_tunnel {
  	int			magic;		/* Should be L2TP_TUNNEL_MAGIC */
b4a9b12d9   Sabrina Dubroca   l2tp: fix race co...
169
170
  
  	unsigned long		dead;
99469c32f   xeb@mail.ru   l2tp: avoid to us...
171
  	struct rcu_head rcu;
fd558d186   James Chapman   l2tp: Split pppol...
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   James Chapman   l2tp: Add L2TPv3 ...
183
  	enum l2tp_encap_type	encap;
fd558d186   James Chapman   l2tp: Split pppol...
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   James Chapman   l2tp: Add debugfs...
190
191
192
  #ifdef CONFIG_DEBUG_FS
  	void (*show)(struct seq_file *m, void *arg);
  #endif
fd558d186   James Chapman   l2tp: Split pppol...
193
194
195
  	int (*recv_payload_hook)(struct sk_buff *skb);
  	void (*old_sk_destruct)(struct sock *);
  	struct sock		*sock;		/* Parent socket */
80d84ef3f   Tom Parkin   l2tp: prevent l2t...
196
197
  	int			fd;		/* Parent fd, if tunnel socket
  						 * was created by userspace */
e18503f41   François Cachereul   l2tp: fix kernel ...
198
199
200
  #if IS_ENABLED(CONFIG_IPV6)
  	bool			v4mapped;
  #endif
fd558d186   James Chapman   l2tp: Split pppol...
201

f8ccac0e4   Tom Parkin   l2tp: put tunnel ...
202
  	struct work_struct	del_work;
fd558d186   James Chapman   l2tp: Split pppol...
203
204
  	uint8_t			priv[0];	/* private data */
  };
309795f4b   James Chapman   l2tp: Add netlink...
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   James Chapman   l2tp: Split pppol...
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   Guillaume Nault   l2tp: fix race in...
238
239
240
  struct l2tp_session *l2tp_session_get(struct net *net,
  				      struct l2tp_tunnel *tunnel,
  				      u32 session_id, bool do_ref);
c1b1203d6   Joe Perches   net: misc: Remove...
241
242
243
  struct l2tp_session *l2tp_session_find(struct net *net,
  				       struct l2tp_tunnel *tunnel,
  				       u32 session_id);
b79026076   Guillaume Nault   l2tp: take refere...
244
245
  struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth,
  					  bool do_ref);
08cb8e5f8   Guillaume Nault   l2tp: take a refe...
246
247
  struct l2tp_session *l2tp_session_get_by_ifname(struct net *net, char *ifname,
  						bool do_ref);
c1b1203d6   Joe Perches   net: misc: Remove...
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   Sabrina Dubroca   l2tp: fix race co...
255
  void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel);
c1b1203d6   Joe Perches   net: misc: Remove...
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   Guillaume Nault   l2tp: fix manual ...
268
  void l2tp_session_set_header_len(struct l2tp_session *session, int version);
c1b1203d6   Joe Perches   net: misc: Remove...
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   Eric Dumazet   l2tp: do not use ...
276
  int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg);
309795f4b   James Chapman   l2tp: Add netlink...
277

fd558d186   James Chapman   l2tp: Split pppol...
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   Joe Perches   net: l2tp: Standa...
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   James Chapman   l2tp: Split pppol...
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   Joe Perches   net: l2tp: Standa...
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   stephen hemminger   l2tp: auto load t...
325
326
  #define MODULE_ALIAS_L2TP_PWTYPE(type) \
  	MODULE_ALIAS("net-l2tp-type-" __stringify(type))
fd558d186   James Chapman   l2tp: Split pppol...
327
  #endif /* _L2TP_CORE_H_ */