Skip to content

Commit

Permalink
bpf: add support for local NodePort via tunnel
Browse files Browse the repository at this point in the history
Gets the case working where we curl the remote's cilium_host IP for
nodeport and the backend is local.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
  • Loading branch information
borkmann committed Jul 21, 2019
1 parent c61b460 commit 3a83623
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 11 deletions.
16 changes: 14 additions & 2 deletions bpf/bpf_overlay.c
Expand Up @@ -35,6 +35,7 @@
#include "lib/l3.h"
#include "lib/drop.h"
#include "lib/policy.h"
#include "lib/nodeport.h"

#ifdef ENABLE_IPV6
static inline int handle_ipv6(struct __sk_buff *skb, __u32 *identity)
Expand All @@ -46,10 +47,10 @@ static inline int handle_ipv6(struct __sk_buff *skb, __u32 *identity)
int l4_off, l3_off = ETH_HLEN, hdrlen;
bool decrypted;

decrypted = ((skb->mark & MARK_MAGIC_HOST_MASK) == MARK_MAGIC_DECRYPT);
if (!revalidate_data(skb, &data, &data_end, &ip6))
return DROP_INVALID;

decrypted = ((skb->mark & MARK_MAGIC_HOST_MASK) == MARK_MAGIC_DECRYPT);
if (decrypted) {
*identity = get_identity(skb);
} else {
Expand Down Expand Up @@ -135,10 +136,20 @@ static inline int handle_ipv4(struct __sk_buff *skb, __u32 *identity)
bool decrypted;
int l4_off;

decrypted = ((skb->mark & MARK_MAGIC_HOST_MASK) == MARK_MAGIC_DECRYPT);
/* verifier workaround (dereference of modified ctx ptr) */
if (!revalidate_data(skb, &data, &data_end, &ip4))
return DROP_INVALID;
#ifdef ENABLE_NODEPORT
if (!tc_index_skip_nodeport(skb)) {
int ret = nodeport_lb4(skb, *identity);
if (ret < 0)
return ret;
}
#endif
if (!revalidate_data(skb, &data, &data_end, &ip4))
return DROP_INVALID;

decrypted = ((skb->mark & MARK_MAGIC_HOST_MASK) == MARK_MAGIC_DECRYPT);
/* If packets are decrypted the key has already been pushed into metadata. */
if (decrypted) {
*identity = get_identity(skb);
Expand Down Expand Up @@ -226,6 +237,7 @@ int from_overlay(struct __sk_buff *skb)
int ret;

bpf_clear_cb(skb);
tc_index_clear_nodeport(skb);

#ifdef ENABLE_IPSEC
if ((skb->mark & MARK_MAGIC_HOST_MASK) == MARK_MAGIC_DECRYPT) {
Expand Down
5 changes: 4 additions & 1 deletion bpf/init.sh
Expand Up @@ -485,14 +485,17 @@ if [ "$MODE" = "vxlan" -o "$MODE" = "geneve" ]; then
CALLS_MAP="cilium_calls_overlay_${ID_WORLD}"
POLICY_MAP="cilium_policy_reserved_${ID_WORLD}"
COPTS="-DSECLABEL=${ID_WORLD} -DPOLICY_MAP=${POLICY_MAP}"
if [ "$NODE_PORT" = "true" ]; then
COPTS="${COPTS} -DLB_L3 -DLB_L4"
fi
bpf_load $ENCAP_DEV "$COPTS" "ingress" bpf_overlay.c bpf_overlay.o from-overlay ${CALLS_MAP}
else
# Remove eventual existing encapsulation device from previous run
ip link del cilium_vxlan 2> /dev/null || true
ip link del cilium_geneve 2> /dev/null || true
fi

if [ "$MODE" = "direct" ] || [ "$MODE" = "ipvlan" ]; then
if [ "$MODE" = "direct" ] || [ "$MODE" = "ipvlan" ] || [ "$NODE_PORT" = "true" ]; then
if [ -z "$NATIVE_DEV" ]; then
echo "No device specified for $MODE mode, ignoring..."
else
Expand Down
13 changes: 11 additions & 2 deletions bpf/lib/encap.h
Expand Up @@ -65,8 +65,8 @@ encap_and_redirect_ipsec(struct __sk_buff *skb, __u32 tunnel_endpoint, __u8 key,
#endif

static inline int __inline__
__encap_and_redirect_with_nodeid(struct __sk_buff *skb, __u32 tunnel_endpoint,
__u32 seclabel, __u32 monitor)
__encap_with_nodeid(struct __sk_buff *skb, __u32 tunnel_endpoint,
__u32 seclabel, __u32 monitor)
{
struct bpf_tunnel_key key = {};
__u32 node_id;
Expand All @@ -84,7 +84,16 @@ __encap_and_redirect_with_nodeid(struct __sk_buff *skb, __u32 tunnel_endpoint,

send_trace_notify(skb, TRACE_TO_OVERLAY, seclabel, 0, 0, ENCAP_IFINDEX,
0, monitor);
return 0;
}

static inline int __inline__
__encap_and_redirect_with_nodeid(struct __sk_buff *skb, __u32 tunnel_endpoint,
__u32 seclabel, __u32 monitor)
{
int ret = __encap_with_nodeid(skb, tunnel_endpoint, seclabel, monitor);
if (ret != 0)
return ret;
return redirect(ENCAP_IFINDEX, 0);
}

Expand Down
35 changes: 30 additions & 5 deletions bpf/lib/nodeport.h
Expand Up @@ -19,10 +19,13 @@
#ifndef __NODEPORT_H_
#define __NODEPORT_H_

#include <bpf/api.h>

#include "nat.h"
#include "lb.h"
#include "conntrack.h"
#include "csum.h"
#include "encap.h"

#define CB_SRC_IDENTITY 0

Expand Down Expand Up @@ -472,7 +475,7 @@ static inline int nodeport_lb4(struct __sk_buff *skb, __u32 src_identity)
* CILIUM_CALL_IPV{4,6}_NODEPORT_REVNAT is plugged into CILIUM_MAP_CALLS
* of the bpf_netdev and of the bpf_lxc.
*/
static inline int rev_nodeport_lb4(struct __sk_buff *skb)
static inline int rev_nodeport_lb4(struct __sk_buff *skb, int *ifindex)
{
struct ipv4_ct_tuple tuple = {};
void *data, *data_end;
Expand Down Expand Up @@ -505,9 +508,31 @@ static inline int rev_nodeport_lb4(struct __sk_buff *skb)

if (!revalidate_data(skb, &data, &data_end, &ip4))
return DROP_INVALID;

#ifdef ENCAP_IFINDEX
{
struct remote_endpoint_info *info;

info = ipcache_lookup4(&IPCACHE_MAP, ip4->daddr, V4_CACHE_KEY_LEN);
if (info != NULL && info->tunnel_endpoint != 0) {
int ret = __encap_with_nodeid(skb, info->tunnel_endpoint,
SECLABEL, TRACE_PAYLOAD_LEN);
if (ret)
return ret;

*ifindex = ENCAP_IFINDEX;

/* fib lookup not necessary when going over tunnel. */
if (eth_store_daddr(skb, fib_params.dmac, 0) < 0)
return DROP_WRITE_ERROR;
if (eth_store_saddr(skb, fib_params.smac, 0) < 0)
return DROP_WRITE_ERROR;

return TC_ACT_OK;
}
}
#endif
fib_params.family = AF_INET;
fib_params.ifindex = NATIVE_DEV_IFINDEX;
fib_params.ifindex = *ifindex;

fib_params.ipv4_src = ip4->saddr;
fib_params.ipv4_dst = ip4->daddr;
Expand All @@ -529,10 +554,10 @@ static inline int rev_nodeport_lb4(struct __sk_buff *skb)
__section_tail(CILIUM_MAP_CALLS, CILIUM_CALL_IPV4_NODEPORT_REVNAT)
int tail_rev_nodeport_lb4(struct __sk_buff *skb)
{
int ret = rev_nodeport_lb4(skb);
int ifindex = NATIVE_DEV_IFINDEX, ret = rev_nodeport_lb4(skb, &ifindex);
if (IS_ERR(ret))
return send_drop_notify_error(skb, 0, ret, TC_ACT_SHOT, METRIC_EGRESS);
return redirect(NATIVE_DEV_IFINDEX, 0);
return redirect(ifindex, 0);
}
#endif /* ENABLE_IPV4 */
#endif /* ENABLE_NODEPORT */
Expand Down
2 changes: 1 addition & 1 deletion daemon/bpf.sha
@@ -1,2 +1,2 @@
GO_BINDATA_SHA1SUM=8175dcb49e1a5213b4a45b281d6419512c623cc7
GO_BINDATA_SHA1SUM=d474a0cd4258193c00de39203b09386fbc49d628
BPF_FILES=../bpf/COPYING ../bpf/Makefile ../bpf/Makefile.bpf ../bpf/bpf_alignchecker.c ../bpf/bpf_features.h ../bpf/bpf_hostdev_ingress.c ../bpf/bpf_ipsec.c ../bpf/bpf_lb.c ../bpf/bpf_lxc.c ../bpf/bpf_netdev.c ../bpf/bpf_network.c ../bpf/bpf_overlay.c ../bpf/bpf_sock.c ../bpf/bpf_xdp.c ../bpf/cilium-map-migrate.c ../bpf/filter_config.h ../bpf/include/bpf/api.h ../bpf/include/elf/elf.h ../bpf/include/elf/gelf.h ../bpf/include/elf/libelf.h ../bpf/include/iproute2/bpf_elf.h ../bpf/include/linux/bpf.h ../bpf/include/linux/bpf_common.h ../bpf/include/linux/byteorder.h ../bpf/include/linux/byteorder/big_endian.h ../bpf/include/linux/byteorder/little_endian.h ../bpf/include/linux/icmp.h ../bpf/include/linux/icmpv6.h ../bpf/include/linux/if_arp.h ../bpf/include/linux/if_ether.h ../bpf/include/linux/if_packet.h ../bpf/include/linux/in.h ../bpf/include/linux/in6.h ../bpf/include/linux/ioctl.h ../bpf/include/linux/ip.h ../bpf/include/linux/ipv6.h ../bpf/include/linux/perf_event.h ../bpf/include/linux/swab.h ../bpf/include/linux/tcp.h ../bpf/include/linux/type_mapper.h ../bpf/include/linux/udp.h ../bpf/init.sh ../bpf/lib/arp.h ../bpf/lib/common.h ../bpf/lib/config.h ../bpf/lib/conntrack.h ../bpf/lib/conntrack_map.h ../bpf/lib/csum.h ../bpf/lib/dbg.h ../bpf/lib/drop.h ../bpf/lib/encap.h ../bpf/lib/eps.h ../bpf/lib/eth.h ../bpf/lib/events.h ../bpf/lib/icmp6.h ../bpf/lib/ipv4.h ../bpf/lib/ipv6.h ../bpf/lib/l3.h ../bpf/lib/l4.h ../bpf/lib/lb.h ../bpf/lib/lxc.h ../bpf/lib/maps.h ../bpf/lib/metrics.h ../bpf/lib/nat.h ../bpf/lib/nat46.h ../bpf/lib/nodeport.h ../bpf/lib/policy.h ../bpf/lib/tailcall.h ../bpf/lib/trace.h ../bpf/lib/utils.h ../bpf/lib/xdp.h ../bpf/lxc_config.h ../bpf/netdev_config.h ../bpf/node_config.h ../bpf/probes/raw_change_tail.t ../bpf/probes/raw_fib_lookup.t ../bpf/probes/raw_insn.h ../bpf/probes/raw_invalidate_hash.t ../bpf/probes/raw_lpm_map.t ../bpf/probes/raw_lru_map.t ../bpf/probes/raw_main.c ../bpf/probes/raw_map_val_adj.t ../bpf/probes/raw_mark_map_val.t ../bpf/probes/raw_sock_cookie.t ../bpf/run_probes.sh ../bpf/sockops/Makefile ../bpf/sockops/bpf_redir.c ../bpf/sockops/bpf_sockops.c ../bpf/sockops/bpf_sockops.h ../bpf/sockops/sockops_config.h
4 changes: 4 additions & 0 deletions daemon/datapath.go
Expand Up @@ -149,6 +149,10 @@ func (d *Daemon) compileBase() error {
}

args[initArgMode] = mode
if option.Config.EnableNodePort &&
strings.ToLower(option.Config.Tunnel) != "disabled" {
args[initArgMode] = option.Config.Tunnel
}
args[initArgDevice] = option.Config.Device
} else {
if option.Config.IsLBEnabled() && strings.ToLower(option.Config.Tunnel) != "disabled" {
Expand Down

0 comments on commit 3a83623

Please sign in to comment.