summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accel-pppd/CMakeLists.txt4
-rw-r--r--accel-pppd/extra/CMakeLists.txt1
-rw-r--r--accel-pppd/extra/pppd_compat.c34
-rw-r--r--accel-pppd/extra/sigchld.c3
-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
-rw-r--r--accel-pppd/radius/acct.c31
-rw-r--r--accel-pppd/radius/radius_p.h5
-rw-r--r--accel-pppd/shaper/CMakeLists.txt2
-rw-r--r--accel-pppd/shaper/libnetlink.c692
-rw-r--r--accel-pppd/shaper/libnetlink.h118
12 files changed, 83 insertions, 880 deletions
diff --git a/accel-pppd/CMakeLists.txt b/accel-pppd/CMakeLists.txt
index 1db4137..fb44b50 100644
--- a/accel-pppd/CMakeLists.txt
+++ b/accel-pppd/CMakeLists.txt
@@ -65,6 +65,10 @@ ADD_EXECUTABLE(accel-pppd
cli/tcp.c
cli/cli.c
+ libnetlink/libnetlink.c
+ libnetlink/iputils.c
+ libnetlink/genl.c
+
pwdb.c
ipdb.c
diff --git a/accel-pppd/extra/CMakeLists.txt b/accel-pppd/extra/CMakeLists.txt
index 365f542..e7b9f07 100644
--- a/accel-pppd/extra/CMakeLists.txt
+++ b/accel-pppd/extra/CMakeLists.txt
@@ -1,4 +1,5 @@
ADD_LIBRARY(pppd_compat SHARED pppd_compat.c)
+TARGET_LINK_LIBRARIES(pppd_compat sigchld)
ADD_LIBRARY(ippool SHARED ippool.c)
ADD_LIBRARY(ipv6pool SHARED ipv6pool.c)
ADD_LIBRARY(sigchld SHARED sigchld.c)
diff --git a/accel-pppd/extra/pppd_compat.c b/accel-pppd/extra/pppd_compat.c
index d89a6a6..d4de18f 100644
--- a/accel-pppd/extra/pppd_compat.c
+++ b/accel-pppd/extra/pppd_compat.c
@@ -47,8 +47,6 @@ struct pppd_compat_pd_t
#endif
int started:1;
int res;
- int bytes_sent;
- int bytes_rcvd;
in_addr_t ipv4_addr;
in_addr_t ipv4_peer_addr;
};
@@ -224,27 +222,6 @@ static void ev_ppp_started(struct ppp_t *ppp)
pd->started = 1;
}
-static void ev_ppp_finishing(struct ppp_t *ppp)
-{
- struct ifpppstatsreq ifreq;
- struct pppd_compat_pd_t *pd = find_pd(ppp);
-
- if (!pd)
- return;
-
- memset(&ifreq, 0, sizeof(ifreq));
- ifreq.stats_ptr = (void *)&ifreq.stats;
- strcpy(ifreq.ifr__name, ppp->ifname);
-
- if (ioctl(sock_fd, SIOCGPPPSTATS, &ifreq)) {
- log_ppp_error("pppd_compat: failed to get ppp statistics: %s\n", strerror(errno));
- return;
- }
-
- pd->bytes_sent = ifreq.stats.p.ppp_obytes;
- pd->bytes_rcvd = ifreq.stats.p.ppp_ibytes;
-}
-
static void ev_ppp_finished(struct ppp_t *ppp)
{
pid_t pid;
@@ -497,12 +474,18 @@ static void fill_argv(char **argv, struct pppd_compat_pd_t *pd, char *path)
static void fill_env(char **env, struct pppd_compat_pd_t *pd)
{
+ struct ppp_t *ppp = pd->ppp;
+ uint64_t tx_bytes, rx_bytes;
+
+ tx_bytes = (uint64_t)ppp->acct_tx_bytes + ppp->acct_output_gigawords*4294967296llu;
+ rx_bytes = (uint64_t)ppp->acct_rx_bytes + ppp->acct_input_gigawords*4294967296llu;
+
snprintf(env[0], 64, "PEERNAME=%s", pd->ppp->username);
if (pd->ppp->stop_time && env[1]) {
snprintf(env[1], 24, "CONNECT_TIME=%lu", pd->ppp->stop_time - pd->ppp->start_time);
- snprintf(env[2], 24, "BYTES_SENT=%u", pd->bytes_sent);
- snprintf(env[3], 24, "BYTES_RCVD=%u", pd->bytes_rcvd);
+ snprintf(env[2], 24, "BYTES_SENT=%llu", (long long unsigned)tx_bytes);
+ snprintf(env[3], 24, "BYTES_RCVD=%llu", (long long unsigned)rx_bytes);
}
}
@@ -537,7 +520,6 @@ static void init(void)
triton_event_register_handler(EV_PPP_STARTING, (triton_event_func)ev_ppp_starting);
triton_event_register_handler(EV_PPP_PRE_UP, (triton_event_func)ev_ppp_pre_up);
triton_event_register_handler(EV_PPP_STARTED, (triton_event_func)ev_ppp_started);
- triton_event_register_handler(EV_PPP_FINISHING, (triton_event_func)ev_ppp_finishing);
triton_event_register_handler(EV_PPP_PRE_FINISHED, (triton_event_func)ev_ppp_finished);
#ifdef RADIUS
if (triton_module_loaded("radius")) {
diff --git a/accel-pppd/extra/sigchld.c b/accel-pppd/extra/sigchld.c
index 8f1a979..d6b0df5 100644
--- a/accel-pppd/extra/sigchld.c
+++ b/accel-pppd/extra/sigchld.c
@@ -109,10 +109,9 @@ void __export sigchld_unlock()
pthread_mutex_unlock(&handlers_lock);
}
-static void init(void)
+static void __init init(void)
{
if (pthread_create(&sigchld_thr, NULL, sigchld_thread, NULL))
log_emerg("sigchld: pthread_create: %s\n", strerror(errno));
}
-DEFINE_INIT(100, init); \ No newline at end of file
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) {
diff --git a/accel-pppd/radius/acct.c b/accel-pppd/radius/acct.c
index 76ad329..9a832a9 100644
--- a/accel-pppd/radius/acct.c
+++ b/accel-pppd/radius/acct.c
@@ -34,7 +34,7 @@ static int req_set_RA(struct rad_req_t *req, const char *secret)
static void req_set_stat(struct rad_req_t *req, struct ppp_t *ppp)
{
- struct ifpppstatsreq ifreq;
+ struct rtnl_link_stats stats;
time_t stop_time;
if (ppp->stop_time)
@@ -42,29 +42,14 @@ static void req_set_stat(struct rad_req_t *req, struct ppp_t *ppp)
else
time(&stop_time);
- memset(&ifreq, 0, sizeof(ifreq));
- ifreq.stats_ptr = (void *)&ifreq.stats;
- strcpy(ifreq.ifr__name, ppp->ifname);
-
- if (ioctl(sock_fd, SIOCGPPPSTATS, &ifreq)) {
- log_ppp_error("radius: failed to get ppp statistics: %s\n", strerror(errno));
- return;
+ if (ppp_read_stats(ppp, &stats) == 0) {
+ rad_packet_change_int(req->pack, NULL, "Acct-Input-Octets", stats.rx_bytes);
+ rad_packet_change_int(req->pack, NULL, "Acct-Output-Octets", stats.tx_bytes);
+ rad_packet_change_int(req->pack, NULL, "Acct-Input-Packets", stats.rx_packets);
+ rad_packet_change_int(req->pack, NULL, "Acct-Output-Packets", stats.tx_packets);
+ rad_packet_change_int(req->pack, NULL, "Acct-Input-Gigawords", ppp->acct_input_gigawords);
+ rad_packet_change_int(req->pack, NULL, "Acct-Output-Gigawords", ppp->acct_output_gigawords);
}
-
- if (ifreq.stats.p.ppp_ibytes < req->rpd->acct_input_octets)
- req->rpd->acct_input_gigawords++;
- req->rpd->acct_input_octets = ifreq.stats.p.ppp_ibytes;
-
- if (ifreq.stats.p.ppp_obytes < req->rpd->acct_output_octets)
- req->rpd->acct_output_gigawords++;
- req->rpd->acct_output_octets = ifreq.stats.p.ppp_obytes;
-
- rad_packet_change_int(req->pack, NULL, "Acct-Input-Octets", ifreq.stats.p.ppp_ibytes);
- rad_packet_change_int(req->pack, NULL, "Acct-Output-Octets", ifreq.stats.p.ppp_obytes);
- rad_packet_change_int(req->pack, NULL, "Acct-Input-Packets", ifreq.stats.p.ppp_ipackets);
- rad_packet_change_int(req->pack, NULL, "Acct-Output-Packets", ifreq.stats.p.ppp_opackets);
- rad_packet_change_int(req->pack, NULL, "Acct-Input-Gigawords", req->rpd->acct_input_gigawords);
- rad_packet_change_int(req->pack, NULL, "Acct-Output-Gigawords", req->rpd->acct_output_gigawords);
rad_packet_change_int(req->pack, NULL, "Acct-Session-Time", stop_time - ppp->start_time);
}
diff --git a/accel-pppd/radius/radius_p.h b/accel-pppd/radius/radius_p.h
index 7422bbf..65d9b6a 100644
--- a/accel-pppd/radius/radius_p.h
+++ b/accel-pppd/radius/radius_p.h
@@ -23,11 +23,6 @@ struct radius_pd_t
struct rad_req_t *auth_req;
struct rad_req_t *acct_req;
struct triton_timer_t acct_interim_timer;
- uint32_t acct_input_octets;
- uint32_t acct_output_octets;
- uint32_t acct_input_gigawords;
- uint32_t acct_output_gigawords;
-
struct triton_timer_t session_timeout;
struct rad_packet_t *dm_coa_req;
diff --git a/accel-pppd/shaper/CMakeLists.txt b/accel-pppd/shaper/CMakeLists.txt
index 515fd83..3c1ac95 100644
--- a/accel-pppd/shaper/CMakeLists.txt
+++ b/accel-pppd/shaper/CMakeLists.txt
@@ -1,4 +1,4 @@
-ADD_LIBRARY(shaper SHARED shaper.c limiter.c leaf_qdisc.c tc_core.c libnetlink.c)
+ADD_LIBRARY(shaper SHARED shaper.c limiter.c leaf_qdisc.c tc_core.c)
INSTALL(TARGETS shaper
LIBRARY DESTINATION lib/accel-ppp
diff --git a/accel-pppd/shaper/libnetlink.c b/accel-pppd/shaper/libnetlink.c
deleted file mode 100644
index 74cd5cb..0000000
--- a/accel-pppd/shaper/libnetlink.c
+++ /dev/null
@@ -1,692 +0,0 @@
-/*
- * libnetlink.c RTnetlink service routines.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <syslog.h>
-#include <fcntl.h>
-#include <net/if_arp.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <errno.h>
-#include <time.h>
-#include <sys/uio.h>
-
-#include "libnetlink.h"
-#include "log.h"
-
-int rcvbuf = 1024 * 1024;
-
-void rtnl_close(struct rtnl_handle *rth)
-{
- if (rth->fd >= 0) {
- close(rth->fd);
- rth->fd = -1;
- }
-}
-
-int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions,
- int protocol)
-{
- socklen_t addr_len;
- int sndbuf = 32768;
-
- memset(rth, 0, sizeof(*rth));
-
- rth->fd = socket(AF_NETLINK, SOCK_RAW, protocol);
- if (rth->fd < 0) {
- log_error("libnetlink: ""Cannot open netlink socket: %s\n", strerror(errno));
- return -1;
- }
-
- if (setsockopt(rth->fd,SOL_SOCKET,SO_SNDBUF,&sndbuf,sizeof(sndbuf)) < 0) {
- log_error("libnetlink: ""SO_SNDBUF: %s\n", strerror(errno));
- return -1;
- }
-
- if (setsockopt(rth->fd,SOL_SOCKET,SO_RCVBUF,&rcvbuf,sizeof(rcvbuf)) < 0) {
- log_error("libnetlink: ""SO_RCVBUF: %s\n", strerror(errno));
- return -1;
- }
-
- memset(&rth->local, 0, sizeof(rth->local));
- rth->local.nl_family = AF_NETLINK;
- rth->local.nl_groups = subscriptions;
-
- if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) {
- log_error("libnetlink: ""Cannot bind netlink socket: %s\n", strerror(errno));
- return -1;
- }
- addr_len = sizeof(rth->local);
- if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) {
- log_error("libnetlink: ""Cannot getsockname: %s\n", strerror(errno));
- return -1;
- }
- if (addr_len != sizeof(rth->local)) {
- log_error("libnetlink: ""Wrong address length %d\n", addr_len);
- return -1;
- }
- if (rth->local.nl_family != AF_NETLINK) {
- log_error("libnetlink: ""Wrong address family %d\n", rth->local.nl_family);
- return -1;
- }
- rth->seq = time(NULL);
- return 0;
-}
-
-int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions)
-{
- return rtnl_open_byproto(rth, subscriptions, NETLINK_ROUTE);
-}
-
-int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
-{
- struct {
- struct nlmsghdr nlh;
- struct rtgenmsg g;
- } req;
-
- memset(&req, 0, sizeof(req));
- req.nlh.nlmsg_len = sizeof(req);
- req.nlh.nlmsg_type = type;
- req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
- req.nlh.nlmsg_pid = 0;
- req.nlh.nlmsg_seq = rth->dump = ++rth->seq;
- req.g.rtgen_family = family;
-
- return send(rth->fd, (void*)&req, sizeof(req), 0);
-}
-
-int rtnl_send(struct rtnl_handle *rth, const char *buf, int len)
-{
- return send(rth->fd, buf, len, 0);
-}
-
-int rtnl_send_check(struct rtnl_handle *rth, const char *buf, int len)
-{
- struct nlmsghdr *h;
- int status;
- char resp[1024];
-
- status = send(rth->fd, buf, len, 0);
- if (status < 0)
- return status;
-
- /* Check for immediate errors */
- status = recv(rth->fd, resp, sizeof(resp), MSG_DONTWAIT|MSG_PEEK);
- if (status < 0) {
- if (errno == EAGAIN)
- return 0;
- return -1;
- }
-
- for (h = (struct nlmsghdr *)resp; NLMSG_OK(h, status);
- h = NLMSG_NEXT(h, status)) {
- if (h->nlmsg_type == NLMSG_ERROR) {
- struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
- if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr)))
- log_error("libnetlink: ""ERROR truncated\n");
- else
- errno = -err->error;
- return -1;
- }
- }
-
- return 0;
-}
-
-int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len)
-{
- struct nlmsghdr nlh;
- struct sockaddr_nl nladdr;
- struct iovec iov[2] = {
- { .iov_base = &nlh, .iov_len = sizeof(nlh) },
- { .iov_base = req, .iov_len = len }
- };
- struct msghdr msg = {
- .msg_name = &nladdr,
- .msg_namelen = sizeof(nladdr),
- .msg_iov = iov,
- .msg_iovlen = 2,
- };
-
- memset(&nladdr, 0, sizeof(nladdr));
- nladdr.nl_family = AF_NETLINK;
-
- nlh.nlmsg_len = NLMSG_LENGTH(len);
- nlh.nlmsg_type = type;
- nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
- nlh.nlmsg_pid = 0;
- nlh.nlmsg_seq = rth->dump = ++rth->seq;
-
- return sendmsg(rth->fd, &msg, 0);
-}
-
-int rtnl_dump_filter_l(struct rtnl_handle *rth,
- const struct rtnl_dump_filter_arg *arg)
-{
- struct sockaddr_nl nladdr;
- struct iovec iov;
- struct msghdr msg = {
- .msg_name = &nladdr,
- .msg_namelen = sizeof(nladdr),
- .msg_iov = &iov,
- .msg_iovlen = 1,
- };
- char buf[16384];
-
- iov.iov_base = buf;
- while (1) {
- int status;
- const struct rtnl_dump_filter_arg *a;
- int found_done = 0;
- int msglen = 0;
-
- iov.iov_len = sizeof(buf);
- status = recvmsg(rth->fd, &msg, 0);
-
- if (status < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- log_error("libnetlink: ""netlink receive error %s (%d)\n",
- strerror(errno), errno);
- return -1;
- }
-
- if (status == 0) {
- log_error("libnetlink: ""EOF on netlink\n");
- return -1;
- }
-
- for (a = arg; a->filter; a++) {
- struct nlmsghdr *h = (struct nlmsghdr*)buf;
- msglen = status;
-
- while (NLMSG_OK(h, msglen)) {
- int err;
-
- if (nladdr.nl_pid != 0 ||
- h->nlmsg_pid != rth->local.nl_pid ||
- h->nlmsg_seq != rth->dump) {
- if (a->junk) {
- err = a->junk(&nladdr, h,
- a->arg2);
- if (err < 0)
- return err;
- }
- goto skip_it;
- }
-
- if (h->nlmsg_type == NLMSG_DONE) {
- found_done = 1;
- break; /* process next filter */
- }
- if (h->nlmsg_type == NLMSG_ERROR) {
- struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
- if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
- fprintf(stderr,
- "ERROR truncated\n");
- } else {
- errno = -err->error;
- log_error("libnetlink: ""RTNETLINK answers: %s\n", strerror(errno));
- }
- return -1;
- }
- err = a->filter(&nladdr, h, a->arg1);
- if (err < 0)
- return err;
-
-skip_it:
- h = NLMSG_NEXT(h, msglen);
- }
- }
-
- if (found_done)
- return 0;
-
- if (msg.msg_flags & MSG_TRUNC) {
- log_error("libnetlink: ""Message truncated\n");
- continue;
- }
- if (msglen) {
- log_error("libnetlink: ""!!!Remnant of size %d\n", msglen);
- exit(1);
- }
- }
-}
-
-int rtnl_dump_filter(struct rtnl_handle *rth,
- rtnl_filter_t filter,
- void *arg1,
- rtnl_filter_t junk,
- void *arg2)
-{
- const struct rtnl_dump_filter_arg a[2] = {
- { .filter = filter, .arg1 = arg1, .junk = junk, .arg2 = arg2 },
- { .filter = NULL, .arg1 = NULL, .junk = NULL, .arg2 = NULL }
- };
-
- return rtnl_dump_filter_l(rth, a);
-}
-
-int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer,
- unsigned groups, struct nlmsghdr *answer,
- rtnl_filter_t junk,
- void *jarg, int ignore_einval)
-{
- int status;
- unsigned seq;
- struct nlmsghdr *h;
- struct sockaddr_nl nladdr;
- struct iovec iov = {
- .iov_base = (void*) n,
- .iov_len = n->nlmsg_len
- };
- struct msghdr msg = {
- .msg_name = &nladdr,
- .msg_namelen = sizeof(nladdr),
- .msg_iov = &iov,
- .msg_iovlen = 1,
- };
- char buf[16384];
-
- memset(&nladdr, 0, sizeof(nladdr));
- nladdr.nl_family = AF_NETLINK;
- nladdr.nl_pid = peer;
- nladdr.nl_groups = groups;
-
- n->nlmsg_seq = seq = ++rtnl->seq;
-
- if (answer == NULL)
- n->nlmsg_flags |= NLM_F_ACK;
-
- status = sendmsg(rtnl->fd, &msg, 0);
-
- if (status < 0) {
- log_error("libnetlink: ""Cannot talk to rtnetlink: %s\n", strerror(errno));
- return -1;
- }
-
- memset(buf,0,sizeof(buf));
-
- iov.iov_base = buf;
-
- while (1) {
- iov.iov_len = sizeof(buf);
- status = recvmsg(rtnl->fd, &msg, 0);
-
- if (status < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- log_error("libnetlink: ""netlink receive error %s (%d)\n",
- strerror(errno), errno);
- return -1;
- }
- if (status == 0) {
- log_error("libnetlink: ""EOF on netlink\n");
- return -1;
- }
- if (msg.msg_namelen != sizeof(nladdr)) {
- log_error("libnetlink: ""sender address length == %d\n", msg.msg_namelen);
- exit(1);
- }
- for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) {
- int err;
- int len = h->nlmsg_len;
- int l = len - sizeof(*h);
-
- if (l<0 || len>status) {
- if (msg.msg_flags & MSG_TRUNC) {
- log_error("libnetlink: ""Truncated message\n");
- return -1;
- }
- log_error("libnetlink: ""!!!malformed message: len=%d\n", len);
- exit(1);
- }
-
- if (nladdr.nl_pid != peer ||
- h->nlmsg_pid != rtnl->local.nl_pid ||
- h->nlmsg_seq != seq) {
- if (junk) {
- err = junk(&nladdr, h, jarg);
- if (err < 0)
- return err;
- }
- /* Don't forget to skip that message. */
- status -= NLMSG_ALIGN(len);
- h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len));
- continue;
- }
-
- if (h->nlmsg_type == NLMSG_ERROR) {
- struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
- if (l < sizeof(struct nlmsgerr)) {
- log_error("libnetlink: ""ERROR truncated\n");
- } else {
- errno = -err->error;
- if (errno == 0 || (errno == EINVAL && ignore_einval)) {
- if (answer)
- memcpy(answer, h, h->nlmsg_len);
- return 0;
- }
- log_error("libnetlink: ""RTNETLINK answers: %s\n", strerror(errno));
- }
- return -1;
- }
- if (answer) {
- memcpy(answer, h, h->nlmsg_len);
- return 0;
- }
-
- log_error("libnetlink: ""Unexpected reply!!!\n");
-
- status -= NLMSG_ALIGN(len);
- h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len));
- }
- if (msg.msg_flags & MSG_TRUNC) {
- log_error("libnetlink: ""Message truncated\n");
- continue;
- }
- if (status) {
- log_error("libnetlink: ""!!!Remnant of size %d\n", status);
- exit(1);
- }
- }
-}
-
-int rtnl_listen(struct rtnl_handle *rtnl,
- rtnl_filter_t handler,
- void *jarg)
-{
- int status;
- struct nlmsghdr *h;
- struct sockaddr_nl nladdr;
- struct iovec iov;
- struct msghdr msg = {
- .msg_name = &nladdr,
- .msg_namelen = sizeof(nladdr),
- .msg_iov = &iov,
- .msg_iovlen = 1,
- };
- char buf[8192];
-
- memset(&nladdr, 0, sizeof(nladdr));
- nladdr.nl_family = AF_NETLINK;
- nladdr.nl_pid = 0;
- nladdr.nl_groups = 0;
-
- iov.iov_base = buf;
- while (1) {
- iov.iov_len = sizeof(buf);
- status = recvmsg(rtnl->fd, &msg, 0);
-
- if (status < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- log_error("libnetlink: ""netlink receive error %s (%d)\n",
- strerror(errno), errno);
- if (errno == ENOBUFS)
- continue;
- return -1;
- }
- if (status == 0) {
- log_error("libnetlink: ""EOF on netlink\n");
- return -1;
- }
- if (msg.msg_namelen != sizeof(nladdr)) {
- log_error("libnetlink: ""Sender address length == %d\n", msg.msg_namelen);
- exit(1);
- }
- for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) {
- int err;
- int len = h->nlmsg_len;
- int l = len - sizeof(*h);
-
- if (l<0 || len>status) {
- if (msg.msg_flags & MSG_TRUNC) {
- log_error("libnetlink: ""Truncated message\n");
- return -1;
- }
- log_error("libnetlink: ""!!!malformed message: len=%d\n", len);
- exit(1);
- }
-
- err = handler(&nladdr, h, jarg);
- if (err < 0)
- return err;
-
- status -= NLMSG_ALIGN(len);
- h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len));
- }
- if (msg.msg_flags & MSG_TRUNC) {
- log_error("libnetlink: ""Message truncated\n");
- continue;
- }
- if (status) {
- log_error("libnetlink: ""!!!Remnant of size %d\n", status);
- exit(1);
- }
- }
-}
-
-int rtnl_from_file(FILE *rtnl, rtnl_filter_t handler,
- void *jarg)
-{
- int status;
- struct sockaddr_nl nladdr;
- char buf[8192];
- struct nlmsghdr *h = (void*)buf;
-
- memset(&nladdr, 0, sizeof(nladdr));
- nladdr.nl_family = AF_NETLINK;
- nladdr.nl_pid = 0;
- nladdr.nl_groups = 0;
-
- while (1) {
- int err, len, type;
- int l;
-
- status = fread(&buf, 1, sizeof(*h), rtnl);
-
- if (status < 0) {
- if (errno == EINTR)
- continue;
- log_error("libnetlink: ""rtnl_from_file: fread");
- return -1;
- }
- if (status == 0)
- return 0;
-
- len = h->nlmsg_len;
- type= h->nlmsg_type;
- l = len - sizeof(*h);
-
- if (l<0 || len>sizeof(buf)) {
- log_error("libnetlink: ""!!!malformed message: len=%d @%lu\n",
- len, ftell(rtnl));
- return -1;
- }
-
- status = fread(NLMSG_DATA(h), 1, NLMSG_ALIGN(l), rtnl);
-
- if (status < 0) {
- log_error("libnetlink: ""rtnl_from_file: fread");
- return -1;
- }
- if (status < l) {
- log_error("libnetlink: ""rtnl-from_file: truncated message\n");
- return -1;
- }
-
- err = handler(&nladdr, h, jarg);
- if (err < 0)
- return err;
- }
-}
-
-int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data)
-{
- int len = RTA_LENGTH(4);
- struct rtattr *rta;
- if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
- fprintf(stderr,"addattr32: Error! max allowed bound %d exceeded\n",maxlen);
- return -1;
- }
- rta = NLMSG_TAIL(n);
- rta->rta_type = type;
- rta->rta_len = len;
- memcpy(RTA_DATA(rta), &data, 4);
- n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
- return 0;
-}
-
-int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
- int alen)
-{
- int len = RTA_LENGTH(alen);
- struct rtattr *rta;
-
- if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
- log_error("libnetlink: ""addattr_l ERROR: message exceeded bound of %d\n",maxlen);
- return -1;
- }
- rta = NLMSG_TAIL(n);
- rta->rta_type = type;
- rta->rta_len = len;
- memcpy(RTA_DATA(rta), data, alen);
- n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
- return 0;
-}
-
-int addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len)
-{
- if (NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len) > maxlen) {
- log_error("libnetlink: ""addraw_l ERROR: message exceeded bound of %d\n",maxlen);
- return -1;
- }
-
- memcpy(NLMSG_TAIL(n), data, len);
- memset((void *) NLMSG_TAIL(n) + len, 0, NLMSG_ALIGN(len) - len);
- n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len);
- return 0;
-}
-
-struct rtattr *addattr_nest(struct nlmsghdr *n, int maxlen, int type)
-{
- struct rtattr *nest = NLMSG_TAIL(n);
-
- addattr_l(n, maxlen, type, NULL, 0);
- return nest;
-}
-
-int addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest)
-{
- nest->rta_len = (void *)NLMSG_TAIL(n) - (void *)nest;
- return n->nlmsg_len;
-}
-
-struct rtattr *addattr_nest_compat(struct nlmsghdr *n, int maxlen, int type,
- const void *data, int len)
-{
- struct rtattr *start = NLMSG_TAIL(n);
-
- addattr_l(n, maxlen, type, data, len);
- addattr_nest(n, maxlen, type);
- return start;
-}
-
-int addattr_nest_compat_end(struct nlmsghdr *n, struct rtattr *start)
-{
- struct rtattr *nest = (void *)start + NLMSG_ALIGN(start->rta_len);
-
- start->rta_len = (void *)NLMSG_TAIL(n) - (void *)start;
- addattr_nest_end(n, nest);
- return n->nlmsg_len;
-}
-
-int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data)
-{
- int len = RTA_LENGTH(4);
- struct rtattr *subrta;
-
- if (RTA_ALIGN(rta->rta_len) + len > maxlen) {
- fprintf(stderr,"rta_addattr32: Error! max allowed bound %d exceeded\n",maxlen);
- return -1;
- }
- subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len));
- subrta->rta_type = type;
- subrta->rta_len = len;
- memcpy(RTA_DATA(subrta), &data, 4);
- rta->rta_len = NLMSG_ALIGN(rta->rta_len) + len;
- return 0;
-}
-
-int rta_addattr_l(struct rtattr *rta, int maxlen, int type,
- const void *data, int alen)
-{
- struct rtattr *subrta;
- int len = RTA_LENGTH(alen);
-
- if (RTA_ALIGN(rta->rta_len) + RTA_ALIGN(len) > maxlen) {
- fprintf(stderr,"rta_addattr_l: Error! max allowed bound %d exceeded\n",maxlen);
- return -1;
- }
- subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len));
- subrta->rta_type = type;
- subrta->rta_len = len;
- memcpy(RTA_DATA(subrta), data, alen);
- rta->rta_len = NLMSG_ALIGN(rta->rta_len) + RTA_ALIGN(len);
- return 0;
-}
-
-int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
-{
- memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
- while (RTA_OK(rta, len)) {
- if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
- tb[rta->rta_type] = rta;
- rta = RTA_NEXT(rta,len);
- }
- if (len)
- log_error("libnetlink: ""!!!Deficit %d, rta_len=%d\n", len, rta->rta_len);
- return 0;
-}
-
-int parse_rtattr_byindex(struct rtattr *tb[], int max, struct rtattr *rta, int len)
-{
- int i = 0;
-
- memset(tb, 0, sizeof(struct rtattr *) * max);
- while (RTA_OK(rta, len)) {
- if (rta->rta_type <= max && i < max)
- tb[i++] = rta;
- rta = RTA_NEXT(rta,len);
- }
- if (len)
- log_error("libnetlink: ""!!!Deficit %d, rta_len=%d\n", len, rta->rta_len);
- return i;
-}
-
-int __parse_rtattr_nested_compat(struct rtattr *tb[], int max, struct rtattr *rta,
- int len)
-{
- if (RTA_PAYLOAD(rta) < len)
- return -1;
- if (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) {
- rta = RTA_DATA(rta) + RTA_ALIGN(len);
- return parse_rtattr_nested(tb, max, rta);
- }
- memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
- return 0;
-}
diff --git a/accel-pppd/shaper/libnetlink.h b/accel-pppd/shaper/libnetlink.h
deleted file mode 100644
index f68bf8a..0000000
--- a/accel-pppd/shaper/libnetlink.h
+++ /dev/null
@@ -1,118 +0,0 @@
-#ifndef __LIBNETLINK_H__
-#define __LIBNETLINK_H__ 1
-
-#include <asm/types.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <linux/if_link.h>
-#include <linux/if_addr.h>
-#include <linux/neighbour.h>
-
-#define TCA_BUF_MAX 64*1024
-#define MAX_MSG 16384
-
-struct rtnl_handle
-{
- int fd;
- struct sockaddr_nl local;
- struct sockaddr_nl peer;
- __u32 seq;
- __u32 dump;
-};
-
-extern int rcvbuf;
-
-extern int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions);
-extern int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, int protocol);
-extern void rtnl_close(struct rtnl_handle *rth);
-extern int rtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type);
-extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len);
-
-typedef int (*rtnl_filter_t)(const struct sockaddr_nl *,
- struct nlmsghdr *n, void *);
-
-struct rtnl_dump_filter_arg
-{
- rtnl_filter_t filter;
- void *arg1;
- rtnl_filter_t junk;
- void *arg2;
-};
-
-extern int rtnl_dump_filter_l(struct rtnl_handle *rth,
- const struct rtnl_dump_filter_arg *arg);
-extern int rtnl_dump_filter(struct rtnl_handle *rth, rtnl_filter_t filter,
- void *arg1,
- rtnl_filter_t junk,
- void *arg2);
-
-extern int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer,
- unsigned groups, struct nlmsghdr *answer,
- rtnl_filter_t junk,
- void *jarg, int ignore_einval);
-extern int rtnl_send(struct rtnl_handle *rth, const char *buf, int);
-extern int rtnl_send_check(struct rtnl_handle *rth, const char *buf, int);
-
-extern int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data);
-extern int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, int alen);
-extern int addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len);
-extern struct rtattr *addattr_nest(struct nlmsghdr *n, int maxlen, int type);
-extern int addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest);
-extern struct rtattr *addattr_nest_compat(struct nlmsghdr *n, int maxlen, int type, const void *data, int len);
-extern int addattr_nest_compat_end(struct nlmsghdr *n, struct rtattr *nest);
-extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data);
-extern int rta_addattr_l(struct rtattr *rta, int maxlen, int type, const void *data, int alen);
-
-extern int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len);
-extern int parse_rtattr_byindex(struct rtattr *tb[], int max, struct rtattr *rta, int len);
-extern int __parse_rtattr_nested_compat(struct rtattr *tb[], int max, struct rtattr *rta, int len);
-
-#define parse_rtattr_nested(tb, max, rta) \
- (parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta)))
-
-#define parse_rtattr_nested_compat(tb, max, rta, data, len) \
-({ data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
- __parse_rtattr_nested_compat(tb, max, rta, len); })
-
-extern int rtnl_listen(struct rtnl_handle *, rtnl_filter_t handler,
- void *jarg);
-extern int rtnl_from_file(FILE *, rtnl_filter_t handler,
- void *jarg);
-
-#define NLMSG_TAIL(nmsg) \
- ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
-
-#ifndef IFA_RTA
-#define IFA_RTA(r) \
- ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
-#endif
-#ifndef IFA_PAYLOAD
-#define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg))
-#endif
-
-#ifndef IFLA_RTA
-#define IFLA_RTA(r) \
- ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
-#endif
-#ifndef IFLA_PAYLOAD
-#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
-#endif
-
-#ifndef NDA_RTA
-#define NDA_RTA(r) \
- ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
-#endif
-#ifndef NDA_PAYLOAD
-#define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndmsg))
-#endif
-
-#ifndef NDTA_RTA
-#define NDTA_RTA(r) \
- ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndtmsg))))
-#endif
-#ifndef NDTA_PAYLOAD
-#define NDTA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndtmsg))
-#endif
-
-#endif /* __LIBNETLINK_H__ */
-