Date: Mon, 14 Jul 2008 13:11:52 GMT From: Gleb Kurtsou <gk@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 145223 for review Message-ID: <200807141311.m6EDBqYn014107@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=145223 Change 145223 by gk@gk_h1 on 2008/07/14 13:11:43 ifc Affected files ... .. //depot/projects/soc2008/gk_l2filter/sbin-ifconfig/ifconfig.8#3 integrate .. //depot/projects/soc2008/gk_l2filter/sbin-ifconfig/ifconfig.c#3 integrate .. //depot/projects/soc2008/gk_l2filter/sbin-ifconfig/ifieee80211.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/bpf.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/bpf.h#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/bpf_zerocopy.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/bpf_zerocopy.h#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/if.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/if_bridge.c#8 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/if_gre.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/if_gre.h#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/if_lagg.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/if_loop.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/if_ppp.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/if_var.h#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/netisr.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/netisr.h#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/raw_cb.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/raw_cb.h#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/raw_usrreq.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-net/rtsock.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/if_ether.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/in.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/in_pcb.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/in_pcb.h#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/ip_gre.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/ip_input.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/libalias/alias.c#3 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/libalias/alias_db.c#3 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/libalias/alias_ftp.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/raw_ip.c#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_asconf.c#3 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_asconf.h#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_bsd_addr.c#3 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_bsd_addr.h#3 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_cc_functions.h#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_constants.h#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_crc32.h#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_indata.c#3 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_indata.h#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_input.c#3 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_input.h#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_os_bsd.h#3 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_output.c#3 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_output.h#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_pcb.c#3 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_pcb.h#3 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_sysctl.h#3 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_timer.c#3 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_timer.h#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_uio.h#3 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_usrreq.c#3 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctp_var.h#3 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctputil.c#3 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/sctputil.h#2 integrate .. //depot/projects/soc2008/gk_l2filter/sys-netinet/udp_usrreq.c#3 integrate Differences ... ==== //depot/projects/soc2008/gk_l2filter/sbin-ifconfig/ifconfig.8#3 (text+ko) ==== @@ -26,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94 -.\" $FreeBSD: src/sbin/ifconfig/ifconfig.8,v 1.147 2008/04/20 20:35:46 sam Exp $ +.\" $FreeBSD: src/sbin/ifconfig/ifconfig.8,v 1.148 2008/06/20 17:26:34 thompsa Exp $ .\" -.Dd April 11, 2008 +.Dd June 20, 2008 .Dt IFCONFIG 8 .Os .Sh NAME @@ -2032,6 +2032,16 @@ parameter. .El .Pp +The following parameters are specific to GRE tunnel interfaces, +.Xr gre 4 : +.Bl -tag -width indent +.It Cm grekey Ar key +Configure the GRE key to be used for outgoing packets. +Note that +.Xr gre 4 will always accept GRE packets with invalid or absent keys. +This command will result in a four byte MTU reduction on the interface. +.El +.Pp The following parameters are specific to .Xr pfsync 4 interfaces: ==== //depot/projects/soc2008/gk_l2filter/sbin-ifconfig/ifconfig.c#3 (text+ko) ==== @@ -38,7 +38,7 @@ static char sccsid[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94"; #endif static const char rcsid[] = - "$FreeBSD: src/sbin/ifconfig/ifconfig.c,v 1.136 2008/03/31 15:38:07 sam Exp $"; + "$FreeBSD: src/sbin/ifconfig/ifconfig.c,v 1.137 2008/06/20 17:26:34 thompsa Exp $"; #endif /* not lint */ #include <sys/param.h> @@ -51,6 +51,7 @@ #include <net/ethernet.h> #include <net/if.h> +#include <net/if_gre.h> #include <net/if_var.h> #include <net/if_dl.h> #include <net/if_types.h> @@ -749,6 +750,18 @@ } static void +setifgrekey(const char *val, int dummy __unused, int s, + const struct afswtch *afp) +{ + uint32_t grekey = atol(val); + + strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); + ifr.ifr_data = (caddr_t)&grekey; + if (ioctl(s, GRESKEY, (caddr_t)&ifr) < 0) + warn("ioctl (set grekey)"); +} + +static void setifname(const char *val, int dummy __unused, int s, const struct afswtch *afp) { @@ -863,6 +876,12 @@ if (ioctl(s, SIOCGIFSTATUS, &ifs) == 0) printf("%s", ifs.ascii); + int grekey = 0; + ifr.ifr_data = (caddr_t)&grekey; + if (ioctl(s, GREGKEY, &ifr) == 0) + if (grekey != 0) + printf("\tgrekey: %d\n", grekey); + close(s); return; } @@ -1038,6 +1057,7 @@ DEF_CMD("noicmp", IFF_LINK1, setifflags), DEF_CMD_ARG("mtu", setifmtu), DEF_CMD_ARG("name", setifname), + DEF_CMD_ARG("grekey", setifgrekey), }; static __constructor void ==== //depot/projects/soc2008/gk_l2filter/sbin-ifconfig/ifieee80211.c#2 (text+ko) ==== @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sbin/ifconfig/ifieee80211.c,v 1.51 2008/04/20 20:35:46 sam Exp $ + * $FreeBSD: src/sbin/ifconfig/ifieee80211.c,v 1.52 2008/06/23 16:08:40 thompsa Exp $ */ /*- @@ -666,9 +666,12 @@ memset(&chan, 0, sizeof(chan)); if (!isanyarg(val)) { int v, flags; + char *ep; getchaninfo(s); - v = atoi(val); + v = strtol(val, &ep, 10); + if (val[0] == '\0' || ep[0] != '\0' || errno == ERANGE) + errx(1, "invalid channel number"); flags = getchannelflags(val, v); if (v > 255) { /* treat as frequency */ mapfreq(&chan, v, flags); ==== //depot/projects/soc2008/gk_l2filter/sys-net/bpf.c#2 (text+ko) ==== @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/net/bpf.c,v 1.195 2008/05/09 19:29:08 jhb Exp $"); +__FBSDID("$FreeBSD: src/sys/net/bpf.c,v 1.197 2008/07/07 09:25:49 dwmalone Exp $"); #include "opt_bpf.h" #include "opt_mac.h" @@ -200,6 +200,28 @@ } /* + * This function gets called when the free buffer is re-assigned. + */ +static void +bpf_buf_reclaimed(struct bpf_d *d) +{ + + BPFD_LOCK_ASSERT(d); + + switch (d->bd_bufmode) { + case BPF_BUFMODE_BUFFER: + return; + + case BPF_BUFMODE_ZBUF: + bpf_zerocopy_buf_reclaimed(d); + return; + + default: + panic("bpf_buf_reclaimed"); + } +} + +/* * If the buffer mechanism has a way to decide that a held buffer can be made * free, then it is exposed via the bpf_canfreebuf() interface. (1) is * returned if the buffer can be discarded, (0) is returned if it cannot. @@ -744,6 +766,7 @@ d->bd_fbuf = d->bd_hbuf; d->bd_hbuf = NULL; d->bd_hlen = 0; + bpf_buf_reclaimed(d); BPFD_UNLOCK(d); return (error); @@ -887,6 +910,7 @@ /* Free the hold buffer. */ d->bd_fbuf = d->bd_hbuf; d->bd_hbuf = NULL; + bpf_buf_reclaimed(d); } d->bd_slen = 0; d->bd_hlen = 0; @@ -903,8 +927,9 @@ * FIONREAD Check for read packet available. * SIOCGIFADDR Get interface address - convenient hook to driver. * BIOCGBLEN Get buffer len [for read()]. - * BIOCSETF Set ethernet read filter. - * BIOCSETWF Set ethernet write filter. + * BIOCSETF Set read filter. + * BIOCSETFNR Set read filter without resetting descriptor. + * BIOCSETWF Set write filter. * BIOCFLUSH Flush read packet buffer. * BIOCPROMISC Put interface into promiscuous mode. * BIOCGDLT Get link layer type. @@ -1023,6 +1048,7 @@ * Set link layer read filter. */ case BIOCSETF: + case BIOCSETFNR: case BIOCSETWF: error = bpf_setf(d, (struct bpf_program *)addr, cmd); break; @@ -1337,8 +1363,9 @@ #ifdef BPF_JITTER d->bd_bfilter = NULL; #endif + if (cmd == BIOCSETF) + reset_d(d); } - reset_d(d); BPFD_UNLOCK(d); if (old != NULL) free((caddr_t)old, M_BPF); @@ -1364,8 +1391,9 @@ #ifdef BPF_JITTER d->bd_bfilter = bpf_jitter(fcode, flen); #endif + if (cmd == BIOCSETF) + reset_d(d); } - reset_d(d); BPFD_UNLOCK(d); if (old != NULL) free((caddr_t)old, M_BPF); @@ -1717,6 +1745,7 @@ d->bd_fbuf = d->bd_hbuf; d->bd_hbuf = NULL; d->bd_hlen = 0; + bpf_buf_reclaimed(d); } /* ==== //depot/projects/soc2008/gk_l2filter/sys-net/bpf.h#2 (text+ko) ==== @@ -34,7 +34,7 @@ * @(#)bpf.h 8.1 (Berkeley) 6/10/93 * @(#)bpf.h 1.34 (LBL) 6/16/96 * - * $FreeBSD: src/sys/net/bpf.h,v 1.50 2008/03/24 13:49:17 csjp Exp $ + * $FreeBSD: src/sys/net/bpf.h,v 1.51 2008/07/07 09:25:49 dwmalone Exp $ */ #ifndef _NET_BPF_H_ @@ -142,6 +142,7 @@ #define BIOCGETZMAX _IOR('B',127, size_t) #define BIOCROTZBUF _IOR('B',128, struct bpf_zbuf) #define BIOCSETZBUF _IOW('B',129, struct bpf_zbuf) +#define BIOCSETFNR _IOW('B',130, struct bpf_program) /* Obsolete */ #define BIOCGSEESENT BIOCGDIRECTION ==== //depot/projects/soc2008/gk_l2filter/sys-net/bpf_zerocopy.c#2 (text+ko) ==== @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/net/bpf_zerocopy.c,v 1.4 2008/04/07 02:51:00 rwatson Exp $"); +__FBSDID("$FreeBSD: src/sys/net/bpf_zerocopy.c,v 1.5 2008/07/05 20:11:28 csjp Exp $"); #include "opt_bpf.h" @@ -410,6 +410,24 @@ } /* + * Notification from the BPF framework that the free buffer has been been + * re-assigned. This happens when the user ackknowledges the buffer. + */ +void +bpf_zerocopy_buf_reclaimed(struct bpf_d *d) +{ + struct zbuf *zb; + + KASSERT(d->bd_bufmode == BPF_BUFMODE_ZBUF, + ("bpf_zerocopy_reclaim_buf: not in zbuf mode")); + + KASSERT(d->bd_fbuf != NULL, + ("bpf_zerocopy_buf_reclaimed: NULL free buff")); + zb = (struct zbuf *)d->bd_fbuf; + zb->zb_flags &= ~ZBUF_FLAG_IMMUTABLE; +} + +/* * Query from the BPF framework regarding whether the buffer currently in the * held position can be moved to the free position, which can be indicated by * the user process making their generation number equal to the kernel ==== //depot/projects/soc2008/gk_l2filter/sys-net/bpf_zerocopy.h#2 (text+ko) ==== @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/net/bpf_zerocopy.h,v 1.2 2008/04/07 02:51:00 rwatson Exp $ + * $FreeBSD: src/sys/net/bpf_zerocopy.h,v 1.3 2008/07/05 20:11:28 csjp Exp $ */ #ifndef _NET_BPF_ZEROCOPY_H_ @@ -42,6 +42,7 @@ void *src, u_int len); void bpf_zerocopy_buffull(struct bpf_d *); void bpf_zerocopy_bufheld(struct bpf_d *); +void bpf_zerocopy_buf_reclaimed(struct bpf_d *); int bpf_zerocopy_canfreebuf(struct bpf_d *); int bpf_zerocopy_canwritebuf(struct bpf_d *); void bpf_zerocopy_free(struct bpf_d *d); ==== //depot/projects/soc2008/gk_l2filter/sys-net/if.c#2 (text+ko) ==== @@ -27,7 +27,7 @@ * SUCH DAMAGE. * * @(#)if.c 8.5 (Berkeley) 1/9/95 - * $FreeBSD: src/sys/net/if.c,v 1.280 2008/05/17 03:38:13 brooks Exp $ + * $FreeBSD: src/sys/net/if.c,v 1.281 2008/06/26 23:05:28 rwatson Exp $ */ #include "opt_compat.h" @@ -133,7 +133,6 @@ #endif int if_index = 0; -struct ifindex_entry *ifindex_table = NULL; int ifqmaxlen = IFQ_MAXLEN; struct ifnethead ifnet; /* depend on static init XXX */ struct ifgrouphead ifg_head; @@ -144,6 +143,11 @@ static int if_indexlim = 8; static struct knlist ifklist; +/* + * Table of ifnet/cdev by index. Locked with ifnet_lock. + */ +static struct ifindex_entry *ifindex_table = NULL; + static void filt_netdetach(struct knote *kn); static int filt_netdev(struct knote *kn, long hint); @@ -160,6 +164,57 @@ MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address"); MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address"); +struct ifnet * +ifnet_byindex(u_short idx) +{ + struct ifnet *ifp; + + IFNET_RLOCK(); + ifp = ifindex_table[idx].ife_ifnet; + IFNET_RUNLOCK(); + return (ifp); +} + +static void +ifnet_setbyindex(u_short idx, struct ifnet *ifp) +{ + + IFNET_WLOCK_ASSERT(); + + ifindex_table[idx].ife_ifnet = ifp; +} + +struct ifaddr * +ifaddr_byindex(u_short idx) +{ + struct ifaddr *ifa; + + IFNET_RLOCK(); + ifa = ifnet_byindex(idx)->if_addr; + IFNET_RUNLOCK(); + return (ifa); +} + +struct cdev * +ifdev_byindex(u_short idx) +{ + struct cdev *cdev; + + IFNET_RLOCK(); + cdev = ifindex_table[idx].ife_dev; + IFNET_RUNLOCK(); + return (cdev); +} + +static void +ifdev_setbyindex(u_short idx, struct cdev *cdev) +{ + + IFNET_WLOCK(); + ifindex_table[idx].ife_dev = cdev; + IFNET_WUNLOCK(); +} + static d_open_t netopen; static d_close_t netclose; static d_ioctl_t netioctl; @@ -298,8 +353,8 @@ TAILQ_INIT(&ifg_head); knlist_init(&ifklist, NULL, NULL, NULL, NULL); if_grow(); /* create initial table */ - ifdev_byindex(0) = make_dev(&net_cdevsw, 0, - UID_ROOT, GID_WHEEL, 0600, "network"); + ifdev_setbyindex(0, make_dev(&net_cdevsw, 0, UID_ROOT, GID_WHEEL, + 0600, "network")); if_clone_init(); } @@ -360,7 +415,9 @@ return (NULL); } } - ifnet_byindex(ifp->if_index) = ifp; + IFNET_WLOCK(); + ifnet_setbyindex(ifp->if_index, ifp); + IFNET_WUNLOCK(); IF_ADDR_LOCK_INIT(ifp); return (ifp); @@ -394,17 +451,18 @@ return; } - IF_ADDR_LOCK_DESTROY(ifp); + IFNET_WLOCK(); + ifnet_setbyindex(ifp->if_index, NULL); - ifnet_byindex(ifp->if_index) = NULL; - /* XXX: should be locked with if_findindex() */ while (if_index > 0 && ifnet_byindex(if_index) == NULL) if_index--; + IFNET_WUNLOCK(); if (if_com_free[type] != NULL) if_com_free[type](ifp->if_l2com, type); + IF_ADDR_LOCK_DESTROY(ifp); free(ifp, M_IFNET); }; @@ -454,10 +512,9 @@ mac_ifnet_create(ifp); #endif - ifdev_byindex(ifp->if_index) = make_dev(&net_cdevsw, - unit2minor(ifp->if_index), - UID_ROOT, GID_WHEEL, 0600, "%s/%s", - net_cdevsw.d_name, ifp->if_xname); + ifdev_setbyindex(ifp->if_index, make_dev(&net_cdevsw, + unit2minor(ifp->if_index), UID_ROOT, GID_WHEEL, 0600, "%s/%s", + net_cdevsw.d_name, ifp->if_xname)); make_dev_alias(ifdev_byindex(ifp->if_index), "%s%d", net_cdevsw.d_name, ifp->if_index); @@ -706,7 +763,7 @@ */ ifp->if_addr = NULL; destroy_dev(ifdev_byindex(ifp->if_index)); - ifdev_byindex(ifp->if_index) = NULL; + ifdev_setbyindex(ifp->if_index, NULL); /* We can now free link ifaddr. */ if (!TAILQ_EMPTY(&ifp->if_addrhead)) { ==== //depot/projects/soc2008/gk_l2filter/sys-net/if_bridge.c#8 (text+ko) ==== @@ -75,7 +75,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/net/if_bridge.c,v 1.112 2008/01/18 09:34:09 thompsa Exp $"); +__FBSDID("$FreeBSD: src/sys/net/if_bridge.c,v 1.114 2008/07/03 15:58:30 thompsa Exp $"); #include "opt_inet.h" #include "opt_inet6.h" @@ -165,9 +165,13 @@ #endif /* - * List of capabilities to mask on the member interface. + * List of capabilities to possibly mask on the member interface. + */ +#define BRIDGE_IFCAPS_MASK (IFCAP_TOE|IFCAP_TSO|IFCAP_TXCSUM) +/* + * List of capabilities to disable on the member interface. */ -#define BRIDGE_IFCAPS_MASK IFCAP_TXCSUM +#define BRIDGE_IFCAPS_STRIP IFCAP_LRO /* * Bridge interface list entry. @@ -177,7 +181,7 @@ struct ifnet *bif_ifp; /* member if */ struct bstp_port bif_stp; /* STP state */ uint32_t bif_flags; /* member if flags */ - int bif_mutecap; /* member muted caps */ + int bif_savedcaps; /* saved capabilities */ uint32_t bif_addrmax; /* max # of addresses */ uint32_t bif_addrcnt; /* cur. # of addresses */ uint32_t bif_addrexceeded;/* # of address violations */ @@ -218,6 +222,7 @@ LIST_HEAD(, bridge_iflist) sc_spanlist; /* span ports list */ struct bstp_state sc_stp; /* STP state */ uint32_t sc_brtexceeded; /* # of cache drops */ + u_char sc_defaddr[6]; /* Default MAC address */ }; static struct mtx bridge_list_mtx; @@ -231,7 +236,9 @@ static void bridge_clone_destroy(struct ifnet *); static int bridge_ioctl(struct ifnet *, u_long, caddr_t); -static void bridge_mutecaps(struct bridge_iflist *, int); +static void bridge_mutecaps(struct bridge_softc *); +static void bridge_set_ifcap(struct bridge_softc *, struct bridge_iflist *, + int); static void bridge_ifdetach(void *arg __unused, struct ifnet *); static void bridge_init(void *); static void bridge_dummynet(struct mbuf *, struct ifnet *); @@ -514,7 +521,6 @@ { struct bridge_softc *sc, *sc2; struct ifnet *bifp, *ifp; - u_char eaddr[6]; int retry; sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO); @@ -556,21 +562,22 @@ * this hardware address isn't already in use on another bridge. */ for (retry = 1; retry != 0;) { - arc4rand(eaddr, ETHER_ADDR_LEN, 1); - eaddr[0] &= ~1; /* clear multicast bit */ - eaddr[0] |= 2; /* set the LAA bit */ + arc4rand(sc->sc_defaddr, ETHER_ADDR_LEN, 1); + sc->sc_defaddr[0] &= ~1; /* clear multicast bit */ + sc->sc_defaddr[0] |= 2; /* set the LAA bit */ retry = 0; mtx_lock(&bridge_list_mtx); LIST_FOREACH(sc2, &bridge_list, sc_list) { bifp = sc2->sc_ifp; - if (memcmp(eaddr, IF_LLADDR(bifp), ETHER_ADDR_LEN) == 0) + if (memcmp(sc->sc_defaddr, + IF_LLADDR(bifp), ETHER_ADDR_LEN) == 0) retry = 1; } mtx_unlock(&bridge_list_mtx); } bstp_attach(&sc->sc_stp, &bridge_ops); - ether_ifattach(ifp, eaddr); + ether_ifattach(ifp, sc->sc_defaddr); /* Now undo some of the damage... */ ifp->if_baudrate = 0; ifp->if_type = IFT_BRIDGE; @@ -744,32 +751,49 @@ * Clear or restore unwanted capabilities on the member interface */ static void -bridge_mutecaps(struct bridge_iflist *bif, int mute) +bridge_mutecaps(struct bridge_softc *sc) +{ + struct bridge_iflist *bif; + int enabled, mask; + + /* Initial bitmask of capabilities to test */ + mask = BRIDGE_IFCAPS_MASK; + + LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { + /* Every member must support it or its disabled */ + mask &= bif->bif_savedcaps; + } + + LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { + enabled = bif->bif_ifp->if_capenable; + enabled &= ~BRIDGE_IFCAPS_STRIP; + /* strip off mask bits and enable them again if allowed */ + enabled &= ~BRIDGE_IFCAPS_MASK; + enabled |= mask; + + bridge_set_ifcap(sc, bif, enabled); + } + +} + +static void +bridge_set_ifcap(struct bridge_softc *sc, struct bridge_iflist *bif, int set) { struct ifnet *ifp = bif->bif_ifp; struct ifreq ifr; int error; - if (ifp->if_ioctl == NULL) - return; - bzero(&ifr, sizeof(ifr)); - ifr.ifr_reqcap = ifp->if_capenable; + ifr.ifr_reqcap = set; - if (mute) { - /* mask off and save capabilities */ - bif->bif_mutecap = ifr.ifr_reqcap & BRIDGE_IFCAPS_MASK; - if (bif->bif_mutecap != 0) - ifr.ifr_reqcap &= ~BRIDGE_IFCAPS_MASK; - } else - /* restore muted capabilities */ - ifr.ifr_reqcap |= bif->bif_mutecap; - - - if (bif->bif_mutecap != 0) { + if (ifp->if_capenable != set) { IFF_LOCKGIANT(ifp); error = (*ifp->if_ioctl)(ifp, SIOCSIFCAP, (caddr_t)&ifr); IFF_UNLOCKGIANT(ifp); + if (error) + if_printf(sc->sc_ifp, + "error setting interface capabilities on %s\n", + ifp->if_xname); } } @@ -825,6 +849,7 @@ int gone) { struct ifnet *ifs = bif->bif_ifp; + struct ifnet *fif = NULL; BRIDGE_LOCK_ASSERT(sc); @@ -836,7 +861,6 @@ * Take the interface out of promiscuous mode. */ (void) ifpromisc(ifs, 0); - bridge_mutecaps(bif, 0); break; case IFT_GIF: @@ -848,6 +872,8 @@ #endif break; } + /* reneable any interface capabilities */ + bridge_set_ifcap(sc, bif, bif->bif_savedcaps); } if (bif->bif_flags & IFBIF_STP) @@ -858,6 +884,23 @@ LIST_REMOVE(bif, bif_next); BRIDGE_XDROP(sc); + /* + * If removing the interface that gave the bridge its mac address, set + * the mac address of the bridge to the address of the next member, or + * to its default address if no members are left. + */ + if (!memcmp(IF_LLADDR(sc->sc_ifp), IF_LLADDR(ifs), ETHER_ADDR_LEN)) { + if (LIST_EMPTY(&sc->sc_iflist)) + bcopy(sc->sc_defaddr, + IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); + else { + fif = LIST_FIRST(&sc->sc_iflist)->bif_ifp; + bcopy(IF_LLADDR(fif), + IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); + } + } + + bridge_mutecaps(sc); /* recalcuate now this interface is removed */ bridge_rtdelete(sc, ifs, IFBF_FLUSHALL); KASSERT(bif->bif_addrcnt == 0, ("%s: %d bridge routes referenced", __func__, bif->bif_addrcnt)); @@ -896,6 +939,8 @@ ifs = ifunit(req->ifbr_ifsname); if (ifs == NULL) return (ENOENT); + if (ifs->if_ioctl == NULL) /* must be supported */ + return (EINVAL); /* If it's in the span list, it can't be a member. */ LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) @@ -925,6 +970,7 @@ bif->bif_ifp = ifs; bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER; + bif->bif_savedcaps = ifs->if_capenable; switch (ifs->if_type) { case IFT_ETHER: @@ -935,8 +981,6 @@ error = ifpromisc(ifs, 1); if (error) goto out; - - bridge_mutecaps(bif, 1); break; case IFT_GIF: @@ -947,6 +991,15 @@ goto out; } + /* + * Assign the interface's MAC address to the bridge if it's the first + * member and the MAC address of the bridge has not been changed from + * the default randomly generated one. + */ + if (LIST_EMPTY(&sc->sc_iflist) && + !memcmp(IF_LLADDR(sc->sc_ifp), sc->sc_defaddr, ETHER_ADDR_LEN)) + bcopy(IF_LLADDR(ifs), IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); + ifs->if_bridge = sc; bstp_create(&sc->sc_stp, &bif->bif_stp, bif->bif_ifp); /* @@ -956,6 +1009,8 @@ */ LIST_INSERT_HEAD(&sc->sc_iflist, bif, bif_next); + /* Set interface capabilities to the intersection set of all members */ + bridge_mutecaps(sc); out: if (error) { if (bif != NULL) ==== //depot/projects/soc2008/gk_l2filter/sys-net/if_gre.c#2 (text+ko) ==== @@ -204,6 +204,7 @@ sc->called = 0; sc->gre_fibnum = curthread->td_proc->p_fibnum; sc->wccp_ver = WCCP_V1; + sc->key = 0; if_attach(GRE2IFP(sc)); bpfattach(GRE2IFP(sc), DLT_NULL, sizeof(u_int32_t)); mtx_lock(&gre_mtx); @@ -244,8 +245,8 @@ struct gre_softc *sc = ifp->if_softc; struct greip *gh; struct ip *ip; - u_short ip_id = 0; - uint8_t ip_tos = 0; + u_short gre_ip_id = 0; + uint8_t gre_ip_tos = 0; u_int16_t etype = 0; struct mobile_h mob_h; u_int32_t af; @@ -362,13 +363,13 @@ switch (dst->sa_family) { case AF_INET: ip = mtod(m, struct ip *); - ip_tos = ip->ip_tos; - ip_id = ip->ip_id; + gre_ip_tos = ip->ip_tos; + gre_ip_id = ip->ip_id; etype = ETHERTYPE_IP; break; #ifdef INET6 case AF_INET6: - ip_id = ip_newid(); + gre_ip_id = ip_newid(); etype = ETHERTYPE_IPV6; break; #endif @@ -383,7 +384,12 @@ error = EAFNOSUPPORT; goto end; } - M_PREPEND(m, sizeof(struct greip), M_DONTWAIT); + + /* Reserve space for GRE header + optional GRE key */ + int hdrlen = sizeof(struct greip); + if (sc->key) + hdrlen += sizeof(uint32_t); + M_PREPEND(m, hdrlen, M_DONTWAIT); } else { _IF_DROP(&ifp->if_snd); m_freem(m); @@ -401,9 +407,18 @@ gh = mtod(m, struct greip *); if (sc->g_proto == IPPROTO_GRE) { - /* we don't have any GRE flags for now */ + uint32_t *options = gh->gi_options; + memset((void *)gh, 0, sizeof(struct greip)); gh->gi_ptype = htons(etype); + gh->gi_flags = 0; + + /* Add key option */ + if (sc->key) + { + gh->gi_flags |= htons(GRE_KP); + *(options++) = htonl(sc->key); + } } gh->gi_pr = sc->g_proto; @@ -413,8 +428,8 @@ ((struct ip*)gh)->ip_v = IPPROTO_IPV4; ((struct ip*)gh)->ip_hl = (sizeof(struct ip)) >> 2; ((struct ip*)gh)->ip_ttl = GRE_TTL; - ((struct ip*)gh)->ip_tos = ip_tos; - ((struct ip*)gh)->ip_id = ip_id; + ((struct ip*)gh)->ip_tos = gre_ip_tos; + ((struct ip*)gh)->ip_id = gre_ip_id; gh->gi_len = m->m_pkthdr.len; } @@ -444,10 +459,12 @@ int s; struct sockaddr_in si; struct sockaddr *sa = NULL; - int error; + int error, adj; struct sockaddr_in sp, sm, dp, dm; + uint32_t key; error = 0; + adj = 0; s = splnet(); switch (cmd) { @@ -722,6 +739,30 @@ si.sin_addr.s_addr = sc->g_dst.s_addr; bcopy(&si, &ifr->ifr_addr, sizeof(ifr->ifr_addr)); break; + case GRESKEY: + error = priv_check(curthread, PRIV_NET_GRE); + if (error) + break; + error = copyin(ifr->ifr_data, &key, sizeof(key)); + if (error) + break; + /* adjust MTU for option header */ + if (key == 0 && sc->key != 0) /* clear */ + adj += sizeof(key); + else if (key != 0 && sc->key == 0) /* set */ + adj -= sizeof(key); + + if (ifp->if_mtu + adj < 576) { + error = EINVAL; + break; + } + ifp->if_mtu += adj; + sc->key = key; + break; + case GREGKEY: + error = copyout(&sc->key, ifr->ifr_data, sizeof(sc->key)); + break; + default: error = EINVAL; break; ==== //depot/projects/soc2008/gk_l2filter/sys-net/if_gre.h#2 (text+ko) ==== @@ -70,6 +70,9 @@ int called; /* infinite recursion preventer */ + uint32_t key; /* key included in outgoing GRE packets */ + /* zero means none */ + wccp_ver_t wccp_ver; /* version of the WCCP */ }; #define GRE2IFP(sc) ((sc)->sc_ifp) @@ -79,6 +82,7 @@ u_int16_t flags; /* GRE flags */ u_int16_t ptype; /* protocol type of payload typically Ether protocol type*/ + uint32_t options[0]; /* optional options */ /* * from here on: fields are optional, presence indicated by flags * @@ -111,6 +115,7 @@ #define gi_dst gi_i.ip_dst #define gi_ptype gi_g.ptype #define gi_flags gi_g.flags +#define gi_options gi_g.options #define GRE_CP 0x8000 /* Checksum Present */ #define GRE_RP 0x4000 /* Routing Present */ @@ -175,6 +180,8 @@ #define GREGADDRD _IOWR('i', 104, struct ifreq) #define GRESPROTO _IOW('i' , 105, struct ifreq) #define GREGPROTO _IOWR('i', 106, struct ifreq) +#define GREGKEY _IOWR('i', 107, struct ifreq) +#define GRESKEY _IOW('i', 108, struct ifreq) #ifdef _KERNEL LIST_HEAD(gre_softc_head, gre_softc); ==== //depot/projects/soc2008/gk_l2filter/sys-net/if_lagg.c#2 (text+ko) ==== @@ -1581,14 +1581,10 @@ struct lagg_lb *lb = (struct lagg_lb *)sc->sc_psc; struct lagg_port *lp = NULL; uint32_t p = 0; - int idx; p = lagg_hashmbuf(m, lb->lb_key); - if ((idx = p % sc->sc_count) >= LAGG_MAX_PORTS) { - m_freem(m); - return (EINVAL); - } - lp = lb->lb_ports[idx]; + p %= sc->sc_count; + lp = lb->lb_ports[p]; /* * Check the port's link state. This will return the next active ==== //depot/projects/soc2008/gk_l2filter/sys-net/if_loop.c#2 (text+ko) ==== @@ -27,7 +27,7 @@ * SUCH DAMAGE. * * @(#)if_loop.c 8.2 (Berkeley) 1/9/95 - * $FreeBSD: src/sys/net/if_loop.c,v 1.116 2008/05/09 20:38:25 rwatson Exp $ + * $FreeBSD: src/sys/net/if_loop.c,v 1.117 2008/06/29 13:17:01 ed Exp $ */ /* @@ -42,7 +42,6 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/module.h> #include <machine/bus.h> @@ -89,12 +88,6 @@ #define LOMTU 16384 #endif -#define LONAME "lo" - -struct lo_softc { - struct ifnet *sc_ifp; -}; - int loioctl(struct ifnet *, u_long, caddr_t); static void lortrequest(int, struct rtentry *, struct rt_addrinfo *); >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200807141311.m6EDBqYn014107>