Skip to content

Commit

Permalink
bpf: remove special handle for ICMPv6 echo targeting router IPv6
Browse files Browse the repository at this point in the history
Previously we didn't have any network interface whose IPv6 was set to
router IPv6, so the special handle for ICMPv6 echo whose destination
address is router IPv6 was required, as kernel couldn't handle such
ICMPv6 echo; but it's no more the case since PR #24208 was merged, now
cilium_host has router IPv6 instead of native IPv6, making kernel
capable of handling this ICMPv6.

Therefore, this commit removes code relevant to this special handle,
including several functions such as icmp6_send_echo_reply,
tail_icmp6_send_echo_reply, __icmp6_send_echo_reply.

Macro SKIP_ICMPV6_ECHO_HANDLING and CILIUM_CALL_SEND_ICMP6_ECHO_REPLY
are also obsolete and deleted.

Deletion of macro CILIUM_CALL_SEND_ICMP6_ECHO_REPLY leaves a gap in the
sequence of numbers, and we don't renumber the other macros in order to
pass the CI tests, otherwise the K8sUpdates test suite would fail due to
"migrate-svc restart count values do not match"

Signed-off-by: Zhichuan Liang <gray.liang@isovalent.com>
  • Loading branch information
jschwinger233 committed Apr 27, 2023
1 parent 40de910 commit cc8c5c0
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 105 deletions.
5 changes: 0 additions & 5 deletions bpf/bpf_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@
/* CB_PROXY_MAGIC overlaps with CB_ENCRYPT_MAGIC */
#define ENCRYPT_OR_PROXY_MAGIC 0

/* Controls the inclusion of the CILIUM_CALL_SEND_ICMP6_ECHO_REPLY section in
* the bpf_lxc object file.
*/
#define SKIP_ICMPV6_ECHO_HANDLING

#ifndef VLAN_FILTER
# define VLAN_FILTER(ifindex, vlan_id) return false;
#endif
Expand Down
12 changes: 4 additions & 8 deletions bpf/bpf_lxc.c
Original file line number Diff line number Diff line change
Expand Up @@ -713,15 +713,11 @@ static __always_inline int __tail_handle_ipv6(struct __ctx_buff *ctx,
if (!revalidate_data_pull(ctx, &data, &data_end, &ip6))
return DROP_INVALID;

/* Handle special ICMPv6 messages. This includes echo requests to the
* logical router address, neighbour advertisements to the router.
* All remaining packets are subjected to forwarding into the container.
/* Handle special ICMPv6 NDP messages, and all remaining packets
* are subjected to forwarding into the container.
*/
if (unlikely(ip6->nexthdr == IPPROTO_ICMPV6)) {
if (data + sizeof(*ip6) + ETH_HLEN + sizeof(struct icmp6hdr) > data_end)
return DROP_INVALID;

ret = icmp6_handle(ctx, ETH_HLEN, ip6, METRIC_EGRESS);
if (unlikely(is_icmp6_ndp(ctx, ip6, ETH_HLEN))) {
ret = icmp6_ndp_handle(ctx, ETH_HLEN, METRIC_EGRESS);
if (IS_ERR(ret))
return ret;
}
Expand Down
5 changes: 0 additions & 5 deletions bpf/bpf_overlay.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@
*/
#define SKIP_ICMPV6_NS_HANDLING

/* Controls the inclusion of the CILIUM_CALL_SEND_ICMP6_ECHO_REPLY section in
* the bpf_lxc object file.
*/
#define SKIP_ICMPV6_ECHO_HANDLING

/* Controls the inclusion of the CILIUM_CALL_SRV6 section in the object file.
*/
#define SKIP_SRV6_HANDLING
Expand Down
5 changes: 0 additions & 5 deletions bpf/bpf_xdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@
*/
#define SKIP_ICMPV6_HOPLIMIT_HANDLING

/* Controls the inclusion of the CILIUM_CALL_SEND_ICMP6_ECHO_REPLY section in
* the bpf_lxc object file.
*/
#define SKIP_ICMPV6_ECHO_HANDLING

/* Controls the inclusion of the CILIUM_CALL_SRV6 section in the object file.
*/
#define SKIP_SRV6_HANDLING
Expand Down
6 changes: 5 additions & 1 deletion bpf/lib/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,11 @@ enum {

#define CILIUM_CALL_DROP_NOTIFY 1
#define CILIUM_CALL_ERROR_NOTIFY 2
#define CILIUM_CALL_SEND_ICMP6_ECHO_REPLY 3
/*
* A gap in the macro numbering sequence was created by #24921.
* It can be reused for a new macro in the future, but caution is needed when
* backporting changes as it may conflict with older versions of the code.
*/
#define CILIUM_CALL_HANDLE_ICMP6_NS 4
#define CILIUM_CALL_SEND_ICMP6_TIME_EXCEEDED 5
#define CILIUM_CALL_ARP 6
Expand Down
92 changes: 11 additions & 81 deletions bpf/lib/icmp6.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,76 +89,6 @@ static __always_inline int icmp6_send_reply(struct __ctx_buff *ctx, int nh_off)
return redirect_self(ctx);
}

static __always_inline int __icmp6_send_echo_reply(struct __ctx_buff *ctx,
int nh_off)
{
struct icmp6hdr icmp6hdr __align_stack_8 = {}, icmp6hdr_old __align_stack_8;
int csum_off = nh_off + ICMP6_CSUM_OFFSET;
__be32 sum;

cilium_dbg(ctx, DBG_ICMP6_REQUEST, nh_off, 0);

if (ctx_load_bytes(ctx, nh_off + sizeof(struct ipv6hdr), &icmp6hdr_old,
sizeof(icmp6hdr_old)) < 0)
return DROP_INVALID;

/* fill icmp6hdr */
icmp6hdr.icmp6_type = 129;
icmp6hdr.icmp6_code = 0;
icmp6hdr.icmp6_cksum = icmp6hdr_old.icmp6_cksum;
icmp6hdr.icmp6_dataun.un_data32[0] = 0;
icmp6hdr.icmp6_identifier = icmp6hdr_old.icmp6_identifier;
icmp6hdr.icmp6_sequence = icmp6hdr_old.icmp6_sequence;

if (ctx_store_bytes(ctx, nh_off + sizeof(struct ipv6hdr), &icmp6hdr,
sizeof(icmp6hdr), 0) < 0)
return DROP_WRITE_ERROR;

/* fixup checksum */
sum = csum_diff(&icmp6hdr_old, sizeof(icmp6hdr_old),
&icmp6hdr, sizeof(icmp6hdr), 0);

if (l4_csum_replace(ctx, csum_off, 0, sum, BPF_F_PSEUDO_HDR) < 0)
return DROP_CSUM_L4;

return icmp6_send_reply(ctx, nh_off);
}

#ifndef SKIP_ICMPV6_ECHO_HANDLING
__section_tail(CILIUM_MAP_CALLS, CILIUM_CALL_SEND_ICMP6_ECHO_REPLY)
int tail_icmp6_send_echo_reply(struct __ctx_buff *ctx)
{
int ret, nh_off = ctx_load_meta(ctx, 0);
enum metric_dir direction = (enum metric_dir)ctx_load_meta(ctx, 1);

ctx_store_meta(ctx, 0, 0);
ret = __icmp6_send_echo_reply(ctx, nh_off);
if (IS_ERR(ret))
return send_drop_notify_error(ctx, 0, ret, CTX_ACT_DROP, direction);
return ret;
}
#endif

/*
* icmp6_send_echo_reply
* @ctx: socket buffer
* @nh_off: offset to the IPv6 header
*
* Send an ICMPv6 echo reply in return to an ICMPv6 echo reply.
*
* NOTE: This is terminal function and will cause the BPF program to exit
*/
static __always_inline int icmp6_send_echo_reply(struct __ctx_buff *ctx,
int nh_off, enum metric_dir direction)
{
ctx_store_meta(ctx, 0, nh_off);
ctx_store_meta(ctx, 1, direction);

ep_tail_call(ctx, CILIUM_CALL_SEND_ICMP6_ECHO_REPLY);

return DROP_MISSED_TAIL_CALL;
}

/*
* send_icmp6_ndisc_adv
* @ctx: socket buffer
Expand Down Expand Up @@ -437,23 +367,23 @@ static __always_inline int icmp6_handle_ns(struct __ctx_buff *ctx, int nh_off,
return DROP_MISSED_TAIL_CALL;
}

static __always_inline int icmp6_handle(struct __ctx_buff *ctx, int nh_off,
struct ipv6hdr *ip6, enum metric_dir direction)
static __always_inline bool
is_icmp6_ndp(struct __ctx_buff *ctx, const struct ipv6hdr *ip6, int nh_off)
{
union v6addr router_ip;
__u8 type = icmp6_load_type(ctx, nh_off);

return ip6->nexthdr == IPPROTO_ICMPV6 &&
(type == ICMP6_NS_MSG_TYPE || type == ICMP6_NA_MSG_TYPE);
}

static __always_inline int icmp6_ndp_handle(struct __ctx_buff *ctx, int nh_off,
enum metric_dir direction)
{
__u8 type = icmp6_load_type(ctx, nh_off);
cilium_dbg(ctx, DBG_ICMP6_HANDLE, type, 0);
BPF_V6(router_ip, ROUTER_IP);

switch (type) {
case ICMP6_NS_MSG_TYPE:
if (type == ICMP6_NS_MSG_TYPE)
return icmp6_handle_ns(ctx, nh_off, direction);
case ICMPV6_ECHO_REQUEST:
if (!ipv6_addrcmp((union v6addr *) &ip6->daddr, &router_ip))
return icmp6_send_echo_reply(ctx, nh_off, direction);
break;
}

/* All branching above will have issued a tail call, all
* remaining traffic is subject to forwarding to containers.
Expand Down

0 comments on commit cc8c5c0

Please sign in to comment.