2015-03-25 22:49:24 +03:00
/* Copyright (c) 2013-2015 PLUMgrid, http://plumgrid.com
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation .
*/
# include <linux/skbuff.h>
# include <linux/netdevice.h>
# include <linux/version.h>
# include <uapi/linux/bpf.h>
# include "bpf_helpers.h"
struct bpf_map_def SEC ( " maps " ) my_map = {
. type = BPF_MAP_TYPE_HASH ,
. key_size = sizeof ( long ) ,
. value_size = sizeof ( long ) ,
. max_entries = 1024 ,
} ;
/* kprobe is NOT a stable ABI. If kernel internals change this bpf+kprobe
* example will no longer be meaningful
*/
SEC ( " kprobe/kfree_skb " )
int bpf_prog2 ( struct pt_regs * ctx )
{
long loc = 0 ;
long init_val = 1 ;
long * value ;
2016-04-04 20:01:34 +03:00
/* read ip of kfree_skb caller.
2015-03-25 22:49:24 +03:00
* non - portable version of __builtin_return_address ( 0 )
*/
2016-04-04 20:01:34 +03:00
BPF_KPROBE_READ_RET_IP ( loc , ctx ) ;
2015-03-25 22:49:24 +03:00
value = bpf_map_lookup_elem ( & my_map , & loc ) ;
if ( value )
* value + = 1 ;
else
bpf_map_update_elem ( & my_map , & loc , & init_val , BPF_ANY ) ;
return 0 ;
}
static unsigned int log2 ( unsigned int v )
{
unsigned int r ;
unsigned int shift ;
r = ( v > 0xFFFF ) < < 4 ; v > > = r ;
shift = ( v > 0xFF ) < < 3 ; v > > = shift ; r | = shift ;
shift = ( v > 0xF ) < < 2 ; v > > = shift ; r | = shift ;
shift = ( v > 0x3 ) < < 1 ; v > > = shift ; r | = shift ;
r | = ( v > > 1 ) ;
return r ;
}
static unsigned int log2l ( unsigned long v )
{
unsigned int hi = v > > 32 ;
if ( hi )
return log2 ( hi ) + 32 ;
else
return log2 ( v ) ;
}
2015-06-13 05:39:12 +03:00
struct hist_key {
char comm [ 16 ] ;
u64 pid_tgid ;
u64 uid_gid ;
2016-04-13 01:10:53 +03:00
u64 index ;
2015-06-13 05:39:12 +03:00
} ;
2015-03-25 22:49:24 +03:00
struct bpf_map_def SEC ( " maps " ) my_hist_map = {
2016-02-02 09:39:58 +03:00
. type = BPF_MAP_TYPE_PERCPU_HASH ,
2015-06-13 05:39:12 +03:00
. key_size = sizeof ( struct hist_key ) ,
2015-03-25 22:49:24 +03:00
. value_size = sizeof ( long ) ,
2015-06-13 05:39:12 +03:00
. max_entries = 1024 ,
2015-03-25 22:49:24 +03:00
} ;
SEC ( " kprobe/sys_write " )
int bpf_prog3 ( struct pt_regs * ctx )
{
2015-07-06 17:20:07 +03:00
long write_size = PT_REGS_PARM3 ( ctx ) ;
2015-03-25 22:49:24 +03:00
long init_val = 1 ;
long * value ;
2016-04-13 01:10:53 +03:00
struct hist_key key ;
2015-06-13 05:39:12 +03:00
key . index = log2l ( write_size ) ;
key . pid_tgid = bpf_get_current_pid_tgid ( ) ;
key . uid_gid = bpf_get_current_uid_gid ( ) ;
bpf_get_current_comm ( & key . comm , sizeof ( key . comm ) ) ;
2015-03-25 22:49:24 +03:00
2015-06-13 05:39:12 +03:00
value = bpf_map_lookup_elem ( & my_hist_map , & key ) ;
2015-03-25 22:49:24 +03:00
if ( value )
__sync_fetch_and_add ( value , 1 ) ;
2015-06-13 05:39:12 +03:00
else
bpf_map_update_elem ( & my_hist_map , & key , & init_val , BPF_ANY ) ;
2015-03-25 22:49:24 +03:00
return 0 ;
}
char _license [ ] SEC ( " license " ) = " GPL " ;
u32 _version SEC ( " version " ) = LINUX_VERSION_CODE ;