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