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