summaryrefslogtreecommitdiff
path: root/accel-pppd/ppp
diff options
context:
space:
mode:
authorKozlov Dmitry <xeb@mail.ru>2012-09-05 21:56:53 +0400
committerKozlov Dmitry <xeb@mail.ru>2012-09-05 21:56:53 +0400
commit28c47fa1ccf6a6550f335046349b1716745a2189 (patch)
tree3d9d64efcdfb11fa7c74fa3dcf3db71eba772b8f /accel-pppd/ppp
parentf26abc454476bded89de516ebc099a3f62c54fb9 (diff)
downloadaccel-ppp-xebd-28c47fa1ccf6a6550f335046349b1716745a2189.tar.gz
accel-ppp-xebd-28c47fa1ccf6a6550f335046349b1716745a2189.zip
gather interface statistics via netlink
Diffstat (limited to 'accel-pppd/ppp')
-rw-r--r--accel-pppd/ppp/ppp.c42
-rw-r--r--accel-pppd/ppp/ppp.h12
-rw-r--r--accel-pppd/ppp/ppp_lcp.c19
3 files changed, 60 insertions, 13 deletions
diff --git a/accel-pppd/ppp/ppp.c b/accel-pppd/ppp/ppp.c
index b8feaa1..3e1386b 100644
--- a/accel-pppd/ppp/ppp.c
+++ b/accel-pppd/ppp/ppp.c
@@ -108,6 +108,7 @@ static void generate_sessionid(struct ppp_t *ppp)
int __export establish_ppp(struct ppp_t *ppp)
{
+ struct rtnl_link_stats stats;
struct ifreq ifr;
struct pppunit_cache *uc = NULL;
@@ -188,6 +189,17 @@ int __export establish_ppp(struct ppp_t *ppp)
}
ppp->ifindex = ifr.ifr_ifindex;
+ if (uc) {
+ if (iplink_get_stats(ppp->ifindex, &stats))
+ log_ppp_warn("ppp: failed to get interface statistics\n");
+ else {
+ ppp->acct_rx_packets_i = stats.rx_packets;
+ ppp->acct_tx_packets_i = stats.tx_packets;
+ ppp->acct_rx_bytes_i = stats.rx_bytes;
+ ppp->acct_tx_bytes_i = stats.tx_bytes;
+ }
+ }
+
log_ppp_info1("connect: %s <--> %s(%s)\n", ppp->ifname, ppp->ctrl->name, ppp->chan_name);
init_layers(ppp);
@@ -239,6 +251,8 @@ static void destablish_ppp(struct ppp_t *ppp)
{
struct pppunit_cache *uc;
+ ppp_read_stats(ppp, NULL);
+
triton_event_fire(EV_PPP_PRE_FINISHED, ppp);
pthread_rwlock_wrlock(&ppp_lock);
@@ -732,6 +746,34 @@ static void save_seq(void)
}
}
+int __export ppp_read_stats(struct ppp_t *ppp, struct rtnl_link_stats *stats)
+{
+ struct rtnl_link_stats lstats;
+
+ if (!stats)
+ stats = &lstats;
+
+ if (iplink_get_stats(ppp->ifindex, stats)) {
+ log_ppp_warn("ppp: failed to get interface statistics\n");
+ return -1;
+ }
+
+ stats->rx_packets -= ppp->acct_rx_packets_i;
+ stats->tx_packets -= ppp->acct_tx_packets_i;
+ stats->rx_bytes -= ppp->acct_rx_bytes_i;
+ stats->tx_bytes -= ppp->acct_tx_bytes_i;
+
+ if (stats->rx_bytes < ppp->acct_rx_bytes)
+ ppp->acct_input_gigawords++;
+ ppp->acct_rx_bytes = stats->rx_bytes;
+
+ if (stats->tx_bytes < ppp->acct_tx_bytes)
+ ppp->acct_output_gigawords++;
+ ppp->acct_tx_bytes = stats->tx_bytes;
+
+ return 0;
+}
+
static void load_config(void)
{
char *opt;
diff --git a/accel-pppd/ppp/ppp.h b/accel-pppd/ppp/ppp.h
index ca97d5a..5e47607 100644
--- a/accel-pppd/ppp/ppp.h
+++ b/accel-pppd/ppp/ppp.h
@@ -8,6 +8,7 @@
#include "triton.h"
#include "list.h"
+#include "iputils.h"
/*
* Packet header = Code, id, length.
@@ -134,6 +135,15 @@ struct ppp_t
struct ppp_lcp_t *lcp;
struct list_head pd_list;
+
+ uint32_t acct_rx_bytes;
+ uint32_t acct_tx_bytes;
+ uint32_t acct_input_gigawords;
+ uint32_t acct_output_gigawords;
+ uint32_t acct_rx_packets_i;
+ uint32_t acct_tx_packets_i;
+ uint32_t acct_rx_bytes_i;
+ uint32_t acct_tx_bytes_i;
};
struct ppp_layer_t;
@@ -200,6 +210,8 @@ int ppp_register_layer(const char *name, struct ppp_layer_t *);
void ppp_unregister_layer(struct ppp_layer_t *);
struct ppp_layer_data_t *ppp_find_layer_data(struct ppp_t *, struct ppp_layer_t *);
+int ppp_read_stats(struct ppp_t *ppp, struct rtnl_link_stats *stats);
+
extern int ppp_shutdown;
void ppp_shutdown_soft(void);
diff --git a/accel-pppd/ppp/ppp_lcp.c b/accel-pppd/ppp/ppp_lcp.c
index e61738c..9b56ed1 100644
--- a/accel-pppd/ppp/ppp_lcp.c
+++ b/accel-pppd/ppp/ppp_lcp.c
@@ -638,9 +638,9 @@ static void send_echo_reply(struct ppp_lcp_t *lcp)
static void send_echo_request(struct triton_timer_t *t)
{
struct ppp_lcp_t *lcp = container_of(t, typeof(*lcp), echo_timer);
- struct ifpppstatsreq ifreq;
- int f = 0;
+ int f = 0, r;
time_t ts;
+ struct rtnl_link_stats stats;
struct lcp_echo_req_t
{
struct lcp_hdr_t hdr;
@@ -655,22 +655,15 @@ static void send_echo_request(struct triton_timer_t *t)
++lcp->echo_sent;
+ r = ppp_read_stats(lcp->ppp, &stats);
+
if (conf_echo_timeout) {
if (lcp->echo_sent == 2) {
- memset(&ifreq, 0, sizeof(ifreq));
- ifreq.stats_ptr = (void *)&ifreq.stats;
- strcpy(ifreq.ifr__name, lcp->ppp->ifname);
-
- if (ioctl(sock_fd, SIOCGPPPSTATS, &ifreq) == 0)
- lcp->last_ipackets = ifreq.stats.p.ppp_ipackets;
-
+ lcp->last_ipackets = stats.rx_packets;
time(&lcp->last_echo_ts);
} else if (lcp->echo_sent > 2) {
time(&ts);
- memset(&ifreq, 0, sizeof(ifreq));
- ifreq.stats_ptr = (void *)&ifreq.stats;
- strcpy(ifreq.ifr__name, lcp->ppp->ifname);
- if (ioctl(sock_fd, SIOCGPPPSTATS, &ifreq) == 0 && lcp->last_ipackets != ifreq.stats.p.ppp_ipackets) {
+ if (r == 0 && lcp->last_ipackets != stats.rx_packets) {
lcp->echo_sent = 1;
lcp_update_echo_timer(lcp);
} else if (ts - lcp->last_echo_ts > conf_echo_timeout) {