summaryrefslogtreecommitdiffstats
path: root/sys/net/if_vlan.c
diff options
context:
space:
mode:
authorandre <andre@FreeBSD.org>2004-05-03 13:48:35 +0000
committerandre <andre@FreeBSD.org>2004-05-03 13:48:35 +0000
commit25ae331e1251bd9562a10f53fdb2f054f7b21dfe (patch)
tree26d69d96320d4278394e06ff25df74de9314a2fc /sys/net/if_vlan.c
parentf8ee348f1d1b903d0b117c893b5f73aed4e5bce8 (diff)
downloadFreeBSD-src-25ae331e1251bd9562a10f53fdb2f054f7b21dfe.zip
FreeBSD-src-25ae331e1251bd9562a10f53fdb2f054f7b21dfe.tar.gz
Link state change notification of ethernet media to the routing socket.
o Extend the if_data structure with an ifi_link_state field and provide the corresponding defines for the valid states. o The mii_linkchg() callback updates the ifi_link_state field and calls rt_ifmsg() to notify listeners on the routing socket in addition to the kqueue KNOTE. o If vlans are configured on a physical interface notify and update all vlan pseudo devices as well with the vlan_link_state() callback. No objections by: sam, wpaul, ru, bms Brucification by: bde
Diffstat (limited to 'sys/net/if_vlan.c')
-rw-r--r--sys/net/if_vlan.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index 87eabb7..25ca790 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -125,6 +125,7 @@ static int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr);
static int vlan_setmulti(struct ifnet *ifp);
static int vlan_unconfig(struct ifnet *ifp);
static int vlan_config(struct ifvlan *ifv, struct ifnet *p);
+static void vlan_link_state(struct ifnet *ifp, int link);
struct if_clone vlan_cloner = IF_CLONE_INITIALIZER(VLANNAME,
vlan_clone_create, vlan_clone_destroy, 0, IF_MAXUNIT);
@@ -209,6 +210,9 @@ vlan_setmulti(struct ifnet *ifp)
*/
extern void (*vlan_input_p)(struct ifnet *, struct mbuf *);
+/* For MII eyes only... */
+extern void (*vlan_link_state_p)(struct ifnet *, int);
+
static int
vlan_modevent(module_t mod, int type, void *data)
{
@@ -218,11 +222,13 @@ vlan_modevent(module_t mod, int type, void *data)
LIST_INIT(&ifv_list);
VLAN_LOCK_INIT();
vlan_input_p = vlan_input;
+ vlan_link_state_p = vlan_link_state;
if_clone_attach(&vlan_cloner);
break;
case MOD_UNLOAD:
if_clone_detach(&vlan_cloner);
vlan_input_p = NULL;
+ vlan_link_state_p = NULL;
while (!LIST_EMPTY(&ifv_list))
vlan_clone_destroy(&LIST_FIRST(&ifv_list)->ifv_if);
VLAN_LOCK_DESTROY();
@@ -532,6 +538,7 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p)
*/
ifv->ifv_if.if_flags = (p->if_flags &
(IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX | IFF_POINTOPOINT));
+ ifv->ifv_if.if_link_state = p->if_link_state;
/*
* If the parent interface can do hardware-assisted
@@ -622,6 +629,7 @@ vlan_unconfig(struct ifnet *ifp)
ifv->ifv_p = NULL;
ifv->ifv_if.if_mtu = ETHERMTU; /* XXX why not 0? */
ifv->ifv_flags = 0;
+ ifv->ifv_if.if_link_state = LINK_STATE_UNKNOWN;
/* Clear our MAC address. */
ifa = ifaddr_byindex(ifv->ifv_if.if_index);
@@ -657,6 +665,23 @@ vlan_set_promisc(struct ifnet *ifp)
return (error);
}
+/* Inform all vlans that their parent has changed link state */
+static void
+vlan_link_state(struct ifnet *ifp, int link)
+{
+ struct ifvlan *ifv;
+
+ VLAN_LOCK();
+ LIST_FOREACH(ifv, &ifv_list, ifv_list) {
+ if (ifv->ifv_p == ifp) {
+ ifv->ifv_if.if_link_state = ifv->ifv_p->if_link_state;
+ rt_ifmsg(&(ifv->ifv_if));
+ KNOTE(&ifp->if_klist, link);
+ }
+ }
+ VLAN_UNLOCK();
+}
+
static int
vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
OpenPOWER on IntegriCloud