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 --- |