Deleted Added
sdiff udiff text old ( 167156 ) new ( 167160 )
full compact
1/*
2 * ng_source.c
3 */
4
5/*-
6 * Copyright (c) 2005 Gleb Smirnoff <glebius@FreeBSD.org>
7 * Copyright 2002 Sandvine Inc.
8 * All rights reserved.

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

34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF SANDVINE IS ADVISED OF THE POSSIBILITY OF SUCH
36 * DAMAGE.
37 *
38 * Author: Dave Chapeskie <dchapeskie@sandvine.com>
39 */
40
41#include <sys/cdefs.h>
42__FBSDID("$FreeBSD: head/sys/netgraph/ng_source.c 167156 2007-03-01 23:16:17Z emaste $");
43
44/*
45 * This node is used for high speed packet geneneration. It queues
46 * all data recieved on its 'input' hook and when told to start via
47 * a control message it sends the packets out its 'output' hook. In
48 * this way this node can be preloaded with a packet stream which it
49 * can then send continuously as fast as possible.
50 *

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

81
82/* Per node info */
83struct privdata {
84 node_p node;
85 hook_p input;
86 hook_p output;
87 struct ng_source_stats stats;
88 struct ifqueue snd_queue; /* packets to send */
89 struct ifnet *output_ifp;
90 struct callout intr_ch;
91 uint64_t packets; /* packets to send */
92 uint32_t queueOctets;
93 struct ng_source_embed_info embed_timestamp;
94};
95typedef struct privdata *sc_p;
96
97/* Node flags */
98#define NG_SOURCE_ACTIVE (NGF_TYPE1)
99
100/* Netgraph methods */
101static ng_constructor_t ng_source_constructor;

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

110static void ng_source_intr(node_p, hook_p, void *, int);
111static void ng_source_clr_data (sc_p);
112static int ng_source_start (sc_p, uint64_t);
113static void ng_source_stop (sc_p);
114static int ng_source_send (sc_p, int, int *);
115static int ng_source_store_output_ifp(sc_p, char *);
116static void ng_source_packet_mod(sc_p, struct mbuf *,
117 int, int, caddr_t, int);
118static int ng_source_dup_mod(sc_p, struct mbuf *,
119 struct mbuf **);
120
121/* Parse type for timeval */
122static const struct ng_parse_struct_field ng_source_timeval_type_fields[] = {
123 { "tv_sec", &ng_parse_int32_type },
124 { "tv_usec", &ng_parse_int32_type },
125 { NULL }

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

140/* Parse type for struct ng_source_embed_info */
141static const struct ng_parse_struct_field ng_source_embed_type_fields[] =
142 NG_SOURCE_EMBED_TYPE_INFO;
143static const struct ng_parse_type ng_source_embed_type = {
144 &ng_parse_struct_type,
145 &ng_source_embed_type_fields
146};
147
148/* List of commands and how to convert arguments to/from ASCII */
149static const struct ng_cmdlist ng_source_cmds[] = {
150 {
151 NGM_SOURCE_COOKIE,
152 NGM_SOURCE_GET_STATS,
153 "getstats",
154 NULL,
155 &ng_source_stats_type

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

212 },
213 {
214 NGM_SOURCE_COOKIE,
215 NGM_SOURCE_GET_TIMESTAMP,
216 "gettimestamp",
217 NULL,
218 &ng_source_embed_type
219 },
220 { 0 }
221};
222
223/* Netgraph type descriptor */
224static struct ng_type ng_source_typestruct = {
225 .version = NG_ABI_VERSION,
226 .name = NG_SOURCE_NODE_TYPE,
227 .constructor = ng_source_constructor,

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

421 error = ENOMEM;
422 goto done;
423 }
424 embed = (struct ng_source_embed_info *)resp->data;
425 bcopy(&sc->embed_timestamp, embed, sizeof(*embed));
426
427 break;
428 }
429 default:
430 error = EINVAL;
431 break;
432 }
433 break;
434 case NGM_ETHER_COOKIE:
435 if (!(msg->header.flags & NGF_RESP)) {
436 error = EINVAL;

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

490 return (error);
491 }
492 KASSERT(hook == sc->input, ("%s: no hook!", __func__));
493
494 /* Enqueue packet. */
495 /* XXX should we check IF_QFULL() ? */
496 _IF_ENQUEUE(&sc->snd_queue, m);
497 sc->queueOctets += m->m_pkthdr.len;
498
499 return (0);
500}
501
502/*
503 * Shutdown processing
504 */
505static int

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

595
596 for (;;) {
597 _IF_DEQUEUE(&sc->snd_queue, m);
598 if (m == NULL)
599 break;
600 NG_FREE_M(m);
601 }
602 sc->queueOctets = 0;
603}
604
605/*
606 * Start sending queued data out the output hook
607 */
608static int
609ng_source_start(sc_p sc, uint64_t packets)
610{

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

756 /* Can't modify beyond end of packet. */
757 /* TODO: Pad packet for this case. */
758 if (offset + len > m->m_len)
759 return;
760
761 bcopy(cp, mtod_off(m, offset, caddr_t), len);
762}
763
764static int
765ng_source_dup_mod(sc_p sc, struct mbuf *m0, struct mbuf **m_ptr)
766{
767 struct mbuf *m;
768 struct ng_source_embed_info *ts;
769 int modify;
770 int error = 0;
771
772 /* Are we going to modify packets? */
773 modify = sc->embed_timestamp.flags & NGM_SOURCE_EMBED_ENABLE;
774
775 /* Duplicate the packet. */
776 if (modify)
777 m = m_dup(m0, M_DONTWAIT);
778 else
779 m = m_copypacket(m0, M_DONTWAIT);
780 if (m == NULL) {
781 error = ENOBUFS;
782 goto done;
783 }
784 *m_ptr = m;
785
786 if (!modify)
787 goto done;
788
789 /* Modify the copied packet for sending. */
790 KASSERT(M_WRITABLE(m), ("%s: packet not writable", __func__));
791
792 ts = &sc->embed_timestamp;
793 if (ts->flags & NGM_SOURCE_EMBED_ENABLE) {
794 struct timeval now;
795 getmicrotime(&now);
796 now.tv_sec = htonl(now.tv_sec);
797 now.tv_usec = htonl(now.tv_usec);
798 ng_source_packet_mod(sc, m, ts->offset, sizeof (now),
799 (caddr_t)&now, ts->flags);
800 }
801
802done:
803 return(error);
804}