You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
1.8 KiB
67 lines
1.8 KiB
// Copyright (c) PLUMgrid, Inc.
|
|
// Licensed under the Apache License, Version 2.0 (the "License")
|
|
#include <bcc/proto.h>
|
|
|
|
struct config {
|
|
int tunnel_ifindex;
|
|
};
|
|
BPF_HASH(conf, int, struct config, 1);
|
|
|
|
struct tunnel_key {
|
|
u32 tunnel_id;
|
|
u32 remote_ipv4;
|
|
};
|
|
BPF_HASH(tunkey2if, struct tunnel_key, int, 1024);
|
|
|
|
BPF_HASH(if2tunkey, int, struct tunnel_key, 1024);
|
|
|
|
// Handle packets from the encap device, demux into the dest tenant
|
|
int handle_ingress(struct __sk_buff *skb) {
|
|
struct bpf_tunnel_key tkey = {};
|
|
struct tunnel_key key;
|
|
bpf_skb_get_tunnel_key(skb, &tkey,
|
|
offsetof(struct bpf_tunnel_key, remote_ipv6[1]), 0);
|
|
|
|
key.tunnel_id = tkey.tunnel_id;
|
|
key.remote_ipv4 = tkey.remote_ipv4;
|
|
int *ifindex = tunkey2if.lookup(&key);
|
|
if (ifindex) {
|
|
//bpf_trace_printk("ingress tunnel_id=%d remote_ip=%08x ifindex=%d\n",
|
|
// key.tunnel_id, key.remote_ipv4, *ifindex);
|
|
// mark from external
|
|
skb->tc_index = 1;
|
|
bpf_clone_redirect(skb, *ifindex, 1/*ingress*/);
|
|
} else {
|
|
bpf_trace_printk("ingress invalid tunnel_id=%d\n", key.tunnel_id);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
// Handle packets from the tenant, mux into the encap device
|
|
int handle_egress(struct __sk_buff *skb) {
|
|
int ifindex = skb->ifindex;
|
|
struct bpf_tunnel_key tkey = {};
|
|
struct tunnel_key *key_p;
|
|
int one = 1;
|
|
struct config *cfg = conf.lookup(&one);
|
|
|
|
if (!cfg) return 1;
|
|
|
|
if (skb->tc_index) {
|
|
//bpf_trace_printk("from external\n");
|
|
// don't send it back out to encap device
|
|
return 1;
|
|
}
|
|
|
|
key_p = if2tunkey.lookup(&ifindex);
|
|
if (key_p) {
|
|
tkey.tunnel_id = key_p->tunnel_id;
|
|
tkey.remote_ipv4 = key_p->remote_ipv4;
|
|
bpf_skb_set_tunnel_key(skb, &tkey,
|
|
offsetof(struct bpf_tunnel_key, remote_ipv6[1]), 0);
|
|
bpf_clone_redirect(skb, cfg->tunnel_ifindex, 0/*egress*/);
|
|
}
|
|
return 1;
|
|
}
|