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 struct ng_l2tp_session_stats stats; /* per sessions statistics */ 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, item_p item); 169 static int ng_l2tp_recv_ctrl(node_p node, item_p item); 170 static int ng_l2tp_recv_data(node_p node, item_p item, hookpriv_p hpriv); 171 172 static int ng_l2tp_xmit_ctrl(priv_p priv, struct mbuf *m, u_int16_t ns); 173 174 static void ng_l2tp_seq_init(priv_p priv); 175 static int ng_l2tp_seq_set(priv_p priv, 176 const struct ng_l2tp_seq_config *conf); 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 static ng_fn_eachhook ng_l2tp_find_session; 187 static ng_fn_eachhook ng_l2tp_reset_session; 188 189 #ifdef INVARIANTS 190 static void ng_l2tp_seq_check(struct l2tp_seq *seq); 191 #endif 192 193 /* Parse type for struct ng_l2tp_seq_config. */ 194 static const struct ng_parse_struct_field 195 ng_l2tp_seq_config_fields[] = NG_L2TP_SEQ_CONFIG_TYPE_INFO; 196 static const struct ng_parse_type ng_l2tp_seq_config_type = { 197 &ng_parse_struct_type, 198 &ng_l2tp_seq_config_fields 199 }; 200 201 /* Parse type for struct ng_l2tp_config */ 202 static const struct ng_parse_struct_field 203 ng_l2tp_config_type_fields[] = NG_L2TP_CONFIG_TYPE_INFO; 204 static const struct ng_parse_type ng_l2tp_config_type = { 205 &ng_parse_struct_type, 206 &ng_l2tp_config_type_fields, 207 }; 208 209 /* Parse type for struct ng_l2tp_sess_config */ 210 static const struct ng_parse_struct_field 211 ng_l2tp_sess_config_type_fields[] = NG_L2TP_SESS_CONFIG_TYPE_INFO; 212 static const struct ng_parse_type ng_l2tp_sess_config_type = { 213 &ng_parse_struct_type, 214 &ng_l2tp_sess_config_type_fields, 215 }; 216 217 /* Parse type for struct ng_l2tp_stats */ 218 static const struct ng_parse_struct_field 219 ng_l2tp_stats_type_fields[] = NG_L2TP_STATS_TYPE_INFO; 220 static const struct ng_parse_type ng_l2tp_stats_type = { 221 &ng_parse_struct_type, 222 &ng_l2tp_stats_type_fields 223 }; 224 225 /* Parse type for struct ng_l2tp_session_stats. */ 226 static const struct ng_parse_struct_field 227 ng_l2tp_session_stats_type_fields[] = NG_L2TP_SESSION_STATS_TYPE_INFO; 228 static const struct ng_parse_type ng_l2tp_session_stats_type = { 229 &ng_parse_struct_type, 230 &ng_l2tp_session_stats_type_fields 231 }; 232 233 /* List of commands and how to convert arguments to/from ASCII */ 234 static const struct ng_cmdlist ng_l2tp_cmdlist[] = { 235 { 236 NGM_L2TP_COOKIE, 237 NGM_L2TP_SET_CONFIG, 238 "setconfig", 239 &ng_l2tp_config_type, 240 NULL 241 }, 242 { 243 NGM_L2TP_COOKIE, 244 NGM_L2TP_GET_CONFIG, 245 "getconfig", 246 NULL, 247 &ng_l2tp_config_type 248 }, 249 { 250 NGM_L2TP_COOKIE, 251 NGM_L2TP_SET_SESS_CONFIG, 252 "setsessconfig", 253 &ng_l2tp_sess_config_type, 254 NULL 255 }, 256 { 257 NGM_L2TP_COOKIE, 258 NGM_L2TP_GET_SESS_CONFIG, 259 "getsessconfig", 260 &ng_parse_hint16_type, 261 &ng_l2tp_sess_config_type 262 }, 263 { 264 NGM_L2TP_COOKIE, 265 NGM_L2TP_GET_STATS, 266 "getstats", 267 NULL, 268 &ng_l2tp_stats_type 269 }, 270 { 271 NGM_L2TP_COOKIE, 272 NGM_L2TP_CLR_STATS, 273 "clrstats", 274 NULL, 275 NULL 276 }, 277 { 278 NGM_L2TP_COOKIE, 279 NGM_L2TP_GETCLR_STATS, 280 "getclrstats", 281 NULL, 282 &ng_l2tp_stats_type 283 }, 284 { 285 NGM_L2TP_COOKIE, 286 NGM_L2TP_GET_SESSION_STATS, 287 "getsessstats", 288 &ng_parse_int16_type, 289 &ng_l2tp_session_stats_type 290 }, 291 { 292 NGM_L2TP_COOKIE, 293 NGM_L2TP_CLR_SESSION_STATS, 294 "clrsessstats", 295 &ng_parse_int16_type, 296 NULL 297 }, 298 { 299 NGM_L2TP_COOKIE, 300 NGM_L2TP_GETCLR_SESSION_STATS, 301 "getclrsessstats", 302 &ng_parse_int16_type, 303 &ng_l2tp_session_stats_type 304 }, 305 { 306 NGM_L2TP_COOKIE, 307 NGM_L2TP_ACK_FAILURE, 308 "ackfailure", 309 NULL, 310 NULL 311 }, 312 { 313 NGM_L2TP_COOKIE, 314 NGM_L2TP_SET_SEQ, 315 "setsequence", 316 &ng_l2tp_seq_config_type, 317 NULL 318 }, 319 { 0 } 320 }; 321 322 /* Node type descriptor */ 323 static struct ng_type ng_l2tp_typestruct = { 324 .version = NG_ABI_VERSION, 325 .name = NG_L2TP_NODE_TYPE, 326 .constructor = ng_l2tp_constructor, 327 .rcvmsg = ng_l2tp_rcvmsg, 328 .shutdown = ng_l2tp_shutdown, 329 .newhook = ng_l2tp_newhook, 330 .rcvdata = ng_l2tp_rcvdata, 331 .disconnect = ng_l2tp_disconnect, 332 .cmdlist = ng_l2tp_cmdlist, 333 }; 334 NETGRAPH_INIT(l2tp, &ng_l2tp_typestruct); 335 336 /* Sequence number state sanity checking */ 337 #ifdef INVARIANTS 338 #define L2TP_SEQ_CHECK(seq) ng_l2tp_seq_check(seq) 339 #else 340 #define L2TP_SEQ_CHECK(x) do { } while (0) 341 #endif 342 343 /* memmove macro */ 344 #define memmove(d, s, l) bcopy(s, d, l) 345 346 /* Whether to use m_copypacket() or m_dup() */ 347 #define L2TP_COPY_MBUF m_copypacket 348 349 /************************************************************************ 350 NETGRAPH NODE STUFF 351 ************************************************************************/ 352 353 /* 354 * Node type constructor 355 */ 356 static int 357 ng_l2tp_constructor(node_p node) 358 { 359 priv_p priv; 360 361 /* Allocate private structure */ 362 MALLOC(priv, priv_p, sizeof(*priv), M_NETGRAPH_L2TP, M_NOWAIT | M_ZERO); 363 if (priv == NULL) 364 return (ENOMEM); 365 NG_NODE_SET_PRIVATE(node, priv); 366 priv->node = node; 367 368 /* Apply a semi-reasonable default configuration */ 369 priv->conf.peer_win = 1; 370 priv->conf.rexmit_max = L2TP_MAX_REXMIT; 371 priv->conf.rexmit_max_to = L2TP_MAX_REXMIT_TO; 372 373 /* Initialize sequence number state */ 374 ng_l2tp_seq_init(priv); 375 376 /* Done */ 377 return (0); 378 } 379 380 /* 381 * Give our OK for a hook to be added. 382 */ 383 static int 384 ng_l2tp_newhook(node_p node, hook_p hook, const char *name) 385 { 386 const priv_p priv = NG_NODE_PRIVATE(node); 387 388 /* Check hook name */ 389 if (strcmp(name, NG_L2TP_HOOK_CTRL) == 0) { 390 if (priv->ctrl != NULL) 391 return (EISCONN); 392 priv->ctrl = hook; 393 } else if (strcmp(name, NG_L2TP_HOOK_LOWER) == 0) { 394 if (priv->lower != NULL) 395 return (EISCONN); 396 priv->lower = hook; 397 } else { 398 static const char hexdig[16] = "0123456789abcdef"; 399 u_int16_t session_id; 400 hookpriv_p hpriv; 401 const char *hex; 402 int i; 403 int j; 404 405 /* Parse hook name to get session ID */ 406 if (strncmp(name, NG_L2TP_HOOK_SESSION_P, 407 sizeof(NG_L2TP_HOOK_SESSION_P) - 1) != 0) 408 return (EINVAL); 409 hex = name + sizeof(NG_L2TP_HOOK_SESSION_P) - 1; 410 for (session_id = i = 0; i < 4; i++) { 411 for (j = 0; j < 16 && hex[i] != hexdig[j]; j++); 412 if (j == 16) 413 return (EINVAL); 414 session_id = (session_id << 4) | j; 415 } 416 if (hex[i] != '\0') 417 return (EINVAL); 418 419 /* Create hook private structure */ 420 MALLOC(hpriv, hookpriv_p, 421 sizeof(*hpriv), M_NETGRAPH_L2TP, M_NOWAIT | M_ZERO); 422 if (hpriv == NULL) 423 return (ENOMEM); 424 hpriv->conf.session_id = htons(session_id); 425 hpriv->conf.control_dseq = L2TP_CONTROL_DSEQ; 426 hpriv->conf.enable_dseq = L2TP_ENABLE_DSEQ; 427 NG_HOOK_SET_PRIVATE(hook, hpriv); 428 } 429 430 /* Done */ 431 return (0); 432 } 433 434 /* 435 * Receive a control message. 436 */ 437 static int 438 ng_l2tp_rcvmsg(node_p node, item_p item, hook_p lasthook) 439 { 440 const priv_p priv = NG_NODE_PRIVATE(node); 441 struct ng_mesg *resp = NULL; 442 struct ng_mesg *msg; 443 int error = 0; 444 445 NGI_GET_MSG(item, msg); 446 switch (msg->header.typecookie) { 447 case NGM_L2TP_COOKIE: 448 switch (msg->header.cmd) { 449 case NGM_L2TP_SET_CONFIG: 450 { 451 struct ng_l2tp_config *const conf = 452 (struct ng_l2tp_config *)msg->data; 453 454 /* Check for invalid or illegal config */ 455 if (msg->header.arglen != sizeof(*conf)) { 456 error = EINVAL; 457 break; 458 } 459 conf->enabled = !!conf->enabled; 460 conf->match_id = !!conf->match_id; 461 conf->tunnel_id = htons(conf->tunnel_id); 462 conf->peer_id = htons(conf->peer_id); 463 if (priv->conf.enabled 464 && ((priv->conf.tunnel_id != 0 465 && conf->tunnel_id != priv->conf.tunnel_id) 466 || ((priv->conf.peer_id != 0 467 && conf->peer_id != priv->conf.peer_id)))) { 468 error = EBUSY; 469 break; 470 } 471 472 /* Save calling node as failure target */ 473 priv->ftarget = NGI_RETADDR(item); 474 475 /* Adjust sequence number state */ 476 if ((error = ng_l2tp_seq_adjust(priv, conf)) != 0) 477 break; 478 479 /* Update node's config */ 480 priv->conf = *conf; 481 break; 482 } 483 case NGM_L2TP_GET_CONFIG: 484 { 485 struct ng_l2tp_config *conf; 486 487 NG_MKRESPONSE(resp, msg, sizeof(*conf), M_NOWAIT); 488 if (resp == NULL) { 489 error = ENOMEM; 490 break; 491 } 492 conf = (struct ng_l2tp_config *)resp->data; 493 *conf = priv->conf; 494 495 /* Put ID's in host order */ 496 conf->tunnel_id = ntohs(conf->tunnel_id); 497 conf->peer_id = ntohs(conf->peer_id); 498 break; 499 } 500 case NGM_L2TP_SET_SESS_CONFIG: 501 { 502 struct ng_l2tp_sess_config *const conf = 503 (struct ng_l2tp_sess_config *)msg->data; 504 hookpriv_p hpriv; 505 hook_p hook; 506 507 /* Check for invalid or illegal config. */ 508 if (msg->header.arglen != sizeof(*conf)) { 509 error = EINVAL; 510 break; 511 } 512 513 /* Put ID's in network order */ 514 conf->session_id = htons(conf->session_id); 515 conf->peer_id = htons(conf->peer_id); 516 517 /* Find matching hook */ 518 NG_NODE_FOREACH_HOOK(node, ng_l2tp_find_session, 519 (void *)(uintptr_t)conf->session_id, hook); 520 if (hook == NULL) { 521 error = ENOENT; 522 break; 523 } 524 hpriv = NG_HOOK_PRIVATE(hook); 525 526 /* Update hook's config */ 527 hpriv->conf = *conf; 528 break; 529 } 530 case NGM_L2TP_GET_SESS_CONFIG: 531 { 532 struct ng_l2tp_sess_config *conf; 533 u_int16_t session_id; 534 hookpriv_p hpriv; 535 hook_p hook; 536 537 /* Get session ID */ 538 if (msg->header.arglen != sizeof(session_id)) { 539 error = EINVAL; 540 break; 541 } 542 memcpy(&session_id, msg->data, 2); 543 session_id = htons(session_id); 544 545 /* Find matching hook */ 546 NG_NODE_FOREACH_HOOK(node, ng_l2tp_find_session, 547 (void *)(uintptr_t)session_id, hook); 548 if (hook == NULL) { 549 error = ENOENT; 550 break; 551 } 552 hpriv = NG_HOOK_PRIVATE(hook); 553 554 /* Send response */ 555 NG_MKRESPONSE(resp, msg, sizeof(hpriv->conf), M_NOWAIT); 556 if (resp == NULL) { 557 error = ENOMEM; 558 break; 559 } 560 conf = (struct ng_l2tp_sess_config *)resp->data; 561 *conf = hpriv->conf; 562 563 /* Put ID's in host order */ 564 conf->session_id = ntohs(conf->session_id); 565 conf->peer_id = ntohs(conf->peer_id); 566 break; 567 } 568 case NGM_L2TP_GET_STATS: 569 case NGM_L2TP_CLR_STATS: 570 case NGM_L2TP_GETCLR_STATS: 571 { 572 if (msg->header.cmd != NGM_L2TP_CLR_STATS) { 573 NG_MKRESPONSE(resp, msg, 574 sizeof(priv->stats), M_NOWAIT); 575 if (resp == NULL) { 576 error = ENOMEM; 577 break; 578 } 579 memcpy(resp->data, 580 &priv->stats, sizeof(priv->stats)); 581 } 582 if (msg->header.cmd != NGM_L2TP_GET_STATS) 583 memset(&priv->stats, 0, sizeof(priv->stats)); 584 break; 585 } 586 case NGM_L2TP_GET_SESSION_STATS: 587 case NGM_L2TP_CLR_SESSION_STATS: 588 case NGM_L2TP_GETCLR_SESSION_STATS: 589 { 590 uint16_t session_id; 591 hookpriv_p hpriv; 592 hook_p hook; 593 594 /* Get session ID. */ 595 if (msg->header.arglen != sizeof(session_id)) { 596 error = EINVAL; 597 break; 598 } 599 bcopy(msg->data, &session_id, sizeof(uint16_t)); 600 session_id = htons(session_id); 601 602 /* Find matching hook. */ 603 NG_NODE_FOREACH_HOOK(node, ng_l2tp_find_session, 604 (void *)(uintptr_t)session_id, hook); 605 if (hook == NULL) { 606 error = ENOENT; 607 break; 608 } 609 hpriv = NG_HOOK_PRIVATE(hook); 610 611 if (msg->header.cmd != NGM_L2TP_CLR_SESSION_STATS) { 612 NG_MKRESPONSE(resp, msg, 613 sizeof(hpriv->stats), M_NOWAIT); 614 if (resp == NULL) { 615 error = ENOMEM; 616 break; 617 } 618 bcopy(&hpriv->stats, resp->data, 619 sizeof(hpriv->stats)); 620 } 621 if (msg->header.cmd != NGM_L2TP_GET_SESSION_STATS) 622 bzero(&hpriv->stats, sizeof(hpriv->stats)); 623 break; 624 } 625 case NGM_L2TP_SET_SEQ: 626 { 627 struct ng_l2tp_seq_config *const conf = 628 (struct ng_l2tp_seq_config *)msg->data; 629 630 /* Check for invalid or illegal seq config. */ 631 if (msg->header.arglen != sizeof(*conf)) { 632 error = EINVAL; 633 break; 634 } 635 conf->ns = htons(conf->ns); 636 conf->nr = htons(conf->nr); 637 conf->rack = htons(conf->rack); 638 conf->xack = htons(conf->xack); 639 640 /* Set sequence numbers. */ 641 error = ng_l2tp_seq_set(priv, conf); 642 break; 643 } 644 default: 645 error = EINVAL; 646 break; 647 } 648 break; 649 default: 650 error = EINVAL; 651 break; 652 } 653 654 /* Done */ 655 NG_RESPOND_MSG(error, node, item, resp); 656 NG_FREE_MSG(msg); 657 return (error); 658 } 659 660 /* 661 * Receive incoming data on a hook. 662 */ 663 static int 664 ng_l2tp_rcvdata(hook_p hook, item_p item) 665 { 666 const node_p node = NG_HOOK_NODE(hook); 667 const priv_p priv = NG_NODE_PRIVATE(node); 668 int error; 669 670 /* Sanity check */ 671 L2TP_SEQ_CHECK(&priv->seq); 672 673 /* If not configured, reject */ 674 if (!priv->conf.enabled) { 675 NG_FREE_ITEM(item); 676 return (ENXIO); 677 } 678 679 /* Handle incoming frame from below */ 680 if (hook == priv->lower) { 681 error = ng_l2tp_recv_lower(node, item); 682 goto done; 683 } 684 685 /* Handle outgoing control frame */ 686 if (hook == priv->ctrl) { 687 error = ng_l2tp_recv_ctrl(node, item); 688 goto done; 689 } 690 691 /* Handle outgoing data frame */ 692 error = ng_l2tp_recv_data(node, item, NG_HOOK_PRIVATE(hook)); 693 694 done: 695 /* Done */ 696 L2TP_SEQ_CHECK(&priv->seq); 697 return (error); 698 } 699 700 /* 701 * Destroy node 702 */ 703 static int 704 ng_l2tp_shutdown(node_p node) 705 { 706 const priv_p priv = NG_NODE_PRIVATE(node); 707 struct l2tp_seq *const seq = &priv->seq; 708 709 /* Sanity check */ 710 L2TP_SEQ_CHECK(seq); 711 712 /* Reset sequence number state */ 713 ng_l2tp_seq_reset(priv); 714 715 /* Free private data if neither timer is running */ 716 if (!seq->rack_timer_running && !seq->xack_timer_running) { 717 FREE(priv, M_NETGRAPH_L2TP); 718 NG_NODE_SET_PRIVATE(node, NULL); 719 } 720 721 /* Unref node */ 722 NG_NODE_UNREF(node); 723 return (0); 724 } 725 726 /* 727 * Hook disconnection 728 */ 729 static int 730 ng_l2tp_disconnect(hook_p hook) 731 { 732 const node_p node = NG_HOOK_NODE(hook); 733 const priv_p priv = NG_NODE_PRIVATE(node); 734 735 /* Zero out hook pointer */ 736 if (hook == priv->ctrl) 737 priv->ctrl = NULL; 738 else if (hook == priv->lower) 739 priv->lower = NULL; 740 else { 741 FREE(NG_HOOK_PRIVATE(hook), M_NETGRAPH_L2TP); 742 NG_HOOK_SET_PRIVATE(hook, NULL); 743 } 744 745 /* Go away if no longer connected to anything */ 746 if (NG_NODE_NUMHOOKS(node) == 0 && NG_NODE_IS_VALID(node)) 747 ng_rmnode_self(node); 748 return (0); 749 } 750 751 /************************************************************************* 752 INTERNAL FUNCTIONS 753 *************************************************************************/ 754 755 /* 756 * Find the hook with a given session ID. 757 */ 758 static int 759 ng_l2tp_find_session(hook_p hook, void *arg) 760 { 761 const hookpriv_p hpriv = NG_HOOK_PRIVATE(hook); 762 const u_int16_t sid = (u_int16_t)(uintptr_t)arg; 763 764 if (hpriv == NULL || hpriv->conf.session_id != sid) 765 return (-1); 766 return (0); 767 } 768 769 /* 770 * Reset a hook's session state. 771 */ 772 static int 773 ng_l2tp_reset_session(hook_p hook, void *arg) 774 { 775 const hookpriv_p hpriv = NG_HOOK_PRIVATE(hook); 776 777 if (hpriv != NULL) { 778 hpriv->conf.control_dseq = 0; 779 hpriv->conf.enable_dseq = 0; 780 bzero(&hpriv->conf, sizeof(struct ng_l2tp_session_stats)); 781 hpriv->nr = 0; 782 hpriv->ns = 0; 783 } 784 return (-1); 785 } 786 787 /* 788 * Handle an incoming frame from below. 789 */ 790 static int 791 ng_l2tp_recv_lower(node_p node, item_p item) 792 { 793 static const u_int16_t req_bits[2][2] = { 794 { L2TP_DATA_0BITS, L2TP_DATA_1BITS }, 795 { L2TP_CTRL_0BITS, L2TP_CTRL_1BITS }, 796 }; 797 const priv_p priv = NG_NODE_PRIVATE(node); 798 hookpriv_p hpriv = NULL; 799 hook_p hook = NULL; 800 u_int16_t ids[2]; 801 struct mbuf *m; 802 u_int16_t hdr; 803 u_int16_t ns; 804 u_int16_t nr; 805 int is_ctrl; 806 int error; 807 int len, plen; 808 809 /* Grab mbuf */ 810 NGI_GET_M(item, m); 811 812 /* Remember full packet length; needed for per session accounting. */ 813 plen = m->m_pkthdr.len; 814 815 /* Update stats */ 816 priv->stats.recvPackets++; 817 priv->stats.recvOctets += plen; 818 819 /* Get initial header */ 820 if (m->m_pkthdr.len < 6) { 821 priv->stats.recvRunts++; 822 NG_FREE_ITEM(item); 823 NG_FREE_M(m); 824 return (EINVAL); 825 } 826 if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) { 827 priv->stats.memoryFailures++; 828 NG_FREE_ITEM(item); 829 return (EINVAL); 830 } 831 hdr = ntohs(*mtod(m, u_int16_t *)); 832 m_adj(m, 2); 833 834 /* Check required header bits and minimum length */ 835 is_ctrl = (hdr & L2TP_HDR_CTRL) != 0; 836 if ((hdr & req_bits[is_ctrl][0]) != 0 837 || (~hdr & req_bits[is_ctrl][1]) != 0) { 838 priv->stats.recvInvalid++; 839 NG_FREE_ITEM(item); 840 NG_FREE_M(m); 841 return (EINVAL); 842 } 843 if (m->m_pkthdr.len < 4 /* tunnel, session id */ 844 + (2 * ((hdr & L2TP_HDR_LEN) != 0)) /* length field */ 845 + (4 * ((hdr & L2TP_HDR_SEQ) != 0)) /* seq # fields */ 846 + (2 * ((hdr & L2TP_HDR_OFF) != 0))) { /* offset field */ 847 priv->stats.recvRunts++; 848 NG_FREE_ITEM(item); 849 NG_FREE_M(m); 850 return (EINVAL); 851 } 852 853 /* Get and validate length field if present */ 854 if ((hdr & L2TP_HDR_LEN) != 0) { 855 if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) { 856 priv->stats.memoryFailures++; 857 NG_FREE_ITEM(item); 858 return (EINVAL); 859 } 860 len = (u_int16_t)ntohs(*mtod(m, u_int16_t *)) - 4; 861 m_adj(m, 2); 862 if (len < 0 || len > m->m_pkthdr.len) { 863 priv->stats.recvInvalid++; 864 NG_FREE_ITEM(item); 865 NG_FREE_M(m); 866 return (EINVAL); 867 } 868 if (len < m->m_pkthdr.len) /* trim extra bytes */ 869 m_adj(m, -(m->m_pkthdr.len - len)); 870 } 871 872 /* Get tunnel ID and session ID */ 873 if (m->m_len < 4 && (m = m_pullup(m, 4)) == NULL) { 874 priv->stats.memoryFailures++; 875 NG_FREE_ITEM(item); 876 return (EINVAL); 877 } 878 memcpy(ids, mtod(m, u_int16_t *), 4); 879 m_adj(m, 4); 880 881 /* Check tunnel ID */ 882 if (ids[0] != priv->conf.tunnel_id 883 && (priv->conf.match_id || ids[0] != 0)) { 884 priv->stats.recvWrongTunnel++; 885 NG_FREE_ITEM(item); 886 NG_FREE_M(m); 887 return (EADDRNOTAVAIL); 888 } 889 890 /* Check session ID (for data packets only) */ 891 if ((hdr & L2TP_HDR_CTRL) == 0) { 892 NG_NODE_FOREACH_HOOK(node, ng_l2tp_find_session, 893 (void *)(uintptr_t)ids[1], hook); 894 if (hook == NULL) { 895 priv->stats.recvUnknownSID++; 896 NG_FREE_ITEM(item); 897 NG_FREE_M(m); 898 return (ENOTCONN); 899 } 900 hpriv = NG_HOOK_PRIVATE(hook); 901 } 902 903 /* Get Ns, Nr fields if present */ 904 if ((hdr & L2TP_HDR_SEQ) != 0) { 905 if (m->m_len < 4 && (m = m_pullup(m, 4)) == NULL) { 906 priv->stats.memoryFailures++; 907 NG_FREE_ITEM(item); 908 return (EINVAL); 909 } 910 memcpy(&ns, &mtod(m, u_int16_t *)[0], 2); 911 ns = ntohs(ns); 912 memcpy(&nr, &mtod(m, u_int16_t *)[1], 2); 913 nr = ntohs(nr); 914 m_adj(m, 4); 915 } 916 917 /* Strip offset padding if present */ 918 if ((hdr & L2TP_HDR_OFF) != 0) { 919 u_int16_t offset; 920 921 /* Get length of offset padding */ 922 if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) { 923 priv->stats.memoryFailures++; 924 NG_FREE_ITEM(item); 925 return (EINVAL); 926 } 927 memcpy(&offset, mtod(m, u_int16_t *), 2); 928 offset = ntohs(offset); 929 930 /* Trim offset padding */ 931 if ((2+offset) > m->m_pkthdr.len) { 932 priv->stats.recvInvalid++; 933 NG_FREE_ITEM(item); 934 NG_FREE_M(m); 935 return (EINVAL); 936 } 937 m_adj(m, 2+offset); 938 } 939 940 /* Handle control packets */ 941 if ((hdr & L2TP_HDR_CTRL) != 0) { 942 943 /* Handle receive ack sequence number Nr */ 944 ng_l2tp_seq_recv_nr(priv, nr); 945 946 /* Discard ZLB packets */ 947 if (m->m_pkthdr.len == 0) { 948 priv->stats.recvZLBs++; 949 NG_FREE_ITEM(item); 950 NG_FREE_M(m); 951 return (0); 952 } 953 954 /* 955 * Prepend session ID to packet here: we don't want to accept 956 * the send sequence number Ns if we have to drop the packet 957 * later because of a memory error, because then the upper 958 * layer would never get the packet. 959 */ 960 M_PREPEND(m, 2, M_DONTWAIT); 961 if (m == NULL) { 962 priv->stats.memoryFailures++; 963 NG_FREE_ITEM(item); 964 return (ENOBUFS); 965 } 966 memcpy(mtod(m, u_int16_t *), &ids[1], 2); 967 968 /* Now handle send sequence number */ 969 if (ng_l2tp_seq_recv_ns(priv, ns) == -1) { 970 NG_FREE_ITEM(item); 971 NG_FREE_M(m); 972 return (0); 973 } 974 975 /* Deliver packet to upper layers */ 976 NG_FWD_NEW_DATA(error, item, priv->ctrl, m); 977 return (error); 978 } 979 980 /* Per session packet, account it. */ 981 hpriv->stats.recvPackets++; 982 hpriv->stats.recvOctets += plen; 983 984 /* Follow peer's lead in data sequencing, if configured to do so */ 985 if (!hpriv->conf.control_dseq) 986 hpriv->conf.enable_dseq = ((hdr & L2TP_HDR_SEQ) != 0); 987 988 /* Handle data sequence numbers if present and enabled */ 989 if ((hdr & L2TP_HDR_SEQ) != 0) { 990 if (hpriv->conf.enable_dseq 991 && L2TP_SEQ_DIFF(ns, hpriv->nr) < 0) { 992 NG_FREE_ITEM(item); /* duplicate or out of order */ 993 NG_FREE_M(m); 994 priv->stats.recvDataDrops++; 995 return (0); 996 } 997 hpriv->nr = ns + 1; 998 } 999 1000 /* Drop empty data packets */ 1001 if (m->m_pkthdr.len == 0) { 1002 NG_FREE_ITEM(item); 1003 NG_FREE_M(m); 1004 return (0); 1005 } 1006 1007 /* Deliver data */ 1008 NG_FWD_NEW_DATA(error, item, hook, m); 1009 return (error); 1010 } 1011 1012 /* 1013 * Handle an outgoing control frame. 1014 */ 1015 static int 1016 ng_l2tp_recv_ctrl(node_p node, item_p item) 1017 { 1018 const priv_p priv = NG_NODE_PRIVATE(node); 1019 struct l2tp_seq *const seq = &priv->seq; 1020 struct mbuf *m; 1021 int i; 1022 1023 /* Grab mbuf and discard other stuff XXX */ 1024 NGI_GET_M(item, m); 1025 NG_FREE_ITEM(item); 1026 1027 /* Packet should have session ID prepended */ 1028 if (m->m_pkthdr.len < 2) { 1029 priv->stats.xmitInvalid++; 1030 m_freem(m); 1031 return (EINVAL); 1032 } 1033 1034 /* Check max length */ 1035 if (m->m_pkthdr.len >= 0x10000 - 14) { 1036 priv->stats.xmitTooBig++; 1037 m_freem(m); 1038 return (EOVERFLOW); 1039 } 1040 1041 /* Find next empty slot in transmit queue */ 1042 for (i = 0; i < L2TP_MAX_XWIN && seq->xwin[i] != NULL; i++); 1043 if (i == L2TP_MAX_XWIN) { 1044 priv->stats.xmitDrops++; 1045 m_freem(m); 1046 return (ENOBUFS); 1047 } 1048 seq->xwin[i] = m; 1049 1050 /* Sanity check receive ack timer state */ 1051 KASSERT((i == 0) ^ seq->rack_timer_running, 1052 ("%s: xwin %d full but rack timer %srunning", 1053 __FUNCTION__, i, seq->rack_timer_running ? "" : "not ")); 1054 1055 /* If peer's receive window is already full, nothing else to do */ 1056 if (i >= seq->cwnd) 1057 return (0); 1058 1059 /* Start retransmit timer if not already running */ 1060 if (!seq->rack_timer_running) { 1061 callout_reset(&seq->rack_timer, 1062 hz, ng_l2tp_seq_rack_timeout, node); 1063 seq->rack_timer_running = 1; 1064 NG_NODE_REF(node); 1065 } 1066 1067 /* Copy packet */ 1068 if ((m = L2TP_COPY_MBUF(seq->xwin[i], M_DONTWAIT)) == NULL) { 1069 priv->stats.memoryFailures++; 1070 return (ENOBUFS); 1071 } 1072 1073 /* Send packet and increment xmit sequence number */ 1074 return (ng_l2tp_xmit_ctrl(priv, m, seq->ns++)); 1075 } 1076 1077 /* 1078 * Handle an outgoing data frame. 1079 */ 1080 static int 1081 ng_l2tp_recv_data(node_p node, item_p item, hookpriv_p hpriv) 1082 { 1083 const priv_p priv = NG_NODE_PRIVATE(node); 1084 struct mbuf *m; 1085 u_int16_t hdr; 1086 int error; 1087 int i = 1; 1088 1089 /* Get mbuf */ 1090 NGI_GET_M(item, m); 1091 1092 /* Check max length */ 1093 if (m->m_pkthdr.len >= 0x10000 - 12) { 1094 priv->stats.xmitDataTooBig++; 1095 NG_FREE_ITEM(item); 1096 NG_FREE_M(m); 1097 return (EOVERFLOW); 1098 } 1099 1100 /* Prepend L2TP header */ 1101 M_PREPEND(m, 6 1102 + (2 * (hpriv->conf.include_length != 0)) 1103 + (4 * (hpriv->conf.enable_dseq != 0)), 1104 M_DONTWAIT); 1105 if (m == NULL) { 1106 priv->stats.memoryFailures++; 1107 NG_FREE_ITEM(item); 1108 return (ENOBUFS); 1109 } 1110 hdr = L2TP_DATA_HDR; 1111 if (hpriv->conf.include_length) { 1112 hdr |= L2TP_HDR_LEN; 1113 mtod(m, u_int16_t *)[i++] = htons(m->m_pkthdr.len); 1114 } 1115 mtod(m, u_int16_t *)[i++] = priv->conf.peer_id; 1116 mtod(m, u_int16_t *)[i++] = hpriv->conf.peer_id; 1117 if (hpriv->conf.enable_dseq) { 1118 hdr |= L2TP_HDR_SEQ; 1119 mtod(m, u_int16_t *)[i++] = htons(hpriv->ns); 1120 mtod(m, u_int16_t *)[i++] = htons(hpriv->nr); 1121 hpriv->ns++; 1122 } 1123 mtod(m, u_int16_t *)[0] = htons(hdr); 1124 1125 /* Update per session stats. */ 1126 hpriv->stats.xmitPackets++; 1127 hpriv->stats.xmitOctets += m->m_pkthdr.len; 1128 1129 /* Send packet */ 1130 NG_FWD_NEW_DATA(error, item, priv->lower, m); 1131 return (error); 1132 } 1133 1134 /* 1135 * Send a message to our controlling node that we've failed. 1136 */ 1137 static void 1138 ng_l2tp_seq_failure(priv_p priv) 1139 { 1140 struct ng_mesg *msg; 1141 int error; 1142 1143 NG_MKMESSAGE(msg, NGM_L2TP_COOKIE, NGM_L2TP_ACK_FAILURE, 0, M_NOWAIT); 1144 if (msg == NULL) 1145 return; 1146 NG_SEND_MSG_ID(error, priv->node, msg, priv->ftarget, 0); 1147 } 1148 1149 /************************************************************************ 1150 SEQUENCE NUMBER HANDLING 1151 ************************************************************************/ 1152 1153 /* 1154 * Initialize sequence number state. 1155 */ 1156 static void 1157 ng_l2tp_seq_init(priv_p priv) 1158 { 1159 struct l2tp_seq *const seq = &priv->seq; 1160 1161 KASSERT(priv->conf.peer_win >= 1, 1162 ("%s: peer_win is zero", __FUNCTION__)); 1163 memset(seq, 0, sizeof(*seq)); 1164 seq->cwnd = 1; 1165 seq->wmax = priv->conf.peer_win; 1166 if (seq->wmax > L2TP_MAX_XWIN) 1167 seq->wmax = L2TP_MAX_XWIN; 1168 seq->ssth = seq->wmax; 1169 seq->max_rexmits = priv->conf.rexmit_max; 1170 seq->max_rexmit_to = priv->conf.rexmit_max_to; 1171 callout_init(&seq->rack_timer, 0); 1172 callout_init(&seq->xack_timer, 0); 1173 L2TP_SEQ_CHECK(seq); 1174 } 1175 1176 /* 1177 * Set sequence number state as given from user. 1178 */ 1179 static int 1180 ng_l2tp_seq_set(priv_p priv, const struct ng_l2tp_seq_config *conf) 1181 { 1182 struct l2tp_seq *const seq = &priv->seq; 1183 1184 /* If node is enabled, deny update to sequence numbers. */ 1185 if (priv->conf.enabled) 1186 return (EBUSY); 1187 1188 /* We only can handle the simple cases. */ 1189 if (conf->xack != conf->nr || conf->ns != conf->rack) 1190 return (EINVAL); 1191 1192 /* Set ns,nr,rack,xack parameters. */ 1193 seq->ns = conf->ns; 1194 seq->nr = conf->nr; 1195 seq->rack = conf->rack; 1196 seq->xack = conf->xack; 1197 1198 return (0); 1199 } 1200 1201 /* 1202 * Adjust sequence number state accordingly after reconfiguration. 1203 */ 1204 static int 1205 ng_l2tp_seq_adjust(priv_p priv, const struct ng_l2tp_config *conf) 1206 { 1207 struct l2tp_seq *const seq = &priv->seq; 1208 u_int16_t new_wmax; 1209 1210 /* If disabling node, reset state sequence number */ 1211 if (!conf->enabled) { 1212 ng_l2tp_seq_reset(priv); 1213 return (0); 1214 } 1215 1216 /* Adjust peer's max recv window; it can only increase */ 1217 new_wmax = conf->peer_win; 1218 if (new_wmax > L2TP_MAX_XWIN) 1219 new_wmax = L2TP_MAX_XWIN; 1220 if (new_wmax == 0) 1221 return (EINVAL); 1222 if (new_wmax < seq->wmax) 1223 return (EBUSY); 1224 seq->wmax = new_wmax; 1225 1226 /* Update retransmit parameters */ 1227 seq->max_rexmits = conf->rexmit_max; 1228 seq->max_rexmit_to = conf->rexmit_max_to; 1229 1230 /* Done */ 1231 return (0); 1232 } 1233 1234 /* 1235 * Reset sequence number state. 1236 */ 1237 static void 1238 ng_l2tp_seq_reset(priv_p priv) 1239 { 1240 struct l2tp_seq *const seq = &priv->seq; 1241 hook_p hook; 1242 int i; 1243 1244 /* Sanity check */ 1245 L2TP_SEQ_CHECK(seq); 1246 1247 /* Stop timers */ 1248 if (seq->rack_timer_running && callout_stop(&seq->rack_timer) == 1) { 1249 seq->rack_timer_running = 0; 1250 NG_NODE_UNREF(priv->node); 1251 } 1252 if (seq->xack_timer_running && callout_stop(&seq->xack_timer) == 1) { 1253 seq->xack_timer_running = 0; 1254 NG_NODE_UNREF(priv->node); 1255 } 1256 1257 /* Free retransmit queue */ 1258 for (i = 0; i < L2TP_MAX_XWIN; i++) { 1259 if (seq->xwin[i] == NULL) 1260 break; 1261 m_freem(seq->xwin[i]); 1262 } 1263 1264 /* Reset session hooks' sequence number states */ 1265 NG_NODE_FOREACH_HOOK(priv->node, ng_l2tp_reset_session, NULL, hook); 1266 1267 /* Reset node's sequence number state */ 1268 memset(seq, 0, sizeof(*seq)); 1269 seq->cwnd = 1; 1270 seq->wmax = L2TP_MAX_XWIN; 1271 seq->ssth = seq->wmax; 1272 1273 /* Done */ 1274 L2TP_SEQ_CHECK(seq); 1275 } 1276 1277 /* 1278 * Handle receipt of an acknowledgement value (Nr) from peer. 1279 */ 1280 static void 1281 ng_l2tp_seq_recv_nr(priv_p priv, u_int16_t nr) 1282 { 1283 struct l2tp_seq *const seq = &priv->seq; 1284 struct mbuf *m; 1285 int nack; 1286 int i; 1287 1288 /* Verify peer's ACK is in range */ 1289 if ((nack = L2TP_SEQ_DIFF(nr, seq->rack)) <= 0) 1290 return; /* duplicate ack */ 1291 if (L2TP_SEQ_DIFF(nr, seq->ns) > 0) { 1292 priv->stats.recvBadAcks++; /* ack for packet not sent */ 1293 return; 1294 } 1295 KASSERT(nack <= L2TP_MAX_XWIN, 1296 ("%s: nack=%d > %d", __FUNCTION__, nack, L2TP_MAX_XWIN)); 1297 1298 /* Update receive ack stats */ 1299 seq->rack = nr; 1300 seq->rexmits = 0; 1301 1302 /* Free acknowledged packets and shift up packets in the xmit queue */ 1303 for (i = 0; i < nack; i++) 1304 m_freem(seq->xwin[i]); 1305 memmove(seq->xwin, seq->xwin + nack, 1306 (L2TP_MAX_XWIN - nack) * sizeof(*seq->xwin)); 1307 memset(seq->xwin + (L2TP_MAX_XWIN - nack), 0, 1308 nack * sizeof(*seq->xwin)); 1309 1310 /* 1311 * Do slow-start/congestion avoidance windowing algorithm described 1312 * in RFC 2661, Appendix A. Here we handle a multiple ACK as if each 1313 * ACK had arrived separately. 1314 */ 1315 if (seq->cwnd < seq->wmax) { 1316 1317 /* Handle slow start phase */ 1318 if (seq->cwnd < seq->ssth) { 1319 seq->cwnd += nack; 1320 nack = 0; 1321 if (seq->cwnd > seq->ssth) { /* into cg.av. phase */ 1322 nack = seq->cwnd - seq->ssth; 1323 seq->cwnd = seq->ssth; 1324 } 1325 } 1326 1327 /* Handle congestion avoidance phase */ 1328 if (seq->cwnd >= seq->ssth) { 1329 seq->acks += nack; 1330 while (seq->acks >= seq->cwnd) { 1331 seq->acks -= seq->cwnd; 1332 if (seq->cwnd < seq->wmax) 1333 seq->cwnd++; 1334 } 1335 } 1336 } 1337 1338 /* Stop xmit timer */ 1339 if (seq->rack_timer_running && callout_stop(&seq->rack_timer) == 1) { 1340 seq->rack_timer_running = 0; 1341 NG_NODE_UNREF(priv->node); 1342 } 1343 1344 /* If transmit queue is empty, we're done for now */ 1345 if (seq->xwin[0] == NULL) 1346 return; 1347 1348 /* Start restransmit timer again */ 1349 callout_reset(&seq->rack_timer, 1350 hz, ng_l2tp_seq_rack_timeout, priv->node); 1351 seq->rack_timer_running = 1; 1352 NG_NODE_REF(priv->node); 1353 1354 /* 1355 * Send more packets, trying to keep peer's receive window full. 1356 * If there is a memory error, pretend packet was sent, as it 1357 * will get retransmitted later anyway. 1358 */ 1359 while ((i = L2TP_SEQ_DIFF(seq->ns, seq->rack)) < seq->cwnd 1360 && seq->xwin[i] != NULL) { 1361 if ((m = L2TP_COPY_MBUF(seq->xwin[i], M_DONTWAIT)) == NULL) 1362 priv->stats.memoryFailures++; 1363 else 1364 ng_l2tp_xmit_ctrl(priv, m, seq->ns); 1365 seq->ns++; 1366 } 1367 } 1368 1369 /* 1370 * Handle receipt of a sequence number value (Ns) from peer. 1371 * We make no attempt to re-order out of order packets. 1372 * 1373 * This function should only be called for non-ZLB packets. 1374 * 1375 * Returns: 1376 * 0 Accept packet 1377 * -1 Drop packet 1378 */ 1379 static int 1380 ng_l2tp_seq_recv_ns(priv_p priv, u_int16_t ns) 1381 { 1382 struct l2tp_seq *const seq = &priv->seq; 1383 1384 /* If not what we expect, drop packet and send an immediate ZLB ack */ 1385 if (ns != seq->nr) { 1386 if (L2TP_SEQ_DIFF(ns, seq->nr) < 0) 1387 priv->stats.recvDuplicates++; 1388 else 1389 priv->stats.recvOutOfOrder++; 1390 ng_l2tp_xmit_ctrl(priv, NULL, seq->ns); 1391 return (-1); 1392 } 1393 1394 /* Update recv sequence number */ 1395 seq->nr++; 1396 1397 /* Start receive ack timer, if not already running */ 1398 if (!seq->xack_timer_running) { 1399 callout_reset(&seq->xack_timer, 1400 L2TP_DELAYED_ACK, ng_l2tp_seq_xack_timeout, priv->node); 1401 seq->xack_timer_running = 1; 1402 NG_NODE_REF(priv->node); 1403 } 1404 1405 /* Accept packet */ 1406 return (0); 1407 } 1408 1409 /* 1410 * Handle an ack timeout. We have an outstanding ack that we 1411 * were hoping to piggy-back, but haven't, so send a ZLB. 1412 */ 1413 static void 1414 ng_l2tp_seq_xack_timeout(void *arg) 1415 { 1416 const node_p node = arg; 1417 const priv_p priv = NG_NODE_PRIVATE(node); 1418 struct l2tp_seq *const seq = &priv->seq; 1419 int s; 1420 1421 /* Check if node is going away */ 1422 s = splnet(); 1423 if (NG_NODE_NOT_VALID(node)) { 1424 seq->xack_timer_running = 0; 1425 if (!seq->rack_timer_running) { 1426 FREE(priv, M_NETGRAPH_L2TP); 1427 NG_NODE_SET_PRIVATE(node, NULL); 1428 } 1429 NG_NODE_UNREF(node); 1430 splx(s); 1431 return; 1432 } 1433 1434 /* Sanity check */ 1435 L2TP_SEQ_CHECK(seq); 1436 1437 /* If ack is still outstanding, send a ZLB */ 1438 if (seq->xack != seq->nr) 1439 ng_l2tp_xmit_ctrl(priv, NULL, seq->ns); 1440 1441 /* Done */ 1442 seq->xack_timer_running = 0; 1443 NG_NODE_UNREF(node); 1444 L2TP_SEQ_CHECK(seq); 1445 splx(s); 1446 } 1447 1448 /* 1449 * Handle a transmit timeout. The peer has failed to respond 1450 * with an ack for our packet, so retransmit it. 1451 */ 1452 static void 1453 ng_l2tp_seq_rack_timeout(void *arg) 1454 { 1455 const node_p node = arg; 1456 const priv_p priv = NG_NODE_PRIVATE(node); 1457 struct l2tp_seq *const seq = &priv->seq; 1458 struct mbuf *m; 1459 u_int delay; 1460 int s; 1461 1462 /* Check if node is going away */ 1463 s = splnet(); 1464 if (NG_NODE_NOT_VALID(node)) { 1465 seq->rack_timer_running = 0; 1466 if (!seq->xack_timer_running) { 1467 FREE(priv, M_NETGRAPH_L2TP); 1468 NG_NODE_SET_PRIVATE(node, NULL); 1469 } 1470 NG_NODE_UNREF(node); 1471 splx(s); 1472 return; 1473 } 1474 1475 /* Sanity check */ 1476 L2TP_SEQ_CHECK(seq); 1477 1478 /* Make sure peer's ack is still outstanding before doing anything */ 1479 if (seq->rack == seq->ns) { 1480 seq->rack_timer_running = 0; 1481 NG_NODE_UNREF(node); 1482 goto done; 1483 } 1484 priv->stats.xmitRetransmits++; 1485 1486 /* Have we reached the retransmit limit? If so, notify owner. */ 1487 if (seq->rexmits++ >= seq->max_rexmits) 1488 ng_l2tp_seq_failure(priv); 1489 1490 /* Restart timer, this time with an increased delay */ 1491 delay = (seq->rexmits > 12) ? (1 << 12) : (1 << seq->rexmits); 1492 if (delay > seq->max_rexmit_to) 1493 delay = seq->max_rexmit_to; 1494 callout_reset(&seq->rack_timer, 1495 hz * delay, ng_l2tp_seq_rack_timeout, node); 1496 1497 /* Do slow-start/congestion algorithm windowing algorithm */ 1498 seq->ssth = (seq->cwnd + 1) / 2; 1499 seq->cwnd = 1; 1500 seq->acks = 0; 1501 1502 /* Retransmit oldest unack'd packet */ 1503 if ((m = L2TP_COPY_MBUF(seq->xwin[0], M_DONTWAIT)) == NULL) 1504 priv->stats.memoryFailures++; 1505 else 1506 ng_l2tp_xmit_ctrl(priv, m, seq->rack); 1507 1508 done: 1509 /* Done */ 1510 L2TP_SEQ_CHECK(seq); 1511 splx(s); 1512 } 1513 1514 /* 1515 * Transmit a control stream packet, payload optional. 1516 * The transmit sequence number is not incremented. 1517 */ 1518 static int 1519 ng_l2tp_xmit_ctrl(priv_p priv, struct mbuf *m, u_int16_t ns) 1520 { 1521 struct l2tp_seq *const seq = &priv->seq; 1522 u_int16_t session_id = 0; 1523 int error; 1524 1525 /* If no mbuf passed, send an empty packet (ZLB) */ 1526 if (m == NULL) { 1527 1528 /* Create a new mbuf for ZLB packet */ 1529 MGETHDR(m, M_DONTWAIT, MT_DATA); 1530 if (m == NULL) { 1531 priv->stats.memoryFailures++; 1532 return (ENOBUFS); 1533 } 1534 m->m_len = m->m_pkthdr.len = 12; 1535 m->m_pkthdr.rcvif = NULL; 1536 priv->stats.xmitZLBs++; 1537 } else { 1538 1539 /* Strip off session ID */ 1540 if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) { 1541 priv->stats.memoryFailures++; 1542 return (ENOBUFS); 1543 } 1544 memcpy(&session_id, mtod(m, u_int16_t *), 2); 1545 m_adj(m, 2); 1546 1547 /* Make room for L2TP header */ 1548 M_PREPEND(m, 12, M_DONTWAIT); 1549 if (m == NULL) { 1550 priv->stats.memoryFailures++; 1551 return (ENOBUFS); 1552 } 1553 } 1554 1555 /* Fill in L2TP header */ 1556 mtod(m, u_int16_t *)[0] = htons(L2TP_CTRL_HDR); 1557 mtod(m, u_int16_t *)[1] = htons(m->m_pkthdr.len); 1558 mtod(m, u_int16_t *)[2] = priv->conf.peer_id; 1559 mtod(m, u_int16_t *)[3] = session_id; 1560 mtod(m, u_int16_t *)[4] = htons(ns); 1561 mtod(m, u_int16_t *)[5] = htons(seq->nr); 1562 1563 /* Update sequence number info and stats */ 1564 priv->stats.xmitPackets++; 1565 priv->stats.xmitOctets += m->m_pkthdr.len; 1566 1567 /* Stop ack timer: we're sending an ack with this packet */ 1568 if (seq->xack_timer_running && callout_stop(&seq->xack_timer) == 1) { 1569 seq->xack_timer_running = 0; 1570 NG_NODE_UNREF(priv->node); 1571 } 1572 seq->xack = seq->nr; 1573 1574 /* Send packet */ 1575 NG_SEND_DATA_ONLY(error, priv->lower, m); 1576 return (error); 1577 } 1578 1579 #ifdef INVARIANTS 1580 /* 1581 * Sanity check sequence number state. 1582 */ 1583 static void 1584 ng_l2tp_seq_check(struct l2tp_seq *seq) 1585 { 1586 const int self_unack = L2TP_SEQ_DIFF(seq->nr, seq->xack); 1587 const int peer_unack = L2TP_SEQ_DIFF(seq->ns, seq->rack); 1588 int i; 1589 1590 #define CHECK(p) KASSERT((p), ("%s: not: %s", __FUNCTION__, #p)) 1591 1592 CHECK(seq->wmax <= L2TP_MAX_XWIN); 1593 CHECK(seq->cwnd >= 1); 1594 CHECK(seq->cwnd <= seq->wmax); 1595 CHECK(seq->ssth >= 1); 1596 CHECK(seq->ssth <= seq->wmax); 1597 if (seq->cwnd < seq->ssth) 1598 CHECK(seq->acks == 0); 1599 else 1600 CHECK(seq->acks <= seq->cwnd); 1601 CHECK(self_unack >= 0); 1602 CHECK(peer_unack >= 0); 1603 CHECK(peer_unack <= seq->wmax); 1604 CHECK((self_unack == 0) ^ seq->xack_timer_running); 1605 CHECK((peer_unack == 0) ^ seq->rack_timer_running); 1606 CHECK(seq->rack_timer_running || !callout_pending(&seq->rack_timer)); 1607 CHECK(seq->xack_timer_running || !callout_pending(&seq->xack_timer)); 1608 for (i = 0; i < peer_unack; i++) 1609 CHECK(seq->xwin[i] != NULL); 1610 for ( ; i < seq->cwnd; i++) /* verify peer's recv window full */ 1611 CHECK(seq->xwin[i] == NULL); 1612 1613 #undef CHECK 1614 } 1615 #endif /* INVARIANTS */ 1616 1617 1618