Author: zec
Date: Fri Aug 13 18:17:32 2010
New Revision: 211283
URL: http://svn.freebsd.org/changeset/base/211283

Log:
  When moving an ethernet ifnet from one vnet to another, destroy the
  associated ng_ether netgraph node in the current vnet, and create a
  new one in the target vnet.
  
  Reviewed by:  julian
  MFC after:    3 days

Modified:
  head/sys/net/if.c
  head/sys/net/if_ethersubr.c

Modified: head/sys/net/if.c
==============================================================================
--- head/sys/net/if.c   Fri Aug 13 15:17:19 2010        (r211282)
+++ head/sys/net/if.c   Fri Aug 13 18:17:32 2010        (r211283)
@@ -956,12 +956,21 @@ if_vmove(struct ifnet *ifp, struct vnet 
         */
        IFNET_WLOCK();
        ifindex_free_locked(ifp->if_index);
+       IFNET_WUNLOCK();
+
+       /*
+        * Perform interface-specific reassignment tasks, if provided by
+        * the driver.
+        */
+       if (ifp->if_reassign != NULL)
+               ifp->if_reassign(ifp, new_vnet, NULL);
 
        /*
         * Switch to the context of the target vnet.
         */
        CURVNET_SET_QUIET(new_vnet);
 
+       IFNET_WLOCK();
        if (ifindex_alloc_locked(&idx) != 0) {
                IFNET_WUNLOCK();
                panic("if_index overflow");

Modified: head/sys/net/if_ethersubr.c
==============================================================================
--- head/sys/net/if_ethersubr.c Fri Aug 13 15:17:19 2010        (r211282)
+++ head/sys/net/if_ethersubr.c Fri Aug 13 18:17:32 2010        (r211283)
@@ -129,6 +129,9 @@ static const u_char etherbroadcastaddr[E
 
 static int ether_resolvemulti(struct ifnet *, struct sockaddr **,
                struct sockaddr *);
+#ifdef VIMAGE
+static void ether_reassign(struct ifnet *, struct vnet *, char *);
+#endif
 
 /* XXX: should be in an arp support file, not here */
 MALLOC_DEFINE(M_ARPCOM, "arpcom", "802.* interface internals");
@@ -944,6 +947,9 @@ ether_ifattach(struct ifnet *ifp, const 
        ifp->if_output = ether_output;
        ifp->if_input = ether_input;
        ifp->if_resolvemulti = ether_resolvemulti;
+#ifdef VIMAGE
+       ifp->if_reassign = ether_reassign;
+#endif
        if (ifp->if_baudrate == 0)
                ifp->if_baudrate = IF_Mbps(10);         /* just a default */
        ifp->if_broadcastaddr = etherbroadcastaddr;
@@ -983,6 +989,25 @@ ether_ifdetach(struct ifnet *ifp)
        if_detach(ifp);
 }
 
+#ifdef VIMAGE
+void
+ether_reassign(struct ifnet *ifp, struct vnet *new_vnet, char *unused __unused)
+{
+
+       if (IFP2AC(ifp)->ac_netgraph != NULL) {
+               KASSERT(ng_ether_detach_p != NULL,
+                   ("ng_ether_detach_p is NULL"));
+               (*ng_ether_detach_p)(ifp);
+       }
+
+       if (ng_ether_attach_p != NULL) {
+               CURVNET_SET_QUIET(new_vnet);
+               (*ng_ether_attach_p)(ifp);
+               CURVNET_RESTORE();
+       }
+}
+#endif
+
 SYSCTL_DECL(_net_link);
 SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet");
 #if defined(INET) || defined(INET6)
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to