__uint(max_entries, 1);
} config SEC(".maps");
-typedef struct {
+struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(pinning, 1);
__type(key, __u32);
__type(value, __u8);
__uint(max_entries, 1 << 16);
-} port_array_t;
+} tcp_ports SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(pinning, 1);
+ __type(key, __u32);
+ __type(value, __u8);
+ __uint(max_entries, 1 << 16);
+} udp_ports SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__uint(max_entries, QOSIFY_FLOW_BUCKETS);
} flow_map SEC(".maps");
-port_array_t tcp_ports SEC(".maps");
-port_array_t udp_ports SEC(".maps");
-
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(pinning, 1);
return;
}
+ src = READ_ONCE(udp->source);
+ dest = READ_ONCE(udp->dest);
if (ingress)
- key = udp->source;
+ key = src;
else
- key = udp->dest;
+ key = dest;
if (proto == IPPROTO_TCP) {
value = bpf_map_lookup_elem(&tcp_ports, &key);
bool trigger = false;
__s32 delta;
__u32 time;
+ int segs = 1;
if (!config->bulk_trigger_pps)
return;
if ((u32)delta > FLOW_TIMEOUT)
goto reset;
- flow->pkt_count++;
+ if (skb->gso_segs)
+ segs = skb->gso_segs;
+ flow->pkt_count += segs;
if (flow->pkt_count > config->bulk_trigger_pps) {
flow->bulk_timeout = config->bulk_trigger_timeout + 1;
trigger = true;
check_flow_prio(struct qosify_flow_config *config, struct __sk_buff *skb,
struct flow_bucket *flow, __u8 *out_val)
{
+ int cur_len = skb->len;
+
if (flow->bulk_timeout)
return;
- if (config->prio_max_avg_pkt_len &&
- ewma(&flow->pkt_len_avg, skb->len) <= config->prio_max_avg_pkt_len)
+ if (!config->prio_max_avg_pkt_len)
+ return;
+
+ if (skb->gso_segs > 1)
+ cur_len /= skb->gso_segs;
+
+ if (ewma(&flow->pkt_len_avg, cur_len) <= config->prio_max_avg_pkt_len)
*out_val = config->dscp_prio;
}
config = get_config();
if (!config)
- return TC_ACT_OK;
+ return TC_ACT_UNSPEC;
if (module_flags & QOSIFY_IP_ONLY)
type = skb->protocol;
else if (type == bpf_htons(ETH_P_IPV6))
ip_val = parse_ipv6(config, skb, &offset, ingress, &dscp);
else
- return TC_ACT_OK;
+ return TC_ACT_UNSPEC;
if (ip_val) {
if (!ip_val->seen)
}
if (dscp_lookup_class(&dscp, ingress, &class))
- return TC_ACT_OK;
+ return TC_ACT_UNSPEC;
if (class) {
check_flow(&class->config, skb, &dscp);
if (dscp_lookup_class(&dscp, ingress, &class))
- return TC_ACT_OK;
+ return TC_ACT_UNSPEC;
}
dscp &= GENMASK(5, 0);
else if (type == bpf_htons(ETH_P_IPV6))
ipv6_change_dsfield(skb, iph_offset, INET_ECN_MASK, dscp, force);
- return TC_ACT_OK;
+ return TC_ACT_UNSPEC;
}
char _license[] SEC("license") = "GPL";