samples/bpf: extend test_tunnel_bpf.sh with IPIP test
authorAlexei Starovoitov <ast@fb.com>
Thu, 15 Sep 2016 20:00:31 +0000 (13:00 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sat, 17 Sep 2016 14:13:07 +0000 (10:13 -0400)
extend existing tests for vxlan, geneve, gre to include IPIP tunnel.
It tests both traditional tunnel configuration and
dynamic via bpf helpers.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
samples/bpf/tcbpf2_kern.c
samples/bpf/test_tunnel_bpf.sh

index 7a15289da6cc4ef1d690507e5a305c59c65abba0..c1917d968fb4ce59a69527bfdab247031ad33d81 100644 (file)
@@ -1,4 +1,5 @@
 /* Copyright (c) 2016 VMware
+ * Copyright (c) 2016 Facebook
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
@@ -188,4 +189,61 @@ int _geneve_get_tunnel(struct __sk_buff *skb)
        return TC_ACT_OK;
 }
 
+SEC("ipip_set_tunnel")
+int _ipip_set_tunnel(struct __sk_buff *skb)
+{
+       struct bpf_tunnel_key key = {};
+       void *data = (void *)(long)skb->data;
+       struct iphdr *iph = data;
+       struct tcphdr *tcp = data + sizeof(*iph);
+       void *data_end = (void *)(long)skb->data_end;
+       int ret;
+
+       /* single length check */
+       if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
+               ERROR(1);
+               return TC_ACT_SHOT;
+       }
+
+       key.tunnel_ttl = 64;
+       if (iph->protocol == IPPROTO_ICMP) {
+               key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
+       } else {
+               if (iph->protocol != IPPROTO_TCP || iph->ihl != 5)
+                       return TC_ACT_SHOT;
+
+               if (tcp->dest == htons(5200))
+                       key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
+               else if (tcp->dest == htons(5201))
+                       key.remote_ipv4 = 0xac100165; /* 172.16.1.101 */
+               else
+                       return TC_ACT_SHOT;
+       }
+
+       ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
+       if (ret < 0) {
+               ERROR(ret);
+               return TC_ACT_SHOT;
+       }
+
+       return TC_ACT_OK;
+}
+
+SEC("ipip_get_tunnel")
+int _ipip_get_tunnel(struct __sk_buff *skb)
+{
+       int ret;
+       struct bpf_tunnel_key key;
+       char fmt[] = "remote ip 0x%x\n";
+
+       ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
+       if (ret < 0) {
+               ERROR(ret);
+               return TC_ACT_SHOT;
+       }
+
+       bpf_trace_printk(fmt, sizeof(fmt), key.remote_ipv4);
+       return TC_ACT_OK;
+}
+
 char _license[] SEC("license") = "GPL";
index 4956589a83aee88d9689b2420fdf2b301b70f731..1ff634f187b7fd927bef6a091b96e32dbca27870 100755 (executable)
@@ -9,15 +9,13 @@
 # local 172.16.1.200 remote 172.16.1.100
 # veth1 IP: 172.16.1.200, tunnel dev <type>11
 
-set -e
-
 function config_device {
        ip netns add at_ns0
        ip link add veth0 type veth peer name veth1
        ip link set veth0 netns at_ns0
        ip netns exec at_ns0 ip addr add 172.16.1.100/24 dev veth0
        ip netns exec at_ns0 ip link set dev veth0 up
-       ip link set dev veth1 up
+       ip link set dev veth1 up mtu 1500
        ip addr add dev veth1 172.16.1.200/24
 }
 
@@ -67,6 +65,19 @@ function add_geneve_tunnel {
        ip addr add dev $DEV 10.1.1.200/24
 }
 
+function add_ipip_tunnel {
+       # in namespace
+       ip netns exec at_ns0 \
+               ip link add dev $DEV_NS type $TYPE local 172.16.1.100 remote 172.16.1.200
+       ip netns exec at_ns0 ip link set dev $DEV_NS up
+       ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
+
+       # out of namespace
+       ip link add dev $DEV type $TYPE external
+       ip link set dev $DEV up
+       ip addr add dev $DEV 10.1.1.200/24
+}
+
 function attach_bpf {
        DEV=$1
        SET_TUNNEL=$2
@@ -85,6 +96,7 @@ function test_gre {
        attach_bpf $DEV gre_set_tunnel gre_get_tunnel
        ping -c 1 10.1.1.100
        ip netns exec at_ns0 ping -c 1 10.1.1.200
+       cleanup
 }
 
 function test_vxlan {
@@ -96,6 +108,7 @@ function test_vxlan {
        attach_bpf $DEV vxlan_set_tunnel vxlan_get_tunnel
        ping -c 1 10.1.1.100
        ip netns exec at_ns0 ping -c 1 10.1.1.200
+       cleanup
 }
 
 function test_geneve {
@@ -107,21 +120,48 @@ function test_geneve {
        attach_bpf $DEV geneve_set_tunnel geneve_get_tunnel
        ping -c 1 10.1.1.100
        ip netns exec at_ns0 ping -c 1 10.1.1.200
+       cleanup
+}
+
+function test_ipip {
+       TYPE=ipip
+       DEV_NS=ipip00
+       DEV=ipip11
+       config_device
+       tcpdump -nei veth1 &
+       cat /sys/kernel/debug/tracing/trace_pipe &
+       add_ipip_tunnel
+       ethtool -K veth1 gso off gro off rx off tx off
+       ip link set dev veth1 mtu 1500
+       attach_bpf $DEV ipip_set_tunnel ipip_get_tunnel
+       ping -c 1 10.1.1.100
+       ip netns exec at_ns0 ping -c 1 10.1.1.200
+       ip netns exec at_ns0 iperf -sD -p 5200 > /dev/null
+       sleep 0.2
+       iperf -c 10.1.1.100 -n 5k -p 5200
+       cleanup
 }
 
 function cleanup {
+       set +ex
+       pkill iperf
        ip netns delete at_ns0
        ip link del veth1
-       ip link del $DEV
+       ip link del ipip11
+       ip link del gretap11
+       ip link del geneve11
+       pkill tcpdump
+       pkill cat
+       set -ex
 }
 
+cleanup
 echo "Testing GRE tunnel..."
 test_gre
-cleanup
 echo "Testing VXLAN tunnel..."
 test_vxlan
-cleanup
 echo "Testing GENEVE tunnel..."
 test_geneve
-cleanup
-echo "Success"
+echo "Testing IPIP tunnel..."
+test_ipip
+echo "*** PASS ***"