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