Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Add the notion of "cloning" of network pseudo-interface ...



details:   https://anonhg.NetBSD.org/src/rev/21edb3e40b68
branches:  trunk
changeset: 494107:21edb3e40b68
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Sun Jul 02 00:20:48 2000 +0000

description:
Add the notion of "cloning" of network pseudo-interface (e.g. `gif').
This allows them to be created and destroyed on the fly via ifconfig(8),
rather than specifying the count in the kernel configuration file.

diffstat:

 sys/net/if.c     |  120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 sys/net/if.h     |   24 ++++++++++-
 sys/sys/sockio.h |    5 +-
 3 files changed, 146 insertions(+), 3 deletions(-)

diffs (210 lines):

diff -r 61ee2eed0ed3 -r 21edb3e40b68 sys/net/if.c
--- a/sys/net/if.c      Sat Jul 01 21:52:05 2000 +0000
+++ b/sys/net/if.c      Sun Jul 02 00:20:48 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if.c,v 1.62 2000/04/26 13:38:13 bouyer Exp $   */
+/*     $NetBSD: if.c,v 1.63 2000/07/02 00:20:48 thorpej Exp $  */
 
 /*-
  * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@@ -147,6 +147,10 @@
 
 int    if_rt_walktree __P((struct radix_node *, void *));
 
+struct if_clone *if_clone_lookup __P((const char *, int *));
+
+LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
+
 /*
  * Network interface utility routines.
  *
@@ -480,6 +484,112 @@
 }
 
 /*
+ * Create a clone network interface.
+ */
+int
+if_clone_create(name)
+       const char *name;
+{
+       struct if_clone *ifc;
+       int unit;
+
+       ifc = if_clone_lookup(name, &unit);
+       if (ifc == NULL)
+               return (EINVAL);
+
+       if (ifunit(name) != NULL)
+               return (EEXIST);
+
+       return ((*ifc->ifc_create)(ifc, unit));
+}
+
+/*
+ * Destroy a clone network interface.
+ */
+int
+if_clone_destroy(name)
+       const char *name;
+{
+       struct if_clone *ifc;
+       struct ifnet *ifp;
+
+       ifc = if_clone_lookup(name, NULL);
+       if (ifc == NULL)
+               return (EINVAL);
+
+       ifp = ifunit(name);
+       if (ifp == NULL)
+               return (ENXIO);
+
+       if (ifc->ifc_destroy == NULL)
+               return (EOPNOTSUPP);
+
+       (*ifc->ifc_destroy)(ifp);
+       return (0);
+}
+
+/*
+ * Look up a network interface cloner.
+ */
+struct if_clone *
+if_clone_lookup(name, unitp)
+       const char *name;
+       int *unitp;
+{
+       struct if_clone *ifc;
+       const char *cp;
+       int i;
+
+       for (ifc = LIST_FIRST(&if_cloners); ifc != NULL;) {
+               for (cp = name, i = 0; i < ifc->ifc_namelen; i++, cp++) {
+                       if (ifc->ifc_name[i] != *cp)
+                               goto next_ifc;
+               }
+               goto found_name;
+ next_ifc:
+               ifc = LIST_NEXT(ifc, ifc_list);
+       }
+
+       /* No match. */
+       return (NULL);
+
+ found_name:
+       for (i = 0; *cp != '\0'; cp++) {
+               if (*cp < '0' || *cp > '9') {
+                       /* Bogus unit number. */
+                       return (NULL);
+               }
+               i = (i * 10) + (*cp - '0');
+       }
+
+       if (unitp != NULL)
+               *unitp = i;
+       return (ifc);
+}
+
+/*
+ * Register a network interface cloner.
+ */
+void
+if_clone_attach(ifc)
+       struct if_clone *ifc;
+{
+
+       LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
+}
+
+/*
+ * Unregister a network interface cloner.
+ */
+void
+if_clone_detach(ifc)
+       struct if_clone *ifc;
+{
+
+       LIST_REMOVE(ifc, ifc_list);
+}
+
+/*
  * Locate an interface based on a complete address.
  */
 /*ARGSUSED*/
@@ -860,6 +970,14 @@
                return (ifconf(cmd, data));
        }
        ifr = (struct ifreq *)data;
+
+       switch (cmd) {
+       case SIOCIFCREATE:
+               return (if_clone_create(ifr->ifr_name));
+       case SIOCIFDESTROY:
+               return (if_clone_destroy(ifr->ifr_name));
+       }
+
        ifp = ifunit(ifr->ifr_name);
        if (ifp == 0)
                return (ENXIO);
diff -r 61ee2eed0ed3 -r 21edb3e40b68 sys/net/if.h
--- a/sys/net/if.h      Sat Jul 01 21:52:05 2000 +0000
+++ b/sys/net/if.h      Sun Jul 02 00:20:48 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if.h,v 1.50 2000/05/15 16:59:37 itojun Exp $   */
+/*     $NetBSD: if.h,v 1.51 2000/07/02 00:20:49 thorpej Exp $  */
 
 /*-
  * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@@ -114,6 +114,22 @@
 struct rtentry;
 struct socket;
 struct ether_header;
+struct ifnet;
+
+/*
+ * Structure describing a `cloning' interface.
+ */
+struct if_clone {
+       LIST_ENTRY(if_clone) ifc_list;  /* on list of cloners */
+       const char *ifc_name;           /* name of device, e.g. `gif' */
+       size_t ifc_namelen;             /* length of name */
+
+       int     (*ifc_create)(struct if_clone *, int);
+       void    (*ifc_destroy)(struct ifnet *);
+};
+
+#define        IF_CLONE_INITIALIZER(name, create, destroy)                     \
+       { { 0 }, name, sizeof(name) - 1, create, destroy }
 
 /*
  * Structure defining statistics and other data kept regarding a network
@@ -582,6 +598,12 @@
 void   ifafree __P((struct ifaddr *));
 void   link_rtrequest __P((int, struct rtentry *, struct sockaddr *));
 
+void   if_clone_attach __P((struct if_clone *));
+void   if_clone_detach __P((struct if_clone *));
+
+int    if_clone_create __P((const char *));
+int    if_clone_destroy __P((const char *));
+
 int    loioctl __P((struct ifnet *, u_long, caddr_t));
 void   loopattach __P((int));
 int    looutput __P((struct ifnet *,
diff -r 61ee2eed0ed3 -r 21edb3e40b68 sys/sys/sockio.h
--- a/sys/sys/sockio.h  Sat Jul 01 21:52:05 2000 +0000
+++ b/sys/sys/sockio.h  Sun Jul 02 00:20:48 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sockio.h,v 1.11 2000/05/13 07:55:05 itojun Exp $       */
+/*     $NetBSD: sockio.h,v 1.12 2000/07/02 00:20:49 thorpej Exp $      */
 
 /*-
  * Copyright (c) 1982, 1986, 1990, 1993, 1994
@@ -99,4 +99,7 @@
                                                           parameters */
 #define SIOCGDRVSPEC    _IOWR('i', 123, struct ifdrv)   /* get driver-specific
                                                           parameters */
+#define        SIOCIFCREATE     _IOW('i', 122, struct ifreq)   /* create clone if */
+#define        SIOCIFDESTROY    _IOW('i', 121, struct ifreq)   /* destroy clone if */
+
 #endif /* !_SYS_SOCKIO_H_ */



Home | Main Index | Thread Index | Old Index