64#include <sys/kernel.h>
65#include <sys/malloc.h>
67#include <sys/socket.h>
68#include <sys/syslog.h>
70#include <net/if_var.h>
77#define NG_SOURCE_INTR_TICKS 1
78#define NG_SOURCE_DRIVER_IFQ_MAXLEN (4*1024)
80#define mtod_off(m,off,t) ((t)(mtod((m),caddr_t)+(off)))
100#define NG_SOURCE_ACTIVE (NGF_TYPE1)
119 int,
int, caddr_t,
int);
122 struct mbuf *m,
int increment);
283 sc = malloc(
sizeof(*sc), M_NETGRAPH, M_WAITOK | M_ZERO);
287 mbufq_init(&sc->snd_queue, 2048);
305 sc->output_ifp = NULL;
327 if (hook == sc->output) {
351 struct ng_mesg *msg, *resp = NULL;
371 sizeof(*
stats), M_NOWAIT);
376 sc->
stats.queueOctets = sc->queueOctets;
377 sc->
stats.queueFrames = mbufq_len(&sc->snd_queue);
379 && !timevalisset(&sc->
stats.endTime)) {
380 getmicrotime(&sc->
stats.elapsedTime);
381 timevalsub(&sc->
stats.elapsedTime,
382 &sc->
stats.startTime);
414 char *ifname = (
char *)msg->
data;
433 pps = *(uint32_t *)msg->
data;
435 sc->
stats.maxPps = pps;
448 bcopy(embed, &sc->embed_timestamp,
sizeof(*embed));
462 bcopy(&sc->embed_timestamp, embed,
sizeof(*embed));
477 embed->
width == 4)) {
481 bcopy(embed, &sc->embed_counter[embed->
index],
501 bcopy(&sc->embed_counter[
index], embed,
sizeof(*embed));
518 char *ifname = (
char *)msg->
data;
563 if (hook == sc->output) {
568 KASSERT(hook == sc->input, (
"%s: no hook!", __func__));
571 error = mbufq_enqueue(&sc->snd_queue, m);
576 sc->queueOctets += m->m_pkthdr.len;
594 free(sc, M_NETGRAPH);
608 KASSERT(sc != NULL, (
"%s: null node private", __func__));
623 ifp = ifunit(ifname);
626 printf(
"%s: can't find interface %s\n", __func__, ifname);
629 sc->output_ifp = ifp;
638 printf(
"ng_source: changing ifq_maxlen from %d to %d\n",
656 sizeof (uint32_t), M_NOWAIT);
660 *(uint32_t *)msg->
data = flag;
674 m = mbufq_dequeue(&sc->snd_queue);
680 sc->last_packet = NULL;
689 if (sc->output_ifp == NULL && sc->
stats.maxPps == 0) {
690 printf(
"ng_source: start without iface or pps configured\n");
700 timevalclear(&sc->
stats.elapsedTime);
701 timevalclear(&sc->
stats.endTime);
702 getmicrotime(&sc->
stats.startTime);
703 getmicrotime(&sc->
stats.lastTime);
718 getmicrotime(&sc->
stats.endTime);
720 timevalsub(&sc->
stats.elapsedTime, &sc->
stats.startTime);
735 KASSERT(sc != NULL, (
"%s: null node private", __func__));
737 if (sc->packets == 0 || sc->output == NULL
743 if (sc->output_ifp != NULL) {
744 ifq = (
struct ifqueue *)&sc->output_ifp->if_snd;
745 packets = ifq->ifq_maxlen - ifq->ifq_len;
747 packets = mbufq_len(&sc->snd_queue);
749 if (sc->
stats.maxPps != 0) {
750 struct timeval now, elapsed;
756 timevalsub(&elapsed, &sc->
stats.lastTime);
757 usec = elapsed.tv_sec * 1000000 + elapsed.tv_usec;
758 maxpkt = (uint64_t)sc->
stats.maxPps * usec / 1000000;
759 sc->
stats.lastTime = now;
765 if (sc->packets == 0)
782 KASSERT(tosend >= 0, (
"%s: negative tosend param", __func__));
784 (
"%s: inactive node", __func__));
786 if ((uint64_t)tosend > sc->packets)
787 tosend = sc->packets;
790 for (sent = 0; error == 0 && sent < tosend; ++sent) {
791 m = mbufq_dequeue(&sc->snd_queue);
798 if (error == ENOBUFS)
799 mbufq_prepend(&sc->snd_queue, m);
801 (
void)mbufq_enqueue(&sc->snd_queue, m);
811 error = mbufq_enqueue(&sc->snd_queue, m);
812 KASSERT(error == 0, (
"%s: re-enqueue packet failed", __func__));
814 sc->
stats.outFrames++;
815 sc->
stats.outOctets += m2->m_pkthdr.len;
842 if (offset + len > m->m_len)
845 bcopy(cp,
mtod_off(m, offset, caddr_t), len);
850 struct mbuf *m,
int increment)
856 cp = (caddr_t)&val +
sizeof(val) - cnt->
width;
867 }
else if (increment < 0 && cnt->next_val < cnt->min_val) {
893 m = m_dup(m0, M_NOWAIT);
895 m = m_copypacket(m0, M_NOWAIT);
906 KASSERT(M_WRITABLE(m), (
"%s: packet not writable", __func__));
909 cnt = &sc->embed_counter[i];
912 sc->last_packet == m0)
920 ts = &sc->embed_timestamp;
924 now.tv_sec = htonl(now.tv_sec);
925 now.tv_usec = htonl(now.tv_usec);
927 (caddr_t)&now, ts->
flags);
int ng_connect_t(hook_p hook)
#define NG_HOOK_NODE(hook)
#define NG_PEER_NODE(hook)
int ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook)
int ng_disconnect_t(hook_p hook)
#define NG_NODE_SET_PRIVATE(node, val)
#define NG_RESPOND_MSG(error, here, item, resp)
#define NG_NODE_UNREF(node)
int ng_rmnode_self(node_p here)
#define ng_callout_init(c)
#define NG_SEND_DATA_ONLY(error, hook, m)
#define NG_SEND_MSG_ID(error, here, msg, ID, retaddr)
int ng_rcvdata_t(hook_p hook, item_p item)
int ng_shutdown_t(node_p node)
int ng_uncallout(struct callout *c, node_p node)
#define NG_FREE_ITEM(item)
int ng_constructor_t(node_p node)
#define NG_NODE_NUMHOOKS(node)
#define NGI_GET_MSG(i, m)
#define NG_NODE_PRIVATE(node)
#define NG_SEND_MSG_HOOK(error, here, msg, hook, retaddr)
int ng_callout(struct callout *c, node_p node, hook_p hook, int ticks, ng_item_fn *fn, void *arg1, int arg2)
int ng_newhook_t(node_p node, hook_p hook, const char *name)
#define NG_MKRESPONSE(rsp, msg, len, how)
#define NG_MKMESSAGE(msg, cookie, cmdid, len, how)
const struct ng_parse_type ng_parse_int32_type
const struct ng_parse_type ng_parse_uint64_type
const struct ng_parse_type ng_parse_string_type
const struct ng_parse_type ng_parse_struct_type
const struct ng_parse_type ng_parse_uint32_type
const struct ng_parse_type ng_parse_int64_type
const struct ng_parse_type ng_parse_uint8_type
static ng_rcvdata_t ng_source_rcvdata
static int ng_source_send(sc_p, int, int *)
static ng_newhook_t ng_source_newhook
NETGRAPH_INIT(source, &ng_source_typestruct)
static const struct ng_parse_struct_field ng_source_embed_type_fields[]
static void ng_source_stop(sc_p)
static const struct ng_parse_type ng_source_embed_type
static int ng_source_set_autosrc(sc_p, uint32_t)
static const struct ng_cmdlist ng_source_cmds[]
static int ng_source_dup_mod(sc_p, struct mbuf *, struct mbuf **)
static void ng_source_clr_data(sc_p)
static struct ng_type ng_source_typestruct
static const struct ng_parse_struct_field ng_source_stats_type_fields[]
static void ng_source_intr(node_p, hook_p, void *, int)
static ng_constructor_t ng_source_constructor
#define NG_SOURCE_DRIVER_IFQ_MAXLEN
static const struct ng_parse_type ng_source_embed_cnt_type
#define mtod_off(m, off, t)
const struct ng_parse_type ng_source_timeval_type
static int ng_source_store_output_ifp(sc_p, char *)
static const struct ng_parse_struct_field ng_source_embed_cnt_type_fields[]
static void ng_source_mod_counter(sc_p sc, struct ng_source_embed_cnt_info *cnt, struct mbuf *m, int increment)
static void ng_source_packet_mod(sc_p, struct mbuf *, int, int, caddr_t, int)
static ng_disconnect_t ng_source_disconnect
static ng_rcvmsg_t ng_source_rcvmsg
static const struct ng_parse_struct_field ng_source_timeval_type_fields[]
static const struct ng_parse_type ng_source_stats_type
static ng_connect_t ng_source_connect
#define NG_SOURCE_INTR_TICKS
static ng_shutdown_t ng_source_rmnode
static int ng_source_start(sc_p, uint64_t)
#define NGM_SOURCE_INC_CNT_PER_LIST
#define NG_SOURCE_HOOK_INPUT
#define NG_SOURCE_NODE_TYPE
#define NG_SOURCE_COUNTERS
#define NGM_SOURCE_EMBED_ENABLE
#define NG_SOURCE_HOOK_OUTPUT
@ NGM_SOURCE_GETCLR_STATS
@ NGM_SOURCE_SET_TIMESTAMP
@ NGM_SOURCE_GET_TIMESTAMP
#define NG_SOURCE_EMBED_CNT_TYPE_INFO
#define NG_SOURCE_EMBED_TYPE_INFO
#define NGM_SOURCE_COOKIE
#define NG_SOURCE_STATS_TYPE_INFO
struct ng_async_stat stats
struct ng_mesg::ng_msghdr header
struct ng_source_embed_cnt_info embed_counter[NG_SOURCE_COUNTERS]
struct ng_source_embed_info embed_timestamp
struct mbuf * last_packet
struct ifnet * output_ifp