summaryrefslogtreecommitdiffstats
path: root/sys/netgraph
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2005-11-04 15:42:01 +0000
committerru <ru@FreeBSD.org>2005-11-04 15:42:01 +0000
commit8a9d6ba9030dfc2edcfe56d57ec03ce610b692de (patch)
tree97434496d40595a0ad1714675dfe4e1102bb43fc /sys/netgraph
parent52caee198230c71e8895ba3639f479f02035678a (diff)
downloadFreeBSD-src-8a9d6ba9030dfc2edcfe56d57ec03ce610b692de.zip
FreeBSD-src-8a9d6ba9030dfc2edcfe56d57ec03ce610b692de.tar.gz
Bring some level of stability to this driver:
- Disallow bundle reconfiguration when virtual interface is running; otherwise, removing a port from a running configuration will cause a panic in the start() method on the next packet on an assumption that a bundle has an even number of ports (2 or 4). - Disallow bringing of virtual interface to a running state when a bundle size is 0; otherwise, adding and then removing the port will similarly cause a panic. - Add missing initialization of fec_ifstat when adding a new port and fix media status reporting when virtual interface isn't yet up (check for fec_status of 1 rather than != 0).
Diffstat (limited to 'sys/netgraph')
-rw-r--r--sys/netgraph/ng_fec.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/sys/netgraph/ng_fec.c b/sys/netgraph/ng_fec.c
index 55da28b..84b5db6 100644
--- a/sys/netgraph/ng_fec.c
+++ b/sys/netgraph/ng_fec.c
@@ -355,6 +355,13 @@ ng_fec_addport(struct ng_fec_private *priv, char *iface)
b = &priv->fec_bundle;
ifp = priv->ifp;
+ /* Only allow reconfiguration if not running. */
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ printf("fec%d: can't add new iface; bundle is running\n",
+ priv->unit);
+ return (EINVAL);
+ }
+
/* Find the interface */
bifp = ifunit(iface);
if (bifp == NULL) {
@@ -443,6 +450,7 @@ ng_fec_addport(struct ng_fec_private *priv, char *iface)
/* Add to the queue */
new->fec_if = bifp;
+ new->fec_ifstat = -1;
TAILQ_INSERT_TAIL(&b->ng_fec_ports, new, fec_list);
return(0);
@@ -463,6 +471,13 @@ ng_fec_delport(struct ng_fec_private *priv, char *iface)
b = &priv->fec_bundle;
ifp = priv->ifp;
+ /* Only allow reconfiguration if not running. */
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ printf("fec%d: can't remove iface; bundle is running\n",
+ priv->unit);
+ return (EINVAL);
+ }
+
/* Find the interface */
bifp = ifunit(iface);
if (bifp == NULL) {
@@ -548,7 +563,7 @@ ng_fec_init(void *arg)
ifp = priv->ifp;
b = &priv->fec_bundle;
- if (b->fec_ifcnt == 1 || b->fec_ifcnt == 3) {
+ if (b->fec_ifcnt != 2 && b->fec_ifcnt != FEC_BUNDLESIZ) {
printf("fec%d: invalid bundle "
"size: %d\n", priv->unit,
b->fec_ifcnt);
@@ -666,7 +681,7 @@ static void ng_fec_ifmedia_sts(struct ifnet *ifp,
ifmr->ifm_status = IFM_AVALID;
TAILQ_FOREACH(p, &b->ng_fec_ports, fec_list) {
- if (p->fec_ifstat) {
+ if (p->fec_ifstat == 1) {
ifmr->ifm_status |= IFM_ACTIVE;
break;
}
@@ -711,7 +726,8 @@ ng_fec_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
if (ifr->ifr_flags & IFF_UP) {
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
/* Sanity. */
- if (b->fec_ifcnt == 1 || b->fec_ifcnt == 3) {
+ if (b->fec_ifcnt != 2 &&
+ b->fec_ifcnt != FEC_BUNDLESIZ) {
printf("fec%d: invalid bundle "
"size: %d\n", priv->unit,
b->fec_ifcnt);
OpenPOWER on IntegriCloud