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

     1  /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
     2  /* Copyright Authors of Cilium */
     3  
     4  /*
     5   * Socket based service load-balancing notification via perf event ring buffer.
     6   *
     7   * API:
     8   * void send_trace_sock_notify(ctx, xlate_point, dst_ip, dst_port)
     9   *
    10   * @ctx:	 socket address structre
    11   * @xlate_point: pre- or post- service translation point for load-balancing
    12   * @dst_ip:	 pre- or post- service translation destination ip address
    13   * @dst_port:	 pre- or post- service translation destination port
    14   *
    15   * If TRACE_SOCK_NOTIFY is not defined, the API will be compiled in as a NOP.
    16   */
    17  #pragma once
    18  
    19  #include <bpf/ctx/sock.h>
    20  
    21  #include "common.h"
    22  #include "events.h"
    23  
    24  /* L4 protocol for the trace event */
    25  enum l4_protocol {
    26  	L4_PROTOCOL_UNKNOWN = 0,
    27  	L4_PROTOCOL_TCP = 1,
    28  	L4_PROTOCOL_UDP = 2,
    29  } __packed;
    30  
    31  /* Direction for translation between service and backend IP */
    32  enum xlate_point {
    33  	XLATE_UNKNOWN = 0,
    34  	XLATE_PRE_DIRECTION_FWD = 1,  /* Pre service forward translation */
    35  	XLATE_POST_DIRECTION_FWD = 2, /* Post service forward translation */
    36  	XLATE_PRE_DIRECTION_REV = 3,  /* Pre reverse service translation */
    37  	XLATE_POST_DIRECTION_REV = 4, /* Post reverse service translation */
    38  } __packed;
    39  
    40  struct ip {
    41  	union {
    42  		struct {
    43  			__be32 ip4;
    44  			__u32 pad1;
    45  			__u32 pad2;
    46  			__u32 pad3;
    47  		};
    48  		union v6addr ip6;
    49  	} __packed;
    50  };
    51  
    52  #ifdef TRACE_SOCK_NOTIFY
    53  struct trace_sock_notify {
    54  	__u8 type;
    55  	__u8 xlate_point;
    56  	struct ip dst_ip;
    57  	__u16 dst_port;
    58  	__u64 sock_cookie;
    59  	__u64 cgroup_id;
    60  	__u8 l4_proto;
    61  	__u8 ipv6 : 1;
    62  	__u8 pad : 7;
    63  } __packed;
    64  
    65  static __always_inline enum l4_protocol
    66  parse_protocol(__u32 l4_proto) {
    67  	switch (l4_proto) {
    68  	case IPPROTO_TCP:
    69  		return L4_PROTOCOL_TCP;
    70  	case IPPROTO_UDP:
    71  		return L4_PROTOCOL_UDP;
    72  	default:
    73  		return L4_PROTOCOL_UNKNOWN;
    74  	}
    75  }
    76  
    77  static __always_inline void
    78  send_trace_sock_notify4(struct __ctx_sock *ctx,
    79  			enum xlate_point xlate_point,
    80  			__u32 dst_ip, __u16 dst_port)
    81  {
    82  	__u64 cgroup_id = 0;
    83  	struct trace_sock_notify msg __align_stack_8;
    84  
    85  	if (is_defined(HAVE_CGROUP_ID))
    86  		cgroup_id = get_current_cgroup_id();
    87  
    88  	msg = (typeof(msg)){
    89  		.type		= CILIUM_NOTIFY_TRACE_SOCK,
    90  		.xlate_point	= xlate_point,
    91  		.dst_ip.ip4	= dst_ip,
    92  		.dst_port	= dst_port,
    93  		.sock_cookie	= sock_local_cookie(ctx),
    94  		.cgroup_id	= cgroup_id,
    95  		.l4_proto	= parse_protocol(ctx->protocol),
    96  		.ipv6		= 0,
    97  	};
    98  
    99  	ctx_event_output(ctx, &EVENTS_MAP, BPF_F_CURRENT_CPU, &msg, sizeof(msg));
   100  }
   101  
   102  static __always_inline void
   103  send_trace_sock_notify6(struct __ctx_sock *ctx,
   104  			enum xlate_point xlate_point,
   105  			union v6addr *dst_addr,
   106  			__u16 dst_port)
   107  {
   108  	__u64 cgroup_id = 0;
   109  	struct trace_sock_notify msg __align_stack_8;
   110  
   111  	if (is_defined(HAVE_CGROUP_ID))
   112  		cgroup_id = get_current_cgroup_id();
   113  	msg = (typeof(msg)){
   114  		.type		= CILIUM_NOTIFY_TRACE_SOCK,
   115  		.xlate_point	= xlate_point,
   116  		.dst_port	= dst_port,
   117  		.sock_cookie	= sock_local_cookie(ctx),
   118  		.cgroup_id	= cgroup_id,
   119  		.l4_proto	= parse_protocol(ctx->protocol),
   120  		.ipv6		= 1,
   121  	};
   122  	ipv6_addr_copy_unaligned(&msg.dst_ip.ip6, dst_addr);
   123  
   124  	ctx_event_output(ctx, &EVENTS_MAP, BPF_F_CURRENT_CPU, &msg, sizeof(msg));
   125  }
   126  #else
   127  static __always_inline void
   128  send_trace_sock_notify4(struct __ctx_sock *ctx __maybe_unused,
   129  			enum xlate_point xlate_point __maybe_unused,
   130  			__u32 dst_ip __maybe_unused, __u16 dst_port __maybe_unused)
   131  {
   132  }
   133  
   134  static __always_inline void
   135  send_trace_sock_notify6(struct __ctx_sock *ctx __maybe_unused,
   136  			enum xlate_point xlate_point __maybe_unused,
   137  			union v6addr *dst_addr __maybe_unused,
   138  			__u16 dst_port __maybe_unused)
   139  {
   140  }
   141  #endif /* TRACE_SOCK_NOTIFY */