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