diff -urN ./bridge-utils-1.0.4-old/brctl/brctl_cmd.c bridge-utils-1.0.4/brctl/brctl_cmd.c --- ./bridge-utils-1.0.4-old/brctl/brctl_cmd.c 2004-06-04 20:03:40.000000000 +0200 +++ bridge-utils-1.0.4/brctl/brctl_cmd.c 2004-07-20 12:23:55.000000000 +0200 @@ -257,13 +257,16 @@ { int stp, err; - if (!strcmp(argv[2], "on") || !strcmp(argv[2], "yes") - || !strcmp(argv[2], "1")) - stp = 1; - else if (!strcmp(argv[2], "off") || !strcmp(argv[2], "no") - || !strcmp(argv[2], "0")) - stp = 0; - else { + stp=-1; + if ( argv[1] && argv[2] ){ + if (!strcmp(argv[2], "on") || !strcmp(argv[2], "yes") + || !strcmp(argv[2], "1")) + stp = 1; + else if (!strcmp(argv[2], "off") || !strcmp(argv[2], "no") + || !strcmp(argv[2], "0")) + stp = 0; + } + if ( stp == -1 ){ fprintf(stderr, "expect on/off for argument\n"); return 1; } @@ -275,6 +278,36 @@ return err != 0; } +static int br_cmd_stp_carrier(char** argv) +{ + int carrier, err; + + carrier=-1; + if ( argv[2] && argv[1] ) { + if (!strcmp(argv[2], "nfc")) + carrier = 1; + else if (!strcmp(argv[2], "off")) + carrier = 0; + else if (!strcmp(argv[2], "mii")) + carrier = 2; + } + + if ( carrier == -1 ) { + fprintf(stderr, "expect off to disable, nfc for net_if_carrier (recommended), mii for mii/ethtool linkstate detection\n"); + return 1; + } + + err = br_set_stp_carrier(argv[1], carrier); + if (err){ + if ( err == EOPNOTSUPP ) + fprintf(stderr,"Don't forget to enable stp.\n"); + else + fprintf(stderr, "set linkstate detection failed: %s\n", + strerror(errno)); + } + return err != 0; +} + static int br_cmd_showstp(char** argv) { struct bridge_info info; @@ -396,6 +429,8 @@ "\t\tshow bridge stp info"}, { 1, "stp", br_cmd_stp, " \tturn stp on/off" }, + { 1, "linkstate", br_cmd_stp_carrier, + " \tturn linkstate detection off / nfc (recommended) / mii" }, }; const struct command *command_lookup(const char *cmd) diff -urN ./bridge-utils-1.0.4-old/doc/brctl.8 bridge-utils-1.0.4/doc/brctl.8 --- ./bridge-utils-1.0.4-old/doc/brctl.8 2001-11-07 18:16:20.000000000 +0100 +++ bridge-utils-1.0.4/doc/brctl.8 2004-07-20 11:23:45.000000000 +0200 @@ -159,6 +159,18 @@ dimension. This metric is used in the designated port and root port selection algorithms. +.B brctl linkstate +enables link state monitoring of the bridge ports. We support two +types of link state monitoring. The first type uses the +net_if_carrier_ok() call to determine interface status. + +The second type uses MII or ETHTOOL ioctls that +are less efficient and utilize a deprecated calling sequence within the kernel. +The netif_carrier_ok() relies on the device driver to maintain its state and +most, but not all, device drivers support this facility. The netif_carrier_ok() +call returns that the link is up when the state is unknown. So if brctl showstp +insists that a link is up when it should not be then switch to . The +code will log errors when it does not support the hardware. .SH NOTES .BR brctl(8) diff -urN ./bridge-utils-1.0.4-old/libbridge/libbridge.h bridge-utils-1.0.4/libbridge/libbridge.h --- ./bridge-utils-1.0.4-old/libbridge/libbridge.h 2004-06-08 17:57:49.000000000 +0200 +++ bridge-utils-1.0.4/libbridge/libbridge.h 2004-07-20 12:03:10.000000000 +0200 @@ -100,6 +100,7 @@ extern int br_set_bridge_max_age(const char *br, struct timeval *tv); extern int br_set_ageing_time(const char *br, struct timeval *tv); extern int br_set_stp_state(const char *br, int stp_state); +extern int br_set_stp_carrier(const char *br, int stp_state); extern int br_set_bridge_priority(const char *br, int bridge_priority); extern int br_set_port_priority(const char *br, const char *p, int port_priority); diff -urN ./bridge-utils-1.0.4-old/libbridge/libbridge_devif.c bridge-utils-1.0.4/libbridge/libbridge_devif.c --- ./bridge-utils-1.0.4-old/libbridge/libbridge_devif.c 2004-06-08 17:57:49.000000000 +0200 +++ bridge-utils-1.0.4/libbridge/libbridge_devif.c 2004-07-19 15:28:07.000000000 +0200 @@ -390,6 +390,11 @@ return br_set(br, "stp_state", stp_state, BRCTL_SET_BRIDGE_STP_STATE); } +int br_set_stp_carrier(const char *br, int stp_state) +{ + return br_set(br, "stp_state", stp_state, BRCTL_SET_BRIDGE_STP_CARRIER); +} + int br_set_bridge_priority(const char *br, int bridge_priority) { return br_set(br, "priority", bridge_priority, diff -urN ./bridge-utils-1.0.4-old/libbridge/libbridge_misc.c bridge-utils-1.0.4/libbridge/libbridge_misc.c --- ./bridge-utils-1.0.4-old/libbridge/libbridge_misc.c 2004-05-21 19:41:49.000000000 +0200 +++ bridge-utils-1.0.4/libbridge/libbridge_misc.c 2004-07-20 09:51:58.000000000 +0200 @@ -25,17 +25,18 @@ #include "libbridge_private.h" -static const char *state_names[5] = { +static const char *state_names[6] = { [BR_STATE_DISABLED] = "disabled", [BR_STATE_LISTENING] = "listening", [BR_STATE_LEARNING] = "learning", [BR_STATE_FORWARDING] = "forwarding", [BR_STATE_BLOCKING] ="blocking", + [BR_STATE_NOLINK] ="nolink", }; const char *br_get_state_name(int state) { - if (state >= 0 && state <= 4) + if (state >= 0 && state <= 5) return state_names[state]; return ""; diff -urN ./bridge-utils-1.0.4-old/libbridge/stamp-h1 bridge-utils-1.0.4/libbridge/stamp-h1 --- ./bridge-utils-1.0.4-old/libbridge/stamp-h1 1970-01-01 01:00:00.000000000 +0100 +++ bridge-utils-1.0.4/libbridge/stamp-h1 2004-07-19 16:04:59.000000000 +0200 @@ -0,0 +1 @@ +timestamp for libbridge/config.h