Skip to content

Commit

Permalink
extend flow filter apis to introduce peerCIDR and make it part of the…
Browse files Browse the repository at this point in the history
… key

Signed-off-by: Mohamed Mahmoud <[email protected]>
  • Loading branch information
msherif1234 committed Jan 7, 2025
1 parent 9e28edf commit 9d5b402
Show file tree
Hide file tree
Showing 14 changed files with 61 additions and 67 deletions.
49 changes: 6 additions & 43 deletions bpf/flows_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,6 @@
if (trace_messages) \
bpf_printk(fmt, ##args)

static __always_inline int is_zero_ip(u8 *ip, u8 len) {
for (int i = 0; i < len; i++) {
if (ip[i] != 0) {
BPF_PRINTK("ip not zero ip[%d]:%d\n", i, ip[i]);
return 0;
}
}
return 1;
}

static __always_inline int is_equal_ip(u8 *ip1, u8 *ip2, u8 len) {
for (int i = 0; i < len; i++) {
if (ip1[i] != ip2[i]) {
BPF_PRINTK("ip mismatched ip1[%d]:%d not equal to ip2[%d]:%d\n", i, ip1[i], i, ip2[i]);
return 0;
}
}
return 1;
}

static __always_inline int do_flow_filter_lookup(flow_id *id, struct filter_key_t *key,
filter_action *action, u8 len, u8 offset,
u16 flags, u32 drop_reason, u32 *sampling) {
Expand Down Expand Up @@ -159,27 +139,6 @@ static __always_inline int do_flow_filter_lookup(flow_id *id, struct filter_key_
goto end;
}

if (!is_zero_ip(rule->ip, len)) {
// for Ingress side we can filter using dstIP and for Egress side we can filter using srcIP
if (id->direction == INGRESS) {
if (is_equal_ip(rule->ip, id->dst_ip + offset, len)) {
BPF_PRINTK("dstIP matched\n");
result++;
} else {
result = 0;
goto end;
}
} else {
if (is_equal_ip(rule->ip, id->src_ip + offset, len)) {
BPF_PRINTK("srcIP matched\n");
result++;
} else {
result = 0;
goto end;
}
}
}

if (rule->direction != MAX_DIRECTION) {
if (rule->direction == id->direction) {
BPF_PRINTK("direction matched\n");
Expand Down Expand Up @@ -214,19 +173,23 @@ static __always_inline int flow_filter_setup_lookup_key(flow_id *id, struct filt
*offset = sizeof(ip4in6);
if (use_src_ip) {
__builtin_memcpy(key->ip_data, id->src_ip + *offset, *len);
__builtin_memcpy(key->peer_ip_data, id->dst_ip + *offset, *len);
} else {
__builtin_memcpy(key->ip_data, id->dst_ip + *offset, *len);
__builtin_memcpy(key->peer_ip_data, id->src_ip + *offset, *len);
}
key->prefix_len = 32;
key->prefix_len = 64;
} else if (eth_protocol == ETH_P_IPV6) {
*len = IP_MAX_LEN;
*offset = 0;
if (use_src_ip) {
__builtin_memcpy(key->ip_data, id->src_ip + *offset, *len);
__builtin_memcpy(key->peer_ip_data, id->dst_ip + *offset, *len);
} else {
__builtin_memcpy(key->ip_data, id->dst_ip + *offset, *len);
__builtin_memcpy(key->peer_ip_data, id->src_ip + *offset, *len);
}
key->prefix_len = 128;
key->prefix_len = 256;
} else {
return -1;
}
Expand Down
6 changes: 3 additions & 3 deletions bpf/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,9 @@ const enum global_counters_key_t *unused9 __attribute__((unused));
// filter key used as key to LPM map to filter out flows that are not interesting for the user
struct filter_key_t {
u32 prefix_len;
u8 peer_ip_data[IP_MAX_LEN];
u8 ip_data[IP_MAX_LEN];
} __attribute__((packed));
} filter_key;

// Force emitting enums/structs into the ELF
const struct filter_key_t *unused10 __attribute__((unused));
Expand Down Expand Up @@ -267,8 +268,7 @@ struct filter_value_t {
tcp_flags tcpFlags;
u8 filter_drops;
u32 sample;
u8 ip[IP_MAX_LEN];
} __attribute__((packed));
} filter_value;

// Force emitting enums/structs into the ELF
const struct filter_value_t *unused12 __attribute__((unused));
Expand Down
1 change: 1 addition & 0 deletions pkg/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ func FlowsAgent(cfg *Config) (*Flows, error) {
FilterIPCIDR: r.FilterIPCIDR,
FilterProtocol: r.FilterProtocol,
FilterPeerIP: r.FilterPeerIP,
FilterPeerCIDR: r.FilterPeerCIDR,
FilterDestinationPort: tracer.ConvertFilterPortsToInstr(r.FilterDestinationPort, r.FilterDestinationPortRange, r.FilterDestinationPorts),
FilterSourcePort: tracer.ConvertFilterPortsToInstr(r.FilterSourcePort, r.FilterSourcePortRange, r.FilterSourcePorts),
FilterPort: tracer.ConvertFilterPortsToInstr(r.FilterPort, r.FilterPortRange, r.FilterPorts),
Expand Down
3 changes: 3 additions & 0 deletions pkg/agent/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ type FlowFilter struct {
FilterDrops bool `json:"drops,omitempty"`
// FilterSample is the sample rate this matching flow will use
FilterSample uint32 `json:"sample,omitempty"`
// FilterPeerCIDR is the PeerIP CIDR to filter flows.
// Example: 10.10.10.0/24 or 100:100:100:100::/64, default is 0.0.0.0/0
FilterPeerCIDR string `json:"peer_cidr,omitempty"`
}

type Config struct {
Expand Down
1 change: 1 addition & 0 deletions pkg/agent/packets_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ func PacketsAgent(cfg *Config) (*Packets, error) {
FilterIPCIDR: r.FilterIPCIDR,
FilterProtocol: r.FilterProtocol,
FilterPeerIP: r.FilterPeerIP,
FilterPeerCIDR: r.FilterPeerCIDR,
FilterDestinationPort: tracer.ConvertFilterPortsToInstr(r.FilterDestinationPort, r.FilterDestinationPortRange, r.FilterDestinationPorts),
FilterSourcePort: tracer.ConvertFilterPortsToInstr(r.FilterSourcePort, r.FilterSourcePortRange, r.FilterSourcePorts),
FilterPort: tracer.ConvertFilterPortsToInstr(r.FilterPort, r.FilterPortRange, r.FilterPorts),
Expand Down
8 changes: 5 additions & 3 deletions pkg/ebpf/bpf_arm64_bpfel.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified pkg/ebpf/bpf_arm64_bpfel.o
Binary file not shown.
8 changes: 5 additions & 3 deletions pkg/ebpf/bpf_powerpc_bpfel.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified pkg/ebpf/bpf_powerpc_bpfel.o
Binary file not shown.
8 changes: 5 additions & 3 deletions pkg/ebpf/bpf_s390_bpfeb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified pkg/ebpf/bpf_s390_bpfeb.o
Binary file not shown.
8 changes: 5 additions & 3 deletions pkg/ebpf/bpf_x86_bpfel.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified pkg/ebpf/bpf_x86_bpfel.o
Binary file not shown.
36 changes: 27 additions & 9 deletions pkg/tracer/flow_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type FilterConfig struct {
FilterIcmpType int
FilterIcmpCode int
FilterPeerIP string
FilterPeerCIDR string
FilterAction string
FilterTCPFlags string
FilterDrops bool
Expand Down Expand Up @@ -82,6 +83,32 @@ func (f *Filter) getFilterKey(config *FilterConfig) (ebpf.BpfFilterKeyT, error)
pfLen, _ := ipNet.Mask.Size()
key.PrefixLen = uint32(pfLen)

if config.FilterPeerCIDR == "" && config.FilterPeerIP == "" {
config.FilterPeerCIDR = "0.0.0.0/0"
}

if config.FilterPeerCIDR != "" {
ip, ipNet, err = net.ParseCIDR(config.FilterPeerCIDR)
if err != nil {
return key, fmt.Errorf("failed to parse FlowFilterPeerCIDR: %w", err)
}
if ip.To4() != nil {
copy(key.PeerIpData[:], ip.To4())
} else {
copy(key.PeerIpData[:], ip.To16())
}
pfLen, _ = ipNet.Mask.Size()
key.PrefixLen += uint32(pfLen)
} else if config.FilterPeerIP != "" {
ip = []byte(config.FilterPeerIP)
copy(key.PeerIpData[:], ip)
if ip.To4() != nil {
key.PrefixLen += 32
} else {
key.PrefixLen += 128
}
}

return key, nil
}

Expand Down Expand Up @@ -129,15 +156,6 @@ func (f *Filter) getFilterValue(config *FilterConfig) (ebpf.BpfFilterValueT, err
val.IcmpType = uint8(config.FilterIcmpType)
val.IcmpCode = uint8(config.FilterIcmpCode)

if config.FilterPeerIP != "" {
ip := net.ParseIP(config.FilterPeerIP)
if ip.To4() != nil {
copy(val.Ip[:], ip.To4())
} else {
copy(val.Ip[:], ip.To16())
}
}

switch config.FilterTCPFlags {
case "SYN":
val.TcpFlags = ebpf.BpfTcpFlagsTSYN_FLAG
Expand Down

0 comments on commit 9d5b402

Please sign in to comment.