Created
July 9, 2020 18:42
-
-
Save anfernee/423a78fca4e8bc27dfcf981bfd88730b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/bpf/lib/icmp6.h b/bpf/lib/icmp6.h | |
index 3446b727e..4fa0aa57e 100644 | |
--- a/bpf/lib/icmp6.h | |
+++ b/bpf/lib/icmp6.h | |
@@ -9,6 +9,8 @@ | |
#include "common.h" | |
#include "eth.h" | |
#include "drop.h" | |
+#include "eps.h" | |
+#include "dbg.h" | |
#define ICMP6_TYPE_OFFSET (sizeof(struct ipv6hdr) + offsetof(struct icmp6hdr, icmp6_type)) | |
#define ICMP6_CSUM_OFFSET (sizeof(struct ipv6hdr) + offsetof(struct icmp6hdr, icmp6_cksum)) | |
@@ -153,8 +155,17 @@ static __always_inline int icmp6_send_echo_reply(struct __ctx_buff *ctx, | |
return DROP_MISSED_TAIL_CALL; | |
} | |
+/* | |
+ * send_icmp6_ndisc_adv | |
+ * @ctx: socket buffer | |
+ * @nh_off: offset to the IPv6 header | |
+ * @mac: device mac address | |
+ * @to_router: ndisc is sent to router, otherwise ndisc is sent to an endpoint. | |
+ * | |
+ * Send an ICMPv6 nadv reply in return to an ICMPv6 ndisc. | |
+ */ | |
static __always_inline int send_icmp6_ndisc_adv(struct __ctx_buff *ctx, | |
- int nh_off, union macaddr *mac) | |
+ int nh_off, union macaddr *mac, bool to_router) | |
{ | |
struct icmp6hdr icmp6hdr __align_stack_8 = {}, icmp6hdr_old __align_stack_8; | |
__u8 opts[8], opts_old[8]; | |
@@ -170,9 +181,16 @@ static __always_inline int send_icmp6_ndisc_adv(struct __ctx_buff *ctx, | |
icmp6hdr.icmp6_code = 0; | |
icmp6hdr.icmp6_cksum = icmp6hdr_old.icmp6_cksum; | |
icmp6hdr.icmp6_dataun.un_data32[0] = 0; | |
- icmp6hdr.icmp6_router = 1; | |
- icmp6hdr.icmp6_solicited = 1; | |
- icmp6hdr.icmp6_override = 0; | |
+ | |
+ if (to_router) { | |
+ icmp6hdr.icmp6_router = 1; | |
+ icmp6hdr.icmp6_solicited = 1; | |
+ icmp6hdr.icmp6_override = 0; | |
+ } else { | |
+ icmp6hdr.icmp6_router = 0; | |
+ icmp6hdr.icmp6_solicited = 0; | |
+ icmp6hdr.icmp6_override = 1; | |
+ } | |
if (ctx_store_bytes(ctx, nh_off + sizeof(struct ipv6hdr), &icmp6hdr, sizeof(icmp6hdr), 0) < 0) | |
return DROP_WRITE_ERROR; | |
@@ -345,6 +363,7 @@ static __always_inline int icmp6_send_time_exceeded(struct __ctx_buff *ctx, | |
static __always_inline int __icmp6_handle_ns(struct __ctx_buff *ctx, int nh_off) | |
{ | |
union v6addr target, router; | |
+ struct endpoint_info *ep; | |
if (ctx_load_bytes(ctx, nh_off + ICMP6_ND_TARGET_OFFSET, target.addr, | |
sizeof(((struct ipv6hdr *)NULL)->saddr)) < 0) | |
@@ -352,11 +371,17 @@ static __always_inline int __icmp6_handle_ns(struct __ctx_buff *ctx, int nh_off) | |
cilium_dbg(ctx, DBG_ICMP6_NS, target.p3, target.p4); | |
+ ep = __lookup_ip6_endpoint(&target); | |
+ | |
BPF_V6(router, ROUTER_IP); | |
if (ipv6_addrcmp(&target, &router) == 0) { | |
union macaddr router_mac = NODE_MAC; | |
- return send_icmp6_ndisc_adv(ctx, nh_off, &router_mac); | |
+ return send_icmp6_ndisc_adv(ctx, nh_off, &router_mac, true); | |
+ } else if (ep != NULL) { | |
+ union macaddr node_mac = NODE_MAC; | |
+ | |
+ return send_icmp6_ndisc_adv(ctx, nh_off, &node_mac, false); | |
} else { | |
/* Unknown target address, drop */ | |
return ACTION_UNKNOWN_ICMP6_NS; | |
@@ -426,6 +451,11 @@ icmp6_host_handle(struct __ctx_buff *ctx __maybe_unused) | |
{ | |
__u8 type __maybe_unused; | |
+ type = icmp6_load_type(ctx, ETH_HLEN); | |
+ if (type == ICMP6_NS_MSG_TYPE) { | |
+ return __icmp6_handle_ns(ctx, ETH_HLEN); | |
+ } | |
+ | |
#ifdef ENABLE_HOST_FIREWALL | |
/* When the host firewall is enabled, we drop and allow ICMPv6 messages | |
* according to RFC4890, except for echo request and reply messages which | |
@@ -473,7 +503,7 @@ icmp6_host_handle(struct __ctx_buff *ctx __maybe_unused) | |
* | ICMPv6-unallocated | CTX_ACT_DROP | | | |
* | ICMPv6-unassigned | CTX_ACT_DROP | | | |
*/ | |
- type = icmp6_load_type(ctx, ETH_HLEN); | |
+ | |
if (type == ICMP6_ECHO_REQUEST_MSG_TYPE || type == ICMP6_ECHO_REPLY_MSG_TYPE) | |
return CTX_ACT_OK; | |
diff --git a/bpf/lib/overloadable_skb.h b/bpf/lib/overloadable_skb.h | |
index 26e0cca07..67e1192d7 100644 | |
--- a/bpf/lib/overloadable_skb.h | |
+++ b/bpf/lib/overloadable_skb.h | |
@@ -73,9 +73,17 @@ redirect_self(const struct __sk_buff *ctx) | |
*/ | |
#ifdef ENABLE_HOST_REDIRECT | |
return redirect(ctx->ifindex, 0); | |
+#else | |
+#ifdef NATIVE_IFINDEX | |
+ if (ctx->ifindex == NATIVE_IFINDEX) { | |
+ return redirect(ctx->ifindex, 0); | |
+ } else { | |
+ return redirect(ctx->ifindex, BPF_F_INGRESS); | |
+ } | |
#else | |
return redirect(ctx->ifindex, BPF_F_INGRESS); | |
-#endif | |
+#endif /* NATIVE_IFINDEX */ | |
+#endif /* ENABLE_HOST_REDIRECT */ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment