Deleted Added
full compact
ng_source.c (106266) ng_source.c (106319)
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
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
9 * without modifications are expressly permitted by Sandvine Inc.;
10provided,
9 * without modifications are expressly permitted by Sandvine Inc.; provided,
11 * however, that:
10 * however, that:
12 * 1. Any and all reproductions of the source or object code must include
13the
14 * copyright notice above and the following disclaimer of warranties;
15and
11 * 1. Any and all reproductions of the source or object code must include the
12 * copyright notice above and the following disclaimer of warranties; and
16 * 2. No rights are granted, in any manner or form, to use Sandvine Inc.
13 * 2. No rights are granted, in any manner or form, to use Sandvine Inc.
17 * trademarks, including the mark "SANDVINE" on advertising,
18endorsements,
19 * or otherwise except as such appears in the above copyright notice or
20in
14 * trademarks, including the mark "SANDVINE" on advertising, endorsements,
15 * or otherwise except as such appears in the above copyright notice or in
21 * the software.
22 *
23 * THIS SOFTWARE IS BEING PROVIDED BY SANDVINE "AS IS", AND TO THE MAXIMUM
16 * the software.
17 *
18 * THIS SOFTWARE IS BEING PROVIDED BY SANDVINE "AS IS", AND TO THE MAXIMUM
24 * EXTENT PERMITTED BY LAW, SANDVINE MAKES NO REPRESENTATIONS OR
25WARRANTIES,
26 * EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, INCLUDING WITHOUT
27LIMITATION,
28 * ANY AND ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
29PARTICULAR
19 * EXTENT PERMITTED BY LAW, SANDVINE MAKES NO REPRESENTATIONS OR WARRANTIES,
20 * EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, INCLUDING WITHOUT LIMITATION,
21 * ANY AND ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
30 * PURPOSE, OR NON-INFRINGEMENT. SANDVINE DOES NOT WARRANT, GUARANTEE, OR
31 * MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE
32 * USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY
33 * OR OTHERWISE. IN NO EVENT SHALL SANDVINE BE LIABLE FOR ANY DAMAGES
34 * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
22 * PURPOSE, OR NON-INFRINGEMENT. SANDVINE DOES NOT WARRANT, GUARANTEE, OR
23 * MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE
24 * USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY
25 * OR OTHERWISE. IN NO EVENT SHALL SANDVINE BE LIABLE FOR ANY DAMAGES
26 * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
35 * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
36EXEMPLARY,
27 * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
37 * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
38 * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
39 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
41 * THIS SOFTWARE, EVEN IF SANDVINE IS ADVISED OF THE POSSIBILITY OF SUCH
42 * DAMAGE.
43 *
44 * Author: Dave Chapeskie <dchapeskie@sandvine.com>
45 *
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 *
46 * $FreeBSD: head/sys/netgraph/ng_source.c 106266 2002-10-31 23:03:09Z julian $
37 * $FreeBSD: head/sys/netgraph/ng_source.c 106319 2002-11-02 01:26:28Z julian $
47 */
48
49/*
50 * This node is used for high speed packet geneneration. It queues
51 * all data recieved on it's 'input' hook and when told to start via
52 * a control message it sends the packets out it's 'output' hook. In
53 * this way this node can be preloaded with a packet stream which is
54 * continuously sent.

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

88};
89
90/* Per node info */
91struct privdata {
92 node_p node;
93 struct source_hookinfo input;
94 struct source_hookinfo output;
95 struct ng_source_stats stats;
38 */
39
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.

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

79};
80
81/* Per node info */
82struct privdata {
83 node_p node;
84 struct source_hookinfo input;
85 struct source_hookinfo output;
86 struct ng_source_stats stats;
96 struct ifqueue snd_queue; /* packets to send
97*/
87 struct ifqueue snd_queue; /* packets to send */
98 struct ifnet *output_ifp;
99 struct callout_handle intr_ch;
88 struct ifnet *output_ifp;
89 struct callout_handle intr_ch;
100 u_int64_t packets; /* packets to send
101*/
90 u_int64_t packets; /* packets to send */
102 u_int32_t queueOctets;
103};
104typedef struct privdata *sc_p;
105
106/* Node flags */
107#define NG_SOURCE_ACTIVE (NGF_TYPE1)
108
109/* XXX */

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

290 if (msg->header.cmd != NGM_SOURCE_CLR_STATS) {
291 NG_MKRESPONSE(resp, msg,
292 sizeof(*stats), M_NOWAIT);
293 if (resp == NULL) {
294 error = ENOMEM;
295 goto done;
296 }
297 sc->stats.queueOctets = sc->queueOctets;
91 u_int32_t queueOctets;
92};
93typedef struct privdata *sc_p;
94
95/* Node flags */
96#define NG_SOURCE_ACTIVE (NGF_TYPE1)
97
98/* XXX */

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

279 if (msg->header.cmd != NGM_SOURCE_CLR_STATS) {
280 NG_MKRESPONSE(resp, msg,
281 sizeof(*stats), M_NOWAIT);
282 if (resp == NULL) {
283 error = ENOMEM;
284 goto done;
285 }
286 sc->stats.queueOctets = sc->queueOctets;
298 sc->stats.queueFrames =
299sc->snd_queue.ifq_len;
287 sc->stats.queueFrames = sc->snd_queue.ifq_len;
300 if ((sc->node->flags & NG_SOURCE_ACTIVE)
301 && !timevalisset(&sc->stats.endTime)) {
288 if ((sc->node->flags & NG_SOURCE_ACTIVE)
289 && !timevalisset(&sc->stats.endTime)) {
302
303getmicrotime(&sc->stats.elapsedTime);
290 getmicrotime(&sc->stats.elapsedTime);
304 timevalsub(&sc->stats.elapsedTime,
291 timevalsub(&sc->stats.elapsedTime,
305
306&sc->stats.startTime);
292 &sc->stats.startTime);
307 }
293 }
308 stats = (struct ng_source_stats
309*)resp->data;
294 stats = (struct ng_source_stats *)resp->data;
310 bcopy(&sc->stats, stats, sizeof(* stats));
311 }
312 if (msg->header.cmd != NGM_SOURCE_GET_STATS)
313 bzero(&sc->stats, sizeof(sc->stats));
314 }
315 break;
316 case NGM_SOURCE_START:
317 {
318 u_int64_t packets = *(u_int64_t *)msg->data;
319 if (sc->output.hook == NULL) {
295 bcopy(&sc->stats, stats, sizeof(* stats));
296 }
297 if (msg->header.cmd != NGM_SOURCE_GET_STATS)
298 bzero(&sc->stats, sizeof(sc->stats));
299 }
300 break;
301 case NGM_SOURCE_START:
302 {
303 u_int64_t packets = *(u_int64_t *)msg->data;
304 if (sc->output.hook == NULL) {
320 printf("%s: start on node with no output
321hook\n", __FUNCTION__);
305 printf("%s: start on node with no output hook\n"
306 , __FUNCTION__);
322 error = EINVAL;
323 break;
324 }
325 /* TODO validation of packets */
326 sc->packets = packets;
327 ng_source_start(sc);
328 }
329 break;

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

357 *
358 * If data comes in the input hook, enqueue it on the send queue.
359 * If data comes in the output hook, discard it.
360 */
361static int
362ng_source_rcvdata(hook_p hook, struct mbuf *m, meta_p meta)
363{
364 const sc_p sc = hook->node->private;
307 error = EINVAL;
308 break;
309 }
310 /* TODO validation of packets */
311 sc->packets = packets;
312 ng_source_start(sc);
313 }
314 break;

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

342 *
343 * If data comes in the input hook, enqueue it on the send queue.
344 * If data comes in the output hook, discard it.
345 */
346static int
347ng_source_rcvdata(hook_p hook, struct mbuf *m, meta_p meta)
348{
349 const sc_p sc = hook->node->private;
365 struct source_hookinfo *const hinfo = (struct source_hookinfo *)
366hook->private;
350 struct source_hookinfo *const hinfo;
367 int error = 0;
368
351 int error = 0;
352
353 hinfo = (struct source_hookinfo *) hook->private;
369 KASSERT(sc != NULL, ("%s: null node private", __FUNCTION__));
370 KASSERT(hinfo != NULL, ("%s: null hook info", __FUNCTION__));
371
372 /* Which hook? */
373 if (hinfo == &sc->output) {
374 /* discard */
375 NG_FREE_DATA(m, meta);
376 return (error);

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

415}
416
417/*
418 * Hook disconnection
419 */
420static int
421ng_source_disconnect(hook_p hook)
422{
354 KASSERT(sc != NULL, ("%s: null node private", __FUNCTION__));
355 KASSERT(hinfo != NULL, ("%s: null hook info", __FUNCTION__));
356
357 /* Which hook? */
358 if (hinfo == &sc->output) {
359 /* discard */
360 NG_FREE_DATA(m, meta);
361 return (error);

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

400}
401
402/*
403 * Hook disconnection
404 */
405static int
406ng_source_disconnect(hook_p hook)
407{
423 struct source_hookinfo *const hinfo = (struct source_hookinfo *)
424hook->private;
425 sc_p sc = (sc_p) hinfo->hook->node->private;
408 struct source_hookinfo *const hinfo;
409 sc_p sc;
426
410
411 hinfo = (struct source_hookinfo *) hook->private;
412 sc = (sc_p) hinfo->hook->node->private;
427 KASSERT(sc != NULL, ("%s: null node private", __FUNCTION__));
428 hinfo->hook = NULL;
429 if (hook->node->numhooks == 0 || hinfo == &sc->output)
430 ng_rmnode(hook->node);
431 return (0);
432}
433
434/*

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

442 struct ifnet *ifp;
443 u_int32_t if_index;
444 int error = 0;
445 int s;
446
447 sc->output_ifp = NULL;
448
449 /* Ask the attached node for the connected interface's index */
413 KASSERT(sc != NULL, ("%s: null node private", __FUNCTION__));
414 hinfo->hook = NULL;
415 if (hook->node->numhooks == 0 || hinfo == &sc->output)
416 ng_rmnode(hook->node);
417 return (0);
418}
419
420/*

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

428 struct ifnet *ifp;
429 u_int32_t if_index;
430 int error = 0;
431 int s;
432
433 sc->output_ifp = NULL;
434
435 /* Ask the attached node for the connected interface's index */
450 NG_MKMESSAGE(msg, NGM_ETHER_COOKIE, NGM_ETHER_GET_IFINDEX, 0,
451M_NOWAIT);
436 NG_MKMESSAGE(msg, NGM_ETHER_COOKIE, NGM_ETHER_GET_IFINDEX, 0, M_NOWAIT);
452 if (msg == NULL)
453 return (ENOBUFS);
454
455 error = ng_send_msg(sc->node, msg, NG_SOURCE_HOOK_OUTPUT, &rsp);
456 if (error != 0)
457 return (error);
458
459 if (rsp == NULL)

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

468 * local to if_attach()
469 */
470 TAILQ_FOREACH(ifp, &ifnet, if_link) {
471 if (ifp->if_index == if_index)
472 break;
473 }
474
475 if (ifp == NULL) {
437 if (msg == NULL)
438 return (ENOBUFS);
439
440 error = ng_send_msg(sc->node, msg, NG_SOURCE_HOOK_OUTPUT, &rsp);
441 if (error != 0)
442 return (error);
443
444 if (rsp == NULL)

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

453 * local to if_attach()
454 */
455 TAILQ_FOREACH(ifp, &ifnet, if_link) {
456 if (ifp->if_index == if_index)
457 break;
458 }
459
460 if (ifp == NULL) {
476 printf("%s: can't find interface %d\n", __FUNCTION__,
477if_index);
461 printf("%s: can't find interface %d\n", __FUNCTION__, if_index);
478 return (EINVAL);
479 }
480 sc->output_ifp = ifp;
481
482#if 1
483 /* XXX mucking with a drivers ifqueue size is ugly but we need it
484 * to queue a lot of packets to get close to line rate on a gigabit
485 * interface with small packets.
486 * XXX we should restore the original value at stop or disconnect
487 */
488 s = splimp(); /* XXX is this required? */
489 if (ifp->if_snd.ifq_maxlen < NG_SOURCE_DRIVER_IFQ_MAXLEN)
490 {
491 printf("ng_source: changing ifq_maxlen from %d to %d\n",
462 return (EINVAL);
463 }
464 sc->output_ifp = ifp;
465
466#if 1
467 /* XXX mucking with a drivers ifqueue size is ugly but we need it
468 * to queue a lot of packets to get close to line rate on a gigabit
469 * interface with small packets.
470 * XXX we should restore the original value at stop or disconnect
471 */
472 s = splimp(); /* XXX is this required? */
473 if (ifp->if_snd.ifq_maxlen < NG_SOURCE_DRIVER_IFQ_MAXLEN)
474 {
475 printf("ng_source: changing ifq_maxlen from %d to %d\n",
492 ifp->if_snd.ifq_maxlen,
493NG_SOURCE_DRIVER_IFQ_MAXLEN);
476 ifp->if_snd.ifq_maxlen, NG_SOURCE_DRIVER_IFQ_MAXLEN);
494 ifp->if_snd.ifq_maxlen = NG_SOURCE_DRIVER_IFQ_MAXLEN;
495 }
496 splx(s);
497#endif
498 return (0);
499}
500
501/*

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

540 */
541static void
542ng_source_start (sc_p sc)
543{
544 SPLASSERT(net, __FUNCTION__);
545 KASSERT(sc->output.hook != NULL,
546 ("%s: output hook unconnected", __FUNCTION__));
547 if ((sc->node->flags & NG_SOURCE_ACTIVE) == 0) {
477 ifp->if_snd.ifq_maxlen = NG_SOURCE_DRIVER_IFQ_MAXLEN;
478 }
479 splx(s);
480#endif
481 return (0);
482}
483
484/*

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

523 */
524static void
525ng_source_start (sc_p sc)
526{
527 SPLASSERT(net, __FUNCTION__);
528 KASSERT(sc->output.hook != NULL,
529 ("%s: output hook unconnected", __FUNCTION__));
530 if ((sc->node->flags & NG_SOURCE_ACTIVE) == 0) {
548 if (sc->output_ifp == NULL && ng_source_get_output_ifp(sc)
549!= 0)
531 if (sc->output_ifp == NULL && ng_source_get_output_ifp(sc) != 0)
550 return;
551 ng_source_set_autosrc(sc, 0);
552 sc->node->flags |= NG_SOURCE_ACTIVE;
553 timevalclear(&sc->stats.elapsedTime);
554 timevalclear(&sc->stats.endTime);
555 getmicrotime(&sc->stats.startTime);
556 sc->intr_ch = timeout(ng_source_intr, sc, 0);
557 }

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

599 ifq = &sc->output_ifp->if_snd;
600 packets = ifq->ifq_maxlen - ifq->ifq_len;
601 ng_source_send(sc, packets, NULL);
602 if (sc->packets == 0) {
603 int s = splnet();
604 ng_source_stop(sc);
605 splx(s);
606 } else
532 return;
533 ng_source_set_autosrc(sc, 0);
534 sc->node->flags |= NG_SOURCE_ACTIVE;
535 timevalclear(&sc->stats.elapsedTime);
536 timevalclear(&sc->stats.endTime);
537 getmicrotime(&sc->stats.startTime);
538 sc->intr_ch = timeout(ng_source_intr, sc, 0);
539 }

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

581 ifq = &sc->output_ifp->if_snd;
582 packets = ifq->ifq_maxlen - ifq->ifq_len;
583 ng_source_send(sc, packets, NULL);
584 if (sc->packets == 0) {
585 int s = splnet();
586 ng_source_stop(sc);
587 splx(s);
588 } else
607 sc->intr_ch = timeout(ng_source_intr, sc,
608NG_SOURCE_INTR_TICKS);
589 sc->intr_ch = timeout(ng_source_intr, sc, NG_SOURCE_INTR_TICKS);
609}
610
611/*
612 * Send packets out our output hook
613 */
614static int
615ng_source_send (sc_p sc, int tosend, int *sent_p)
616{

--- 66 unchanged lines hidden ---
590}
591
592/*
593 * Send packets out our output hook
594 */
595static int
596ng_source_send (sc_p sc, int tosend, int *sent_p)
597{

--- 66 unchanged lines hidden ---