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__ */