bpf: return TC_ACT_UNSPEC to allow other filters to proceed
[project/qosify.git] / qosify-bpf.c
index eb13e9bd42c956eac7765c5c27b1e95a28183c99..54a1e38e266842a716fbf3858d1fb16dd3912b49 100644 (file)
@@ -44,13 +44,21 @@ struct {
        __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);
@@ -60,9 +68,6 @@ struct {
        __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);
@@ -258,10 +263,12 @@ parse_l4proto(struct qosify_config *config, struct __sk_buff *skb,
                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);
@@ -471,7 +478,7 @@ int classify(struct __sk_buff *skb)
 
        config = get_config();
        if (!config)
-               return TC_ACT_OK;
+               return TC_ACT_UNSPEC;
 
        if (module_flags & QOSIFY_IP_ONLY)
                type = skb->protocol;
@@ -484,7 +491,7 @@ int classify(struct __sk_buff *skb)
        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)
@@ -493,13 +500,13 @@ int classify(struct __sk_buff *skb)
        }
 
        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);
@@ -511,7 +518,7 @@ int classify(struct __sk_buff *skb)
        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";