bpf/accesslog/l24/write_l3.c (113 lines of code) (raw):

// Licensed to Apache Software Foundation (ASF) under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Apache Software Foundation (ASF) licenses this file to you under // the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. #include "l24.h" #include "../common/data_args.h" SEC("kprobe/__ip_queue_xmit") int ip_queue_xmit(struct pt_regs * ctx){ __u64 id = bpf_get_current_pid_tgid(); struct sock_data_args_t *data_args = bpf_map_lookup_elem(&socket_data_args, &id); if (data_args != NULL) { struct sk_buff * skb = (struct sk_buff *)PT_REGS_PARM2(ctx); // update current transmit skb data_args->buffer = skb; // adding skb detail into map(for getting all l2-3 detail from skb) struct skb_transmit_detail detail = {}; detail.l3_enter_time = bpf_ktime_get_ns(); bpf_map_update_elem(&sk_buff_transmit_detail_map, &skb, &detail, 0); } return 0; } SEC("kretprobe/__ip_queue_xmit") int ip_queue_xmit_ret(struct pt_regs * ctx){ __u64 id = bpf_get_current_pid_tgid(); // getting skb struct sock_data_args_t *data_args = bpf_map_lookup_elem(&socket_data_args, &id); if (data_args == NULL) { return 0; } // getting all l2-3 detail struct skb_transmit_detail *detail = bpf_map_lookup_elem(&sk_buff_transmit_detail_map, &data_args->buffer); if (detail == NULL) { return 0; } data_args->l3_duration += bpf_ktime_get_ns() - detail->l3_enter_time; if (detail->l3_output_time > 0 && detail->l3_local_time > 0) { data_args->l3_local_duration += detail->l3_output_time - detail->l3_local_time; } if (detail->l3_finish_time > 0 && detail->l3_output_time > 0) { data_args->l3_output_duration += detail->l3_finish_time - detail->l3_output_time; } data_args->total_resolve_mac_count = detail->total_resolve_neigh_count; data_args->total_resolve_mac_time = detail->total_resolve_neigh_time; data_args->total_net_filter_count = detail->total_nf_count; data_args->total_net_filter_time = detail->total_nf_time; if (detail->l2_enter_time > 0 && detail->l2_exit_time > 0) { data_args->l2_duration = detail->l2_exit_time - detail->l2_enter_time; data_args->l2_enter_queue_count++; } data_args->ifindex = _(detail->ifindex); if (detail->l2_enter_time > 0) { data_args->l2_enter_queue_package_count++; } if (detail->l2_start_xmit_time > 0 && detail->l2_enter_time > 0) { data_args->l2_ready_send_duration += detail->l2_start_xmit_time - detail->l2_enter_time; } if (detail->l2_finish_xmit_time > 0 && detail->l2_start_xmit_time > 0) { data_args->l2_send_duration += detail->l2_finish_xmit_time - detail->l2_start_xmit_time; } return 0; } SEC("kprobe/ip_local_out") int ip_local(struct pt_regs * ctx){ struct sk_buff * skb = (struct sk_buff *)PT_REGS_PARM3(ctx); struct skb_transmit_detail *detail = bpf_map_lookup_elem(&sk_buff_transmit_detail_map, &skb); if (detail != NULL) { detail->l3_local_time = bpf_ktime_get_ns(); } return 0; } struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 10000); __type(key, __u64); __type(value, struct sk_buff *); } ip_output_temp SEC(".maps"); SEC("kprobe/ip_output") int ip_output(struct pt_regs * ctx){ struct sk_buff * skb = (struct sk_buff *)PT_REGS_PARM3(ctx); struct skb_transmit_detail *detail = bpf_map_lookup_elem(&sk_buff_transmit_detail_map, &skb); if (detail != NULL) { detail->l3_output_time = bpf_ktime_get_ns(); } return 0; } SEC("kprobe/ip_finish_output2") int ip_finish_output2(struct pt_regs * ctx){ struct sk_buff * skb = (struct sk_buff *)PT_REGS_PARM3(ctx); struct skb_transmit_detail *detail = bpf_map_lookup_elem(&sk_buff_transmit_detail_map, &skb); if (detail != NULL) { long unsigned int _skb_refdst; bpf_probe_read(&_skb_refdst, sizeof(_skb_refdst), &skb->_skb_refdst); struct dst_entry *entry = (void *)(_skb_refdst & SKB_DST_PTRMASK); struct net_device *device; bpf_probe_read(&device, sizeof(device), &entry->dev); int ifindex; bpf_probe_read(&ifindex, sizeof(ifindex), &device->ifindex); detail->ifindex = ifindex; detail->l3_finish_time = bpf_ktime_get_ns(); } return 0; } SEC("kprobe/neigh_resolve_output") int neigh_resolve_output(struct pt_regs * ctx){ struct sk_buff * skb = (struct sk_buff *)PT_REGS_PARM2(ctx); struct skb_transmit_detail *detail = bpf_map_lookup_elem(&sk_buff_transmit_detail_map, &skb); if (detail != NULL) { detail->enter_resolve_neigh_time = bpf_ktime_get_ns(); save_l24_tmp_args(L24_TEMP_ARGS_NEIGHT_RESOLVE_OUTPUT, skb); } return 0; } SEC("kretprobe/neigh_resolve_output") int neigh_resolve_output_ret(struct pt_regs * ctx){ struct skb_transmit_detail *detail = get_l24_transmit_tmp_args(L24_TEMP_ARGS_NEIGHT_RESOLVE_OUTPUT); if (detail != NULL) { detail->total_resolve_neigh_count++; detail->total_resolve_neigh_time = bpf_ktime_get_ns() - detail->enter_resolve_neigh_time; } return 0; }