summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2006-11-01 09:07:47 +0000
committerthompsa <thompsa@FreeBSD.org>2006-11-01 09:07:47 +0000
commit905c36ce8074bad2f741ebcef77cfdc91cd2f2d9 (patch)
tree16428f9402e25da25aee2aed4b8426fbdc3b197d /sbin
parent7f880f15f45632bc40511ee0d3775b38e5ae2628 (diff)
downloadFreeBSD-src-905c36ce8074bad2f741ebcef77cfdc91cd2f2d9.zip
FreeBSD-src-905c36ce8074bad2f741ebcef77cfdc91cd2f2d9.tar.gz
Bring in support for the Rapid Spanning Tree Protocol (802.1w).
RSTP provides faster spanning tree convergence, the protocol will exchange information with neighboring switches to quickly transition to forwarding without creating loops. The code will default to RSTP mode but will downgrade any port connected to a legacy STP network so is fully backward compatible. Reviewed by: syrinx Tested by: syrinx
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ifconfig/ifbridge.c173
-rw-r--r--sbin/ifconfig/ifconfig.843
2 files changed, 181 insertions, 35 deletions
diff --git a/sbin/ifconfig/ifbridge.c b/sbin/ifconfig/ifbridge.c
index c42213f..3f708b2 100644
--- a/sbin/ifconfig/ifbridge.c
+++ b/sbin/ifconfig/ifbridge.c
@@ -61,6 +61,27 @@ static const char rcsid[] =
#include "ifconfig.h"
+static const char *stpstates[] = {
+ "disabled",
+ "listening",
+ "learning",
+ "forwarding",
+ "blocking",
+ "discarding"
+};
+static const char *stpproto[] = {
+ "stp",
+ "-",
+ "rstp"
+};
+static const char *stproles[] = {
+ "disabled",
+ "root",
+ "designated",
+ "alternate",
+ "backup"
+};
+
static int
get_val(const char *cp, u_long *valp)
{
@@ -113,13 +134,6 @@ do_bridgeflag(int sock, const char *ifs, int flag, int set)
static void
bridge_interfaces(int s, const char *prefix)
{
- static const char *stpstates[] = {
- "disabled",
- "listening",
- "learning",
- "forwarding",
- "blocking",
- };
struct ifbifconf bifc;
struct ifbreq *req;
char *inbuf = NULL, *ninbuf;
@@ -159,12 +173,35 @@ bridge_interfaces(int s, const char *prefix)
printf("port %u priority %u",
req->ifbr_portno, req->ifbr_priority);
printf(" path cost %u", req->ifbr_path_cost);
+ if (req->ifbr_proto <
+ sizeof(stpproto) / sizeof(stpproto[0]))
+ printf(" proto %s", stpproto[req->ifbr_proto]);
+ else
+ printf(" <unknown proto %d>",
+ req->ifbr_proto);
+
+ printf("\n%s", pad);
+ if (req->ifbr_role <
+ sizeof(stproles) / sizeof(stproles[0]))
+ printf("role %s", stproles[req->ifbr_role]);
+ else
+ printf("<unknown role %d>",
+ req->ifbr_role);
if (req->ifbr_state <
sizeof(stpstates) / sizeof(stpstates[0]))
- printf(" %s", stpstates[req->ifbr_state]);
+ printf(" state %s", stpstates[req->ifbr_state]);
else
printf(" <unknown state %d>",
req->ifbr_state);
+
+ if (req->ifbr_p2p)
+ printf(" p2p");
+ else
+ printf(" shared");
+ if (req->ifbr_edge)
+ printf(" edge");
+ if (req->ifbr_autoedge)
+ printf(" autoedge");
printf("\n");
}
}
@@ -210,28 +247,22 @@ bridge_addresses(int s, const char *prefix)
static void
bridge_status(int s)
{
- struct ifbrparam param;
+ struct ifbropreq param;
u_int16_t pri;
- u_int8_t ht, fd, ma;
-
- if (do_cmd(s, BRDGGPRI, &param, sizeof(param), 0) < 0)
- return;
- pri = param.ifbrp_prio;
-
- if (do_cmd(s, BRDGGHT, &param, sizeof(param), 0) < 0)
- return;
- ht = param.ifbrp_hellotime;
-
- if (do_cmd(s, BRDGGFD, &param, sizeof(param), 0) < 0)
- return;
- fd = param.ifbrp_fwddelay;
+ u_int8_t ht, fd, ma, hc, pro;
- if (do_cmd(s, BRDGGMA, &param, sizeof(param), 0) < 0)
+ if (do_cmd(s, BRDGPARAM, &param, sizeof(param), 0) < 0)
return;
- ma = param.ifbrp_maxage;
+ pri = param.ifbop_priority;
+ pro = param.ifbop_protocol;
+ ht = param.ifbop_hellotime;
+ fd = param.ifbop_fwddelay;
+ hc = param.ifbop_holdcount;
+ ma = param.ifbop_maxage;
- printf("\tpriority %u hellotime %u fwddelay %u maxage %u\n",
- pri, ht, fd, ma);
+ printf("\tpriority %u hellotime %u fwddelay %u"
+ " maxage %u hc %u proto %s\n",
+ pri, ht, fd, ma, hc, stpproto[pro]);
bridge_interfaces(s, "\tmember: ");
@@ -326,6 +357,54 @@ unsetbridge_stp(const char *val, int d, int s, const struct afswtch *afp)
}
static void
+setbridge_edge(const char *val, int d, int s, const struct afswtch *afp)
+{
+ struct ifbreq req;
+
+ memset(&req, 0, sizeof(req));
+ strlcpy(req.ifbr_ifsname, val, sizeof(req.ifbr_ifsname));
+ req.ifbr_edge = 1;
+ if (do_cmd(s, BRDGSEDGE, &req, sizeof(req), 1) < 0)
+ err(1, "BRDGSEDGE %s", val);
+}
+
+static void
+unsetbridge_edge(const char *val, int d, int s, const struct afswtch *afp)
+{
+ struct ifbreq req;
+
+ memset(&req, 0, sizeof(req));
+ strlcpy(req.ifbr_ifsname, val, sizeof(req.ifbr_ifsname));
+ req.ifbr_edge = 0;
+ if (do_cmd(s, BRDGSEDGE, &req, sizeof(req), 1) < 0)
+ err(1, "BRDGSEDGE %s", val);
+}
+
+static void
+setbridge_autoedge(const char *val, int d, int s, const struct afswtch *afp)
+{
+ struct ifbreq req;
+
+ memset(&req, 0, sizeof(req));
+ strlcpy(req.ifbr_ifsname, val, sizeof(req.ifbr_ifsname));
+ req.ifbr_autoedge = 1;
+ if (do_cmd(s, BRDGSAEDGE, &req, sizeof(req), 1) < 0)
+ err(1, "BRDGSAEDGE %s", val);
+}
+
+static void
+unsetbridge_autoedge(const char *val, int d, int s, const struct afswtch *afp)
+{
+ struct ifbreq req;
+
+ memset(&req, 0, sizeof(req));
+ strlcpy(req.ifbr_ifsname, val, sizeof(req.ifbr_ifsname));
+ req.ifbr_autoedge = 0;
+ if (do_cmd(s, BRDGSAEDGE, &req, sizeof(req), 1) < 0)
+ err(1, "BRDGSAEDGE %s", val);
+}
+
+static void
setbridge_flush(const char *val, int d, int s, const struct afswtch *afp)
{
struct ifbreq req;
@@ -469,6 +548,38 @@ setbridge_priority(const char *arg, int d, int s, const struct afswtch *afp)
}
static void
+setbridge_protocol(const char *arg, int d, int s, const struct afswtch *afp)
+{
+ struct ifbrparam param;
+
+ if (strcasecmp(arg, "stp") == 0) {
+ param.ifbrp_proto = 0;
+ } else if (strcasecmp(arg, "rstp") == 0) {
+ param.ifbrp_proto = 2;
+ } else {
+ errx(1, "unknown stp protocol");
+ }
+
+ if (do_cmd(s, BRDGSPROTO, &param, sizeof(param), 1) < 0)
+ err(1, "BRDGSPROTO %s", arg);
+}
+
+static void
+setbridge_holdcount(const char *arg, int d, int s, const struct afswtch *afp)
+{
+ struct ifbrparam param;
+ u_long val;
+
+ if (get_val(arg, &val) < 0 || (val & ~0xff) != 0)
+ errx(1, "invalid value: %s", arg);
+
+ param.ifbrp_txhc = val & 0xff;
+
+ if (do_cmd(s, BRDGSTXHC, &param, sizeof(param), 1) < 0)
+ err(1, "BRDGSTXHC %s", arg);
+}
+
+static void
setbridge_ifpriority(const char *ifn, const char *pri, int s,
const struct afswtch *afp)
{
@@ -496,11 +607,11 @@ setbridge_ifpathcost(const char *ifn, const char *cost, int s,
memset(&req, 0, sizeof(req));
- if (get_val(cost, &val) < 0 || (val & ~0xff) != 0)
+ if (get_val(cost, &val) < 0)
errx(1, "invalid value: %s", cost);
strlcpy(req.ifbr_ifsname, ifn, sizeof(req.ifbr_ifsname));
- req.ifbr_path_cost = val & 0xffff;
+ req.ifbr_path_cost = val;
if (do_cmd(s, BRDGSIFCOST, &req, sizeof(req), 1) < 0)
err(1, "BRDGSIFCOST %s", cost);
@@ -532,6 +643,10 @@ static struct cmd bridge_cmds[] = {
DEF_CMD_ARG("-span", unsetbridge_span),
DEF_CMD_ARG("stp", setbridge_stp),
DEF_CMD_ARG("-stp", unsetbridge_stp),
+ DEF_CMD_ARG("edge", setbridge_edge),
+ DEF_CMD_ARG("-edge", unsetbridge_edge),
+ DEF_CMD_ARG("autoedge", setbridge_autoedge),
+ DEF_CMD_ARG("-autoedge", unsetbridge_autoedge),
DEF_CMD("flush", 0, setbridge_flush),
DEF_CMD("flushall", 0, setbridge_flushall),
DEF_CMD_ARG2("static", setbridge_static),
@@ -542,6 +657,8 @@ static struct cmd bridge_cmds[] = {
DEF_CMD_ARG("fwddelay", setbridge_fwddelay),
DEF_CMD_ARG("maxage", setbridge_maxage),
DEF_CMD_ARG("priority", setbridge_priority),
+ DEF_CMD_ARG("proto", setbridge_protocol),
+ DEF_CMD_ARG("holdcount", setbridge_holdcount),
DEF_CMD_ARG2("ifpriority", setbridge_ifpriority),
DEF_CMD_ARG2("ifpathcost", setbridge_ifpathcost),
DEF_CMD_ARG("timeout", setbridge_timeout),
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index ec58dc1..0221909 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -1267,38 +1267,67 @@ Spanning Tree is used to detect and remove loops in a network topology.
Disable Spanning Tree protocol on
.Ar interface .
This is the default for all interfaces added to a bridge.
+.It Cm edge Ar interface
+Set
+.Ar interface
+as an edge port.
+An edge port connects directly to end stations cannot create bridging
+loops in the network, this allows it to transition straight to forwarding.
+.It Cm -edge Ar interface
+Disable edge status on
+.Ar interface .
+.It Cm autoedge Ar interface
+Allow
+.Ar interface
+to automatically detect edge status.
+This is the default for all interfaces added to a bridge.
+.It Cm -autoedge Ar interface
+Disable automatic edge status on
+.Ar interface .
.It Cm maxage Ar seconds
Set the time that a Spanning Tree protocol configuration is valid.
The default is 20 seconds.
-The minimum is 1 second and the maximum is 255 seconds.
+The minimum is 6 seconds and the maximum is 40 seconds.
.It Cm fwddelay Ar seconds
Set the time that must pass before an interface begins forwarding
packets when Spanning Tree is enabled.
The default is 15 seconds.
-The minimum is 1 second and the maximum is 255 seconds.
+The minimum is 4 seconds and the maximum is 30 seconds.
.It Cm hellotime Ar seconds
Set the time between broadcasting of Spanning Tree protocol
configuration messages.
+The hello time may only be changed when operating in legacy stp mode.
The default is 2 seconds.
-The minimum is 1 second and the maximum is 255 seconds.
+The minimum is 1 second and the maximum is 2 seconds.
.It Cm priority Ar value
Set the bridge priority for Spanning Tree.
The default is 32768.
-The minimum is 0 and the maximum is 65536.
+The minimum is 0 and the maximum is 61440.
+.It Cm protocol Ar value
+Set the Spanning Tree protocol.
+The default is rstp.
+The available options are stp and rstp.
+.It Cm holdcount Ar value
+Set the transmit hold count for Spanning Tree.
+This is the number of packets transmitted before being rate limited.
+The default is 6.
+The minimum is 1 and the maximum is 10.
.It Cm ifpriority Ar interface Ar value
Set the Spanning Tree priority of
.Ar interface
to
.Ar value .
The default is 128.
-The minimum is 0 and the maximum is 255.
+The minimum is 0 and the maximum is 240.
.It Cm ifpathcost Ar interface Ar value
Set the Spanning Tree path cost of
.Ar interface
to
.Ar value .
-The default is 55.
-The minimum is 0 and the maximum is 65535.
+The default is calculated from the link speed.
+To change a previously selected path cost back to automatic, set the
+cost to 0.
+The minimum is 1 and the maximum is 200000000.
.El
.Pp
The following parameters are specific to IP tunnel interfaces,
OpenPOWER on IntegriCloud