summaryrefslogtreecommitdiffstats
path: root/sys/net/if_vlan.c
diff options
context:
space:
mode:
authoryar <yar@FreeBSD.org>2004-05-25 14:30:12 +0000
committeryar <yar@FreeBSD.org>2004-05-25 14:30:12 +0000
commitbd82e3f62a435a5344e625c8f159c51f44e6a16c (patch)
tree3f2b0a83b3ed903462f906ee4d7ebb96b15a804e /sys/net/if_vlan.c
parentc1fe0e4c6c5ef780884fb08a839394690ee9223b (diff)
downloadFreeBSD-src-bd82e3f62a435a5344e625c8f159c51f44e6a16c.zip
FreeBSD-src-bd82e3f62a435a5344e625c8f159c51f44e6a16c.tar.gz
After all the relevant drivers have been fixed, fix vlan(4) itself
WRT manipulating capabilities of the parent interface: - use ioctl(SIOCSIFCAP) to toggle VLAN_MTU (the way that was done before was just wrong); - use the right order of conditional clauses to set the MTU fudge (that is logically independent from toggling VLAN_MTU.)
Diffstat (limited to 'sys/net/if_vlan.c')
-rw-r--r--sys/net/if_vlan.c54
1 files changed, 27 insertions, 27 deletions
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index 187ee9e..21809c7 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -498,30 +498,31 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p)
/*
* If the parent supports the VLAN_MTU capability,
* i.e. can Tx/Rx larger than ETHER_MAX_LEN frames,
- * enable it.
+ * use it.
+ * First of all, enable Tx/Rx of such extended frames on the
+ * parent if it's disabled and we're the first to attach.
*/
p->if_nvlans++;
- if (p->if_nvlans == 1 && (p->if_capabilities & IFCAP_VLAN_MTU) != 0) {
+ if (p->if_nvlans == 1 &&
+ (p->if_capabilities & IFCAP_VLAN_MTU) &&
+ (p->if_capenable & IFCAP_VLAN_MTU) == 0) {
+ struct ifreq ifr;
+ int error;
+
+ ifr.ifr_reqcap = p->if_capenable | IFCAP_VLAN_MTU;
+ error = (*p->if_ioctl)(p, SIOCSIFCAP, (caddr_t) &ifr);
+ if (error) {
+ p->if_nvlans--;
+ return (error);
+ }
+ }
+ if (p->if_capenable & IFCAP_VLAN_MTU) {
/*
- * Enable Tx/Rx of VLAN-sized frames.
+ * No need to fudge the MTU since the parent can
+ * handle extended frames.
*/
- p->if_capenable |= IFCAP_VLAN_MTU;
- if (p->if_flags & IFF_UP) {
- struct ifreq ifr;
- int error;
-
- ifr.ifr_flags = p->if_flags;
- error = (*p->if_ioctl)(p, SIOCSIFFLAGS,
- (caddr_t) &ifr);
- if (error) {
- p->if_nvlans--;
- if (p->if_nvlans == 0)
- p->if_capenable &= ~IFCAP_VLAN_MTU;
- return (error);
- }
- }
ifv->ifv_mtufudge = 0;
- } else if ((p->if_capabilities & IFCAP_VLAN_MTU) == 0) {
+ } else {
/*
* Fudge the MTU by the encapsulation size. This
* makes us incompatible with strictly compliant
@@ -621,16 +622,15 @@ vlan_unconfig(struct ifnet *ifp)
p->if_nvlans--;
if (p->if_nvlans == 0) {
+ struct ifreq ifr;
+
/*
- * Disable Tx/Rx of VLAN-sized frames.
+ * Try to disable Tx/Rx of VLAN-sized frames.
+ * This may have no effect for some interfaces,
+ * but only the parent driver knows that.
*/
- p->if_capenable &= ~IFCAP_VLAN_MTU;
- if (p->if_flags & IFF_UP) {
- struct ifreq ifr;
-
- ifr.ifr_flags = p->if_flags;
- (*p->if_ioctl)(p, SIOCSIFFLAGS, (caddr_t) &ifr);
- }
+ ifr.ifr_reqcap = p->if_capenable & ~IFCAP_VLAN_MTU;
+ (*p->if_ioctl)(p, SIOCSIFCAP, (caddr_t) &ifr);
}
}
OpenPOWER on IntegriCloud