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