Skip to content

Commit

Permalink
DNS enhancement features [BP 1.6.2] (#394)
Browse files Browse the repository at this point in the history
* Allow DNS tracking to use configurable port for tracking

Today DNS tracking uses only port 53 which is the
port defined for DNS service and it get mapped
to different port at the container level to
avoid root access. This change wil allow
tracking at the pod level as well

Signed-off-by: Mohamed Mahmoud <[email protected]>
(cherry picked from commit 45824dd)

* shrink dns port to u16 as that should be enough

Signed-off-by: Mohamed Mahmoud <[email protected]>
(cherry picked from commit fa535f2)

* Allow flow filtering for L4 protocols using two ports

For example allow TCP ports="80,100" with por1 always < port2

Signed-off-by: Mohamed Mahmoud <[email protected]>
(cherry picked from commit e68c3ba)

* Allow filtering with wildcard protocol field

Signed-off-by: Mohamed Mahmoud <[email protected]>
(cherry picked from commit b53ce35)

* Bump grpc to v1.65.0

Signed-off-by: Mohamed Mahmoud <[email protected]>

---------

Signed-off-by: Mohamed Mahmoud <[email protected]>
  • Loading branch information
msherif1234 authored Aug 22, 2024
1 parent 434968e commit 72b6619
Show file tree
Hide file tree
Showing 120 changed files with 1,515 additions and 11,123 deletions.
1 change: 1 addition & 0 deletions bpf/configs.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ volatile const u8 enable_rtt = 0;
volatile const u8 enable_pca = 0;
volatile const u8 enable_dns_tracking = 0;
volatile const u8 enable_flows_filtering = 0;
volatile const u16 dns_port = 0;
#endif //__CONFIGS_H__
5 changes: 3 additions & 2 deletions bpf/dns_tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
#define __DNS_TRACKER_H__
#include "utils.h"

#define DNS_PORT 53
#define DNS_QR_FLAG 0x8000
#define UDP_MAXMSG 512
#define EINVAL 22
#define DNS_DEFAULT_PORT 53

struct dns_header {
u16 id;
Expand Down Expand Up @@ -67,7 +67,8 @@ static __always_inline u8 calc_dns_header_offset(pkt_info *pkt, void *data_end)

static __always_inline int track_dns_packet(struct __sk_buff *skb, pkt_info *pkt) {
void *data_end = (void *)(long)skb->data_end;
if (pkt->id->dst_port == DNS_PORT || pkt->id->src_port == DNS_PORT) {
if (pkt->id->dst_port == dns_port || pkt->id->src_port == dns_port ||
pkt->id->dst_port == DNS_DEFAULT_PORT || pkt->id->src_port == DNS_DEFAULT_PORT) {
dns_flow_id dns_req;

u8 len = calc_dns_header_offset(pkt, data_end);
Expand Down
162 changes: 80 additions & 82 deletions bpf/flows_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,98 +49,96 @@ static __always_inline int do_flow_filter_lookup(flow_id *id, struct filter_key_
*action = rule->action;
result++;
}

if (rule->protocol != 0) {
if (rule->protocol == id->transport_protocol) {
BPF_PRINTK("protocol matched\n");
result++;
switch (rule->protocol) {
case IPPROTO_TCP:
case IPPROTO_UDP:
case IPPROTO_SCTP:
// dstPort matching
if (rule->dstPortStart != 0 && rule->dstPortEnd == 0) {
if (rule->dstPortStart == id->dst_port) {
BPF_PRINTK("dstPortStart matched\n");
result++;
} else {
result = 0;
goto end;
}
} else if (rule->dstPortStart != 0 && rule->dstPortEnd != 0) {
if (rule->dstPortStart <= id->dst_port &&
id->dst_port <= rule->dstPortEnd) {
BPF_PRINTK("dstPortStart and dstPortEnd matched\n");
result++;
} else {
result = 0;
goto end;
}
// match specific rule protocol or use wildcard protocol
if (rule->protocol == id->transport_protocol || rule->protocol == 0) {
switch (id->transport_protocol) {
case IPPROTO_TCP:
case IPPROTO_UDP:
case IPPROTO_SCTP:
// dstPort matching
if ((rule->dstPortStart != 0 && rule->dstPortEnd == 0) || rule->dstPort1 != 0 ||
rule->dstPort2 != 0) {
if (rule->dstPortStart == id->dst_port || rule->dstPort1 == id->dst_port ||
rule->dstPort2 == id->dst_port) {
BPF_PRINTK("dstPort matched\n");
result++;
} else {
result = 0;
goto end;
}
// srcPort matching
if (rule->srcPortStart != 0 && rule->srcPortEnd == 0) {
if (rule->srcPortStart == id->src_port) {
BPF_PRINTK("srcPortStart matched\n");
result++;
} else {
result = 0;
goto end;
}
} else if (rule->srcPortStart != 0 && rule->srcPortEnd != 0) {
if (rule->srcPortStart <= id->src_port &&
id->src_port <= rule->srcPortEnd) {
BPF_PRINTK("srcPortStart and srcPortEnd matched\n");
result++;
} else {
result = 0;
goto end;
}
} else if (rule->dstPortStart != 0 && rule->dstPortEnd != 0) {
if (rule->dstPortStart <= id->dst_port && id->dst_port <= rule->dstPortEnd) {
BPF_PRINTK("dstPortStart and dstPortEnd matched\n");
result++;
} else {
result = 0;
goto end;
}
// Generic port matching check for either src or dst port
if (rule->portStart != 0 && rule->portEnd == 0) {
if (rule->portStart == id->src_port || rule->portStart == id->dst_port) {
BPF_PRINTK("portStart matched\n");
result++;
} else {
result = 0;
goto end;
}
} else if (rule->portStart != 0 && rule->portEnd != 0) {
if ((rule->portStart <= id->src_port && id->src_port <= rule->portEnd) ||
(rule->portStart <= id->dst_port && id->dst_port <= rule->portEnd)) {
BPF_PRINTK("portStart and portEnd matched\n");
result++;
} else {
result = 0;
goto end;
}
}
// srcPort matching
if ((rule->srcPortStart != 0 && rule->srcPortEnd == 0) || rule->srcPort1 != 0 ||
rule->srcPort2 != 0) {
if (rule->srcPortStart == id->src_port || rule->srcPort1 == id->src_port ||
rule->srcPort2 == id->src_port) {
BPF_PRINTK("srcPort matched\n");
result++;
} else {
result = 0;
goto end;
}
break;
case IPPROTO_ICMP:
case IPPROTO_ICMPV6:
if (rule->icmpType != 0) {
if (rule->icmpType == id->icmp_type) {
BPF_PRINTK("icmpType matched\n");
} else if (rule->srcPortStart != 0 && rule->srcPortEnd != 0) {
if (rule->srcPortStart <= id->src_port && id->src_port <= rule->srcPortEnd) {
BPF_PRINTK("srcPortStart and srcPortEnd matched\n");
result++;
} else {
result = 0;
goto end;
}
}
// Generic port matching check for either src or dst port
if ((rule->portStart != 0 && rule->portEnd == 0) || rule->port1 != 0 ||
rule->port2 != 0) {
if (rule->portStart == id->src_port || rule->portStart == id->dst_port ||
rule->port1 == id->src_port || rule->port1 == id->dst_port ||
rule->port2 == id->src_port || rule->port2 == id->dst_port) {
BPF_PRINTK("port matched\n");
result++;
} else {
result = 0;
goto end;
}
} else if (rule->portStart != 0 && rule->portEnd != 0) {
if ((rule->portStart <= id->src_port && id->src_port <= rule->portEnd) ||
(rule->portStart <= id->dst_port && id->dst_port <= rule->portEnd)) {
BPF_PRINTK("portStart and portEnd matched\n");
result++;
} else {
result = 0;
goto end;
}
}
break;
case IPPROTO_ICMP:
case IPPROTO_ICMPV6:
if (rule->icmpType != 0) {
if (rule->icmpType == id->icmp_type) {
BPF_PRINTK("icmpType matched\n");
result++;
} else {
result = 0;
goto end;
}
if (rule->icmpCode != 0) {
if (rule->icmpCode == id->icmp_code) {
BPF_PRINTK("icmpCode matched\n");
result++;
} else {
result = 0;
goto end;
}
if (rule->icmpCode != 0) {
if (rule->icmpCode == id->icmp_code) {
BPF_PRINTK("icmpCode matched\n");
result++;
} else {
result = 0;
goto end;
}
}
}
break;
}
} else {
result = 0;
goto end;
break;
}
}

Expand Down
6 changes: 6 additions & 0 deletions bpf/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,16 @@ struct filter_value_t {
u8 protocol;
u16 dstPortStart;
u16 dstPortEnd;
u16 dstPort1;
u16 dstPort2;
u16 srcPortStart;
u16 srcPortEnd;
u16 srcPort1;
u16 srcPort2;
u16 portStart;
u16 portEnd;
u16 port1;
u16 port2;
u8 icmpType;
u8 icmpCode;
direction direction;
Expand Down
7 changes: 5 additions & 2 deletions docs/flow_filtering.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@ Rule-base filtering is a method to control the flow of packets cached in the eBP
- `FILTER_PROTOCOL` - Protocol of the flow filter rule. Possible values are `TCP`, `UDP`, `SCTP`, `ICMP`, `ICMPv6`.
- `FILTER_SOURCE_PORT` - Single Source port of the flow filter rule.
- `FILTER_SOURCE_PORT_RANGE` - Source port range of the flow filter rule. using "80-100" format.
- `FILTER_SOURCE_PORTS` - Source port two values of the flow filter rule. using "80,100" format.
- `FILTER_DESTINATION_PORT` - Single Destination port of the flow filter rule.
- `FILTER_DESTINATION_PORT_RANGE` - Destination port range of the flow filter rule. using "80-100" format.
- `FILTER_PORT` - Single L4 port of the flow filter rule, can be either source or destination port.
- `FILTER_PORT_RANGE` - L4 port range of the flow filter rule. using "80-100" format can be either source or destination ports range.
- `FILTER_DESTINATION_PORTS` - Destination port two values of the flow filter rule. using "80,100" format.
- `FILTER_PORT` - Single L4 port of the flow filter rule can be either source or destination port.
- `FILTER_PORT_RANGE` - L4 port range of the flow filter rule. using "80–100" format can be either a source or destination ports range.
- `FILTER_PORTS` - Two ports values of the flow filter rule. using "80,100" format can be either two ports for src or two ports for destination.
- `FILTER_ICMP_TYPE` - ICMP type of the flow filter rule.
- `FILTER_ICMP_CODE` - ICMP code of the flow filter rule.
- `FILTER_PEER_IP` - Specific Peer IP address of the flow filter rule.
Expand Down
19 changes: 9 additions & 10 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ require (
github.com/vladimirvivien/gexe v0.3.0
github.com/vmware/go-ipfix v0.9.0
golang.org/x/sys v0.21.0
google.golang.org/grpc v1.63.2
google.golang.org/grpc v1.65.0
google.golang.org/protobuf v1.34.2
gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.30.2
Expand All @@ -40,7 +40,7 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
Expand Down Expand Up @@ -113,16 +113,15 @@ require (
go.opentelemetry.io/otel/trace v1.26.0 // indirect
go.opentelemetry.io/proto/otlp v1.2.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/oauth2 v0.18.0 // indirect
golang.org/x/term v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/oauth2 v0.20.0 // indirect
golang.org/x/term v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
golang.org/x/time v0.5.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
Loading

0 comments on commit 72b6619

Please sign in to comment.