Skip to content

Commit 70a07e8

Browse files
committed
tc
1 parent e9fc8f4 commit 70a07e8

File tree

4 files changed

+41
-22
lines changed

4 files changed

+41
-22
lines changed

docker/Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
1212
clang \
1313
libbpf-dev \
1414
iproute2 \
15+
ethtool \
16+
procps \
1517
python3 \
18+
jq \
1619
&& apt-get clean && rm -rf /var/lib/apt/lists/*
1720

1821
#Copy sfunnel stuff

docker/entrypoint.sh

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ _IFACES=$(ls /sys/class/net | tr "\n" " " | sed 's/\s*$//g')
3434
IFACES=${IFACES:-$_IFACES}
3535
NETNS=${NETNS:-}
3636

37-
UNSEG_DEV_NAME=${UNSEG_DEV_NAME:-_unseg}
37+
SEG_DEV_NAME=${SEG_DEV_NAME:-_seg}
3838

3939
PROG=/opt/sfunnel/src/tc_sfunnel.o
4040

4141
#Compile eBPF program only if rulesset are defined at load time
4242
#either via file or ENV
4343
compile(){
4444
cd /opt/sfunnel/src
45-
UNSEG_DEV_IFINDEX=${UNSEG_DEV_IFINDEX} DEBUG=${DEBUG} FILE=/etc/sfunnel/ruleset make
45+
SEG_DEV_MAC="${SEG_DEV_MAC}" SEG_DEV_IFINDEX=${SEG_DEV_IFINDEX} DEBUG=${DEBUG} FILE=/etc/sfunnel/ruleset make
4646
}
4747

4848
#$1: PROG
@@ -96,7 +96,7 @@ echo " \$DEBUG='${DEBUG}'"
9696
echo " \$NETNS='${NETNS}'"
9797
echo " \$N_ATTEMPTS='${N_ATTEMPTS}'"
9898
echo " \$RETRY_DELAY='${RETRY_DELAY}'"
99-
echo " \$UNSEG_DEV_NAME='${UNSEG_DEV_NAME}'"
99+
echo " \$SEG_DEV_NAME='${SEG_DEV_NAME}'"
100100
echo "[INFO] Container info:"
101101
echo " Kernel: $(uname -a)"
102102
echo " Debian: $(cat /etc/debian_version)"
@@ -109,12 +109,23 @@ if [[ "${DEBUG}" == "1" ]]; then
109109
set -x
110110
fi
111111

112-
# Create GSO/TSO/UFO unsegmenting device (work-around
113-
if [[ "${UNSEG_DEV_NAME}" != ""]]; then
114-
ip link add ${UNSEG_DEV_NAME} type dummy
115-
ip link set up dev ${UNSEG_DEV_NAME}
116-
ethtool -K ${UNSEG_DEV_NAME} gso off tso off ufo off
117-
UNSEG_DEV_IFINDEX=$(ip link show ${UNSEG_DEV_NAME} | head -n 1 | awk '{print $1}' | tr -d ':')
112+
# Create GSO/TSO/UFO unsegmenting device (work-around)
113+
if [[ "${SEG_DEV_NAME}" != "" ]]; then
114+
if [[ "$(ip link | grep ${SEG_DEV_NAME})" == "" ]]; then
115+
ip link add ${SEG_DEV_NAME} type veth peer name ${SEG_DEV_NAME}_pair
116+
fi
117+
ip link set up dev ${SEG_DEV_NAME}
118+
ip link set up dev ${SEG_DEV_NAME}_pair
119+
ip link set mtu 1480 dev ${SEG_DEV_NAME}
120+
ip link set mtu 1480 dev ${SEG_DEV_NAME}_pair
121+
ethtool -K ${SEG_DEV_NAME} gso off tso off ufo off
122+
ethtool -K ${SEG_DEV_NAME}_pair gso off tso off ufo off
123+
SEG_DEV_IFINDEX=$(ip link show ${SEG_DEV_NAME} | head -n 1 | awk '{print $1}' | tr -d ':')
124+
SEG_DEV_MAC="$(ip -j link show ${SEG_DEV_NAME}_pair | jq -r '.[0].address' | tr -d ':' | sed 's/\(..\)/0x\1, /g' | sed 's/,\s*$$//')"
125+
126+
echo 1 > /proc/sys/net/ipv4/conf/${SEG_DEV_NAME}/accept_local
127+
echo 1 > /proc/sys/net/ipv4/conf/${SEG_DEV_NAME}_pair/accept_local
128+
echo 1 > /proc/sys/net/ipv4/ip_forward
118129
fi
119130

120131
#Make sure /etc/sfunnel exists, even if no volume is mounted
@@ -166,4 +177,3 @@ for IFACE in ${IFACES}; do
166177
done
167178

168179
echo "[INFO] Successfully ${OP_STR}ed BPF program(s) on interfaces {${IFACES}} DIRECTION=${DIRECTION}"
169-

src/Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
all: compile
22

3-
UNSEG_DEV_IFINDEX ?=
3+
SEG_DEV_IFINDEX ?= 0
4+
SEG_DEV_MAC ?= 0x00,0x00,0x00,0x00,0x00,0x00
45
FILE ?= ruleset.default
56
CFLAGS = -O2 -Wall -Werror -g
67
ifeq ($(DEBUG), 1)
@@ -9,7 +10,7 @@ endif
910

1011
compile:
1112
python3 ../tools/gen.py $(FILE) > ruleset.h
12-
clang $(CFLAGS) -DUNSEG_DEV_IFINDEX=$(UNSEG_DEV_IFINDEX) -target bpf -c sfunnel.c -o tc_sfunnel.o
13+
clang $(CFLAGS) -DSEG_DEV_MAC="$(SEG_DEV_MAC)" -DSEG_DEV_IFINDEX=$(SEG_DEV_IFINDEX) -target bpf -c sfunnel.c -o tc_sfunnel.o
1314

1415
clean:
1516
rm -rf *.o || true

src/sfunnel.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -319,19 +319,24 @@ static inline int proc_ip4(struct __sk_buff* skb, __u8* eth, struct iphdr* ip){
319319
}
320320
PRINTK("[%p] Matched rule#%u", skb, rule->id);
321321

322-
#ifndef UNSEG_DEV_IFINDEX
323-
//Check that packet is not GSO/TSO/UFO
324-
if(skb->gso_size > 0){
325-
if(skb->mark&REDIRECT_PKT_BIT){
326-
//The packet has been redirected before, but is looped
327-
//back GSOed => drop
328-
return TC_ACT_SHOT;
329-
}
322+
#ifdef SEG_DEV_IFINDEX
323+
//Redirecting all pkts, incl. non GSOed, to avoid reorderings.
324+
if((skb->mark&REDIRECT_PKT_BIT) == 0){
325+
__u8 _seg_mac[ETH_ALEN] = {SEG_DEV_MAC};
326+
bpf_skb_store_bytes(skb, offsetof(struct ethhdr, h_dest),
327+
_seg_mac, ETH_ALEN, 0);
328+
330329
skb->mark |= REDIRECT_PKT_BIT;
331-
return bpf_redirect(UNSEG_DEV_IFINDEX, BPF_F_INGRESS);
330+
return bpf_redirect(SEG_DEV_IFINDEX, 0);
331+
}else if(skb->gso_size > 0){
332+
//The packet has been redirected before, but is looped
333+
//back GSOed => drop (bug)
334+
bpf_printk("Recirculated pkt is still GSOed");
335+
return TC_ACT_SHOT;
332336
}
337+
333338
skb->mark &= ~REDIRECT_PKT_BIT;
334-
#endif //UNSEG_DEV_IFINDEX
339+
#endif //SEG_DEV_IFINDEX
335340

336341
//Direct actions
337342
if(rule->actions.drop.execute){

0 commit comments

Comments
 (0)