Skip to content

Commit

Permalink
Merge Main to Release 1.0 (#55)
Browse files Browse the repository at this point in the history
* Mocks for public APIs

* PR feedback

* Make the sdk client global for mocks

* Update sdk client for NA mocks (#26)

* Update sdk client

* fix var

* API interface change and UTs for TC functions (#25)

* UTs for tc functions

* Fix vet

* Add mocks

* Feedback

* PR feedbacl

* UTs for recovery and progs (#27)

* UTs for recovery and progs

* PR feedbacks

* UTs for cache and kprobes (#28)

* Xdp and Events UT (#29)

* XDP and events update

* cleanup

* Third party attribution doc

* readme-v1 (#30)

* Update README.md (#33)

* Update README.md

* chore: spelling in README (#36)

* Add github action for functional tests

* Merge issue with func tests (#38)

* test-data: Fix to use __builtin_memset() instead of memset() (#40)

In BPF programs, when using functions like `memset()` and `memcpy()`,
you should use LLVM built-in functions like `__builtin_memset()`.

Signed-off-by: shun159 <dreamdiagnosis@gmail.com>

* Bump golang.org/x/sys from 0.6.0 to 0.12.0 (#41)

Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.6.0 to 0.12.0.
- [Commits](golang/sys@v0.6.0...v0.12.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Fixup poller for events race condition (#43)

* Fixup poller for events race condition

* Testing package go tidy

* makefile: fix to remove unused option from build-bpf target (#42)

* makefile: fix to remove unused option from build-bpf target

Signed-off-by: shun159 <dreamdiagnosis@gmail.com>

* makefile: refactor using pattern rule

Signed-off-by: shun159 <dreamdiagnosis@gmail.com>

---------

Signed-off-by: shun159 <dreamdiagnosis@gmail.com>

* test-data: fix to solve compile warning for test-data (#45)

* test-data: fix to solve compile warning for test-data

use `void`instead of the `struct sched_process_fork_t` to solve
compile warnings for resolvedata and tc.ingress

```shellsesson
$ doas make test-data/recoverydata.bpf.elf
clang -I../../.. -g -O2 -Wall -fpie -target bpf -DCORE -D__BPF_TRACING__ -D__TARGET_ARCH_x86  -c test-data/recoverydata.bpf.c -o test-data/recoverydata.bpf.elf
test-data/recoverydata.bpf.c:101:31: warning: declaration of 'struct sched_process_fork_t' will not be visible outside of this function [-Wvisibility]
int sched_process_fork(struct sched_process_fork_t *ctx) {
                              ^
1 warning generated.
```

Signed-off-by: shun159 <dreamdiagnosis@gmail.com>

* makefile: Refactor the vmlinux and unit-test targets

1. Check the existence of the /sys/kernel/btf/vmlinux file before generating the header file using bpftool.

2. Improve the idempotency of the vmlinux target.

3. Add the `LOGFILE_PATH` variable to allow specifying a different path for the `AWS_EBPF_SDK_LOG_FILE`.

Signed-off-by: shun159 <dreamdiagnosis@gmail.com>

---------

Signed-off-by: shun159 <dreamdiagnosis@gmail.com>

* kprobe: Add defer statements for resource cleanup in KprobeAttach()/KretprobeAttach (#46)

Ensure that file handle is properly closed using `defer` statements.

Signed-off-by: shun159 <dreamdiagnosis@gmail.com>

* Add v6 test and inc log level (#53)

* Fix verifier log buffer size (#54)

---------

Signed-off-by: shun159 <dreamdiagnosis@gmail.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Apurup Chevuru <60630804+achevuru@users.noreply.github.com>
Co-authored-by: Alex Jones <alex@k8sgpt.ai>
Co-authored-by: Davanum Srinivas <davanum@gmail.com>
Co-authored-by: Eishun Kondoh <dreamdiagnosis@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Loading branch information
6 people authored Oct 18, 2023
1 parent 6ecc2a6 commit 2df701c
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 4 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Note: This is the first version of SDK and interface is subject to change so kin

## How to build SDK?

Run `make buid-linux` - this will build the sdk binary.
Run `make build-linux` - this will build the sdk binary.

## How to build elf file?

Expand Down
14 changes: 12 additions & 2 deletions pkg/progs/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"os"
"path/filepath"
"runtime"
"strings"
"syscall"
"unsafe"

Expand Down Expand Up @@ -184,6 +185,12 @@ func (m *BpfProgram) UnPinProg(pinPath string) error {
return unix.Close(int(m.ProgFD))
}

func parseLogs(log []byte) []string {
logStr := string(log)
logs := strings.Split(logStr, "\n")
return logs
}

func (m *BpfProgram) LoadProg(progMetaData CreateEBPFProgInput) (int, error) {

var prog_type uint32
Expand All @@ -204,7 +211,7 @@ func (m *BpfProgram) LoadProg(progMetaData CreateEBPFProgInput) (int, error) {
prog_type = uint32(netlink.BPF_PROG_TYPE_UNSPEC)
}

logBuf := make([]byte, 65535)
logBuf := make([]byte, utils.GetLogBufferSize())
program := netlink.BPFAttr{
ProgType: prog_type,
LogBuf: uintptr(unsafe.Pointer(&logBuf[0])),
Expand All @@ -227,7 +234,10 @@ func (m *BpfProgram) LoadProg(progMetaData CreateEBPFProgInput) (int, error) {

log.Infof("Load prog done with fd : %d", int(fd))
if errno != 0 {
log.Errorf(string(logBuf))
logArray := parseLogs(logBuf)
for _, str := range logArray {
fmt.Println(str)
}
return -1, errno
}

Expand Down
5 changes: 5 additions & 0 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package utils
import (
"encoding/binary"
"fmt"
"math"
"os"
"runtime"
"syscall"
Expand Down Expand Up @@ -194,3 +195,7 @@ func Unmount_bpf_fs() error {
}
return err
}

func GetLogBufferSize() int {
return math.MaxUint32 >> 8
}
142 changes: 142 additions & 0 deletions test/c/test-v6.bpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>

#define BPF_F_NO_PREALLOC 1
#define ETH_HLEN 14
#define BPF_MAP_ID_INGRESS_MAP 2
#define MAX_RULES 256
#define MIN_RULES 128
#define PIN_GLOBAL_NS 2
#define RESERVED_IP_PROTOCOL 255
#define ANY_IP_PROTOCOL 254
#define ANY_PORT 0

struct bpf_map_def_pvt {
__u32 type;
__u32 key_size;
__u32 value_size;
__u32 max_entries;
__u32 map_flags;
__u32 pinning;
__u32 inner_map_fd;
};

struct keystruct
{
__u32 prefix_len;
__u8 ip[16];
};

struct lpm_trie_key {
__u32 prefixlen;
__u8 ip[16];
};

struct lpm_trie_val {
__u32 protocol;
__u32 start_port;
__u32 end_port;
};

struct bpf_map_def_pvt SEC("maps") ingress_map = {
.type = BPF_MAP_TYPE_LPM_TRIE,
.key_size =sizeof(struct lpm_trie_key),
.value_size = sizeof(struct lpm_trie_val[30]),
.max_entries = 65536,
.map_flags = BPF_F_NO_PREALLOC,
.pinning = PIN_GLOBAL_NS,
};


SEC("tc_cls")
int handle_ingress(struct __sk_buff *skb)
{
struct keystruct trie_key;
struct lpm_trie_val *trie_val;
__u16 l4_src_port = 0;
__u16 l4_dst_port = 0;
void *data_end = (void *)(long)skb->data_end;
void *data = (void *)(long)skb->data;


struct ethhdr *ether = data;
if (data + sizeof(*ether) > data_end) {
return BPF_OK;
}

if (ether->h_proto == 0xdd86) { // htons(ETH_P_IPV6) -> 0x086ddU
data += sizeof(*ether);
struct ipv6hdr *ip = data;
struct tcphdr *l4_tcp_hdr = data + sizeof(struct ipv6hdr);
struct udphdr *l4_udp_hdr = data + sizeof(struct ipv6hdr);
struct sctphdr *l4_sctp_hdr = data + sizeof(struct ipv6hdr);

if (data + sizeof(*ip) > data_end) {
return BPF_OK;
}

if (ip->version != 6) {
return BPF_OK;
}

//ICMPv6 - Neighbor Discovery Packets
if (ip->nexthdr == 58) {
return BPF_OK;
}

switch (ip->nexthdr) {
case IPPROTO_TCP:
if (data + sizeof(*ip) + sizeof(*l4_tcp_hdr) > data_end) {
return BPF_OK;
}
l4_src_port = (((((unsigned short)(l4_tcp_hdr->source) & 0xFF)) << 8) | (((unsigned short)(l4_tcp_hdr->source) & 0xFF00) >> 8));
l4_dst_port = (((((unsigned short)(l4_tcp_hdr->dest) & 0xFF)) << 8) | (((unsigned short)(l4_tcp_hdr->dest) & 0xFF00) >> 8));
break;
case IPPROTO_UDP:
if (data + sizeof(*ip) + sizeof(*l4_udp_hdr) > data_end) {
return BPF_OK;
}
l4_src_port = (((((unsigned short)(l4_udp_hdr->source) & 0xFF)) << 8) | (((unsigned short)(l4_udp_hdr->source) & 0xFF00) >> 8));
l4_dst_port = (((((unsigned short)(l4_udp_hdr->dest) & 0xFF)) << 8) | (((unsigned short)(l4_udp_hdr->dest) & 0xFF00) >> 8));
break;
case IPPROTO_SCTP:
if (data + sizeof(*ip) + sizeof(*l4_sctp_hdr) > data_end) {
return BPF_OK;
}
l4_src_port = (((((unsigned short)(l4_sctp_hdr->source) & 0xFF)) << 8) | (((unsigned short)(l4_sctp_hdr->source) & 0xFF00) >> 8));
l4_dst_port = (((((unsigned short)(l4_sctp_hdr->dest) & 0xFF)) << 8) | (((unsigned short)(l4_sctp_hdr->dest) & 0xFF00) >> 8));
break;
}

trie_key.prefix_len = 128;
//Fill the IP Key to be used for lookup
for (int i=0; i<16; i++){
trie_key.ip[i] = ip->saddr.in6_u.u6_addr8[i];
}

//Check if it's in the allowed list
trie_val = bpf_map_lookup_elem(&ingress_map, &trie_key);
if (trie_val == NULL) {
return BPF_DROP;
}

for (int i=0; i<30; i++, trie_val++){
if (trie_val->protocol == RESERVED_IP_PROTOCOL) {
return BPF_DROP;
}

if ((trie_val->protocol == ANY_IP_PROTOCOL) || (trie_val->protocol == ip->nexthdr &&
((trie_val->start_port == ANY_PORT) || (l4_dst_port == trie_val->start_port) ||
(l4_dst_port > trie_val->start_port && l4_dst_port <= trie_val->end_port)))) {
return BPF_OK;
}
}
return BPF_DROP;
}
return BPF_OK;

}

char _license[] SEC("license") = "GPL";
14 changes: 13 additions & 1 deletion test/c/test.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ struct lpm_trie_val {
struct bpf_map_def_pvt SEC("maps") ingress_map = {
.type = BPF_MAP_TYPE_LPM_TRIE,
.key_size =sizeof(struct lpm_trie_key),
.value_size = sizeof(struct lpm_trie_val[8]),
.value_size = sizeof(struct lpm_trie_val[30]),
.max_entries = 65536,
.map_flags = BPF_F_NO_PREALLOC,
.pinning = PIN_GLOBAL_NS,
Expand Down Expand Up @@ -114,6 +114,18 @@ int handle_ingress(struct __sk_buff *skb)
return BPF_DROP;
}

for (int i=0; i<30; i++, trie_val++){
if (trie_val->protocol == RESERVED_IP_PROTOCOL) {
return BPF_DROP;
}

if ((trie_val->protocol == ANY_IP_PROTOCOL) || (trie_val->protocol == ip->protocol &&
((trie_val->start_port == ANY_PORT) || (l4_dst_port == trie_val->start_port) ||
(l4_dst_port > trie_val->start_port && l4_dst_port <= trie_val->end_port)))) {
return BPF_OK;
}
}

return BPF_OK;

}
Expand Down
15 changes: 15 additions & 0 deletions test/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func main() {
mount_bpf_fs()
testFunctions := []testFunc{
{Name: "Test loading Program", Func: TestLoadProg},
{Name: "Test loading V6 Program", Func: TestLoadv6Prog},
{Name: "Test loading TC filter", Func: TestLoadTCfilter},
{Name: "Test loading Maps without Program", Func: TestLoadMapWithNoProg},
{Name: "Test loading Map operations", Func: TestMapOperations},
Expand Down Expand Up @@ -110,6 +111,20 @@ func TestLoadProg() error {
return nil
}

func TestLoadv6Prog() error {
gosdkClient := goelf.New()
progInfo, _, err := gosdkClient.LoadBpfFile("c/test-v6.bpf.elf", "test")
if err != nil {
fmt.Println("Load BPF failed", "err:", err)
return err
}

for pinPath, _ := range progInfo {
fmt.Println("Prog Info: ", "Pin Path: ", pinPath)
}
return nil
}

func TestLoadMapWithNoProg() error {
gosdkClient := goelf.New()
_, loadedMap, err := gosdkClient.LoadBpfFile("c/test-map.bpf.elf", "test")
Expand Down

0 comments on commit 2df701c

Please sign in to comment.