void bpf2_jit_free(struct bpf_program *prog) { if (prog->jit_image) { INIT_WORK(&prog->work, bpf2_jit_free_deferred); schedule_work(&prog->work); } else { free_bpf_program(prog); } }
static void bpf2_jit_free_deferred(struct work_struct *work) { struct bpf_program *prog = container_of(work, struct bpf_program, work); unsigned long addr = (unsigned long)prog->jit_image & PAGE_MASK; struct bpf_binary_header *header = (void *)addr; set_memory_rw(addr, header->pages); module_free(NULL, header); free_bpf_program(prog); }
int dial(char *eth, int bufcnt) // get us a raw connection to an interface { int i, n, s; struct sockaddr_ll sa; enum { aoe_type = 0x88a2 }; memset(&sa, 0, sizeof sa); s = socket(PF_PACKET, SOCK_RAW, htons(aoe_type)); if (s == -1) { perror("got bad socket"); return -1; } i = getindx(s, eth); sa.sll_family = AF_PACKET; sa.sll_protocol = htons(0x88a2); sa.sll_ifindex = i; n = bind(s, (struct sockaddr *)&sa, sizeof sa); if (n == -1) { perror("bind funky"); return -1; } struct bpf_program { ulong bf_len; void *bf_insns; } *bpf_program = create_bpf_program(shelf, slot); setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, bpf_program, sizeof(*bpf_program)); free_bpf_program(bpf_program); n = bufcnt * getmtu(s, eth); if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &n, sizeof(n)) < 0) perror("setsockopt SOL_SOCKET, SO_SNDBUF"); if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)) < 0) perror("setsockopt SOL_SOCKET, SO_RCVBUF"); return s; }
int dial(char *eth, int bufcnt) { char m; int fd = -1; struct bpf_version bv; u_int v; unsigned bufsize, linktype; char device[sizeof BPF_DEV]; struct ifreq ifr; struct bpf_program *bpf_program = create_bpf_program(shelf, slot); strncpy(device, BPF_DEV, sizeof BPF_DEV); /* find a bpf device we can use, check /dev/bpf[0-9] */ for (m = '0'; m <= '9'; m++) { device[sizeof(BPF_DEV)-2] = m; if ((fd = open(device, O_RDWR)) > 0) break; } if (fd < 0) { perror("open"); return -1; } if (ioctl(fd, BIOCVERSION, &bv) < 0) { perror("BIOCVERSION"); goto bad; } if (bv.bv_major != BPF_MAJOR_VERSION || bv.bv_minor < BPF_MINOR_VERSION) { fprintf(stderr, "kernel bpf filter out of date\n"); goto bad; } /* * Try finding a good size for the buffer; 65536 may be too * big, so keep cutting it in half until we find a size * that works, or run out of sizes to try. * */ for (v = 65536; v != 0; v >>= 1) { (void) ioctl(fd, BIOCSBLEN, (caddr_t)&v); (void)strncpy(ifr.ifr_name, eth, sizeof(ifr.ifr_name)); if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0) break; /* that size worked; we're done */ if (errno != ENOBUFS) { fprintf(stderr, "BIOCSETIF: %s: %s\n", eth, strerror(errno)); goto bad; } } if (v == 0) { fprintf(stderr, "BIOCSBLEN: %s: No buffer size worked\n", eth); goto bad; } /* Allocate memory for the packet buffer */ pktbufsz = v; if ((pktbuf = malloc(pktbufsz)) == NULL) { perror("malloc"); goto bad; } /* Don't wait for buffer to be full or timeout */ v = 1; if (ioctl(fd, BIOCIMMEDIATE, &v) < 0) { perror("BIOCIMMEDIATE"); goto bad; } /* Only read incoming packets */ v = 0; if (ioctl(fd, BIOCSSEESENT, &v) < 0) { perror("BIOCSSEESENT"); goto bad; } /* Don't complete ethernet hdr */ v = 1; if (ioctl(fd, BIOCSHDRCMPLT, &v) < 0) { perror("BIOCSHDRCMPLT"); goto bad; } /* Get the data link layer type. */ if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) { perror("BIOCGDLT"); goto bad; } linktype = v; /* Get the filter buf size */ if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) { perror("BIOCGBLEN"); goto bad; } bufsize = v; if (ioctl(fd, BIOCSETF, (caddr_t)bpf_program) < 0) { perror("BIOSETF"); goto bad; } free_bpf_program(bpf_program); return(fd); bad: free_bpf_program(bpf_program); close(fd); return(-1); }