summaryrefslogtreecommitdiff
path: root/sys/netgraph
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2007-08-28 18:49:33 +0000
committerAlexander Motin <mav@FreeBSD.org>2007-08-28 18:49:33 +0000
commit3a18582946ed9288cf07c6c2866cb34d5af9c313 (patch)
treef2e133713da6cb1af5e0173fd9831b51d6727f12 /sys/netgraph
parente0e896563c4f8bd199ca6972ace957fd8c468769 (diff)
Notes
Diffstat (limited to 'sys/netgraph')
-rw-r--r--sys/netgraph/ng_ppp.c266
-rw-r--r--sys/netgraph/ng_ppp.h30
2 files changed, 222 insertions, 74 deletions
diff --git a/sys/netgraph/ng_ppp.c b/sys/netgraph/ng_ppp.c
index 282603c28c39..8b81dc83e48b 100644
--- a/sys/netgraph/ng_ppp.c
+++ b/sys/netgraph/ng_ppp.c
@@ -196,7 +196,7 @@ struct ng_ppp_frag {
/* Per-link private information */
struct ng_ppp_link {
struct ng_ppp_link_conf conf; /* link configuration */
- struct ng_ppp_link_stat stats; /* link stats */
+ struct ng_ppp_link_stat64 stats; /* link stats */
hook_p hook; /* connection to link data */
int32_t seq; /* highest rec'd seq# - MSEQ */
uint32_t latency; /* calculated link latency */
@@ -207,7 +207,7 @@ struct ng_ppp_link {
/* Total per-node private information */
struct ng_ppp_private {
struct ng_ppp_bund_conf conf; /* bundle config */
- struct ng_ppp_link_stat bundleStats; /* bundle stats */
+ struct ng_ppp_link_stat64 bundleStats; /* bundle stats */
struct ng_ppp_link links[NG_PPP_MAX_LINKS];/* per-link info */
int32_t xseq; /* next out MP seq # */
int32_t mseq; /* min links[i].seq */
@@ -221,6 +221,8 @@ struct ng_ppp_private {
frags;
int qlen; /* fraq queue length */
struct callout fragTimer; /* fraq queue check */
+ struct mtx rmtx; /* recv mutex */
+ struct mtx xmtx; /* xmit mutex */
};
typedef struct ng_ppp_private *priv_p;
@@ -299,7 +301,7 @@ static int ng_ppp_mp_xmit(node_p node, item_p item, uint16_t proto);
static int ng_ppp_mp_recv(node_p node, item_p item, uint16_t proto,
uint16_t linkNum);
static int ng_ppp_link_xmit(node_p node, item_p item, uint16_t proto,
- uint16_t linkNum);
+ uint16_t linkNum, int plen);
static int ng_ppp_bypass(node_p node, item_p item, uint16_t proto,
uint16_t linkNum);
@@ -381,6 +383,14 @@ static const struct ng_parse_type ng_ppp_stats_type = {
&ng_ppp_stats_type_fields
};
+/* Parse type for struct ng_ppp_link_stat64 */
+static const struct ng_parse_struct_field ng_ppp_stats64_type_fields[]
+ = NG_PPP_STATS64_TYPE_INFO;
+static const struct ng_parse_type ng_ppp_stats64_type = {
+ &ng_parse_struct_type,
+ &ng_ppp_stats64_type_fields
+};
+
/* List of commands and how to convert arguments to/from ASCII */
static const struct ng_cmdlist ng_ppp_cmds[] = {
{
@@ -425,6 +435,20 @@ static const struct ng_cmdlist ng_ppp_cmds[] = {
&ng_parse_int16_type,
&ng_ppp_stats_type
},
+ {
+ NGM_PPP_COOKIE,
+ NGM_PPP_GET_LINK_STATS64,
+ "getstats64",
+ &ng_parse_int16_type,
+ &ng_ppp_stats64_type
+ },
+ {
+ NGM_PPP_COOKIE,
+ NGM_PPP_GETCLR_LINK_STATS64,
+ "getclrstats64",
+ &ng_parse_int16_type,
+ &ng_ppp_stats64_type
+ },
{ 0 }
};
@@ -476,6 +500,9 @@ ng_ppp_constructor(node_p node)
priv->links[i].seq = MP_NOSEQ;
ng_callout_init(&priv->fragTimer);
+ mtx_init(&priv->rmtx, "ng_ppp_recv", NULL, MTX_DEF);
+ mtx_init(&priv->xmtx, "ng_ppp_xmit", NULL, MTX_DEF);
+
/* Done */
return (0);
}
@@ -515,9 +542,6 @@ ng_ppp_newhook(node_p node, hook_p hook, const char *name)
!priv->conf.enableMultilink && priv->numActiveLinks >= 1)
return (ENODEV);
- /* MP recv code is not thread-safe. */
- NG_HOOK_FORCE_WRITER(hook);
-
} else { /* must be a non-link hook */
int i;
@@ -615,10 +639,13 @@ ng_ppp_rcvmsg(node_p node, item_p item, hook_p lasthook)
case NGM_PPP_GET_LINK_STATS:
case NGM_PPP_CLR_LINK_STATS:
case NGM_PPP_GETCLR_LINK_STATS:
+ case NGM_PPP_GET_LINK_STATS64:
+ case NGM_PPP_GETCLR_LINK_STATS64:
{
- struct ng_ppp_link_stat *stats;
+ struct ng_ppp_link_stat64 *stats;
uint16_t linkNum;
+ /* Process request. */
if (msg->header.arglen != sizeof(uint16_t))
ERROUT(EINVAL);
linkNum = *((uint16_t *) msg->data);
@@ -627,14 +654,38 @@ ng_ppp_rcvmsg(node_p node, item_p item, hook_p lasthook)
ERROUT(EINVAL);
stats = (linkNum == NG_PPP_BUNDLE_LINKNUM) ?
&priv->bundleStats : &priv->links[linkNum].stats;
- if (msg->header.cmd != NGM_PPP_CLR_LINK_STATS) {
+
+ /* Make 64bit reply. */
+ if (msg->header.cmd == NGM_PPP_GET_LINK_STATS64 ||
+ msg->header.cmd == NGM_PPP_GETCLR_LINK_STATS64) {
NG_MKRESPONSE(resp, msg,
- sizeof(struct ng_ppp_link_stat), M_NOWAIT);
+ sizeof(struct ng_ppp_link_stat64), M_NOWAIT);
if (resp == NULL)
ERROUT(ENOMEM);
bcopy(stats, resp->data, sizeof(*stats));
+ } else
+ /* Make 32bit reply. */
+ if (msg->header.cmd == NGM_PPP_GET_LINK_STATS ||
+ msg->header.cmd == NGM_PPP_GETCLR_LINK_STATS) {
+ struct ng_ppp_link_stat *rs;
+ NG_MKRESPONSE(resp, msg,
+ sizeof(struct ng_ppp_link_stat), M_NOWAIT);
+ if (resp == NULL)
+ ERROUT(ENOMEM);
+ rs = (struct ng_ppp_link_stat *)resp->data;
+ /* Truncate 64->32 bits. */
+ rs->xmitFrames = stats->xmitFrames;
+ rs->xmitOctets = stats->xmitOctets;
+ rs->recvFrames = stats->recvFrames;
+ rs->recvOctets = stats->recvOctets;
+ rs->badProtos = stats->badProtos;
+ rs->runts = stats->runts;
+ rs->dupFragments = stats->dupFragments;
+ rs->dropFragments = stats->dropFragments;
}
- if (msg->header.cmd != NGM_PPP_GET_LINK_STATS)
+ /* Clear stats. */
+ if (msg->header.cmd != NGM_PPP_GET_LINK_STATS &&
+ msg->header.cmd != NGM_PPP_GET_LINK_STATS64)
bzero(stats, sizeof(*stats));
break;
}
@@ -684,6 +735,8 @@ ng_ppp_shutdown(node_p node)
/* Take down netgraph node */
ng_ppp_frag_reset(node);
+ mtx_destroy(&priv->rmtx);
+ mtx_destroy(&priv->xmtx);
bzero(priv, sizeof(*priv));
FREE(priv, M_NETGRAPH_PPP);
NG_NODE_SET_PRIVATE(node, NULL);
@@ -812,7 +865,7 @@ ng_ppp_rcvdata_bypass(hook_p hook, item_p item)
return (ng_ppp_hcomp_xmit(NG_HOOK_NODE(hook), item, proto));
else
return (ng_ppp_link_xmit(NG_HOOK_NODE(hook), item, proto,
- linkNum));
+ linkNum, 0));
}
static int
@@ -1177,10 +1230,6 @@ ng_ppp_crypt_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
{
const priv_p priv = NG_NODE_PRIVATE(node);
- /* Stats */
- priv->bundleStats.recvFrames++;
- priv->bundleStats.recvOctets += NGI_M(item)->m_pkthdr.len;
-
if (proto == PROT_CRYPTD) {
if (priv->conf.enableDecryption &&
priv->hooks[HOOK_INDEX_DECRYPT] != NULL) {
@@ -1234,7 +1283,7 @@ ng_ppp_rcvdata_decrypt(hook_p hook, item_p item)
*/
static int
-ng_ppp_link_xmit(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
+ng_ppp_link_xmit(node_p node, item_p item, uint16_t proto, uint16_t linkNum, int plen)
{
const priv_p priv = NG_NODE_PRIVATE(node);
struct ng_ppp_link *link;
@@ -1244,8 +1293,7 @@ ng_ppp_link_xmit(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
/* Check if link correct. */
if (linkNum >= NG_PPP_MAX_LINKS) {
- NG_FREE_ITEM(item);
- return (ENETDOWN);
+ ERROUT(ENETDOWN);
}
/* Get link pointer (optimization). */
@@ -1253,8 +1301,7 @@ ng_ppp_link_xmit(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
/* Check link status (if real). */
if (link->hook == NULL) {
- NG_FREE_ITEM(item);
- return (ENETDOWN);
+ ERROUT(ENETDOWN);
}
/* Extract mbuf. */
@@ -1264,34 +1311,39 @@ ng_ppp_link_xmit(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
mru = link->conf.mru;
if (mru != 0 && m->m_pkthdr.len > mru) {
NG_FREE_M(m);
- NG_FREE_ITEM(item);
- return (EMSGSIZE);
+ ERROUT(EMSGSIZE);
}
/* Prepend protocol number, possibly compressed. */
if ((m = ng_ppp_addproto(m, proto, link->conf.enableProtoComp)) ==
NULL) {
- NG_FREE_ITEM(item);
- return (ENOBUFS);
+ ERROUT(ENOBUFS);
}
/* Prepend address and control field (unless compressed). */
if (proto == PROT_LCP || !link->conf.enableACFComp) {
- if ((m = ng_ppp_prepend(m, &ng_ppp_acf, 2)) == NULL) {
- NG_FREE_ITEM(item);
- return (ENOBUFS);
- }
+ if ((m = ng_ppp_prepend(m, &ng_ppp_acf, 2)) == NULL)
+ ERROUT(ENOBUFS);
}
/* Deliver frame. */
len = m->m_pkthdr.len;
NG_FWD_NEW_DATA(error, item, link->hook, m);
- /* Update stats and 'bytes in queue' counter. */
- if (error == 0) {
- link->stats.xmitFrames++;
- link->stats.xmitOctets += len;
+ mtx_lock(&priv->xmtx);
+
+ /* Update link stats. */
+ link->stats.xmitFrames++;
+ link->stats.xmitOctets += len;
+ /* Update bundle stats. */
+ if (plen > 0) {
+ priv->bundleStats.xmitFrames++;
+ priv->bundleStats.xmitOctets += plen;
+ }
+
+ /* Update 'bytes in queue' counter. */
+ if (error == 0) {
/* bytesInQueue and lastWrite required only for mp_strategy. */
if (priv->conf.enableMultilink && !priv->allLinksEqual &&
!priv->conf.enableRoundRobin) {
@@ -1305,6 +1357,11 @@ ng_ppp_link_xmit(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
link->bytesInQueue = 50 * 1600;
}
}
+ mtx_unlock(&priv->xmtx);
+ return (error);
+
+done:
+ NG_FREE_ITEM(item);
return (error);
}
@@ -1321,47 +1378,54 @@ ng_ppp_rcvdata(hook_p hook, item_p item)
struct ng_ppp_link * const link = &priv->links[linkNum];
uint16_t proto;
struct mbuf *m;
+ int error = 0;
KASSERT(linkNum < NG_PPP_MAX_LINKS,
("%s: bogus index 0x%x", __func__, index));
NGI_GET_M(item, m);
+ mtx_lock(&priv->rmtx);
+
/* Stats */
link->stats.recvFrames++;
link->stats.recvOctets += m->m_pkthdr.len;
/* Strip address and control fields, if present. */
- if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) {
- NG_FREE_ITEM(item);
- return (ENOBUFS);
- }
+ if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL)
+ ERROUT(ENOBUFS);
if (bcmp(mtod(m, uint8_t *), &ng_ppp_acf, 2) == 0)
m_adj(m, 2);
- if ((m = ng_ppp_cutproto(m, &proto)) == NULL) {
- NG_FREE_ITEM(item);
- return (ENOBUFS);
- }
+ /* Get protocol number */
+ if ((m = ng_ppp_cutproto(m, &proto)) == NULL)
+ ERROUT(ENOBUFS);
NGI_M(item) = m; /* Put changed m back into item. */
if (!PROT_VALID(proto)) {
link->stats.badProtos++;
- NG_FREE_ITEM(item);
- return (EIO);
+ ERROUT(EIO);
}
/* LCP packets must go directly to bypass. */
- if (proto >= 0xB000)
+ if (proto >= 0xB000) {
+ mtx_unlock(&priv->rmtx);
return (ng_ppp_bypass(node, item, proto, linkNum));
-
- if (!link->conf.enableLink) {
- /* Non-LCP packets are denied on a disabled link. */
- NG_FREE_ITEM(item);
- return (ENXIO);
}
+
+ /* Other packets are denied on a disabled link. */
+ if (!link->conf.enableLink)
+ ERROUT(ENXIO);
+
+ /* Proceed to multilink layer. Mutex will be unlocked inside. */
+ error = ng_ppp_mp_recv(node, item, proto, linkNum);
+ mtx_assert(&priv->rmtx, MA_NOTOWNED);
+ return (error);
- return (ng_ppp_mp_recv(node, item, proto, linkNum));
+done:
+ mtx_unlock(&priv->rmtx);
+ NG_FREE_ITEM(item);
+ return (error);
}
/*
@@ -1429,9 +1493,16 @@ ng_ppp_mp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
struct ng_ppp_frag *qent;
int i, diff, inserted;
struct mbuf *m;
+ int error = 0;
- if ((!priv->conf.enableMultilink) || proto != PROT_MP)
+ if ((!priv->conf.enableMultilink) || proto != PROT_MP) {
+ /* Stats */
+ priv->bundleStats.recvFrames++;
+ priv->bundleStats.recvOctets += NGI_M(item)->m_pkthdr.len;
+
+ mtx_unlock(&priv->rmtx);
return (ng_ppp_crypt_recv(node, item, proto, linkNum));
+ }
NGI_GET_M(item, m);
NG_FREE_ITEM(item);
@@ -1443,10 +1514,10 @@ ng_ppp_mp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
if (m->m_pkthdr.len < 2) {
link->stats.runts++;
NG_FREE_M(m);
- return (EINVAL);
+ ERROUT(EINVAL);
}
if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL)
- return (ENOBUFS);
+ ERROUT(ENOBUFS);
shdr = ntohs(*mtod(m, uint16_t *));
frag->seq = MP_SHORT_EXTEND(shdr);
@@ -1460,10 +1531,10 @@ ng_ppp_mp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
if (m->m_pkthdr.len < 4) {
link->stats.runts++;
NG_FREE_M(m);
- return (EINVAL);
+ ERROUT(EINVAL);
}
if (m->m_len < 4 && (m = m_pullup(m, 4)) == NULL)
- return (ENOBUFS);
+ ERROUT(ENOBUFS);
lhdr = ntohl(*mtod(m, uint32_t *));
frag->seq = MP_LONG_EXTEND(lhdr);
@@ -1480,7 +1551,7 @@ ng_ppp_mp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
if (diff < 0) {
link->stats.dropFragments++;
NG_FREE_M(m);
- return (0);
+ ERROUT(0);
}
/* Update highest received sequence number on this link and MSEQ */
@@ -1497,8 +1568,7 @@ ng_ppp_mp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
MALLOC(frag, struct ng_ppp_frag *, sizeof(*frag), M_NETGRAPH_PPP, M_NOWAIT);
if (frag == NULL) {
NG_FREE_M(m);
- ng_ppp_frag_process(node);
- return (ENOMEM);
+ goto process;
}
*frag = frag0;
@@ -1514,15 +1584,21 @@ ng_ppp_mp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
link->stats.dupFragments++;
NG_FREE_M(frag->data);
FREE(frag, M_NETGRAPH_PPP);
- return (EINVAL);
+ ERROUT(EINVAL);
}
}
if (!inserted)
TAILQ_INSERT_HEAD(&priv->frags, frag, f_qent);
priv->qlen++;
+process:
/* Process the queue */
- return ng_ppp_frag_process(node);
+ /* NOTE: rmtx will be unlocked for sending time! */
+ error = ng_ppp_frag_process(node);
+
+done:
+ mtx_unlock(&priv->rmtx);
+ return (error);
}
/************************************************************************
@@ -1729,9 +1805,20 @@ ng_ppp_frag_process(node_p node)
NG_FREE_M(m);
continue;
}
- if ((item = ng_package_data(m, NG_NOFLAGS)) != NULL)
+ if ((item = ng_package_data(m, NG_NOFLAGS)) != NULL) {
+ /* Stats */
+ priv->bundleStats.recvFrames++;
+ priv->bundleStats.recvOctets +=
+ NGI_M(item)->m_pkthdr.len;
+
+ /* Drop mutex for the sending time.
+ * Priv may change, but we are ready!
+ */
+ mtx_unlock(&priv->rmtx);
ng_ppp_crypt_recv(node, item, proto,
NG_PPP_BUNDLE_LINKNUM);
+ mtx_lock(&priv->rmtx);
+ }
}
/* Delete dead fragments and try again */
} while (ng_ppp_frag_trim(node) || ng_ppp_frag_drop(node));
@@ -1824,9 +1911,14 @@ ng_ppp_frag_checkstale(node_p node)
}
/* Deliver packet */
- if ((item = ng_package_data(m, NG_NOFLAGS)) != NULL)
+ if ((item = ng_package_data(m, NG_NOFLAGS)) != NULL) {
+ /* Stats */
+ priv->bundleStats.recvFrames++;
+ priv->bundleStats.recvOctets += NGI_M(item)->m_pkthdr.len;
+
ng_ppp_crypt_recv(node, item, proto,
NG_PPP_BUNDLE_LINKNUM);
+ }
}
}
@@ -1860,20 +1952,23 @@ ng_ppp_mp_xmit(node_p node, item_p item, uint16_t proto)
int firstFragment;
int activeLinkNum;
struct mbuf *m;
+ int len;
+ int frags;
+ int32_t seq;
/* At least one link must be active */
if (priv->numActiveLinks == 0) {
NG_FREE_ITEM(item);
return (ENETDOWN);
}
+
+ /* Save length for later stats. */
+ len = NGI_M(item)->m_pkthdr.len;
- /* Update stats. */
- priv->bundleStats.xmitFrames++;
- priv->bundleStats.xmitOctets += NGI_M(item)->m_pkthdr.len;
-
- if (!priv->conf.enableMultilink)
+ if (!priv->conf.enableMultilink) {
return (ng_ppp_link_xmit(node, item, proto,
- priv->activeLinks[0]));
+ priv->activeLinks[0], len));
+ }
/* Extract mbuf. */
NGI_GET_M(item, m);
@@ -1886,6 +1981,8 @@ ng_ppp_mp_xmit(node_p node, item_p item, uint16_t proto)
/* Clear distribution plan */
bzero(&distrib, priv->numActiveLinks * sizeof(distrib[0]));
+ mtx_lock(&priv->xmtx);
+
/* Round-robin strategy */
if (priv->conf.enableRoundRobin) {
activeLinkNum = priv->lastLink++ % priv->numActiveLinks;
@@ -1920,6 +2017,29 @@ ng_ppp_mp_xmit(node_p node, item_p item, uint16_t proto)
ng_ppp_mp_strategy(node, m->m_pkthdr.len, distrib);
deliver:
+ /* Estimate fragments count */
+ frags = 0;
+ for (activeLinkNum = priv->numActiveLinks - 1;
+ activeLinkNum >= 0; activeLinkNum--) {
+ const uint16_t linkNum = priv->activeLinks[activeLinkNum];
+ struct ng_ppp_link *const link = &priv->links[linkNum];
+
+ frags += (distrib[activeLinkNum] + link->conf.mru - hdr_len - 1) /
+ (link->conf.mru - hdr_len);
+ }
+
+ /* Get out initial sequence number */
+ seq = priv->xseq;
+
+ /* Update next sequence number */
+ if (priv->conf.xmitShortSeq) {
+ priv->xseq = (seq + frags) & MP_SHORT_SEQ_MASK;
+ } else {
+ priv->xseq = (seq + frags) & MP_LONG_SEQ_MASK;
+ }
+
+ mtx_unlock(&priv->xmtx);
+
/* Send alloted portions of frame out on the link(s) */
for (firstFragment = 1, activeLinkNum = priv->numActiveLinks - 1;
activeLinkNum >= 0; activeLinkNum--) {
@@ -1955,9 +2075,8 @@ deliver:
if (priv->conf.xmitShortSeq) {
uint16_t shdr;
- shdr = priv->xseq;
- priv->xseq =
- (priv->xseq + 1) & MP_SHORT_SEQ_MASK;
+ shdr = seq;
+ seq = (seq + 1) & MP_SHORT_SEQ_MASK;
if (firstFragment)
shdr |= MP_SHORT_FIRST_FLAG;
if (lastFragment)
@@ -1967,9 +2086,8 @@ deliver:
} else {
uint32_t lhdr;
- lhdr = priv->xseq;
- priv->xseq =
- (priv->xseq + 1) & MP_LONG_SEQ_MASK;
+ lhdr = seq;
+ seq = (seq + 1) & MP_LONG_SEQ_MASK;
if (firstFragment)
lhdr |= MP_LONG_FIRST_FLAG;
if (lastFragment)
@@ -1986,7 +2104,7 @@ deliver:
/* Send fragment */
if ((item = ng_package_data(m2, NG_NOFLAGS)) != NULL) {
error = ng_ppp_link_xmit(node, item, PROT_MP,
- linkNum);
+ linkNum, (firstFragment?len:0));
if (error != 0) {
if (!lastFragment)
NG_FREE_M(m);
diff --git a/sys/netgraph/ng_ppp.h b/sys/netgraph/ng_ppp.h
index c1a3c68d254e..c081f2874f26 100644
--- a/sys/netgraph/ng_ppp.h
+++ b/sys/netgraph/ng_ppp.h
@@ -48,6 +48,9 @@
#define NG_PPP_NODE_TYPE "ppp"
#define NGM_PPP_COOKIE 940897795
+/* 64bit stats presence flag */
+#define NG_PPP_STATS64
+
/* Maximum number of supported links */
#define NG_PPP_MAX_LINKS 16
@@ -97,6 +100,8 @@ enum {
NGM_PPP_GET_LINK_STATS, /* takes link #, returns stats struct */
NGM_PPP_CLR_LINK_STATS, /* takes link #, clears link stats */
NGM_PPP_GETCLR_LINK_STATS, /* takes link #, returns & clrs stats */
+ NGM_PPP_GET_LINK_STATS64, /* takes link #, returns stats64 struct */
+ NGM_PPP_GETCLR_LINK_STATS64, /* takes link #, returns stats64 & clrs */
};
/* Multi-link sequence number state (for debugging) */
@@ -212,4 +217,29 @@ struct ng_ppp_link_stat {
{ NULL } \
}
+/* Statistics struct for a link (or the bundle if NG_PPP_BUNDLE_LINKNUM) */
+struct ng_ppp_link_stat64 {
+ u_int64_t xmitFrames; /* xmit frames on link */
+ u_int64_t xmitOctets; /* xmit octets on link */
+ u_int64_t recvFrames; /* recv frames on link */
+ u_int64_t recvOctets; /* recv octets on link */
+ u_int64_t badProtos; /* frames rec'd with bogus protocol */
+ u_int64_t runts; /* Too short MP fragments */
+ u_int64_t dupFragments; /* MP frames with duplicate seq # */
+ u_int64_t dropFragments; /* MP fragments we had to drop */
+};
+
+/* Keep this in sync with the above structure definition */
+#define NG_PPP_STATS64_TYPE_INFO { \
+ { "xmitFrames", &ng_parse_uint64_type }, \
+ { "xmitOctets", &ng_parse_uint64_type }, \
+ { "recvFrames", &ng_parse_uint64_type }, \
+ { "recvOctets", &ng_parse_uint64_type }, \
+ { "badProtos", &ng_parse_uint64_type }, \
+ { "runts", &ng_parse_uint64_type }, \
+ { "dupFragments", &ng_parse_uint64_type }, \
+ { "dropFragments", &ng_parse_uint64_type }, \
+ { NULL } \
+}
+
#endif /* _NETGRAPH_NG_PPP_H_ */