Deleted Added
full compact
ng_source.c (125033) ng_source.c (125077)
1/*
2 * ng_source.c
3 *
4 * Copyright 2002 Sandvine Inc.
5 * All rights reserved.
6 *
7 * Subject to the following obligations and disclaimer of warranty, use and
8 * redistribution of this software, in source or object code forms, with or

--- 19 unchanged lines hidden (view full) ---

28 * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF SANDVINE IS ADVISED OF THE POSSIBILITY OF SUCH
33 * DAMAGE.
34 *
35 * Author: Dave Chapeskie <dchapeskie@sandvine.com>
1/*
2 * ng_source.c
3 *
4 * Copyright 2002 Sandvine Inc.
5 * All rights reserved.
6 *
7 * Subject to the following obligations and disclaimer of warranty, use and
8 * redistribution of this software, in source or object code forms, with or

--- 19 unchanged lines hidden (view full) ---

28 * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF SANDVINE IS ADVISED OF THE POSSIBILITY OF SUCH
33 * DAMAGE.
34 *
35 * Author: Dave Chapeskie <dchapeskie@sandvine.com>
36 *
37 * $FreeBSD: head/sys/netgraph/ng_source.c 125033 2004-01-26 14:53:16Z harti $
38 */
39
36 */
37
38#include <sys/cdefs.h>
39__FBSDID("$FreeBSD: head/sys/netgraph/ng_source.c 125077 2004-01-27 10:45:37Z harti $");
40
40/*
41 * This node is used for high speed packet geneneration. It queues
42 * all data recieved on it's 'input' hook and when told to start via
43 * a control message it sends the packets out it's 'output' hook. In
44 * this way this node can be preloaded with a packet stream which is
45 * continuously sent.
46 *
47 * Currently it just copies the mbufs as required. It could do various

--- 42 unchanged lines hidden (view full) ---

90 u_int64_t packets; /* packets to send */
91 u_int32_t queueOctets;
92};
93typedef struct privdata *sc_p;
94
95/* Node flags */
96#define NG_SOURCE_ACTIVE (NGF_TYPE1)
97
41/*
42 * This node is used for high speed packet geneneration. It queues
43 * all data recieved on it's 'input' hook and when told to start via
44 * a control message it sends the packets out it's 'output' hook. In
45 * this way this node can be preloaded with a packet stream which is
46 * continuously sent.
47 *
48 * Currently it just copies the mbufs as required. It could do various

--- 42 unchanged lines hidden (view full) ---

91 u_int64_t packets; /* packets to send */
92 u_int32_t queueOctets;
93};
94typedef struct privdata *sc_p;
95
96/* Node flags */
97#define NG_SOURCE_ACTIVE (NGF_TYPE1)
98
98/* XXX */
99#if 1
100#undef KASSERT
101#define KASSERT(expr,msg) do { \
102 if (!(expr)) { \
103 printf msg ; \
104 panic("Assertion"); \
105 } \
106 } while(0)
107#endif
108
109/* Netgraph methods */
110static ng_constructor_t ng_source_constructor;
111static ng_rcvmsg_t ng_source_rcvmsg;
112static ng_shutdown_t ng_source_rmnode;
113static ng_newhook_t ng_source_newhook;
114static ng_rcvdata_t ng_source_rcvdata;
115static ng_disconnect_t ng_source_disconnect;
116

--- 4 unchanged lines hidden (view full) ---

121static void ng_source_start (sc_p);
122static void ng_source_stop (sc_p);
123static int ng_source_send (sc_p, int, int *);
124static int ng_source_store_output_ifp(sc_p sc,
125 struct ng_mesg *msg);
126
127
128/* Parse type for timeval */
99/* Netgraph methods */
100static ng_constructor_t ng_source_constructor;
101static ng_rcvmsg_t ng_source_rcvmsg;
102static ng_shutdown_t ng_source_rmnode;
103static ng_newhook_t ng_source_newhook;
104static ng_rcvdata_t ng_source_rcvdata;
105static ng_disconnect_t ng_source_disconnect;
106

--- 4 unchanged lines hidden (view full) ---

111static void ng_source_start (sc_p);
112static void ng_source_stop (sc_p);
113static int ng_source_send (sc_p, int, int *);
114static int ng_source_store_output_ifp(sc_p sc,
115 struct ng_mesg *msg);
116
117
118/* Parse type for timeval */
129static const struct ng_parse_struct_field ng_source_timeval_type_fields[] =
130{
119static const struct ng_parse_struct_field ng_source_timeval_type_fields[] = {
131 { "tv_sec", &ng_parse_int32_type },
132 { "tv_usec", &ng_parse_int32_type },
133 { NULL }
134};
135const struct ng_parse_type ng_source_timeval_type = {
136 &ng_parse_struct_type,
137 &ng_source_timeval_type_fields
138};

--- 65 unchanged lines hidden (view full) ---

204 NG_ABI_VERSION,
205 NG_SOURCE_NODE_TYPE,
206 NULL, /* module event handler */
207 ng_source_constructor,
208 ng_source_rcvmsg,
209 ng_source_rmnode,
210 ng_source_newhook,
211 NULL, /* findhook */
120 { "tv_sec", &ng_parse_int32_type },
121 { "tv_usec", &ng_parse_int32_type },
122 { NULL }
123};
124const struct ng_parse_type ng_source_timeval_type = {
125 &ng_parse_struct_type,
126 &ng_source_timeval_type_fields
127};

--- 65 unchanged lines hidden (view full) ---

193 NG_ABI_VERSION,
194 NG_SOURCE_NODE_TYPE,
195 NULL, /* module event handler */
196 ng_source_constructor,
197 ng_source_rcvmsg,
198 ng_source_rmnode,
199 ng_source_newhook,
200 NULL, /* findhook */
212 NULL,
201 NULL, /* connect */
213 ng_source_rcvdata, /* rcvdata */
214 ng_source_disconnect,
215 ng_source_cmds
216};
217NETGRAPH_INIT(source, &ng_source_typestruct);
218
219static int ng_source_set_autosrc(sc_p, u_int32_t);
220

--- 21 unchanged lines hidden (view full) ---

242 * Add a hook
243 */
244static int
245ng_source_newhook(node_p node, hook_p hook, const char *name)
246{
247 sc_p sc;
248
249 sc = NG_NODE_PRIVATE(node);
202 ng_source_rcvdata, /* rcvdata */
203 ng_source_disconnect,
204 ng_source_cmds
205};
206NETGRAPH_INIT(source, &ng_source_typestruct);
207
208static int ng_source_set_autosrc(sc_p, u_int32_t);
209

--- 21 unchanged lines hidden (view full) ---

231 * Add a hook
232 */
233static int
234ng_source_newhook(node_p node, hook_p hook, const char *name)
235{
236 sc_p sc;
237
238 sc = NG_NODE_PRIVATE(node);
250 KASSERT(sc != NULL, ("%s: null node private", __FUNCTION__));
239 KASSERT(sc != NULL, ("%s: null node private", __func__));
251 if (strcmp(name, NG_SOURCE_HOOK_INPUT) == 0) {
252 sc->input.hook = hook;
253 NG_HOOK_SET_PRIVATE(hook, &sc->input);
254 } else if (strcmp(name, NG_SOURCE_HOOK_OUTPUT) == 0) {
255 sc->output.hook = hook;
256 NG_HOOK_SET_PRIVATE(hook, &sc->output);
257 sc->output_ifp = 0;
258 bzero(&sc->stats, sizeof(sc->stats));

--- 10 unchanged lines hidden (view full) ---

269{
270 sc_p sc;
271 struct ng_mesg *resp = NULL;
272 int error = 0;
273 struct ng_mesg *msg;
274
275 sc = NG_NODE_PRIVATE(node);
276 NGI_GET_MSG(item, msg);
240 if (strcmp(name, NG_SOURCE_HOOK_INPUT) == 0) {
241 sc->input.hook = hook;
242 NG_HOOK_SET_PRIVATE(hook, &sc->input);
243 } else if (strcmp(name, NG_SOURCE_HOOK_OUTPUT) == 0) {
244 sc->output.hook = hook;
245 NG_HOOK_SET_PRIVATE(hook, &sc->output);
246 sc->output_ifp = 0;
247 bzero(&sc->stats, sizeof(sc->stats));

--- 10 unchanged lines hidden (view full) ---

258{
259 sc_p sc;
260 struct ng_mesg *resp = NULL;
261 int error = 0;
262 struct ng_mesg *msg;
263
264 sc = NG_NODE_PRIVATE(node);
265 NGI_GET_MSG(item, msg);
277 KASSERT(sc != NULL, ("%s: null node private", __FUNCTION__));
266 KASSERT(sc != NULL, ("%s: null node private", __func__));
278 switch (msg->header.typecookie) {
279 case NGM_SOURCE_COOKIE:
280 if (msg->header.flags & NGF_RESP) {
281 error = EINVAL;
282 break;
283 }
284 switch (msg->header.cmd) {
285 case NGM_SOURCE_GET_STATS:

--- 24 unchanged lines hidden (view full) ---

310 bzero(&sc->stats, sizeof(sc->stats));
311 }
312 break;
313 case NGM_SOURCE_START:
314 {
315 u_int64_t packets = *(u_int64_t *)msg->data;
316 if (sc->output.hook == NULL) {
317 printf("%s: start on node with no output hook\n"
267 switch (msg->header.typecookie) {
268 case NGM_SOURCE_COOKIE:
269 if (msg->header.flags & NGF_RESP) {
270 error = EINVAL;
271 break;
272 }
273 switch (msg->header.cmd) {
274 case NGM_SOURCE_GET_STATS:

--- 24 unchanged lines hidden (view full) ---

299 bzero(&sc->stats, sizeof(sc->stats));
300 }
301 break;
302 case NGM_SOURCE_START:
303 {
304 u_int64_t packets = *(u_int64_t *)msg->data;
305 if (sc->output.hook == NULL) {
306 printf("%s: start on node with no output hook\n"
318 , __FUNCTION__);
307 , __func__);
319 error = EINVAL;
320 break;
321 }
322 /* TODO validation of packets */
323 sc->packets = packets;
324 ng_source_start(sc);
325 }
326 break;
327 case NGM_SOURCE_START_NOW:
328 {
329 u_int64_t packets = *(u_int64_t *)msg->data;
330 if (sc->output.hook == NULL) {
331 printf("%s: start on node with no output hook\n"
308 error = EINVAL;
309 break;
310 }
311 /* TODO validation of packets */
312 sc->packets = packets;
313 ng_source_start(sc);
314 }
315 break;
316 case NGM_SOURCE_START_NOW:
317 {
318 u_int64_t packets = *(u_int64_t *)msg->data;
319 if (sc->output.hook == NULL) {
320 printf("%s: start on node with no output hook\n"
332 , __FUNCTION__);
321 , __func__);
333 error = EINVAL;
334 break;
335 }
336 if (sc->node->nd_flags & NG_SOURCE_ACTIVE) {
337 error = EBUSY;
338 break;
339 }
340 /* TODO validation of packets */

--- 64 unchanged lines hidden (view full) ---

405 struct source_hookinfo *hinfo;
406 int error = 0;
407 struct mbuf *m;
408
409 sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
410 NGI_GET_M(item, m);
411 NG_FREE_ITEM(item);
412 hinfo = NG_HOOK_PRIVATE(hook);
322 error = EINVAL;
323 break;
324 }
325 if (sc->node->nd_flags & NG_SOURCE_ACTIVE) {
326 error = EBUSY;
327 break;
328 }
329 /* TODO validation of packets */

--- 64 unchanged lines hidden (view full) ---

394 struct source_hookinfo *hinfo;
395 int error = 0;
396 struct mbuf *m;
397
398 sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
399 NGI_GET_M(item, m);
400 NG_FREE_ITEM(item);
401 hinfo = NG_HOOK_PRIVATE(hook);
413 KASSERT(sc != NULL, ("%s: null node private", __FUNCTION__));
414 KASSERT(hinfo != NULL, ("%s: null hook info", __FUNCTION__));
402 KASSERT(sc != NULL, ("%s: null node private", __func__));
403 KASSERT(hinfo != NULL, ("%s: null hook info", __func__));
415
416 /* Which hook? */
417 if (hinfo == &sc->output) {
418 /* discard */
419 NG_FREE_M(m);
420 return (error);
421 }
404
405 /* Which hook? */
406 if (hinfo == &sc->output) {
407 /* discard */
408 NG_FREE_M(m);
409 return (error);
410 }
422 KASSERT(hinfo == &sc->input, ("%s: no hook!", __FUNCTION__));
411 KASSERT(hinfo == &sc->input, ("%s: no hook!", __func__));
423
424 if ((m->m_flags & M_PKTHDR) == 0) {
412
413 if ((m->m_flags & M_PKTHDR) == 0) {
425 printf("%s: mbuf without PKTHDR\n", __FUNCTION__);
414 printf("%s: mbuf without PKTHDR\n", __func__);
426 NG_FREE_M(m);
427 return (EINVAL);
428 }
429
430 /* enque packet */
431 /* XXX should we check IF_QFULL() ? */
432 _IF_ENQUEUE(&sc->snd_queue, m);
433 sc->queueOctets += m->m_pkthdr.len;

--- 5 unchanged lines hidden (view full) ---

439 * Shutdown processing
440 */
441static int
442ng_source_rmnode(node_p node)
443{
444 sc_p sc;
445
446 sc = NG_NODE_PRIVATE(node);
415 NG_FREE_M(m);
416 return (EINVAL);
417 }
418
419 /* enque packet */
420 /* XXX should we check IF_QFULL() ? */
421 _IF_ENQUEUE(&sc->snd_queue, m);
422 sc->queueOctets += m->m_pkthdr.len;

--- 5 unchanged lines hidden (view full) ---

428 * Shutdown processing
429 */
430static int
431ng_source_rmnode(node_p node)
432{
433 sc_p sc;
434
435 sc = NG_NODE_PRIVATE(node);
447 KASSERT(sc != NULL, ("%s: null node private", __FUNCTION__));
436 KASSERT(sc != NULL, ("%s: null node private", __func__));
448 node->nd_flags |= NG_INVALID;
449 ng_source_stop(sc);
450 ng_source_clr_data(sc);
451 NG_NODE_SET_PRIVATE(node, NULL);
452 NG_NODE_UNREF(node);
437 node->nd_flags |= NG_INVALID;
438 ng_source_stop(sc);
439 ng_source_clr_data(sc);
440 NG_NODE_SET_PRIVATE(node, NULL);
441 NG_NODE_UNREF(node);
453 FREE(sc, M_NETGRAPH);
442 free(sc, M_NETGRAPH);
454 return (0);
455}
456
457/*
458 * Hook disconnection
459 */
460static int
461ng_source_disconnect(hook_p hook)
462{
463 struct source_hookinfo *hinfo;
464 sc_p sc;
465
466 hinfo = NG_HOOK_PRIVATE(hook);
467 sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
443 return (0);
444}
445
446/*
447 * Hook disconnection
448 */
449static int
450ng_source_disconnect(hook_p hook)
451{
452 struct source_hookinfo *hinfo;
453 sc_p sc;
454
455 hinfo = NG_HOOK_PRIVATE(hook);
456 sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
468 KASSERT(sc != NULL, ("%s: null node private", __FUNCTION__));
457 KASSERT(sc != NULL, ("%s: null node private", __func__));
469 hinfo->hook = NULL;
470 if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0 || hinfo == &sc->output)
471 ng_rmnode_self(NG_HOOK_NODE(hook));
472 return (0);
473}
474
475/*
476 *

--- 39 unchanged lines hidden (view full) ---

516 IFNET_RLOCK();
517 TAILQ_FOREACH(ifp, &ifnet, if_link) {
518 if (ifp->if_index == if_index)
519 break;
520 }
521 IFNET_RUNLOCK();
522
523 if (ifp == NULL) {
458 hinfo->hook = NULL;
459 if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0 || hinfo == &sc->output)
460 ng_rmnode_self(NG_HOOK_NODE(hook));
461 return (0);
462}
463
464/*
465 *

--- 39 unchanged lines hidden (view full) ---

505 IFNET_RLOCK();
506 TAILQ_FOREACH(ifp, &ifnet, if_link) {
507 if (ifp->if_index == if_index)
508 break;
509 }
510 IFNET_RUNLOCK();
511
512 if (ifp == NULL) {
524 printf("%s: can't find interface %d\n", __FUNCTION__, if_index);
513 printf("%s: can't find interface %d\n", __func__, if_index);
525 return (EINVAL);
526 }
527 sc->output_ifp = ifp;
528
529#if 1
530 /* XXX mucking with a drivers ifqueue size is ugly but we need it
531 * to queue a lot of packets to get close to line rate on a gigabit
532 * interface with small packets.
533 * XXX we should restore the original value at stop or disconnect
534 */
535 s = splimp(); /* XXX is this required? */
514 return (EINVAL);
515 }
516 sc->output_ifp = ifp;
517
518#if 1
519 /* XXX mucking with a drivers ifqueue size is ugly but we need it
520 * to queue a lot of packets to get close to line rate on a gigabit
521 * interface with small packets.
522 * XXX we should restore the original value at stop or disconnect
523 */
524 s = splimp(); /* XXX is this required? */
536 if (ifp->if_snd.ifq_maxlen < NG_SOURCE_DRIVER_IFQ_MAXLEN)
537 {
525 if (ifp->if_snd.ifq_maxlen < NG_SOURCE_DRIVER_IFQ_MAXLEN) {
538 printf("ng_source: changing ifq_maxlen from %d to %d\n",
539 ifp->if_snd.ifq_maxlen, NG_SOURCE_DRIVER_IFQ_MAXLEN);
540 ifp->if_snd.ifq_maxlen = NG_SOURCE_DRIVER_IFQ_MAXLEN;
541 }
542 splx(s);
543#endif
544 return (0);
545}
546
547/*
548 * Set the attached ethernet node's ethernet source address override flag.
549 */
550static int
551ng_source_set_autosrc(sc_p sc, u_int32_t flag)
552{
553 struct ng_mesg *msg;
554 int error = 0;
555
556 NG_MKMESSAGE(msg, NGM_ETHER_COOKIE, NGM_ETHER_SET_AUTOSRC,
526 printf("ng_source: changing ifq_maxlen from %d to %d\n",
527 ifp->if_snd.ifq_maxlen, NG_SOURCE_DRIVER_IFQ_MAXLEN);
528 ifp->if_snd.ifq_maxlen = NG_SOURCE_DRIVER_IFQ_MAXLEN;
529 }
530 splx(s);
531#endif
532 return (0);
533}
534
535/*
536 * Set the attached ethernet node's ethernet source address override flag.
537 */
538static int
539ng_source_set_autosrc(sc_p sc, u_int32_t flag)
540{
541 struct ng_mesg *msg;
542 int error = 0;
543
544 NG_MKMESSAGE(msg, NGM_ETHER_COOKIE, NGM_ETHER_SET_AUTOSRC,
557 sizeof (u_int32_t), M_NOWAIT);
545 sizeof (u_int32_t), M_NOWAIT);
558 if (msg == NULL)
559 return(ENOBUFS);
560
561 *(u_int32_t *)msg->data = flag;
562 NG_SEND_MSG_HOOK(error, sc->node, msg, sc->output.hook, NULL);
563 return (error);
564}
565

--- 16 unchanged lines hidden (view full) ---

582
583/*
584 * Start sending queued data out the output hook
585 */
586static void
587ng_source_start (sc_p sc)
588{
589 KASSERT(sc->output.hook != NULL,
546 if (msg == NULL)
547 return(ENOBUFS);
548
549 *(u_int32_t *)msg->data = flag;
550 NG_SEND_MSG_HOOK(error, sc->node, msg, sc->output.hook, NULL);
551 return (error);
552}
553

--- 16 unchanged lines hidden (view full) ---

570
571/*
572 * Start sending queued data out the output hook
573 */
574static void
575ng_source_start (sc_p sc)
576{
577 KASSERT(sc->output.hook != NULL,
590 ("%s: output hook unconnected", __FUNCTION__));
578 ("%s: output hook unconnected", __func__));
591 if (((sc->node->nd_flags & NG_SOURCE_ACTIVE) == 0) &&
592 (sc->output_ifp == NULL))
593 ng_source_request_output_ifp(sc);
594}
595
596/*
597 * Stop sending queued data out the output hook
598 */

--- 18 unchanged lines hidden (view full) ---

617 */
618static void
619ng_source_intr (void *arg)
620{
621 sc_p sc = (sc_p) arg;
622 struct ifqueue *ifq;
623 int packets;
624
579 if (((sc->node->nd_flags & NG_SOURCE_ACTIVE) == 0) &&
580 (sc->output_ifp == NULL))
581 ng_source_request_output_ifp(sc);
582}
583
584/*
585 * Stop sending queued data out the output hook
586 */

--- 18 unchanged lines hidden (view full) ---

605 */
606static void
607ng_source_intr (void *arg)
608{
609 sc_p sc = (sc_p) arg;
610 struct ifqueue *ifq;
611 int packets;
612
625 KASSERT(sc != NULL, ("%s: null node private", __FUNCTION__));
613 KASSERT(sc != NULL, ("%s: null node private", __func__));
626
627 callout_handle_init(&sc->intr_ch);
628 if (sc->packets == 0 || sc->output.hook == NULL
629 || (sc->node->nd_flags & NG_SOURCE_ACTIVE) == 0) {
630 ng_source_stop(sc);
631 return;
632 }
633

--- 19 unchanged lines hidden (view full) ---

653ng_source_send (sc_p sc, int tosend, int *sent_p)
654{
655 struct ifqueue tmp_queue;
656 struct mbuf *m, *m2;
657 int sent = 0;
658 int error = 0;
659 int s, s2;
660
614
615 callout_handle_init(&sc->intr_ch);
616 if (sc->packets == 0 || sc->output.hook == NULL
617 || (sc->node->nd_flags & NG_SOURCE_ACTIVE) == 0) {
618 ng_source_stop(sc);
619 return;
620 }
621

--- 19 unchanged lines hidden (view full) ---

641ng_source_send (sc_p sc, int tosend, int *sent_p)
642{
643 struct ifqueue tmp_queue;
644 struct mbuf *m, *m2;
645 int sent = 0;
646 int error = 0;
647 int s, s2;
648
661 KASSERT(sc != NULL, ("%s: null node private", __FUNCTION__));
662 KASSERT(tosend >= 0, ("%s: negative tosend param", __FUNCTION__));
649 KASSERT(sc != NULL, ("%s: null node private", __func__));
650 KASSERT(tosend >= 0, ("%s: negative tosend param", __func__));
663 KASSERT(sc->node->nd_flags & NG_SOURCE_ACTIVE,
651 KASSERT(sc->node->nd_flags & NG_SOURCE_ACTIVE,
664 ("%s: inactive node", __FUNCTION__));
652 ("%s: inactive node", __func__));
665
666 if ((u_int64_t)tosend > sc->packets)
667 tosend = sc->packets;
668
669 /* Copy the required number of packets to a temporary queue */
670 bzero (&tmp_queue, sizeof (tmp_queue));
671 for (sent = 0; error == 0 && sent < tosend; ++sent) {
672 s = splnet();

--- 48 unchanged lines hidden ---
653
654 if ((u_int64_t)tosend > sc->packets)
655 tosend = sc->packets;
656
657 /* Copy the required number of packets to a temporary queue */
658 bzero (&tmp_queue, sizeof (tmp_queue));
659 for (sent = 0; error == 0 && sent < tosend; ++sent) {
660 s = splnet();

--- 48 unchanged lines hidden ---