github.com/cilium/cilium@v1.16.2/bpf/bpf_network.c (about)

     1  // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
     2  /* Copyright Authors of Cilium */
     3  
     4  #include <bpf/ctx/skb.h>
     5  #include <bpf/api.h>
     6  
     7  #include <node_config.h>
     8  #include <netdev_config.h>
     9  
    10  #include "lib/common.h"
    11  #include "lib/trace.h"
    12  #include "lib/encrypt.h"
    13  
    14  __section_entry
    15  int cil_from_network(struct __ctx_buff *ctx)
    16  {
    17  	int ret = CTX_ACT_OK;
    18  
    19  	__u16 proto __maybe_unused;
    20  	__u32 ingress_ifindex = ctx->ingress_ifindex;
    21  	struct trace_ctx trace = {
    22  		.reason = TRACE_REASON_UNKNOWN,
    23  		.monitor = 0,
    24  	};
    25  	enum trace_point obs_point_to = TRACE_TO_STACK;
    26  	enum trace_point obs_point_from = TRACE_FROM_NETWORK;
    27  
    28  	bpf_clear_meta(ctx);
    29  
    30  	/* This program should be attached to the tc-ingress of
    31  	 * the network-facing device. Thus, as far as Cilium
    32  	 * knows, no one touches to the ctx->mark before this
    33  	 * program.
    34  	 *
    35  	 * One exception is the case the packets are re-insearted
    36  	 * from the stack by xfrm. In that case, the packets should
    37  	 * be marked with MARK_MAGIC_DECRYPT.
    38  	 */
    39  	if ((ctx->mark & MARK_MAGIC_HOST_MASK) == MARK_MAGIC_DECRYPT)
    40  		obs_point_from = TRACE_FROM_STACK;
    41  
    42  #ifdef ENABLE_IPSEC
    43  	/* Pass unknown protocols to the stack */
    44  	if (!validate_ethertype(ctx, &proto))
    45  		goto out;
    46  
    47  	ret = do_decrypt(ctx, proto);
    48  #endif
    49  
    50  /* We need to handle following possible packets come to this program
    51   *
    52   * 1. ESP packets coming from network (encrypted and not marked)
    53   * 2. Non-ESP packets coming from network (plain and not marked)
    54   * 3. Non-ESP packets coming from stack re-inserted by xfrm (plain
    55   *    and marked with MARK_MAGIC_DECRYPT, IPSec mode only)
    56   *
    57   * 1. will be traced with TRACE_REASON_ENCRYPTED, because
    58   * do_decrypt marks them with MARK_MAGIC_DECRYPT.
    59   *
    60   * 2. will be traced without TRACE_REASON_ENCRYPTED, because
    61   * do_decrypt does't touch to mark.
    62   *
    63   * 3. will be traced without TRACE_REASON_ENCRYPTED, because
    64   * do_decrypt clears the mark.
    65   *
    66   * Note that 1. contains the ESP packets someone else generated.
    67   * In that case, we trace it as "encrypted", but it doesn't mean
    68   * "encrypted by Cilium".
    69   *
    70   * We won't use TRACE_REASON_ENCRYPTED even if the packets are ESP,
    71   * because it doesn't matter for the non-IPSec mode.
    72   */
    73  #ifdef ENABLE_IPSEC
    74  	if ((ctx->mark & MARK_MAGIC_HOST_MASK) == MARK_MAGIC_DECRYPT)
    75  		trace.reason = TRACE_REASON_ENCRYPTED;
    76  
    77  	/* Only possible redirect in here is the one in the do_decrypt
    78  	 * which redirects to cilium_host.
    79  	 */
    80  	if (ret == CTX_ACT_REDIRECT)
    81  		obs_point_to = TRACE_TO_HOST;
    82  #endif
    83  
    84  out:
    85  	send_trace_notify(ctx, obs_point_from, UNKNOWN_ID, UNKNOWN_ID,
    86  			  TRACE_EP_ID_UNKNOWN, ingress_ifindex,
    87  			  trace.reason, trace.monitor);
    88  
    89  	send_trace_notify(ctx, obs_point_to, UNKNOWN_ID, UNKNOWN_ID,
    90  			  TRACE_EP_ID_UNKNOWN, ingress_ifindex,
    91  			  trace.reason, trace.monitor);
    92  
    93  	return ret;
    94  }
    95  
    96  BPF_LICENSE("Dual BSD/GPL");