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 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 14 static inline __u64 ptr_to_u64(const void *ptr) 15 { 16 return (__u64) (unsigned long) ptr; 17 } 18 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 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