github.com/fafucoder/cilium@v1.6.11/bpf/lib/drop.h (about)

     1  /*
     2   *  Copyright (C) 2016-2019 Authors of Cilium
     3   *
     4   *  This program is free software; you can redistribute it and/or modify
     5   *  it under the terms of the GNU General Public License as published by
     6   *  the Free Software Foundation; either version 2 of the License, or
     7   *  (at your option) any later version.
     8   *
     9   *  This program is distributed in the hope that it will be useful,
    10   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    11   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12   *  GNU General Public License for more details.
    13   *
    14   *  You should have received a copy of the GNU General Public License
    15   *  along with this program; if not, write to the Free Software
    16   *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    17   */
    18  /*
    19   * Drop & error notification via perf event ring buffer
    20   *
    21   * API:
    22   * int send_drop_notify(skb, src, dst, dst_id, reason, exitcode, __u8 direction)
    23   * int send_drop_notify_error(skb, error, exitcode, __u8 direction)
    24   *
    25   * If DROP_NOTIFY is not defined, the API will be compiled in as a NOP.
    26   */
    27  
    28  #ifndef __LIB_DROP__
    29  #define __LIB_DROP__
    30  
    31  #include "dbg.h"
    32  #include "events.h"
    33  #include "common.h"
    34  #include "utils.h"
    35  #include "metrics.h"
    36  
    37  #ifdef DROP_NOTIFY
    38  
    39  struct drop_notify {
    40  	NOTIFY_COMMON_HDR
    41  	__u32		len_orig;
    42  	__u32		len_cap;
    43  	__u32		src_label;
    44  	__u32		dst_label;
    45  	__u32		dst_id;
    46  	__u32		unused;
    47  };
    48  
    49  __section_tail(CILIUM_MAP_CALLS, CILIUM_CALL_DROP_NOTIFY) int __send_drop_notify(struct __sk_buff *skb)
    50  {
    51  	uint64_t skb_len = (uint64_t)skb->len, cap_len = min((uint64_t)TRACE_PAYLOAD_LEN, (uint64_t)skb_len);
    52  	uint32_t hash = get_hash_recalc(skb);
    53  	struct drop_notify msg = {
    54  		.type = CILIUM_NOTIFY_DROP,
    55  		.source = EVENT_SOURCE,
    56  		.hash = hash,
    57  		.len_orig = skb_len,
    58  		.len_cap = cap_len,
    59  		.src_label = skb->cb[0],
    60  		.dst_label = skb->cb[1],
    61  		.dst_id = skb->cb[3],
    62  		.unused = 0,
    63  	};
    64  	// mask needed to calm verifier
    65  	int error = skb->cb[2] & 0xFFFFFFFF;
    66  
    67  	if (error < 0)
    68  		error = -error;
    69  
    70  	msg.subtype = error;
    71  
    72  	skb_event_output(skb, &EVENTS_MAP,
    73  			 (cap_len << 32) | BPF_F_CURRENT_CPU,
    74  			 &msg, sizeof(msg));
    75  
    76  	return skb->cb[4];
    77  }
    78  
    79  /**
    80   * send_drop_notify
    81   * @skb:	socket buffer
    82   * @src:	source identity
    83   * @dst:	destination identity
    84   * @dst_id:	designated destination endpoint ID
    85   * @reason:	Reason for drop
    86   * @exitcode:	error code to return to the kernel
    87   *
    88   * Generate a notification to indicate a packet was dropped.
    89   *
    90   * NOTE: This is terminal function and will cause the BPF program to exit
    91   */
    92  static inline int send_drop_notify(struct __sk_buff *skb, __u32 src, __u32 dst,
    93  				   __u32 dst_id, int reason, int exitcode, __u8 direction)
    94  {
    95  	skb->cb[0] = src;
    96  	skb->cb[1] = dst;
    97  	skb->cb[2] = reason;
    98  	skb->cb[3] = dst_id;
    99  	skb->cb[4] = exitcode;
   100  
   101  	update_metrics(skb->len, direction, -reason);
   102  
   103  	ep_tail_call(skb, CILIUM_CALL_DROP_NOTIFY);
   104  
   105  	return exitcode;
   106  }
   107  
   108  #else
   109  
   110  static inline int send_drop_notify(struct __sk_buff *skb, __u32 src, __u32 dst,
   111  				   __u32 dst_id, int reason, int exitcode, __u8 direction)
   112  {
   113  	update_metrics(skb->len, direction, -reason);
   114  	return exitcode;
   115  }
   116  
   117  #endif
   118  
   119  static inline int send_drop_notify_error(struct __sk_buff *skb, __u32 src, int error,
   120                                           int exitcode, __u8 direction)
   121  {
   122  	return send_drop_notify(skb, src, 0, 0, error, exitcode, direction);
   123  }
   124  
   125  #endif /* __LIB_DROP__ */