This commit is contained in:
yunwei37
2023-06-03 15:42:19 +00:00
parent 4fa77d68db
commit 35f3c97912
110 changed files with 14135 additions and 1032 deletions

8
29-sockops/.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
.vscode
package.json
*.o
*.skel.json
*.skel.yaml
package.yaml
ecli
ecc

27
29-sockops/bpf_redir.c Normal file
View File

@@ -0,0 +1,27 @@
#include <linux/bpf.h>
#include <sys/socket.h>
#include "bpf_sockops.h"
__section("sk_msg")
int bpf_redir(struct sk_msg_md *msg)
{
__u64 flags = BPF_F_INGRESS;
struct sock_key key = {};
sk_msg_extract4_key(msg, &key);
// See whether the source or destination IP is local host
if (key.sip4 == 16777343 || key.dip4 == 16777343) {
// See whether the source or destination port is 10000
if (key.sport == 4135 || key.dport == 4135) {
int len1 = (__u64)msg->data_end - (__u64)msg->data;
printk("<<< redir_proxy port %d --> %d (%d)\n", key.sport, key.dport, len1);
msg_redirect_hash(msg, &sock_ops_map, &key, flags);
}
}
return SK_PASS;
}
BPF_LICENSE("GPL");
int _version __section("version") = 1;

52
29-sockops/bpf_sockops.c Normal file
View File

@@ -0,0 +1,52 @@
#include <linux/bpf.h>
#include <linux/bpf_common.h>
#include <sys/socket.h>
#include "bpf_sockops.h"
static inline void bpf_sock_ops_ipv4(struct bpf_sock_ops *skops)
{
struct sock_key key = {};
sk_extract4_key(skops, &key);
if (key.dip4 == 16777343 || key.sip4 == 16777343 ) {
if (key.dport == 4135 || key.sport == 4135) {
int ret = sock_hash_update(skops, &sock_ops_map, &key, BPF_NOEXIST);
printk("<<< ipv4 op = %d, port %d --> %d\n", skops->op, key.sport, key.dport);
if (ret != 0)
printk("*** FAILED %d ***\n", ret);
}
}
}
static inline void bpf_sock_ops_ipv6(struct bpf_sock_ops *skops)
{
if (skops->remote_ip4)
bpf_sock_ops_ipv4(skops);
}
__section("sockops")
int bpf_sockmap(struct bpf_sock_ops *skops)
{
__u32 family, op;
family = skops->family;
op = skops->op;
printk("<<< op %d, port = %d --> %d\n", op, skops->local_port, skops->remote_port);
switch (op) {
case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:
case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB:
if (family == AF_INET6)
bpf_sock_ops_ipv6(skops);
else if (family == AF_INET)
bpf_sock_ops_ipv4(skops);
break;
default:
break;
}
return 0;
}
BPF_LICENSE("GPL");
int _version __section("version") = 1;

168
29-sockops/bpf_sockops.h Normal file
View File

@@ -0,0 +1,168 @@
#include <linux/types.h>
#include <linux/swab.h>
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define __bpf_ntohs(x) __builtin_bswap16(x)
# define __bpf_htons(x) __builtin_bswap16(x)
# define __bpf_constant_ntohs(x) ___constant_swab16(x)
# define __bpf_constant_htons(x) ___constant_swab16(x)
# define __bpf_ntohl(x) __builtin_bswap32(x)
# define __bpf_htonl(x) __builtin_bswap32(x)
# define __bpf_constant_ntohl(x) ___constant_swab32(x)
# define __bpf_constant_htonl(x) ___constant_swab32(x)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define __bpf_ntohs(x) (x)
# define __bpf_htons(x) (x)
# define __bpf_constant_ntohs(x) (x)
# define __bpf_constant_htons(x) (x)
# define __bpf_ntohl(x) (x)
# define __bpf_htonl(x) (x)
# define __bpf_constant_ntohl(x) (x)
# define __bpf_constant_htonl(x) (x)
#else
# error "Fix your compiler's __BYTE_ORDER__?!"
#endif
#define bpf_htons(x) \
(__builtin_constant_p(x) ? \
__bpf_constant_htons(x) : __bpf_htons(x))
#define bpf_ntohs(x) \
(__builtin_constant_p(x) ? \
__bpf_constant_ntohs(x) : __bpf_ntohs(x))
#define bpf_htonl(x) \
(__builtin_constant_p(x) ? \
__bpf_constant_htonl(x) : __bpf_htonl(x))
#define bpf_ntohl(x) \
(__builtin_constant_p(x) ? \
__bpf_constant_ntohl(x) : __bpf_ntohl(x))
/** Section helper macros. */
#ifndef __section
# define __section(NAME) \
__attribute__((section(NAME), used))
#endif
#ifndef __section_tail
# define __section_tail(ID, KEY) \
__section(__stringify(ID) "/" __stringify(KEY))
#endif
#ifndef __section_cls_entry
# define __section_cls_entry \
__section("classifier")
#endif
#ifndef __section_act_entry
# define __section_act_entry \
__section("action")
#endif
#ifndef __section_license
# define __section_license \
__section("license")
#endif
#ifndef __section_maps
# define __section_maps \
__section("maps")
#endif
/** Declaration helper macros. */
#ifndef BPF_LICENSE
# define BPF_LICENSE(NAME) \
char ____license[] __section_license = NAME
#endif
#ifndef BPF_FUNC
# define BPF_FUNC(NAME, ...) \
(*NAME)(__VA_ARGS__) = (void *)BPF_FUNC_##NAME
#endif
static int BPF_FUNC(sock_hash_update, struct bpf_sock_ops *skops, void *map, void *key, uint64_t flags);
static int BPF_FUNC(msg_redirect_hash, struct sk_msg_md *md, void *map, void *key, uint64_t flags);
static void BPF_FUNC(trace_printk, const char *fmt, int fmt_size, ...);
#ifndef printk
# define printk(fmt, ...) \
({ \
char ____fmt[] = fmt; \
trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__); \
})
#endif
struct bpf_map_def {
__u32 type;
__u32 key_size;
__u32 value_size;
__u32 max_entries;
__u32 map_flags;
};
union v6addr {
struct {
__u32 p1;
__u32 p2;
__u32 p3;
__u32 p4;
};
__u8 addr[16];
};
struct sock_key {
union {
struct {
__u32 sip4;
__u32 pad1;
__u32 pad2;
__u32 pad3;
};
union v6addr sip6;
};
union {
struct {
__u32 dip4;
__u32 pad4;
__u32 pad5;
__u32 pad6;
};
union v6addr dip6;
};
__u8 family;
__u8 pad7;
__u16 pad8;
__u32 sport;
__u32 dport;
} __attribute__((packed));
struct bpf_map_def __section_maps sock_ops_map = {
.type = BPF_MAP_TYPE_SOCKHASH,
.key_size = sizeof(struct sock_key),
.value_size = sizeof(int),
.max_entries = 65535,
.map_flags = 0,
};
static inline void sk_extract4_key(struct bpf_sock_ops *ops,
struct sock_key *key)
{
key->dip4 = ops->remote_ip4;
key->sip4 = ops->local_ip4;
key->family = 1;
key->sport = (bpf_htonl(ops->local_port) >> 16);
key->dport = ops->remote_port >> 16;
}
static inline void sk_msg_extract4_key(struct sk_msg_md *msg,
struct sock_key *key)
{
key->sip4 = msg->remote_ip4;
key->dip4 = msg->local_ip4;
key->family = 1;
key->dport = (bpf_htonl(msg->local_port) >> 16);
key->sport = msg->remote_port >> 16;
}

View File

@@ -0,0 +1,3 @@
FROM envoyproxy/envoy:latest
COPY envoy.yaml /etc/envoy/envoy.yaml
EXPOSE 9901

View File

@@ -0,0 +1,30 @@
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 9901
static_resources:
listeners:
- name: iperf3-listener
address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.tcp_proxy
config:
stat_prefix: iperf3-listener
cluster: iperf3_server
clusters:
- name: iperf3_server
connect_timeout: 1.0s
type: static
lb_policy: ROUND_ROBIN
hosts:
- socket_address:
address: 127.0.0.1
port_value: 5201

245
29-sockops/index.html Normal file

File diff suppressed because one or more lines are too long

20
29-sockops/load.sh Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/bash
set -x
set -e
# Mount bpf filesystem
sudo mount -t bpf bpf /sys/fs/bpf/
# Load the bpf_sockops program
sudo bpftool prog load bpf_sockops.o "/sys/fs/bpf/bpf_sockop"
sudo bpftool cgroup attach "/sys/fs/cgroup/unified/" sock_ops pinned "/sys/fs/bpf/bpf_sockop"
MAP_ID=$(sudo bpftool prog show pinned "/sys/fs/bpf/bpf_sockop" | grep -o -E 'map_ids [0-9]+' | awk '{print $2}')
sudo bpftool map pin id $MAP_ID "/sys/fs/bpf/sock_ops_map"
# Load the bpf_redir program
if [ -z $1 ]
then
sudo bpftool prog load bpf_redir.o "/sys/fs/bpf/bpf_redir" map name sock_ops_map pinned "/sys/fs/bpf/sock_ops_map"
sudo bpftool prog attach pinned "/sys/fs/bpf/bpf_redir" msg_verdict pinned "/sys/fs/bpf/sock_ops_map"
fi

BIN
29-sockops/merbridge.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

2
29-sockops/trace.sh Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
sudo cat /sys/kernel/debug/tracing/trace_pipe

13
29-sockops/unload.sh Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/bash
set -x
# UnLoad the bpf_redir program
sudo bpftool prog detach pinned "/sys/fs/bpf/bpf_redir" msg_verdict pinned "/sys/fs/bpf/sock_ops_map"
sudo rm "/sys/fs/bpf/bpf_redir"
# UnLoad the bpf_sockops program
sudo bpftool cgroup detach "/sys/fs/cgroup/unified/" sock_ops pinned "/sys/fs/bpf/bpf_sockop"
sudo rm "/sys/fs/bpf/bpf_sockop"
# Delete the map
sudo rm "/sys/fs/bpf/sock_ops_map"