Skip to content

Commit

Permalink
cilium: create lib for encryption
Browse files Browse the repository at this point in the history
To allow both bpf_network and bpf_host to use the same code add a encrypt.h
file to put common routines.

Signed-off-by: John Fastabend <john.fastabend@gmail.com>
  • Loading branch information
jrfastab authored and christarazi committed Sep 29, 2020
1 parent 0b8148b commit 9ed106a
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 99 deletions.
114 changes: 15 additions & 99 deletions bpf/bpf_network.c
Expand Up @@ -8,93 +8,18 @@
#include <netdev_config.h>

#include "lib/common.h"
#include "lib/maps.h"
#include "lib/ipv6.h"
#include "lib/eth.h"
#include "lib/dbg.h"
#include "lib/trace.h"
#include "lib/l3.h"
#include "lib/drop.h"

#ifdef ENABLE_IPV6
static __always_inline int handle_ipv6(struct __ctx_buff *ctx)
{
#ifdef ENABLE_IPSEC
void *data_end, *data;
struct ipv6hdr *ip6;
bool decrypted;

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

if (!decrypted) {
/* IPSec is not currently enforce (feature coming soon)
* so for now just handle normally
*/
if (ip6->nexthdr != IPPROTO_ESP)
return 0;

/* Decrypt "key" is determined by SPI */
ctx->mark = MARK_MAGIC_DECRYPT;

/* We are going to pass this up the stack for IPsec decryption
* but eth_type_trans may already have labeled this as an
* OTHERHOST type packet. To avoid being dropped by IP stack
* before IPSec can be processed mark as a HOST packet.
*/
ctx_change_type(ctx, PACKET_HOST);
return CTX_ACT_OK;
}

ctx->mark = 0;
return redirect(CILIUM_IFINDEX, 0);
#endif
return 0;
}
#endif /* ENABLE_IPV6 */

#ifdef ENABLE_IPV4
static __always_inline int handle_ipv4(struct __ctx_buff *ctx)
{
#ifdef ENABLE_IPSEC
void *data_end, *data;
struct iphdr *ip4;
bool decrypted;

decrypted = ((ctx->mark & MARK_MAGIC_HOST_MASK) == MARK_MAGIC_DECRYPT);
if (!revalidate_data_pull(ctx, &data, &data_end, &ip4))
return DROP_INVALID;

if (!decrypted) {
/* IPSec is not currently enforce (feature coming soon)
* so for now just handle normally
*/
if (ip4->protocol != IPPROTO_ESP)
goto out;
/* Decrypt "key" is determined by SPI */
ctx->mark = MARK_MAGIC_DECRYPT;
ctx_change_type(ctx, PACKET_HOST);
return CTX_ACT_OK;
}

ctx->mark = 0;
return redirect(CILIUM_IFINDEX, 0);
out:
#endif
return 0;
}
#endif
#include "lib/encrypt.h"

__section("from-network")
int from_network(struct __ctx_buff *ctx)
{
#ifdef ENABLE_IPSEC
__u16 proto;
int ret = 0;
int ret;

bpf_clear_meta(ctx);

#ifdef ENABLE_IPSEC
if ((ctx->mark & MARK_MAGIC_HOST_MASK) == MARK_MAGIC_DECRYPT) {
send_trace_notify(ctx, TRACE_FROM_NETWORK, get_identity(ctx), 0, 0,
ctx->ingress_ifindex,
Expand All @@ -106,30 +31,21 @@ int from_network(struct __ctx_buff *ctx)
ctx->ingress_ifindex, 0, TRACE_PAYLOAD_LEN);
}

if (!validate_ethertype(ctx, &proto)) {
/* Pass unknown traffic to the stack */
ret = CTX_ACT_OK;
return ret;
}
bpf_clear_meta(ctx);

switch (proto) {
case bpf_htons(ETH_P_IPV6):
#ifdef ENABLE_IPV6
ret = handle_ipv6(ctx);
#endif
break;
#ifdef ENABLE_IPSEC
/* Pass unknown protocols to the stack */
if (!validate_ethertype(ctx, &proto))
return CTX_ACT_OK;

case bpf_htons(ETH_P_IP):
#ifdef ENABLE_IPV4
ret = handle_ipv4(ctx);
ret = do_decrypt(ctx, proto);
if (!ret)
return CTX_ACT_OK;
ctx->mark = 0;
return redirect(CILIUM_IFINDEX, 0);
#endif
break;

default:
/* Pass unknown traffic to the stack */
ret = CTX_ACT_OK;
}
return ret;
/* Pass unknown traffic to the stack */
return CTX_ACT_OK;
}

BPF_LICENSE("GPL");
72 changes: 72 additions & 0 deletions bpf/lib/encrypt.h
@@ -0,0 +1,72 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2020 Authors of Cilium */

#ifndef __LIB_ENCRYPT_H_
#define __LIB_ENCRYPT_H_

#include <bpf/ctx/skb.h>
#include <bpf/api.h>

#include "lib/common.h"
#include "lib/ipv6.h"
#include "lib/l3.h"
#include "lib/eth.h"

#ifdef ENABLE_IPSEC
static __always_inline int
do_decrypt(struct __ctx_buff *ctx, __u16 proto)
{
bool decrypted;

decrypted = ((ctx->mark & MARK_MAGIC_HOST_MASK) == MARK_MAGIC_DECRYPT);
if (!decrypted) {
void *data, *data_end;
__u8 protocol = 0;
#ifdef ENABLE_IPV6
struct ipv6hdr *ip6;
#endif
#ifdef ENABLE_IPV4
struct iphdr *ip4;
#endif

switch (proto) {
#ifdef ENABLE_IPV6
case bpf_htons(ETH_P_IPV6):
if (!revalidate_data_pull(ctx, &data, &data_end, &ip6))
break;
protocol = ip6->nexthdr;
break;
#endif
#ifdef ENABLE_IPV4
case bpf_htons(ETH_P_IP):
if (!revalidate_data(ctx, &data, &data_end, &ip4))
break;

protocol = ip4->protocol;
break;
#endif
}

if (protocol == IPPROTO_ESP) {
/* Decrypt "key" is determined by SPI */
ctx->mark = MARK_MAGIC_DECRYPT;
/* We are going to pass this up the stack for IPsec decryption
* but eth_type_trans may already have labeled this as an
* OTHERHOST type packet. To avoid being dropped by IP stack
* before IPSec can be processed mark as a HOST packet.
*/
ctx_change_type(ctx, PACKET_HOST);
return 0;
}
}
return -ENOENT;
}
#else
static __always_inline int
do_decrypt(struct __ctx_buff __maybe_unused *ctx, __u16 __maybe_unused proto)
{
return -ENOENT;
}
#endif /* ENABLE_IPSEC */
#endif /* __LIB_ENCRYPT_H_ */

0 comments on commit 9ed106a

Please sign in to comment.