1/*-
2 * Copyright (c) 2001-2002 Packet Design, LLC.
3 * All rights reserved.
4 *
5 * Subject to the following obligations and disclaimer of warranty,
6 * use and redistribution of this software, in source or object code
7 * forms, with or without modifications are expressly permitted by
8 * Packet Design; provided, however, that:
9 *
10 *    (i)  Any and all reproductions of the source or object code
11 *         must include the copyright notice above and the following
12 *         disclaimer of warranties; and
13 *    (ii) No rights are granted, in any manner or form, to use
14 *         Packet Design trademarks, including the mark "PACKET DESIGN"
15 *         on advertising, endorsements, or otherwise except as such
16 *         appears in the above copyright notice or in the software.
17 *
18 * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
19 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
20 * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
21 * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
22 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
23 * OR NON-INFRINGEMENT.  PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
24 * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
25 * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
26 * RELIABILITY OR OTHERWISE.  IN NO EVENT SHALL PACKET DESIGN BE
27 * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
28 * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
29 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
30 * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
31 * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
34 * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
35 * THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Author: Archie Cobbs <archie@freebsd.org>
38 *
39 * $FreeBSD$
40 */
41
42/*
43 * L2TP netgraph node type.
44 *
45 * This node type implements the lower layer of the
46 * L2TP protocol as specified in RFC 2661.
47 */
48
49#include <sys/param.h>
50#include <sys/systm.h>
51#include <sys/kernel.h>
52#include <sys/time.h>
53#include <sys/conf.h>
54#include <sys/mbuf.h>
55#include <sys/malloc.h>
56#include <sys/errno.h>
57#include <sys/libkern.h>
58
59#include <netgraph/ng_message.h>
60#include <netgraph/netgraph.h>
61#include <netgraph/ng_parse.h>
62#include <netgraph/ng_l2tp.h>
63
64#ifdef NG_SEPARATE_MALLOC
65static MALLOC_DEFINE(M_NETGRAPH_L2TP, "netgraph_l2tp", "netgraph l2tp node");
66#else
67#define M_NETGRAPH_L2TP M_NETGRAPH
68#endif
69
70/* L2TP header format (first 2 bytes only) */
71#define L2TP_HDR_CTRL		0x8000			/* control packet */
72#define L2TP_HDR_LEN		0x4000			/* has length field */
73#define L2TP_HDR_SEQ		0x0800			/* has ns, nr fields */
74#define L2TP_HDR_OFF		0x0200			/* has offset field */
75#define L2TP_HDR_PRIO		0x0100			/* give priority */
76#define L2TP_HDR_VERS_MASK	0x000f			/* version field mask */
77#define L2TP_HDR_VERSION	0x0002			/* version field */
78
79/* Bits that must be zero or one in first two bytes of header */
80#define L2TP_CTRL_0BITS		0x030d			/* ctrl: must be 0 */
81#define L2TP_CTRL_1BITS		0xc802			/* ctrl: must be 1 */
82#define L2TP_DATA_0BITS		0x800d			/* data: must be 0 */
83#define L2TP_DATA_1BITS		0x0002			/* data: must be 1 */
84
85/* Standard xmit ctrl and data header bits */
86#define L2TP_CTRL_HDR		(L2TP_HDR_CTRL | L2TP_HDR_LEN \
87				    | L2TP_HDR_SEQ | L2TP_HDR_VERSION)
88#define L2TP_DATA_HDR		(L2TP_HDR_VERSION)	/* optional: len, seq */
89
90/* Some hard coded values */
91#define L2TP_MAX_XWIN		128			/* my max xmit window */
92#define L2TP_MAX_REXMIT		5			/* default max rexmit */
93#define L2TP_MAX_REXMIT_TO	30			/* default rexmit to */
94#define L2TP_DELAYED_ACK	((hz + 19) / 20)	/* delayed ack: 50 ms */
95
96/* Default data sequence number configuration for new sessions */
97#define L2TP_CONTROL_DSEQ	1			/* we are the lns */
98#define L2TP_ENABLE_DSEQ	1			/* enable data seq # */
99
100/* Compare sequence numbers using circular math */
101#define L2TP_SEQ_DIFF(x, y)	((int16_t)((x) - (y)))
102
103#define SESSHASHSIZE		0x0020
104#define SESSHASH(x)		(((x) ^ ((x) >> 8)) & (SESSHASHSIZE - 1))
105
106/* Hook private data (data session hooks only) */
107struct ng_l2tp_hook_private {
108	struct ng_l2tp_sess_config	conf;	/* hook/session config */
109	struct ng_l2tp_session_stats	stats;	/* per sessions statistics */
110	hook_p				hook;	/* hook reference */
111	u_int16_t			ns;	/* data ns sequence number */
112	u_int16_t			nr;	/* data nr sequence number */
113	LIST_ENTRY(ng_l2tp_hook_private) sessions;
114};
115typedef struct ng_l2tp_hook_private *hookpriv_p;
116
117/*
118 * Sequence number state
119 *
120 * Invariants:
121 *    - If cwnd < ssth, we're doing slow start, otherwise congestion avoidance
122 *    - The number of unacknowledged xmit packets is (ns - rack) <= seq->wmax
123 *    - The first (ns - rack) mbuf's in xwin[] array are copies of these
124 *	unacknowledged packets; the remainder of xwin[] consists first of
125 *	zero or more further untransmitted packets in the transmit queue
126 *    - We try to keep the peer's receive window as full as possible.
127 *	Therefore, (i < cwnd && xwin[i] != NULL) implies (ns - rack) > i.
128 *    - rack_timer is running iff (ns - rack) > 0 (unack'd xmit'd pkts)
129 *    - If xack != nr, there are unacknowledged recv packet(s) (delayed ack)
130 *    - xack_timer is running iff xack != nr (unack'd rec'd pkts)
131 */
132struct l2tp_seq {
133	u_int16_t		ns;		/* next xmit seq we send */
134	u_int16_t		nr;		/* next recv seq we expect */
135	u_int16_t		inproc;		/* packet is in processing */
136	u_int16_t		rack;		/* last 'nr' we rec'd */
137	u_int16_t		xack;		/* last 'nr' we sent */
138	u_int16_t		wmax;		/* peer's max recv window */
139	u_int16_t		cwnd;		/* current congestion window */
140	u_int16_t		ssth;		/* slow start threshold */
141	u_int16_t		acks;		/* # consecutive acks rec'd */
142	u_int16_t		rexmits;	/* # retransmits sent */
143	struct callout		rack_timer;	/* retransmit timer */
144	struct callout		xack_timer;	/* delayed ack timer */
145	struct mbuf		*xwin[L2TP_MAX_XWIN];	/* transmit window */
146	struct mtx		mtx;			/* seq mutex */
147};
148
149/* Node private data */
150struct ng_l2tp_private {
151	node_p			node;		/* back pointer to node */
152	hook_p			ctrl;		/* hook to upper layers */
153	hook_p			lower;		/* hook to lower layers */
154	struct ng_l2tp_config	conf;		/* node configuration */
155	struct ng_l2tp_stats	stats;		/* node statistics */
156	struct l2tp_seq		seq;		/* ctrl sequence number state */
157	ng_ID_t			ftarget;	/* failure message target */
158	LIST_HEAD(, ng_l2tp_hook_private) sesshash[SESSHASHSIZE];
159};
160typedef struct ng_l2tp_private *priv_p;
161
162/* Netgraph node methods */
163static ng_constructor_t	ng_l2tp_constructor;
164static ng_rcvmsg_t	ng_l2tp_rcvmsg;
165static ng_shutdown_t	ng_l2tp_shutdown;
166static ng_newhook_t	ng_l2tp_newhook;
167static ng_rcvdata_t	ng_l2tp_rcvdata;
168static ng_rcvdata_t	ng_l2tp_rcvdata_lower;
169static ng_rcvdata_t	ng_l2tp_rcvdata_ctrl;
170static ng_disconnect_t	ng_l2tp_disconnect;
171
172/* Internal functions */
173static int	ng_l2tp_xmit_ctrl(priv_p priv, struct mbuf *m, u_int16_t ns);
174
175static void	ng_l2tp_seq_init(priv_p priv);
176static int	ng_l2tp_seq_set(priv_p priv,
177			const struct ng_l2tp_seq_config *conf);
178static int	ng_l2tp_seq_adjust(priv_p priv,
179			const struct ng_l2tp_config *conf);
180static void	ng_l2tp_seq_reset(priv_p priv);
181static void	ng_l2tp_seq_failure(priv_p priv);
182static void	ng_l2tp_seq_recv_nr(priv_p priv, u_int16_t nr);
183static void	ng_l2tp_seq_xack_timeout(node_p node, hook_p hook,
184		    void *arg1, int arg2);
185static void	ng_l2tp_seq_rack_timeout(node_p node, hook_p hook,
186		    void *arg1, int arg2);
187
188static hookpriv_p	ng_l2tp_find_session(priv_p privp, u_int16_t sid);
189static ng_fn_eachhook	ng_l2tp_reset_session;
190
191#ifdef INVARIANTS
192static void	ng_l2tp_seq_check(struct l2tp_seq *seq);
193#endif
194
195/* Parse type for struct ng_l2tp_seq_config. */
196static const struct ng_parse_struct_field
197	ng_l2tp_seq_config_fields[] = NG_L2TP_SEQ_CONFIG_TYPE_INFO;
198static const struct ng_parse_type ng_l2tp_seq_config_type = {
199	&ng_parse_struct_type,
200	&ng_l2tp_seq_config_fields
201};
202
203/* Parse type for struct ng_l2tp_config */
204static const struct ng_parse_struct_field
205	ng_l2tp_config_type_fields[] = NG_L2TP_CONFIG_TYPE_INFO;
206static const struct ng_parse_type ng_l2tp_config_type = {
207	&ng_parse_struct_type,
208	&ng_l2tp_config_type_fields,
209};
210
211/* Parse type for struct ng_l2tp_sess_config */
212static const struct ng_parse_struct_field
213	ng_l2tp_sess_config_type_fields[] = NG_L2TP_SESS_CONFIG_TYPE_INFO;
214static const struct ng_parse_type ng_l2tp_sess_config_type = {
215	&ng_parse_struct_type,
216	&ng_l2tp_sess_config_type_fields,
217};
218
219/* Parse type for struct ng_l2tp_stats */
220static const struct ng_parse_struct_field
221	ng_l2tp_stats_type_fields[] = NG_L2TP_STATS_TYPE_INFO;
222static const struct ng_parse_type ng_l2tp_stats_type = {
223	&ng_parse_struct_type,
224	&ng_l2tp_stats_type_fields
225};
226
227/* Parse type for struct ng_l2tp_session_stats. */
228static const struct ng_parse_struct_field
229	ng_l2tp_session_stats_type_fields[] = NG_L2TP_SESSION_STATS_TYPE_INFO;
230static const struct ng_parse_type ng_l2tp_session_stats_type = {
231	&ng_parse_struct_type,
232	&ng_l2tp_session_stats_type_fields
233};
234
235/* List of commands and how to convert arguments to/from ASCII */
236static const struct ng_cmdlist ng_l2tp_cmdlist[] = {
237	{
238	  NGM_L2TP_COOKIE,
239	  NGM_L2TP_SET_CONFIG,
240	  "setconfig",
241	  &ng_l2tp_config_type,
242	  NULL
243	},
244	{
245	  NGM_L2TP_COOKIE,
246	  NGM_L2TP_GET_CONFIG,
247	  "getconfig",
248	  NULL,
249	  &ng_l2tp_config_type
250	},
251	{
252	  NGM_L2TP_COOKIE,
253	  NGM_L2TP_SET_SESS_CONFIG,
254	  "setsessconfig",
255	  &ng_l2tp_sess_config_type,
256	  NULL
257	},
258	{
259	  NGM_L2TP_COOKIE,
260	  NGM_L2TP_GET_SESS_CONFIG,
261	  "getsessconfig",
262	  &ng_parse_hint16_type,
263	  &ng_l2tp_sess_config_type
264	},
265	{
266	  NGM_L2TP_COOKIE,
267	  NGM_L2TP_GET_STATS,
268	  "getstats",
269	  NULL,
270	  &ng_l2tp_stats_type
271	},
272	{
273	  NGM_L2TP_COOKIE,
274	  NGM_L2TP_CLR_STATS,
275	  "clrstats",
276	  NULL,
277	  NULL
278	},
279	{
280	  NGM_L2TP_COOKIE,
281	  NGM_L2TP_GETCLR_STATS,
282	  "getclrstats",
283	  NULL,
284	  &ng_l2tp_stats_type
285	},
286	{
287	  NGM_L2TP_COOKIE,
288	  NGM_L2TP_GET_SESSION_STATS,
289	  "getsessstats",
290	  &ng_parse_int16_type,
291	  &ng_l2tp_session_stats_type
292	},
293	{
294	  NGM_L2TP_COOKIE,
295	  NGM_L2TP_CLR_SESSION_STATS,
296	  "clrsessstats",
297	  &ng_parse_int16_type,
298	  NULL
299	},
300	{
301	  NGM_L2TP_COOKIE,
302	  NGM_L2TP_GETCLR_SESSION_STATS,
303	  "getclrsessstats",
304	  &ng_parse_int16_type,
305	  &ng_l2tp_session_stats_type
306	},
307	{
308	  NGM_L2TP_COOKIE,
309	  NGM_L2TP_ACK_FAILURE,
310	  "ackfailure",
311	  NULL,
312	  NULL
313	},
314	{
315	  NGM_L2TP_COOKIE,
316	  NGM_L2TP_SET_SEQ,
317	  "setsequence",
318	  &ng_l2tp_seq_config_type,
319	  NULL
320	},
321	{ 0 }
322};
323
324/* Node type descriptor */
325static struct ng_type ng_l2tp_typestruct = {
326	.version =	NG_ABI_VERSION,
327	.name =		NG_L2TP_NODE_TYPE,
328	.constructor =	ng_l2tp_constructor,
329	.rcvmsg =	ng_l2tp_rcvmsg,
330	.shutdown =	ng_l2tp_shutdown,
331	.newhook =	ng_l2tp_newhook,
332	.rcvdata =	ng_l2tp_rcvdata,
333	.disconnect =	ng_l2tp_disconnect,
334	.cmdlist =	ng_l2tp_cmdlist,
335};
336NETGRAPH_INIT(l2tp, &ng_l2tp_typestruct);
337
338/* Sequence number state sanity checking */
339#ifdef INVARIANTS
340#define L2TP_SEQ_CHECK(seq)	ng_l2tp_seq_check(seq)
341#else
342#define L2TP_SEQ_CHECK(x)	do { } while (0)
343#endif
344
345/* Whether to use m_copypacket() or m_dup() */
346#define L2TP_COPY_MBUF		m_copypacket
347
348#define ERROUT(x)	do { error = (x); goto done; } while (0)
349
350/************************************************************************
351			NETGRAPH NODE STUFF
352************************************************************************/
353
354/*
355 * Node type constructor
356 */
357static int
358ng_l2tp_constructor(node_p node)
359{
360	priv_p priv;
361	int	i;
362
363	/* Allocate private structure */
364	priv = malloc(sizeof(*priv), M_NETGRAPH_L2TP, M_WAITOK | M_ZERO);
365	NG_NODE_SET_PRIVATE(node, priv);
366	priv->node = node;
367
368	/* Apply a semi-reasonable default configuration */
369	priv->conf.peer_win = 1;
370	priv->conf.rexmit_max = L2TP_MAX_REXMIT;
371	priv->conf.rexmit_max_to = L2TP_MAX_REXMIT_TO;
372
373	/* Initialize sequence number state */
374	ng_l2tp_seq_init(priv);
375
376	for (i = 0; i < SESSHASHSIZE; i++)
377	    LIST_INIT(&priv->sesshash[i]);
378
379	/* Done */
380	return (0);
381}
382
383/*
384 * Give our OK for a hook to be added.
385 */
386static int
387ng_l2tp_newhook(node_p node, hook_p hook, const char *name)
388{
389	const priv_p priv = NG_NODE_PRIVATE(node);
390
391	/* Check hook name */
392	if (strcmp(name, NG_L2TP_HOOK_CTRL) == 0) {
393		if (priv->ctrl != NULL)
394			return (EISCONN);
395		priv->ctrl = hook;
396		NG_HOOK_SET_RCVDATA(hook, ng_l2tp_rcvdata_ctrl);
397	} else if (strcmp(name, NG_L2TP_HOOK_LOWER) == 0) {
398		if (priv->lower != NULL)
399			return (EISCONN);
400		priv->lower = hook;
401		NG_HOOK_SET_RCVDATA(hook, ng_l2tp_rcvdata_lower);
402	} else {
403		static const char hexdig[16] = "0123456789abcdef";
404		u_int16_t session_id;
405		hookpriv_p hpriv;
406		uint16_t hash;
407		const char *hex;
408		int i;
409		int j;
410
411		/* Parse hook name to get session ID */
412		if (strncmp(name, NG_L2TP_HOOK_SESSION_P,
413		    sizeof(NG_L2TP_HOOK_SESSION_P) - 1) != 0)
414			return (EINVAL);
415		hex = name + sizeof(NG_L2TP_HOOK_SESSION_P) - 1;
416		for (session_id = i = 0; i < 4; i++) {
417			for (j = 0; j < 16 && hex[i] != hexdig[j]; j++);
418			if (j == 16)
419				return (EINVAL);
420			session_id = (session_id << 4) | j;
421		}
422		if (hex[i] != '\0')
423			return (EINVAL);
424
425		/* Create hook private structure */
426		hpriv = malloc(sizeof(*hpriv),
427		    M_NETGRAPH_L2TP, M_NOWAIT | M_ZERO);
428		if (hpriv == NULL)
429			return (ENOMEM);
430		hpriv->conf.session_id = session_id;
431		hpriv->conf.control_dseq = L2TP_CONTROL_DSEQ;
432		hpriv->conf.enable_dseq = L2TP_ENABLE_DSEQ;
433		hpriv->hook = hook;
434		NG_HOOK_SET_PRIVATE(hook, hpriv);
435		hash = SESSHASH(hpriv->conf.session_id);
436		LIST_INSERT_HEAD(&priv->sesshash[hash], hpriv, sessions);
437	}
438
439	/* Done */
440	return (0);
441}
442
443/*
444 * Receive a control message.
445 */
446static int
447ng_l2tp_rcvmsg(node_p node, item_p item, hook_p lasthook)
448{
449	const priv_p priv = NG_NODE_PRIVATE(node);
450	struct ng_mesg *resp = NULL;
451	struct ng_mesg *msg;
452	int error = 0;
453
454	NGI_GET_MSG(item, msg);
455	switch (msg->header.typecookie) {
456	case NGM_L2TP_COOKIE:
457		switch (msg->header.cmd) {
458		case NGM_L2TP_SET_CONFIG:
459		    {
460			struct ng_l2tp_config *const conf =
461				(struct ng_l2tp_config *)msg->data;
462
463			/* Check for invalid or illegal config */
464			if (msg->header.arglen != sizeof(*conf)) {
465				error = EINVAL;
466				break;
467			}
468			conf->enabled = !!conf->enabled;
469			conf->match_id = !!conf->match_id;
470			if (priv->conf.enabled
471			    && ((priv->conf.tunnel_id != 0
472			       && conf->tunnel_id != priv->conf.tunnel_id)
473			      || ((priv->conf.peer_id != 0
474			       && conf->peer_id != priv->conf.peer_id)))) {
475				error = EBUSY;
476				break;
477			}
478
479			/* Save calling node as failure target */
480			priv->ftarget = NGI_RETADDR(item);
481
482			/* Adjust sequence number state */
483			if ((error = ng_l2tp_seq_adjust(priv, conf)) != 0)
484				break;
485
486			/* Update node's config */
487			priv->conf = *conf;
488			break;
489		    }
490		case NGM_L2TP_GET_CONFIG:
491		    {
492			struct ng_l2tp_config *conf;
493
494			NG_MKRESPONSE(resp, msg, sizeof(*conf), M_NOWAIT);
495			if (resp == NULL) {
496				error = ENOMEM;
497				break;
498			}
499			conf = (struct ng_l2tp_config *)resp->data;
500			*conf = priv->conf;
501			break;
502		    }
503		case NGM_L2TP_SET_SESS_CONFIG:
504		    {
505			struct ng_l2tp_sess_config *const conf =
506			    (struct ng_l2tp_sess_config *)msg->data;
507			hookpriv_p hpriv;
508
509			/* Check for invalid or illegal config. */
510			if (msg->header.arglen != sizeof(*conf)) {
511				error = EINVAL;
512				break;
513			}
514
515			/* Find matching hook */
516			hpriv = ng_l2tp_find_session(priv, conf->session_id);
517			if (hpriv == NULL) {
518				error = ENOENT;
519				break;
520			}
521
522			/* Update hook's config */
523			hpriv->conf = *conf;
524			break;
525		    }
526		case NGM_L2TP_GET_SESS_CONFIG:
527		    {
528			struct ng_l2tp_sess_config *conf;
529			u_int16_t session_id;
530			hookpriv_p hpriv;
531
532			/* Get session ID */
533			if (msg->header.arglen != sizeof(session_id)) {
534				error = EINVAL;
535				break;
536			}
537			memcpy(&session_id, msg->data, 2);
538
539			/* Find matching hook */
540			hpriv = ng_l2tp_find_session(priv, session_id);
541			if (hpriv == NULL) {
542				error = ENOENT;
543				break;
544			}
545
546			/* Send response */
547			NG_MKRESPONSE(resp, msg, sizeof(hpriv->conf), M_NOWAIT);
548			if (resp == NULL) {
549				error = ENOMEM;
550				break;
551			}
552			conf = (struct ng_l2tp_sess_config *)resp->data;
553			*conf = hpriv->conf;
554			break;
555		    }
556		case NGM_L2TP_GET_STATS:
557		case NGM_L2TP_CLR_STATS:
558		case NGM_L2TP_GETCLR_STATS:
559		    {
560			if (msg->header.cmd != NGM_L2TP_CLR_STATS) {
561				NG_MKRESPONSE(resp, msg,
562				    sizeof(priv->stats), M_NOWAIT);
563				if (resp == NULL) {
564					error = ENOMEM;
565					break;
566				}
567				memcpy(resp->data,
568				    &priv->stats, sizeof(priv->stats));
569			}
570			if (msg->header.cmd != NGM_L2TP_GET_STATS)
571				memset(&priv->stats, 0, sizeof(priv->stats));
572			break;
573		    }
574		case NGM_L2TP_GET_SESSION_STATS:
575		case NGM_L2TP_CLR_SESSION_STATS:
576		case NGM_L2TP_GETCLR_SESSION_STATS:
577		    {
578			uint16_t session_id;
579			hookpriv_p hpriv;
580
581			/* Get session ID. */
582			if (msg->header.arglen != sizeof(session_id)) {
583				error = EINVAL;
584				break;
585			}
586			bcopy(msg->data, &session_id, sizeof(uint16_t));
587
588			/* Find matching hook. */
589			hpriv = ng_l2tp_find_session(priv, session_id);
590			if (hpriv == NULL) {
591				error = ENOENT;
592				break;
593			}
594
595			if (msg->header.cmd != NGM_L2TP_CLR_SESSION_STATS) {
596				NG_MKRESPONSE(resp, msg,
597				    sizeof(hpriv->stats), M_NOWAIT);
598				if (resp == NULL) {
599					error = ENOMEM;
600					break;
601				}
602				bcopy(&hpriv->stats, resp->data,
603					sizeof(hpriv->stats));
604			}
605			if (msg->header.cmd != NGM_L2TP_GET_SESSION_STATS)
606				bzero(&hpriv->stats, sizeof(hpriv->stats));
607			break;
608		    }
609		case NGM_L2TP_SET_SEQ:
610		    {
611			struct ng_l2tp_seq_config *const conf =
612				(struct ng_l2tp_seq_config *)msg->data;
613
614			/* Check for invalid or illegal seq config. */
615			if (msg->header.arglen != sizeof(*conf)) {
616				error = EINVAL;
617				break;
618			}
619			conf->ns = htons(conf->ns);
620			conf->nr = htons(conf->nr);
621			conf->rack = htons(conf->rack);
622			conf->xack = htons(conf->xack);
623
624			/* Set sequence numbers. */
625			error = ng_l2tp_seq_set(priv, conf);
626			break;
627		    }
628		default:
629			error = EINVAL;
630			break;
631		}
632		break;
633	default:
634		error = EINVAL;
635		break;
636	}
637
638	/* Done */
639	NG_RESPOND_MSG(error, node, item, resp);
640	NG_FREE_MSG(msg);
641	return (error);
642}
643
644/*
645 * Destroy node
646 */
647static int
648ng_l2tp_shutdown(node_p node)
649{
650	const priv_p priv = NG_NODE_PRIVATE(node);
651	struct l2tp_seq *const seq = &priv->seq;
652
653	/* Sanity check */
654	L2TP_SEQ_CHECK(seq);
655
656	/* Reset sequence number state */
657	ng_l2tp_seq_reset(priv);
658
659	/* Free private data if neither timer is running */
660	ng_uncallout(&seq->rack_timer, node);
661	ng_uncallout(&seq->xack_timer, node);
662
663	mtx_destroy(&seq->mtx);
664
665	free(priv, M_NETGRAPH_L2TP);
666
667	/* Unref node */
668	NG_NODE_UNREF(node);
669	return (0);
670}
671
672/*
673 * Hook disconnection
674 */
675static int
676ng_l2tp_disconnect(hook_p hook)
677{
678	const node_p node = NG_HOOK_NODE(hook);
679	const priv_p priv = NG_NODE_PRIVATE(node);
680
681	/* Zero out hook pointer */
682	if (hook == priv->ctrl)
683		priv->ctrl = NULL;
684	else if (hook == priv->lower)
685		priv->lower = NULL;
686	else {
687		const hookpriv_p hpriv = NG_HOOK_PRIVATE(hook);
688		LIST_REMOVE(hpriv, sessions);
689		free(hpriv, M_NETGRAPH_L2TP);
690		NG_HOOK_SET_PRIVATE(hook, NULL);
691	}
692
693	/* Go away if no longer connected to anything */
694	if (NG_NODE_NUMHOOKS(node) == 0 && NG_NODE_IS_VALID(node))
695		ng_rmnode_self(node);
696	return (0);
697}
698
699/*************************************************************************
700			INTERNAL FUNCTIONS
701*************************************************************************/
702
703/*
704 * Find the hook with a given session ID.
705 */
706static hookpriv_p
707ng_l2tp_find_session(priv_p privp, u_int16_t sid)
708{
709	uint16_t	hash = SESSHASH(sid);
710	hookpriv_p	hpriv = NULL;
711
712	LIST_FOREACH(hpriv, &privp->sesshash[hash], sessions) {
713		if (hpriv->conf.session_id == sid)
714			break;
715	}
716
717	return (hpriv);
718}
719
720/*
721 * Reset a hook's session state.
722 */
723static int
724ng_l2tp_reset_session(hook_p hook, void *arg)
725{
726	const hookpriv_p hpriv = NG_HOOK_PRIVATE(hook);
727
728	if (hpriv != NULL) {
729		hpriv->conf.control_dseq = 0;
730		hpriv->conf.enable_dseq = 0;
731		bzero(&hpriv->stats, sizeof(struct ng_l2tp_session_stats));
732		hpriv->nr = 0;
733		hpriv->ns = 0;
734	}
735	return (-1);
736}
737
738/*
739 * Handle an incoming frame from below.
740 */
741static int
742ng_l2tp_rcvdata_lower(hook_p h, item_p item)
743{
744	static const u_int16_t req_bits[2][2] = {
745		{ L2TP_DATA_0BITS, L2TP_DATA_1BITS },
746		{ L2TP_CTRL_0BITS, L2TP_CTRL_1BITS },
747	};
748	const node_p node = NG_HOOK_NODE(h);
749	const priv_p priv = NG_NODE_PRIVATE(node);
750	hookpriv_p hpriv = NULL;
751	hook_p hook = NULL;
752	struct mbuf *m;
753	u_int16_t tid, sid;
754	u_int16_t hdr;
755	u_int16_t ns, nr;
756	int is_ctrl;
757	int error;
758	int len, plen;
759
760	/* Sanity check */
761	L2TP_SEQ_CHECK(&priv->seq);
762
763	/* If not configured, reject */
764	if (!priv->conf.enabled) {
765		NG_FREE_ITEM(item);
766		ERROUT(ENXIO);
767	}
768
769	/* Grab mbuf */
770	NGI_GET_M(item, m);
771
772	/* Remember full packet length; needed for per session accounting. */
773	plen = m->m_pkthdr.len;
774
775	/* Update stats */
776	priv->stats.recvPackets++;
777	priv->stats.recvOctets += plen;
778
779	/* Get initial header */
780	if (m->m_pkthdr.len < 6) {
781		priv->stats.recvRunts++;
782		NG_FREE_ITEM(item);
783		NG_FREE_M(m);
784		ERROUT(EINVAL);
785	}
786	if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) {
787		priv->stats.memoryFailures++;
788		NG_FREE_ITEM(item);
789		ERROUT(EINVAL);
790	}
791	hdr = (mtod(m, uint8_t *)[0] << 8) + mtod(m, uint8_t *)[1];
792	m_adj(m, 2);
793
794	/* Check required header bits and minimum length */
795	is_ctrl = (hdr & L2TP_HDR_CTRL) != 0;
796	if ((hdr & req_bits[is_ctrl][0]) != 0
797	    || (~hdr & req_bits[is_ctrl][1]) != 0) {
798		priv->stats.recvInvalid++;
799		NG_FREE_ITEM(item);
800		NG_FREE_M(m);
801		ERROUT(EINVAL);
802	}
803	if (m->m_pkthdr.len < 4				/* tunnel, session id */
804	    + (2 * ((hdr & L2TP_HDR_LEN) != 0))		/* length field */
805	    + (4 * ((hdr & L2TP_HDR_SEQ) != 0))		/* seq # fields */
806	    + (2 * ((hdr & L2TP_HDR_OFF) != 0))) {	/* offset field */
807		priv->stats.recvRunts++;
808		NG_FREE_ITEM(item);
809		NG_FREE_M(m);
810		ERROUT(EINVAL);
811	}
812
813	/* Get and validate length field if present */
814	if ((hdr & L2TP_HDR_LEN) != 0) {
815		if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) {
816			priv->stats.memoryFailures++;
817			NG_FREE_ITEM(item);
818			ERROUT(EINVAL);
819		}
820		len = (mtod(m, uint8_t *)[0] << 8) + mtod(m, uint8_t *)[1] - 4;
821		m_adj(m, 2);
822		if (len < 0 || len > m->m_pkthdr.len) {
823			priv->stats.recvInvalid++;
824			NG_FREE_ITEM(item);
825			NG_FREE_M(m);
826			ERROUT(EINVAL);
827		}
828		if (len < m->m_pkthdr.len)		/* trim extra bytes */
829			m_adj(m, -(m->m_pkthdr.len - len));
830	}
831
832	/* Get tunnel ID and session ID */
833	if (m->m_len < 4 && (m = m_pullup(m, 4)) == NULL) {
834		priv->stats.memoryFailures++;
835		NG_FREE_ITEM(item);
836		ERROUT(EINVAL);
837	}
838	tid = (mtod(m, u_int8_t *)[0] << 8) + mtod(m, u_int8_t *)[1];
839	sid = (mtod(m, u_int8_t *)[2] << 8) + mtod(m, u_int8_t *)[3];
840	m_adj(m, 4);
841
842	/* Check tunnel ID */
843	if (tid != priv->conf.tunnel_id &&
844	    (priv->conf.match_id || tid != 0)) {
845		priv->stats.recvWrongTunnel++;
846		NG_FREE_ITEM(item);
847		NG_FREE_M(m);
848		ERROUT(EADDRNOTAVAIL);
849	}
850
851	/* Check session ID (for data packets only) */
852	if ((hdr & L2TP_HDR_CTRL) == 0) {
853		hpriv = ng_l2tp_find_session(priv, sid);
854		if (hpriv == NULL) {
855			priv->stats.recvUnknownSID++;
856			NG_FREE_ITEM(item);
857			NG_FREE_M(m);
858			ERROUT(ENOTCONN);
859		}
860		hook = hpriv->hook;
861	}
862
863	/* Get Ns, Nr fields if present */
864	if ((hdr & L2TP_HDR_SEQ) != 0) {
865		if (m->m_len < 4 && (m = m_pullup(m, 4)) == NULL) {
866			priv->stats.memoryFailures++;
867			NG_FREE_ITEM(item);
868			ERROUT(EINVAL);
869		}
870		ns = (mtod(m, u_int8_t *)[0] << 8) + mtod(m, u_int8_t *)[1];
871		nr = (mtod(m, u_int8_t *)[2] << 8) + mtod(m, u_int8_t *)[3];
872		m_adj(m, 4);
873	} else
874		ns = nr = 0;
875
876	/* Strip offset padding if present */
877	if ((hdr & L2TP_HDR_OFF) != 0) {
878		u_int16_t offset;
879
880		/* Get length of offset padding */
881		if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) {
882			priv->stats.memoryFailures++;
883			NG_FREE_ITEM(item);
884			ERROUT(EINVAL);
885		}
886		offset = (mtod(m, u_int8_t *)[0] << 8) + mtod(m, u_int8_t *)[1];
887
888		/* Trim offset padding */
889		if ((2+offset) > m->m_pkthdr.len) {
890			priv->stats.recvInvalid++;
891			NG_FREE_ITEM(item);
892			NG_FREE_M(m);
893			ERROUT(EINVAL);
894		}
895		m_adj(m, 2+offset);
896	}
897
898	/* Handle control packets */
899	if ((hdr & L2TP_HDR_CTRL) != 0) {
900		struct l2tp_seq *const seq = &priv->seq;
901
902		/* Handle receive ack sequence number Nr */
903		ng_l2tp_seq_recv_nr(priv, nr);
904
905		/* Discard ZLB packets */
906		if (m->m_pkthdr.len == 0) {
907			priv->stats.recvZLBs++;
908			NG_FREE_ITEM(item);
909			NG_FREE_M(m);
910			ERROUT(0);
911		}
912
913		mtx_lock(&seq->mtx);
914		/*
915		 * If not what we expect or we are busy, drop packet and
916		 * send an immediate ZLB ack.
917		 */
918		if (ns != seq->nr || seq->inproc) {
919			if (L2TP_SEQ_DIFF(ns, seq->nr) <= 0)
920				priv->stats.recvDuplicates++;
921			else
922				priv->stats.recvOutOfOrder++;
923			mtx_unlock(&seq->mtx);
924			ng_l2tp_xmit_ctrl(priv, NULL, seq->ns);
925			NG_FREE_ITEM(item);
926			NG_FREE_M(m);
927			ERROUT(0);
928		}
929		/*
930		 * Until we deliver this packet we can't receive next one as
931		 * we have no information for sending ack.
932		 */
933		seq->inproc = 1;
934		mtx_unlock(&seq->mtx);
935
936		/* Prepend session ID to packet. */
937		M_PREPEND(m, 2, M_NOWAIT);
938		if (m == NULL) {
939			seq->inproc = 0;
940			priv->stats.memoryFailures++;
941			NG_FREE_ITEM(item);
942			ERROUT(ENOBUFS);
943		}
944		mtod(m, u_int8_t *)[0] = sid >> 8;
945		mtod(m, u_int8_t *)[1] = sid & 0xff;
946
947		/* Deliver packet to upper layers */
948		NG_FWD_NEW_DATA(error, item, priv->ctrl, m);
949
950		mtx_lock(&seq->mtx);
951		/* Ready to process next packet. */
952		seq->inproc = 0;
953
954		/* If packet was successfully delivered send ack. */
955		if (error == 0) {
956			/* Update recv sequence number */
957			seq->nr++;
958			/* Start receive ack timer, if not already running */
959			if (!callout_active(&seq->xack_timer)) {
960				ng_callout(&seq->xack_timer, priv->node, NULL,
961				    L2TP_DELAYED_ACK, ng_l2tp_seq_xack_timeout,
962				    NULL, 0);
963			}
964		}
965		mtx_unlock(&seq->mtx);
966
967		ERROUT(error);
968	}
969
970	/* Per session packet, account it. */
971	hpriv->stats.recvPackets++;
972	hpriv->stats.recvOctets += plen;
973
974	/* Follow peer's lead in data sequencing, if configured to do so */
975	if (!hpriv->conf.control_dseq)
976		hpriv->conf.enable_dseq = ((hdr & L2TP_HDR_SEQ) != 0);
977
978	/* Handle data sequence numbers if present and enabled */
979	if ((hdr & L2TP_HDR_SEQ) != 0) {
980		if (hpriv->conf.enable_dseq
981		    && L2TP_SEQ_DIFF(ns, hpriv->nr) < 0) {
982			NG_FREE_ITEM(item);	/* duplicate or out of order */
983			NG_FREE_M(m);
984			priv->stats.recvDataDrops++;
985			ERROUT(0);
986		}
987		hpriv->nr = ns + 1;
988	}
989
990	/* Drop empty data packets */
991	if (m->m_pkthdr.len == 0) {
992		NG_FREE_ITEM(item);
993		NG_FREE_M(m);
994		ERROUT(0);
995	}
996
997	/* Deliver data */
998	NG_FWD_NEW_DATA(error, item, hook, m);
999done:
1000	/* Done */
1001	L2TP_SEQ_CHECK(&priv->seq);
1002	return (error);
1003}
1004
1005/*
1006 * Handle an outgoing control frame.
1007 */
1008static int
1009ng_l2tp_rcvdata_ctrl(hook_p hook, item_p item)
1010{
1011	const node_p node = NG_HOOK_NODE(hook);
1012	const priv_p priv = NG_NODE_PRIVATE(node);
1013	struct l2tp_seq *const seq = &priv->seq;
1014	struct mbuf *m;
1015	int error;
1016	int i;
1017	u_int16_t	ns;
1018
1019	/* Sanity check */
1020	L2TP_SEQ_CHECK(&priv->seq);
1021
1022	/* If not configured, reject */
1023	if (!priv->conf.enabled) {
1024		NG_FREE_ITEM(item);
1025		ERROUT(ENXIO);
1026	}
1027
1028	/* Grab mbuf and discard other stuff XXX */
1029	NGI_GET_M(item, m);
1030	NG_FREE_ITEM(item);
1031
1032	/* Packet should have session ID prepended */
1033	if (m->m_pkthdr.len < 2) {
1034		priv->stats.xmitInvalid++;
1035		m_freem(m);
1036		ERROUT(EINVAL);
1037	}
1038
1039	/* Check max length */
1040	if (m->m_pkthdr.len >= 0x10000 - 14) {
1041		priv->stats.xmitTooBig++;
1042		m_freem(m);
1043		ERROUT(EOVERFLOW);
1044	}
1045
1046	mtx_lock(&seq->mtx);
1047
1048	/* Find next empty slot in transmit queue */
1049	for (i = 0; i < L2TP_MAX_XWIN && seq->xwin[i] != NULL; i++);
1050	if (i == L2TP_MAX_XWIN) {
1051		mtx_unlock(&seq->mtx);
1052		priv->stats.xmitDrops++;
1053		m_freem(m);
1054		ERROUT(ENOBUFS);
1055	}
1056	seq->xwin[i] = m;
1057
1058	/* If peer's receive window is already full, nothing else to do */
1059	if (i >= seq->cwnd) {
1060		mtx_unlock(&seq->mtx);
1061		ERROUT(0);
1062	}
1063
1064	/* Start retransmit timer if not already running */
1065	if (!callout_active(&seq->rack_timer))
1066		ng_callout(&seq->rack_timer, node, NULL,
1067		    hz, ng_l2tp_seq_rack_timeout, NULL, 0);
1068
1069	ns = seq->ns++;
1070
1071	mtx_unlock(&seq->mtx);
1072
1073	/* Copy packet */
1074	if ((m = L2TP_COPY_MBUF(m, M_NOWAIT)) == NULL) {
1075		priv->stats.memoryFailures++;
1076		ERROUT(ENOBUFS);
1077	}
1078
1079	/* Send packet and increment xmit sequence number */
1080	error = ng_l2tp_xmit_ctrl(priv, m, ns);
1081done:
1082	/* Done */
1083	L2TP_SEQ_CHECK(&priv->seq);
1084	return (error);
1085}
1086
1087/*
1088 * Handle an outgoing data frame.
1089 */
1090static int
1091ng_l2tp_rcvdata(hook_p hook, item_p item)
1092{
1093	const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
1094	const hookpriv_p hpriv = NG_HOOK_PRIVATE(hook);
1095	struct mbuf *m;
1096	uint8_t *p;
1097	u_int16_t hdr;
1098	int error;
1099	int i = 2;
1100
1101	/* Sanity check */
1102	L2TP_SEQ_CHECK(&priv->seq);
1103
1104	/* If not configured, reject */
1105	if (!priv->conf.enabled) {
1106		NG_FREE_ITEM(item);
1107		ERROUT(ENXIO);
1108	}
1109
1110	/* Get mbuf */
1111	NGI_GET_M(item, m);
1112
1113	/* Check max length */
1114	if (m->m_pkthdr.len >= 0x10000 - 12) {
1115		priv->stats.xmitDataTooBig++;
1116		NG_FREE_ITEM(item);
1117		NG_FREE_M(m);
1118		ERROUT(EOVERFLOW);
1119	}
1120
1121	/* Prepend L2TP header */
1122	M_PREPEND(m, 6
1123	    + (2 * (hpriv->conf.include_length != 0))
1124	    + (4 * (hpriv->conf.enable_dseq != 0)),
1125	    M_NOWAIT);
1126	if (m == NULL) {
1127		priv->stats.memoryFailures++;
1128		NG_FREE_ITEM(item);
1129		ERROUT(ENOBUFS);
1130	}
1131	p = mtod(m, uint8_t *);
1132	hdr = L2TP_DATA_HDR;
1133	if (hpriv->conf.include_length) {
1134		hdr |= L2TP_HDR_LEN;
1135		p[i++] = m->m_pkthdr.len >> 8;
1136		p[i++] = m->m_pkthdr.len & 0xff;
1137	}
1138	p[i++] = priv->conf.peer_id >> 8;
1139	p[i++] = priv->conf.peer_id & 0xff;
1140	p[i++] = hpriv->conf.peer_id >> 8;
1141	p[i++] = hpriv->conf.peer_id & 0xff;
1142	if (hpriv->conf.enable_dseq) {
1143		hdr |= L2TP_HDR_SEQ;
1144		p[i++] = hpriv->ns >> 8;
1145		p[i++] = hpriv->ns & 0xff;
1146		p[i++] = hpriv->nr >> 8;
1147		p[i++] = hpriv->nr & 0xff;
1148		hpriv->ns++;
1149	}
1150	p[0] = hdr >> 8;
1151	p[1] = hdr & 0xff;
1152
1153	/* Update per session stats. */
1154	hpriv->stats.xmitPackets++;
1155	hpriv->stats.xmitOctets += m->m_pkthdr.len;
1156
1157	/* And the global one. */
1158	priv->stats.xmitPackets++;
1159	priv->stats.xmitOctets += m->m_pkthdr.len;
1160
1161	/* Send packet */
1162	NG_FWD_NEW_DATA(error, item, priv->lower, m);
1163done:
1164	/* Done */
1165	L2TP_SEQ_CHECK(&priv->seq);
1166	return (error);
1167}
1168
1169/*
1170 * Send a message to our controlling node that we've failed.
1171 */
1172static void
1173ng_l2tp_seq_failure(priv_p priv)
1174{
1175	struct ng_mesg *msg;
1176	int error;
1177
1178	NG_MKMESSAGE(msg, NGM_L2TP_COOKIE, NGM_L2TP_ACK_FAILURE, 0, M_NOWAIT);
1179	if (msg == NULL)
1180		return;
1181	NG_SEND_MSG_ID(error, priv->node, msg, priv->ftarget, 0);
1182}
1183
1184/************************************************************************
1185			SEQUENCE NUMBER HANDLING
1186************************************************************************/
1187
1188/*
1189 * Initialize sequence number state.
1190 */
1191static void
1192ng_l2tp_seq_init(priv_p priv)
1193{
1194	struct l2tp_seq *const seq = &priv->seq;
1195
1196	KASSERT(priv->conf.peer_win >= 1,
1197	    ("%s: peer_win is zero", __func__));
1198	memset(seq, 0, sizeof(*seq));
1199	seq->cwnd = 1;
1200	seq->wmax = priv->conf.peer_win;
1201	if (seq->wmax > L2TP_MAX_XWIN)
1202		seq->wmax = L2TP_MAX_XWIN;
1203	seq->ssth = seq->wmax;
1204	ng_callout_init(&seq->rack_timer);
1205	ng_callout_init(&seq->xack_timer);
1206	mtx_init(&seq->mtx, "ng_l2tp", NULL, MTX_DEF);
1207	L2TP_SEQ_CHECK(seq);
1208}
1209
1210/*
1211 * Set sequence number state as given from user.
1212 */
1213static int
1214ng_l2tp_seq_set(priv_p priv, const struct ng_l2tp_seq_config *conf)
1215{
1216	struct l2tp_seq *const seq = &priv->seq;
1217
1218	/* If node is enabled, deny update to sequence numbers. */
1219	if (priv->conf.enabled)
1220		return (EBUSY);
1221
1222	/* We only can handle the simple cases. */
1223	if (conf->xack != conf->nr || conf->ns != conf->rack)
1224		return (EINVAL);
1225
1226	/* Set ns,nr,rack,xack parameters. */
1227	seq->ns = conf->ns;
1228	seq->nr = conf->nr;
1229	seq->rack = conf->rack;
1230	seq->xack = conf->xack;
1231
1232	return (0);
1233}
1234
1235/*
1236 * Adjust sequence number state accordingly after reconfiguration.
1237 */
1238static int
1239ng_l2tp_seq_adjust(priv_p priv, const struct ng_l2tp_config *conf)
1240{
1241	struct l2tp_seq *const seq = &priv->seq;
1242	u_int16_t new_wmax;
1243
1244	/* If disabling node, reset state sequence number */
1245	if (!conf->enabled) {
1246		ng_l2tp_seq_reset(priv);
1247		return (0);
1248	}
1249
1250	/* Adjust peer's max recv window; it can only increase */
1251	new_wmax = conf->peer_win;
1252	if (new_wmax > L2TP_MAX_XWIN)
1253		new_wmax = L2TP_MAX_XWIN;
1254	if (new_wmax == 0)
1255		return (EINVAL);
1256	if (new_wmax < seq->wmax)
1257		return (EBUSY);
1258	seq->wmax = new_wmax;
1259
1260	/* Done */
1261	return (0);
1262}
1263
1264/*
1265 * Reset sequence number state.
1266 */
1267static void
1268ng_l2tp_seq_reset(priv_p priv)
1269{
1270	struct l2tp_seq *const seq = &priv->seq;
1271	hook_p hook;
1272	int i;
1273
1274	/* Sanity check */
1275	L2TP_SEQ_CHECK(seq);
1276
1277	/* Stop timers */
1278	ng_uncallout(&seq->rack_timer, priv->node);
1279	ng_uncallout(&seq->xack_timer, priv->node);
1280
1281	/* Free retransmit queue */
1282	for (i = 0; i < L2TP_MAX_XWIN; i++) {
1283		if (seq->xwin[i] == NULL)
1284			break;
1285		m_freem(seq->xwin[i]);
1286	}
1287
1288	/* Reset session hooks' sequence number states */
1289	NG_NODE_FOREACH_HOOK(priv->node, ng_l2tp_reset_session, NULL, hook);
1290
1291	/* Reset node's sequence number state */
1292	seq->ns = 0;
1293	seq->nr = 0;
1294	seq->rack = 0;
1295	seq->xack = 0;
1296	seq->wmax = L2TP_MAX_XWIN;
1297	seq->cwnd = 1;
1298	seq->ssth = seq->wmax;
1299	seq->acks = 0;
1300	seq->rexmits = 0;
1301	bzero(seq->xwin, sizeof(seq->xwin));
1302
1303	/* Done */
1304	L2TP_SEQ_CHECK(seq);
1305}
1306
1307/*
1308 * Handle receipt of an acknowledgement value (Nr) from peer.
1309 */
1310static void
1311ng_l2tp_seq_recv_nr(priv_p priv, u_int16_t nr)
1312{
1313	struct l2tp_seq *const seq = &priv->seq;
1314	struct mbuf	*xwin[L2TP_MAX_XWIN];	/* partial local copy */
1315	int		nack;
1316	int		i, j;
1317	uint16_t	ns;
1318
1319	mtx_lock(&seq->mtx);
1320
1321	/* Verify peer's ACK is in range */
1322	if ((nack = L2TP_SEQ_DIFF(nr, seq->rack)) <= 0) {
1323		mtx_unlock(&seq->mtx);
1324		return;				/* duplicate ack */
1325	}
1326	if (L2TP_SEQ_DIFF(nr, seq->ns) > 0) {
1327		mtx_unlock(&seq->mtx);
1328		priv->stats.recvBadAcks++;	/* ack for packet not sent */
1329		return;
1330	}
1331	KASSERT(nack <= L2TP_MAX_XWIN,
1332	    ("%s: nack=%d > %d", __func__, nack, L2TP_MAX_XWIN));
1333
1334	/* Update receive ack stats */
1335	seq->rack = nr;
1336	seq->rexmits = 0;
1337
1338	/* Free acknowledged packets and shift up packets in the xmit queue */
1339	for (i = 0; i < nack; i++)
1340		m_freem(seq->xwin[i]);
1341	memmove(seq->xwin, seq->xwin + nack,
1342	    (L2TP_MAX_XWIN - nack) * sizeof(*seq->xwin));
1343	memset(seq->xwin + (L2TP_MAX_XWIN - nack), 0,
1344	    nack * sizeof(*seq->xwin));
1345
1346	/*
1347	 * Do slow-start/congestion avoidance windowing algorithm described
1348	 * in RFC 2661, Appendix A. Here we handle a multiple ACK as if each
1349	 * ACK had arrived separately.
1350	 */
1351	if (seq->cwnd < seq->wmax) {
1352
1353		/* Handle slow start phase */
1354		if (seq->cwnd < seq->ssth) {
1355			seq->cwnd += nack;
1356			nack = 0;
1357			if (seq->cwnd > seq->ssth) {	/* into cg.av. phase */
1358				nack = seq->cwnd - seq->ssth;
1359				seq->cwnd = seq->ssth;
1360			}
1361		}
1362
1363		/* Handle congestion avoidance phase */
1364		if (seq->cwnd >= seq->ssth) {
1365			seq->acks += nack;
1366			while (seq->acks >= seq->cwnd) {
1367				seq->acks -= seq->cwnd;
1368				if (seq->cwnd < seq->wmax)
1369					seq->cwnd++;
1370			}
1371		}
1372	}
1373
1374	/* Stop xmit timer */
1375	if (callout_active(&seq->rack_timer))
1376		ng_uncallout(&seq->rack_timer, priv->node);
1377
1378	/* If transmit queue is empty, we're done for now */
1379	if (seq->xwin[0] == NULL) {
1380		mtx_unlock(&seq->mtx);
1381		return;
1382	}
1383
1384	/* Start restransmit timer again */
1385	ng_callout(&seq->rack_timer, priv->node, NULL,
1386	    hz, ng_l2tp_seq_rack_timeout, NULL, 0);
1387
1388	/*
1389	 * Send more packets, trying to keep peer's receive window full.
1390	 * Make copy of everything we need before lock release.
1391	 */
1392	ns = seq->ns;
1393	j = 0;
1394	while ((i = L2TP_SEQ_DIFF(seq->ns, seq->rack)) < seq->cwnd
1395	    && seq->xwin[i] != NULL) {
1396		xwin[j++] = seq->xwin[i];
1397		seq->ns++;
1398	}
1399
1400	mtx_unlock(&seq->mtx);
1401
1402	/*
1403	 * Send prepared.
1404	 * If there is a memory error, pretend packet was sent, as it
1405	 * will get retransmitted later anyway.
1406	 */
1407	for (i = 0; i < j; i++) {
1408		struct mbuf 	*m;
1409		if ((m = L2TP_COPY_MBUF(xwin[i], M_NOWAIT)) == NULL)
1410			priv->stats.memoryFailures++;
1411		else
1412			ng_l2tp_xmit_ctrl(priv, m, ns);
1413		ns++;
1414	}
1415}
1416
1417/*
1418 * Handle an ack timeout. We have an outstanding ack that we
1419 * were hoping to piggy-back, but haven't, so send a ZLB.
1420 */
1421static void
1422ng_l2tp_seq_xack_timeout(node_p node, hook_p hook, void *arg1, int arg2)
1423{
1424	const priv_p priv = NG_NODE_PRIVATE(node);
1425	struct l2tp_seq *const seq = &priv->seq;
1426
1427	/* Make sure callout is still active before doing anything */
1428	if (callout_pending(&seq->xack_timer) ||
1429	    (!callout_active(&seq->xack_timer)))
1430		return;
1431
1432	/* Sanity check */
1433	L2TP_SEQ_CHECK(seq);
1434
1435	/* Send a ZLB */
1436	ng_l2tp_xmit_ctrl(priv, NULL, seq->ns);
1437
1438	/* callout_deactivate() is not needed here
1439	    as ng_uncallout() was called by ng_l2tp_xmit_ctrl() */
1440
1441	/* Sanity check */
1442	L2TP_SEQ_CHECK(seq);
1443}
1444
1445/*
1446 * Handle a transmit timeout. The peer has failed to respond
1447 * with an ack for our packet, so retransmit it.
1448 */
1449static void
1450ng_l2tp_seq_rack_timeout(node_p node, hook_p hook, void *arg1, int arg2)
1451{
1452	const priv_p priv = NG_NODE_PRIVATE(node);
1453	struct l2tp_seq *const seq = &priv->seq;
1454	struct mbuf *m;
1455	u_int delay;
1456
1457	/* Make sure callout is still active before doing anything */
1458	if (callout_pending(&seq->rack_timer) ||
1459	    (!callout_active(&seq->rack_timer)))
1460		return;
1461
1462	/* Sanity check */
1463	L2TP_SEQ_CHECK(seq);
1464
1465	priv->stats.xmitRetransmits++;
1466
1467	/* Have we reached the retransmit limit? If so, notify owner. */
1468	if (seq->rexmits++ >= priv->conf.rexmit_max)
1469		ng_l2tp_seq_failure(priv);
1470
1471	/* Restart timer, this time with an increased delay */
1472	delay = (seq->rexmits > 12) ? (1 << 12) : (1 << seq->rexmits);
1473	if (delay > priv->conf.rexmit_max_to)
1474		delay = priv->conf.rexmit_max_to;
1475	ng_callout(&seq->rack_timer, node, NULL,
1476	    hz * delay, ng_l2tp_seq_rack_timeout, NULL, 0);
1477
1478	/* Do slow-start/congestion algorithm windowing algorithm */
1479	seq->ns = seq->rack;
1480	seq->ssth = (seq->cwnd + 1) / 2;
1481	seq->cwnd = 1;
1482	seq->acks = 0;
1483
1484	/* Retransmit oldest unack'd packet */
1485	if ((m = L2TP_COPY_MBUF(seq->xwin[0], M_NOWAIT)) == NULL)
1486		priv->stats.memoryFailures++;
1487	else
1488		ng_l2tp_xmit_ctrl(priv, m, seq->ns++);
1489
1490	/* callout_deactivate() is not needed here
1491	    as ng_callout() is getting called each time */
1492
1493	/* Sanity check */
1494	L2TP_SEQ_CHECK(seq);
1495}
1496
1497/*
1498 * Transmit a control stream packet, payload optional.
1499 * The transmit sequence number is not incremented.
1500 */
1501static int
1502ng_l2tp_xmit_ctrl(priv_p priv, struct mbuf *m, u_int16_t ns)
1503{
1504	struct l2tp_seq *const seq = &priv->seq;
1505	uint8_t *p;
1506	u_int16_t session_id = 0;
1507	int error;
1508
1509	mtx_lock(&seq->mtx);
1510
1511	/* Stop ack timer: we're sending an ack with this packet.
1512	   Doing this before to keep state predictable after error. */
1513	if (callout_active(&seq->xack_timer))
1514		ng_uncallout(&seq->xack_timer, priv->node);
1515
1516	seq->xack = seq->nr;
1517
1518	mtx_unlock(&seq->mtx);
1519
1520	/* If no mbuf passed, send an empty packet (ZLB) */
1521	if (m == NULL) {
1522
1523		/* Create a new mbuf for ZLB packet */
1524		MGETHDR(m, M_NOWAIT, MT_DATA);
1525		if (m == NULL) {
1526			priv->stats.memoryFailures++;
1527			return (ENOBUFS);
1528		}
1529		m->m_len = m->m_pkthdr.len = 12;
1530		m->m_pkthdr.rcvif = NULL;
1531		priv->stats.xmitZLBs++;
1532	} else {
1533
1534		/* Strip off session ID */
1535		if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) {
1536			priv->stats.memoryFailures++;
1537			return (ENOBUFS);
1538		}
1539		session_id = (mtod(m, u_int8_t *)[0] << 8) + mtod(m, u_int8_t *)[1];
1540
1541		/* Make room for L2TP header */
1542		M_PREPEND(m, 10, M_NOWAIT);	/* - 2 + 12 = 10 */
1543		if (m == NULL) {
1544			priv->stats.memoryFailures++;
1545			return (ENOBUFS);
1546		}
1547	}
1548
1549	/* Fill in L2TP header */
1550	p = mtod(m, u_int8_t *);
1551	p[0] = L2TP_CTRL_HDR >> 8;
1552	p[1] = L2TP_CTRL_HDR & 0xff;
1553	p[2] = m->m_pkthdr.len >> 8;
1554	p[3] = m->m_pkthdr.len & 0xff;
1555	p[4] = priv->conf.peer_id >> 8;
1556	p[5] = priv->conf.peer_id & 0xff;
1557	p[6] = session_id >> 8;
1558	p[7] = session_id & 0xff;
1559	p[8] = ns >> 8;
1560	p[9] = ns & 0xff;
1561	p[10] = seq->nr >> 8;
1562	p[11] = seq->nr & 0xff;
1563
1564	/* Update sequence number info and stats */
1565	priv->stats.xmitPackets++;
1566	priv->stats.xmitOctets += m->m_pkthdr.len;
1567
1568	/* Send packet */
1569	NG_SEND_DATA_ONLY(error, priv->lower, m);
1570	return (error);
1571}
1572
1573#ifdef INVARIANTS
1574/*
1575 * Sanity check sequence number state.
1576 */
1577static void
1578ng_l2tp_seq_check(struct l2tp_seq *seq)
1579{
1580	int self_unack, peer_unack;
1581	int i;
1582
1583#define CHECK(p)	KASSERT((p), ("%s: not: %s", __func__, #p))
1584
1585	mtx_lock(&seq->mtx);
1586
1587	self_unack = L2TP_SEQ_DIFF(seq->nr, seq->xack);
1588	peer_unack = L2TP_SEQ_DIFF(seq->ns, seq->rack);
1589	CHECK(seq->wmax <= L2TP_MAX_XWIN);
1590	CHECK(seq->cwnd >= 1);
1591	CHECK(seq->cwnd <= seq->wmax);
1592	CHECK(seq->ssth >= 1);
1593	CHECK(seq->ssth <= seq->wmax);
1594	if (seq->cwnd < seq->ssth)
1595		CHECK(seq->acks == 0);
1596	else
1597		CHECK(seq->acks <= seq->cwnd);
1598	CHECK(self_unack >= 0);
1599	CHECK(peer_unack >= 0);
1600	CHECK(peer_unack <= seq->wmax);
1601	CHECK((self_unack == 0) ^ callout_active(&seq->xack_timer));
1602	CHECK((peer_unack == 0) ^ callout_active(&seq->rack_timer));
1603	for (i = 0; i < peer_unack; i++)
1604		CHECK(seq->xwin[i] != NULL);
1605	for ( ; i < seq->cwnd; i++)	    /* verify peer's recv window full */
1606		CHECK(seq->xwin[i] == NULL);
1607
1608	mtx_unlock(&seq->mtx);
1609
1610#undef CHECK
1611}
1612#endif	/* INVARIANTS */
1613