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