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.4 2003/08/07 21:17:32 dillon 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 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 MALLOC(priv, priv_p, 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 FREE(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 MALLOC(hpriv, hookpriv_p, 384 sizeof(*hpriv), M_NETGRAPH_L2TP, 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 FREE(priv->ftarget, M_NETGRAPH_L2TP); 437 MALLOC(priv->ftarget, char *, 438 strlen(raddr) + 1, 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 FREE(resp, M_NETGRAPH); 575 FREE(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 FREE(priv->ftarget, M_NETGRAPH_L2TP); 641 FREE(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 FREE(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, M_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 __FUNCTION__, 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], M_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 M_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 (void)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", __FUNCTION__)); 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", __FUNCTION__, 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], M_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 int s; 1266 1267 /* Check if node is going away */ 1268 s = splnet(); 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 splx(s); 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 splx(s); 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 int s; 1309 1310 /* Check if node is going away */ 1311 s = splnet(); 1312 if (NG_NODE_NOT_VALID(node)) { 1313 seq->rack_timer_running = 0; 1314 if (!seq->xack_timer_running) { 1315 if (priv->ftarget != NULL) 1316 FREE(priv->ftarget, M_NETGRAPH_L2TP); 1317 FREE(priv, M_NETGRAPH_L2TP); 1318 NG_NODE_SET_PRIVATE(node, NULL); 1319 } 1320 NG_NODE_UNREF(node); 1321 splx(s); 1322 return; 1323 } 1324 1325 /* Sanity check */ 1326 L2TP_SEQ_CHECK(seq); 1327 1328 /* Make sure peer's ack is still outstanding before doing anything */ 1329 if (seq->rack == seq->ns) { 1330 seq->rack_timer_running = 0; 1331 NG_NODE_UNREF(node); 1332 goto done; 1333 } 1334 priv->stats.xmitRetransmits++; 1335 1336 /* Have we reached the retransmit limit? If so, notify owner. */ 1337 if (seq->rexmits++ >= seq->max_rexmits) 1338 ng_l2tp_seq_failure(priv); 1339 1340 /* Restart timer, this time with an increased delay */ 1341 delay = (seq->rexmits > 12) ? (1 << 12) : (1 << seq->rexmits); 1342 if (delay > seq->max_rexmit_to) 1343 delay = seq->max_rexmit_to; 1344 callout_reset(&seq->rack_timer, 1345 hz * delay, ng_l2tp_seq_rack_timeout, node); 1346 1347 /* Do slow-start/congestion algorithm windowing algorithm */ 1348 seq->ssth = (seq->cwnd + 1) / 2; 1349 seq->cwnd = 1; 1350 seq->acks = 0; 1351 1352 /* Retransmit oldest unack'd packet */ 1353 if ((m = L2TP_COPY_MBUF(seq->xwin[0], M_DONTWAIT)) == NULL) 1354 priv->stats.memoryFailures++; 1355 else 1356 ng_l2tp_xmit_ctrl(priv, m, seq->rack); 1357 1358 done: 1359 /* Done */ 1360 L2TP_SEQ_CHECK(seq); 1361 splx(s); 1362 } 1363 1364 /* 1365 * Transmit a control stream packet, payload optional. 1366 * The transmit sequence number is not incremented. 1367 */ 1368 static int 1369 ng_l2tp_xmit_ctrl(priv_p priv, struct mbuf *m, u_int16_t ns) 1370 { 1371 struct l2tp_seq *const seq = &priv->seq; 1372 u_int16_t session_id = 0; 1373 meta_p meta = NULL; 1374 int error; 1375 1376 /* If no mbuf passed, send an empty packet (ZLB) */ 1377 if (m == NULL) { 1378 1379 /* Create a new mbuf for ZLB packet */ 1380 MGETHDR(m, M_DONTWAIT, MT_DATA); 1381 if (m == NULL) { 1382 priv->stats.memoryFailures++; 1383 return (ENOBUFS); 1384 } 1385 m->m_len = m->m_pkthdr.len = 12; 1386 m->m_pkthdr.rcvif = NULL; 1387 priv->stats.xmitZLBs++; 1388 } else { 1389 1390 /* Strip off session ID */ 1391 if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) { 1392 priv->stats.memoryFailures++; 1393 return (ENOBUFS); 1394 } 1395 memcpy(&session_id, mtod(m, u_int16_t *), 2); 1396 m_adj(m, 2); 1397 1398 /* Make room for L2TP header */ 1399 M_PREPEND(m, 12, M_DONTWAIT); 1400 if (m == NULL) { 1401 priv->stats.memoryFailures++; 1402 return (ENOBUFS); 1403 } 1404 } 1405 1406 /* Fill in L2TP header */ 1407 mtod(m, u_int16_t *)[0] = htons(L2TP_CTRL_HDR); 1408 mtod(m, u_int16_t *)[1] = htons(m->m_pkthdr.len); 1409 mtod(m, u_int16_t *)[2] = priv->conf.peer_id; 1410 mtod(m, u_int16_t *)[3] = session_id; 1411 mtod(m, u_int16_t *)[4] = htons(ns); 1412 mtod(m, u_int16_t *)[5] = htons(seq->nr); 1413 1414 /* Update sequence number info and stats */ 1415 priv->stats.xmitPackets++; 1416 priv->stats.xmitOctets += m->m_pkthdr.len; 1417 1418 /* Stop ack timer: we're sending an ack with this packet */ 1419 if (seq->xack_timer_running && callout_stop(&seq->xack_timer) == 1) { 1420 seq->xack_timer_running = 0; 1421 NG_NODE_UNREF(priv->node); 1422 } 1423 seq->xack = seq->nr; 1424 1425 /* Send packet */ 1426 NG_SEND_DATA(error, priv->lower, m, meta); 1427 return (error); 1428 } 1429 1430 #ifdef INVARIANTS 1431 /* 1432 * Sanity check sequence number state. 1433 */ 1434 static void 1435 ng_l2tp_seq_check(struct l2tp_seq *seq) 1436 { 1437 const int self_unack = L2TP_SEQ_DIFF(seq->nr, seq->xack); 1438 const int peer_unack = L2TP_SEQ_DIFF(seq->ns, seq->rack); 1439 int i; 1440 1441 #define CHECK(p) KASSERT((p), ("%s: not: %s", __FUNCTION__, #p)) 1442 1443 CHECK(seq->wmax <= L2TP_MAX_XWIN); 1444 CHECK(seq->cwnd >= 1); 1445 CHECK(seq->cwnd <= seq->wmax); 1446 CHECK(seq->ssth >= 1); 1447 CHECK(seq->ssth <= seq->wmax); 1448 if (seq->cwnd < seq->ssth) 1449 CHECK(seq->acks == 0); 1450 else 1451 CHECK(seq->acks <= seq->cwnd); 1452 CHECK(self_unack >= 0); 1453 CHECK(peer_unack >= 0); 1454 CHECK(peer_unack <= seq->wmax); 1455 CHECK((self_unack == 0) ^ seq->xack_timer_running); 1456 CHECK((peer_unack == 0) ^ seq->rack_timer_running); 1457 CHECK(seq->rack_timer_running || !callout_pending(&seq->rack_timer)); 1458 CHECK(seq->xack_timer_running || !callout_pending(&seq->xack_timer)); 1459 for (i = 0; i < peer_unack; i++) 1460 CHECK(seq->xwin[i] != NULL); 1461 for ( ; i < seq->cwnd; i++) /* verify peer's recv window full */ 1462 CHECK(seq->xwin[i] == NULL); 1463 1464 #undef CHECK 1465 } 1466 #endif /* INVARIANTS */ 1467 1468 1469