mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-29 01:22:25 +00:00
qosify: update to latest version
This improves bulk traffic detection. Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
config defaults
|
||||
list defaults /etc/qosify-defaults.conf
|
||||
option dscp_prio CS5
|
||||
option dscp_icmp CS6
|
||||
option dscp_bulk CS0
|
||||
option dscp_default_udp CS4
|
||||
option bulk_trigger_timeout 5
|
||||
option bulk_trigger_pps 0
|
||||
option bulk_trigger_pps 100
|
||||
option prio_max_avg_pkt_len 500
|
||||
|
||||
config interface wan
|
||||
option name wan
|
||||
|
||||
@@ -30,10 +30,12 @@ add_defaults() {
|
||||
add_option int timeout
|
||||
add_option string dscp_prio
|
||||
add_option string dscp_bulk
|
||||
add_option string dscp_icmp
|
||||
add_option string dscp_default_udp
|
||||
add_option string dscp_default_tcp
|
||||
add_option int bulk_trigger_timeout
|
||||
add_option int bulk_trigger_pps
|
||||
add_option int prio_max_avg_pkt_len
|
||||
}
|
||||
|
||||
add_interface() {
|
||||
|
||||
@@ -36,6 +36,34 @@ static const struct {
|
||||
[CL_MAP_CONFIG] = { "config", "config" },
|
||||
};
|
||||
|
||||
static const struct {
|
||||
const char name[5];
|
||||
uint8_t val;
|
||||
} codepoints[] = {
|
||||
{ "CS0", 0 },
|
||||
{ "CS1", 8 },
|
||||
{ "CS2", 16 },
|
||||
{ "CS3", 24 },
|
||||
{ "CS4", 32 },
|
||||
{ "CS5", 40 },
|
||||
{ "CS6", 48 },
|
||||
{ "CS7", 56 },
|
||||
{ "AF11", 10 },
|
||||
{ "AF12", 12 },
|
||||
{ "AF13", 14 },
|
||||
{ "AF21", 18 },
|
||||
{ "AF22", 20 },
|
||||
{ "AF22", 22 },
|
||||
{ "AF31", 26 },
|
||||
{ "AF32", 28 },
|
||||
{ "AF33", 30 },
|
||||
{ "AF41", 34 },
|
||||
{ "AF42", 36 },
|
||||
{ "AF43", 38 },
|
||||
{ "EF", 46 },
|
||||
{ "VA", 44 },
|
||||
};
|
||||
|
||||
static void qosify_map_timer_cb(struct uloop_timeout *t)
|
||||
{
|
||||
qosify_map_gc();
|
||||
@@ -104,6 +132,8 @@ static void __qosify_map_set_dscp_default(enum qosify_map_id id, uint8_t val)
|
||||
int fd = qosify_map_fds[id];
|
||||
int i;
|
||||
|
||||
val |= QOSIFY_DSCP_DEFAULT_FLAG;
|
||||
|
||||
for (i = 0; i < (1 << 16); i++) {
|
||||
data.addr.port = htons(i);
|
||||
if (avl_find(&map_data, &data))
|
||||
@@ -159,38 +189,11 @@ static char *str_skip(char *str, bool space)
|
||||
static int
|
||||
qosify_map_codepoint(const char *val)
|
||||
{
|
||||
static const struct {
|
||||
const char name[5];
|
||||
uint8_t val;
|
||||
} cp[] = {
|
||||
{ "CS0", 0 },
|
||||
{ "CS1", 8 },
|
||||
{ "CS2", 16 },
|
||||
{ "CS3", 24 },
|
||||
{ "CS4", 32 },
|
||||
{ "CS5", 40 },
|
||||
{ "CS6", 48 },
|
||||
{ "CS7", 56 },
|
||||
{ "AF11", 10 },
|
||||
{ "AF12", 12 },
|
||||
{ "AF13", 14 },
|
||||
{ "AF21", 18 },
|
||||
{ "AF22", 20 },
|
||||
{ "AF22", 22 },
|
||||
{ "AF31", 26 },
|
||||
{ "AF32", 28 },
|
||||
{ "AF33", 30 },
|
||||
{ "AF41", 34 },
|
||||
{ "AF42", 36 },
|
||||
{ "AF43", 38 },
|
||||
{ "EF", 46 },
|
||||
{ "VA", 44 },
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cp); i++)
|
||||
if (!strcmp(cp[i].name, val))
|
||||
return cp[i].val;
|
||||
for (i = 0; i < ARRAY_SIZE(codepoints); i++)
|
||||
if (!strcmp(codepoints[i].name, val))
|
||||
return codepoints[i].val;
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
@@ -351,6 +354,28 @@ int qosify_map_dscp_value(const char *val)
|
||||
return dscp + (fallback << 6);
|
||||
}
|
||||
|
||||
static void
|
||||
qosify_map_dscp_codepoint_str(char *dest, int len, uint8_t dscp)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dscp & QOSIFY_DSCP_FALLBACK_FLAG) {
|
||||
*(dest++) = '+';
|
||||
len--;
|
||||
dscp &= ~QOSIFY_DSCP_FALLBACK_FLAG;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(codepoints); i++) {
|
||||
if (codepoints[i].val != dscp)
|
||||
continue;
|
||||
|
||||
snprintf(dest, len, "%s", codepoints[i].name);
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(dest, len, "0x%x", dscp);
|
||||
}
|
||||
|
||||
static void
|
||||
qosify_map_parse_line(char *str)
|
||||
{
|
||||
@@ -543,6 +568,10 @@ void qosify_map_dump(struct blob_buf *b)
|
||||
blobmsg_add_u8(b, "file", e->data.file);
|
||||
blobmsg_add_u8(b, "user", e->data.user);
|
||||
|
||||
buf = blobmsg_alloc_string_buffer(b, "dscp", buf_len);
|
||||
qosify_map_dscp_codepoint_str(buf, buf_len, e->data.dscp);
|
||||
blobmsg_add_string_buffer(b);
|
||||
|
||||
blobmsg_add_string(b, "type", qosify_map_info[e->data.id].type_name);
|
||||
|
||||
buf = blobmsg_alloc_string_buffer(b, "value", buf_len);
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "qosify-bpf.h"
|
||||
|
||||
#define INET_ECN_MASK 3
|
||||
#define DSCP_FALLBACK_FLAG BIT(6)
|
||||
|
||||
#define FLOW_CHECK_INTERVAL ((u32)((1000000000ULL) >> 24))
|
||||
#define FLOW_TIMEOUT ((u32)((30ULL * 1000000000ULL) >> 24))
|
||||
@@ -211,33 +210,37 @@ static void
|
||||
parse_l4proto(struct qosify_config *config, struct __sk_buff *skb,
|
||||
__u32 offset, __u8 proto, __u8 *dscp_out)
|
||||
{
|
||||
struct udphdr *udp = skb_ptr(skb, offset);
|
||||
__u32 key;
|
||||
struct udphdr *udp;
|
||||
__u32 src, dest, key;
|
||||
__u8 *value;
|
||||
|
||||
udp = skb_ptr(skb, offset);
|
||||
if (skb_check(skb, &udp->len))
|
||||
return;
|
||||
|
||||
if (module_flags & QOSIFY_INGRESS)
|
||||
key = udp->source;
|
||||
else
|
||||
key = udp->dest;
|
||||
|
||||
if (proto == IPPROTO_TCP)
|
||||
value = bpf_map_lookup_elem(&tcp_ports, &key);
|
||||
else if (proto == IPPROTO_UDP)
|
||||
value = bpf_map_lookup_elem(&udp_ports, &key);
|
||||
else {
|
||||
if ((proto == IPPROTO_ICMP || proto == IPPROTO_ICMPV6) &&
|
||||
config && config->dscp_icmp != 0xff)
|
||||
*dscp_out = config->dscp_icmp;
|
||||
if (config && (proto == IPPROTO_ICMP || proto == IPPROTO_ICMPV6)) {
|
||||
*dscp_out = config->dscp_icmp;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!value)
|
||||
return;
|
||||
src = udp->source;
|
||||
dest = udp->dest;
|
||||
|
||||
if ((*value & DSCP_FALLBACK_FLAG) && *dscp_out)
|
||||
if (module_flags & QOSIFY_INGRESS)
|
||||
key = src;
|
||||
else
|
||||
key = dest;
|
||||
|
||||
if (proto == IPPROTO_TCP) {
|
||||
value = bpf_map_lookup_elem(&tcp_ports, &key);
|
||||
} else {
|
||||
if (proto != IPPROTO_UDP)
|
||||
key = 0;
|
||||
|
||||
value = bpf_map_lookup_elem(&udp_ports, &key);
|
||||
}
|
||||
|
||||
if (!value)
|
||||
return;
|
||||
|
||||
*dscp_out = *value;
|
||||
@@ -253,9 +256,16 @@ check_flow(struct qosify_config *config, struct __sk_buff *skb,
|
||||
__u32 hash;
|
||||
__u32 time;
|
||||
|
||||
if (!(*dscp & QOSIFY_DSCP_DEFAULT_FLAG))
|
||||
return;
|
||||
|
||||
if (!config)
|
||||
return;
|
||||
|
||||
if (!config->bulk_trigger_pps &&
|
||||
!config->prio_max_avg_pkt_len)
|
||||
return;
|
||||
|
||||
time = cur_time();
|
||||
hash = bpf_get_hash_recalc(skb);
|
||||
flow = bpf_map_lookup_elem(&flow_map, &hash);
|
||||
@@ -287,7 +297,8 @@ check_flow(struct qosify_config *config, struct __sk_buff *skb,
|
||||
if (flow->pkt_count < 0xffff)
|
||||
flow->pkt_count++;
|
||||
|
||||
if (flow->pkt_count > config->bulk_trigger_pps) {
|
||||
if (config->bulk_trigger_pps &&
|
||||
flow->pkt_count > config->bulk_trigger_pps) {
|
||||
flow->dscp = config->dscp_bulk;
|
||||
flow->bulk_timeout = config->bulk_trigger_timeout;
|
||||
}
|
||||
@@ -302,8 +313,7 @@ out:
|
||||
flow->dscp = 0xff;
|
||||
}
|
||||
|
||||
if (flow->dscp != 0xff &&
|
||||
!(*dscp && (flow->dscp & DSCP_FALLBACK_FLAG)))
|
||||
if (flow->dscp != 0xff)
|
||||
*dscp = flow->dscp;
|
||||
|
||||
return;
|
||||
@@ -324,8 +334,9 @@ parse_ipv4(struct __sk_buff *skb, __u32 *offset)
|
||||
struct qosify_config *config;
|
||||
const __u32 zero_port = 0;
|
||||
struct iphdr *iph;
|
||||
__u8 dscp = 0;
|
||||
__u8 dscp = 0xff;
|
||||
__u8 *value;
|
||||
__u8 ipproto;
|
||||
int hdr_len;
|
||||
void *key;
|
||||
bool force;
|
||||
@@ -337,7 +348,7 @@ parse_ipv4(struct __sk_buff *skb, __u32 *offset)
|
||||
return;
|
||||
|
||||
hdr_len = iph->ihl * 4;
|
||||
if (bpf_skb_pull_data(skb, *offset + hdr_len))
|
||||
if (bpf_skb_pull_data(skb, *offset + hdr_len + sizeof(struct udphdr)))
|
||||
return;
|
||||
|
||||
iph = skb_ptr(skb, *offset);
|
||||
@@ -346,7 +357,8 @@ parse_ipv4(struct __sk_buff *skb, __u32 *offset)
|
||||
if (skb_check(skb, (void *)(iph + 1)))
|
||||
return;
|
||||
|
||||
parse_l4proto(config, skb, *offset, iph->protocol, &dscp);
|
||||
ipproto = iph->protocol;
|
||||
parse_l4proto(config, skb, *offset, ipproto, &dscp);
|
||||
|
||||
if (module_flags & QOSIFY_INGRESS)
|
||||
key = &iph->saddr;
|
||||
@@ -355,14 +367,14 @@ parse_ipv4(struct __sk_buff *skb, __u32 *offset)
|
||||
|
||||
value = bpf_map_lookup_elem(&ipv4_map, key);
|
||||
/* use udp port 0 entry as fallback for non-tcp/udp */
|
||||
if (!value)
|
||||
if (!value && dscp == 0xff)
|
||||
value = bpf_map_lookup_elem(&udp_ports, &zero_port);
|
||||
if (value)
|
||||
dscp = *value;
|
||||
|
||||
check_flow(config, skb, &dscp);
|
||||
|
||||
force = !(dscp & DSCP_FALLBACK_FLAG);
|
||||
force = !(dscp & QOSIFY_DSCP_FALLBACK_FLAG);
|
||||
dscp &= GENMASK(5, 0);
|
||||
|
||||
ipv4_change_dsfield(iph, INET_ECN_MASK, dscp << 2, force);
|
||||
@@ -376,12 +388,13 @@ parse_ipv6(struct __sk_buff *skb, __u32 *offset)
|
||||
struct ipv6hdr *iph;
|
||||
__u8 dscp = 0;
|
||||
__u8 *value;
|
||||
__u8 ipproto;
|
||||
void *key;
|
||||
bool force;
|
||||
|
||||
config = get_config();
|
||||
|
||||
if (bpf_skb_pull_data(skb, *offset + sizeof(*iph)))
|
||||
if (bpf_skb_pull_data(skb, *offset + sizeof(*iph) + sizeof(struct udphdr)))
|
||||
return;
|
||||
|
||||
iph = skb_ptr(skb, *offset);
|
||||
@@ -390,12 +403,13 @@ parse_ipv6(struct __sk_buff *skb, __u32 *offset)
|
||||
if (skb_check(skb, (void *)(iph + 1)))
|
||||
return;
|
||||
|
||||
ipproto = iph->nexthdr;
|
||||
if (module_flags & QOSIFY_INGRESS)
|
||||
key = &iph->saddr;
|
||||
else
|
||||
key = &iph->daddr;
|
||||
|
||||
parse_l4proto(config, skb, *offset, iph->nexthdr, &dscp);
|
||||
parse_l4proto(config, skb, *offset, ipproto, &dscp);
|
||||
|
||||
value = bpf_map_lookup_elem(&ipv6_map, key);
|
||||
|
||||
@@ -407,7 +421,7 @@ parse_ipv6(struct __sk_buff *skb, __u32 *offset)
|
||||
|
||||
check_flow(config, skb, &dscp);
|
||||
|
||||
force = !(dscp & DSCP_FALLBACK_FLAG);
|
||||
force = !(dscp & QOSIFY_DSCP_FALLBACK_FLAG);
|
||||
dscp &= GENMASK(5, 0);
|
||||
|
||||
ipv6_change_dsfield(iph, INET_ECN_MASK, dscp << 2, force);
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
#define QOSIFY_INGRESS (1 << 0)
|
||||
#define QOSIFY_IP_ONLY (1 << 1)
|
||||
|
||||
|
||||
#define QOSIFY_DSCP_FALLBACK_FLAG (1 << 6)
|
||||
#define QOSIFY_DSCP_DEFAULT_FLAG (1 << 7)
|
||||
|
||||
/* global config data */
|
||||
struct qosify_config {
|
||||
uint8_t dscp_prio;
|
||||
|
||||
Reference in New Issue
Block a user