1 /* Copyright (c) 2016 PLUMgrid
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of version 2 of the GNU General Public
5 * License as published by the Free Software Foundation.
7 #define KBUILD_MODNAME "foo"
8 #include <uapi/linux/bpf.h>
10 #include <linux/if_ether.h>
11 #include <linux/if_packet.h>
12 #include <linux/if_vlan.h>
14 #include <linux/ipv6.h>
15 #include "bpf_helpers.h"
17 struct bpf_map_def
SEC("maps") rxcnt
= {
18 .type
= BPF_MAP_TYPE_PERCPU_ARRAY
,
19 .key_size
= sizeof(u32
),
20 .value_size
= sizeof(long),
24 static int parse_ipv4(void *data
, u64 nh_off
, void *data_end
)
26 struct iphdr
*iph
= data
+ nh_off
;
28 if (iph
+ 1 > data_end
)
33 static int parse_ipv6(void *data
, u64 nh_off
, void *data_end
)
35 struct ipv6hdr
*ip6h
= data
+ nh_off
;
37 if (ip6h
+ 1 > data_end
)
43 int xdp_prog1(struct xdp_md
*ctx
)
45 void *data_end
= (void *)(long)ctx
->data_end
;
46 void *data
= (void *)(long)ctx
->data
;
47 struct ethhdr
*eth
= data
;
54 nh_off
= sizeof(*eth
);
55 if (data
+ nh_off
> data_end
)
58 h_proto
= eth
->h_proto
;
60 if (h_proto
== htons(ETH_P_8021Q
) || h_proto
== htons(ETH_P_8021AD
)) {
61 struct vlan_hdr
*vhdr
;
64 nh_off
+= sizeof(struct vlan_hdr
);
65 if (data
+ nh_off
> data_end
)
67 h_proto
= vhdr
->h_vlan_encapsulated_proto
;
69 if (h_proto
== htons(ETH_P_8021Q
) || h_proto
== htons(ETH_P_8021AD
)) {
70 struct vlan_hdr
*vhdr
;
73 nh_off
+= sizeof(struct vlan_hdr
);
74 if (data
+ nh_off
> data_end
)
76 h_proto
= vhdr
->h_vlan_encapsulated_proto
;
79 if (h_proto
== htons(ETH_P_IP
))
80 ipproto
= parse_ipv4(data
, nh_off
, data_end
);
81 else if (h_proto
== htons(ETH_P_IPV6
))
82 ipproto
= parse_ipv6(data
, nh_off
, data_end
);
86 value
= bpf_map_lookup_elem(&rxcnt
, &ipproto
);
93 char _license
[] SEC("license") = "GPL";