forked from Minki/linux
samples/bpf: remove the bpf tunnel testsuite.
Move the testsuite to selftests/bpf/{test_tunnel_kern.c, test_tunnel.sh} Signed-off-by: William Tu <u9012063@gmail.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:
parent
933a741e3b
commit
b05cd74043
@ -114,7 +114,6 @@ always += sock_flags_kern.o
|
||||
always += test_probe_write_user_kern.o
|
||||
always += trace_output_kern.o
|
||||
always += tcbpf1_kern.o
|
||||
always += tcbpf2_kern.o
|
||||
always += tc_l2_redirect_kern.o
|
||||
always += lathist_kern.o
|
||||
always += offwaketime_kern.o
|
||||
|
@ -1,612 +0,0 @@
|
||||
/* 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
|
||||
* License as published by the Free Software Foundation.
|
||||
*/
|
||||
#define KBUILD_MODNAME "foo"
|
||||
#include <uapi/linux/bpf.h>
|
||||
#include <uapi/linux/if_ether.h>
|
||||
#include <uapi/linux/if_packet.h>
|
||||
#include <uapi/linux/ip.h>
|
||||
#include <uapi/linux/ipv6.h>
|
||||
#include <uapi/linux/in.h>
|
||||
#include <uapi/linux/tcp.h>
|
||||
#include <uapi/linux/filter.h>
|
||||
#include <uapi/linux/pkt_cls.h>
|
||||
#include <uapi/linux/erspan.h>
|
||||
#include <net/ipv6.h>
|
||||
#include "bpf_helpers.h"
|
||||
#include "bpf_endian.h"
|
||||
|
||||
#define _htonl __builtin_bswap32
|
||||
#define ERROR(ret) do {\
|
||||
char fmt[] = "ERROR line:%d ret:%d\n";\
|
||||
bpf_trace_printk(fmt, sizeof(fmt), __LINE__, ret); \
|
||||
} while(0)
|
||||
|
||||
struct geneve_opt {
|
||||
__be16 opt_class;
|
||||
u8 type;
|
||||
u8 length:5;
|
||||
u8 r3:1;
|
||||
u8 r2:1;
|
||||
u8 r1:1;
|
||||
u8 opt_data[8]; /* hard-coded to 8 byte */
|
||||
};
|
||||
|
||||
struct vxlan_metadata {
|
||||
u32 gbp;
|
||||
};
|
||||
|
||||
SEC("gre_set_tunnel")
|
||||
int _gre_set_tunnel(struct __sk_buff *skb)
|
||||
{
|
||||
int ret;
|
||||
struct bpf_tunnel_key key;
|
||||
|
||||
__builtin_memset(&key, 0x0, sizeof(key));
|
||||
key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
|
||||
key.tunnel_id = 2;
|
||||
key.tunnel_tos = 0;
|
||||
key.tunnel_ttl = 64;
|
||||
|
||||
ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
|
||||
BPF_F_ZERO_CSUM_TX | BPF_F_SEQ_NUMBER);
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
SEC("gre_get_tunnel")
|
||||
int _gre_get_tunnel(struct __sk_buff *skb)
|
||||
{
|
||||
int ret;
|
||||
struct bpf_tunnel_key key;
|
||||
char fmt[] = "key %d 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.tunnel_id, key.remote_ipv4);
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
SEC("ip6gretap_set_tunnel")
|
||||
int _ip6gretap_set_tunnel(struct __sk_buff *skb)
|
||||
{
|
||||
struct bpf_tunnel_key key;
|
||||
int ret;
|
||||
|
||||
__builtin_memset(&key, 0x0, sizeof(key));
|
||||
key.remote_ipv6[3] = _htonl(0x11); /* ::11 */
|
||||
key.tunnel_id = 2;
|
||||
key.tunnel_tos = 0;
|
||||
key.tunnel_ttl = 64;
|
||||
key.tunnel_label = 0xabcde;
|
||||
|
||||
ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
|
||||
BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX |
|
||||
BPF_F_SEQ_NUMBER);
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
SEC("ip6gretap_get_tunnel")
|
||||
int _ip6gretap_get_tunnel(struct __sk_buff *skb)
|
||||
{
|
||||
char fmt[] = "key %d remote ip6 ::%x label %x\n";
|
||||
struct bpf_tunnel_key key;
|
||||
int ret;
|
||||
|
||||
ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
|
||||
BPF_F_TUNINFO_IPV6);
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
bpf_trace_printk(fmt, sizeof(fmt),
|
||||
key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
|
||||
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
SEC("erspan_set_tunnel")
|
||||
int _erspan_set_tunnel(struct __sk_buff *skb)
|
||||
{
|
||||
struct bpf_tunnel_key key;
|
||||
struct erspan_metadata md;
|
||||
int ret;
|
||||
|
||||
__builtin_memset(&key, 0x0, sizeof(key));
|
||||
key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
|
||||
key.tunnel_id = 2;
|
||||
key.tunnel_tos = 0;
|
||||
key.tunnel_ttl = 64;
|
||||
|
||||
ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
__builtin_memset(&md, 0, sizeof(md));
|
||||
#ifdef ERSPAN_V1
|
||||
md.version = 1;
|
||||
md.u.index = bpf_htonl(123);
|
||||
#else
|
||||
u8 direction = 1;
|
||||
u8 hwid = 7;
|
||||
|
||||
md.version = 2;
|
||||
md.u.md2.dir = direction;
|
||||
md.u.md2.hwid = hwid & 0xf;
|
||||
md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
|
||||
#endif
|
||||
|
||||
ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
SEC("erspan_get_tunnel")
|
||||
int _erspan_get_tunnel(struct __sk_buff *skb)
|
||||
{
|
||||
char fmt[] = "key %d remote ip 0x%x erspan version %d\n";
|
||||
struct bpf_tunnel_key key;
|
||||
struct erspan_metadata md;
|
||||
u32 index;
|
||||
int ret;
|
||||
|
||||
ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
bpf_trace_printk(fmt, sizeof(fmt),
|
||||
key.tunnel_id, key.remote_ipv4, md.version);
|
||||
|
||||
#ifdef ERSPAN_V1
|
||||
char fmt2[] = "\tindex %x\n";
|
||||
|
||||
index = bpf_ntohl(md.u.index);
|
||||
bpf_trace_printk(fmt2, sizeof(fmt2), index);
|
||||
#else
|
||||
char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
|
||||
|
||||
bpf_trace_printk(fmt2, sizeof(fmt2),
|
||||
md.u.md2.dir,
|
||||
(md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
|
||||
bpf_ntohl(md.u.md2.timestamp));
|
||||
#endif
|
||||
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
SEC("ip4ip6erspan_set_tunnel")
|
||||
int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
|
||||
{
|
||||
struct bpf_tunnel_key key;
|
||||
struct erspan_metadata md;
|
||||
int ret;
|
||||
|
||||
__builtin_memset(&key, 0x0, sizeof(key));
|
||||
key.remote_ipv6[3] = _htonl(0x11);
|
||||
key.tunnel_id = 2;
|
||||
key.tunnel_tos = 0;
|
||||
key.tunnel_ttl = 64;
|
||||
|
||||
ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
|
||||
BPF_F_TUNINFO_IPV6);
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
__builtin_memset(&md, 0, sizeof(md));
|
||||
|
||||
#ifdef ERSPAN_V1
|
||||
md.u.index = htonl(123);
|
||||
md.version = 1;
|
||||
#else
|
||||
u8 direction = 0;
|
||||
u8 hwid = 17;
|
||||
|
||||
md.version = 2;
|
||||
md.u.md2.dir = direction;
|
||||
md.u.md2.hwid = hwid & 0xf;
|
||||
md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
|
||||
#endif
|
||||
|
||||
ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
SEC("ip4ip6erspan_get_tunnel")
|
||||
int _ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
|
||||
{
|
||||
char fmt[] = "ip6erspan get key %d remote ip6 ::%x erspan version %d\n";
|
||||
struct bpf_tunnel_key key;
|
||||
struct erspan_metadata md;
|
||||
u32 index;
|
||||
int ret;
|
||||
|
||||
ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
bpf_trace_printk(fmt, sizeof(fmt),
|
||||
key.tunnel_id, key.remote_ipv4, md.version);
|
||||
|
||||
#ifdef ERSPAN_V1
|
||||
char fmt2[] = "\tindex %x\n";
|
||||
|
||||
index = bpf_ntohl(md.u.index);
|
||||
bpf_trace_printk(fmt2, sizeof(fmt2), index);
|
||||
#else
|
||||
char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
|
||||
|
||||
bpf_trace_printk(fmt2, sizeof(fmt2),
|
||||
md.u.md2.dir,
|
||||
(md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
|
||||
bpf_ntohl(md.u.md2.timestamp));
|
||||
#endif
|
||||
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
SEC("vxlan_set_tunnel")
|
||||
int _vxlan_set_tunnel(struct __sk_buff *skb)
|
||||
{
|
||||
int ret;
|
||||
struct bpf_tunnel_key key;
|
||||
struct vxlan_metadata md;
|
||||
|
||||
__builtin_memset(&key, 0x0, sizeof(key));
|
||||
key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
|
||||
key.tunnel_id = 2;
|
||||
key.tunnel_tos = 0;
|
||||
key.tunnel_ttl = 64;
|
||||
|
||||
ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
|
||||
ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
SEC("vxlan_get_tunnel")
|
||||
int _vxlan_get_tunnel(struct __sk_buff *skb)
|
||||
{
|
||||
int ret;
|
||||
struct bpf_tunnel_key key;
|
||||
struct vxlan_metadata md;
|
||||
char fmt[] = "key %d remote ip 0x%x vxlan gbp 0x%x\n";
|
||||
|
||||
ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
bpf_trace_printk(fmt, sizeof(fmt),
|
||||
key.tunnel_id, key.remote_ipv4, md.gbp);
|
||||
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
SEC("geneve_set_tunnel")
|
||||
int _geneve_set_tunnel(struct __sk_buff *skb)
|
||||
{
|
||||
int ret, ret2;
|
||||
struct bpf_tunnel_key key;
|
||||
struct geneve_opt gopt;
|
||||
|
||||
__builtin_memset(&key, 0x0, sizeof(key));
|
||||
key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
|
||||
key.tunnel_id = 2;
|
||||
key.tunnel_tos = 0;
|
||||
key.tunnel_ttl = 64;
|
||||
|
||||
__builtin_memset(&gopt, 0x0, sizeof(gopt));
|
||||
gopt.opt_class = 0x102; /* Open Virtual Networking (OVN) */
|
||||
gopt.type = 0x08;
|
||||
gopt.r1 = 0;
|
||||
gopt.r2 = 0;
|
||||
gopt.r3 = 0;
|
||||
gopt.length = 2; /* 4-byte multiple */
|
||||
*(int *) &gopt.opt_data = 0xdeadbeef;
|
||||
|
||||
ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
SEC("geneve_get_tunnel")
|
||||
int _geneve_get_tunnel(struct __sk_buff *skb)
|
||||
{
|
||||
int ret;
|
||||
struct bpf_tunnel_key key;
|
||||
struct geneve_opt gopt;
|
||||
char fmt[] = "key %d remote ip 0x%x geneve class 0x%x\n";
|
||||
|
||||
ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
bpf_trace_printk(fmt, sizeof(fmt),
|
||||
key.tunnel_id, key.remote_ipv4, gopt.opt_class);
|
||||
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;
|
||||
}
|
||||
|
||||
SEC("ipip6_set_tunnel")
|
||||
int _ipip6_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.remote_ipv6[0] = _htonl(0x2401db00);
|
||||
key.tunnel_ttl = 64;
|
||||
|
||||
if (iph->protocol == IPPROTO_ICMP) {
|
||||
key.remote_ipv6[3] = _htonl(1);
|
||||
} else {
|
||||
if (iph->protocol != IPPROTO_TCP || iph->ihl != 5) {
|
||||
ERROR(iph->protocol);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
if (tcp->dest == htons(5200)) {
|
||||
key.remote_ipv6[3] = _htonl(1);
|
||||
} else if (tcp->dest == htons(5201)) {
|
||||
key.remote_ipv6[3] = _htonl(2);
|
||||
} else {
|
||||
ERROR(tcp->dest);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
}
|
||||
|
||||
ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
SEC("ipip6_get_tunnel")
|
||||
int _ipip6_get_tunnel(struct __sk_buff *skb)
|
||||
{
|
||||
int ret;
|
||||
struct bpf_tunnel_key key;
|
||||
char fmt[] = "remote ip6 %x::%x\n";
|
||||
|
||||
ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
|
||||
_htonl(key.remote_ipv6[3]));
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
SEC("ip6ip6_set_tunnel")
|
||||
int _ip6ip6_set_tunnel(struct __sk_buff *skb)
|
||||
{
|
||||
struct bpf_tunnel_key key = {};
|
||||
void *data = (void *)(long)skb->data;
|
||||
struct ipv6hdr *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.remote_ipv6[0] = _htonl(0x2401db00);
|
||||
key.tunnel_ttl = 64;
|
||||
|
||||
if (iph->nexthdr == NEXTHDR_ICMP) {
|
||||
key.remote_ipv6[3] = _htonl(1);
|
||||
} else {
|
||||
if (iph->nexthdr != NEXTHDR_TCP) {
|
||||
ERROR(iph->nexthdr);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
if (tcp->dest == htons(5200)) {
|
||||
key.remote_ipv6[3] = _htonl(1);
|
||||
} else if (tcp->dest == htons(5201)) {
|
||||
key.remote_ipv6[3] = _htonl(2);
|
||||
} else {
|
||||
ERROR(tcp->dest);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
}
|
||||
|
||||
ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
SEC("ip6ip6_get_tunnel")
|
||||
int _ip6ip6_get_tunnel(struct __sk_buff *skb)
|
||||
{
|
||||
int ret;
|
||||
struct bpf_tunnel_key key;
|
||||
char fmt[] = "remote ip6 %x::%x\n";
|
||||
|
||||
ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
|
||||
if (ret < 0) {
|
||||
ERROR(ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
|
||||
_htonl(key.remote_ipv6[3]));
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
SEC("xfrm_get_state")
|
||||
int _xfrm_get_state(struct __sk_buff *skb)
|
||||
{
|
||||
struct bpf_xfrm_state x;
|
||||
char fmt[] = "reqid %d spi 0x%x remote ip 0x%x\n";
|
||||
int ret;
|
||||
|
||||
ret = bpf_skb_get_xfrm_state(skb, 0, &x, sizeof(x), 0);
|
||||
if (ret < 0)
|
||||
return TC_ACT_OK;
|
||||
|
||||
bpf_trace_printk(fmt, sizeof(fmt), x.reqid, bpf_ntohl(x.spi),
|
||||
bpf_ntohl(x.remote_ipv4));
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
@ -1,390 +0,0 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# In Namespace 0 (at_ns0) using native tunnel
|
||||
# Overlay IP: 10.1.1.100
|
||||
# local 192.16.1.100 remote 192.16.1.200
|
||||
# veth0 IP: 172.16.1.100, tunnel dev <type>00
|
||||
|
||||
# Out of Namespace using BPF set/get on lwtunnel
|
||||
# Overlay IP: 10.1.1.200
|
||||
# local 172.16.1.200 remote 172.16.1.100
|
||||
# veth1 IP: 172.16.1.200, tunnel dev <type>11
|
||||
|
||||
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 mtu 1500
|
||||
ip addr add dev veth1 172.16.1.200/24
|
||||
}
|
||||
|
||||
function add_gre_tunnel {
|
||||
# in namespace
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE seq key 2 \
|
||||
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 key 2 external
|
||||
ip link set dev $DEV up
|
||||
ip addr add dev $DEV 10.1.1.200/24
|
||||
}
|
||||
|
||||
function add_ip6gretap_tunnel {
|
||||
|
||||
# assign ipv6 address
|
||||
ip netns exec at_ns0 ip addr add ::11/96 dev veth0
|
||||
ip netns exec at_ns0 ip link set dev veth0 up
|
||||
ip addr add dev veth1 ::22/96
|
||||
ip link set dev veth1 up
|
||||
|
||||
# in namespace
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE seq flowlabel 0xbcdef key 2 \
|
||||
local ::11 remote ::22
|
||||
|
||||
ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
|
||||
ip netns exec at_ns0 ip addr add dev $DEV_NS fc80::100/96
|
||||
ip netns exec at_ns0 ip link set dev $DEV_NS up
|
||||
|
||||
# out of namespace
|
||||
ip link add dev $DEV type $TYPE external
|
||||
ip addr add dev $DEV 10.1.1.200/24
|
||||
ip addr add dev $DEV fc80::200/24
|
||||
ip link set dev $DEV up
|
||||
}
|
||||
|
||||
function add_erspan_tunnel {
|
||||
# in namespace
|
||||
if [ "$1" == "v1" ]; then
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE seq key 2 \
|
||||
local 172.16.1.100 remote 172.16.1.200 \
|
||||
erspan_ver 1 erspan 123
|
||||
else
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE seq key 2 \
|
||||
local 172.16.1.100 remote 172.16.1.200 \
|
||||
erspan_ver 2 erspan_dir egress erspan_hwid 3
|
||||
fi
|
||||
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 add_ip6erspan_tunnel {
|
||||
|
||||
# assign ipv6 address
|
||||
ip netns exec at_ns0 ip addr add ::11/96 dev veth0
|
||||
ip netns exec at_ns0 ip link set dev veth0 up
|
||||
ip addr add dev veth1 ::22/96
|
||||
ip link set dev veth1 up
|
||||
|
||||
# in namespace
|
||||
if [ "$1" == "v1" ]; then
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE seq key 2 \
|
||||
local ::11 remote ::22 \
|
||||
erspan_ver 1 erspan 123
|
||||
else
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE seq key 2 \
|
||||
local ::11 remote ::22 \
|
||||
erspan_ver 2 erspan_dir egress erspan_hwid 7
|
||||
fi
|
||||
ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
|
||||
ip netns exec at_ns0 ip link set dev $DEV_NS up
|
||||
|
||||
# out of namespace
|
||||
ip link add dev $DEV type $TYPE external
|
||||
ip addr add dev $DEV 10.1.1.200/24
|
||||
ip link set dev $DEV up
|
||||
}
|
||||
|
||||
function add_vxlan_tunnel {
|
||||
# Set static ARP entry here because iptables set-mark works
|
||||
# on L3 packet, as a result not applying to ARP packets,
|
||||
# causing errors at get_tunnel_{key/opt}.
|
||||
|
||||
# in namespace
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE id 2 dstport 4789 gbp remote 172.16.1.200
|
||||
ip netns exec at_ns0 ip link set dev $DEV_NS address 52:54:00:d9:01:00 up
|
||||
ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
|
||||
ip netns exec at_ns0 arp -s 10.1.1.200 52:54:00:d9:02:00
|
||||
ip netns exec at_ns0 iptables -A OUTPUT -j MARK --set-mark 0x800FF
|
||||
|
||||
# out of namespace
|
||||
ip link add dev $DEV type $TYPE external gbp dstport 4789
|
||||
ip link set dev $DEV address 52:54:00:d9:02:00 up
|
||||
ip addr add dev $DEV 10.1.1.200/24
|
||||
arp -s 10.1.1.100 52:54:00:d9:01:00
|
||||
}
|
||||
|
||||
function add_geneve_tunnel {
|
||||
# in namespace
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE id 2 dstport 6081 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 dstport 6081 external
|
||||
ip link set dev $DEV up
|
||||
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 setup_xfrm_tunnel {
|
||||
auth=0x$(printf '1%.0s' {1..40})
|
||||
enc=0x$(printf '2%.0s' {1..32})
|
||||
spi_in_to_out=0x1
|
||||
spi_out_to_in=0x2
|
||||
# in namespace
|
||||
# in -> out
|
||||
ip netns exec at_ns0 \
|
||||
ip xfrm state add src 172.16.1.100 dst 172.16.1.200 proto esp \
|
||||
spi $spi_in_to_out reqid 1 mode tunnel \
|
||||
auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
|
||||
ip netns exec at_ns0 \
|
||||
ip xfrm policy add src 10.1.1.100/32 dst 10.1.1.200/32 dir out \
|
||||
tmpl src 172.16.1.100 dst 172.16.1.200 proto esp reqid 1 \
|
||||
mode tunnel
|
||||
# out -> in
|
||||
ip netns exec at_ns0 \
|
||||
ip xfrm state add src 172.16.1.200 dst 172.16.1.100 proto esp \
|
||||
spi $spi_out_to_in reqid 2 mode tunnel \
|
||||
auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
|
||||
ip netns exec at_ns0 \
|
||||
ip xfrm policy add src 10.1.1.200/32 dst 10.1.1.100/32 dir in \
|
||||
tmpl src 172.16.1.200 dst 172.16.1.100 proto esp reqid 2 \
|
||||
mode tunnel
|
||||
# address & route
|
||||
ip netns exec at_ns0 \
|
||||
ip addr add dev veth0 10.1.1.100/32
|
||||
ip netns exec at_ns0 \
|
||||
ip route add 10.1.1.200 dev veth0 via 172.16.1.200 \
|
||||
src 10.1.1.100
|
||||
|
||||
# out of namespace
|
||||
# in -> out
|
||||
ip xfrm state add src 172.16.1.100 dst 172.16.1.200 proto esp \
|
||||
spi $spi_in_to_out reqid 1 mode tunnel \
|
||||
auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
|
||||
ip xfrm policy add src 10.1.1.100/32 dst 10.1.1.200/32 dir in \
|
||||
tmpl src 172.16.1.100 dst 172.16.1.200 proto esp reqid 1 \
|
||||
mode tunnel
|
||||
# out -> in
|
||||
ip xfrm state add src 172.16.1.200 dst 172.16.1.100 proto esp \
|
||||
spi $spi_out_to_in reqid 2 mode tunnel \
|
||||
auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
|
||||
ip xfrm policy add src 10.1.1.200/32 dst 10.1.1.100/32 dir out \
|
||||
tmpl src 172.16.1.200 dst 172.16.1.100 proto esp reqid 2 \
|
||||
mode tunnel
|
||||
# address & route
|
||||
ip addr add dev veth1 10.1.1.200/32
|
||||
ip route add 10.1.1.100 dev veth1 via 172.16.1.100 src 10.1.1.200
|
||||
}
|
||||
|
||||
function attach_bpf {
|
||||
DEV=$1
|
||||
SET_TUNNEL=$2
|
||||
GET_TUNNEL=$3
|
||||
tc qdisc add dev $DEV clsact
|
||||
tc filter add dev $DEV egress bpf da obj tcbpf2_kern.o sec $SET_TUNNEL
|
||||
tc filter add dev $DEV ingress bpf da obj tcbpf2_kern.o sec $GET_TUNNEL
|
||||
}
|
||||
|
||||
function test_gre {
|
||||
TYPE=gretap
|
||||
DEV_NS=gretap00
|
||||
DEV=gretap11
|
||||
config_device
|
||||
add_gre_tunnel
|
||||
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_ip6gre {
|
||||
TYPE=ip6gre
|
||||
DEV_NS=ip6gre00
|
||||
DEV=ip6gre11
|
||||
config_device
|
||||
# reuse the ip6gretap function
|
||||
add_ip6gretap_tunnel
|
||||
attach_bpf $DEV ip6gretap_set_tunnel ip6gretap_get_tunnel
|
||||
# underlay
|
||||
ping6 -c 4 ::11
|
||||
# overlay: ipv4 over ipv6
|
||||
ip netns exec at_ns0 ping -c 1 10.1.1.200
|
||||
ping -c 1 10.1.1.100
|
||||
# overlay: ipv6 over ipv6
|
||||
ip netns exec at_ns0 ping6 -c 1 fc80::200
|
||||
cleanup
|
||||
}
|
||||
|
||||
function test_ip6gretap {
|
||||
TYPE=ip6gretap
|
||||
DEV_NS=ip6gretap00
|
||||
DEV=ip6gretap11
|
||||
config_device
|
||||
add_ip6gretap_tunnel
|
||||
attach_bpf $DEV ip6gretap_set_tunnel ip6gretap_get_tunnel
|
||||
# underlay
|
||||
ping6 -c 4 ::11
|
||||
# overlay: ipv4 over ipv6
|
||||
ip netns exec at_ns0 ping -i .2 -c 1 10.1.1.200
|
||||
ping -c 1 10.1.1.100
|
||||
# overlay: ipv6 over ipv6
|
||||
ip netns exec at_ns0 ping6 -c 1 fc80::200
|
||||
cleanup
|
||||
}
|
||||
|
||||
function test_erspan {
|
||||
TYPE=erspan
|
||||
DEV_NS=erspan00
|
||||
DEV=erspan11
|
||||
config_device
|
||||
add_erspan_tunnel $1
|
||||
attach_bpf $DEV erspan_set_tunnel erspan_get_tunnel
|
||||
ping -c 1 10.1.1.100
|
||||
ip netns exec at_ns0 ping -c 1 10.1.1.200
|
||||
cleanup
|
||||
}
|
||||
|
||||
function test_ip6erspan {
|
||||
TYPE=ip6erspan
|
||||
DEV_NS=ip6erspan00
|
||||
DEV=ip6erspan11
|
||||
config_device
|
||||
add_ip6erspan_tunnel $1
|
||||
attach_bpf $DEV ip4ip6erspan_set_tunnel ip4ip6erspan_get_tunnel
|
||||
ping6 -c 3 ::11
|
||||
ip netns exec at_ns0 ping -c 1 10.1.1.200
|
||||
cleanup
|
||||
}
|
||||
|
||||
function test_vxlan {
|
||||
TYPE=vxlan
|
||||
DEV_NS=vxlan00
|
||||
DEV=vxlan11
|
||||
config_device
|
||||
add_vxlan_tunnel
|
||||
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 {
|
||||
TYPE=geneve
|
||||
DEV_NS=geneve00
|
||||
DEV=geneve11
|
||||
config_device
|
||||
add_geneve_tunnel
|
||||
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 test_xfrm_tunnel {
|
||||
config_device
|
||||
tcpdump -nei veth1 ip &
|
||||
output=$(mktemp)
|
||||
cat /sys/kernel/debug/tracing/trace_pipe | tee $output &
|
||||
setup_xfrm_tunnel
|
||||
tc qdisc add dev veth1 clsact
|
||||
tc filter add dev veth1 proto ip ingress bpf da obj tcbpf2_kern.o \
|
||||
sec xfrm_get_state
|
||||
ip netns exec at_ns0 ping -c 1 10.1.1.200
|
||||
grep "reqid 1" $output
|
||||
grep "spi 0x1" $output
|
||||
grep "remote ip 0xac100164" $output
|
||||
cleanup
|
||||
}
|
||||
|
||||
function cleanup {
|
||||
set +ex
|
||||
pkill iperf
|
||||
ip netns delete at_ns0
|
||||
ip link del veth1
|
||||
ip link del ipip11
|
||||
ip link del gretap11
|
||||
ip link del ip6gre11
|
||||
ip link del ip6gretap11
|
||||
ip link del vxlan11
|
||||
ip link del geneve11
|
||||
ip link del erspan11
|
||||
ip link del ip6erspan11
|
||||
ip x s flush
|
||||
ip x p flush
|
||||
pkill tcpdump
|
||||
pkill cat
|
||||
set -ex
|
||||
}
|
||||
|
||||
trap cleanup 0 2 3 6 9
|
||||
cleanup
|
||||
echo "Testing GRE tunnel..."
|
||||
test_gre
|
||||
echo "Testing IP6GRE tunnel..."
|
||||
test_ip6gre
|
||||
echo "Testing IP6GRETAP tunnel..."
|
||||
test_ip6gretap
|
||||
echo "Testing ERSPAN tunnel..."
|
||||
test_erspan v1
|
||||
test_erspan v2
|
||||
echo "Testing IP6ERSPAN tunnel..."
|
||||
test_ip6erspan v1
|
||||
test_ip6erspan v2
|
||||
echo "Testing VXLAN tunnel..."
|
||||
test_vxlan
|
||||
echo "Testing GENEVE tunnel..."
|
||||
test_geneve
|
||||
echo "Testing IPIP tunnel..."
|
||||
test_ipip
|
||||
echo "Testing IPSec tunnel..."
|
||||
test_xfrm_tunnel
|
||||
echo "*** PASS ***"
|
Loading…
Reference in New Issue
Block a user