int br_read_fdb(const char *bridge, struct fdb_entry *fdbs, unsigned long offset, int num) { int i, fd = -1, n; struct __fdb_entry fe[num]; #ifdef HAVE_LIBSYSFS struct sysfs_class_device *dev; /* open /sys/class/net/brXXX/brforward */ if (br_class_net && (dev = sysfs_get_class_device(br_class_net, (char *) bridge))) { char path[SYSFS_PATH_MAX]; snprintf(path, SYSFS_PATH_MAX, "%s/%s", dev->path, SYSFS_BRIDGE_FDB); fd = open(path, O_RDONLY, 0); } if (fd != -1) { /* read records from file */ lseek(fd, offset*sizeof(struct __fdb_entry), SEEK_SET); n = read(fd, fe, num*sizeof(struct __fdb_entry)); if (n > 0) n /= sizeof(struct __fdb_entry); } else #endif { /* old kernel, use ioctl */ unsigned long args[4] = { BRCTL_GET_FDB_ENTRIES, (unsigned long) fe, num, offset }; struct ifreq ifr; int retries = 0; strncpy(ifr.ifr_name, bridge, IFNAMSIZ); ifr.ifr_data = (char *) args; retry: n = ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr); /* table can change during ioctl processing */ if (n < 0 && errno == EAGAIN && ++retries < 10) { sleep(0); goto retry; } } for (i = 0; i < n; i++) __copy_fdb(fdbs+i, fe+i); if (fd > 0) close(fd); return n; }
int br_read_fdb(struct bridge *br, struct fdb_entry *fdbs, int offset, int num) { struct __fdb_entry f[num]; int i; int numread; if ((numread = br_device_ioctl(br, BRCTL_GET_FDB_ENTRIES, (unsigned long)f, num, offset)) < 0) return errno; for (i=0;i<numread;i++) __copy_fdb(fdbs+i, f+i); return numread; }
int br_read_fdb(const char *bridge, struct fdb_entry *fdbs, unsigned long offset, int num) { FILE *f; int i, n; struct __fdb_entry fe[num]; char path[SYSFS_PATH_MAX]; /* open /sys/class/net/brXXX/brforward */ snprintf(path, SYSFS_PATH_MAX, SYSFS_CLASS_NET "%s/brforward", bridge); f = fopen(path, "r"); if (f) { fseek(f, offset*sizeof(struct __fdb_entry), SEEK_SET); n = fread(fe, sizeof(struct __fdb_entry), num, f); fclose(f); } else { /* old kernel, use ioctl */ unsigned long args[4] = { BRCTL_GET_FDB_ENTRIES, (unsigned long) fe, num, offset }; struct ifreq ifr; int retries = 0; strncpy(ifr.ifr_name, bridge, IFNAMSIZ); ifr.ifr_data = (char *) args; retry: n = ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr); /* table can change during ioctl processing */ if (n < 0 && errno == EAGAIN && ++retries < 10) { sleep(0); goto retry; } } for (i = 0; i < n; i++) __copy_fdb(fdbs+i, fe+i); return n; }
int br_read_fdb(struct bridge *br, struct fdb_entry *fdbs, int offset, int num) { struct __fdb_entry f[num]; int i; int numread; again: numread = br_device_ioctl(br, BRCTL_GET_FDB_ENTRIES, (unsigned long)f, num, offset); if (numread < 0) { if (errno == EAGAIN) goto again; return -errno; } for (i=0;i<numread;i++) __copy_fdb(fdbs+i, f+i); return numread; }