xref: /linux-tools/ebpf/kernel-samples-bpf/ipfirewall_cmd.c (revision 7889a9fe3f6cd23238c94fad4e1c698d5585c3fe)
1*7889a9feSDavid Wang #include <stdio.h>
2*7889a9feSDavid Wang #include <string.h>
3*7889a9feSDavid Wang #include <linux/bpf.h>
4*7889a9feSDavid Wang #include <unistd.h>
5*7889a9feSDavid Wang #include <asm/unistd.h>
6*7889a9feSDavid Wang 
sys_bpf(enum bpf_cmd cmd,union bpf_attr * attr,unsigned int size)7*7889a9feSDavid Wang static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr, unsigned int size)
8*7889a9feSDavid Wang {
9*7889a9feSDavid Wang 	return syscall(__NR_bpf, cmd, attr, size);
10*7889a9feSDavid Wang }
11*7889a9feSDavid Wang 
ptr_to_u64(const void * ptr)12*7889a9feSDavid Wang static inline __u64 ptr_to_u64(const void *ptr)
13*7889a9feSDavid Wang {
14*7889a9feSDavid Wang 	return (__u64) (unsigned long) ptr;
15*7889a9feSDavid Wang }
16*7889a9feSDavid Wang 
parse(char * p)17*7889a9feSDavid Wang unsigned int parse(char *p) {
18*7889a9feSDavid Wang     int k, i=0, b;
19*7889a9feSDavid Wang     unsigned int ip=0, mk=0xffffffff;
20*7889a9feSDavid Wang     for (k=0; k<4; k++) {
21*7889a9feSDavid Wang         b=0;
22*7889a9feSDavid Wang         if (p[i]<'0'||p[i]>'9') return 0;
23*7889a9feSDavid Wang         while(p[i]>='0'&&p[i]<='9') {
24*7889a9feSDavid Wang             b=b*10+p[i++]-'0';
25*7889a9feSDavid Wang             if (b>256) return 0;
26*7889a9feSDavid Wang         }
27*7889a9feSDavid Wang         if (k<3&&p[i]!='.') return 0;
28*7889a9feSDavid Wang         if (k==3&&p[i]!=0&&p[i]!='/') return 0;
29*7889a9feSDavid Wang         ip = (ip<<8) | b;
30*7889a9feSDavid Wang         if (k==3) break;
31*7889a9feSDavid Wang         i++;
32*7889a9feSDavid Wang     }
33*7889a9feSDavid Wang     if (p[i]==0) mk=0xffffffff;
34*7889a9feSDavid Wang     else if (p[i]=='/') {
35*7889a9feSDavid Wang         i++; b=0;
36*7889a9feSDavid Wang         while(p[i]>='0'&&p[i]<='9') {
37*7889a9feSDavid Wang             b=b*10+p[i++]-'0';
38*7889a9feSDavid Wang             if (b>32) return 0;
39*7889a9feSDavid Wang         }
40*7889a9feSDavid Wang         if (p[i]!=0||b>32||b<1) return 0;
41*7889a9feSDavid Wang         b=32-b;
42*7889a9feSDavid Wang         mk>>=b; mk<<=b;
43*7889a9feSDavid Wang     } else return 0;
44*7889a9feSDavid Wang     return ip&mk;
45*7889a9feSDavid Wang }
46*7889a9feSDavid Wang 
main(int argc,char * argv[])47*7889a9feSDavid Wang int main(int argc, char *argv[]) {
48*7889a9feSDavid Wang     unsigned int ip, value;
49*7889a9feSDavid Wang     union bpf_attr attr_pin, attr_elem;
50*7889a9feSDavid Wang     int fd, rc;
51*7889a9feSDavid Wang     memset(&attr_pin, 0, sizeof(attr_pin));
52*7889a9feSDavid Wang     memset(&attr_elem, 0, sizeof(attr_elem));
53*7889a9feSDavid Wang     attr_pin.pathname = ptr_to_u64("/sys/fs/bpf/rules");
54*7889a9feSDavid Wang     fd = sys_bpf(BPF_OBJ_GET, &attr_pin, sizeof(attr_pin));
55*7889a9feSDavid Wang     if (fd<0) {
56*7889a9feSDavid Wang         printf("bpf map /sys/fs/bpf/rules not exist yet, need to start bpf prog first\n");
57*7889a9feSDavid Wang         return 1;
58*7889a9feSDavid Wang     }
59*7889a9feSDavid Wang     attr_elem.map_fd = fd;
60*7889a9feSDavid Wang     attr_elem.key = ptr_to_u64(&ip);
61*7889a9feSDavid Wang     attr_elem.value = ptr_to_u64(&value);
62*7889a9feSDavid Wang     if (argc != 3) {
63*7889a9feSDavid Wang         printf("usage: %s [allow/block] [ipnetwork]\n", argv[0]);
64*7889a9feSDavid Wang         return 1;
65*7889a9feSDavid Wang     }
66*7889a9feSDavid Wang     if (strcmp(argv[1], "allow")==0) {
67*7889a9feSDavid Wang         ip = parse(argv[2]);
68*7889a9feSDavid Wang         printf("allow ip %x\n", ip);
69*7889a9feSDavid Wang         if (ip==0) {
70*7889a9feSDavid Wang             printf("ip network %s not valid\n", argv[2]);
71*7889a9feSDavid Wang             return 1;
72*7889a9feSDavid Wang         }
73*7889a9feSDavid Wang         value=0;
74*7889a9feSDavid Wang         rc = sys_bpf(BPF_MAP_UPDATE_ELEM, &attr_elem, sizeof(attr_elem));
75*7889a9feSDavid Wang         if (rc<0) {
76*7889a9feSDavid Wang             printf("fail to register the firewall rule\n");
77*7889a9feSDavid Wang             return 1;
78*7889a9feSDavid Wang         }
79*7889a9feSDavid Wang     } else if (strcmp(argv[1], "block")==0) {
80*7889a9feSDavid Wang         ip = parse(argv[2]);
81*7889a9feSDavid Wang         printf("block ip %x\n", ip);
82*7889a9feSDavid Wang         if (ip==0) {
83*7889a9feSDavid Wang             printf("ip network %s not valid\n", argv[2]);
84*7889a9feSDavid Wang             return 1;
85*7889a9feSDavid Wang         }
86*7889a9feSDavid Wang         value=1;
87*7889a9feSDavid Wang         rc = sys_bpf(BPF_MAP_UPDATE_ELEM, &attr_elem, sizeof(attr_elem));
88*7889a9feSDavid Wang         if (rc<0) {
89*7889a9feSDavid Wang             printf("fail to register the firewall rule\n");
90*7889a9feSDavid Wang             return 1;
91*7889a9feSDavid Wang         }
92*7889a9feSDavid Wang     } else {
93*7889a9feSDavid Wang         printf("usage: %s [allow/block] [ipnetwork]\n", argv[0]);
94*7889a9feSDavid Wang         return 1;
95*7889a9feSDavid Wang     }
96*7889a9feSDavid Wang }
97