PERFORCE change 145223 for review

Gleb Kurtsou gk at FreeBSD.org
Mon Jul 14 13:11:53 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=145223

Change 145223 by gk at 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) <<<


More information about the p4-projects mailing list