aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshemminger <shemminger>2004-06-04 18:03:40 +0000
committershemminger <shemminger>2004-06-04 18:03:40 +0000
commita7a262260da372c42850f7ce01a070275711c60d (patch)
tree80fc054fb772cdf309b90f0f0515a9e4e7387d61
parent946695beaac41b6b50a5e641bbfd292f85e5a163 (diff)
downloadandroid_external_brctl-a7a262260da372c42850f7ce01a070275711c60d.tar.gz
android_external_brctl-a7a262260da372c42850f7ce01a070275711c60d.tar.bz2
android_external_brctl-a7a262260da372c42850f7ce01a070275711c60d.zip
Get rid of all visible signs of port number and ifindex
from API, and display output. Fix foreach_port for case when /sys is missing (but compiled for sysfs).
-rw-r--r--brctl/brctl_cmd.c22
-rw-r--r--brctl/brctl_disp.c8
-rw-r--r--libbridge/libbridge.h11
-rw-r--r--libbridge/libbridge_devif.c172
-rw-r--r--libbridge/libbridge_if.c50
-rw-r--r--libbridge/libbridge_init.c64
6 files changed, 161 insertions, 166 deletions
diff --git a/brctl/brctl_cmd.c b/brctl/brctl_cmd.c
index f9da974..9ab7166 100644
--- a/brctl/brctl_cmd.c
+++ b/brctl/brctl_cmd.c
@@ -82,16 +82,13 @@ static int br_cmd_delbr(char** argv)
static int br_cmd_addif(char** argv)
{
int err;
- int ifindex = if_nametoindex(argv[2]);
- if (!ifindex) {
- fprintf(stderr, "interface %s does not exist!\n", argv[2]);
- return 1;
- }
-
- switch (err = br_add_interface(argv[1], ifindex)) {
+ switch (err = br_add_interface(argv[1], argv[2])) {
case 0:
return 0;
+ case ENODEV:
+ fprintf(stderr, "interface %s does not exist!\n", argv[2]);
+ return 1;
case EBUSY:
fprintf(stderr, "device %s is already a member of a bridge; "
@@ -115,16 +112,13 @@ static int br_cmd_addif(char** argv)
static int br_cmd_delif(char** argv)
{
int err;
- int ifindex = if_nametoindex(argv[2]);
- if (!ifindex) {
- fprintf(stderr, "interface %s does not exist!\n", argv[2]);
- return 1;
- }
-
- switch (err = br_del_interface(argv[1], ifindex)) {
+ switch (err = br_del_interface(argv[1], argv[2])) {
case 0:
return 0;
+ case ENODEV:
+ fprintf(stderr, "interface %s does not exist!\n", argv[2]);
+ return 1;
case EINVAL:
fprintf(stderr, "device %s is not a slave of %s\n",
diff --git a/brctl/brctl_disp.c b/brctl/brctl_disp.c
index a1f4aa3..acdc687 100644
--- a/brctl/brctl_disp.c
+++ b/brctl/brctl_disp.c
@@ -37,7 +37,7 @@ void br_show_timer(const struct timeval *tv)
static int first;
-static int dump_interface(const char *b, const char *p, int ind, void *arg)
+static int dump_interface(const char *b, const char *p, void *arg)
{
if (first)
@@ -62,12 +62,12 @@ void br_dump_interface_list(const char *br)
printf("\n");
}
-static int dump_port_info(const char *br, const char *p, int count, void *arg)
+static int dump_port_info(const char *br, const char *p, void *arg)
{
struct port_info pinfo;
- printf("%s (%i)", p, count);
- if (br_get_port_info(br, p, count, &pinfo)) {
+ printf("%s", p);
+ if (br_get_port_info(br, p, &pinfo)) {
printf("\tcan't get port info\n");
return 1;
}
diff --git a/libbridge/libbridge.h b/libbridge/libbridge.h
index 1be50b0..a8ff2c2 100644
--- a/libbridge/libbridge.h
+++ b/libbridge/libbridge.h
@@ -82,19 +82,18 @@ extern void br_shutdown(void);
extern int br_foreach_bridge(int (*iterator)(const char *brname, void *),
void *arg);
extern int br_foreach_port(const char *brname,
- int (*iterator)(const char *brname,
- const char *port, int ifindex,
- void *),
+ int (*iterator)(const char *brname, const char *port,
+ void *arg ),
void *arg);
extern const char *br_get_state_name(int state);
extern int br_get_bridge_info(const char *br, struct bridge_info *info);
-extern int br_get_port_info(const char *brname, const char *port, int count,
+extern int br_get_port_info(const char *brname, const char *port,
struct port_info *info);
extern int br_add_bridge(const char *brname);
extern int br_del_bridge(const char *brname);
-extern int br_add_interface(const char *br, int ifindex);
-extern int br_del_interface(const char *br, int ifindex);
+extern int br_add_interface(const char *br, const char *dev);
+extern int br_del_interface(const char *br, const char *dev);
extern int br_set_bridge_forward_delay(const char *br, struct timeval *tv);
extern int br_set_bridge_hello_time(const char *br, struct timeval *tv);
extern int br_set_bridge_max_age(const char *br, struct timeval *tv);
diff --git a/libbridge/libbridge_devif.c b/libbridge/libbridge_devif.c
index 018f9ce..0ca355d 100644
--- a/libbridge/libbridge_devif.c
+++ b/libbridge/libbridge_devif.c
@@ -70,16 +70,13 @@ static void fetch_id(struct sysfs_directory *sdir, const char *name,
memset(id, 0, sizeof(id));
attr = sysfs_get_directory_attribute(sdir, (char *) name);
- dprintf("fetch_id %s/%s = %s\n", sdir->path, name,
- attr ? attr->value : "<null>\n");
-
if (!attr) {
- fprintf(stderr, "Can't find attribute %s/%s\n", sdir->path, name);
+ dprintf("Can't find attribute %s/%s\n", sdir->path, name);
return;
}
if (strlen(attr->value) < 17)
- fprintf(stderr, "Bad format for %s: '%s'\n", name, attr->value);
+ dprintf("Bad format for %s: '%s'\n", name, attr->value);
else {
const char *cp = attr->value;
id->prio[0] = getoctet(cp); cp += 2;
@@ -101,7 +98,7 @@ static void fetch_tv(struct sysfs_directory *sdir, const char *name,
= sysfs_get_directory_attribute(sdir, (char *) name);
if (!attr) {
- fprintf(stderr, "Can't find attribute %s/%s\n", sdir->path, name);
+ dprintf("Can't find attribute %s/%s\n", sdir->path, name);
memset(tv, 0, sizeof(tv));
return;
}
@@ -117,13 +114,51 @@ static int fetch_int(struct sysfs_directory *sdir, const char *name)
int val = 0;
if (!attr)
- fprintf(stderr, "Can't find attribute %s/%s\n", sdir->path, name);
+ dprintf("Can't find attribute %s/%s\n", sdir->path, name);
else
val = strtol(attr->value, NULL, 0);
return val;
}
#endif
+/*
+ * Convert device name to an index in the list of ports in bridge.
+ *
+ * Old API does bridge operations as if ports were an array
+ * inside bridge structure.
+ */
+static int get_portno(const char *brname, const char *ifname)
+{
+ int i;
+ int ifindex = if_nametoindex(ifname);
+ int ifindices[MAX_PORTS];
+ unsigned long args[4] = { BRCTL_GET_PORT_LIST,
+ (unsigned long)ifindices, MAX_PORTS, 0 };
+ struct ifreq ifr;
+
+ if (ifindex <= 0)
+ goto error;
+
+ memset(ifindices, 0, sizeof(ifindices));
+ strncpy(ifr.ifr_name, brname, IFNAMSIZ);
+ ifr.ifr_data = (char *) &args;
+
+ if (ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr) < 0) {
+ dprintf("get_portno: get ports of %s failed: %s\n",
+ brname, strerror(errno));
+ goto error;
+ }
+
+ for (i = 0; i < MAX_PORTS; i++) {
+ if (ifindices[i] == ifindex)
+ return i;
+ }
+
+ dprintf("%s is not a in bridge %s\n", ifname, brname);
+ error:
+ return -1;
+}
+
/* get information via ioctl */
static int old_get_bridge_info(const char *bridge, struct bridge_info *info)
{
@@ -207,22 +242,31 @@ int br_get_bridge_info(const char *bridge, struct bridge_info *info)
#endif
}
-static int old_get_port_info(const char *brname, int index,
+static int old_get_port_info(const char *brname, const char *port,
struct port_info *info)
{
struct __port_info i;
- struct ifreq ifr;
- unsigned long args[4] = { BRCTL_GET_PORT_INFO,
- (unsigned long) &i, index, 0 };
+ int index;
memset(info, 0, sizeof(*info));
- strncpy(ifr.ifr_name, brname, IFNAMSIZ);
- ifr.ifr_data = (char *) &args;
- if (ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr) < 0) {
- dprintf("old can't get port %s(%d) info %s\n",
- brname, index, strerror(errno));
+ index = get_portno(brname, port);
+ if (index < 0)
return errno;
+
+ else {
+ struct ifreq ifr;
+ unsigned long args[4] = { BRCTL_GET_PORT_INFO,
+ (unsigned long) &i, index, 0 };
+
+ strncpy(ifr.ifr_name, brname, IFNAMSIZ);
+ ifr.ifr_data = (char *) &args;
+
+ if (ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr) < 0) {
+ dprintf("old can't get port %s(%d) info %s\n",
+ brname, index, strerror(errno));
+ return errno;
+ }
}
memcpy(&info->designated_root, &i.designated_root, 8);
@@ -245,16 +289,17 @@ static int old_get_port_info(const char *brname, int index,
/*
* Get information about port on bridge.
*/
-int br_get_port_info(const char *brname, const char *port, int index,
+int br_get_port_info(const char *brname, const char *port,
struct port_info *info)
{
#ifndef HAVE_LIBSYSFS
- return old_get_port_info(brname, index, info);
+ return old_get_port_info(brname, port, info);
#else
struct sysfs_directory *sdir
= bridge_sysfs_directory(port, SYSFS_BRIDGE_PORT_ATTR);
+
if (!sdir)
- return old_get_port_info(brname, index, info);
+ return old_get_port_info(brname, port, info);
memset(info, 0, sizeof(*info));
fetch_id(sdir, "designated_root", &info->designated_root);
@@ -278,47 +323,6 @@ int br_get_port_info(const char *brname, const char *port, int index,
#endif
}
-int br_add_interface(const char *bridge, int ifindex)
-{
- struct ifreq ifr;
- int err;
-
- strncpy(ifr.ifr_name, bridge, IFNAMSIZ);
-#ifdef SIOCBRADDIF
- ifr.ifr_ifindex = ifindex;
- err = ioctl(br_socket_fd, SIOCBRADDIF, &ifr);
- if (err < 0)
-#endif
- {
- unsigned long args[4] = { BRCTL_ADD_IF, ifindex, 0, 0 };
-
- ifr.ifr_data = (char *) args;
- err = ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr);
- }
-
- return err < 0 ? errno : 0;
-}
-
-int br_del_interface(const char *bridge, int ifindex)
-{
- struct ifreq ifr;
- int err;
-
- strncpy(ifr.ifr_name, bridge, IFNAMSIZ);
-#ifdef SIOCBRDELIF
- ifr.ifr_ifindex = ifindex;
- err = ioctl(br_socket_fd, SIOCBRDELIF, &ifr);
- if (err < 0)
-#endif
- {
- unsigned long args[4] = { BRCTL_DEL_IF, ifindex, 0, 0 };
-
- ifr.ifr_data = (char *) args;
- err = ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr);
- }
-
- return err < 0 ? errno : 0;
-}
static int br_set(const char *bridge, const char *name,
unsigned long value, unsigned long oldcode)
@@ -390,45 +394,6 @@ int br_set_bridge_priority(const char *br, int bridge_priority)
BRCTL_SET_BRIDGE_PRIORITY);
}
-/* sigh.. if_nametoindex busted on older glibc and uclibc */
-static inline unsigned int ifnametoindex(const char* ifname)
-{
- struct ifreq ifr;
-
- strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
-
- return (ioctl(br_socket_fd, SIOCGIFINDEX,&ifr) < 0) ? 0 : ifr.ifr_ifindex;
-}
-
-static int nametoportindex(const char *brname, const char *ifname)
-{
- int i;
- int ifindex = ifnametoindex(ifname);
- int ifindices[MAX_PORTS];
- unsigned long args[4] = { BRCTL_GET_PORT_LIST,
- (unsigned long)ifindices, MAX_PORTS, 0 };
- struct ifreq ifr;
-
- if (ifindex <= 0)
- goto error;
-
- memset(ifindices, 0, sizeof(ifindices));
- strncpy(ifr.ifr_name, brname, IFNAMSIZ);
- ifr.ifr_data = (char *) &args;
-
- if (ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr) < 0)
- goto error;
-
- for (i = 0; i < MAX_PORTS; i++) {
- if (ifindices[i] == ifindex)
- return i;
- }
-
- dprintf("%s is not a in bridge %s\n", ifname, brname);
- error:
- return -1;
-}
-
static int port_set(const char *bridge, const char *ifname,
const char *name, unsigned long value,
unsigned long oldcode)
@@ -454,7 +419,7 @@ static int port_set(const char *bridge, const char *ifname,
sysfs_close_directory(sdir);
} else
#endif
- if ( (index = nametoportindex(bridge, ifname)) < 0)
+ if ( (index = get_portno(bridge, ifname)) < 0)
ret = index;
else {
@@ -527,9 +492,12 @@ int br_read_fdb(const char *bridge, struct fdb_entry *fdbs,
retry:
n = ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr);
- sleep(0);
- if (n < 0 && errno == EAGAIN && ++retries < 10)
+
+ /* table can change during ioctl processing */
+ if (n < 0 && errno == EAGAIN && ++retries < 10) {
+ sleep(0);
goto retry;
+ }
}
for (i = 0; i < n; i++)
diff --git a/libbridge/libbridge_if.c b/libbridge/libbridge_if.c
index 5a31f0e..77d3f8a 100644
--- a/libbridge/libbridge_if.c
+++ b/libbridge/libbridge_if.c
@@ -65,3 +65,53 @@ int br_del_bridge(const char *brname)
}
return ret < 0 ? errno : 0;
}
+
+int br_add_interface(const char *bridge, const char *dev)
+{
+ struct ifreq ifr;
+ int err;
+ int ifindex = if_nametoindex(dev);
+
+ if (ifindex == 0)
+ return ENODEV;
+
+ strncpy(ifr.ifr_name, bridge, IFNAMSIZ);
+#ifdef SIOCBRADDIF
+ ifr.ifr_ifindex = ifindex;
+ err = ioctl(br_socket_fd, SIOCBRADDIF, &ifr);
+ if (err < 0)
+#endif
+ {
+ unsigned long args[4] = { BRCTL_ADD_IF, ifindex, 0, 0 };
+
+ ifr.ifr_data = (char *) args;
+ err = ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr);
+ }
+
+ return err < 0 ? errno : 0;
+}
+
+int br_del_interface(const char *bridge, const char *dev)
+{
+ struct ifreq ifr;
+ int err;
+ int ifindex = if_nametoindex(dev);
+
+ if (ifindex == 0)
+ return ENODEV;
+
+ strncpy(ifr.ifr_name, bridge, IFNAMSIZ);
+#ifdef SIOCBRDELIF
+ ifr.ifr_ifindex = ifindex;
+ err = ioctl(br_socket_fd, SIOCBRDELIF, &ifr);
+ if (err < 0)
+#endif
+ {
+ unsigned long args[4] = { BRCTL_DEL_IF, ifindex, 0, 0 };
+
+ ifr.ifr_data = (char *) args;
+ err = ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr);
+ }
+
+ return err < 0 ? errno : 0;
+}
diff --git a/libbridge/libbridge_init.c b/libbridge/libbridge_init.c
index 3abcb18..b194705 100644
--- a/libbridge/libbridge_init.c
+++ b/libbridge/libbridge_init.c
@@ -82,7 +82,7 @@ static int new_foreach_bridge(int (*iterator)(const char *name, void *),
devlist = sysfs_get_class_devices(br_class_net);
if (!devlist) {
- fprintf(stderr, "Can't read devices from sysfs\n");
+ dprintf("Can't read devices from sysfs\n");
return -errno;
}
@@ -98,18 +98,6 @@ static int new_foreach_bridge(int (*iterator)(const char *name, void *),
}
#endif
-/* once again, if_indextoname busted on older glibc and uclibc */
-static inline char * ifindextoname (unsigned int ifindex, char *ifname)
-{
- struct ifreq ifr;
-
- ifr.ifr_ifindex = ifindex;
- if ( ioctl(br_socket_fd, SIOCGIFNAME, &ifr) < 0)
- return NULL;
-
- return strncpy(ifname, ifr.ifr_name, IFNAMSIZ);
-}
-
/*
* Old interface uses ioctl
*/
@@ -124,14 +112,14 @@ static int old_foreach_bridge(int (*iterator)(const char *, void *),
num = ioctl(br_socket_fd, SIOCGIFBR, args);
if (num < 0) {
- fprintf(stderr, "Get bridge indices failed: %s\n",
+ dprintf("Get bridge indices failed: %s\n",
strerror(errno));
return -errno;
}
for (i = 0; i < num; i++) {
- if (!ifindextoname(ifindices[i], ifname)) {
- fprintf(stderr, "get find name for ifindex %d\n",
+ if (!if_indextoname(ifindices[i], ifname)) {
+ dprintf("get find name for ifindex %d\n",
ifindices[i]);
return -errno;
}
@@ -167,11 +155,10 @@ int br_foreach_bridge(int (*iterator)(const char *, void *),
/*
* Only used if sysfs is not available.
*/
-static int old_foreach_port(const char *brname,
- int (*iterator)(const char *br,
- const char *port, int ind,
- void *arg),
- void *arg)
+static int old_foreach_port(const char *brname,
+ int (*iterator)(const char *br, const char *port,
+ void *arg),
+ void *arg)
{
int i, err, count;
struct ifreq ifr;
@@ -186,7 +173,7 @@ static int old_foreach_port(const char *brname,
err = ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr);
if (err < 0) {
- fprintf(stderr, "list ports for bridge:'%s' failed: %s\n",
+ dprintf("list ports for bridge:'%s' failed: %s\n",
brname, strerror(errno));
return -errno;
}
@@ -195,33 +182,29 @@ static int old_foreach_port(const char *brname,
for (i = 0; i < MAX_PORTS; i++) {
if (!ifindices[i])
continue;
- if (!ifindextoname(ifindices[i], ifname)) {
- fprintf(stderr, "can't find name for ifindex:%d\n",
+
+ if (!if_indextoname(ifindices[i], ifname)) {
+ dprintf("can't find name for ifindex:%d\n",
ifindices[i]);
continue;
}
++count;
- if (iterator(brname, ifname, i, arg))
+ if (iterator(brname, ifname, arg))
break;
}
return count;
}
-
-
/*
* Iterate over all ports in bridge (using sysfs).
*/
int br_foreach_port(const char *brname,
- int (*iterator)(const char *br, const char *port,
- int ind, void *arg),
+ int (*iterator)(const char *br, const char *port, void *arg),
void *arg)
{
-#ifndef HAVE_LIBSYSFS
- return old_foreach_port(brname, iterator, arg);
-#else
+#ifdef HAVE_LIBSYSFS
struct sysfs_class_device *dev;
struct sysfs_directory *dir;
struct sysfs_link *plink;
@@ -231,7 +214,7 @@ int br_foreach_port(const char *brname,
if (!br_class_net ||
!(dev = sysfs_get_class_device(br_class_net, (char *) brname)))
- return -ENODEV;
+ goto old;
snprintf(path, sizeof(path), "%s/%s",
dev->path, SYSFS_BRIDGE_PORT_SUBDIR);
@@ -242,26 +225,27 @@ int br_foreach_port(const char *brname,
/* no /sys/class/net/ethX/brif subdirectory
* either: old kernel, or not really a bridge
*/
- err = old_foreach_port(brname, iterator, arg);
- goto out1;
+ goto old;
}
links = sysfs_get_dir_links(dir);
if (!links) {
err = -ENOSYS;
- goto out2;
+ goto out;
}
err = 0;
dlist_for_each_data(links, plink, struct sysfs_link) {
++err;
- if (iterator(brname, plink->name, err, arg))
+ if (iterator(brname, plink->name, arg))
break;
-
}
- out2:
+ out:
sysfs_close_directory(dir);
- out1:
return err;
+
+ old:
#endif
+ return old_foreach_port(brname, iterator, arg);
+
}