Skip to content

Commit

Permalink
add basic l3dsr dscp
Browse files Browse the repository at this point in the history
  • Loading branch information
Shikugawa committed May 28, 2023
1 parent 9857c64 commit 81fb422
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 0 deletions.
5 changes: 5 additions & 0 deletions examples/basic_l3dsr/dscp/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

FROM ubuntu:22.04

RUN apt update \
&& apt install -y libc6-dev-i386 clang libbpf-dev iproute2
76 changes: 76 additions & 0 deletions examples/basic_l3dsr/dscp/spec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
preinit:
- cmds:
- cmd: docker build -t xdptmp .

nodes:
- name: R1
image: xdptmp
interfaces:
- { name: net1, type: direct, args: CLOS#net1 }
sysctls:
- sysctl: net.ipv4.ip_forward=1
- sysctl: net.ipv4.conf.all.rp_filter=0
- sysctl: net.ipv4.conf.default.rp_filter=0

- name: C1
image: slankdev/mikanectl
docker_run_extra_args: --entrypoint bash
interfaces:
- { name: net0, type: direct, args: CLOS#net0 }
sysctls:
- sysctl: net.ipv4.ip_forward=1
- sysctl: net.ipv4.conf.all.rp_filter=0
- sysctl: net.ipv4.conf.default.rp_filter=0

- name: C2
image: slankdev/mikanectl
docker_run_extra_args: --entrypoint bash
interfaces:
- { name: net2, type: direct, args: CLOS#net2 }
sysctls:
- sysctl: net.ipv4.ip_forward=1
- sysctl: net.ipv4.conf.all.rp_filter=0
- sysctl: net.ipv4.conf.default.rp_filter=0

- name: CLOS
image: nicolaka/netshoot
interfaces:
- { name: net0, type: direct, args: C1#net0 }
- { name: net1, type: direct, args: R1#net1 }
- { name: net2, type: direct, args: C2#net2 }
sysctls:
- sysctl: net.ipv4.ip_forward=1
- sysctl: net.ipv4.conf.all.rp_filter=0
- sysctl: net.ipv4.conf.default.rp_filter=0

postinit:
cmds:
- cmd: docker cp xdp.c R1:/root/xdp.c
- cmd: docker exec R1 clang -O2 -Wall -target bpf -c /root/xdp.c
- cmd: docker exec R1 ip link set net1 xdpgeneric obj lb.o sec xdp-lb

node_configs:
- name: R1
cmds:
- cmd: ip addr add 142.0.0.1/32 dev lo
- cmd: ip addr add 10.0.1.1/24 dev net1
- cmd: ip route add default via 10.0.1.2
- name: C1
cmds:
- cmd: ip addr add 10.0.0.1/24 dev net0
- cmd: ip route add default via 10.0.0.2
- name: C2
cmds:
- cmd: nohup mikanectl ifconfig-http -p 80 &
- cmd: ip addr add 10.0.2.1/24 dev net2
- cmd: ip route add default via 10.0.2.2
- cmd: ip route add local 142.0.0.1/32 dev lo
- cmd: tc qdisc add dev net2 clsact
- cmd: tc filter add dev net2 ingress u32 match ip dsfield 0xa 0x1e action nat ingress 10.0.2.1 142.0.0.1

- name: CLOS
cmds:
- cmd: ip addr add 10.0.0.2/24 dev net0
- cmd: ip addr add 10.0.1.2/24 dev net1
- cmd: ip addr add 10.0.2.2/24 dev net2
- cmd: ip route add 142.0.0.1/32 dev net1
85 changes: 85 additions & 0 deletions examples/basic_l3dsr/dscp/xdp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/icmp.h>
#include <linux/ip.h>
#include <linux/in.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_endian.h>

#ifndef DSCP
#define DSCP 10
#endif

static __always_inline __u16 csum_fold_helper(__u64 csum) {
int i;
#pragma unroll
for (i = 0; i < 4; i ++) {
if (csum >> 16)
csum = (csum & 0xffff) + (csum >> 16);
}
return ~csum;
}

static __always_inline void ipv4_csum(void *data_start, int data_size, __u64 *csum) {
*csum = bpf_csum_diff(0, 0, data_start, data_size, *csum);
*csum = csum_fold_helper(*csum);
}

static __always_inline int process_ipv4(struct xdp_md* ctx,
__u64 data, __u64 data_end) {
__u8 src_mac[ETH_ALEN];
struct ethhdr *eth;
struct iphdr *iph;

__u32 dst_addr = 0xa000201;
__u64 csum = 0;

eth = (struct ethhdr*)(data);

if ((__u64)(eth + 1) > data_end)
return XDP_DROP;

iph = (struct iphdr*)(data + sizeof(struct ethhdr));

if ((__u64)(iph + 1) > data_end)
return XDP_DROP;

if (iph->daddr == bpf_htonl(0x8e000001)) {
iph->tos = DSCP;
iph->daddr = bpf_htonl(dst_addr);
iph->check = 0;
ipv4_csum(iph, sizeof(struct iphdr), &csum);
iph->check = csum;

__builtin_memcpy(src_mac, eth->h_source, ETH_ALEN);
__builtin_memcpy(eth->h_source, eth->h_dest, ETH_ALEN);
__builtin_memcpy(eth->h_dest, src_mac, ETH_ALEN);

return XDP_TX;
}
return XDP_PASS;
}

static __always_inline int process_eth(struct xdp_md* ctx) {
__u64 data = ctx->data;
__u64 data_end = ctx->data_end;
struct ethhdr *eth;

eth = (struct ethhdr*)data;

if ((__u64)(eth + 1) > data_end)
return XDP_DROP;

if (eth->h_proto == bpf_htons(ETH_P_IP)) {
return process_ipv4(ctx, data, data_end);
}
return XDP_PASS;
}

SEC("xdp-lb")
int entry(struct xdp_md *ctx) {
int ret = process_eth(ctx);
return ret;
}

char __license[] SEC("license") = "GPL";

0 comments on commit 81fb422

Please sign in to comment.