diff options
author | thompsa <thompsa@FreeBSD.org> | 2006-11-27 00:35:40 +0000 |
---|---|---|
committer | thompsa <thompsa@FreeBSD.org> | 2006-11-27 00:35:40 +0000 |
commit | 66955654aa682a306eccbcb98e5b6348a2d4c42d (patch) | |
tree | 7b48400cdbc7f90b6778963478fb4a368310b32c | |
parent | 2b74709ded53782adf2b6728fd8d69dc9d019d48 (diff) | |
download | FreeBSD-src-66955654aa682a306eccbcb98e5b6348a2d4c42d.zip FreeBSD-src-66955654aa682a306eccbcb98e5b6348a2d4c42d.tar.gz |
Sync with the OpenBSD port of RSTP
- use flags rather than sperate ioctls for edge, p2p
- implement p2p and autop2p flags
- define large pathcost constant as ULL
- show bridgeid and rootid in ifconfig
Obtained from: Reyk Floeter <reyk@openbsd.org>
-rw-r--r-- | sbin/ifconfig/ifbridge.c | 92 | ||||
-rw-r--r-- | sys/net/bridgestp.c | 36 | ||||
-rw-r--r-- | sys/net/bridgestp.h | 3 | ||||
-rw-r--r-- | sys/net/if_bridge.c | 77 | ||||
-rw-r--r-- | sys/net/if_bridgevar.h | 26 |
5 files changed, 130 insertions, 104 deletions
diff --git a/sbin/ifconfig/ifbridge.c b/sbin/ifconfig/ifbridge.c index 1100aab..7d6fb43 100644 --- a/sbin/ifconfig/ifbridge.c +++ b/sbin/ifconfig/ifbridge.c @@ -61,6 +61,16 @@ static const char rcsid[] = #include "ifconfig.h" +#define PV2ID(pv, epri, eaddr) do { \ + epri = pv >> 48; \ + eaddr[0] = pv >> 40; \ + eaddr[1] = pv >> 32; \ + eaddr[2] = pv >> 24; \ + eaddr[3] = pv >> 16; \ + eaddr[4] = pv >> 8; \ + eaddr[5] = pv >> 0; \ +} while (0) + static const char *stpstates[] = { "disabled", "listening", @@ -193,15 +203,6 @@ bridge_interfaces(int s, const char *prefix) 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"); } } @@ -250,6 +251,8 @@ bridge_status(int s) struct ifbropreq param; u_int16_t pri; u_int8_t ht, fd, ma, hc, pro; + u_int8_t lladdr[ETHER_ADDR_LEN]; + u_int16_t bprio; if (do_cmd(s, BRDGPARAM, ¶m, sizeof(param), 0) < 0) return; @@ -260,9 +263,16 @@ bridge_status(int s) hc = param.ifbop_holdcount; ma = param.ifbop_maxage; - printf("\tpriority %u hellotime %u fwddelay %u" - " maxage %u hc %u proto %s\n", - pri, ht, fd, ma, hc, stpproto[pro]); + PV2ID(param.ifbop_bridgeid, bprio, lladdr); + printf("\tid %s priority %u hellotime %u fwddelay %u\n", + ether_ntoa((struct ether_addr *)lladdr), pri, ht, fd); + printf("\tmaxage %u holdcnt %u proto %s\n", + ma, hc, stpproto[pro]); + + PV2ID(param.ifbop_designated_root, bprio, lladdr); + printf("\troot id %s priority %d ifcost %u port %u\n", + ether_ntoa((struct ether_addr *)lladdr), bprio, + param.ifbop_root_path_cost, param.ifbop_root_port & 0xfff); bridge_interfaces(s, "\tmember: "); @@ -373,49 +383,49 @@ 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); + do_bridgeflag(s, val, IFBIF_BSTP_EDGE, 1); } 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); + do_bridgeflag(s, val, IFBIF_BSTP_EDGE, 0); } 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); + do_bridgeflag(s, val, IFBIF_BSTP_AUTOEDGE, 1); } static void unsetbridge_autoedge(const char *val, int d, int s, const struct afswtch *afp) { - struct ifbreq req; + do_bridgeflag(s, val, IFBIF_BSTP_AUTOEDGE, 0); +} - 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_p2p(const char *val, int d, int s, const struct afswtch *afp) +{ + do_bridgeflag(s, val, IFBIF_BSTP_P2P, 1); +} + +static void +unsetbridge_p2p(const char *val, int d, int s, const struct afswtch *afp) +{ + do_bridgeflag(s, val, IFBIF_BSTP_P2P, 0); +} + +static void +setbridge_autop2p(const char *val, int d, int s, const struct afswtch *afp) +{ + do_bridgeflag(s, val, IFBIF_BSTP_AUTOP2P, 1); +} + +static void +unsetbridge_autop2p(const char *val, int d, int s, const struct afswtch *afp) +{ + do_bridgeflag(s, val, IFBIF_BSTP_AUTOP2P, 0); } static void @@ -663,6 +673,10 @@ static struct cmd bridge_cmds[] = { DEF_CMD_ARG("-edge", unsetbridge_edge), DEF_CMD_ARG("autoedge", setbridge_autoedge), DEF_CMD_ARG("-autoedge", unsetbridge_autoedge), + DEF_CMD_ARG("p2p", setbridge_p2p), + DEF_CMD_ARG("-p2p", unsetbridge_p2p), + DEF_CMD_ARG("autop2p", setbridge_autop2p), + DEF_CMD_ARG("-autop2p", unsetbridge_autop2p), DEF_CMD("flush", 0, setbridge_flush), DEF_CMD("flushall", 0, setbridge_flushall), DEF_CMD_ARG2("static", setbridge_static), diff --git a/sys/net/bridgestp.c b/sys/net/bridgestp.c index eff97da..d255de0 100644 --- a/sys/net/bridgestp.c +++ b/sys/net/bridgestp.c @@ -1658,6 +1658,33 @@ bstp_set_autoedge(struct bstp_port *bp, int set) BSTP_UNLOCK(bs); return (0); } + +int +bstp_set_p2p(struct bstp_port *bp, int set) +{ + struct bstp_state *bs = bp->bp_bs; + + BSTP_LOCK(bs); + bp->bp_p2p_link = set; + BSTP_UNLOCK(bs); + return (0); +} + +int +bstp_set_autop2p(struct bstp_port *bp, int set) +{ + struct bstp_state *bs = bp->bp_bs; + + BSTP_LOCK(bs); + if (set) { + bp->bp_flags |= BSTP_PORT_AUTOP2P; + bstp_ifupdstatus(bs, bp); + } else + bp->bp_flags &= ~BSTP_PORT_AUTOP2P; + BSTP_UNLOCK(bs); + return (0); +} + /* * Calculate the path cost according to the link speed. */ @@ -1675,7 +1702,7 @@ bstp_calc_path_cost(struct bstp_port *bp) return (BSTP_DEFAULT_PATH_COST); /* formula from section 17.14, IEEE Std 802.1D-2004 */ - path_cost = 20000000000 / (ifp->if_baudrate / 1000); + path_cost = 20000000000ULL / (ifp->if_baudrate / 1000); if (path_cost > BSTP_MAX_PATH_COST) path_cost = BSTP_MAX_PATH_COST; @@ -1774,7 +1801,10 @@ bstp_ifupdstatus(struct bstp_state *bs, struct bstp_port *bp) if ((error == 0) && (ifp->if_flags & IFF_UP)) { if (ifmr.ifm_status & IFM_ACTIVE) { /* A full-duplex link is assumed to be point to point */ - bp->bp_p2p_link = ifmr.ifm_active & IFM_FDX ? 1 : 0; + if (bp->bp_flags & BSTP_PORT_AUTOP2P) { + bp->bp_p2p_link = + ifmr.ifm_active & IFM_FDX ? 1 : 0; + } if (bp->bp_role == BSTP_ROLE_DISABLED) bstp_enable_port(bs, bp); @@ -2126,7 +2156,7 @@ bstp_create(struct bstp_state *bs, struct bstp_port *bp, struct ifnet *ifp) /* Init state */ bp->bp_infois = BSTP_INFO_DISABLED; - bp->bp_flags = BSTP_PORT_AUTOEDGE; + bp->bp_flags = BSTP_PORT_AUTOEDGE|BSTP_PORT_AUTOP2P; bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING); bstp_set_port_proto(bp, bs->bs_protover); bstp_set_port_role(bp, BSTP_ROLE_DISABLED); diff --git a/sys/net/bridgestp.h b/sys/net/bridgestp.h index 8e09cf9..9ebe354 100644 --- a/sys/net/bridgestp.h +++ b/sys/net/bridgestp.h @@ -108,6 +108,7 @@ #define BSTP_PORT_DISPUTED 0x0004 #define BSTP_PORT_ADMCOST 0x0008 #define BSTP_PORT_AUTOEDGE 0x0010 +#define BSTP_PORT_AUTOP2P 0x0020 /* BPDU priority */ #define BSTP_PDU_SUPERIOR 1 @@ -382,6 +383,8 @@ int bstp_set_port_priority(struct bstp_port *, int); int bstp_set_path_cost(struct bstp_port *, uint32_t); int bstp_set_edge(struct bstp_port *, int); int bstp_set_autoedge(struct bstp_port *, int); +int bstp_set_p2p(struct bstp_port *, int); +int bstp_set_autop2p(struct bstp_port *, int); struct mbuf *bstp_input(struct bstp_port *, struct ifnet *, struct mbuf *); #endif /* _KERNEL */ diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 068ade7..c88ec83 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -309,8 +309,6 @@ static int bridge_ioctl_grte(struct bridge_softc *, void *); static int bridge_ioctl_gifsstp(struct bridge_softc *, void *); static int bridge_ioctl_sproto(struct bridge_softc *, void *); static int bridge_ioctl_stxhc(struct bridge_softc *, void *); -static int bridge_ioctl_sedge(struct bridge_softc *, void *); -static int bridge_ioctl_saedge(struct bridge_softc *, void *); static int bridge_pfil(struct mbuf **, struct ifnet *, struct ifnet *, int); static int bridge_ip_checkbasic(struct mbuf **mp); @@ -430,12 +428,6 @@ const struct bridge_control bridge_control_table[] = { { bridge_ioctl_stxhc, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER }, - - { bridge_ioctl_sedge, sizeof(struct ifbreq), - BC_F_COPYIN|BC_F_SUSER }, - - { bridge_ioctl_saedge, sizeof(struct ifbreq), - BC_F_COPYIN|BC_F_SUSER }, }; const int bridge_control_table_size = sizeof(bridge_control_table) / sizeof(bridge_control_table[0]); @@ -662,6 +654,7 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) struct ifbareq ifbareq; struct ifbaconf ifbaconf; struct ifbrparam ifbrparam; + struct ifbropreq ifbropreq; } args; struct ifdrv *ifd = (struct ifdrv *) data; const struct bridge_control *bc; @@ -1021,10 +1014,16 @@ bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg) req->ifbr_proto = bp->bp_protover; req->ifbr_role = bp->bp_role; req->ifbr_stpflags = bp->bp_flags; - req->ifbr_edge = bp->bp_operedge; - req->ifbr_autoedge = (bp->bp_flags & BSTP_PORT_AUTOEDGE) ? 1 : 0; - req->ifbr_p2p = bp->bp_p2p_link; + /* Copy STP state options as flags */ + if (bp->bp_operedge) + req->ifbr_ifsflags |= IFBIF_BSTP_EDGE; + if (bp->bp_flags & BSTP_PORT_AUTOEDGE) + req->ifbr_ifsflags |= IFBIF_BSTP_AUTOEDGE; + if (bp->bp_p2p_link) + req->ifbr_ifsflags |= IFBIF_BSTP_P2P; + if (bp->bp_flags & BSTP_PORT_AUTOP2P) + req->ifbr_ifsflags |= IFBIF_BSTP_AUTOP2P; return (0); } @@ -1033,11 +1032,13 @@ bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg) { struct ifbreq *req = arg; struct bridge_iflist *bif; + struct bstp_port *bp; int error; bif = bridge_lookup_member(sc, req->ifbr_ifsname); if (bif == NULL) return (ENOENT); + bp = &bif->bif_stp; if (req->ifbr_ifsflags & IFBIF_SPAN) /* SPAN is readonly */ @@ -1054,7 +1055,14 @@ bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg) bstp_disable(&bif->bif_stp); } - bif->bif_flags = req->ifbr_ifsflags; + /* Pass on STP flags */ + bstp_set_edge(bp, req->ifbr_ifsflags & IFBIF_BSTP_EDGE ? 1 : 0); + bstp_set_autoedge(bp, req->ifbr_ifsflags & IFBIF_BSTP_AUTOEDGE ? 1 : 0); + bstp_set_p2p(bp, req->ifbr_ifsflags & IFBIF_BSTP_P2P ? 1 : 0); + bstp_set_autop2p(bp, req->ifbr_ifsflags & IFBIF_BSTP_AUTOP2P ? 1 : 0); + + /* Save the bits relating to the bridge */ + bif->bif_flags = req->ifbr_ifsflags & IFBIFMASK; return (0); } @@ -1085,7 +1093,6 @@ bridge_ioctl_gifs(struct bridge_softc *sc, void *arg) { struct ifbifconf *bifc = arg; struct bridge_iflist *bif; - struct bstp_port *bp; struct ifbreq breq; int count, len, error = 0; @@ -1109,18 +1116,10 @@ bridge_ioctl_gifs(struct bridge_softc *sc, void *arg) strlcpy(breq.ifbr_ifsname, bif->bif_ifp->if_xname, sizeof(breq.ifbr_ifsname)); - bp = &bif->bif_stp; - breq.ifbr_ifsflags = bif->bif_flags; - breq.ifbr_state = bp->bp_state; - breq.ifbr_priority = bp->bp_priority; - breq.ifbr_path_cost = bp->bp_path_cost; - breq.ifbr_portno = bif->bif_ifp->if_index & 0xfff; - breq.ifbr_proto = bp->bp_protover; - breq.ifbr_role = bp->bp_role; - breq.ifbr_stpflags = bp->bp_flags; - breq.ifbr_edge = bp->bp_operedge; - breq.ifbr_autoedge = (bp->bp_flags & BSTP_PORT_AUTOEDGE) ? 1:0; - breq.ifbr_p2p = bp->bp_p2p_link; + /* Fill in the ifbreq structure */ + error = bridge_ioctl_gifflags(sc, &breq); + if (error) + break; error = copyout(&breq, bifc->ifbic_req + count, sizeof(breq)); if (error) break; @@ -1416,7 +1415,9 @@ bridge_ioctl_gbparam(struct bridge_softc *sc, void *arg) req->ifbop_priority = bs->bs_bridge_priority; req->ifbop_protocol = bs->bs_protover; req->ifbop_root_path_cost = bs->bs_root_pv.pv_cost; + req->ifbop_bridgeid = bs->bs_bridge_pv.pv_dbridge_id; req->ifbop_designated_root = bs->bs_root_pv.pv_root_id; + req->ifbop_designated_bridge = bs->bs_root_pv.pv_dbridge_id; req->ifbop_last_tc_time.tv_sec = bs->bs_last_tc_time.tv_sec; req->ifbop_last_tc_time.tv_usec = bs->bs_last_tc_time.tv_usec; @@ -1499,32 +1500,6 @@ bridge_ioctl_stxhc(struct bridge_softc *sc, void *arg) return (bstp_set_holdcount(&sc->sc_stp, param->ifbrp_txhc)); } -static int -bridge_ioctl_sedge(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); - - return (bstp_set_edge(&bif->bif_stp, req->ifbr_edge)); -} - -static int -bridge_ioctl_saedge(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); - - return (bstp_set_autoedge(&bif->bif_stp, req->ifbr_autoedge)); -} - /* * bridge_ifdetach: * diff --git a/sys/net/if_bridgevar.h b/sys/net/if_bridgevar.h index a5241b9..6a470fe 100644 --- a/sys/net/if_bridgevar.h +++ b/sys/net/if_bridgevar.h @@ -114,8 +114,6 @@ * (ifbpstpconf) */ #define BRDGSPROTO 28 /* set protocol (ifbrparam) */ #define BRDGSTXHC 29 /* set tx hold count (ifbrparam) */ -#define BRDGSEDGE 30 /* set edge status (ifbreq) */ -#define BRDGSAEDGE 31 /* set autoedge status (ifbreq) */ /* * Generic bridge control request. @@ -124,9 +122,6 @@ struct ifbreq { char ifbr_ifsname[IFNAMSIZ]; /* member if name */ uint32_t ifbr_ifsflags; /* member if flags */ uint32_t ifbr_stpflags; /* member if STP flags */ - uint8_t ifbr_edge; /* member if STP edge */ - uint8_t ifbr_autoedge; /* member if STP autoedge */ - uint8_t ifbr_p2p; /* member if STP p2p */ uint32_t ifbr_path_cost; /* member if STP cost */ uint8_t ifbr_portno; /* member if port number */ uint8_t ifbr_priority; /* member if STP priority */ @@ -136,13 +131,20 @@ struct ifbreq { }; /* BRDGGIFFLAGS, BRDGSIFFLAGS */ -#define IFBIF_LEARNING 0x01 /* if can learn */ -#define IFBIF_DISCOVER 0x02 /* if sends packets w/ unknown dest. */ -#define IFBIF_STP 0x04 /* if participates in spanning tree */ -#define IFBIF_SPAN 0x08 /* if is a span port */ -#define IFBIF_STICKY 0x10 /* if learned addresses stick */ +#define IFBIF_LEARNING 0x0001 /* if can learn */ +#define IFBIF_DISCOVER 0x0002 /* if sends packets w/ unknown dest. */ +#define IFBIF_STP 0x0004 /* if participates in spanning tree */ +#define IFBIF_SPAN 0x0008 /* if is a span port */ +#define IFBIF_STICKY 0x0010 /* if learned addresses stick */ +#define IFBIF_BSTP_EDGE 0x0020 /* member stp edge port */ +#define IFBIF_BSTP_AUTOEDGE 0x0040 /* member stp autoedge enabled */ +#define IFBIF_BSTP_P2P 0x0080 /* member stp p2p */ +#define IFBIF_BSTP_AUTOP2P 0x0100 /* member stp autop2p enabled */ -#define IFBIFBITS "\020\1LEARNING\2DISCOVER\3STP\4SPAN\5STICKY" +#define IFBIFBITS "\020\001LEARNING\002DISCOVER\003STP\004SPAN" \ + "\005STICKY\006EDGE\007AUTOEDGE\010P2P\011AUTOP2P" +#define IFBIFMASK ~(IFBIF_BSTP_EDGE|IFBIF_BSTP_AUTOEDGE|IFBIF_BSTP_P2P| \ + IFBIF_BSTP_AUTOP2P) /* not saved */ /* BRDGFLUSH */ #define IFBF_FLUSHDYN 0x00 /* flush learned addresses only */ @@ -223,7 +225,9 @@ struct ifbropreq { uint16_t ifbop_priority; uint16_t ifbop_root_port; uint32_t ifbop_root_path_cost; + uint64_t ifbop_bridgeid; uint64_t ifbop_designated_root; + uint64_t ifbop_designated_bridge; struct timeval ifbop_last_tc_time; }; |