summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Pfatschbacher <mpf@cvs.openbsd.org>2005-04-20 23:02:23 +0000
committerMarco Pfatschbacher <mpf@cvs.openbsd.org>2005-04-20 23:02:23 +0000
commit572d3058c355bfe59cc3664582319393ca50e9c3 (patch)
treed1905470aa59b1a9a28a19d05fcc9e68a1bd7fc8
parent3040ff520d8c53f7587470475ccf7770c5ab6eed (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.c21
-rw-r--r--sys/net/if_vlan_var.h3
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