github.com/cilium/cilium@v1.16.2/bpf/lib/policy_log.h (about)

     1  /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
     2  /* Copyright Authors of Cilium */
     3  
     4  /*
     5   * Policy verdict notification via perf event ring buffer.
     6   *
     7   * API:
     8   * void send_policy_verdict_notify(ctx, remote_label, dst_port, proto, dir,
     9   *                                 is_ipv6, verdict, match_type)
    10   *
    11   * If POLICY_VERDICT_NOTIFY is not defined, the API will be a non-op.
    12   */
    13  #pragma once
    14  
    15  #include "common.h"
    16  
    17  #ifdef POLICY_VERDICT_NOTIFY
    18  
    19  #ifndef POLICY_VERDICT_LOG_FILTER
    20  DEFINE_U32(POLICY_VERDICT_LOG_FILTER, 0xffff);
    21  #define POLICY_VERDICT_LOG_FILTER fetch_u32(POLICY_VERDICT_LOG_FILTER)
    22  #endif
    23  
    24  struct policy_verdict_notify {
    25  	NOTIFY_CAPTURE_HDR
    26  	__u32	remote_label;
    27  	__s32	verdict;
    28  	__u16	dst_port;
    29  	__u8	proto;
    30  	__u8	dir:2,
    31  		ipv6:1,
    32  		match_type:3,
    33  		audited:1,
    34  		pad0:1;
    35  	__u8	auth_type;
    36  	__u8	pad1; /* align with 64 bits */
    37  	__u16	pad2; /* align with 64 bits */
    38  };
    39  
    40  static __always_inline bool policy_verdict_filter_allow(__u32 filter, __u8 dir)
    41  {
    42  	/* Make dir being volatile to avoid compiler optimizing out
    43  	 * filter (thinking it to be zero).
    44  	 */
    45  	volatile __u8 d = dir;
    46  
    47  	return ((filter & d) > 0);
    48  }
    49  
    50  static __always_inline void
    51  send_policy_verdict_notify(struct __ctx_buff *ctx, __u32 remote_label, __u16 dst_port,
    52  			   __u8 proto, __u8 dir, __u8 is_ipv6, int verdict, __u16 proxy_port,
    53  			   __u8 match_type, __u8 is_audited, __u8 auth_type)
    54  {
    55  	__u64 ctx_len = ctx_full_len(ctx);
    56  	__u64 cap_len = min_t(__u64, TRACE_PAYLOAD_LEN, ctx_len);
    57  	struct policy_verdict_notify msg;
    58  
    59  #if defined(IS_BPF_HOST)
    60  	/* When this function is called in the context of bpf_host (e.g. by
    61  	 * host firewall) POLICY_VERDICT_LOG_FILTER is always set to 0,
    62  	 * preventing any policy verdict notification, as the logic to set it
    63  	 * is only wired up to endpoints.
    64  	 *
    65  	 * Insead of tweaking POLICY_VERDICT_LOG_FILTER and reloading bpf_host
    66  	 * based on whether host firewall policies are present or not, just
    67  	 * always enable policy verdicts notifications, and filter out the ones
    68  	 * for default allow policies, to prevent a flood of notifications for
    69  	 * traffic allowed by default.
    70  	 */
    71  	if (match_type == POLICY_MATCH_ALL && verdict == CTX_ACT_OK)
    72  		return;
    73  #else
    74  	if (!policy_verdict_filter_allow(POLICY_VERDICT_LOG_FILTER, dir))
    75  		return;
    76  #endif
    77  
    78  	if (verdict == 0)
    79  		verdict = (int)proxy_port;
    80  
    81  	msg = (typeof(msg)) {
    82  		__notify_common_hdr(CILIUM_NOTIFY_POLICY_VERDICT, 0),
    83  		__notify_pktcap_hdr(ctx_len, (__u16)cap_len),
    84  		.remote_label	= remote_label,
    85  		.verdict	= verdict,
    86  		.dst_port	= bpf_ntohs(dst_port),
    87  		.match_type	= match_type,
    88  		.proto		= proto,
    89  		.dir		= dir,
    90  		.ipv6		= is_ipv6,
    91  		.audited	= is_audited,
    92  		.auth_type      = auth_type,
    93  	};
    94  
    95  	ctx_event_output(ctx, &EVENTS_MAP,
    96  			 (cap_len << 32) | BPF_F_CURRENT_CPU,
    97  			 &msg, sizeof(msg));
    98  }
    99  #else
   100  static __always_inline void
   101  send_policy_verdict_notify(struct __ctx_buff *ctx __maybe_unused,
   102  			   __u32 remote_label __maybe_unused, __u16 dst_port __maybe_unused,
   103  			   __u8 proto __maybe_unused, __u8 dir __maybe_unused,
   104  			   __u8 is_ipv6 __maybe_unused, int verdict __maybe_unused,
   105  			   __u16 proxy_port __maybe_unused,
   106  			   __u8 match_type __maybe_unused, __u8 is_audited __maybe_unused,
   107  			   __u8 auth_type __maybe_unused)
   108  {
   109  }
   110  #endif /* POLICY_VERDICT_NOTIFY */