View | Details | Raw Unified | Return to bug 241133
Collapse All | Expand All

(-)ng_l2tp.c (-123 / +96 lines)
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
}

Return to bug 241133