Deleted Added
full compact
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,
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
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
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
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,
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 $
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 */
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 */
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;
288 if ((sc->node->flags & NG_SOURCE_ACTIVE)
289 && !timevalisset(&sc->stats.endTime)) {
302
303getmicrotime(&sc->stats.elapsedTime);
290 getmicrotime(&sc->stats.elapsedTime);
291 timevalsub(&sc->stats.elapsedTime,
305
306&sc->stats.startTime);
292 &sc->stats.startTime);
293 }
308 stats = (struct ng_source_stats
309*)resp->data;
294 stats = (struct ng_source_stats *)resp->data;
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__);
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;
351 int error = 0;
352
353 hinfo = (struct source_hookinfo *) hook->private;
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;
410
411 hinfo = (struct source_hookinfo *) hook->private;
412 sc = (sc_p) hinfo->hook->node->private;
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);
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);
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);
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)
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);
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 ---