Lines Matching +full:recv +full:- +full:not +full:- +full:empty
1 /*-
2 * Copyright (c) 2001-2002 Packet Design, LLC.
23 * OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
102 #define L2TP_SEQ_DIFF(x, y) ((int16_t)((x) - (y)))
105 #define SESSHASH(x) (((x) ^ ((x) >> 8)) & (SESSHASHSIZE - 1))
122 * - If cwnd < ssth, we're doing slow start, otherwise congestion avoidance
123 * - The number of unacknowledged xmit packets is (ns - rack) <= seq->wmax
124 * - The first (ns - rack) mbuf's in xwin[] array are copies of these
127 * - We try to keep the peer's receive window as full as possible.
128 * Therefore, (i < cwnd && xwin[i] != NULL) implies (ns - rack) > i.
129 * - rack_timer is running iff (ns - rack) > 0 (unack'd xmit'd pkts)
130 * - If xack != nr, there are unacknowledged recv packet(s) (delayed ack)
131 * - xack_timer is running iff xack != nr (unack'd rec'd pkts)
135 u_int16_t nr; /* next recv seq we expect */
139 u_int16_t wmax; /* peer's max recv window */
337 mtx_lock(&(seq)->mtx); \
342 mtx_unlock(&(seq)->mtx); \
345 #define SEQ_LOCK(seq) mtx_lock(&(seq)->mtx)
346 #define SEQ_UNLOCK(seq) mtx_unlock(&(seq)->mtx)
348 #define SEQ_LOCK_ASSERT(seq) mtx_assert(&(seq)->mtx, MA_OWNED)
371 priv->node = node; in ng_l2tp_constructor()
373 /* Apply a semi-reasonable default configuration */ in ng_l2tp_constructor()
374 priv->conf.peer_win = 1; in ng_l2tp_constructor()
375 priv->conf.rexmit_max = L2TP_MAX_REXMIT; in ng_l2tp_constructor()
376 priv->conf.rexmit_max_to = L2TP_MAX_REXMIT_TO; in ng_l2tp_constructor()
382 LIST_INIT(&priv->sesshash[i]); in ng_l2tp_constructor()
398 if (priv->ctrl != NULL) in ng_l2tp_newhook()
400 priv->ctrl = hook; in ng_l2tp_newhook()
403 if (priv->lower != NULL) in ng_l2tp_newhook()
405 priv->lower = hook; in ng_l2tp_newhook()
418 sizeof(NG_L2TP_HOOK_SESSION_P) - 1) != 0) in ng_l2tp_newhook()
420 hex = name + sizeof(NG_L2TP_HOOK_SESSION_P) - 1; in ng_l2tp_newhook()
435 hpriv->conf.session_id = session_id; in ng_l2tp_newhook()
436 hpriv->conf.control_dseq = L2TP_CONTROL_DSEQ; in ng_l2tp_newhook()
437 hpriv->conf.enable_dseq = L2TP_ENABLE_DSEQ; in ng_l2tp_newhook()
438 hpriv->hook = hook; in ng_l2tp_newhook()
440 hash = SESSHASH(hpriv->conf.session_id); in ng_l2tp_newhook()
441 LIST_INSERT_HEAD(&priv->sesshash[hash], hpriv, sessions); in ng_l2tp_newhook()
460 switch (msg->header.typecookie) { in ng_l2tp_rcvmsg()
462 switch (msg->header.cmd) { in ng_l2tp_rcvmsg()
466 (struct ng_l2tp_config *)msg->data; in ng_l2tp_rcvmsg()
469 if (msg->header.arglen != sizeof(*conf)) { in ng_l2tp_rcvmsg()
473 conf->enabled = !!conf->enabled; in ng_l2tp_rcvmsg()
474 conf->match_id = !!conf->match_id; in ng_l2tp_rcvmsg()
475 if (priv->conf.enabled in ng_l2tp_rcvmsg()
476 && ((priv->conf.tunnel_id != 0 in ng_l2tp_rcvmsg()
477 && conf->tunnel_id != priv->conf.tunnel_id) in ng_l2tp_rcvmsg()
478 || ((priv->conf.peer_id != 0 in ng_l2tp_rcvmsg()
479 && conf->peer_id != priv->conf.peer_id)))) { in ng_l2tp_rcvmsg()
485 priv->ftarget = NGI_RETADDR(item); in ng_l2tp_rcvmsg()
492 priv->conf = *conf; in ng_l2tp_rcvmsg()
504 conf = (struct ng_l2tp_config *)resp->data; in ng_l2tp_rcvmsg()
505 *conf = priv->conf; in ng_l2tp_rcvmsg()
511 (struct ng_l2tp_sess_config *)msg->data; in ng_l2tp_rcvmsg()
515 if (msg->header.arglen != sizeof(*conf)) { in ng_l2tp_rcvmsg()
521 hpriv = ng_l2tp_find_session(priv, conf->session_id); in ng_l2tp_rcvmsg()
528 hpriv->conf = *conf; in ng_l2tp_rcvmsg()
538 if (msg->header.arglen != sizeof(session_id)) { in ng_l2tp_rcvmsg()
542 memcpy(&session_id, msg->data, 2); in ng_l2tp_rcvmsg()
552 NG_MKRESPONSE(resp, msg, sizeof(hpriv->conf), M_NOWAIT); in ng_l2tp_rcvmsg()
557 conf = (struct ng_l2tp_sess_config *)resp->data; in ng_l2tp_rcvmsg()
558 *conf = hpriv->conf; in ng_l2tp_rcvmsg()
565 if (msg->header.cmd != NGM_L2TP_CLR_STATS) { in ng_l2tp_rcvmsg()
567 sizeof(priv->stats), M_NOWAIT); in ng_l2tp_rcvmsg()
572 memcpy(resp->data, in ng_l2tp_rcvmsg()
573 &priv->stats, sizeof(priv->stats)); in ng_l2tp_rcvmsg()
575 if (msg->header.cmd != NGM_L2TP_GET_STATS) in ng_l2tp_rcvmsg()
576 memset(&priv->stats, 0, sizeof(priv->stats)); in ng_l2tp_rcvmsg()
587 if (msg->header.arglen != sizeof(session_id)) { in ng_l2tp_rcvmsg()
591 bcopy(msg->data, &session_id, sizeof(uint16_t)); in ng_l2tp_rcvmsg()
600 if (msg->header.cmd != NGM_L2TP_CLR_SESSION_STATS) { in ng_l2tp_rcvmsg()
602 sizeof(hpriv->stats), M_NOWAIT); in ng_l2tp_rcvmsg()
607 bcopy(&hpriv->stats, resp->data, in ng_l2tp_rcvmsg()
608 sizeof(hpriv->stats)); in ng_l2tp_rcvmsg()
610 if (msg->header.cmd != NGM_L2TP_GET_SESSION_STATS) in ng_l2tp_rcvmsg()
611 bzero(&hpriv->stats, sizeof(hpriv->stats)); in ng_l2tp_rcvmsg()
617 (struct ng_l2tp_seq_config *)msg->data; in ng_l2tp_rcvmsg()
620 if (msg->header.arglen != sizeof(*conf)) { in ng_l2tp_rcvmsg()
624 conf->ns = htons(conf->ns); in ng_l2tp_rcvmsg()
625 conf->nr = htons(conf->nr); in ng_l2tp_rcvmsg()
626 conf->rack = htons(conf->rack); in ng_l2tp_rcvmsg()
627 conf->xack = htons(conf->xack); in ng_l2tp_rcvmsg()
656 struct l2tp_seq *const seq = &priv->seq; in ng_l2tp_shutdown()
664 callout_drain(&seq->rack_timer); in ng_l2tp_shutdown()
665 callout_drain(&seq->xack_timer); in ng_l2tp_shutdown()
667 mtx_destroy(&seq->mtx); in ng_l2tp_shutdown()
686 if (hook == priv->ctrl) in ng_l2tp_disconnect()
687 priv->ctrl = NULL; in ng_l2tp_disconnect()
688 else if (hook == priv->lower) in ng_l2tp_disconnect()
689 priv->lower = NULL; in ng_l2tp_disconnect()
716 LIST_FOREACH(hpriv, &privp->sesshash[hash], sessions) { in ng_l2tp_find_session()
717 if (hpriv->conf.session_id == sid) in ng_l2tp_find_session()
733 hpriv->conf.control_dseq = 0; in ng_l2tp_reset_session()
734 hpriv->conf.enable_dseq = 0; in ng_l2tp_reset_session()
735 bzero(&hpriv->stats, sizeof(struct ng_l2tp_session_stats)); in ng_l2tp_reset_session()
736 hpriv->nr = 0; in ng_l2tp_reset_session()
737 hpriv->ns = 0; in ng_l2tp_reset_session()
739 return (-1); in ng_l2tp_reset_session()
764 /* If not configured, reject */ in ng_l2tp_rcvdata_lower()
765 if (!priv->conf.enabled) { in ng_l2tp_rcvdata_lower()
774 plen = m->m_pkthdr.len; in ng_l2tp_rcvdata_lower()
777 priv->stats.recvPackets++; in ng_l2tp_rcvdata_lower()
778 priv->stats.recvOctets += plen; in ng_l2tp_rcvdata_lower()
781 if (m->m_pkthdr.len < 6) { in ng_l2tp_rcvdata_lower()
782 priv->stats.recvRunts++; in ng_l2tp_rcvdata_lower()
787 if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) { in ng_l2tp_rcvdata_lower()
788 priv->stats.memoryFailures++; in ng_l2tp_rcvdata_lower()
799 priv->stats.recvInvalid++; in ng_l2tp_rcvdata_lower()
804 if (m->m_pkthdr.len < 4 /* tunnel, session id */ in ng_l2tp_rcvdata_lower()
808 priv->stats.recvRunts++; in ng_l2tp_rcvdata_lower()
816 if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) { in ng_l2tp_rcvdata_lower()
817 priv->stats.memoryFailures++; in ng_l2tp_rcvdata_lower()
821 len = (mtod(m, uint8_t *)[0] << 8) + mtod(m, uint8_t *)[1] - 4; in ng_l2tp_rcvdata_lower()
823 if (len < 0 || len > m->m_pkthdr.len) { in ng_l2tp_rcvdata_lower()
824 priv->stats.recvInvalid++; in ng_l2tp_rcvdata_lower()
829 if (len < m->m_pkthdr.len) /* trim extra bytes */ in ng_l2tp_rcvdata_lower()
830 m_adj(m, -(m->m_pkthdr.len - len)); in ng_l2tp_rcvdata_lower()
834 if (m->m_len < 4 && (m = m_pullup(m, 4)) == NULL) { in ng_l2tp_rcvdata_lower()
835 priv->stats.memoryFailures++; in ng_l2tp_rcvdata_lower()
844 if (tid != priv->conf.tunnel_id && in ng_l2tp_rcvdata_lower()
845 (priv->conf.match_id || tid != 0)) { in ng_l2tp_rcvdata_lower()
846 priv->stats.recvWrongTunnel++; in ng_l2tp_rcvdata_lower()
856 priv->stats.recvUnknownSID++; in ng_l2tp_rcvdata_lower()
861 hook = hpriv->hook; in ng_l2tp_rcvdata_lower()
866 if (m->m_len < 4 && (m = m_pullup(m, 4)) == NULL) { in ng_l2tp_rcvdata_lower()
867 priv->stats.memoryFailures++; in ng_l2tp_rcvdata_lower()
882 if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) { in ng_l2tp_rcvdata_lower()
883 priv->stats.memoryFailures++; in ng_l2tp_rcvdata_lower()
890 if ((2+offset) > m->m_pkthdr.len) { in ng_l2tp_rcvdata_lower()
891 priv->stats.recvInvalid++; in ng_l2tp_rcvdata_lower()
901 struct l2tp_seq *const seq = &priv->seq; in ng_l2tp_rcvdata_lower()
909 if (m->m_pkthdr.len == 0) { in ng_l2tp_rcvdata_lower()
911 priv->stats.recvZLBs++; in ng_l2tp_rcvdata_lower()
918 * If not what we expect or we are busy, drop packet and in ng_l2tp_rcvdata_lower()
921 if (ns != seq->nr || seq->inproc) { in ng_l2tp_rcvdata_lower()
922 if (L2TP_SEQ_DIFF(ns, seq->nr) <= 0) in ng_l2tp_rcvdata_lower()
923 priv->stats.recvDuplicates++; in ng_l2tp_rcvdata_lower()
925 priv->stats.recvOutOfOrder++; in ng_l2tp_rcvdata_lower()
926 ng_l2tp_xmit_ctrl(priv, NULL, seq->ns); in ng_l2tp_rcvdata_lower()
936 priv->stats.memoryFailures++; in ng_l2tp_rcvdata_lower()
947 seq->inproc = 1; in ng_l2tp_rcvdata_lower()
951 NG_FWD_NEW_DATA(error, item, priv->ctrl, m); in ng_l2tp_rcvdata_lower()
955 seq->inproc = 0; in ng_l2tp_rcvdata_lower()
959 /* Update recv sequence number */ in ng_l2tp_rcvdata_lower()
960 seq->nr++; in ng_l2tp_rcvdata_lower()
961 /* Start receive ack timer, if not already running */ in ng_l2tp_rcvdata_lower()
962 if (!callout_active(&seq->xack_timer)) { in ng_l2tp_rcvdata_lower()
963 callout_reset(&seq->xack_timer, in ng_l2tp_rcvdata_lower()
974 hpriv->stats.recvPackets++; in ng_l2tp_rcvdata_lower()
975 hpriv->stats.recvOctets += plen; in ng_l2tp_rcvdata_lower()
978 if (!hpriv->conf.control_dseq) in ng_l2tp_rcvdata_lower()
979 hpriv->conf.enable_dseq = ((hdr & L2TP_HDR_SEQ) != 0); in ng_l2tp_rcvdata_lower()
983 if (hpriv->conf.enable_dseq in ng_l2tp_rcvdata_lower()
984 && L2TP_SEQ_DIFF(ns, hpriv->nr) < 0) { in ng_l2tp_rcvdata_lower()
987 priv->stats.recvDataDrops++; in ng_l2tp_rcvdata_lower()
990 hpriv->nr = ns + 1; in ng_l2tp_rcvdata_lower()
993 /* Drop empty data packets */ in ng_l2tp_rcvdata_lower()
994 if (m->m_pkthdr.len == 0) { in ng_l2tp_rcvdata_lower()
1014 struct l2tp_seq *const seq = &priv->seq; in ng_l2tp_rcvdata_ctrl()
1020 /* If not configured, reject */ in ng_l2tp_rcvdata_ctrl()
1021 if (!priv->conf.enabled) { in ng_l2tp_rcvdata_ctrl()
1031 if (m->m_pkthdr.len < 2) { in ng_l2tp_rcvdata_ctrl()
1032 priv->stats.xmitInvalid++; in ng_l2tp_rcvdata_ctrl()
1038 if (m->m_pkthdr.len >= 0x10000 - 14) { in ng_l2tp_rcvdata_ctrl()
1039 priv->stats.xmitTooBig++; in ng_l2tp_rcvdata_ctrl()
1046 /* Find next empty slot in transmit queue */ in ng_l2tp_rcvdata_ctrl()
1047 for (i = 0; i < L2TP_MAX_XWIN && seq->xwin[i] != NULL; i++); in ng_l2tp_rcvdata_ctrl()
1050 priv->stats.xmitDrops++; in ng_l2tp_rcvdata_ctrl()
1054 seq->xwin[i] = m; in ng_l2tp_rcvdata_ctrl()
1057 if (i >= seq->cwnd) { in ng_l2tp_rcvdata_ctrl()
1062 /* Start retransmit timer if not already running */ in ng_l2tp_rcvdata_ctrl()
1063 if (!callout_active(&seq->rack_timer)) in ng_l2tp_rcvdata_ctrl()
1064 callout_reset(&seq->rack_timer, hz, ng_l2tp_seq_rack_timeout, in ng_l2tp_rcvdata_ctrl()
1067 ns = seq->ns++; in ng_l2tp_rcvdata_ctrl()
1072 priv->stats.memoryFailures++; in ng_l2tp_rcvdata_ctrl()
1096 /* If not configured, reject */ in ng_l2tp_rcvdata()
1097 if (!priv->conf.enabled) { in ng_l2tp_rcvdata()
1106 if (m->m_pkthdr.len >= 0x10000 - 12) { in ng_l2tp_rcvdata()
1107 priv->stats.xmitDataTooBig++; in ng_l2tp_rcvdata()
1115 + (2 * (hpriv->conf.include_length != 0)) in ng_l2tp_rcvdata()
1116 + (4 * (hpriv->conf.enable_dseq != 0)), in ng_l2tp_rcvdata()
1119 priv->stats.memoryFailures++; in ng_l2tp_rcvdata()
1125 if (hpriv->conf.include_length) { in ng_l2tp_rcvdata()
1127 p[i++] = m->m_pkthdr.len >> 8; in ng_l2tp_rcvdata()
1128 p[i++] = m->m_pkthdr.len & 0xff; in ng_l2tp_rcvdata()
1130 p[i++] = priv->conf.peer_id >> 8; in ng_l2tp_rcvdata()
1131 p[i++] = priv->conf.peer_id & 0xff; in ng_l2tp_rcvdata()
1132 p[i++] = hpriv->conf.peer_id >> 8; in ng_l2tp_rcvdata()
1133 p[i++] = hpriv->conf.peer_id & 0xff; in ng_l2tp_rcvdata()
1134 if (hpriv->conf.enable_dseq) { in ng_l2tp_rcvdata()
1136 p[i++] = hpriv->ns >> 8; in ng_l2tp_rcvdata()
1137 p[i++] = hpriv->ns & 0xff; in ng_l2tp_rcvdata()
1138 p[i++] = hpriv->nr >> 8; in ng_l2tp_rcvdata()
1139 p[i++] = hpriv->nr & 0xff; in ng_l2tp_rcvdata()
1140 hpriv->ns++; in ng_l2tp_rcvdata()
1146 hpriv->stats.xmitPackets++; in ng_l2tp_rcvdata()
1147 hpriv->stats.xmitOctets += m->m_pkthdr.len; in ng_l2tp_rcvdata()
1150 priv->stats.xmitPackets++; in ng_l2tp_rcvdata()
1151 priv->stats.xmitOctets += m->m_pkthdr.len; in ng_l2tp_rcvdata()
1154 NG_FWD_NEW_DATA(error, item, priv->lower, m); in ng_l2tp_rcvdata()
1171 NG_SEND_MSG_ID(error, priv->node, msg, priv->ftarget, 0); in ng_l2tp_seq_failure()
1184 struct l2tp_seq *const seq = &priv->seq; in ng_l2tp_seq_init()
1186 KASSERT(priv->conf.peer_win >= 1, in ng_l2tp_seq_init()
1189 seq->cwnd = 1; in ng_l2tp_seq_init()
1190 seq->wmax = priv->conf.peer_win; in ng_l2tp_seq_init()
1191 if (seq->wmax > L2TP_MAX_XWIN) in ng_l2tp_seq_init()
1192 seq->wmax = L2TP_MAX_XWIN; in ng_l2tp_seq_init()
1193 seq->ssth = seq->wmax; in ng_l2tp_seq_init()
1194 mtx_init(&seq->mtx, "ng_l2tp", NULL, MTX_DEF); in ng_l2tp_seq_init()
1195 callout_init_mtx(&seq->rack_timer, &seq->mtx, CALLOUT_RETURNUNLOCKED); in ng_l2tp_seq_init()
1196 callout_init_mtx(&seq->xack_timer, &seq->mtx, CALLOUT_RETURNUNLOCKED); in ng_l2tp_seq_init()
1205 struct l2tp_seq *const seq = &priv->seq; in ng_l2tp_seq_set()
1208 if (priv->conf.enabled) in ng_l2tp_seq_set()
1212 if (conf->xack != conf->nr || conf->ns != conf->rack) in ng_l2tp_seq_set()
1216 seq->ns = conf->ns; in ng_l2tp_seq_set()
1217 seq->nr = conf->nr; in ng_l2tp_seq_set()
1218 seq->rack = conf->rack; in ng_l2tp_seq_set()
1219 seq->xack = conf->xack; in ng_l2tp_seq_set()
1230 struct l2tp_seq *const seq = &priv->seq; in ng_l2tp_seq_adjust()
1236 if (!conf->enabled) { in ng_l2tp_seq_adjust()
1242 /* Adjust peer's max recv window; it can only increase */ in ng_l2tp_seq_adjust()
1243 new_wmax = conf->peer_win; in ng_l2tp_seq_adjust()
1248 if (new_wmax < seq->wmax) in ng_l2tp_seq_adjust()
1250 seq->wmax = new_wmax; in ng_l2tp_seq_adjust()
1263 struct l2tp_seq *const seq = &priv->seq; in ng_l2tp_seq_reset()
1269 (void )callout_stop(&seq->rack_timer); in ng_l2tp_seq_reset()
1270 (void )callout_stop(&seq->xack_timer); in ng_l2tp_seq_reset()
1274 if (seq->xwin[i] == NULL) in ng_l2tp_seq_reset()
1276 m_freem(seq->xwin[i]); in ng_l2tp_seq_reset()
1280 NG_NODE_FOREACH_HOOK(priv->node, ng_l2tp_reset_session, NULL); in ng_l2tp_seq_reset()
1283 seq->ns = 0; in ng_l2tp_seq_reset()
1284 seq->nr = 0; in ng_l2tp_seq_reset()
1285 seq->rack = 0; in ng_l2tp_seq_reset()
1286 seq->xack = 0; in ng_l2tp_seq_reset()
1287 seq->wmax = L2TP_MAX_XWIN; in ng_l2tp_seq_reset()
1288 seq->cwnd = 1; in ng_l2tp_seq_reset()
1289 seq->ssth = seq->wmax; in ng_l2tp_seq_reset()
1290 seq->acks = 0; in ng_l2tp_seq_reset()
1291 seq->rexmits = 0; in ng_l2tp_seq_reset()
1292 bzero(seq->xwin, sizeof(seq->xwin)); in ng_l2tp_seq_reset()
1301 struct l2tp_seq *const seq = &priv->seq; in ng_l2tp_seq_recv_nr()
1310 if ((nack = L2TP_SEQ_DIFF(nr, seq->rack)) <= 0) in ng_l2tp_seq_recv_nr()
1312 if (L2TP_SEQ_DIFF(nr, seq->ns) > 0) { in ng_l2tp_seq_recv_nr()
1313 priv->stats.recvBadAcks++; /* ack for packet not sent */ in ng_l2tp_seq_recv_nr()
1320 seq->rack = nr; in ng_l2tp_seq_recv_nr()
1321 seq->rexmits = 0; in ng_l2tp_seq_recv_nr()
1325 m_freem(seq->xwin[i]); in ng_l2tp_seq_recv_nr()
1326 memmove(seq->xwin, seq->xwin + nack, in ng_l2tp_seq_recv_nr()
1327 (L2TP_MAX_XWIN - nack) * sizeof(*seq->xwin)); in ng_l2tp_seq_recv_nr()
1328 memset(seq->xwin + (L2TP_MAX_XWIN - nack), 0, in ng_l2tp_seq_recv_nr()
1329 nack * sizeof(*seq->xwin)); in ng_l2tp_seq_recv_nr()
1332 * Do slow-start/congestion avoidance windowing algorithm described in ng_l2tp_seq_recv_nr()
1336 if (seq->cwnd < seq->wmax) { in ng_l2tp_seq_recv_nr()
1338 if (seq->cwnd < seq->ssth) { in ng_l2tp_seq_recv_nr()
1339 seq->cwnd += nack; in ng_l2tp_seq_recv_nr()
1341 if (seq->cwnd > seq->ssth) { /* into cg.av. phase */ in ng_l2tp_seq_recv_nr()
1342 nack = seq->cwnd - seq->ssth; in ng_l2tp_seq_recv_nr()
1343 seq->cwnd = seq->ssth; in ng_l2tp_seq_recv_nr()
1348 if (seq->cwnd >= seq->ssth) { in ng_l2tp_seq_recv_nr()
1349 seq->acks += nack; in ng_l2tp_seq_recv_nr()
1350 while (seq->acks >= seq->cwnd) { in ng_l2tp_seq_recv_nr()
1351 seq->acks -= seq->cwnd; in ng_l2tp_seq_recv_nr()
1352 if (seq->cwnd < seq->wmax) in ng_l2tp_seq_recv_nr()
1353 seq->cwnd++; in ng_l2tp_seq_recv_nr()
1359 if (callout_active(&seq->rack_timer)) in ng_l2tp_seq_recv_nr()
1360 (void )callout_stop(&seq->rack_timer); in ng_l2tp_seq_recv_nr()
1362 /* If transmit queue is empty, we're done for now */ in ng_l2tp_seq_recv_nr()
1363 if (seq->xwin[0] == NULL) in ng_l2tp_seq_recv_nr()
1367 callout_reset(&seq->rack_timer, hz, ng_l2tp_seq_rack_timeout, in ng_l2tp_seq_recv_nr()
1368 priv->node); in ng_l2tp_seq_recv_nr()
1374 ns = seq->ns; in ng_l2tp_seq_recv_nr()
1376 while ((i = L2TP_SEQ_DIFF(seq->ns, seq->rack)) < seq->cwnd in ng_l2tp_seq_recv_nr()
1377 && seq->xwin[i] != NULL) { in ng_l2tp_seq_recv_nr()
1378 xwin[j++] = seq->xwin[i]; in ng_l2tp_seq_recv_nr()
1379 seq->ns++; in ng_l2tp_seq_recv_nr()
1390 priv->stats.memoryFailures++; in ng_l2tp_seq_recv_nr()
1401 * were hoping to piggy-back, but haven't, so send a ZLB.
1409 struct l2tp_seq *const seq = &priv->seq; in ng_l2tp_seq_xack_timeout()
1412 MPASS(!callout_pending(&seq->xack_timer)); in ng_l2tp_seq_xack_timeout()
1413 MPASS(callout_active(&seq->xack_timer)); in ng_l2tp_seq_xack_timeout()
1416 CURVNET_SET(node->nd_vnet); in ng_l2tp_seq_xack_timeout()
1418 ng_l2tp_xmit_ctrl(priv, NULL, seq->ns); in ng_l2tp_seq_xack_timeout()
1422 /* callout_deactivate() is not needed here in ng_l2tp_seq_xack_timeout()
1436 struct l2tp_seq *const seq = &priv->seq; in ng_l2tp_seq_rack_timeout()
1441 MPASS(seq->xwin[0]); in ng_l2tp_seq_rack_timeout()
1442 MPASS(!callout_pending(&seq->rack_timer)); in ng_l2tp_seq_rack_timeout()
1443 MPASS(callout_active(&seq->rack_timer)); in ng_l2tp_seq_rack_timeout()
1446 CURVNET_SET(node->nd_vnet); in ng_l2tp_seq_rack_timeout()
1448 priv->stats.xmitRetransmits++; in ng_l2tp_seq_rack_timeout()
1451 if (seq->rexmits++ >= priv->conf.rexmit_max) in ng_l2tp_seq_rack_timeout()
1455 delay = (seq->rexmits > 12) ? (1 << 12) : (1 << seq->rexmits); in ng_l2tp_seq_rack_timeout()
1456 if (delay > priv->conf.rexmit_max_to) in ng_l2tp_seq_rack_timeout()
1457 delay = priv->conf.rexmit_max_to; in ng_l2tp_seq_rack_timeout()
1458 callout_reset(&seq->rack_timer, hz * delay, ng_l2tp_seq_rack_timeout, in ng_l2tp_seq_rack_timeout()
1461 /* Do slow-start/congestion algorithm windowing algorithm */ in ng_l2tp_seq_rack_timeout()
1462 seq->ns = seq->rack; in ng_l2tp_seq_rack_timeout()
1463 seq->ssth = (seq->cwnd + 1) / 2; in ng_l2tp_seq_rack_timeout()
1464 seq->cwnd = 1; in ng_l2tp_seq_rack_timeout()
1465 seq->acks = 0; in ng_l2tp_seq_rack_timeout()
1468 m = L2TP_COPY_MBUF(seq->xwin[0], M_NOWAIT); in ng_l2tp_seq_rack_timeout()
1471 priv->stats.memoryFailures++; in ng_l2tp_seq_rack_timeout()
1473 ng_l2tp_xmit_ctrl(priv, m, seq->ns++); in ng_l2tp_seq_rack_timeout()
1478 /* callout_deactivate() is not needed here in ng_l2tp_seq_rack_timeout()
1484 * The transmit sequence number is not incremented.
1490 struct l2tp_seq *const seq = &priv->seq; in ng_l2tp_xmit_ctrl()
1499 if (callout_active(&seq->xack_timer)) in ng_l2tp_xmit_ctrl()
1500 (void )callout_stop(&seq->xack_timer); in ng_l2tp_xmit_ctrl()
1502 nr = seq->xack = seq->nr; in ng_l2tp_xmit_ctrl()
1506 /* If no mbuf passed, send an empty packet (ZLB) */ in ng_l2tp_xmit_ctrl()
1511 priv->stats.memoryFailures++; in ng_l2tp_xmit_ctrl()
1514 m->m_len = m->m_pkthdr.len = 12; in ng_l2tp_xmit_ctrl()
1515 m->m_pkthdr.rcvif = NULL; in ng_l2tp_xmit_ctrl()
1516 priv->stats.xmitZLBs++; in ng_l2tp_xmit_ctrl()
1519 if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) { in ng_l2tp_xmit_ctrl()
1520 priv->stats.memoryFailures++; in ng_l2tp_xmit_ctrl()
1526 M_PREPEND(m, 10, M_NOWAIT); /* - 2 + 12 = 10 */ in ng_l2tp_xmit_ctrl()
1528 priv->stats.memoryFailures++; in ng_l2tp_xmit_ctrl()
1538 priv->stats.memoryFailures++; in ng_l2tp_xmit_ctrl()
1547 p[2] = m->m_pkthdr.len >> 8; in ng_l2tp_xmit_ctrl()
1548 p[3] = m->m_pkthdr.len & 0xff; in ng_l2tp_xmit_ctrl()
1549 p[4] = priv->conf.peer_id >> 8; in ng_l2tp_xmit_ctrl()
1550 p[5] = priv->conf.peer_id & 0xff; in ng_l2tp_xmit_ctrl()
1559 priv->stats.xmitPackets++; in ng_l2tp_xmit_ctrl()
1560 priv->stats.xmitOctets += m->m_pkthdr.len; in ng_l2tp_xmit_ctrl()
1563 NG_SEND_DATA_ONLY(error, priv->lower, m); in ng_l2tp_xmit_ctrl()
1577 #define CHECK(p) KASSERT((p), ("%s: not: %s", __func__, #p)) in ng_l2tp_seq_check()
1581 self_unack = L2TP_SEQ_DIFF(seq->nr, seq->xack); in ng_l2tp_seq_check()
1582 peer_unack = L2TP_SEQ_DIFF(seq->ns, seq->rack); in ng_l2tp_seq_check()
1583 CHECK(seq->wmax <= L2TP_MAX_XWIN); in ng_l2tp_seq_check()
1584 CHECK(seq->cwnd >= 1); in ng_l2tp_seq_check()
1585 CHECK(seq->cwnd <= seq->wmax); in ng_l2tp_seq_check()
1586 CHECK(seq->ssth >= 1); in ng_l2tp_seq_check()
1587 CHECK(seq->ssth <= seq->wmax); in ng_l2tp_seq_check()
1588 if (seq->cwnd < seq->ssth) in ng_l2tp_seq_check()
1589 CHECK(seq->acks == 0); in ng_l2tp_seq_check()
1591 CHECK(seq->acks <= seq->cwnd); in ng_l2tp_seq_check()
1594 CHECK(peer_unack <= seq->wmax); in ng_l2tp_seq_check()
1595 CHECK((self_unack == 0) ^ callout_active(&seq->xack_timer)); in ng_l2tp_seq_check()
1596 CHECK((peer_unack == 0) ^ callout_active(&seq->rack_timer)); in ng_l2tp_seq_check()
1598 CHECK(seq->xwin[i] != NULL); in ng_l2tp_seq_check()
1599 for ( ; i < seq->cwnd; i++) /* verify peer's recv window full */ in ng_l2tp_seq_check()
1600 CHECK(seq->xwin[i] == NULL); in ng_l2tp_seq_check()