Date: Wed, 12 Apr 2006 05:20:36 +0200 From: Max Laier <max@love2party.net> To: freebsd-net@freebsd.org Cc: andre@freebsd.org Subject: Re: Interface groups (from OpenBSD) Message-ID: <200604120520.42362.max@love2party.net> In-Reply-To: <200603281131.28240.max@love2party.net> References: <200603281131.28240.max@love2party.net>
next in thread | previous in thread | raw e-mail | index | archive | help
--nextPart1349231.b1GtDd56l5 Content-Type: multipart/mixed; boundary="Boundary-01=_FIHPE+/4nKkInpx" Content-Transfer-Encoding: 7bit Content-Disposition: inline --Boundary-01=_FIHPE+/4nKkInpx Content-Type: text/plain; charset="iso-8859-6" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline On Tuesday 28 March 2006 11:31, Max Laier wrote: > Hi, > > while porting OpenBSD 3.9 (soon to be released) pf I stumbled on interface > groups. This is a mechanism to group arbitrary interfaces into logical > groups. It is just naming (not functional change), but it helps to convey > semantic information (e.g. group "LAN", "DMZ" ...) about your interface to > supporting applications. This way you can write a policies for interface > group "LAN" and have it applied to all the VLAN interfaces that come and > go. Administration is done via ifconfig. We currently have "ifconfig nam= e" > which does part of the job. > > My question: Does that sound like something interesting for us and should= I > go for importing it into FreeBSD proper, or is it not at all interesting > and we don't want it (in which case I'd hack something up for pf). > > Technical reasoning: A proper import would add an additional TAILQ link > into struct ifnet (which is a great deal of ABI change and causes the usu= al > headaches). The hack would use a single void *, but we'd have to pay for > the additional indirection. Also yet another config tool would be requir= ed > to administer the interface <-> group binding. Okay, here is a first version for discussion and review. It seems fully=20 functional, but test with care. As we allow interface names that do not en= d=20 with a digit (e.g. stf(4) and renamed interfaces) I can't use this to=20 discriminate interfaces and groups. So, in order to show interfaces in a=20 group I had to add a "-g" switch to ifconfig. Printing of group membership= s=20 is under verbose for now, but that's subject to discussion. I'm not sure if the "egress" group makes sense for us, yet. Andre, any pla= ns=20 there wrt to routing? For now it's just uncommented. Comments and reviews appreciated. Thanks. =2D-=20 /"\ Best regards, | mlaier@freebsd.org \ / Max Laier | ICQ #67774661 X http://pf4freebsd.love2party.net/ | mlaier@EFnet / \ ASCII Ribbon Campaign | Against HTML Mail and News --Boundary-01=_FIHPE+/4nKkInpx Content-Type: text/x-diff; charset="iso-8859-6"; name="group.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="group.diff" Index: sbin/ifconfig/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: /usr/store/mlaier/fcvs/src/sbin/ifconfig/Makefile,v retrieving revision 1.30 diff -u -r1.30 Makefile =2D-- sbin/ifconfig/Makefile 20 Mar 2006 14:24:57 -0000 1.30 +++ sbin/ifconfig/Makefile 12 Apr 2006 02:46:29 -0000 @@ -26,6 +26,7 @@ SRCS+=3D ifieee80211.c # SIOC[GS]IEEE80211 support =20 SRCS+=3D ifcarp.c # SIOC[GS]VH support +SRCS+=3D ifgroup.c # ... SRCS+=3D ifpfsync.c # pfsync(4) support =20 SRCS+=3D ifbridge.c # bridge support 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: /usr/store/mlaier/fcvs/src/sbin/ifconfig/ifconfig.8,v retrieving revision 1.116 diff -u -r1.116 ifconfig.8 =2D-- sbin/ifconfig/ifconfig.8 8 Apr 2006 21:38:09 -0000 1.116 +++ sbin/ifconfig/ifconfig.8 12 Apr 2006 02:39:33 -0000 @@ -28,7 +28,7 @@ .\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94 .\" $FreeBSD: src/sbin/ifconfig/ifconfig.8,v 1.116 2006/04/08 21:38:09 sco= ttl Exp $ .\" =2D.Dd February 27, 2006 +.Dd April 12, 2006 .Dt IFCONFIG 8 .Os .Sh NAME @@ -71,6 +71,8 @@ .Op Fl u .Op Fl v .Op Fl C +.Nm +.Op Fl g Ar groupname .Sh DESCRIPTION The .Nm @@ -178,6 +180,8 @@ .Dq name unit , for example, .Dq Li ed0 . +.It Ar groupname +List the interfaces in the given group. .El .Pp The following parameters may be set with @@ -262,6 +266,22 @@ transmit messages through that interface. If possible, the interface will be reset to disable reception as well. This action does not automatically disable routes using the interface. +.It Cm group Ar group-name +Assign the interface to a +.Dq group . +Any interface can be in multiple groups. +.Pp +Cloned interfaces are members of their interface family group by default. +For example, a PPP interface such as +.Em ppp0 +is a member of the PPP interface family group, +.Em ppp . +.\" The interface(s) the default route(s) point to are members of the +.\" .Em egress +.\" interface group. +.It Cm -group Ar group-name +Remove the interface from the given +.Dq group . .It Cm eui64 (Inet6 only.) Fill interface index Index: sbin/ifconfig/ifgroup.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: sbin/ifconfig/ifgroup.c diff -N sbin/ifconfig/ifgroup.c =2D-- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sbin/ifconfig/ifgroup.c 12 Apr 2006 02:30:45 -0000 @@ -0,0 +1,186 @@ +/*- + * Copyright (c) 2006 Max Laier. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURP= OSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENT= IAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STR= ICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY W= AY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static const char rcsid[] =3D + "$FreeBSD$"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <net/if.h> + +#include <ctype.h> +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "ifconfig.h" + +/* ARGSUSED */ +static void +setifgroup(const char *group_name, int d, int s, const struct afswtch *raf= p) +{ + struct ifgroupreq ifgr; + + memset(&ifgr, 0, sizeof(ifgr)); + strlcpy(ifgr.ifgr_name, name, IFNAMSIZ); + + if (group_name[0] && isdigit(group_name[strlen(group_name) - 1])) + errx(1, "setifgroup: group names may not end in a digit"); + + if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >=3D IFNAMSIZ) + errx(1, "setifgroup: group name too long"); + if (ioctl(s, SIOCAIFGROUP, (caddr_t)&ifgr) =3D=3D -1) + err(1," SIOCAIFGROUP"); +} + +/* ARGSUSED */ +static void +unsetifgroup(const char *group_name, int d, int s, const struct afswtch *r= afp) +{ + struct ifgroupreq ifgr; + + memset(&ifgr, 0, sizeof(ifgr)); + strlcpy(ifgr.ifgr_name, name, IFNAMSIZ); + + if (group_name[0] && isdigit(group_name[strlen(group_name) - 1])) + errx(1, "unsetifgroup: group names may not end in a digit"); + + if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >=3D IFNAMSIZ) + errx(1, "unsetifgroup: group name too long"); + if (ioctl(s, SIOCDIFGROUP, (caddr_t)&ifgr) =3D=3D -1) + err(1, "SIOCDIFGROUP"); +} + +static void +getifgroups(int s) +{ + int len, cnt; + struct ifgroupreq ifgr; + struct ifg_req *ifg; + + if (!verbose) + return; + + memset(&ifgr, 0, sizeof(ifgr)); + strlcpy(ifgr.ifgr_name, name, IFNAMSIZ); + + if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) =3D=3D -1) { + if (errno =3D=3D EINVAL || errno =3D=3D ENOTTY) + return; + else + err(1, "SIOCGIFGROUP"); + } + + len =3D ifgr.ifgr_len; + ifgr.ifgr_groups =3D + (struct ifg_req *)calloc(len / sizeof(struct ifg_req), + sizeof(struct ifg_req)); + if (ifgr.ifgr_groups =3D=3D NULL) + err(1, "getifgroups"); + if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) =3D=3D -1) + err(1, "SIOCGIFGROUP"); + + cnt =3D 0; + ifg =3D ifgr.ifgr_groups; + for (; ifg && len >=3D sizeof(struct ifg_req); ifg++) { + len -=3D sizeof(struct ifg_req); + if (strcmp(ifg->ifgrq_group, "all")) { + if (cnt =3D=3D 0) + printf("\tgroups: "); + cnt++; + printf("%s ", ifg->ifgrq_group); + } + } + if (cnt) + printf("\n"); +} + +static void +printgroup(char *groupname) +{ + struct ifgroupreq ifgr; + struct ifg_req *ifg; + int len, cnt =3D 0; + int s; + + s =3D socket(AF_INET, SOCK_DGRAM, 0); + if (s =3D=3D -1) + err(1, "socket(AF_INET,SOCK_DGRAM)"); + bzero(&ifgr, sizeof(ifgr)); + strlcpy(ifgr.ifgr_name, groupname, sizeof(ifgr.ifgr_name)); + if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) =3D=3D -1) { + if (errno =3D=3D EINVAL || errno =3D=3D ENOTTY || + errno =3D=3D ENOENT) + exit(0); + else + err(1, "SIOCGIFGMEMB"); + } + + len =3D ifgr.ifgr_len; + if ((ifgr.ifgr_groups =3D calloc(1, len)) =3D=3D NULL) + err(1, "printgroup"); + if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) =3D=3D -1) + err(1, "SIOCGIFGMEMB"); + + for (ifg =3D ifgr.ifgr_groups; ifg && len >=3D sizeof(struct ifg_req); + ifg++) { + len -=3D sizeof(struct ifg_req); + printf("%s\n", ifg->ifgrq_member); + cnt++; + } + free(ifgr.ifgr_groups); + + exit(0); +} + +static struct cmd group_cmds[] =3D { + DEF_CMD_ARG("group", setifgroup), + DEF_CMD_ARG("-group", unsetifgroup), +}; +static struct afswtch af_group =3D { + .af_name =3D "af_group", + .af_af =3D AF_UNSPEC, + .af_other_status =3D getifgroups, +}; +static struct option group_gopt =3D { "g:", "[-g groupname]", printgroup }; + +static __constructor void +group_ctor(void) +{ +#define N(a) (sizeof(a) / sizeof(a[0])) + int i; + + for (i =3D 0; i < N(group_cmds); i++) + cmd_register(&group_cmds[i]); + af_register(&af_group); + opt_register(&group_gopt); +#undef N +} 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: /usr/store/mlaier/fcvs/src/sys/net/if.c,v retrieving revision 1.255 diff -u -r1.255 if.c =2D-- sys/net/if.c 21 Mar 2006 14:31:18 -0000 1.255 +++ sys/net/if.c 12 Apr 2006 02:57:34 -0000 @@ -113,6 +113,8 @@ static int ifhwioctl(u_long, struct ifnet *, caddr_t, struct thread *); static void if_start_deferred(void *context, int pending); static void do_link_state_change(void *, int); +static int if_getgroup(struct ifgroupreq *, struct ifnet *); +static int if_getgroupmembers(struct ifgroupreq *); #ifdef INET6 /* * XXX: declare here to avoid to include many inet6 related files.. @@ -125,6 +127,7 @@ struct ifindex_entry *ifindex_table =3D NULL; int ifqmaxlen =3D IFQ_MAXLEN; struct ifnethead ifnet; /* depend on static init XXX */ +struct ifgrouphead ifg_head; struct mtx ifnet_lock; static if_com_alloc_t *if_com_alloc[256]; static if_com_free_t *if_com_free[256]; @@ -282,6 +285,7 @@ =20 IFNET_LOCK_INIT(); TAILQ_INIT(&ifnet); + TAILQ_INIT(&ifg_head); knlist_init(&ifklist, NULL, NULL, NULL, NULL); if_grow(); /* create initial table */ ifdev_byindex(0) =3D make_dev(&net_cdevsw, 0, @@ -441,6 +445,10 @@ TAILQ_INIT(&ifp->if_addrhead); TAILQ_INIT(&ifp->if_prefixhead); TAILQ_INIT(&ifp->if_multiaddrs); + TAILQ_INIT(&ifp->if_groups); + + if_addgroup(ifp, IFG_ALL); + knlist_init(&ifp->if_klist, NULL, NULL, NULL, NULL); getmicrotime(&ifp->if_lastchange); ifp->if_data.ifi_epoch =3D time_uptime; @@ -713,6 +721,213 @@ } =20 /* + * Add a group to an interface + */ +int +if_addgroup(struct ifnet *ifp, const char *groupname) +{ + struct ifg_list *ifgl; + struct ifg_group *ifg =3D NULL; + struct ifg_member *ifgm; + + if (groupname[0] && groupname[strlen(groupname) - 1] >=3D '0' && + groupname[strlen(groupname) - 1] <=3D '9') + return (EINVAL); + + IFNET_WLOCK(); + TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) + if (!strcmp(ifgl->ifgl_group->ifg_group, groupname)) { + IFNET_WUNLOCK(); + return (EEXIST); + } + + if ((ifgl =3D (struct ifg_list *)malloc(sizeof(struct ifg_list), M_TEMP, + M_NOWAIT)) =3D=3D NULL) { + IFNET_WUNLOCK(); + return (ENOMEM); + } + + if ((ifgm =3D (struct ifg_member *)malloc(sizeof(struct ifg_member), + M_TEMP, M_NOWAIT)) =3D=3D NULL) { + free(ifgl, M_TEMP); + IFNET_WUNLOCK(); + return (ENOMEM); + } + + TAILQ_FOREACH(ifg, &ifg_head, ifg_next) + if (!strcmp(ifg->ifg_group, groupname)) + break; + + if (ifg =3D=3D NULL) { + if ((ifg =3D (struct ifg_group *)malloc(sizeof(struct ifg_group), + M_TEMP, M_NOWAIT)) =3D=3D NULL) { + free(ifgl, M_TEMP); + free(ifgm, M_TEMP); + IFNET_WUNLOCK(); + return (ENOMEM); + } + strlcpy(ifg->ifg_group, groupname, sizeof(ifg->ifg_group)); + ifg->ifg_refcnt =3D 0; + TAILQ_INIT(&ifg->ifg_members); + EVENTHANDLER_INVOKE(group_attach_event, ifg); + TAILQ_INSERT_TAIL(&ifg_head, ifg, ifg_next); + } + + ifg->ifg_refcnt++; + ifgl->ifgl_group =3D ifg; + ifgm->ifgm_ifp =3D ifp; + + IF_ADDR_LOCK(ifp); + TAILQ_INSERT_TAIL(&ifg->ifg_members, ifgm, ifgm_next); + TAILQ_INSERT_TAIL(&ifp->if_groups, ifgl, ifgl_next); + IF_ADDR_UNLOCK(ifp); + + EVENTHANDLER_INVOKE(group_change_event, groupname); + IFNET_WUNLOCK(); + + return (0); +} + +/* + * Remove a group from an interface + */ +int +if_delgroup(struct ifnet *ifp, const char *groupname) +{ + struct ifg_list *ifgl; + struct ifg_member *ifgm; + + IFNET_WLOCK(); + TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) + if (!strcmp(ifgl->ifgl_group->ifg_group, groupname)) + break; + if (ifgl =3D=3D NULL) { + IFNET_WUNLOCK(); + return (ENOENT); + } + + IF_ADDR_LOCK(ifp); + TAILQ_REMOVE(&ifp->if_groups, ifgl, ifgl_next); + IF_ADDR_UNLOCK(ifp); + + TAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, ifgm_next) + if (ifgm->ifgm_ifp =3D=3D ifp) + break; + + if (ifgm !=3D NULL) { + TAILQ_REMOVE(&ifgl->ifgl_group->ifg_members, ifgm, ifgm_next); + free(ifgm, M_TEMP); + } + + if (--ifgl->ifgl_group->ifg_refcnt =3D=3D 0) { + TAILQ_REMOVE(&ifg_head, ifgl->ifgl_group, ifg_next); + EVENTHANDLER_INVOKE(group_detach_event, ifgl->ifgl_group); + free(ifgl->ifgl_group, M_TEMP); + } + IFNET_WUNLOCK(); + + free(ifgl, M_TEMP); + + EVENTHANDLER_INVOKE(group_change_event, groupname); + + return (0); +} + +/* + * Stores all groups from an interface in memory pointed + * to by data + */ +static int +if_getgroup(struct ifgroupreq *data, struct ifnet *ifp) +{ + int len, error; + struct ifg_list *ifgl; + struct ifg_req ifgrq, *ifgp; + struct ifgroupreq *ifgr =3D data; + + if (ifgr->ifgr_len =3D=3D 0) { + IF_ADDR_LOCK(ifp); + TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) + ifgr->ifgr_len +=3D sizeof(struct ifg_req); + IF_ADDR_UNLOCK(ifp); + return (0); + } + + len =3D ifgr->ifgr_len; + ifgp =3D ifgr->ifgr_groups; + /* XXX: wire */ + IF_ADDR_LOCK(ifp); + TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) { + if (len < sizeof(ifgrq)) { + IF_ADDR_UNLOCK(ifp); + return (EINVAL); + } + bzero(&ifgrq, sizeof ifgrq); + strlcpy(ifgrq.ifgrq_group, ifgl->ifgl_group->ifg_group, + sizeof(ifgrq.ifgrq_group)); + if ((error =3D copyout(&ifgrq, ifgp, sizeof(struct ifg_req)))) { + IF_ADDR_UNLOCK(ifp); + return (error); + } + len -=3D sizeof(ifgrq); + ifgp++; + } + IF_ADDR_UNLOCK(ifp); + + return (0); +} + +/* + * Stores all members of a group in memory pointed to by data + */ +static int +if_getgroupmembers(struct ifgroupreq *data) +{ + struct ifgroupreq *ifgr =3D data; + struct ifg_group *ifg; + struct ifg_member *ifgm; + struct ifg_req ifgrq, *ifgp; + int len, error; + + IFNET_RLOCK(); + TAILQ_FOREACH(ifg, &ifg_head, ifg_next) + if (!strcmp(ifg->ifg_group, ifgr->ifgr_name)) + break; + if (ifg =3D=3D NULL) { + IFNET_RUNLOCK(); + return (ENOENT); + } + + if (ifgr->ifgr_len =3D=3D 0) { + TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) + ifgr->ifgr_len +=3D sizeof(ifgrq); + IFNET_RUNLOCK(); + return (0); + } + + len =3D ifgr->ifgr_len; + ifgp =3D ifgr->ifgr_groups; + TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) { + if (len < sizeof(ifgrq)) { + IFNET_RUNLOCK(); + return (EINVAL); + } + bzero(&ifgrq, sizeof ifgrq); + strlcpy(ifgrq.ifgrq_member, ifgm->ifgm_ifp->if_xname, + sizeof(ifgrq.ifgrq_member)); + if ((error =3D copyout(&ifgrq, ifgp, sizeof(struct ifg_req)))) { + IFNET_RUNLOCK(); + return (error); + } + len -=3D sizeof(ifgrq); + ifgp++; + } + IFNET_RUNLOCK(); + + return (0); +} + +/* * Delete Routes for a Network Interface * * Called for each routing entry via the rnh->rnh_walktree() call above @@ -1470,6 +1685,35 @@ ifr->ifr_addr.sa_data, ifr->ifr_addr.sa_len); break; =20 + case SIOCAIFGROUP: + { + struct ifgroupreq *ifgr =3D (struct ifgroupreq *)ifr; + + error =3D suser(td); + if (error) + return (error); + if ((error =3D if_addgroup(ifp, ifgr->ifgr_group))) + return (error); + break; + } + + case SIOCGIFGROUP: + if ((error =3D if_getgroup((struct ifgroupreq *)ifr, ifp))) + return (error); + break; + + case SIOCDIFGROUP: + { + struct ifgroupreq *ifgr =3D (struct ifgroupreq *)ifr; + + error =3D suser(td); + if (error) + return (error); + if ((error =3D if_delgroup(ifp, ifgr->ifgr_group))) + return (error); + break; + } + default: error =3D ENOIOCTL; break; @@ -1509,6 +1753,8 @@ =20 case SIOCIFGCLONERS: return (if_clone_list((struct if_clonereq *)data)); + case SIOCGIFGMEMB: + return (if_getgroupmembers((struct ifgroupreq *)data)); } =20 ifp =3D ifunit(ifr->ifr_name); 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: /usr/store/mlaier/fcvs/src/sys/net/if.h,v retrieving revision 1.101 diff -u -r1.101 if.h =2D-- sys/net/if.h 2 Feb 2006 19:58:37 -0000 1.101 +++ sys/net/if.h 11 Apr 2006 03:41:57 -0000 @@ -359,6 +359,37 @@ #endif =20 /* + * interface groups + */ + +#define IFG_ALL "all" /* group contains all interfaces */ +/* XXX: will we implement this? */ +#define IFG_EGRESS "egress" /* if(s) default route(s) point to */ + +struct ifg_req { + union { + char ifgrqu_group[IFNAMSIZ]; + char ifgrqu_member[IFNAMSIZ]; + } ifgrq_ifgrqu; +#define ifgrq_group ifgrq_ifgrqu.ifgrqu_group +#define ifgrq_member ifgrq_ifgrqu.ifgrqu_member +}; + +/* + * Used to lookup groups for an interface + */ +struct ifgroupreq { + char ifgr_name[IFNAMSIZ]; + u_int ifgr_len; + union { + char ifgru_group[IFNAMSIZ]; + struct ifg_req *ifgru_groups; + } ifgr_ifgru; +#define ifgr_group ifgr_ifgru.ifgru_group +#define ifgr_groups ifgr_ifgru.ifgru_groups +}; + +/* * Structure for SIOC[AGD]LIFADDR */ struct if_laddrreq { Index: sys/net/if_clone.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: /usr/store/mlaier/fcvs/src/sys/net/if_clone.c,v retrieving revision 1.9 diff -u -r1.9 if_clone.c =2D-- sys/net/if_clone.c 24 Nov 2005 18:56:14 -0000 1.9 +++ sys/net/if_clone.c 12 Apr 2006 01:03:27 -0000 @@ -158,6 +158,8 @@ if (ifp =3D=3D NULL) panic("%s: lookup failed for %s", __func__, name); =20 + if_addgroup(ifp, ifc->ifc_name); + IF_CLONE_LOCK(ifc); IFC_IFLIST_INSERT(ifc, ifp); IF_CLONE_UNLOCK(ifc); @@ -210,9 +212,13 @@ IFC_IFLIST_REMOVE(ifc, ifp); IF_CLONE_UNLOCK(ifc); =20 + if_delgroup(ifp, ifc->ifc_name); + err =3D (*ifc->ifc_destroy)(ifc, ifp); =20 if (err !=3D 0) { + if_addgroup(ifp, ifc->ifc_name); + IF_CLONE_LOCK(ifc); IFC_IFLIST_INSERT(ifc, ifp); IF_CLONE_UNLOCK(ifc); 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: /usr/store/mlaier/fcvs/src/sys/net/if_var.h,v retrieving revision 1.106 diff -u -r1.106 if_var.h =2D-- sys/net/if_var.h 30 Jan 2006 13:45:15 -0000 1.106 +++ sys/net/if_var.h 12 Apr 2006 02:59:42 -0000 @@ -91,6 +91,7 @@ TAILQ_HEAD(ifaddrhead, ifaddr); /* instantiation is preserved in the list = */ TAILQ_HEAD(ifprefixhead, ifprefix); TAILQ_HEAD(ifmultihead, ifmultiaddr); +TAILQ_HEAD(ifgrouphead, ifg_group); =20 /* * Structure defining a queue for a network interface. @@ -182,6 +183,9 @@ struct task if_linktask; /* task for link change events */ struct mtx if_addr_mtx; /* mutex to protect address lists */ LIST_ENTRY(ifnet) if_clones; /* interfaces of a cloner */ + TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */ + /* protected by if_addr_mtx */ + void *if_pf_kif; }; =20 typedef void if_init_f_t(void *); @@ -318,6 +322,37 @@ typedef void (*ifnet_departure_event_handler_t)(void *, struct ifnet *); EVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_departure_event_handler_= t); =20 +/* + * interface groups + */ +struct ifg_group { + char ifg_group[IFNAMSIZ]; + u_int ifg_refcnt; + void *ifg_pf_kif; + TAILQ_HEAD(, ifg_member) ifg_members; + TAILQ_ENTRY(ifg_group) ifg_next; +}; + +struct ifg_member { + TAILQ_ENTRY(ifg_member) ifgm_next; + struct ifnet *ifgm_ifp; +}; + +struct ifg_list { + struct ifg_group *ifgl_group; + TAILQ_ENTRY(ifg_list) ifgl_next; +}; + +/* group attach event */ +typedef void (*group_attach_event_handler_t)(void *, struct ifg_group *); +EVENTHANDLER_DECLARE(group_attach_event, group_attach_event_handler_t); +/* group detach event */ +typedef void (*group_detach_event_handler_t)(void *, struct ifg_group *); +EVENTHANDLER_DECLARE(group_detach_event, group_detach_event_handler_t); +/* group change event */ +typedef void (*group_change_event_handler_t)(void *, const char *); +EVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t); + #define IF_AFDATA_LOCK_INIT(ifp) \ mtx_init(&(ifp)->if_afdata_mtx, "if_afdata", NULL, MTX_DEF) #define IF_AFDATA_LOCK(ifp) mtx_lock(&(ifp)->if_afdata_mtx) @@ -624,6 +659,8 @@ extern struct ifnet *loif; /* first loopback interface */ extern int if_index; =20 +int if_addgroup(struct ifnet *, const char *); +int if_delgroup(struct ifnet *, const char *); int if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **); int if_allmulti(struct ifnet *, int); struct ifnet* if_alloc(u_char); 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: /usr/store/mlaier/fcvs/src/sys/sys/sockio.h,v retrieving revision 1.29 diff -u -r1.29 sockio.h =2D-- sys/sys/sockio.h 2 Feb 2006 19:58:37 -0000 1.29 +++ sys/sys/sockio.h 12 Apr 2006 00:36:11 -0000 @@ -117,4 +117,9 @@ #define SIOCIFDESTROY _IOW('i', 121, struct ifreq) /* destroy clone if */ #define SIOCIFGCLONERS _IOWR('i', 120, struct if_clonereq) /* get cloners = */ =20 +#define SIOCAIFGROUP _IOW('i', 135, struct ifgroupreq) /* add an ifgroup = */ +#define SIOCGIFGROUP _IOWR('i', 136, struct ifgroupreq) /* get ifgroups */ +#define SIOCDIFGROUP _IOW('i', 137, struct ifgroupreq) /* delete ifgroup = */ +#define SIOCGIFGMEMB _IOWR('i', 138, struct ifgroupreq) /* get members */ + #endif /* !_SYS_SOCKIO_H_ */ --Boundary-01=_FIHPE+/4nKkInpx-- --nextPart1349231.b1GtDd56l5 Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (FreeBSD) iD8DBQBEPHIKXyyEoT62BG0RAsXWAJ4pgUKyND/wsYYxxFBYDqlMawYSvQCdFKmP utDZ9vHV+y3fZLcqiYuKMnA= =LLdv -----END PGP SIGNATURE----- --nextPart1349231.b1GtDd56l5--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200604120520.42362.max>