Subject: bridge(4) fixes and improvement
To: None <tech-net@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: tech-net
Date: 03/14/2003 18:45:18
--gKMricLos+KVdGMg
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,
I'd like to commit the attached diff. It fixes two bugs I found with
bridge(4):
- stp isn't initialised when we turn the bridge up; as a result
  brconfig bridge0 add if0 add if1 stp if0 stp if1 up
  (which is the way of setting up stp in brconfig(8)) doen't work
  because the stp state for both interface stays disabled.
- in brconfig, setting the if priority doesn't work because of a cut-n-paste
  mistake: do_cmd() was called with BRDGSPRI instead of BRDGSIFPRIO.

It also adds the a way to change an interface path cost. This is usefull in
some cases. For example, you have a backup link which you don't want to be
used.

Comments, objections ?

--
Manuel Bouyer, LIP6, Universite Paris VI.           Manuel.Bouyer@lip6.fr
     NetBSD: 24 ans d'experience feront toujours la difference
--

--gKMricLos+KVdGMg
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="bridge.diff"

Index: sbin/brconfig/brconfig.8
===================================================================
RCS file: /cvsroot/src/sbin/brconfig/brconfig.8,v
retrieving revision 1.3
diff -u -r1.3 brconfig.8
--- sbin/brconfig/brconfig.8	2001/11/16 11:26:53	1.3
+++ sbin/brconfig/brconfig.8	2003/03/14 17:44:13
@@ -176,6 +176,12 @@
 to
 .Ar value .
 The default is 128.  The minimum is 0 and the maximum is 255.
+.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.
 .El
 .Sh EXAMPLES
 The following then placed in the file
Index: sbin/brconfig/brconfig.c
===================================================================
RCS file: /cvsroot/src/sbin/brconfig/brconfig.c,v
retrieving revision 1.1
diff -u -r1.1 brconfig.c
--- sbin/brconfig/brconfig.c	2001/08/17 21:42:11	1.1
+++ sbin/brconfig/brconfig.c	2003/03/14 17:44:13
@@ -85,6 +85,7 @@
 void	cmd_maxage(const struct command *, int, const char *, char **);
 void	cmd_priority(const struct command *, int, const char *, char **);
 void	cmd_ifpriority(const struct command *, int, const char *, char **);
+void	cmd_ifpathcost(const struct command *, int, const char *, char **);
 void	cmd_timeout(const struct command *, int, const char *, char **);
 void	cmd_stp(const struct command *, int, const char *, char **);
 
@@ -115,6 +116,7 @@
 	{ "maxage",		1,	0,		cmd_maxage },
 	{ "priority",		1,	0,		cmd_priority },
 	{ "ifpriority",		2,	0,		cmd_ifpriority },
+	{ "ifpathcost",		2,	0,		cmd_ifpathcost },
 	{ "timeout",		1,	0,		cmd_timeout },
 	{ "stp",		1,	0,		cmd_stp },
 	{ "-stp",		1,	CMD_INVERT,	cmd_stp },
@@ -256,6 +258,7 @@
 		"<bridge> hellotime <time>",
 		"<bridge> priority <value>",
 		"<bridge> ifpriority <interface> <value>",
+		"<bridge> ifpathcost <interface> <value>",
 		NULL,
 	};
 	extern const char *__progname;
@@ -424,6 +427,7 @@
 		printf("port %u priority %u",
 		    req->ifbr_portno, req->ifbr_priority);
 		if (req->ifbr_ifsflags & IFBIF_STP) {
+			printf(" path cost %u", req->ifbr_path_cost);
 			if (req->ifbr_state <
 			    sizeof(stpstates) / sizeof(stpstates[0]))
 				printf(" %s", stpstates[req->ifbr_state]);
@@ -769,7 +773,26 @@
 	strlcpy(req.ifbr_ifsname, argv[0], sizeof(req.ifbr_ifsname));
 	req.ifbr_priority = val & 0xff;
 
-	if (do_cmd(sock, bridge, BRDGSPRI, &req, sizeof(req), 1) < 0)
+	if (do_cmd(sock, bridge, BRDGSIFPRIO, &req, sizeof(req), 1) < 0)
+		err(1, "%s %s", cmd->cmd_keyword, argv[0]);
+}
+
+void
+cmd_ifpathcost(const struct command *cmd, int sock, const char *bridge,
+    char **argv)
+{
+	struct ifbreq req;
+	u_long val;
+
+	memset(&req, 0, sizeof(req));
+
+	if (get_val(argv[1], &val) < 0 || (val & ~0xff) != 0)
+		errx(1, "%s: invalid value: %s", cmd->cmd_keyword, argv[1]);
+
+	strlcpy(req.ifbr_ifsname, argv[0], sizeof(req.ifbr_ifsname));
+	req.ifbr_path_cost = val & 0xffff;
+
+	if (do_cmd(sock, bridge, BRDGSIFCOST, &req, sizeof(req), 1) < 0)
 		err(1, "%s %s", cmd->cmd_keyword, argv[0]);
 }
 
Index: sys/net/if_bridge.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_bridge.c,v
retrieving revision 1.5.4.1
diff -u -r1.5.4.1 if_bridge.c
--- sys/net/if_bridge.c	2002/06/10 16:28:33	1.5.4.1
+++ sys/net/if_bridge.c	2003/03/14 17:44:13
@@ -216,6 +216,7 @@
 int	bridge_ioctl_gma(struct bridge_softc *, void *);
 int	bridge_ioctl_sma(struct bridge_softc *, void *);
 int	bridge_ioctl_sifprio(struct bridge_softc *, void *);
+int	bridge_ioctl_sifcost(struct bridge_softc *, void *);
 
 struct bridge_control {
 	int	(*bc_func)(struct bridge_softc *, void *);
@@ -284,6 +285,9 @@
 
 	{ bridge_ioctl_sifprio,		sizeof(struct ifbreq),
 	  BC_F_COPYIN|BC_F_SUSER },
+
+	{ bridge_ioctl_sifcost,		sizeof(struct ifbreq),
+	  BC_F_COPYIN|BC_F_SUSER },
 };
 const int bridge_control_table_size =
     sizeof(bridge_control_table) / sizeof(bridge_control_table[0]);
@@ -633,6 +637,7 @@
 	req->ifbr_ifsflags = bif->bif_flags;
 	req->ifbr_state = bif->bif_state;
 	req->ifbr_priority = bif->bif_priority;
+	req->ifbr_path_cost = bif->bif_path_cost;
 	req->ifbr_portno = bif->bif_ifp->if_index & 0xff;
 
 	return (0);
@@ -716,6 +721,7 @@
 		breq.ifbr_ifsflags = bif->bif_flags;
 		breq.ifbr_state = bif->bif_state;
 		breq.ifbr_priority = bif->bif_priority;
+		breq.ifbr_path_cost = bif->bif_path_cost;
 		breq.ifbr_portno = bif->bif_ifp->if_index & 0xff;
 		error = copyout(&breq, bifc->ifbic_req + count, sizeof(breq));
 		if (error)
@@ -933,6 +939,24 @@
 	return (0);
 }
 
+int
+bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg)
+{
+	struct ifbreq *req = arg;
+	struct bridge_iflist *bif;
+
+	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
+	if (bif == NULL)
+		return (ENOENT);
+
+	bif->bif_path_cost = req->ifbr_path_cost;
+
+	if (sc->sc_if.if_flags & IFF_RUNNING)
+		bstp_initialization(sc);
+
+	return (0);
+}
+
 /*
  * bridge_ifdetach:
  *
@@ -968,6 +992,7 @@
 	    bridge_timer, sc);
 
 	ifp->if_flags |= IFF_RUNNING;
+	bstp_initialization(sc);
 	return (0);
 }
 
Index: sys/net/if_bridgevar.h
===================================================================
RCS file: /cvsroot/src/sys/net/if_bridgevar.h,v
retrieving revision 1.1
diff -u -r1.1 if_bridgevar.h
--- sys/net/if_bridgevar.h	2001/08/17 21:37:28	1.1
+++ sys/net/if_bridgevar.h	2003/03/14 17:44:13
@@ -102,6 +102,7 @@
 #define	BRDGGMA			19	/* get max age (ifbrparam) */
 #define	BRDGSMA			20	/* set max age (ifbrparam) */
 #define	BRDGSIFPRIO		21	/* set if priority (ifbreq) */
+#define	BRDGSIFCOST		22	/* set if path cost (ifbreq) */
 
 /*
  * Generic bridge control request.
@@ -111,6 +112,7 @@
 	uint32_t	ifbr_ifsflags;		/* member if flags */
 	uint8_t		ifbr_state;		/* member if STP state */
 	uint8_t		ifbr_priority;		/* member if STP priority */
+	uint8_t		ifbr_path_cost;		/* member if STP cost */
 	uint8_t		ifbr_portno;		/* member if port number */
 };
 

--gKMricLos+KVdGMg--