summaryrefslogtreecommitdiff
path: root/accel-pppd/shaper/limiter.c
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2014-11-17 18:45:29 +0300
committerDmitry Kozlov <xeb@mail.ru>2014-11-17 18:45:29 +0300
commitca13dfe2c774835c3aed9567747c9b8b989446ba (patch)
treeaba9f272cae35c38ca24319460e5f55df3022d9a /accel-pppd/shaper/limiter.c
parentbe476ff24258d1c3a043c69040ab147e6ed59c5a (diff)
downloadaccel-ppp-ca13dfe2c774835c3aed9567747c9b8b989446ba.tar.gz
accel-ppp-ca13dfe2c774835c3aed9567747c9b8b989446ba.zip
shaper: introduce "fwmark" option
If specified then fwmark filters will be installed to bypass shaper
Diffstat (limited to 'accel-pppd/shaper/limiter.c')
-rw-r--r--accel-pppd/shaper/limiter.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/accel-pppd/shaper/limiter.c b/accel-pppd/shaper/limiter.c
index 954a1169..2398bfea 100644
--- a/accel-pppd/shaper/limiter.c
+++ b/accel-pppd/shaper/limiter.c
@@ -246,7 +246,8 @@ static int install_police(struct rtnl_handle *rth, int ifindex, int rate, int bu
req.t.tcm_ifindex = ifindex;
req.t.tcm_handle = 1;
req.t.tcm_parent = 0xffff0000;
- req.t.tcm_info = TC_H_MAKE(1 << 16, ntohs(ETH_P_IP));
+
+ req.t.tcm_info = TC_H_MAKE(100 << 16, ntohs(ETH_P_IP));
addattr_l(&req.n, sizeof(req), TCA_KIND, "u32", 4);
@@ -340,7 +341,9 @@ static int install_htb_ifb(struct rtnl_handle *rth, int ifindex, __u32 priority,
req.t.tcm_ifindex = ifindex;
req.t.tcm_handle = 1;
req.t.tcm_parent = 0xffff0000;
- req.t.tcm_info = TC_H_MAKE(1 << 16, ntohs(ETH_P_IP));
+
+ req.t.tcm_info = TC_H_MAKE(100 << 16, ntohs(ETH_P_IP));
+
addattr_l(&req.n, sizeof(req), TCA_KIND, "u32", 4);
@@ -390,6 +393,35 @@ static int install_htb_ifb(struct rtnl_handle *rth, int ifindex, __u32 priority,
return 0;
}
+static int install_fwmark(struct rtnl_handle *rth, int ifindex, int parent)
+{
+ struct rtattr *tail;
+
+ struct {
+ struct nlmsghdr n;
+ struct tcmsg t;
+ char buf[1024];
+ } req;
+
+ memset(&req, 0, sizeof(req) - 1024);
+
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg));
+ req.n.nlmsg_flags = NLM_F_REQUEST|NLM_F_EXCL|NLM_F_CREATE;
+ req.n.nlmsg_type = RTM_NEWTFILTER;
+ req.t.tcm_family = AF_UNSPEC;
+ req.t.tcm_ifindex = ifindex;
+ req.t.tcm_handle = 1;
+ req.t.tcm_parent = parent;
+ req.t.tcm_info = TC_H_MAKE(90 << 16, ntohs(ETH_P_IP));
+
+ addattr_l(&req.n, sizeof(req), TCA_KIND, "fw", 3);
+ tail = NLMSG_TAIL(&req.n);
+ addattr_l(&req.n, TCA_BUF_MAX, TCA_OPTIONS, NULL, 0);
+ addattr32(&req.n, TCA_BUF_MAX, TCA_FW_CLASSID, TC_H_MAKE(conf_fwmark << 16, 0));
+ tail->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)tail;
+ return rtnl_talk(rth, &req.n, 0, 0, NULL, NULL, NULL, 0);
+}
+
static int remove_root(struct rtnl_handle *rth, int ifindex)
{
struct qdisc_opt opt = {
@@ -450,6 +482,11 @@ int install_limiter(struct ap_session *ses, int down_speed, int down_burst, int
if (r == 0)
r = install_leaf_qdisc(&rth, conf_ifb_ifindex, 0x00010001 + ses->unit_idx + 1, (1 + ses->unit_idx + 1) << 16);
}
+
+ if (conf_fwmark) {
+ install_fwmark(&rth, ses->ifindex, 0x00010000);
+ install_fwmark(&rth, ses->ifindex, TC_H_INGRESS);
+ }
rtnl_close(&rth);