diff options
author | Marco Pfatschbacher <mpf@cvs.openbsd.org> | 2005-04-20 23:02:23 +0000 |
---|---|---|
committer | Marco Pfatschbacher <mpf@cvs.openbsd.org> | 2005-04-20 23:02:23 +0000 |
commit | 572d3058c355bfe59cc3664582319393ca50e9c3 (patch) | |
tree | d1905470aa59b1a9a28a19d05fcc9e68a1bd7fc8 | |
parent | 3040ff520d8c53f7587470475ccf7770c5ab6eed (diff) |
Make vlan(4) aware of its physical interface link state.
Changes are reported to userland and to other
interfaces sitting on top of us.
OK henning@, camield@
Tested by camield@ and Alexey E. Suslikov
-rw-r--r-- | sys/net/if_vlan.c | 21 | ||||
-rw-r--r-- | sys/net/if_vlan_var.h | 3 |
2 files changed, 22 insertions, 2 deletions
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index 8d4b1fe7da9..dfb34bc08f7 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vlan.c,v 1.51 2005/04/18 04:07:17 brad Exp $ */ +/* $OpenBSD: if_vlan.c,v 1.52 2005/04/20 23:02:22 mpf Exp $ */ /* * Copyright 1998 Massachusetts Institute of Technology * @@ -90,6 +90,7 @@ void vlan_start (struct ifnet *ifp); int vlan_ioctl (struct ifnet *ifp, u_long cmd, caddr_t addr); int vlan_unconfig (struct ifnet *ifp); int vlan_config (struct ifvlan *, struct ifnet *, u_int16_t); +void vlan_vlandev_state(void *); void vlanattach (int count); int vlan_set_promisc (struct ifnet *ifp); int vlan_ether_addmulti(struct ifvlan *, struct ifreq *); @@ -467,6 +468,11 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, u_int16_t tag) ifv->ifv_tag = tag; s = splnet(); LIST_INSERT_HEAD(&vlan_tagh[TAG_HASH(tag)], ifv, ifv_list); + + /* Register callback for physical link state changes */ + ifv->lh_cookie = hook_establish(p->if_linkstatehooks, 1, + vlan_vlandev_state, ifv); + vlan_vlandev_state(ifv); splx(s); return 0; @@ -505,6 +511,7 @@ vlan_unconfig(struct ifnet *ifp) /* Disconnect from parent. */ ifv->ifv_p = NULL; ifv->ifv_if.if_mtu = ETHERMTU; + hook_disestablish(p->if_linkstatehooks, ifv->lh_cookie); /* Clear our MAC address. */ ifa = ifnet_addrs[ifv->ifv_if.if_index]; @@ -517,6 +524,18 @@ vlan_unconfig(struct ifnet *ifp) return 0; } +void +vlan_vlandev_state(void *v) +{ + struct ifvlan *ifv = v; + + if (ifv->ifv_if.if_link_state == ifv->ifv_p->if_link_state) + return; + + ifv->ifv_if.if_link_state = ifv->ifv_p->if_link_state; + if_link_state_change(&ifv->ifv_if); +} + int vlan_set_promisc(struct ifnet *ifp) { diff --git a/sys/net/if_vlan_var.h b/sys/net/if_vlan_var.h index cefe543a032..9277f1bbd83 100644 --- a/sys/net/if_vlan_var.h +++ b/sys/net/if_vlan_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vlan_var.h,v 1.12 2005/04/17 23:02:02 brad Exp $ */ +/* $OpenBSD: if_vlan_var.h,v 1.13 2005/04/20 23:02:22 mpf Exp $ */ /* * Copyright 1998 Massachusetts Institute of Technology @@ -56,6 +56,7 @@ struct ifvlan { LIST_HEAD(__vlan_mchead, vlan_mc_entry) vlan_mc_listhead; LIST_ENTRY(ifvlan) ifv_list; int ifv_flags; + void *lh_cookie; }; #define ifv_if ifv_ac.ac_if |