aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshemminger <shemminger>2004-04-13 22:51:05 +0000
committershemminger <shemminger>2004-04-13 22:51:05 +0000
commit9e65dd9b37f465fc8a62e0e2baa9084d79657d0b (patch)
tree995b86685d11eb52310fa7077b014c1f67a8b015
parent99274cbbd7c2fc8ed0791119fbba2765da29c0c5 (diff)
downloadbridge-utils-9e65dd9b37f465fc8a62e0e2baa9084d79657d0b.tar.gz
Support for 1000's of ports on bridge.v0.9.8
Don't read port and bridge info automatically, add a new API hook to do that. Version 0.9.8
-rw-r--r--brctl/Makefile.in2
-rw-r--r--brctl/brctl.c2
-rw-r--r--brctl/brctl_cmd.c3
-rw-r--r--bridge-utils.spec2
-rw-r--r--libbridge/libbridge_devif.c50
-rw-r--r--libbridge/libbridge_init.c139
6 files changed, 120 insertions, 78 deletions
diff --git a/brctl/Makefile.in b/brctl/Makefile.in
index f56bd9c..fd66905 100644
--- a/brctl/Makefile.in
+++ b/brctl/Makefile.in
@@ -4,7 +4,7 @@ KERNEL_HEADERS=-I@KERNEL_HEADERS@
CC=@CC@
CFLAGS= -Wall -g @CFLAGS@
INCLUDE=-I../libbridge $(KERNEL_HEADERS)
-LIBS= -L ../libbridge -lbridge -lsysfs
+LIBS= -L ../libbridge -lbridge
prefix=@prefix@
exec_prefix=@exec_prefix@
diff --git a/brctl/brctl.c b/brctl/brctl.c
index 1849373..267170f 100644
--- a/brctl/brctl.c
+++ b/brctl/brctl.c
@@ -23,7 +23,7 @@
#include "libbridge.h"
#include "brctl.h"
-const char *version = "0.9.7";
+const char *version = "0.9.8";
const char *help_message =
"commands:\n"
diff --git a/brctl/brctl_cmd.c b/brctl/brctl_cmd.c
index 5e630e8..99d9725 100644
--- a/brctl/brctl_cmd.c
+++ b/brctl/brctl_cmd.c
@@ -276,8 +276,7 @@ void br_cmd_stp(struct bridge *br, char *arg0, char *arg1)
err = br_set_stp_state(br, stp);
if (err)
- fprintf(stderr, "set stp status failed: %s\n",
- strerror(err));
+ fprintf(stderr, "set stp status failed: %d\n", err);
}
void br_cmd_showstp(struct bridge *br, char *arg0, char *arg1)
diff --git a/bridge-utils.spec b/bridge-utils.spec
index d696027..144679b 100644
--- a/bridge-utils.spec
+++ b/bridge-utils.spec
@@ -1,6 +1,6 @@
Summary: Utilities for configuring the linux ethernet bridge.
Name: bridge-utils
-Version: 0.9.7
+Version: 0.9.8
Release: 1
Copyright: GPL
Group: System Environment/Base
diff --git a/libbridge/libbridge_devif.c b/libbridge/libbridge_devif.c
index 4ffe98d..085eaea 100644
--- a/libbridge/libbridge_devif.c
+++ b/libbridge/libbridge_devif.c
@@ -43,56 +43,6 @@ int br_device_ioctl(const struct bridge *br, unsigned long arg0,
return ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr);
}
-int br_get_bridge_info(const struct bridge *br, struct bridge_info *info)
-{
- struct __bridge_info i;
-
- if (br_device_ioctl(br, BRCTL_GET_BRIDGE_INFO,
- (unsigned long )&i, 0, 0) < 0) {
- return errno;
- }
-
- memcpy(&info->designated_root, &i.designated_root, 8);
- memcpy(&info->bridge_id, &i.bridge_id, 8);
- info->root_path_cost = i.root_path_cost;
- info->root_port = i.root_port;
- info->topology_change = i.topology_change;
- info->topology_change_detected = i.topology_change_detected;
- info->stp_enabled = i.stp_enabled;
- __jiffies_to_tv(&info->max_age, i.max_age);
- __jiffies_to_tv(&info->hello_time, i.hello_time);
- __jiffies_to_tv(&info->forward_delay, i.forward_delay);
- __jiffies_to_tv(&info->bridge_max_age, i.bridge_max_age);
- __jiffies_to_tv(&info->bridge_hello_time, i.bridge_hello_time);
- __jiffies_to_tv(&info->bridge_forward_delay, i.bridge_forward_delay);
- __jiffies_to_tv(&info->ageing_time, i.ageing_time);
- return 0;
-}
-
-int br_get_port_info(const struct port *p, struct port_info *info)
-{
- struct __port_info i;
-
- if (br_device_ioctl(p->parent, BRCTL_GET_PORT_INFO,
- (unsigned long)&i, p->index, 0) < 0) {
- fprintf(stderr, "%s: can't get port %d info %s\n",
- p->parent->ifname, p->index, strerror(errno));
- return errno;
- }
-
- memcpy(&info->designated_root, &i.designated_root, 8);
- memcpy(&info->designated_bridge, &i.designated_bridge, 8);
- info->port_id = i.port_id;
- info->designated_port = i.designated_port;
- info->path_cost = i.path_cost;
- info->designated_cost = i.designated_cost;
- info->state = i.state;
- info->top_change_ack = i.top_change_ack;
- info->config_pending = i.config_pending;
-
- return 0;
-}
-
int br_add_interface(struct bridge *br, int ifindex)
{
if (br_device_ioctl(br, BRCTL_ADD_IF, ifindex, 0, 0) < 0)
diff --git a/libbridge/libbridge_init.c b/libbridge/libbridge_init.c
index eb5399c..d401250 100644
--- a/libbridge/libbridge_init.c
+++ b/libbridge/libbridge_init.c
@@ -32,6 +32,79 @@
int br_socket_fd;
struct bridge *bridge_list;
+static void __bridge_info_copy(struct bridge_info *info,
+ const struct __bridge_info *i)
+{
+ memcpy(&info->designated_root, &i->designated_root, 8);
+ memcpy(&info->bridge_id, &i->bridge_id, 8);
+ info->root_path_cost = i->root_path_cost;
+ info->topology_change = i->topology_change;
+ info->topology_change_detected = i->topology_change_detected;
+ info->root_port = i->root_port;
+ info->stp_enabled = i->stp_enabled;
+ __jiffies_to_tv(&info->max_age, i->max_age);
+ __jiffies_to_tv(&info->hello_time, i->hello_time);
+ __jiffies_to_tv(&info->forward_delay, i->forward_delay);
+ __jiffies_to_tv(&info->bridge_max_age, i->bridge_max_age);
+ __jiffies_to_tv(&info->bridge_hello_time, i->bridge_hello_time);
+ __jiffies_to_tv(&info->bridge_forward_delay, i->bridge_forward_delay);
+ __jiffies_to_tv(&info->ageing_time, i->ageing_time);
+ __jiffies_to_tv(&info->hello_timer_value, i->hello_timer_value);
+ __jiffies_to_tv(&info->tcn_timer_value, i->tcn_timer_value);
+ __jiffies_to_tv(&info->topology_change_timer_value,
+ i->topology_change_timer_value);
+ __jiffies_to_tv(&info->gc_timer_value, i->gc_timer_value);
+}
+
+
+int br_get_bridge_info(const struct bridge *br, struct bridge_info *info)
+{
+ struct __bridge_info i;
+
+ if (br_device_ioctl(br, BRCTL_GET_BRIDGE_INFO,
+ (unsigned long )&i, 0, 0) < 0) {
+ return errno;
+ }
+
+ __bridge_info_copy(info, &i);
+ return 0;
+}
+
+static void __port_info_copy(struct port_info *info,
+ const struct __port_info *i)
+{
+ memcpy(&info->designated_root, &i->designated_root, 8);
+ memcpy(&info->designated_bridge, &i->designated_bridge, 8);
+ info->port_id = i->port_id;
+ info->designated_port = i->designated_port;
+ info->path_cost = i->path_cost;
+ info->designated_cost = i->designated_cost;
+ info->state = i->state;
+ info->top_change_ack = i->top_change_ack;
+ info->config_pending = i->config_pending;
+ __jiffies_to_tv(&info->message_age_timer_value,
+ i->message_age_timer_value);
+ __jiffies_to_tv(&info->forward_delay_timer_value,
+ i->forward_delay_timer_value);
+ __jiffies_to_tv(&info->hold_timer_value,
+ i->hold_timer_value);
+}
+
+int br_get_port_info(const struct port *p, struct port_info *info)
+{
+ struct __port_info i;
+
+ if (br_device_ioctl(p->parent, BRCTL_GET_PORT_INFO,
+ (unsigned long)&i, p->index, 0) < 0) {
+ fprintf(stderr, "%s: can't get port %d info %s\n",
+ p->parent->ifname, p->index, strerror(errno));
+ return errno;
+ }
+ __port_info_copy(info, &i);
+
+ return 0;
+}
+
static void br_nuke_bridge(struct bridge *b)
{
struct port *p, *n;
@@ -46,26 +119,31 @@ static void br_nuke_bridge(struct bridge *b)
static int br_make_port_list(struct bridge *br)
{
- int err;
- int i;
- int ifindices[MAX_PORTS];
+ int i, cnt;
struct port *p, **top;
+ int *ifindices;
+
+ ifindices = calloc(MAX_PORTS, sizeof(int));
+ if (!ifindices)
+ return -ENOMEM;
- memset(ifindices, 0, sizeof(ifindices));
- if (br_device_ioctl(br, BRCTL_GET_PORT_LIST, (unsigned long)ifindices,
- MAX_PORTS, 0) < 0)
+ cnt = br_device_ioctl(br, BRCTL_GET_PORT_LIST,
+ (unsigned long)ifindices,
+ MAX_PORTS, 0);
+ if (cnt < 0)
return errno;
+ if (cnt == 0)
+ cnt = 256; /* old 2.4 compatiablity */
+
top = &br->firstport;
- for (i = 0; i < MAX_PORTS; i++) {
+ for (i = 0; i < cnt; i++) {
if (!ifindices[i])
continue;
p = malloc(sizeof(struct port));
- if (!p) {
- err = -ENOMEM;
- goto error_out;
- }
+ if (!p)
+ goto nomem;
p->next = NULL;
p->ifindex = ifindices[i];
@@ -75,9 +153,10 @@ static int br_make_port_list(struct bridge *br)
top = &p->next;
}
+ free(ifindices);
return 0;
- error_out:
+ nomem:
p = br->firstport;
while (p) {
struct port *n = p->next;
@@ -85,14 +164,31 @@ static int br_make_port_list(struct bridge *br)
p = n;
}
br->firstport = NULL;
+ free(ifindices);
+
+ return -ENOMEM;
+}
+
+static struct bridge *new_bridge(int ifindex, const char *name)
+{
+ struct bridge *br;
- return err;
+ br = malloc(sizeof(struct bridge));
+ if (br) {
+ memset(br, 0, sizeof(struct bridge));
+ br->ifindex = ifindex;
+ strncpy(br->ifname, name, IFNAMSIZ);
+ br->firstport = NULL;
+ }
+ return br;
}
static int br_make_bridge_list(void)
{
+ struct bridge *br;
int i, num;
int ifindices[MAX_BRIDGES];
+ char ifname[IFNAMSIZ];
num = br_get_br(BRCTL_GET_BRIDGES, (unsigned long)ifindices,
MAX_BRIDGES);
@@ -101,19 +197,16 @@ static int br_make_bridge_list(void)
strerror(errno));
return errno;
}
- bridge_list = NULL;
- for (i = 0;i < num; i++) {
- struct bridge *br;
- br = malloc(sizeof(struct bridge));
- if (!br)
- return -ENOMEM;
+ bridge_list = NULL;
+ for (i = 0; i < num; i++) {
+ if (!if_indextoname(ifindices[i], ifname))
+ continue;
+ br = new_bridge(ifindices[i], ifname);
+ if (!br) /* ignore the problem could just be a race! */
+ continue;
- memset(br, 0, sizeof(struct bridge));
- br->ifindex = ifindices[i];
- br->firstport = NULL;
if ( br_make_port_list(br)) {
- /* ignore the problem could just be a race! */
free(br);
continue;
}