Implement minimalistic L2TP sessions statistics and correct man page
for L2TP tunnel statistics (which do not take an argument sessionID). Reviewed by: archie Approved by: pjd (mentor)
This commit is contained in:
parent
30d8b6d6ad
commit
5b63f751da
@ -261,18 +261,28 @@ the current configuration for the corresponding data session as a
|
||||
.Vt "struct ng_l2tp_sess_config" .
|
||||
The corresponding session hook must be connected.
|
||||
.It Dv NGM_L2TP_GET_STATS
|
||||
This command takes a two byte session ID as an argument and returns a
|
||||
This command returns a
|
||||
.Vt "struct ng_l2tp_stats"
|
||||
containing statistics for the corresponding data session.
|
||||
The corresponding session hook must be connected.
|
||||
containing statistics of the L2TP tunnel.
|
||||
.It Dv NGM_L2TP_CLR_STATS
|
||||
This command takes a two byte session ID as an argument and
|
||||
clears the statistics for that data session.
|
||||
The corresponding session hook must be connected.
|
||||
This command clears the statistics for the L2TP tunnel.
|
||||
.It Dv NGM_L2TP_GETCLR_STATS
|
||||
Same as
|
||||
.Dv NGM_L2TP_GET_STATS ,
|
||||
but also atomically clears the statistics as well.
|
||||
.It Dv NGM_L2TP_GET_SESSION_STATS
|
||||
This command takes a two byte session ID as an argument and returns a
|
||||
.Vt "struct ng_l2tp_session_stats"
|
||||
containing statistics for the corresponding data session.
|
||||
The corresponding session hook must be connected.
|
||||
.It Dv NGM_L2TP_CLR_SESSION_STATS
|
||||
This command takes a two byte session ID as an argument and
|
||||
clears the statistics for that data session.
|
||||
The corresponding session hook must be connected.
|
||||
.It Dv NGM_L2TP_GETCLR_SESSION_STATS
|
||||
Same as
|
||||
.Dv NGM_L2TP_GET_SESSION_STATS ,
|
||||
but also atomically clears the statistics as well.
|
||||
.It Dv NGM_L2TP_SET_SEQ
|
||||
This command sets the sequence numbers of a not yet enabled node.
|
||||
It takes a
|
||||
|
@ -150,6 +150,7 @@ typedef struct ng_l2tp_private *priv_p;
|
||||
/* Hook private data (data session hooks only) */
|
||||
struct ng_l2tp_hook_private {
|
||||
struct ng_l2tp_sess_config conf; /* hook/session config */
|
||||
struct ng_l2tp_session_stats stats; /* per sessions statistics */
|
||||
u_int16_t ns; /* data ns sequence number */
|
||||
u_int16_t nr; /* data nr sequence number */
|
||||
};
|
||||
@ -221,6 +222,14 @@ static const struct ng_parse_type ng_l2tp_stats_type = {
|
||||
&ng_l2tp_stats_type_fields
|
||||
};
|
||||
|
||||
/* Parse type for struct ng_l2tp_session_stats. */
|
||||
static const struct ng_parse_struct_field
|
||||
ng_l2tp_session_stats_type_fields[] = NG_L2TP_SESSION_STATS_TYPE_INFO;
|
||||
static const struct ng_parse_type ng_l2tp_session_stats_type = {
|
||||
&ng_parse_struct_type,
|
||||
&ng_l2tp_session_stats_type_fields
|
||||
};
|
||||
|
||||
/* List of commands and how to convert arguments to/from ASCII */
|
||||
static const struct ng_cmdlist ng_l2tp_cmdlist[] = {
|
||||
{
|
||||
@ -272,6 +281,27 @@ static const struct ng_cmdlist ng_l2tp_cmdlist[] = {
|
||||
NULL,
|
||||
&ng_l2tp_stats_type
|
||||
},
|
||||
{
|
||||
NGM_L2TP_COOKIE,
|
||||
NGM_L2TP_GET_SESSION_STATS,
|
||||
"getsessstats",
|
||||
&ng_parse_int16_type,
|
||||
&ng_l2tp_session_stats_type
|
||||
},
|
||||
{
|
||||
NGM_L2TP_COOKIE,
|
||||
NGM_L2TP_CLR_SESSION_STATS,
|
||||
"clrsessstats",
|
||||
&ng_parse_int16_type,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
NGM_L2TP_COOKIE,
|
||||
NGM_L2TP_GETCLR_SESSION_STATS,
|
||||
"getclrsessstats",
|
||||
&ng_parse_int16_type,
|
||||
&ng_l2tp_session_stats_type
|
||||
},
|
||||
{
|
||||
NGM_L2TP_COOKIE,
|
||||
NGM_L2TP_ACK_FAILURE,
|
||||
@ -553,6 +583,45 @@ ng_l2tp_rcvmsg(node_p node, item_p item, hook_p lasthook)
|
||||
memset(&priv->stats, 0, sizeof(priv->stats));
|
||||
break;
|
||||
}
|
||||
case NGM_L2TP_GET_SESSION_STATS:
|
||||
case NGM_L2TP_CLR_SESSION_STATS:
|
||||
case NGM_L2TP_GETCLR_SESSION_STATS:
|
||||
{
|
||||
uint16_t session_id;
|
||||
hookpriv_p hpriv;
|
||||
hook_p hook;
|
||||
|
||||
/* Get session ID. */
|
||||
if (msg->header.arglen != sizeof(session_id)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
bcopy(msg->data, &session_id, sizeof(uint16_t));
|
||||
session_id = htons(session_id);
|
||||
|
||||
/* Find matching hook. */
|
||||
NG_NODE_FOREACH_HOOK(node, ng_l2tp_find_session,
|
||||
(void *)(uintptr_t)session_id, hook);
|
||||
if (hook == NULL) {
|
||||
error = ENOENT;
|
||||
break;
|
||||
}
|
||||
hpriv = NG_HOOK_PRIVATE(hook);
|
||||
|
||||
if (msg->header.cmd != NGM_L2TP_CLR_SESSION_STATS) {
|
||||
NG_MKRESPONSE(resp, msg,
|
||||
sizeof(hpriv->stats), M_NOWAIT);
|
||||
if (resp == NULL) {
|
||||
error = ENOMEM;
|
||||
break;
|
||||
}
|
||||
bcopy(&hpriv->stats, resp->data,
|
||||
sizeof(hpriv->stats));
|
||||
}
|
||||
if (msg->header.cmd != NGM_L2TP_GET_SESSION_STATS)
|
||||
bzero(&hpriv->stats, sizeof(hpriv->stats));
|
||||
break;
|
||||
}
|
||||
case NGM_L2TP_SET_SEQ:
|
||||
{
|
||||
struct ng_l2tp_seq_config *const conf =
|
||||
@ -708,6 +777,7 @@ ng_l2tp_reset_session(hook_p hook, void *arg)
|
||||
if (hpriv != NULL) {
|
||||
hpriv->conf.control_dseq = 0;
|
||||
hpriv->conf.enable_dseq = 0;
|
||||
bzero(&hpriv->conf, sizeof(struct ng_l2tp_session_stats));
|
||||
hpriv->nr = 0;
|
||||
hpriv->ns = 0;
|
||||
}
|
||||
@ -734,14 +804,17 @@ ng_l2tp_recv_lower(node_p node, item_p item)
|
||||
u_int16_t nr;
|
||||
int is_ctrl;
|
||||
int error;
|
||||
int len;
|
||||
int len, plen;
|
||||
|
||||
/* Grab mbuf */
|
||||
NGI_GET_M(item, m);
|
||||
|
||||
/* Remember full packet length; needed for per session accounting. */
|
||||
plen = m->m_pkthdr.len;
|
||||
|
||||
/* Update stats */
|
||||
priv->stats.recvPackets++;
|
||||
priv->stats.recvOctets += m->m_pkthdr.len;
|
||||
priv->stats.recvOctets += plen;
|
||||
|
||||
/* Get initial header */
|
||||
if (m->m_pkthdr.len < 6) {
|
||||
@ -904,6 +977,10 @@ ng_l2tp_recv_lower(node_p node, item_p item)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* Per session packet, account it. */
|
||||
hpriv->stats.recvPackets++;
|
||||
hpriv->stats.recvOctets += plen;
|
||||
|
||||
/* Follow peer's lead in data sequencing, if configured to do so */
|
||||
if (!hpriv->conf.control_dseq)
|
||||
hpriv->conf.enable_dseq = ((hdr & L2TP_HDR_SEQ) != 0);
|
||||
@ -1045,6 +1122,10 @@ ng_l2tp_recv_data(node_p node, item_p item, hookpriv_p hpriv)
|
||||
}
|
||||
mtod(m, u_int16_t *)[0] = htons(hdr);
|
||||
|
||||
/* Update per session stats. */
|
||||
hpriv->stats.xmitPackets++;
|
||||
hpriv->stats.xmitOctets += m->m_pkthdr.len;
|
||||
|
||||
/* Send packet */
|
||||
NG_FWD_NEW_DATA(error, item, priv->lower, m);
|
||||
return (error);
|
||||
|
@ -45,7 +45,7 @@
|
||||
|
||||
/* Node type name and magic cookie */
|
||||
#define NG_L2TP_NODE_TYPE "l2tp"
|
||||
#define NGM_L2TP_COOKIE 1091448040
|
||||
#define NGM_L2TP_COOKIE 1091515793
|
||||
|
||||
/* Hook names */
|
||||
#define NG_L2TP_HOOK_CTRL "ctrl" /* control channel hook */
|
||||
@ -161,6 +161,23 @@ struct ng_l2tp_stats {
|
||||
{ NULL } \
|
||||
}
|
||||
|
||||
/* Session statistics struct. */
|
||||
struct ng_l2tp_session_stats {
|
||||
u_int64_t xmitPackets; /* number of packets xmit */
|
||||
u_int64_t xmitOctets; /* number of octets xmit */
|
||||
u_int64_t recvPackets; /* number of packets received */
|
||||
u_int64_t recvOctets; /* number of octets received */
|
||||
};
|
||||
|
||||
/* Keep this in sync with the above structure definition. */
|
||||
#define NG_L2TP_SESSION_STATS_TYPE_INFO { \
|
||||
{ "xmitPackets", &ng_parse_uint64_type }, \
|
||||
{ "xmitOctets", &ng_parse_uint64_type }, \
|
||||
{ "recvPackets", &ng_parse_uint64_type }, \
|
||||
{ "recvOctets", &ng_parse_uint64_type }, \
|
||||
{ NULL } \
|
||||
}
|
||||
|
||||
/* Netgraph commands */
|
||||
enum {
|
||||
NGM_L2TP_SET_CONFIG = 1, /* supply a struct ng_l2tp_config */
|
||||
@ -170,6 +187,9 @@ enum {
|
||||
NGM_L2TP_GET_STATS, /* returns struct ng_l2tp_stats */
|
||||
NGM_L2TP_CLR_STATS, /* clears stats */
|
||||
NGM_L2TP_GETCLR_STATS, /* returns & clears stats */
|
||||
NGM_L2TP_GET_SESSION_STATS, /* returns session stats */
|
||||
NGM_L2TP_CLR_SESSION_STATS, /* clears session stats */
|
||||
NGM_L2TP_GETCLR_SESSION_STATS, /* returns & clears session stats */
|
||||
NGM_L2TP_ACK_FAILURE, /* sent *from* node after ack timeout */
|
||||
NGM_L2TP_SET_SEQ /* supply a struct ng_l2tp_seq_config */
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user