Pantek Library
Hosting Provided By
CybrHost
High Speed Hosting

VLAN related panics in 3.2

From: Chris Pascoe <c.pascoe(at)itee.uq.edu.au>
Date: Thu Jan 30 2003 - 05:32:59 EST


Hello,

Attached is a patch which fixes bugs in the VLAN multicast handling code. It should apply against 3.2-stable and -current. I think this patch will address the errors/panic seen in bug number 3007.

Problems fixed:

  • Memory corruption in (leading to panic) when vlans and ipv6 are enabled. The system was copying a struct sockaddr (when recording what multicast addresses are in use so it can free them later) into a malloc'd space that was only big enough for an ethernet address. Changed the target variable to hold a struct sockaddr_storage which is guaranteed to be large enough.
  • Multicast lists would not be purged correctly at interface deconfiguration time. When passing the multicast address that should be removed to the parent interface, an incomplete length would be passed for non-ipv4 multicast addresses. Similar problems to the first bug.
  • Multicast list initialised incorrectly every time the vlan interface's if_start method is called. This causes a memory leak for every multicast address registered and incorrect reference counts on the parent interface - so a multicast address may never be removed from the parent's multicast filters. Moved this initialisation to occur at interface creation time.
  • Multicast addresses would never be registered on the parent interfaces. The NetBSD codebase (where the most recent vlan changes were ported from) handle SIOCADDMULTI in its ether_ioctl function and uses this to register multicast addresses on the parent. On OpenBSD the parent's if_ioctl must be called directly.

Regards,
Chris

--
Christopher Pascoe
IT Infrastructure Manager
School of Information Technology and Electrical Engineering
The University of Queensland   Brisbane  QLD  4072  Australia
Index: sys/net/if_vlan_var.h
===================================================================
RCS file:
/cvs/src/sys/net/if_vlan_var.h,v
retrieving revision 1.8
diff -u -r1.8
if_vlan_var.h
--- sys/net/if_vlan_var.h	12 Jun 2002 01:42:29 -0000	1.8
+++
sys/net/if_vlan_var.h	30 Jan 2003 10:14:16 -0000

@@ -42,7 +42,7 @@
union { struct ether_multi *mcu_enm; } mc_u; - struct ether_addr mc_addr; + struct sockaddr_storage mc_addr; }; struct ifvlan { Index: sys/net/if_vlan.c =================================================================== RCS file: /cvs/src/sys/net/if_vlan.c,v retrieving revision 1.32 diff -u -r1.32 if_vlan.c --- sys/net/if_vlan.c 12 Jun 2002 01:42:29 -0000 1.32 +++ sys/net/if_vlan.c 30 Jan 2003 10:14:29 -0000
@@ -110,6 +110,7 @@
bzero(ifv_softc, nifvlan * sizeof(struct ifvlan)); for (i = 0; i < nifvlan; i++) { + LIST_INIT(&ifv_softc[i].vlan_mc_listhead); ifp = &ifv_softc[i].ifv_if; ifp->if_softc = &ifv_softc[i]; sprintf(ifp->if_xname, "vlan%d", i); @@ -141,7 +142,6 @@ ifv = ifp->if_softc; p = ifv->ifv_p; - LIST_INIT(&ifv->vlan_mc_listhead); ifp->if_flags |= IFF_OACTIVE; for (;;) {
@@ -640,6 +640,7 @@
int vlan_ether_addmulti(struct ifvlan *ifv, struct ifreq *ifr) { + struct ifnet *ifp = ifv->ifv_p; /* Parent. */ struct vlan_mc_entry *mc; u_int8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; int error;
@@ -672,10 +673,10 @@
memcpy(&mc->mc_addr, &ifr->ifr_addr, ifr->ifr_addr.sa_len); LIST_INSERT_HEAD(&ifv->vlan_mc_listhead, mc, mc_entries); - error = ether_ioctl(ifv->ifv_p, &ifv->ifv_ac, SIOCADDMULTI, - (caddr_t)ifr); + error = (*ifp->if_ioctl)(ifp, SIOCADDMULTI, (caddr_t)ifr); if (error != 0)
Do you need help?X
goto ioctl_failed; + return (error); ioctl_failed:
@@ -683,12 +684,14 @@
FREE(mc, M_DEVBUF); alloc_failed: (void)ether_delmulti(ifr, (struct arpcom *)&ifv->ifv_ac); + return (error); } int vlan_ether_delmulti(struct ifvlan *ifv, struct ifreq *ifr) { + struct ifnet *ifp = ifv->ifv_p; /* Parent. */ struct ether_multi *enm; struct vlan_mc_entry *mc; u_int8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN];
@@ -707,8 +710,7 @@
return (error); /* We no longer use this multicast address. Tell parent so. */ - error = ether_ioctl(ifv->ifv_p, &ifv->ifv_ac, SIOCDELMULTI, - (caddr_t)ifr); + error = (*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)ifr); if (error == 0) { /* And forget about this address. */ for (mc = LIST_FIRST(&ifv->vlan_mc_listhead); mc != NULL;
@@ -745,7 +747,7 @@
memcpy(ifr->ifr_name, ifp->if_xname, IFNAMSIZ); while ((mc = LIST_FIRST(&ifv->vlan_mc_listhead)) != NULL) { - memcpy(&ifr->ifr_addr, &mc->mc_addr, ETHER_ADDR_LEN); + memcpy(&ifr->ifr_addr, &mc->mc_addr, mc->mc_addr.ss_len); (void)(*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)ifr); LIST_REMOVE(mc, mc_entries); FREE(mc, M_DEVBUF);
Received on Thu Jan 30 05:35:04 2003

This archive was generated by hypermail 2.1.8 : Wed Aug 23 2006 - 13:29:48 EDT


Contact Us  Legal Notices  Order Services Online 
Pantek Home  Privacy Policy  IT news  Site Map  Pantek Library