From owner-freebsd-audit Tue Jun 26 14:45:24 2001 Delivered-To: freebsd-audit@freebsd.org Received: from odin.ac.hmc.edu (Odin.AC.HMC.Edu [134.173.32.75]) by hub.freebsd.org (Postfix) with ESMTP id 5D49C37B401; Tue, 26 Jun 2001 14:43:16 -0700 (PDT) (envelope-from brdavis@odin.ac.hmc.edu) Received: (from brdavis@localhost) by odin.ac.hmc.edu (8.11.0/8.11.0) id f5QLhFt11927; Tue, 26 Jun 2001 14:43:15 -0700 Date: Tue, 26 Jun 2001 14:43:15 -0700 From: Brooks Davis To: net@freebsd.org, audit@freebsd.org Subject: review request: network interface cloning Message-ID: <20010626144313.A7909@Odin.AC.HMC.Edu> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-md5; protocol="application/pgp-signature"; boundary="PNTmBPCT7hxwcZjr" Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG --PNTmBPCT7hxwcZjr Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Please review the attached patch. It does the following: - implementes network interface cloning via ifconfig - adds cloning support to gif - removes gif dependencies from stf - makes gif and stf modular Notes: The cloning API isn't quite that of NetBSD because the NetBSD API only supported the creation of staticaly numbered interfaces which can lead to races and starvation in theory. This patch instead allows interfaces to implement wildcard interface creation via "ifconfig gif# create". Hajimu UMEMOTO found a bug related to deletion of gif IPv6 tunnels in certain situations. We're fairly certain it's in the IPv6 routing code rather then in gif. Since even with this bug, the world will be a better place with this patch, I've documented it in gif(4)'s BUGS section and suggest we commit anyway to get cloning into the system. -- Brooks P.S. The patch can also be found at: http://people.freebsd.org/~brooks/patches/gif.diff --=20 Any statement of the form "X is the one, true Y" is FALSE. PGP fingerprint 655D 519C 26A7 82E7 2529 9BF0 5D8E 8BE9 F238 1AD4 Index: sbin/ifconfig/ifconfig.8 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sbin/ifconfig/ifconfig.8,v retrieving revision 1.42 diff -u -u -r1.42 ifconfig.8 --- sbin/ifconfig/ifconfig.8 2001/06/11 12:38:43 1.42 +++ sbin/ifconfig/ifconfig.8 2001/06/22 01:11:23 @@ -43,6 +43,7 @@ .Op Fl L .Op Fl m .Ar interface +.Op Cm create .Op Ar address_family .Oo .Ar address Ns Op Cm / Ns Ar prefixlength @@ -50,6 +51,9 @@ .Oc .Op Ar parameters .Nm +.Ar interface +.Cm destroy +.Nm .Fl a .Op Fl L .Op Fl d @@ -66,6 +70,7 @@ .Op Fl d .Op Fl m .Op Fl u +.Op Fl C .Sh DESCRIPTION .Nm Ifconfig is used to assign an address @@ -269,6 +274,18 @@ Unconfigure the physical source and destination address for IP tunnel interfaces previously configured with .Cm tunnel . +.It Cm create +Create the specified network pseudo-device. +.It Cm destroy +Destroy the specified network pseudo-device. +.It Cm plumb +Another name for the +.Fl create +parameter. Included for Solaris compatability. +.It Cm unplumb +Another name for the +.Fl destroy +parameter. Included for Solaris compatability. .It Cm vlan Ar vlan_tag If the interface is a vlan pseudo interface, set the vlan tag value to @@ -586,6 +603,12 @@ and .Fl u=20 (only list interfaces that are up). +.Pp +The +.Fl C +flag may be used to list all of the interface cloners available on +the system, with no additional information. Use of this flag is +mutually exclusive with all other flags and commands. .Pp Only the super-user may modify the configuration of a network interface. .Sh NOTES Index: sbin/ifconfig/ifconfig.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sbin/ifconfig/ifconfig.c,v retrieving revision 1.63 diff -u -u -r1.63 ifconfig.c --- sbin/ifconfig/ifconfig.c 2001/06/11 12:38:43 1.63 +++ sbin/ifconfig/ifconfig.c 2001/06/22 01:12:06 @@ -135,6 +135,7 @@ struct afswtch; =20 int supmedia =3D 0; +int listcloners =3D 0; =20 #ifdef INET6 char addr_buf[MAXHOSTNAMELEN *2 + 1]; /*for getnameinfo()*/ @@ -144,6 +145,7 @@ void checkatrange __P((struct sockaddr_at *)); int ifconfig __P((int argc, char *const *argv, const struct afswtch *afp)); void notealias __P((const char *, int, int, const struct afswtch *afp)); +void list_cloners __P((void)); void printb __P((const char *s, unsigned value, const char *bits)); void rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *)); void status __P((const struct afswtch *afp, int addrcount, @@ -175,8 +177,12 @@ #endif c_func setifipdst; c_func setifflags, setifmetric, setifmtu, setiflladdr; +c_func clone_destroy; =20 =20 +void clone_create __P((void)); + + #define NEXTARG 0xffffff #define NEXTARG2 0xfffffe =20 @@ -239,6 +245,13 @@ { "vlandev", NEXTARG, setvlandev }, { "-vlandev", NEXTARG, unsetvlandev }, #endif +#if 0 + /* XXX `create' special-cased below */ + {"create", 0, clone_create }, + {"plumb", 0, clone_create }, +#endif + {"destroy", 0, clone_destroy }, + {"unplumb", 0, clone_destroy }, #ifdef USE_IEEE80211 { "ssid", NEXTARG, set80211ssid }, { "nwid", NEXTARG, set80211ssid }, @@ -364,16 +377,20 @@ usage() { #ifndef INET6 - fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n", + fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n", "usage: ifconfig interface address_family [address [dest_address]]", " [parameters]", + " ifconfig -C", + " ifconfig interface create", " ifconfig -a [-d] [-m] [-u] [address_family]", " ifconfig -l [-d] [-u] [address_family]", " ifconfig [-d] [-m] [-u]"); #else - fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n", + fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n", "usage: ifconfig [-L] interface address_family [address [dest_address]]", " [parameters]", + " ifconfig -C", + " ifconfig interface create", " ifconfig -a [-L] [-d] [-m] [-u] [address_family]", " ifconfig -l [-d] [-u] [address_family]", " ifconfig [-L] [-d] [-m] [-u]"); @@ -402,7 +419,7 @@ =20 /* Parse leading line options */ all =3D downonly =3D uponly =3D namesonly =3D 0; - while ((c =3D getopt(argc, argv, "adlmu" + while ((c =3D getopt(argc, argv, "Cadlmu" #ifdef INET6 "L" #endif @@ -428,6 +445,9 @@ case 'm': /* show media choices in status */ supmedia =3D 1; break; + case 'C': + listcloners =3D 1; + break; default: usage(); break; @@ -436,6 +456,16 @@ argc -=3D optind; argv +=3D optind; =20 + if (listcloners) { + /* -C must be solitary */ + if (all || supmedia || uponly || downonly || namesonly || + argc > 0) + usage(); + =09 + list_cloners(); + exit(0); + } + /* -l cannot be used with -a or -m */ if (namesonly && (all || supmedia)) usage(); @@ -448,6 +478,7 @@ if (!namesonly && argc < 1) all =3D 1; =20 + /* -a and -l allow an address family arg to limit the output */ if (all || namesonly) { if (argc > 1) @@ -473,6 +504,18 @@ =20 /* check and maybe load support for this interface */ ifmaybeload(name); + + /* + * NOTE: We must special-case the `create' command right + * here as we would otherwise fail when trying to find + * the interface. + */ + if (argc > 0 && strcmp(argv[0], "create") =3D=3D 0) { + clone_create(); + argc--, argv++; + if (argc =3D=3D 0) + exit(0); + } } =20 /* Check for address family */ @@ -1861,7 +1904,8 @@ =20 /* turn interface and unit into module name */ strcpy(ifkind, "if_"); - for (cp =3D name, dp =3D ifkind + 3; (*cp !=3D 0) && !isdigit(*cp); cp++,= dp++) + for (cp =3D name, dp =3D ifkind + 3; + (*cp !=3D 0) && !isdigit(*cp) && *cp !=3D '#'; cp++, dp++) *dp =3D *cp; *dp =3D 0; =20 @@ -1887,4 +1931,82 @@ =20 /* not present, we should try to load it */ kldload(ifkind); +} + +void +list_cloners(void) +{ + struct if_clonereq ifcr; + char *cp, *buf; + int idx; + int s; + + s =3D socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) + err(1, "socket"); + + memset(&ifcr, 0, sizeof(ifcr)); + + if (ioctl(s, SIOCIFGCLONERS, &ifcr) < 0) + err(1, "SIOCIFGCLONERS for count"); + + buf =3D malloc(ifcr.ifcr_total * IFNAMSIZ); + if (buf =3D=3D NULL) + err(1, "unable to allocate cloner name buffer"); + + ifcr.ifcr_count =3D ifcr.ifcr_total; + ifcr.ifcr_buffer =3D buf; + + if (ioctl(s, SIOCIFGCLONERS, &ifcr) < 0) + err(1, "SIOCIFGCLONERS for names"); + + /* + * In case some disappeared in the mean time, clamp it down. + */ + if (ifcr.ifcr_count > ifcr.ifcr_total) + ifcr.ifcr_count =3D ifcr.ifcr_total; + + for (cp =3D buf, idx =3D 0; idx < ifcr.ifcr_count; idx++, cp +=3D IFNAMSI= Z) { + if (idx > 0) + putchar(' '); + printf("%s", cp); + } + + putchar('\n'); + free(buf); + return; +} + +void +clone_create() +{ + int s; + + s =3D socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) + err(1, "socket"); + + bzero(&ifr, sizeof(ifr)); + (void) strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + if (ioctl(s, SIOCIFCREATE, &ifr) < 0) + err(1, "SIOCIFCREATE"); + + if (strcmp(name, ifr.ifr_name) !=3D 0) { + printf("%s\n", ifr.ifr_name); + strlcpy(name, ifr.ifr_name, sizeof(name)); + } + + close(s); +} + +void +clone_destroy(val, d, s, rafp) + const char *val; + int d; + int s; + const struct afswtch *rafp; +{ + (void) strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + if (ioctl(s, SIOCIFDESTROY, &ifr) < 0) + err(1, "SIOCIFDESTROY"); } Index: sys/conf/files =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/conf/files,v retrieving revision 1.535 diff -u -u -r1.535 files --- sys/conf/files 2001/06/22 06:34:40 1.535 +++ sys/conf/files 2001/06/23 06:40:44 @@ -893,7 +893,7 @@ net/if_ethersubr.c optional ether net/if_faith.c count faith net/if_fddisubr.c optional fddi -net/if_gif.c count gif +net/if_gif.c optional gif net/if_iso88025subr.c optional token net/if_loop.c optional loop net/if_media.c standard @@ -901,7 +901,7 @@ net/if_ppp.c count ppp net/if_sl.c optional sl net/if_spppsubr.c optional sppp -net/if_stf.c count stf +net/if_stf.c optional stf net/if_tun.c optional tun net/if_tap.c optional tap net/if_vlan.c count vlan Index: sys/i386/conf/GENERIC =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/i386/conf/GENERIC,v retrieving revision 1.312 diff -u -u -r1.312 GENERIC --- sys/i386/conf/GENERIC 2001/06/12 09:39:57 1.312 +++ sys/i386/conf/GENERIC 2001/06/18 22:04:21 @@ -210,7 +210,7 @@ device tun # Packet tunnel. device pty # Pseudo-ttys (telnet etc) device md # Memory "disks" -device gif 4 # IPv6 and IPv4 tunneling +device gif # IPv6 and IPv4 tunneling device faith 1 # IPv6-to-IPv4 relaying (translation) =20 # The `bpf' device enables the Berkeley Packet Filter. Index: sys/ia64/conf/GENERIC =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/ia64/conf/GENERIC,v retrieving revision 1.10 diff -u -u -r1.10 GENERIC --- sys/ia64/conf/GENERIC 2001/05/29 18:49:03 1.10 +++ sys/ia64/conf/GENERIC 2001/06/09 00:55:41 @@ -140,7 +140,7 @@ device tun # Packet tunnel. device pty # Pseudo-ttys (telnet etc) device md # Memory "disks" -device gif 4 # IPv6 and IPv4 tunneling +device gif # IPv6 and IPv4 tunneling device faith 1 # IPv6-to-IPv4 relaying/(translation) =20 # The `bpf' device enables the Berkeley Packet Filter. Index: sys/alpha/conf/GENERIC =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/alpha/conf/GENERIC,v retrieving revision 1.113 diff -u -u -r1.113 GENERIC --- sys/alpha/conf/GENERIC 2001/05/30 03:19:05 1.113 +++ sys/alpha/conf/GENERIC 2001/06/09 00:55:14 @@ -165,7 +165,7 @@ device tun # Packet tunnel. device pty # Pseudo-ttys (telnet etc) device md # Memory "disks" -device gif 4 # IPv6 and IPv4 tunneling +device gif # IPv6 and IPv4 tunneling device faith 1 # IPv6-to-IPv4 relaying/(translation) =20 # The `bpf' device enables the Berkeley Packet Filter. Index: sys/net/if.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/net/if.c,v retrieving revision 1.109 diff -u -u -r1.109 if.c --- sys/net/if.c 2001/06/11 12:38:58 1.109 +++ sys/net/if.c 2001/06/22 00:11:09 @@ -56,6 +56,7 @@ #include #include #include +#include #include #include =20 @@ -96,6 +97,12 @@ extern void nd6_setmtu __P((struct ifnet *)); #endif =20 +struct if_clone *if_clone_lookup __P((const char *, int *)); +int if_clone_list __P((struct if_clonereq *)); + +LIST_HEAD(, if_clone) if_cloners =3D LIST_HEAD_INITIALIZER(if_cloners); +int if_cloners_count; + /* * Network interface utility routines. * @@ -350,6 +357,179 @@ } =20 /* + * Create a clone network interface. + */ +int +if_clone_create(name, len) + char *name; + int len; +{ + struct if_clone *ifc; + char *dp; + int wildcard =3D 0; + int unit; + int err; + + ifc =3D if_clone_lookup(name, &unit); + if (ifc =3D=3D NULL) + return (EINVAL); + + if (ifunit(name) !=3D NULL) + return (EEXIST); + + if (unit < 0) + wildcard =3D 1; + + err =3D (*ifc->ifc_create)(ifc, &unit); + if (err !=3D 0) + return (err); + + /* In the wildcard case, we need to update the name. */ + if (wildcard) { + for (dp =3D name; *dp !=3D '#'; dp++); + if (snprintf(dp, len - (dp-name), "%d", unit) > + len - (dp-name) - 1) { + /* + * This can only be a programmer error and + * there's no straightforward way to recover if + * it happens. + */ + panic("interface name too long"); + } + =09 + } + + return (0); +} + +/* + * Destroy a clone network interface. + */ +int +if_clone_destroy(name) + const char *name; +{ + struct if_clone *ifc; + struct ifnet *ifp; + + ifc =3D if_clone_lookup(name, NULL); + if (ifc =3D=3D NULL) + return (EINVAL); + + ifp =3D ifunit(name); + if (ifp =3D=3D NULL) + return (ENXIO); + + if (ifc->ifc_destroy =3D=3D 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 =3D LIST_FIRST(&if_cloners); ifc !=3D NULL;) { + for (cp =3D name, i =3D 0; i < ifc->ifc_namelen; i++, cp++) { + if (ifc->ifc_name[i] !=3D *cp) + goto next_ifc; + } + goto found_name; + next_ifc: + ifc =3D LIST_NEXT(ifc, ifc_list); + } + + /* No match. */ + return (NULL); + + found_name: + if (*cp =3D=3D '#' && *(cp+1) =3D=3D '\0') { + i =3D -1; + } else { + for (i =3D 0; *cp !=3D '\0'; cp++) { + if (*cp < '0' || *cp > '9') { + /* Bogus unit number. */ + return (NULL); + } + i =3D (i * 10) + (*cp - '0'); + } + } + + if (unitp !=3D NULL) + *unitp =3D 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); + if_cloners_count++; +} + +/* + * Unregister a network interface cloner. + */ +void +if_clone_detach(ifc) + struct if_clone *ifc; +{ + + LIST_REMOVE(ifc, ifc_list); + if_cloners_count--; +} + +/* + * Provide list of interface cloners to userspace. + */ +int +if_clone_list(ifcr) + struct if_clonereq *ifcr; +{ + char outbuf[IFNAMSIZ], *dst; + struct if_clone *ifc; + int count, error =3D 0; + + ifcr->ifcr_total =3D if_cloners_count; + if ((dst =3D ifcr->ifcr_buffer) =3D=3D NULL) { + /* Just asking how many there are. */ + return (0); + } + + if (ifcr->ifcr_count < 0) + return (EINVAL); + + count =3D (if_cloners_count < ifcr->ifcr_count) ? + if_cloners_count : ifcr->ifcr_count; + + for (ifc =3D LIST_FIRST(&if_cloners); ifc !=3D NULL && count !=3D 0; + ifc =3D LIST_NEXT(ifc, ifc_list), count--, dst +=3D IFNAMSIZ) { + strncpy(outbuf, ifc->ifc_name, IFNAMSIZ); + outbuf[IFNAMSIZ - 1] =3D '\0'; /* sanity */ + error =3D copyout(outbuf, dst, IFNAMSIZ); + if (error) + break; + } + + return (error); +} + +/* * Locate an interface based on a complete address. */ /*ARGSUSED*/ @@ -687,10 +867,10 @@ * interface structure pointer. */ struct ifnet * -ifunit(char *name) +ifunit(const char *name) { char namebuf[IFNAMSIZ + 1]; - char *cp; + const char *cp; struct ifnet *ifp; int unit; unsigned len, m; @@ -781,6 +961,20 @@ return (ifconf(cmd, data)); } ifr =3D (struct ifreq *)data; + + switch (cmd) { + case SIOCIFCREATE: + case SIOCIFDESTROY: + if ((error =3D suser(p)) !=3D 0) + return (error); + return ((cmd =3D=3D SIOCIFCREATE) ? + if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name)) : + if_clone_destroy(ifr->ifr_name)); +=09 + case SIOCIFGCLONERS: + return (if_clone_list((struct if_clonereq *)data)); + } + ifp =3D ifunit(ifr->ifr_name); if (ifp =3D=3D 0) return (ENXIO); Index: sys/net/if.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/net/if.h,v retrieving revision 1.61 diff -u -u -r1.61 if.h --- sys/net/if.h 2001/02/21 06:39:56 1.61 +++ sys/net/if.h 2001/06/22 06:03:23 @@ -37,6 +37,8 @@ #ifndef _NET_IF_H_ #define _NET_IF_H_ =20 +#include + /* * does not depend on on most other systems. This * helps userland compatibility. (struct timeval ifi_lastchange) @@ -45,6 +47,40 @@ #include #endif =20 +struct ifnet; + +/* + * Length of interface external name, including terminating '\0'. + * Note: this is the same size as a generic device's external name. + */ +#define IFNAMSIZ 16 +#define IF_NAMESIZE IFNAMSIZ + +/* + * 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 used to query names of interface cloners. + */ + +struct if_clonereq { + int ifcr_total; /* total cloners (out) */ + int ifcr_count; /* room for this many in user buffer */ + char *ifcr_buffer; /* buffer for cloner names */ +}; + /* * Structure describing information about an interface * which may be of interest to management entities. @@ -151,8 +187,6 @@ * remainder may be interface specific. */ struct ifreq { -#define IFNAMSIZ 16 -#define IF_NAMESIZE IFNAMSIZ char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */ union { struct sockaddr ifru_addr; Index: sys/net/if_var.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/net/if_var.h,v retrieving revision 1.33 diff -u -u -r1.33 if_var.h --- sys/net/if_var.h 2001/03/28 09:17:55 1.33 +++ sys/net/if_var.h 2001/06/22 00:00:59 @@ -401,7 +401,7 @@ /*void ifinit __P((void));*/ /* declared in systm.h for main() */ int ifioctl __P((struct socket *, u_long, caddr_t, struct proc *)); int ifpromisc __P((struct ifnet *, int)); -struct ifnet *ifunit __P((char *)); +struct ifnet *ifunit __P((const char *)); struct ifnet *if_withname __P((struct sockaddr *)); =20 int if_poll_recv_slow __P((struct ifnet *ifp, int *quotap)); @@ -422,6 +422,12 @@ struct ifmultiaddr *ifmaof_ifpforaddr __P((struct sockaddr *, struct ifnet *)); int if_simloop __P((struct ifnet *ifp, struct mbuf *m, int af, int hlen)); + +void if_clone_attach __P((struct if_clone *)); +void if_clone_detach __P((struct if_clone *)); + +int if_clone_create __P((char *, int)); +int if_clone_destroy __P((const char *)); =20 #endif /* _KERNEL */ =20 Index: sys/net/if_gif.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/net/if_gif.c,v retrieving revision 1.11 diff -u -u -r1.11 if_gif.c --- sys/net/if_gif.c 2001/06/19 15:53:51 1.11 +++ sys/net/if_gif.c 2001/06/25 20:21:24 @@ -44,6 +44,9 @@ #include #include #include +#include +#include /* XXX: Shouldn't really be required! */ +#include #include =20 #include @@ -58,6 +61,8 @@ #ifdef INET #include #include +#include +#include #endif /* INET */ =20 #ifdef INET6 @@ -74,29 +79,47 @@ #include #include =20 -#include "gif.h" -#include "bpf.h" -#define NBPFILTER NBPF - #include + +#define GIFNAME "gif" +#define GIFDEV "if_gif" +#define GIF_MAXUNIT 0x7fff /* ifp->if_unit is only 15 bits */ + +static MALLOC_DEFINE(M_GIF, "gif", "Generic Tunnel Interface"); +static struct rman gifunits[1]; +TAILQ_HEAD(gifhead, gif_softc) gifs =3D TAILQ_HEAD_INITIALIZER(gifs); =20 -#if NGIF > 0 +int gif_clone_create __P((struct if_clone *, int *)); +void gif_clone_destroy __P((struct ifnet *)); =20 -void gifattach __P((void *)); +struct if_clone gif_cloner =3D + IF_CLONE_INITIALIZER("gif", gif_clone_create, gif_clone_destroy); + +static int gifmodevent __P((module_t, int, void *)); +void gif_delete_tunnel __P((struct gif_softc *)); static int gif_encapcheck __P((const struct mbuf *, int, int, void *)); + #ifdef INET -extern struct protosw in_gif_protosw; +extern struct domain inetdomain; +struct ipprotosw in_gif_protosw =3D +{ SOCK_RAW, &inetdomain, 0/*IPPROTO_IPV[46]*/, PR_ATOMIC|PR_ADDR, + in_gif_input, rip_output, 0, rip_ctloutput, + 0, + 0, 0, 0, 0, + &rip_usrreqs +}; +#endif +#ifdef INET6 +extern struct domain6 inet6domain; +struct ip6protosw in6_gif_protosw =3D +{ SOCK_RAW, &inet6domain, 0/*IPPROTO_IPV[46]*/, PR_ATOMIC|PR_ADDR, + in6_gif_input, rip6_output, 0, rip6_ctloutput, + 0, + 0, 0, 0, 0, + &rip6_usrreqs +}; #endif -#ifdef INET6 -extern struct ip6protosw in6_gif_protosw; -#endif =20 -/* - * gif global variable definitions - */ -static int ngif; /* number of interfaces */ -static struct gif_softc *gif =3D 0; - #ifndef MAX_GIF_NEST /* * This macro controls the upper limitation on nesting of gif tunnels. @@ -110,64 +133,158 @@ #endif static int max_gif_nesting =3D MAX_GIF_NEST; =20 -void -gifattach(dummy) - void *dummy; +int +gif_clone_create(ifc, unit) + struct if_clone *ifc; + int *unit; { + struct resource *r; struct gif_softc *sc; - int i; =20 - ngif =3D NGIF; - gif =3D sc =3D malloc(ngif * sizeof(struct gif_softc), M_DEVBUF, M_WAITOK= ); - bzero(sc, ngif * sizeof(struct gif_softc)); - for (i =3D 0; i < ngif; sc++, i++) { - sc->gif_if.if_name =3D "gif"; - sc->gif_if.if_unit =3D i; - - sc->encap_cookie4 =3D sc->encap_cookie6 =3D NULL; -#ifdef INET - sc->encap_cookie4 =3D encap_attach_func(AF_INET, -1, - gif_encapcheck, &in_gif_protosw, sc); - if (sc->encap_cookie4 =3D=3D NULL) { - printf("%s: attach failed\n", if_name(&sc->gif_if)); - continue; - } + if (*unit > GIF_MAXUNIT) + return (ENXIO); + + if (*unit < 0) { + r =3D rman_reserve_resource(gifunits, 0, GIF_MAXUNIT, 1, + RF_ALLOCATED | RF_ACTIVE, NULL); + if (r =3D=3D NULL) + return (ENOSPC); + *unit =3D rman_get_start(r); + } else { + r =3D rman_reserve_resource(gifunits, *unit, *unit, 1, + RF_ALLOCATED | RF_ACTIVE, NULL); + if (r =3D=3D NULL) + return (EEXIST); + } +=09 + sc =3D malloc (sizeof(struct gif_softc), M_GIF, M_WAITOK); + bzero(sc, sizeof(struct gif_softc)); + + sc->gif_if.if_softc =3D sc; + sc->gif_if.if_name =3D GIFNAME; + sc->gif_if.if_unit =3D *unit; + sc->r_unit =3D r; + + sc->encap_cookie4 =3D sc->encap_cookie6 =3D NULL; +#ifdef INET + sc->encap_cookie4 =3D encap_attach_func(AF_INET, -1, + gif_encapcheck, (struct protosw*)&in_gif_protosw, sc); + if (sc->encap_cookie4 =3D=3D NULL) { + printf("%s: unable to attach encap4\n", if_name(&sc->gif_if)); + free(sc, M_GIF); + return (EIO); /* XXX */ + } #endif #ifdef INET6 - sc->encap_cookie6 =3D encap_attach_func(AF_INET6, -1, - gif_encapcheck, (struct protosw *)&in6_gif_protosw, sc); - if (sc->encap_cookie6 =3D=3D NULL) { - if (sc->encap_cookie4) { - encap_detach(sc->encap_cookie4); - sc->encap_cookie4 =3D NULL; - } - printf("%s: attach failed\n", if_name(&sc->gif_if)); - continue; + sc->encap_cookie6 =3D encap_attach_func(AF_INET6, -1, + gif_encapcheck, (struct protosw *)&in6_gif_protosw, sc); + if (sc->encap_cookie6 =3D=3D NULL) { + if (sc->encap_cookie4) { + encap_detach(sc->encap_cookie4); + sc->encap_cookie4 =3D NULL; } + printf("%s: unable to attach encap6\n", if_name(&sc->gif_if)); + free(sc, M_GIF); + return (EIO); /* XXX */ + } #endif =20 - sc->gif_if.if_mtu =3D GIF_MTU; - sc->gif_if.if_flags =3D IFF_POINTOPOINT | IFF_MULTICAST; + sc->gif_if.if_mtu =3D GIF_MTU; + sc->gif_if.if_flags =3D IFF_POINTOPOINT | IFF_MULTICAST; #if 0 - /* turn off ingress filter */ - sc->gif_if.if_flags |=3D IFF_LINK2; + /* turn off ingress filter */ + sc->gif_if.if_flags |=3D IFF_LINK2; #endif - sc->gif_if.if_ioctl =3D gif_ioctl; - sc->gif_if.if_output =3D gif_output; - sc->gif_if.if_type =3D IFT_GIF; - sc->gif_if.if_snd.ifq_maxlen =3D IFQ_MAXLEN; - if_attach(&sc->gif_if); -#if NBPFILTER > 0 -#ifdef HAVE_OLD_BPF - bpfattach(&sc->gif_if, DLT_NULL, sizeof(u_int)); -#else - bpfattach(&sc->gif_if.if_bpf, &sc->gif_if, DLT_NULL, sizeof(u_int)); + sc->gif_if.if_ioctl =3D gif_ioctl; + sc->gif_if.if_output =3D gif_output; + sc->gif_if.if_type =3D IFT_GIF; + sc->gif_if.if_snd.ifq_maxlen =3D IFQ_MAXLEN; + if_attach(&sc->gif_if); + bpfattach(&sc->gif_if, DLT_NULL, sizeof(u_int)); + TAILQ_INSERT_TAIL(&gifs, sc, gif_link); + return (0); +} + +void +gif_clone_destroy(ifp) + struct ifnet *ifp; +{ + int err; + struct gif_softc *sc =3D ifp->if_softc; + + gif_delete_tunnel(sc); + TAILQ_REMOVE(&gifs, sc, gif_link); + if (sc->encap_cookie4 !=3D NULL) { + err =3D encap_detach(sc->encap_cookie4); + KASSERT(err =3D=3D 0, ("Unexpected error detaching encap_cookie4")); + } + if (sc->encap_cookie6 !=3D NULL) { + err =3D encap_detach(sc->encap_cookie6); + KASSERT(err =3D=3D 0, ("Unexpected error detaching encap_cookie6")); + } + + bpfdetach(ifp); + if_detach(ifp); + + err =3D rman_release_resource(sc->r_unit); + KASSERT(err =3D=3D 0, ("Unexpected error freeing resource")); + + free(sc, M_GIF); +} + +static int +gifmodevent(mod, type, data) + module_t mod; + int type; + void *data; +{ + int err; + + switch (type) { + case MOD_LOAD: + gifunits->rm_type =3D RMAN_ARRAY; + gifunits->rm_descr =3D "configurable if_gif units"; + err =3D rman_init(gifunits); + if (err !=3D 0) + return (err); + err =3D rman_manage_region(gifunits, 0, GIF_MAXUNIT); + if (err !=3D 0) { + printf("%s: gifunits: rman_manage_region: Failed %d\n", + GIFNAME, err); + rman_fini(gifunits); + return (err); + } + if_clone_attach(&gif_cloner); + +#ifdef INET6 + ip6_gif_hlim =3D GIF_HLIM; #endif + + break; + case MOD_UNLOAD: + if_clone_detach(&gif_cloner); + + while (!TAILQ_EMPTY(&gifs)) + gif_clone_destroy(&TAILQ_FIRST(&gifs)->gif_if); + + err =3D rman_fini(gifunits); + if (err !=3D 0) + return (err); +#ifdef INET6 + ip6_gif_hlim =3D 0; #endif + break; } + return 0; } + +static moduledata_t gif_mod =3D { + "if_gif", + gifmodevent, + 0 +}; =20 -PSEUDO_SET(gifattach, if_gif); +DECLARE_MODULE(if_gif, gif_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); =20 static int gif_encapcheck(m, off, proto, arg) @@ -261,7 +378,6 @@ goto end; } =20 -#if NBPFILTER > 0 if (ifp->if_bpf) { /* * We need to prepend the address family as @@ -277,13 +393,8 @@ m0.m_len =3D 4; m0.m_data =3D (char *)⁡ =09 -#ifdef HAVE_OLD_BPF bpf_mtap(ifp, &m0); -#else - bpf_mtap(ifp->if_bpf, &m0); -#endif } -#endif ifp->if_opackets++;=09 ifp->if_obytes +=3D m->m_pkthdr.len; =20 @@ -333,7 +444,6 @@ =20 m->m_pkthdr.rcvif =3D gifp; =09 -#if NBPFILTER > 0 if (gifp->if_bpf) { /* * We need to prepend the address family as @@ -349,13 +459,8 @@ m0.m_len =3D 4; m0.m_data =3D (char *)&af1; =09 -#ifdef HAVE_OLD_BPF bpf_mtap(gifp, &m0); -#else - bpf_mtap(gifp->if_bpf, &m0); -#endif } -#endif /*NBPFILTER > 0*/ =20 /* * Put the packet to the network layer input queue according to the @@ -408,8 +513,8 @@ int error =3D 0, size; struct sockaddr *dst, *src; struct sockaddr *sa; - int i; int s; + struct ifnet *ifp2; struct gif_softc *sc2; =09 switch (cmd) { @@ -523,8 +628,10 @@ break; } =20 - for (i =3D 0; i < ngif; i++) { - sc2 =3D gif + i; + TAILQ_FOREACH(ifp2, &ifnet, if_link) { + if (strcmp(ifp2->if_name, GIFNAME) !=3D 0) + continue; + sc2 =3D ifp2->if_softc; if (sc2 =3D=3D sc) continue; if (!sc2->gif_pdst || !sc2->gif_psrc) @@ -697,5 +804,21 @@ } bad: return error; +} + +void +gif_delete_tunnel(sc) + struct gif_softc *sc; +{ + /* XXX: NetBSD protects this function with splsoftnet() */ + + if (sc->gif_psrc) { + free((caddr_t)sc->gif_psrc, M_IFADDR); + sc->gif_psrc =3D NULL; + } + if (sc->gif_pdst) { + free((caddr_t)sc->gif_pdst, M_IFADDR); + sc->gif_pdst =3D NULL; + } + /* change the IFF_UP flag as well? */ } -#endif /*NGIF > 0*/ Index: sys/net/if_gif.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/net/if_gif.h,v retrieving revision 1.4 diff -u -u -r1.4 if_gif.h --- sys/net/if_gif.h 2001/06/11 12:38:58 1.4 +++ sys/net/if_gif.h 2001/06/25 20:16:12 @@ -60,6 +60,8 @@ int gif_flags; const struct encaptab *encap_cookie4; const struct encaptab *encap_cookie6; + struct resource *r_unit; /* resource allocated for this unit */ + TAILQ_ENTRY(gif_softc) gif_link; /* all gif's are linked */ }; =20 #define gif_ro gifsc_gifscr.gifscr_ro Index: sys/net/if_stf.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/net/if_stf.c,v retrieving revision 1.7 diff -u -u -r1.7 if_stf.c --- sys/net/if_stf.c 2001/06/11 12:38:58 1.7 +++ sys/net/if_stf.c 2001/06/25 20:11:52 @@ -98,12 +98,12 @@ #include #include #include +#include #include #include =20 #include #include -#include #include #include =20 @@ -113,23 +113,7 @@ =20 #include =20 -#include "bpf.h" -#define NBPFILTER NBPF -#include "stf.h" -#include "gif.h" /*XXX*/ - -#if NBPFILTER > 0 #include -#endif - -#if NGIF > 0 -#include -#endif - -#if NSTF > 0 -#if NSTF !=3D 1 -# error only single stf interface allowed -#endif =20 #define IN6_IS_ADDR_6TO4(x) (ntohs((x)->s6_addr16[0]) =3D=3D 0x2002) #define GET_V4(x) ((struct in_addr *)(&(x)->s6_addr16[1])) @@ -145,17 +129,20 @@ }; =20 static struct stf_softc *stf; -static int nstf; =20 -#if NGIF > 0 -extern int ip_gif_ttl; /*XXX*/ -#else -static int ip_gif_ttl =3D 40; /*XXX*/ -#endif +static MALLOC_DEFINE(M_STF, "stf", "6to4 Tunnel Interface"); +static int ip_stf_ttl =3D 40; =20 -extern struct protosw in_stf_protosw; +extern struct domain inetdomain; +struct ipprotosw in_stf_protosw =3D +{ SOCK_RAW, &inetdomain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR, + in_stf_input, rip_output, 0, rip_ctloutput, + 0, + 0, 0, 0, 0, + &rip_usrreqs +}; =20 -void stfattach __P((void *)); +static int stfmodevent __P((module_t, int, void *)); static int stf_encapcheck __P((const struct mbuf *, int, int, void *)); static struct in6_ifaddr *stf_getsrcifa6 __P((struct ifnet *)); static int stf_output __P((struct ifnet *, struct mbuf *, struct sockaddr = *, @@ -167,31 +154,31 @@ static void stf_rtrequest __P((int, struct rtentry *, struct sockaddr *)); static int stf_ioctl __P((struct ifnet *, u_long, caddr_t)); =20 -void -stfattach(dummy) - void *dummy; +static int +stfmodevent(mod, type, data) + module_t mod; + int type; + void *data; { struct stf_softc *sc; - int i; + int err; const struct encaptab *p; + + switch (type) { + case MOD_LOAD: + stf =3D malloc(sizeof(struct stf_softc), M_STF, M_WAITOK); + bzero(stf, sizeof(struct stf_softc)); + sc =3D stf; =20 - nstf =3D NSTF; - stf =3D malloc(nstf * sizeof(struct stf_softc), M_DEVBUF, M_WAITOK); - bzero(stf, nstf * sizeof(struct stf_softc)); - sc =3D stf; - - /* XXX just in case... */ - for (i =3D 0; i < nstf; i++) { - sc =3D &stf[i]; bzero(sc, sizeof(*sc)); sc->sc_if.if_name =3D "stf"; - sc->sc_if.if_unit =3D i; + sc->sc_if.if_unit =3D 0; =20 p =3D encap_attach_func(AF_INET, IPPROTO_IPV6, stf_encapcheck, &in_stf_protosw, sc); if (p =3D=3D NULL) { printf("%s: attach failed\n", if_name(&sc->sc_if)); - continue; + return (ENOMEM); } sc->encap_cookie =3D p; =20 @@ -206,18 +193,33 @@ #endif sc->sc_if.if_snd.ifq_maxlen =3D IFQ_MAXLEN; if_attach(&sc->sc_if); -#if NBPFILTER > 0 #ifdef HAVE_OLD_BPF bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int)); #else bpfattach(&sc->sc_if.if_bpf, &sc->sc_if, DLT_NULL, sizeof(u_int)); #endif -#endif + break; + case MOD_UNLOAD: + sc =3D stf; + bpfdetach(&sc->sc_if); + if_detach(&sc->sc_if); + err =3D encap_detach(sc->encap_cookie); + KASSERT(err =3D=3D 0, ("Unexpected error detaching encap_cookie")); + free(sc, M_STF); + break; } + + return (0); } =20 -PSEUDO_SET(stfattach, if_stf); +static moduledata_t stf_mod =3D { + "if_stf", + stfmodevent, + 0 +}; =20 +DECLARE_MODULE(if_stf, stf_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); + static int stf_encapcheck(m, off, proto, arg) const struct mbuf *m; @@ -389,7 +391,7 @@ &ip->ip_src, sizeof(ip->ip_src)); bcopy(in4, &ip->ip_dst, sizeof(ip->ip_dst)); ip->ip_p =3D IPPROTO_IPV6; - ip->ip_ttl =3D ip_gif_ttl; /*XXX*/ + ip->ip_ttl =3D ip_stf_ttl; ip->ip_len =3D m->m_pkthdr.len; /*host order*/ if (ifp->if_flags & IFF_LINK1) ip_ecn_ingress(ECN_ALLOWED, &ip->ip_tos, &tos); @@ -583,7 +585,6 @@ =20 m->m_pkthdr.rcvif =3D ifp; =09 -#if NBPFILTER > 0 if (ifp->if_bpf) { /* * We need to prepend the address family as @@ -605,7 +606,6 @@ bpf_mtap(ifp->if_bpf, &m0); #endif } -#endif /*NBPFILTER > 0*/ =20 /* * Put the packet to the network layer input queue according to the @@ -679,5 +679,3 @@ =20 return error; } - -#endif /* NSTF > 0 */ Index: sys/netinet/in_gif.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/netinet/in_gif.c,v retrieving revision 1.10 diff -u -u -r1.10 in_gif.c --- sys/netinet/in_gif.c 2001/06/11 12:39:00 1.10 +++ sys/netinet/in_gif.c 2001/06/22 19:21:57 @@ -67,17 +67,9 @@ =20 #include =09 =20 -#include "gif.h" - -#include - #include =20 -#if NGIF > 0 int ip_gif_ttl =3D GIF_TTL; -#else -int ip_gif_ttl =3D 0; -#endif SYSCTL_INT(_net_inet_ip, IPCTL_GIF_TTL, gifttl, CTLFLAG_RW, &ip_gif_ttl, 0, ""); =20 @@ -210,25 +202,15 @@ } =20 void -#if __STDC__ -in_gif_input(struct mbuf *m, ...) -#else -in_gif_input(m, va_alist) +in_gif_input(m, off, proto) struct mbuf *m; - va_dcl -#endif + int off; + int proto; { - int off, proto; struct ifnet *gifp =3D NULL; struct ip *ip; - va_list ap; int af; u_int8_t otos; - - va_start(ap, m); - off =3D va_arg(ap, int); - proto =3D va_arg(ap, int); - va_end(ap); =20 ip =3D mtod(m, struct ip *); =20 Index: sys/netinet/in_gif.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/netinet/in_gif.h,v retrieving revision 1.4 diff -u -u -r1.4 in_gif.h --- sys/netinet/in_gif.h 2000/07/04 16:35:05 1.4 +++ sys/netinet/in_gif.h 2001/06/22 19:19:23 @@ -37,7 +37,7 @@ =20 extern int ip_gif_ttl; =20 -void in_gif_input __P((struct mbuf *, ...)); +void in_gif_input __P((struct mbuf *, int off, int proto)); int in_gif_output __P((struct ifnet *, int, struct mbuf *, struct rtentry = *)); int gif_encapcheck4 __P((const struct mbuf *, int, int, void *)); =20 Index: sys/netinet/in_proto.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/netinet/in_proto.c,v retrieving revision 1.56 diff -u -u -r1.56 in_proto.c --- sys/netinet/in_proto.c 2001/06/11 12:39:00 1.56 +++ sys/netinet/in_proto.c 2001/06/11 17:41:06 @@ -78,16 +78,6 @@ #include #endif /* IPSEC */ =20 -#include "gif.h" -#if NGIF > 0 -#include -#endif - -#include "stf.h" -#if NSTF > 0 -#include -#endif - #ifdef IPXIP #include #endif @@ -212,26 +202,6 @@ &rip_usrreqs }, }; - -#if NGIF > 0 -struct ipprotosw in_gif_protosw =3D -{ SOCK_RAW, &inetdomain, 0/*IPPROTO_IPV[46]*/, PR_ATOMIC|PR_ADDR, - in_gif_input, rip_output, 0, rip_ctloutput, - 0, - 0, 0, 0, 0, - &rip_usrreqs -}; -#endif /*NGIF*/ - -#if NSTF > 0 -struct ipprotosw in_stf_protosw =3D -{ SOCK_RAW, &inetdomain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR, - in_stf_input, rip_output, 0, rip_ctloutput, - 0, - 0, 0, 0, 0, - &rip_usrreqs -}; -#endif /*NSTF*/ =20 extern int in_inithead __P((void **, int)); =20 Index: sys/netinet6/in6.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/netinet6/in6.c,v retrieving revision 1.12 diff -u -u -r1.12 in6.c --- sys/netinet6/in6.c 2001/06/11 12:39:05 1.12 +++ sys/netinet6/in6.c 2001/06/11 17:00:35 @@ -105,11 +105,6 @@ #include #endif =20 -#include "gif.h" -#if NGIF > 0 -#include -#endif - #include =20 MALLOC_DEFINE(M_IPMADDR, "in6_multi", "internet multicast address"); Index: sys/netinet6/in6_proto.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/netinet6/in6_proto.c,v retrieving revision 1.14 diff -u -u -r1.14 in6_proto.c --- sys/netinet6/in6_proto.c 2001/06/11 12:39:05 1.14 +++ sys/netinet6/in6_proto.c 2001/06/11 17:01:55 @@ -128,11 +128,6 @@ =20 #include =20 -#include "gif.h" -#if NGIF > 0 -#include -#endif - #include =20 /* @@ -251,16 +246,6 @@ }, }; =20 -#if NGIF > 0 -struct ip6protosw in6_gif_protosw =3D -{ SOCK_RAW, &inet6domain, 0/*IPPROTO_IPV[46]*/, PR_ATOMIC|PR_ADDR, - in6_gif_input, rip6_output, 0, rip6_ctloutput, - 0, - 0, 0, 0, 0, - &rip6_usrreqs -}; -#endif /*NGIF*/ - extern int in6_inithead __P((void **, int)); =20 struct domain inet6domain =3D @@ -299,11 +284,7 @@ int ip6_dad_count =3D 1; /* DupAddrDetectionTransmits */ u_int32_t ip6_flow_seq; int ip6_auto_flowlabel =3D 1; -#if NGIF > 0 -int ip6_gif_hlim =3D GIF_HLIM; -#else int ip6_gif_hlim =3D 0; -#endif int ip6_use_deprecated =3D 1; /* allow deprecated addr (RFC2462 5.5.4) */ int ip6_rr_prune =3D 5; /* router renumbering prefix * walk list every 5 sec. */ Index: sys/netinet6/ip6_input.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/netinet6/ip6_input.c,v retrieving revision 1.27 diff -u -u -r1.27 ip6_input.c --- sys/netinet6/ip6_input.c 2001/06/11 12:39:05 1.27 +++ sys/netinet6/ip6_input.c 2001/06/11 16:58:56 @@ -121,7 +121,6 @@ #include =20 #include "faith.h" -#include "gif.h" =20 #include =20 Index: sys/sys/sockio.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/sys/sockio.h,v retrieving revision 1.18 diff -u -u -r1.18 sockio.h --- sys/sys/sockio.h 2001/06/11 20:34:19 1.18 +++ sys/sys/sockio.h 2001/06/21 21:22:58 @@ -100,4 +100,8 @@ #define SIOCGIFSTATUS _IOWR('i', 59, struct ifstat) /* get IF status */ #define SIOCSIFLLADDR _IOW('i', 60, struct ifreq) /* set link level addr */ =20 +#define SIOCIFCREATE _IOWR('i', 122, struct ifreq) /* create clone if */ +#define SIOCIFDESTROY _IOW('i', 121, struct ifreq) /* destroy clone if */ +#define SIOCIFGCLONERS _IOWR('i', 120, struct if_clonereq) /* get cloners = */ + #endif /* !_SYS_SOCKIO_H_ */ Index: sys/modules/Makefile =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/sys/modules/Makefile,v retrieving revision 1.186 diff -u -u -r1.186 Makefile --- sys/modules/Makefile 2001/06/14 15:15:54 1.186 +++ sys/modules/Makefile 2001/06/22 01:10:08 @@ -8,7 +8,8 @@ =20 SUBDIR=3D 3dfx accf_data accf_http agp aha amr an aue \ cam ccd cd9660 coda cue dc de dgm digi ed fdescfs fs fxp if_disc if_ef \ - if_ppp if_sl if_tap if_tun ip6fw ipfilter ipfw ispfw joy kue lge \ + if_gif if_ppp if_sl if_stf if_tap if_tun \ + ip6fw ipfilter ipfw ispfw joy kue lge \ libmchain linux lnc md mii mlx msdosfs ncp netgraph nfs nge ntfs \ nullfs nwfs pcn portalfs procfs ${_random} \ rl rp sf sis sk sn snp sound sppp ste sym syscons sysvipc ti tl twe \ --- sys/modules/if_gif/Makefile.orig Fri Jun 8 19:00:25 2001 +++ sys/modules/if_gif/Makefile Fri Jun 8 19:04:43 2001 @@ -0,0 +1,18 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../net ${.CURDIR}/../../netinet ${.CURDIR}/../../neti= net6 + +KMOD=3D if_gif +SRCS=3D if_gif.c in_gif.c in6_gif.c opt_inet.h opt_inet6.h opt_mrouting.h +NOMAN=3D + +opt_inet.h: + echo "#define INET 1" > ${.TARGET} + +opt_inet6.h: + echo "#define INET6 1" > ${.TARGET} + +opt_mrouting.h: + echo "#define MROUTING 1" > ${.TARGET} + +.include --- sys/modules/if_stf/Makefile.orig Mon Jun 11 11:34:03 2001 +++ sys/modules/if_stf/Makefile Mon Jun 11 11:36:30 2001 @@ -0,0 +1,15 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../net + +KMOD=3D if_stf +SRCS=3D if_stf.c opt_inet.h opt_inet6.h +NOMAN=3D + +opt_inet.h: + echo "#define INET 1" > ${.TARGET} + +opt_inet6.h: + echo "#define INET6 1" > ${.TARGET} + +.include Index: etc/rc.network =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/etc/rc.network,v retrieving revision 1.99 diff -u -u -r1.99 rc.network --- etc/rc.network 2001/06/16 15:48:43 1.99 +++ etc/rc.network 2001/06/22 01:29:04 @@ -766,7 +766,7 @@ continue ;; *) - ifconfig $i tunnel ${peers} + ifconfig $i create tunnel ${peers} ;; esac done Index: share/man/man4/gif.4 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/share/man/man4/gif.4,v retrieving revision 1.9 diff -u -r1.9 gif.4 --- share/man/man4/gif.4 2001/06/11 12:38:48 1.9 +++ share/man/man4/gif.4 2001/06/25 20:42:04 @@ -35,7 +35,7 @@ .Nm gif .Nd generic tunnel interface .Sh SYNOPSIS -.Cd "device gif" Op Ar count +.Cd "device gif" .Sh DESCRIPTION The .Nm @@ -210,3 +210,19 @@ .Dv IFF_LINK0 flag. The behavior was obsoleted and is no longer supported. +.Pp +In some cases, when +.Cm ifconfig gifN destroy +is executed, an IPv6 default route is removed. +This problem occures when the following conditions are met: +.Bl -dash -offset indent -compact +.It +The host doesn't accept RA (i.e. net.inet6.ip6.accept_rtadv=3D0), +.It +the default route is installed manually, and +.It +.Cm ifconfig gifN destroy +is executed. +.El +It is thought that this is not actually a bug in gif, but rather lies +somewhere around a manipulation of an IPv6 routing table. --PNTmBPCT7hxwcZjr Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.4 (GNU/Linux) Comment: For info see http://www.gnupg.org iD8DBQE7OQHwXY6L6fI4GtQRAjnsAKC3laFZY6DXqns41zRclOrTtYKPLwCfRxrn NZRRjCE/ol1qSUMwRxh+mkg= =uDfo -----END PGP SIGNATURE----- --PNTmBPCT7hxwcZjr-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message