Lines 56-61
Link Here
|
56 |
#include <sys/errno.h> |
56 |
#include <sys/errno.h> |
57 |
#include <sys/libkern.h> |
57 |
#include <sys/libkern.h> |
58 |
|
58 |
|
|
|
59 |
#include <net/vnet.h> |
60 |
|
59 |
#include <netgraph/ng_message.h> |
61 |
#include <netgraph/ng_message.h> |
60 |
#include <netgraph/netgraph.h> |
62 |
#include <netgraph/netgraph.h> |
61 |
#include <netgraph/ng_parse.h> |
63 |
#include <netgraph/ng_parse.h> |
Lines 180-197
static int ng_l2tp_seq_adjust(priv_p priv,
Link Here
|
180 |
static void ng_l2tp_seq_reset(priv_p priv); |
182 |
static void ng_l2tp_seq_reset(priv_p priv); |
181 |
static void ng_l2tp_seq_failure(priv_p priv); |
183 |
static void ng_l2tp_seq_failure(priv_p priv); |
182 |
static void ng_l2tp_seq_recv_nr(priv_p priv, u_int16_t nr); |
184 |
static void ng_l2tp_seq_recv_nr(priv_p priv, u_int16_t nr); |
183 |
static void ng_l2tp_seq_xack_timeout(node_p node, hook_p hook, |
185 |
static void ng_l2tp_seq_xack_timeout(void *); |
184 |
void *arg1, int arg2); |
186 |
static void ng_l2tp_seq_rack_timeout(void *); |
185 |
static void ng_l2tp_seq_rack_timeout(node_p node, hook_p hook, |
|
|
186 |
void *arg1, int arg2); |
187 |
|
187 |
|
188 |
static hookpriv_p ng_l2tp_find_session(priv_p privp, u_int16_t sid); |
188 |
static hookpriv_p ng_l2tp_find_session(priv_p privp, u_int16_t sid); |
189 |
static ng_fn_eachhook ng_l2tp_reset_session; |
189 |
static ng_fn_eachhook ng_l2tp_reset_session; |
190 |
|
190 |
|
191 |
#ifdef INVARIANTS |
|
|
192 |
static void ng_l2tp_seq_check(struct l2tp_seq *seq); |
193 |
#endif |
194 |
|
195 |
/* Parse type for struct ng_l2tp_seq_config. */ |
191 |
/* Parse type for struct ng_l2tp_seq_config. */ |
196 |
static const struct ng_parse_struct_field |
192 |
static const struct ng_parse_struct_field |
197 |
ng_l2tp_seq_config_fields[] = NG_L2TP_SEQ_CONFIG_TYPE_INFO; |
193 |
ng_l2tp_seq_config_fields[] = NG_L2TP_SEQ_CONFIG_TYPE_INFO; |
Lines 335-346
static struct ng_type ng_l2tp_typestruct = {
Link Here
|
335 |
}; |
331 |
}; |
336 |
NETGRAPH_INIT(l2tp, &ng_l2tp_typestruct); |
332 |
NETGRAPH_INIT(l2tp, &ng_l2tp_typestruct); |
337 |
|
333 |
|
338 |
/* Sequence number state sanity checking */ |
334 |
/* Sequence number state locking & sanity checking */ |
339 |
#ifdef INVARIANTS |
335 |
#ifdef INVARIANTS |
340 |
#define L2TP_SEQ_CHECK(seq) ng_l2tp_seq_check(seq) |
336 |
static void ng_l2tp_seq_check(struct l2tp_seq *seq); |
|
|
337 |
#define SEQ_LOCK(seq) do { \ |
338 |
mtx_lock(&(seq)->mtx); \ |
339 |
ng_l2tp_seq_check(seq); \ |
340 |
} while (0) |
341 |
#define SEQ_UNLOCK(seq) do { \ |
342 |
ng_l2tp_seq_check(seq); \ |
343 |
mtx_unlock(&(seq)->mtx); \ |
344 |
} while (0) |
341 |
#else |
345 |
#else |
342 |
#define L2TP_SEQ_CHECK(x) do { } while (0) |
346 |
#define SEQ_LOCK(seq) mtx_lock(&(seq)->mtx) |
|
|
347 |
#define SEQ_UNLOCK(seq) mtx_unlock(&(seq)->mtx) |
343 |
#endif |
348 |
#endif |
|
|
349 |
#define SEQ_LOCK_ASSERT(seq) mtx_assert(&(seq)->mtx, MA_OWNED) |
344 |
|
350 |
|
345 |
/* Whether to use m_copypacket() or m_dup() */ |
351 |
/* Whether to use m_copypacket() or m_dup() */ |
346 |
#define L2TP_COPY_MBUF m_copypacket |
352 |
#define L2TP_COPY_MBUF m_copypacket |
Lines 650-664
ng_l2tp_shutdown(node_p node)
Link Here
|
650 |
const priv_p priv = NG_NODE_PRIVATE(node); |
656 |
const priv_p priv = NG_NODE_PRIVATE(node); |
651 |
struct l2tp_seq *const seq = &priv->seq; |
657 |
struct l2tp_seq *const seq = &priv->seq; |
652 |
|
658 |
|
653 |
/* Sanity check */ |
|
|
654 |
L2TP_SEQ_CHECK(seq); |
655 |
|
656 |
/* Reset sequence number state */ |
659 |
/* Reset sequence number state */ |
|
|
660 |
SEQ_LOCK(seq); |
657 |
ng_l2tp_seq_reset(priv); |
661 |
ng_l2tp_seq_reset(priv); |
|
|
662 |
SEQ_UNLOCK(seq); |
658 |
|
663 |
|
659 |
/* Free private data if neither timer is running */ |
664 |
/* Free private data if neither timer is running */ |
660 |
ng_uncallout(&seq->rack_timer, node); |
665 |
callout_drain(&seq->rack_timer); |
661 |
ng_uncallout(&seq->xack_timer, node); |
666 |
callout_drain(&seq->xack_timer); |
662 |
|
667 |
|
663 |
mtx_destroy(&seq->mtx); |
668 |
mtx_destroy(&seq->mtx); |
664 |
|
669 |
|
Lines 757-765
ng_l2tp_rcvdata_lower(hook_p h, item_p item)
Link Here
|
757 |
int error; |
762 |
int error; |
758 |
int len, plen; |
763 |
int len, plen; |
759 |
|
764 |
|
760 |
/* Sanity check */ |
|
|
761 |
L2TP_SEQ_CHECK(&priv->seq); |
762 |
|
763 |
/* If not configured, reject */ |
765 |
/* If not configured, reject */ |
764 |
if (!priv->conf.enabled) { |
766 |
if (!priv->conf.enabled) { |
765 |
NG_FREE_ITEM(item); |
767 |
NG_FREE_ITEM(item); |
Lines 899-916
ng_l2tp_rcvdata_lower(hook_p h, item_p item)
Link Here
|
899 |
if ((hdr & L2TP_HDR_CTRL) != 0) { |
901 |
if ((hdr & L2TP_HDR_CTRL) != 0) { |
900 |
struct l2tp_seq *const seq = &priv->seq; |
902 |
struct l2tp_seq *const seq = &priv->seq; |
901 |
|
903 |
|
|
|
904 |
SEQ_LOCK(seq); |
905 |
|
902 |
/* Handle receive ack sequence number Nr */ |
906 |
/* Handle receive ack sequence number Nr */ |
903 |
ng_l2tp_seq_recv_nr(priv, nr); |
907 |
ng_l2tp_seq_recv_nr(priv, nr); |
904 |
|
908 |
|
905 |
/* Discard ZLB packets */ |
909 |
/* Discard ZLB packets */ |
906 |
if (m->m_pkthdr.len == 0) { |
910 |
if (m->m_pkthdr.len == 0) { |
|
|
911 |
SEQ_UNLOCK(seq); |
907 |
priv->stats.recvZLBs++; |
912 |
priv->stats.recvZLBs++; |
908 |
NG_FREE_ITEM(item); |
913 |
NG_FREE_ITEM(item); |
909 |
NG_FREE_M(m); |
914 |
NG_FREE_M(m); |
910 |
ERROUT(0); |
915 |
ERROUT(0); |
911 |
} |
916 |
} |
912 |
|
917 |
|
913 |
mtx_lock(&seq->mtx); |
|
|
914 |
/* |
918 |
/* |
915 |
* If not what we expect or we are busy, drop packet and |
919 |
* If not what we expect or we are busy, drop packet and |
916 |
* send an immediate ZLB ack. |
920 |
* send an immediate ZLB ack. |
Lines 920-942
ng_l2tp_rcvdata_lower(hook_p h, item_p item)
Link Here
|
920 |
priv->stats.recvDuplicates++; |
924 |
priv->stats.recvDuplicates++; |
921 |
else |
925 |
else |
922 |
priv->stats.recvOutOfOrder++; |
926 |
priv->stats.recvOutOfOrder++; |
923 |
mtx_unlock(&seq->mtx); |
|
|
924 |
ng_l2tp_xmit_ctrl(priv, NULL, seq->ns); |
927 |
ng_l2tp_xmit_ctrl(priv, NULL, seq->ns); |
925 |
NG_FREE_ITEM(item); |
928 |
NG_FREE_ITEM(item); |
926 |
NG_FREE_M(m); |
929 |
NG_FREE_M(m); |
927 |
ERROUT(0); |
930 |
ERROUT(0); |
928 |
} |
931 |
} |
929 |
/* |
|
|
930 |
* Until we deliver this packet we can't receive next one as |
931 |
* we have no information for sending ack. |
932 |
*/ |
933 |
seq->inproc = 1; |
934 |
mtx_unlock(&seq->mtx); |
935 |
|
932 |
|
936 |
/* Prepend session ID to packet. */ |
933 |
/* Prepend session ID to packet. */ |
937 |
M_PREPEND(m, 2, M_NOWAIT); |
934 |
M_PREPEND(m, 2, M_NOWAIT); |
938 |
if (m == NULL) { |
935 |
if (m == NULL) { |
939 |
seq->inproc = 0; |
936 |
SEQ_UNLOCK(seq); |
940 |
priv->stats.memoryFailures++; |
937 |
priv->stats.memoryFailures++; |
941 |
NG_FREE_ITEM(item); |
938 |
NG_FREE_ITEM(item); |
942 |
ERROUT(ENOBUFS); |
939 |
ERROUT(ENOBUFS); |
Lines 944-953
ng_l2tp_rcvdata_lower(hook_p h, item_p item)
Link Here
|
944 |
mtod(m, u_int8_t *)[0] = sid >> 8; |
941 |
mtod(m, u_int8_t *)[0] = sid >> 8; |
945 |
mtod(m, u_int8_t *)[1] = sid & 0xff; |
942 |
mtod(m, u_int8_t *)[1] = sid & 0xff; |
946 |
|
943 |
|
|
|
944 |
/* |
945 |
* Until we deliver this packet we can't receive next one as |
946 |
* we have no information for sending ack. |
947 |
*/ |
948 |
seq->inproc = 1; |
949 |
SEQ_UNLOCK(seq); |
950 |
|
947 |
/* Deliver packet to upper layers */ |
951 |
/* Deliver packet to upper layers */ |
948 |
NG_FWD_NEW_DATA(error, item, priv->ctrl, m); |
952 |
NG_FWD_NEW_DATA(error, item, priv->ctrl, m); |
949 |
|
953 |
|
950 |
mtx_lock(&seq->mtx); |
954 |
SEQ_LOCK(seq); |
951 |
/* Ready to process next packet. */ |
955 |
/* Ready to process next packet. */ |
952 |
seq->inproc = 0; |
956 |
seq->inproc = 0; |
953 |
|
957 |
|
Lines 957-968
ng_l2tp_rcvdata_lower(hook_p h, item_p item)
Link Here
|
957 |
seq->nr++; |
961 |
seq->nr++; |
958 |
/* Start receive ack timer, if not already running */ |
962 |
/* Start receive ack timer, if not already running */ |
959 |
if (!callout_active(&seq->xack_timer)) { |
963 |
if (!callout_active(&seq->xack_timer)) { |
960 |
ng_callout(&seq->xack_timer, priv->node, NULL, |
964 |
callout_reset(&seq->xack_timer, |
961 |
L2TP_DELAYED_ACK, ng_l2tp_seq_xack_timeout, |
965 |
L2TP_DELAYED_ACK, ng_l2tp_seq_xack_timeout, |
962 |
NULL, 0); |
966 |
node); |
963 |
} |
967 |
} |
964 |
} |
968 |
} |
965 |
mtx_unlock(&seq->mtx); |
969 |
SEQ_UNLOCK(seq); |
966 |
|
970 |
|
967 |
ERROUT(error); |
971 |
ERROUT(error); |
968 |
} |
972 |
} |
Lines 997-1004
ng_l2tp_rcvdata_lower(hook_p h, item_p item)
Link Here
|
997 |
/* Deliver data */ |
1001 |
/* Deliver data */ |
998 |
NG_FWD_NEW_DATA(error, item, hook, m); |
1002 |
NG_FWD_NEW_DATA(error, item, hook, m); |
999 |
done: |
1003 |
done: |
1000 |
/* Done */ |
|
|
1001 |
L2TP_SEQ_CHECK(&priv->seq); |
1002 |
return (error); |
1004 |
return (error); |
1003 |
} |
1005 |
} |
1004 |
|
1006 |
|
Lines 1016-1024
ng_l2tp_rcvdata_ctrl(hook_p hook, item_p item)
Link Here
|
1016 |
int i; |
1018 |
int i; |
1017 |
u_int16_t ns; |
1019 |
u_int16_t ns; |
1018 |
|
1020 |
|
1019 |
/* Sanity check */ |
|
|
1020 |
L2TP_SEQ_CHECK(&priv->seq); |
1021 |
|
1022 |
/* If not configured, reject */ |
1021 |
/* If not configured, reject */ |
1023 |
if (!priv->conf.enabled) { |
1022 |
if (!priv->conf.enabled) { |
1024 |
NG_FREE_ITEM(item); |
1023 |
NG_FREE_ITEM(item); |
Lines 1043-1054
ng_l2tp_rcvdata_ctrl(hook_p hook, item_p item)
Link Here
|
1043 |
ERROUT(EOVERFLOW); |
1042 |
ERROUT(EOVERFLOW); |
1044 |
} |
1043 |
} |
1045 |
|
1044 |
|
1046 |
mtx_lock(&seq->mtx); |
1045 |
SEQ_LOCK(seq); |
1047 |
|
1046 |
|
1048 |
/* Find next empty slot in transmit queue */ |
1047 |
/* Find next empty slot in transmit queue */ |
1049 |
for (i = 0; i < L2TP_MAX_XWIN && seq->xwin[i] != NULL; i++); |
1048 |
for (i = 0; i < L2TP_MAX_XWIN && seq->xwin[i] != NULL; i++); |
1050 |
if (i == L2TP_MAX_XWIN) { |
1049 |
if (i == L2TP_MAX_XWIN) { |
1051 |
mtx_unlock(&seq->mtx); |
1050 |
SEQ_UNLOCK(seq); |
1052 |
priv->stats.xmitDrops++; |
1051 |
priv->stats.xmitDrops++; |
1053 |
m_freem(m); |
1052 |
m_freem(m); |
1054 |
ERROUT(ENOBUFS); |
1053 |
ERROUT(ENOBUFS); |
Lines 1057-1077
ng_l2tp_rcvdata_ctrl(hook_p hook, item_p item)
Link Here
|
1057 |
|
1056 |
|
1058 |
/* If peer's receive window is already full, nothing else to do */ |
1057 |
/* If peer's receive window is already full, nothing else to do */ |
1059 |
if (i >= seq->cwnd) { |
1058 |
if (i >= seq->cwnd) { |
1060 |
mtx_unlock(&seq->mtx); |
1059 |
SEQ_UNLOCK(seq); |
1061 |
ERROUT(0); |
1060 |
ERROUT(0); |
1062 |
} |
1061 |
} |
1063 |
|
1062 |
|
1064 |
/* Start retransmit timer if not already running */ |
1063 |
/* Start retransmit timer if not already running */ |
1065 |
if (!callout_active(&seq->rack_timer)) |
1064 |
if (!callout_active(&seq->rack_timer)) |
1066 |
ng_callout(&seq->rack_timer, node, NULL, |
1065 |
callout_reset(&seq->rack_timer, hz, ng_l2tp_seq_rack_timeout, |
1067 |
hz, ng_l2tp_seq_rack_timeout, NULL, 0); |
1066 |
node); |
1068 |
|
1067 |
|
1069 |
ns = seq->ns++; |
1068 |
ns = seq->ns++; |
1070 |
|
|
|
1071 |
mtx_unlock(&seq->mtx); |
1072 |
|
1069 |
|
1073 |
/* Copy packet */ |
1070 |
/* Copy packet */ |
1074 |
if ((m = L2TP_COPY_MBUF(m, M_NOWAIT)) == NULL) { |
1071 |
if ((m = L2TP_COPY_MBUF(m, M_NOWAIT)) == NULL) { |
|
|
1072 |
SEQ_UNLOCK(seq); |
1075 |
priv->stats.memoryFailures++; |
1073 |
priv->stats.memoryFailures++; |
1076 |
ERROUT(ENOBUFS); |
1074 |
ERROUT(ENOBUFS); |
1077 |
} |
1075 |
} |
Lines 1079-1086
ng_l2tp_rcvdata_ctrl(hook_p hook, item_p item)
Link Here
|
1079 |
/* Send packet and increment xmit sequence number */ |
1077 |
/* Send packet and increment xmit sequence number */ |
1080 |
error = ng_l2tp_xmit_ctrl(priv, m, ns); |
1078 |
error = ng_l2tp_xmit_ctrl(priv, m, ns); |
1081 |
done: |
1079 |
done: |
1082 |
/* Done */ |
|
|
1083 |
L2TP_SEQ_CHECK(&priv->seq); |
1084 |
return (error); |
1080 |
return (error); |
1085 |
} |
1081 |
} |
1086 |
|
1082 |
|
Lines 1098-1106
ng_l2tp_rcvdata(hook_p hook, item_p item)
Link Here
|
1098 |
int error; |
1094 |
int error; |
1099 |
int i = 2; |
1095 |
int i = 2; |
1100 |
|
1096 |
|
1101 |
/* Sanity check */ |
|
|
1102 |
L2TP_SEQ_CHECK(&priv->seq); |
1103 |
|
1104 |
/* If not configured, reject */ |
1097 |
/* If not configured, reject */ |
1105 |
if (!priv->conf.enabled) { |
1098 |
if (!priv->conf.enabled) { |
1106 |
NG_FREE_ITEM(item); |
1099 |
NG_FREE_ITEM(item); |
Lines 1161-1168
ng_l2tp_rcvdata(hook_p hook, item_p item)
Link Here
|
1161 |
/* Send packet */ |
1154 |
/* Send packet */ |
1162 |
NG_FWD_NEW_DATA(error, item, priv->lower, m); |
1155 |
NG_FWD_NEW_DATA(error, item, priv->lower, m); |
1163 |
done: |
1156 |
done: |
1164 |
/* Done */ |
|
|
1165 |
L2TP_SEQ_CHECK(&priv->seq); |
1166 |
return (error); |
1157 |
return (error); |
1167 |
} |
1158 |
} |
1168 |
|
1159 |
|
Lines 1201-1210
ng_l2tp_seq_init(priv_p priv)
Link Here
|
1201 |
if (seq->wmax > L2TP_MAX_XWIN) |
1192 |
if (seq->wmax > L2TP_MAX_XWIN) |
1202 |
seq->wmax = L2TP_MAX_XWIN; |
1193 |
seq->wmax = L2TP_MAX_XWIN; |
1203 |
seq->ssth = seq->wmax; |
1194 |
seq->ssth = seq->wmax; |
1204 |
ng_callout_init(&seq->rack_timer); |
|
|
1205 |
ng_callout_init(&seq->xack_timer); |
1206 |
mtx_init(&seq->mtx, "ng_l2tp", NULL, MTX_DEF); |
1195 |
mtx_init(&seq->mtx, "ng_l2tp", NULL, MTX_DEF); |
1207 |
L2TP_SEQ_CHECK(seq); |
1196 |
callout_init_mtx(&seq->rack_timer, &seq->mtx, CALLOUT_RETURNUNLOCKED); |
|
|
1197 |
callout_init_mtx(&seq->xack_timer, &seq->mtx, CALLOUT_RETURNUNLOCKED); |
1208 |
} |
1198 |
} |
1209 |
|
1199 |
|
1210 |
/* |
1200 |
/* |
Lines 1240-1249
ng_l2tp_seq_adjust(priv_p priv, const struct ng_l2tp_c
Link Here
|
1240 |
{ |
1230 |
{ |
1241 |
struct l2tp_seq *const seq = &priv->seq; |
1231 |
struct l2tp_seq *const seq = &priv->seq; |
1242 |
u_int16_t new_wmax; |
1232 |
u_int16_t new_wmax; |
|
|
1233 |
int error = 0; |
1243 |
|
1234 |
|
|
|
1235 |
SEQ_LOCK(seq); |
1244 |
/* If disabling node, reset state sequence number */ |
1236 |
/* If disabling node, reset state sequence number */ |
1245 |
if (!conf->enabled) { |
1237 |
if (!conf->enabled) { |
1246 |
ng_l2tp_seq_reset(priv); |
1238 |
ng_l2tp_seq_reset(priv); |
|
|
1239 |
SEQ_UNLOCK(seq); |
1247 |
return (0); |
1240 |
return (0); |
1248 |
} |
1241 |
} |
1249 |
|
1242 |
|
Lines 1252-1264
ng_l2tp_seq_adjust(priv_p priv, const struct ng_l2tp_c
Link Here
|
1252 |
if (new_wmax > L2TP_MAX_XWIN) |
1245 |
if (new_wmax > L2TP_MAX_XWIN) |
1253 |
new_wmax = L2TP_MAX_XWIN; |
1246 |
new_wmax = L2TP_MAX_XWIN; |
1254 |
if (new_wmax == 0) |
1247 |
if (new_wmax == 0) |
1255 |
return (EINVAL); |
1248 |
ERROUT(EINVAL); |
1256 |
if (new_wmax < seq->wmax) |
1249 |
if (new_wmax < seq->wmax) |
1257 |
return (EBUSY); |
1250 |
ERROUT(EBUSY); |
1258 |
seq->wmax = new_wmax; |
1251 |
seq->wmax = new_wmax; |
1259 |
|
1252 |
|
1260 |
/* Done */ |
1253 |
done: |
1261 |
return (0); |
1254 |
SEQ_UNLOCK(seq); |
|
|
1255 |
return (error); |
1262 |
} |
1256 |
} |
1263 |
|
1257 |
|
1264 |
/* |
1258 |
/* |
Lines 1271-1282
ng_l2tp_seq_reset(priv_p priv)
Link Here
|
1271 |
hook_p hook; |
1265 |
hook_p hook; |
1272 |
int i; |
1266 |
int i; |
1273 |
|
1267 |
|
1274 |
/* Sanity check */ |
1268 |
SEQ_LOCK_ASSERT(seq); |
1275 |
L2TP_SEQ_CHECK(seq); |
|
|
1276 |
|
1269 |
|
1277 |
/* Stop timers */ |
1270 |
/* Stop timers */ |
1278 |
ng_uncallout(&seq->rack_timer, priv->node); |
1271 |
(void )callout_stop(&seq->rack_timer); |
1279 |
ng_uncallout(&seq->xack_timer, priv->node); |
1272 |
(void )callout_stop(&seq->xack_timer); |
1280 |
|
1273 |
|
1281 |
/* Free retransmit queue */ |
1274 |
/* Free retransmit queue */ |
1282 |
for (i = 0; i < L2TP_MAX_XWIN; i++) { |
1275 |
for (i = 0; i < L2TP_MAX_XWIN; i++) { |
Lines 1299-1307
ng_l2tp_seq_reset(priv_p priv)
Link Here
|
1299 |
seq->acks = 0; |
1292 |
seq->acks = 0; |
1300 |
seq->rexmits = 0; |
1293 |
seq->rexmits = 0; |
1301 |
bzero(seq->xwin, sizeof(seq->xwin)); |
1294 |
bzero(seq->xwin, sizeof(seq->xwin)); |
1302 |
|
|
|
1303 |
/* Done */ |
1304 |
L2TP_SEQ_CHECK(seq); |
1305 |
} |
1295 |
} |
1306 |
|
1296 |
|
1307 |
/* |
1297 |
/* |
Lines 1316-1330
ng_l2tp_seq_recv_nr(priv_p priv, u_int16_t nr)
Link Here
|
1316 |
int i, j; |
1306 |
int i, j; |
1317 |
uint16_t ns; |
1307 |
uint16_t ns; |
1318 |
|
1308 |
|
1319 |
mtx_lock(&seq->mtx); |
1309 |
SEQ_LOCK_ASSERT(seq); |
1320 |
|
1310 |
|
1321 |
/* Verify peer's ACK is in range */ |
1311 |
/* Verify peer's ACK is in range */ |
1322 |
if ((nack = L2TP_SEQ_DIFF(nr, seq->rack)) <= 0) { |
1312 |
if ((nack = L2TP_SEQ_DIFF(nr, seq->rack)) <= 0) |
1323 |
mtx_unlock(&seq->mtx); |
|
|
1324 |
return; /* duplicate ack */ |
1313 |
return; /* duplicate ack */ |
1325 |
} |
|
|
1326 |
if (L2TP_SEQ_DIFF(nr, seq->ns) > 0) { |
1314 |
if (L2TP_SEQ_DIFF(nr, seq->ns) > 0) { |
1327 |
mtx_unlock(&seq->mtx); |
|
|
1328 |
priv->stats.recvBadAcks++; /* ack for packet not sent */ |
1315 |
priv->stats.recvBadAcks++; /* ack for packet not sent */ |
1329 |
return; |
1316 |
return; |
1330 |
} |
1317 |
} |
Lines 1349-1355
ng_l2tp_seq_recv_nr(priv_p priv, u_int16_t nr)
Link Here
|
1349 |
* ACK had arrived separately. |
1336 |
* ACK had arrived separately. |
1350 |
*/ |
1337 |
*/ |
1351 |
if (seq->cwnd < seq->wmax) { |
1338 |
if (seq->cwnd < seq->wmax) { |
1352 |
|
|
|
1353 |
/* Handle slow start phase */ |
1339 |
/* Handle slow start phase */ |
1354 |
if (seq->cwnd < seq->ssth) { |
1340 |
if (seq->cwnd < seq->ssth) { |
1355 |
seq->cwnd += nack; |
1341 |
seq->cwnd += nack; |
Lines 1373-1389
ng_l2tp_seq_recv_nr(priv_p priv, u_int16_t nr)
Link Here
|
1373 |
|
1359 |
|
1374 |
/* Stop xmit timer */ |
1360 |
/* Stop xmit timer */ |
1375 |
if (callout_active(&seq->rack_timer)) |
1361 |
if (callout_active(&seq->rack_timer)) |
1376 |
ng_uncallout(&seq->rack_timer, priv->node); |
1362 |
(void )callout_stop(&seq->rack_timer); |
1377 |
|
1363 |
|
1378 |
/* If transmit queue is empty, we're done for now */ |
1364 |
/* If transmit queue is empty, we're done for now */ |
1379 |
if (seq->xwin[0] == NULL) { |
1365 |
if (seq->xwin[0] == NULL) |
1380 |
mtx_unlock(&seq->mtx); |
|
|
1381 |
return; |
1366 |
return; |
1382 |
} |
|
|
1383 |
|
1367 |
|
1384 |
/* Start restransmit timer again */ |
1368 |
/* Start restransmit timer again */ |
1385 |
ng_callout(&seq->rack_timer, priv->node, NULL, |
1369 |
callout_reset(&seq->rack_timer, hz, ng_l2tp_seq_rack_timeout, |
1386 |
hz, ng_l2tp_seq_rack_timeout, NULL, 0); |
1370 |
priv->node); |
1387 |
|
1371 |
|
1388 |
/* |
1372 |
/* |
1389 |
* Send more packets, trying to keep peer's receive window full. |
1373 |
* Send more packets, trying to keep peer's receive window full. |
Lines 1397-1404
ng_l2tp_seq_recv_nr(priv_p priv, u_int16_t nr)
Link Here
|
1397 |
seq->ns++; |
1381 |
seq->ns++; |
1398 |
} |
1382 |
} |
1399 |
|
1383 |
|
1400 |
mtx_unlock(&seq->mtx); |
|
|
1401 |
|
1402 |
/* |
1384 |
/* |
1403 |
* Send prepared. |
1385 |
* Send prepared. |
1404 |
* If there is a memory error, pretend packet was sent, as it |
1386 |
* If there is a memory error, pretend packet was sent, as it |
Lines 1408-1415
ng_l2tp_seq_recv_nr(priv_p priv, u_int16_t nr)
Link Here
|
1408 |
struct mbuf *m; |
1390 |
struct mbuf *m; |
1409 |
if ((m = L2TP_COPY_MBUF(xwin[i], M_NOWAIT)) == NULL) |
1391 |
if ((m = L2TP_COPY_MBUF(xwin[i], M_NOWAIT)) == NULL) |
1410 |
priv->stats.memoryFailures++; |
1392 |
priv->stats.memoryFailures++; |
1411 |
else |
1393 |
else { |
1412 |
ng_l2tp_xmit_ctrl(priv, m, ns); |
1394 |
ng_l2tp_xmit_ctrl(priv, m, ns); |
|
|
1395 |
SEQ_LOCK(seq); |
1396 |
} |
1413 |
ns++; |
1397 |
ns++; |
1414 |
} |
1398 |
} |
1415 |
} |
1399 |
} |
Lines 1419-1445
ng_l2tp_seq_recv_nr(priv_p priv, u_int16_t nr)
Link Here
|
1419 |
* were hoping to piggy-back, but haven't, so send a ZLB. |
1403 |
* were hoping to piggy-back, but haven't, so send a ZLB. |
1420 |
*/ |
1404 |
*/ |
1421 |
static void |
1405 |
static void |
1422 |
ng_l2tp_seq_xack_timeout(node_p node, hook_p hook, void *arg1, int arg2) |
1406 |
ng_l2tp_seq_xack_timeout(void *arg) |
1423 |
{ |
1407 |
{ |
|
|
1408 |
const node_p node = arg; |
1424 |
const priv_p priv = NG_NODE_PRIVATE(node); |
1409 |
const priv_p priv = NG_NODE_PRIVATE(node); |
1425 |
struct l2tp_seq *const seq = &priv->seq; |
1410 |
struct l2tp_seq *const seq = &priv->seq; |
1426 |
|
1411 |
|
1427 |
/* Make sure callout is still active before doing anything */ |
1412 |
SEQ_LOCK_ASSERT(seq); |
1428 |
if (callout_pending(&seq->xack_timer) || |
1413 |
MPASS(!callout_pending(&seq->xack_timer)); |
1429 |
(!callout_active(&seq->xack_timer))) |
1414 |
MPASS(callout_active(&seq->xack_timer)); |
1430 |
return; |
|
|
1431 |
|
1415 |
|
1432 |
/* Sanity check */ |
1416 |
CURVNET_SET(node->nd_vnet); |
1433 |
L2TP_SEQ_CHECK(seq); |
|
|
1434 |
|
1435 |
/* Send a ZLB */ |
1417 |
/* Send a ZLB */ |
1436 |
ng_l2tp_xmit_ctrl(priv, NULL, seq->ns); |
1418 |
ng_l2tp_xmit_ctrl(priv, NULL, seq->ns); |
|
|
1419 |
CURVNET_RESTORE(); |
1437 |
|
1420 |
|
1438 |
/* callout_deactivate() is not needed here |
1421 |
/* callout_deactivate() is not needed here |
1439 |
as ng_uncallout() was called by ng_l2tp_xmit_ctrl() */ |
1422 |
as callout_stop() was called by ng_l2tp_xmit_ctrl() */ |
1440 |
|
|
|
1441 |
/* Sanity check */ |
1442 |
L2TP_SEQ_CHECK(seq); |
1443 |
} |
1423 |
} |
1444 |
|
1424 |
|
1445 |
/* |
1425 |
/* |
Lines 1447-1469
ng_l2tp_seq_xack_timeout(node_p node, hook_p hook, voi
Link Here
|
1447 |
* with an ack for our packet, so retransmit it. |
1427 |
* with an ack for our packet, so retransmit it. |
1448 |
*/ |
1428 |
*/ |
1449 |
static void |
1429 |
static void |
1450 |
ng_l2tp_seq_rack_timeout(node_p node, hook_p hook, void *arg1, int arg2) |
1430 |
ng_l2tp_seq_rack_timeout(void *arg) |
1451 |
{ |
1431 |
{ |
|
|
1432 |
const node_p node = arg; |
1452 |
const priv_p priv = NG_NODE_PRIVATE(node); |
1433 |
const priv_p priv = NG_NODE_PRIVATE(node); |
1453 |
struct l2tp_seq *const seq = &priv->seq; |
1434 |
struct l2tp_seq *const seq = &priv->seq; |
1454 |
struct mbuf *m; |
1435 |
struct mbuf *m; |
1455 |
u_int delay; |
1436 |
u_int delay; |
1456 |
|
1437 |
|
1457 |
/* Sanity check */ |
1438 |
SEQ_LOCK_ASSERT(seq); |
1458 |
L2TP_SEQ_CHECK(seq); |
1439 |
MPASS(seq->xwin[0]); |
|
|
1440 |
MPASS(!callout_pending(&seq->rack_timer)); |
1441 |
MPASS(callout_active(&seq->rack_timer)); |
1459 |
|
1442 |
|
1460 |
mtx_lock(&seq->mtx); |
1443 |
CURVNET_SET(node->nd_vnet); |
1461 |
/* Make sure callout is still active before doing anything */ |
|
|
1462 |
if (callout_pending(&seq->rack_timer) || |
1463 |
!callout_active(&seq->rack_timer)) { |
1464 |
mtx_unlock(&seq->mtx); |
1465 |
return; |
1466 |
} |
1467 |
|
1444 |
|
1468 |
priv->stats.xmitRetransmits++; |
1445 |
priv->stats.xmitRetransmits++; |
1469 |
|
1446 |
|
Lines 1475-1482
ng_l2tp_seq_rack_timeout(node_p node, hook_p hook, voi
Link Here
|
1475 |
delay = (seq->rexmits > 12) ? (1 << 12) : (1 << seq->rexmits); |
1452 |
delay = (seq->rexmits > 12) ? (1 << 12) : (1 << seq->rexmits); |
1476 |
if (delay > priv->conf.rexmit_max_to) |
1453 |
if (delay > priv->conf.rexmit_max_to) |
1477 |
delay = priv->conf.rexmit_max_to; |
1454 |
delay = priv->conf.rexmit_max_to; |
1478 |
ng_callout(&seq->rack_timer, node, NULL, |
1455 |
callout_reset(&seq->rack_timer, hz * delay, ng_l2tp_seq_rack_timeout, |
1479 |
hz * delay, ng_l2tp_seq_rack_timeout, NULL, 0); |
1456 |
node); |
1480 |
|
1457 |
|
1481 |
/* Do slow-start/congestion algorithm windowing algorithm */ |
1458 |
/* Do slow-start/congestion algorithm windowing algorithm */ |
1482 |
seq->ns = seq->rack; |
1459 |
seq->ns = seq->rack; |
Lines 1486-1530
ng_l2tp_seq_rack_timeout(node_p node, hook_p hook, voi
Link Here
|
1486 |
|
1463 |
|
1487 |
/* Retransmit oldest unack'd packet */ |
1464 |
/* Retransmit oldest unack'd packet */ |
1488 |
m = L2TP_COPY_MBUF(seq->xwin[0], M_NOWAIT); |
1465 |
m = L2TP_COPY_MBUF(seq->xwin[0], M_NOWAIT); |
1489 |
mtx_unlock(&seq->mtx); |
1466 |
if (m == NULL) { |
1490 |
if (m == NULL) |
1467 |
SEQ_UNLOCK(seq); |
1491 |
priv->stats.memoryFailures++; |
1468 |
priv->stats.memoryFailures++; |
1492 |
else |
1469 |
} else |
1493 |
ng_l2tp_xmit_ctrl(priv, m, seq->ns++); |
1470 |
ng_l2tp_xmit_ctrl(priv, m, seq->ns++); |
1494 |
|
1471 |
|
|
|
1472 |
CURVNET_RESTORE(); |
1473 |
|
1495 |
/* callout_deactivate() is not needed here |
1474 |
/* callout_deactivate() is not needed here |
1496 |
as ng_callout() is getting called each time */ |
1475 |
as ng_callout() is getting called each time */ |
1497 |
|
|
|
1498 |
/* Sanity check */ |
1499 |
L2TP_SEQ_CHECK(seq); |
1500 |
} |
1476 |
} |
1501 |
|
1477 |
|
1502 |
/* |
1478 |
/* |
1503 |
* Transmit a control stream packet, payload optional. |
1479 |
* Transmit a control stream packet, payload optional. |
1504 |
* The transmit sequence number is not incremented. |
1480 |
* The transmit sequence number is not incremented. |
|
|
1481 |
* Requires seq lock, returns unlocked. |
1505 |
*/ |
1482 |
*/ |
1506 |
static int |
1483 |
static int |
1507 |
ng_l2tp_xmit_ctrl(priv_p priv, struct mbuf *m, u_int16_t ns) |
1484 |
ng_l2tp_xmit_ctrl(priv_p priv, struct mbuf *m, u_int16_t ns) |
1508 |
{ |
1485 |
{ |
1509 |
struct l2tp_seq *const seq = &priv->seq; |
1486 |
struct l2tp_seq *const seq = &priv->seq; |
1510 |
uint8_t *p; |
1487 |
uint8_t *p; |
1511 |
u_int16_t session_id = 0; |
1488 |
uint16_t nr, session_id = 0; |
1512 |
int error; |
1489 |
int error; |
1513 |
|
1490 |
|
1514 |
mtx_lock(&seq->mtx); |
1491 |
SEQ_LOCK_ASSERT(seq); |
1515 |
|
1492 |
|
1516 |
/* Stop ack timer: we're sending an ack with this packet. |
1493 |
/* Stop ack timer: we're sending an ack with this packet. |
1517 |
Doing this before to keep state predictable after error. */ |
1494 |
Doing this before to keep state predictable after error. */ |
1518 |
if (callout_active(&seq->xack_timer)) |
1495 |
if (callout_active(&seq->xack_timer)) |
1519 |
ng_uncallout(&seq->xack_timer, priv->node); |
1496 |
(void )callout_stop(&seq->xack_timer); |
1520 |
|
1497 |
|
1521 |
seq->xack = seq->nr; |
1498 |
nr = seq->xack = seq->nr; |
1522 |
|
1499 |
|
1523 |
mtx_unlock(&seq->mtx); |
1500 |
SEQ_UNLOCK(seq); |
1524 |
|
1501 |
|
1525 |
/* If no mbuf passed, send an empty packet (ZLB) */ |
1502 |
/* If no mbuf passed, send an empty packet (ZLB) */ |
1526 |
if (m == NULL) { |
1503 |
if (m == NULL) { |
1527 |
|
|
|
1528 |
/* Create a new mbuf for ZLB packet */ |
1504 |
/* Create a new mbuf for ZLB packet */ |
1529 |
MGETHDR(m, M_NOWAIT, MT_DATA); |
1505 |
MGETHDR(m, M_NOWAIT, MT_DATA); |
1530 |
if (m == NULL) { |
1506 |
if (m == NULL) { |
Lines 1535-1541
ng_l2tp_xmit_ctrl(priv_p priv, struct mbuf *m, u_int16
Link Here
|
1535 |
m->m_pkthdr.rcvif = NULL; |
1511 |
m->m_pkthdr.rcvif = NULL; |
1536 |
priv->stats.xmitZLBs++; |
1512 |
priv->stats.xmitZLBs++; |
1537 |
} else { |
1513 |
} else { |
1538 |
|
|
|
1539 |
/* Strip off session ID */ |
1514 |
/* Strip off session ID */ |
1540 |
if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) { |
1515 |
if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) { |
1541 |
priv->stats.memoryFailures++; |
1516 |
priv->stats.memoryFailures++; |
Lines 1573-1580
ng_l2tp_xmit_ctrl(priv_p priv, struct mbuf *m, u_int16
Link Here
|
1573 |
p[7] = session_id & 0xff; |
1548 |
p[7] = session_id & 0xff; |
1574 |
p[8] = ns >> 8; |
1549 |
p[8] = ns >> 8; |
1575 |
p[9] = ns & 0xff; |
1550 |
p[9] = ns & 0xff; |
1576 |
p[10] = seq->nr >> 8; |
1551 |
p[10] = nr >> 8; |
1577 |
p[11] = seq->nr & 0xff; |
1552 |
p[11] = nr & 0xff; |
1578 |
|
1553 |
|
1579 |
/* Update sequence number info and stats */ |
1554 |
/* Update sequence number info and stats */ |
1580 |
priv->stats.xmitPackets++; |
1555 |
priv->stats.xmitPackets++; |
Lines 1597-1603
ng_l2tp_seq_check(struct l2tp_seq *seq)
Link Here
|
1597 |
|
1572 |
|
1598 |
#define CHECK(p) KASSERT((p), ("%s: not: %s", __func__, #p)) |
1573 |
#define CHECK(p) KASSERT((p), ("%s: not: %s", __func__, #p)) |
1599 |
|
1574 |
|
1600 |
mtx_lock(&seq->mtx); |
1575 |
SEQ_LOCK_ASSERT(seq); |
1601 |
|
1576 |
|
1602 |
self_unack = L2TP_SEQ_DIFF(seq->nr, seq->xack); |
1577 |
self_unack = L2TP_SEQ_DIFF(seq->nr, seq->xack); |
1603 |
peer_unack = L2TP_SEQ_DIFF(seq->ns, seq->rack); |
1578 |
peer_unack = L2TP_SEQ_DIFF(seq->ns, seq->rack); |
Lines 1619-1626
ng_l2tp_seq_check(struct l2tp_seq *seq)
Link Here
|
1619 |
CHECK(seq->xwin[i] != NULL); |
1594 |
CHECK(seq->xwin[i] != NULL); |
1620 |
for ( ; i < seq->cwnd; i++) /* verify peer's recv window full */ |
1595 |
for ( ; i < seq->cwnd; i++) /* verify peer's recv window full */ |
1621 |
CHECK(seq->xwin[i] == NULL); |
1596 |
CHECK(seq->xwin[i] == NULL); |
1622 |
|
|
|
1623 |
mtx_unlock(&seq->mtx); |
1624 |
|
1597 |
|
1625 |
#undef CHECK |
1598 |
#undef CHECK |
1626 |
} |
1599 |
} |