[Zrouter-src-freebsd] ZRouter.org: push to FreeBSD HEAD tree

zrouter-src-freebsd at zrouter.org zrouter-src-freebsd at zrouter.org
Fri Mar 2 15:39:52 UTC 2012


details:   http://zrouter.org/hg/FreeBSD/head//rev/4bd6486a01ce
changeset: 397:4bd6486a01ce
user:      ray at terran.dlink.ua
date:      Fri Mar 02 17:15:56 2012 +0200
description:
Update to FreeBSD-HEAD @232391

diffstat:

 head/sys/net/bridgestp.c       |   87 +++++++------
 head/sys/net/bridgestp.h       |    4 +-
 head/sys/net/flowtable.c       |    6 +-
 head/sys/net/ieee8023ad_lacp.c |    4 +-
 head/sys/net/if.c              |    6 +-
 head/sys/net/if.h              |   54 ++++++++-
 head/sys/net/if_bridge.c       |   21 ++-
 head/sys/net/if_faith.c        |    4 +-
 head/sys/net/if_lagg.c         |   21 +++-
 head/sys/net/if_lagg.h         |    6 +-
 head/sys/net/if_llatbl.h       |    6 +-
 head/sys/net/if_var.h          |   19 +--
 head/sys/net/netmap.h          |  147 +++++++++++++----------
 head/sys/net/netmap_user.h     |   28 +--
 head/sys/net/route.c           |  185 ++++++++++++++++++-----------
 head/sys/net/route.h           |    5 +-
 head/sys/net/rtsock.c          |  253 +++++++++++++++++++++++++++++++++-------
 head/sys/net/zlib.h            |    4 +-
 18 files changed, 575 insertions(+), 285 deletions(-)

diffs (1706 lines):

diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/bridgestp.c
--- a/head/sys/net/bridgestp.c	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/bridgestp.c	Fri Mar 02 17:15:56 2012 +0200
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/net/bridgestp.c 222834 2011-06-07 20:46:03Z zec $");
+__FBSDID("$FreeBSD: head/sys/net/bridgestp.c 232118 2012-02-24 17:50:36Z thompsa $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -134,7 +134,7 @@
 static void	bstp_timer_start(struct bstp_timer *, uint16_t);
 static void	bstp_timer_stop(struct bstp_timer *);
 static void	bstp_timer_latch(struct bstp_timer *);
-static int	bstp_timer_expired(struct bstp_timer *);
+static int	bstp_timer_dectest(struct bstp_timer *);
 static void	bstp_hello_timer_expiry(struct bstp_state *,
 		    struct bstp_port *);
 static void	bstp_message_age_expiry(struct bstp_state *,
@@ -446,7 +446,7 @@
 	return (flags);
 }
 
-struct mbuf *
+void
 bstp_input(struct bstp_port *bp, struct ifnet *ifp, struct mbuf *m)
 {
 	struct bstp_state *bs = bp->bp_bs;
@@ -456,7 +456,7 @@
 
 	if (bp->bp_active == 0) {
 		m_freem(m);
-		return (NULL);
+		return;
 	}
 
 	BSTP_LOCK(bs);
@@ -521,7 +521,6 @@
 	BSTP_UNLOCK(bs);
 	if (m)
 		m_freem(m);
-	return (NULL);
 }
 
 static void
@@ -1862,30 +1861,32 @@
 
 	CURVNET_SET(bs->bs_vnet);
 
-	/* slow timer to catch missed link events */
-	if (bstp_timer_expired(&bs->bs_link_timer)) {
-		LIST_FOREACH(bp, &bs->bs_bplist, bp_next)
-			bstp_ifupdstatus(bs, bp);
+	/* poll link events on interfaces that do not support linkstate */
+	if (bstp_timer_dectest(&bs->bs_link_timer)) {
+		LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
+			if (!(bp->bp_ifp->if_capabilities & IFCAP_LINKSTATE))
+				bstp_ifupdstatus(bs, bp);
+		}
 		bstp_timer_start(&bs->bs_link_timer, BSTP_LINK_TIMER);
 	}
 
 	LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
 		/* no events need to happen for these */
-		bstp_timer_expired(&bp->bp_tc_timer);
-		bstp_timer_expired(&bp->bp_recent_root_timer);
-		bstp_timer_expired(&bp->bp_forward_delay_timer);
-		bstp_timer_expired(&bp->bp_recent_backup_timer);
+		bstp_timer_dectest(&bp->bp_tc_timer);
+		bstp_timer_dectest(&bp->bp_recent_root_timer);
+		bstp_timer_dectest(&bp->bp_forward_delay_timer);
+		bstp_timer_dectest(&bp->bp_recent_backup_timer);
 
-		if (bstp_timer_expired(&bp->bp_hello_timer))
+		if (bstp_timer_dectest(&bp->bp_hello_timer))
 			bstp_hello_timer_expiry(bs, bp);
 
-		if (bstp_timer_expired(&bp->bp_message_age_timer))
+		if (bstp_timer_dectest(&bp->bp_message_age_timer))
 			bstp_message_age_expiry(bs, bp);
 
-		if (bstp_timer_expired(&bp->bp_migrate_delay_timer))
+		if (bstp_timer_dectest(&bp->bp_migrate_delay_timer))
 			bstp_migrate_delay_expiry(bs, bp);
 
-		if (bstp_timer_expired(&bp->bp_edge_delay_timer))
+		if (bstp_timer_dectest(&bp->bp_edge_delay_timer))
 			bstp_edge_delay_expiry(bs, bp);
 
 		/* update the various state machines for the port */
@@ -1924,7 +1925,7 @@
 }
 
 static int
-bstp_timer_expired(struct bstp_timer *t)
+bstp_timer_dectest(struct bstp_timer *t)
 {
 	if (t->active == 0 || t->latched)
 		return (0);
@@ -2012,24 +2013,33 @@
 	struct bstp_port *bp;
 	struct ifnet *ifp, *mif;
 	u_char *e_addr;
+	void *bridgeptr;
 	static const u_char llzero[ETHER_ADDR_LEN];	/* 00:00:00:00:00:00 */
 
 	BSTP_LOCK_ASSERT(bs);
 
+	if (LIST_EMPTY(&bs->bs_bplist))
+		goto disablestp;
+
 	mif = NULL;
+	bridgeptr = LIST_FIRST(&bs->bs_bplist)->bp_ifp->if_bridge;
+	KASSERT(bridgeptr != NULL, ("Invalid bridge pointer"));
 	/*
 	 * Search through the Ethernet adapters and find the one with the
-	 * lowest value. The adapter which we take the MAC address from does
-	 * not need to be part of the bridge, it just needs to be a unique
-	 * value.
+	 * lowest value. Make sure the adapter which we take the MAC address
+	 * from is part of this bridge, so we can have more than one independent
+	 * bridges in the same STP domain.
 	 */
 	IFNET_RLOCK_NOSLEEP();
 	TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
 		if (ifp->if_type != IFT_ETHER)
-			continue;
+			continue;	/* Not Ethernet */
+
+		if (ifp->if_bridge != bridgeptr)
+			continue;	/* Not part of our bridge */
 
 		if (bstp_addr_cmp(IF_LLADDR(ifp), llzero) == 0)
-			continue;
+			continue;	/* No mac address set */
 
 		if (mif == NULL) {
 			mif = ifp;
@@ -2041,21 +2051,8 @@
 		}
 	}
 	IFNET_RUNLOCK_NOSLEEP();
-
-	if (LIST_EMPTY(&bs->bs_bplist) || mif == NULL) {
-		/* Set the bridge and root id (lower bits) to zero */
-		bs->bs_bridge_pv.pv_dbridge_id =
-		    ((uint64_t)bs->bs_bridge_priority) << 48;
-		bs->bs_bridge_pv.pv_root_id = bs->bs_bridge_pv.pv_dbridge_id;
-		bs->bs_root_pv = bs->bs_bridge_pv;
-		/* Disable any remaining ports, they will have no MAC address */
-		LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
-			bp->bp_infois = BSTP_INFO_DISABLED;
-			bstp_set_port_role(bp, BSTP_ROLE_DISABLED);
-		}
-		callout_stop(&bs->bs_bstpcallout);
-		return;
-	}
+	if (mif == NULL)
+		goto disablestp;
 
 	e_addr = IF_LLADDR(mif);
 	bs->bs_bridge_pv.pv_dbridge_id =
@@ -2083,6 +2080,20 @@
 
 	bstp_assign_roles(bs);
 	bstp_timer_start(&bs->bs_link_timer, BSTP_LINK_TIMER);
+	return;
+
+disablestp:
+	/* Set the bridge and root id (lower bits) to zero */
+	bs->bs_bridge_pv.pv_dbridge_id =
+	    ((uint64_t)bs->bs_bridge_priority) << 48;
+	bs->bs_bridge_pv.pv_root_id = bs->bs_bridge_pv.pv_dbridge_id;
+	bs->bs_root_pv = bs->bs_bridge_pv;
+	/* Disable any remaining ports, they will have no MAC address */
+	LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
+		bp->bp_infois = BSTP_INFO_DISABLED;
+		bstp_set_port_role(bp, BSTP_ROLE_DISABLED);
+	}
+	callout_stop(&bs->bs_bstpcallout);
 }
 
 static int
diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/bridgestp.h
--- a/head/sys/net/bridgestp.h	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/bridgestp.h	Fri Mar 02 17:15:56 2012 +0200
@@ -67,7 +67,7 @@
  *
  * OpenBSD: if_bridge.h,v 1.14 2001/03/22 03:48:29 jason Exp
  *
- * $FreeBSD: head/sys/net/bridgestp.h 222834 2011-06-07 20:46:03Z zec $
+ * $FreeBSD: head/sys/net/bridgestp.h 232014 2012-02-23 00:59:21Z thompsa $
  */
 
 /*
@@ -392,6 +392,6 @@
 int	bstp_set_autoedge(struct bstp_port *, int);
 int	bstp_set_ptp(struct bstp_port *, int);
 int	bstp_set_autoptp(struct bstp_port *, int);
-struct mbuf *bstp_input(struct bstp_port *, struct ifnet *, struct mbuf *);
+void	bstp_input(struct bstp_port *, struct ifnet *, struct mbuf *);
 
 #endif /* _KERNEL */
diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/flowtable.c
--- a/head/sys/net/flowtable.c	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/flowtable.c	Fri Mar 02 17:15:56 2012 +0200
@@ -34,7 +34,7 @@
 #include "opt_inet6.h"
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/net/flowtable.c 230598 2012-01-26 20:02:40Z kmacy $");
+__FBSDID("$FreeBSD: head/sys/net/flowtable.c 231852 2012-02-17 02:39:58Z bz $");
 
 #include <sys/param.h>  
 #include <sys/types.h>
@@ -374,7 +374,7 @@
 
 #ifndef RADIX_MPATH
 static void
-in_rtalloc_ign_wrapper(struct route *ro, uint32_t hash, u_int fibnum)
+rtalloc_ign_wrapper(struct route *ro, uint32_t hash, u_int fibnum)
 {
 
 	rtalloc_ign_fib(ro, 0, fibnum);
@@ -1315,7 +1315,7 @@
 #ifdef RADIX_MPATH
 	ft->ft_rtalloc = rtalloc_mpath_fib;
 #else
-	ft->ft_rtalloc = in_rtalloc_ign_wrapper;
+	ft->ft_rtalloc = rtalloc_ign_wrapper;
 #endif
 	if (flags & FL_PCPU) {
 		ft->ft_lock = flowtable_pcpu_lock;
diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/ieee8023ad_lacp.c
--- a/head/sys/net/ieee8023ad_lacp.c	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/ieee8023ad_lacp.c	Fri Mar 02 17:15:56 2012 +0200
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/net/ieee8023ad_lacp.c 232008 2012-02-22 22:01:30Z thompsa $");
 
 #include <sys/param.h>
 #include <sys/callout.h>
@@ -812,7 +812,7 @@
 		return (NULL);
 	}
 
-	if (m->m_flags & M_FLOWID)
+	if (sc->use_flowid && (m->m_flags & M_FLOWID))
 		hash = m->m_pkthdr.flowid;
 	else
 		hash = lagg_hashmbuf(m, lsc->lsc_hashkey);
diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/if.c
--- a/head/sys/net/if.c	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/if.c	Fri Mar 02 17:15:56 2012 +0200
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)if.c	8.5 (Berkeley) 1/9/95
- * $FreeBSD: head/sys/net/if.c 229621 2012-01-05 19:00:36Z jhb $
+ * $FreeBSD: head/sys/net/if.c 231229 2012-02-08 22:05:26Z pluknet $
  */
 
 #include "opt_compat.h"
@@ -456,7 +456,6 @@
 	ifp->if_afdata_initialized = 0;
 	IF_AFDATA_LOCK_INIT(ifp);
 	TAILQ_INIT(&ifp->if_addrhead);
-	TAILQ_INIT(&ifp->if_prefixhead);
 	TAILQ_INIT(&ifp->if_multiaddrs);
 	TAILQ_INIT(&ifp->if_groups);
 #ifdef MAC
@@ -1408,7 +1407,7 @@
 }
 
 /*
- * Reference count functions for ifaddrs.
+ * Initialization, destruction and refcounting functions for ifaddrs.
  */
 void
 ifa_init(struct ifaddr *ifa)
@@ -1416,6 +1415,7 @@
 
 	mtx_init(&ifa->ifa_mtx, "ifaddr", NULL, MTX_DEF);
 	refcount_init(&ifa->ifa_refcnt, 1);
+	ifa->if_data.ifi_datalen = sizeof(ifa->if_data);
 }
 
 void
diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/if.h
--- a/head/sys/net/if.h	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/if.h	Fri Mar 02 17:15:56 2012 +0200
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)if.h	8.1 (Berkeley) 6/10/93
- * $FreeBSD: head/sys/net/if.h 228768 2011-12-21 12:39:08Z glebius $
+ * $FreeBSD: head/sys/net/if.h 231505 2012-02-11 06:02:16Z bz $
  */
 
 #ifndef _NET_IF_H_
@@ -244,6 +244,7 @@
 /*
  * Message format for use in obtaining information about interfaces
  * from getkerninfo and the routing socket
+ * For the new, extensible interface see struct if_msghdrl below.
  */
 struct if_msghdr {
 	u_short	ifm_msglen;	/* to skip over non-understood messages */
@@ -256,8 +257,34 @@
 };
 
 /*
+ * The 'l' version shall be used by new interfaces, like NET_RT_IFLISTL.  It is
+ * extensible after ifm_data_off or within ifm_data.  Both the if_msghdr and
+ * if_data now have a member field detailing the struct length in addition to
+ * the routing message length.  Macros are provided to find the start of
+ * ifm_data and the start of the socket address strucutres immediately following
+ * struct if_msghdrl given a pointer to struct if_msghdrl.
+ */
+#define	IF_MSGHDRL_IFM_DATA(_l) \
+    (struct if_data *)((char *)(_l) + (_l)->ifm_data_off)
+#define	IF_MSGHDRL_RTA(_l) \
+    (void *)((uintptr_t)(_l) + (_l)->ifm_len)
+struct if_msghdrl {
+	u_short	ifm_msglen;	/* to skip over non-understood messages */
+	u_char	ifm_version;	/* future binary compatibility */
+	u_char	ifm_type;	/* message type */
+	int	ifm_addrs;	/* like rtm_addrs */
+	int	ifm_flags;	/* value of if_flags */
+	u_short	ifm_index;	/* index for associated ifp */
+	u_short _ifm_spare1;	/* spare space to grow if_index, see if_var.h */
+	u_short	ifm_len;	/* length of if_msghdrl incl. if_data */
+	u_short	ifm_data_off;	/* offset of if_data from beginning */
+	struct	if_data ifm_data;/* statistics and other data about if */
+};
+
+/*
  * Message format for use in obtaining information about interface addresses
  * from getkerninfo and the routing socket
+ * For the new, extensible interface see struct ifa_msghdrl below.
  */
 struct ifa_msghdr {
 	u_short	ifam_msglen;	/* to skip over non-understood messages */
@@ -267,6 +294,31 @@
 	int	ifam_flags;	/* value of ifa_flags */
 	u_short	ifam_index;	/* index for associated ifp */
 	int	ifam_metric;	/* value of ifa_metric */
+};
+
+/*
+ * The 'l' version shall be used by new interfaces, like NET_RT_IFLISTL.  It is
+ * extensible after ifam_metric or within ifam_data.  Both the ifa_msghdrl and
+ * if_data now have a member field detailing the struct length in addition to
+ * the routing message length.  Macros are provided to find the start of
+ * ifm_data and the start of the socket address strucutres immediately following
+ * struct ifa_msghdrl given a pointer to struct ifa_msghdrl.
+ */
+#define	IFA_MSGHDRL_IFAM_DATA(_l) \
+    (struct if_data *)((char *)(_l) + (_l)->ifam_data_off)
+#define	IFA_MSGHDRL_RTA(_l) \
+    (void *)((uintptr_t)(_l) + (_l)->ifam_len)
+struct ifa_msghdrl {
+	u_short	ifam_msglen;	/* to skip over non-understood messages */
+	u_char	ifam_version;	/* future binary compatibility */
+	u_char	ifam_type;	/* message type */
+	int	ifam_addrs;	/* like rtm_addrs */
+	int	ifam_flags;	/* value of ifa_flags */
+	u_short	ifam_index;	/* index for associated ifp */
+	u_short _ifam_spare1;	/* spare space to grow if_index, see if_var.h */
+	u_short	ifam_len;	/* length of ifa_msghdrl incl. if_data */
+	u_short	ifam_data_off;	/* offset of if_data from beginning */
+	int	ifam_metric;	/* value of ifa_metric */
 	struct	if_data ifam_data;/* statistics and other data about if or
 				 * address */
 };
diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/if_bridge.c
--- a/head/sys/net/if_bridge.c	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/if_bridge.c	Fri Mar 02 17:15:56 2012 +0200
@@ -75,7 +75,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/net/if_bridge.c 227459 2011-11-11 22:57:52Z brooks $");
+__FBSDID("$FreeBSD: head/sys/net/if_bridge.c 232315 2012-02-29 20:58:21Z thompsa $");
 
 #include "opt_inet.h"
 #include "opt_inet6.h"
@@ -144,10 +144,10 @@
 #define	BRIDGE_RTHASH_MASK		(BRIDGE_RTHASH_SIZE - 1)
 
 /*
- * Maximum number of addresses to cache.
+ * Default maximum number of addresses to cache.
  */
 #ifndef BRIDGE_RTABLE_MAX
-#define	BRIDGE_RTABLE_MAX		100
+#define	BRIDGE_RTABLE_MAX		2000
 #endif
 
 /*
@@ -355,19 +355,26 @@
                                    locally destined packets */
 static int log_stp   = 0;   /* log STP state changes */
 static int bridge_inherit_mac = 0;   /* share MAC with first bridge member */
+TUNABLE_INT("net.link.bridge.pfil_onlyip", &pfil_onlyip);
 SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_onlyip, CTLFLAG_RW,
     &pfil_onlyip, 0, "Only pass IP packets when pfil is enabled");
+TUNABLE_INT("net.link.bridge.ipfw_arp", &pfil_ipfw_arp);
 SYSCTL_INT(_net_link_bridge, OID_AUTO, ipfw_arp, CTLFLAG_RW,
     &pfil_ipfw_arp, 0, "Filter ARP packets through IPFW layer2");
+TUNABLE_INT("net.link.bridge.pfil_bridge", &pfil_bridge);
 SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_bridge, CTLFLAG_RW,
     &pfil_bridge, 0, "Packet filter on the bridge interface");
+TUNABLE_INT("net.link.bridge.pfil_member", &pfil_member);
 SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_member, CTLFLAG_RW,
     &pfil_member, 0, "Packet filter on the member interface");
+TUNABLE_INT("net.link.bridge.pfil_local_phys", &pfil_local_phys);
 SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_local_phys, CTLFLAG_RW,
     &pfil_local_phys, 0,
     "Packet filter on the physical interface for locally destined packets");
+TUNABLE_INT("net.link.bridge.log_stp", &log_stp);
 SYSCTL_INT(_net_link_bridge, OID_AUTO, log_stp, CTLFLAG_RW,
     &log_stp, 0, "Log STP state changes");
+TUNABLE_INT("net.link.bridge.inherit_mac", &bridge_inherit_mac);
 SYSCTL_INT(_net_link_bridge, OID_AUTO, inherit_mac, CTLFLAG_RW,
     &bridge_inherit_mac, 0,
     "Inherit MAC address from the first bridge member");
@@ -2208,11 +2215,9 @@
 		/* Tap off 802.1D packets; they do not get forwarded. */
 		if (memcmp(eh->ether_dhost, bstp_etheraddr,
 		    ETHER_ADDR_LEN) == 0) {
-			m = bstp_input(&bif->bif_stp, ifp, m);
-			if (m == NULL) {
-				BRIDGE_UNLOCK(sc);
-				return (NULL);
-			}
+			bstp_input(&bif->bif_stp, ifp, m); /* consumes mbuf */
+			BRIDGE_UNLOCK(sc);
+			return (NULL);
 		}
 
 		if ((bif->bif_flags & IFBIF_STP) &&
diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/if_faith.c
--- a/head/sys/net/if_faith.c	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/if_faith.c	Fri Mar 02 17:15:56 2012 +0200
@@ -28,7 +28,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/net/if_faith.c 231852 2012-02-17 02:39:58Z bz $
  */
 /*
  * derived from
@@ -338,7 +338,7 @@
 	sin6.sin6_family = AF_INET6;
 	sin6.sin6_len = sizeof(struct sockaddr_in6);
 	sin6.sin6_addr = *in6;
-	rt = rtalloc1((struct sockaddr *)&sin6, 0, 0UL);
+	rt = in6_rtalloc1((struct sockaddr *)&sin6, 0, 0UL, RT_DEFAULT_FIB);
 	if (rt && rt->rt_ifp && rt->rt_ifp->if_type == IFT_FAITH &&
 	    (rt->rt_ifp->if_flags & IFF_UP) != 0)
 		ret = 1;
diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/if_lagg.c
--- a/head/sys/net/if_lagg.c	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/if_lagg.c	Fri Mar 02 17:15:56 2012 +0200
@@ -18,7 +18,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/net/if_lagg.c 227459 2011-11-11 22:57:52Z brooks $");
+__FBSDID("$FreeBSD: head/sys/net/if_lagg.c 232080 2012-02-23 21:56:53Z thompsa $");
 
 #include "opt_inet.h"
 #include "opt_inet6.h"
@@ -172,6 +172,11 @@
 SYSCTL_INT(_net_link_lagg, OID_AUTO, failover_rx_all, CTLFLAG_RW,
     &lagg_failover_rx_all, 0,
     "Accept input from any interface in a failover lagg");
+static int def_use_flowid = 1; /* Default value for using M_FLOWID */
+TUNABLE_INT("net.link.lagg.default_use_flowid", &def_use_flowid);
+SYSCTL_INT(_net_link_lagg, OID_AUTO, default_use_flowid, CTLFLAG_RW,
+    &def_use_flowid, 0,
+    "Default setting for using flow id for load sharing");
 
 static int
 lagg_modevent(module_t mod, int type, void *data)
@@ -262,6 +267,8 @@
 	struct ifnet *ifp;
 	int i, error = 0;
 	static const u_char eaddr[6];	/* 00:00:00:00:00:00 */
+	struct sysctl_oid *oid;
+	char num[14];			/* sufficient for 32 bits */
 
 	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
 	ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
@@ -270,6 +277,15 @@
 		return (ENOSPC);
 	}
 
+	sysctl_ctx_init(&sc->ctx);
+	snprintf(num, sizeof(num), "%u", unit);
+	sc->use_flowid = def_use_flowid;
+	oid = SYSCTL_ADD_NODE(&sc->ctx, &SYSCTL_NODE_CHILDREN(_net_link, lagg),
+		OID_AUTO, num, CTLFLAG_RD, NULL, "");
+	SYSCTL_ADD_INT(&sc->ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
+		"use_flowid", CTLTYPE_INT|CTLFLAG_RW, &sc->use_flowid, sc->use_flowid,
+		"Use flow id for load sharing");
+
 	sc->sc_proto = LAGG_PROTO_NONE;
 	for (i = 0; lagg_protos[i].ti_proto != LAGG_PROTO_NONE; i++) {
 		if (lagg_protos[i].ti_proto == LAGG_PROTO_DEFAULT) {
@@ -349,6 +365,7 @@
 
 	LAGG_WUNLOCK(sc);
 
+	sysctl_ctx_free(&sc->ctx);
 	ifmedia_removeall(&sc->sc_media);
 	ether_ifdetach(ifp);
 	if_free(ifp);
@@ -1676,7 +1693,7 @@
 	struct lagg_port *lp = NULL;
 	uint32_t p = 0;
 
-	if (m->m_flags & M_FLOWID)
+	if (sc->use_flowid && (m->m_flags & M_FLOWID))
 		p = m->m_pkthdr.flowid;
 	else
 		p = lagg_hashmbuf(m, lb->lb_key);
diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/if_lagg.h
--- a/head/sys/net/if_lagg.h	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/if_lagg.h	Fri Mar 02 17:15:56 2012 +0200
@@ -15,12 +15,14 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/net/if_lagg.h 232008 2012-02-22 22:01:30Z thompsa $
  */
 
 #ifndef _NET_LAGG_H
 #define _NET_LAGG_H
 
+#include <sys/sysctl.h>
+
 /*
  * Global definitions
  */
@@ -202,6 +204,8 @@
 	eventhandler_tag vlan_attach;
 	eventhandler_tag vlan_detach;
 #endif
+	struct sysctl_ctx_list		ctx;		/* sysctl variables */
+	int				use_flowid;	/* use M_FLOWID */
 };
 
 struct lagg_port {
diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/if_llatbl.h
--- a/head/sys/net/if_llatbl.h	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/if_llatbl.h	Fri Mar 02 17:15:56 2012 +0200
@@ -25,7 +25,7 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/net/if_llatbl.h 225698 2011-09-20 20:27:26Z kmacy $");
+__FBSDID("$FreeBSD: head/sys/net/if_llatbl.h 232054 2012-02-23 18:21:37Z kmacy $");
 
 #ifndef	_NET_IF_LLATBL_H_
 #define	_NET_IF_LLATBL_H_
@@ -106,7 +106,6 @@
 		("negative refcnt %d", (lle)->lle_refcnt));	\
 	(lle)->lle_refcnt++;					\
 } while (0)
-
 #define	LLE_REMREF(lle)	do {					\
 	LLE_WLOCK_ASSERT(lle);					\
 	KASSERT((lle)->lle_refcnt > 1,				\
@@ -116,7 +115,7 @@
 
 #define	LLE_FREE_LOCKED(lle) do {				\
 	if ((lle)->lle_refcnt <= 1)				\
-		(lle)->lle_tbl->llt_free((lle)->lle_tbl, (lle));\
+		(lle)->lle_free((lle)->lle_tbl, (lle));\
 	else {							\
 		(lle)->lle_refcnt--;				\
 		LLE_WUNLOCK(lle);				\
@@ -152,7 +151,6 @@
 	int			llt_af;
 	struct ifnet		*llt_ifp;
 
-	void			(*llt_free)(struct lltable *, struct llentry *);
 	void			(*llt_prefix_free)(struct lltable *,
 				    const struct sockaddr *prefix,
 				    const struct sockaddr *mask,
diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/if_var.h
--- a/head/sys/net/if_var.h	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/if_var.h	Fri Mar 02 17:15:56 2012 +0200
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *	From: @(#)if.h	8.1 (Berkeley) 6/10/93
- * $FreeBSD: head/sys/net/if_var.h 229873 2012-01-09 19:34:12Z jhb $
+ * $FreeBSD: head/sys/net/if_var.h 231229 2012-02-08 22:05:26Z pluknet $
  */
 
 #ifndef	_NET_IF_VAR_H_
@@ -96,7 +96,6 @@
 
 TAILQ_HEAD(ifnethead, ifnet);	/* we use TAILQs so that the order of */
 TAILQ_HEAD(ifaddrhead, ifaddr);	/* instantiation is preserved in the list */
-TAILQ_HEAD(ifprefixhead, ifprefix);
 TAILQ_HEAD(ifmultihead, ifmultiaddr);
 TAILQ_HEAD(ifgrouphead, ifg_group);
 
@@ -184,7 +183,7 @@
 	struct	label *if_label;	/* interface MAC label */
 
 	/* these are only used by IPv6 */
-	struct	ifprefixhead if_prefixhead; /* list of prefixes per if */
+	void	*if_unused[2];
 	void	*if_afdata[AF_MAX];
 	int	if_afdata_initialized;
 	struct	rwlock if_afdata_lock;
@@ -762,20 +761,6 @@
 #endif
 
 /*
- * The prefix structure contains information about one prefix
- * of an interface.  They are maintained by the different address families,
- * are allocated and attached when a prefix or an address is set,
- * and are linked together so all prefixes for an interface can be located.
- */
-struct ifprefix {
-	struct	sockaddr *ifpr_prefix;	/* prefix of interface */
-	struct	ifnet *ifpr_ifp;	/* back-pointer to interface */
-	TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */
-	u_char	ifpr_plen;		/* prefix length in bits */
-	u_char	ifpr_type;		/* protocol dependent prefix type */
-};
-
-/*
  * Multicast address structure.  This is analogous to the ifaddr
  * structure except that it keeps track of multicast addresses.
  */
diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/netmap.h
--- a/head/sys/net/netmap.h	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/netmap.h	Fri Mar 02 17:15:56 2012 +0200
@@ -31,12 +31,14 @@
  */
 
 /*
- * $FreeBSD: head/sys/net/netmap.h 228276 2011-12-05 12:06:53Z luigi $
- * $Id: netmap.h 9753 2011-11-28 15:10:43Z luigi $
+ * $FreeBSD: head/sys/net/netmap.h 232238 2012-02-27 19:05:01Z luigi $
+ * $Id: netmap.h 10601 2012-02-21 16:40:14Z luigi $
  *
- * This header contains the definitions of the constants and the
- * structures needed by the ``netmap'' module, both kernel and
- * userspace.
+ * Definitions of constants and the structures used by the netmap
+ * framework, for the part visible to both kernel and userspace.
+ * Detailed info on netmap is available with "man netmap" or at
+ * 
+ *	http://info.iet.unipi.it/~luigi/netmap/
  */
 
 #ifndef _NET_NETMAP_H_
@@ -48,14 +50,8 @@
  * The data structures used by netmap are shown below. Those in
  * capital letters are in an mmapp()ed area shared with userspace,
  * while others are private to the kernel.
- * Shared structures do not contain pointers but only relative
+ * Shared structures do not contain pointers but only memory
  * offsets, so that addressing is portable between kernel and userspace.
- *
- * The 'softc' of each interface is extended with a struct netmap_adapter
- * containing information to support netmap operation. In addition to
- * the fixed fields, it has two pointers to reach the arrays of
- * 'struct netmap_kring' which in turn reaches the various
- * struct netmap_ring, shared with userspace.
 
 
  softc
@@ -67,19 +63,22 @@
 +----------------+<------+
 |(netmap_adapter)|
 |                |                             netmap_kring
-| tx_rings *--------------------------------->+-------------+
-|                |       netmap_kring         | ring *---------> ...
-| rx_rings *---------->+--------------+       | nr_hwcur    |
-+----------------+     | ring    *-------+    | nr_hwavail  |
-                       | nr_hwcur     |  |    | selinfo     |
-                       | nr_hwavail   |  |    +-------------+
-                       | selinfo      |  |    |     ...     |
-                       +--------------+  |  (na_num_rings+1 entries)
-                       |    ....      |  |    |             |
-                    (na_num_rings+1 entries)  +-------------+
-                       |              |  |
-                       +--------------+  |
-                                         |      NETMAP_RING
+| tx_rings *--------------------------------->+---------------+
+|                |       netmap_kring         | ring    *---------.
+| rx_rings *--------->+---------------+       | nr_hwcur      |   |
++----------------+    | ring    *--------.    | nr_hwavail    |   V
+                      | nr_hwcur      |  |    | selinfo       |   |
+                      | nr_hwavail    |  |    +---------------+   .
+                      | selinfo       |  |    |     ...       |   .
+                      +---------------+  |    |(ntx+1 entries)|
+                      |    ....       |  |    |               |
+                      |(nrx+1 entries)|  |    +---------------+
+                      |               |  |
+   KERNEL             +---------------+  |
+                                         |
+  ====================================================================
+                                         |
+   USERSPACE                             |      NETMAP_RING
                                          +---->+-------------+
                                              / | cur         |
    NETMAP_IF  (nifp, one per file desc.)    /  | avail       |
@@ -100,16 +99,23 @@
     | txring_ofs[n] |
     +---------------+
 
- * The NETMAP_RING is the shadow ring that mirrors the NIC rings.
+ * The private descriptor ('softc' or 'adapter') of each interface
+ * is extended with a "struct netmap_adapter" containing netmap-related
+ * info (see description in dev/netmap/netmap_kernel.h.
+ * Among other things, tx_rings and rx_rings point to the arrays of
+ * "struct netmap_kring" which in turn reache the various
+ * "struct netmap_ring", shared with userspace.
+
+ * The NETMAP_RING is the userspace-visible replica of the NIC ring.
  * Each slot has the index of a buffer, its length and some flags.
  * In user space, the buffer address is computed as
- *	(char *)ring + buf_ofs + index*MAX_BUF_SIZE
+ *	(char *)ring + buf_ofs + index*NETMAP_BUF_SIZE
  * In the kernel, buffers do not necessarily need to be contiguous,
  * and the virtual and physical addresses are derived through
- * a lookup table. When userspace wants to use a different buffer
- * in a location, it must set the NS_BUF_CHANGED flag to make
- * sure that the kernel recomputes updates the hardware ring and
- * other fields (bus_dmamap, etc.) as needed.
+ * a lookup table.
+ * To associate a different buffer to a slot, applications must
+ * write the new index in buf_idx, and set NS_BUF_CHANGED flag to
+ * make sure that the kernel updates the hardware ring as needed.
  *
  * Normally the driver is not requested to report the result of
  * transmissions (this can dramatically speed up operation).
@@ -133,13 +139,16 @@
  *
  * In TX rings:
  *	avail	indicates the number of slots available for transmission.
- *		It is decremented by the application when it appends a
- *		packet, and set to nr_hwavail (see below) on a
- *		NIOCTXSYNC to reflect the actual state of the queue
- *		(keeping track of completed transmissions).
- *	cur	indicates the empty slot to use for the next packet
+ *		It is updated by the kernel after every netmap system call.
+ *		It MUST BE decremented by the application when it appends a
+ *		packet.
+ *	cur	indicates the slot to use for the next packet
  *		to send (i.e. the "tail" of the queue).
- *		It is incremented by the application.
+ *		It MUST BE incremented by the application before
+ *		netmap system calls to reflect the number of newly
+ *		sent packets.
+ *		It is checked by the kernel on netmap system calls
+ *		(normally unmodified by the kernel unless invalid).
  *
  *   The kernel side of netmap uses two additional fields in its own
  *   private ring structure, netmap_kring:
@@ -153,12 +162,17 @@
  *
  * In RX rings:
  *	avail	is the number of packets available (possibly 0).
- *		It is decremented by the software when it consumes
- *		a packet, and set to nr_hwavail on a NIOCRXSYNC
- *	cur	indicates the first slot that contains a packet
- *		(the "head" of the queue).
- *		It is incremented by the software when it consumes
+ *		It MUST BE decremented by the application when it consumes
+ *		a packet, and it is updated to nr_hwavail on a NIOCRXSYNC
+ *	cur	indicates the first slot that contains a packet not
+ *		processed yet (the "head" of the queue).
+ *		It MUST BE incremented by the software when it consumes
  *		a packet.
+ *	reserved	indicates the number of buffers before 'cur'
+ *		that the application has still in use. Normally 0,
+ *		it MUST BE incremented by the application when it
+ *		does not return the buffer immediately, and decremented
+ *		when the buffer is finally freed.
  *
  *   The kernel side of netmap uses two additional fields in the kring:
  *	nr_hwcur is a copy of nr_cur on an NIOCRXSYNC
@@ -182,7 +196,8 @@
 	const ssize_t	buf_ofs;
 	const uint32_t	num_slots;	/* number of slots in the ring. */
 	uint32_t	avail;		/* number of usable slots */
-	uint32_t	cur;		/* 'current' r/w position */
+	uint32_t        cur;		/* 'current' r/w position */
+	uint32_t	reserved;	/* not refilled before current */
 
 	const uint16_t	nr_buf_size;
 	uint16_t	flags;
@@ -191,7 +206,7 @@
 	struct timeval	ts;		/* time of last *sync() */
 
 	/* the slots follow. This struct has variable size */
-	struct netmap_slot slot[0]; /* array of slots. */
+	struct netmap_slot slot[0];	/* array of slots. */
 };
 
 
@@ -204,24 +219,23 @@
  * nmr_queueid passed on the ioctl.
  */
 struct netmap_if {
-	char ni_name[IFNAMSIZ]; /* name of the interface. */
-	const u_int ni_version;	/* API version, currently unused */
-	const u_int ni_num_queues; /* number of queue pairs (TX/RX). */
-	const u_int ni_rx_queues;  /* if zero, use ni_num_queues */
+	char		ni_name[IFNAMSIZ]; /* name of the interface. */
+	const u_int	ni_version;	/* API version, currently unused */
+	const u_int	ni_rx_queues;	/* number of rx queue pairs */
+	const u_int	ni_tx_queues;	/* if zero, same as ni_tx_queues */
 	/*
-	 * the following array contains the offset of the
-	 * each netmap ring from this structure. The first num_queues+1
-	 * refer to the tx rings, the next n+1 refer to the rx rings.
+	 * The following array contains the offset of each netmap ring
+	 * from this structure. The first ni_tx_queues+1 entries refer
+	 * to the tx rings, the next ni_rx_queues+1 refer to the rx rings
+	 * (the last entry in each block refers to the host stack rings).
 	 * The area is filled up by the kernel on NIOCREG,
 	 * and then only read by userspace code.
-	 * entries 0..ni_num_queues-1 indicate the hardware queues,
-	 * entry ni_num_queues is the queue from/to the stack.
 	 */
 	const ssize_t	ring_ofs[0];
 };
 
-#ifndef IFCAP_NETMAP	/* this should go in net/if.h */
-#define	IFCAP_NETMAP	0x100000
+#ifndef IFCAP_NETMAP
+#define IFCAP_NETMAP	0x100000	/* used on linux */
 #endif
 
 #ifndef NIOCREGIF	
@@ -246,24 +260,29 @@
  */
 struct nmreq {
 	char		nr_name[IFNAMSIZ];
-	uint32_t	nr_version;	/* API version (unused) */
+	uint32_t	nr_version;	/* API version */
+#define	NETMAP_API	2		/* current version */
 	uint32_t	nr_offset;	/* nifp offset in the shared region */
 	uint32_t	nr_memsize;	/* size of the shared region */
-	uint32_t	nr_numslots;	/* descriptors per queue */
-	uint16_t	nr_numrings;
+	uint32_t	nr_tx_slots;	/* slots in tx rings */
+	uint32_t	nr_rx_slots;	/* slots in rx rings */
+	uint16_t	nr_tx_rings;	/* number of tx rings */
+	uint16_t	nr_rx_rings;	/* number of rx rings */
 	uint16_t	nr_ringid;	/* ring(s) we care about */
 #define NETMAP_HW_RING	0x4000		/* low bits indicate one hw ring */
-#define NETMAP_SW_RING	0x2000		/* we process the sw ring */
-#define NETMAP_NO_TX_POLL	0x1000	/* no gratuitous txsync on poll */
+#define NETMAP_SW_RING	0x2000		/* process the sw ring */
+#define NETMAP_NO_TX_POLL	0x1000	/* no automatic txsync on poll */
 #define NETMAP_RING_MASK 0xfff		/* the ring number */
+	uint16_t	spare1;
+	uint32_t	spare2[4];
 };
 
 /*
- * default buf size is 2048, but it may make sense to have
- * it shorter for better cache usage.
+ * FreeBSD uses the size value embedded in the _IOWR to determine
+ * how much to copy in/out. So we need it to match the actual
+ * data structure we pass. We put some spares in the structure
+ * to ease compatibility with other versions
  */
-
-#define	NETMAP_BUF_SIZE	(2048)
 #define NIOCGINFO	_IOWR('i', 145, struct nmreq) /* return IF info */
 #define NIOCREGIF	_IOWR('i', 146, struct nmreq) /* interface register */
 #define NIOCUNREGIF	_IO('i', 147) /* interface unregister */
diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/netmap_user.h
--- a/head/sys/net/netmap_user.h	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/netmap_user.h	Fri Mar 02 17:15:56 2012 +0200
@@ -31,15 +31,14 @@
  */
 
 /*
- * $FreeBSD: head/sys/net/netmap_user.h 227614 2011-11-17 12:17:39Z luigi $
- * $Id: netmap_user.h 9495 2011-10-18 15:28:23Z luigi $
+ * $FreeBSD: head/sys/net/netmap_user.h 232238 2012-02-27 19:05:01Z luigi $
+ * $Id: netmap_user.h 10597 2012-02-21 05:08:32Z luigi $
  *
  * This header contains the macros used to manipulate netmap structures
  * and packets in userspace. See netmap(4) for more information.
  *
- * The address of the struct netmap_if, say nifp, is determined
- * by the value returned from ioctl(.., NIOCREG, ...) and the mmap
- * region:
+ * The address of the struct netmap_if, say nifp, is computed from the
+ * value returned from ioctl(.., NIOCREG, ...) and the mmap region:
  *	ioctl(fd, NIOCREG, &req);
  *	mem = mmap(0, ... );
  *	nifp = NETMAP_IF(mem, req.nr_nifp);
@@ -71,27 +70,20 @@
 
 #define NETMAP_RXRING(nifp, index)			\
 	((struct netmap_ring *)((char *)(nifp) +	\
-	    (nifp)->ring_ofs[index + (nifp)->ni_num_queues+1] ) )
+	    (nifp)->ring_ofs[index + (nifp)->ni_tx_queues+1] ) )
 
-#if NETMAP_BUF_SIZE != 2048
-#error cannot handle odd size
 #define NETMAP_BUF(ring, index)				\
-	((char *)(ring) + (ring)->buf_ofs + ((index)*NETMAP_BUF_SIZE))
-#else
-#define NETMAP_BUF(ring, index)				\
-	((char *)(ring) + (ring)->buf_ofs + ((index)<<11))
-#endif
+	((char *)(ring) + (ring)->buf_ofs + ((index)*(ring)->nr_buf_size))
+
+#define NETMAP_BUF_IDX(ring, buf)			\
+	( ((char *)(buf) - ((char *)(ring) + (ring)->buf_ofs) ) / \
+		(ring)->nr_buf_size) ) 
 
 #define	NETMAP_RING_NEXT(r, i)				\
 	((i)+1 == (r)->num_slots ? 0 : (i) + 1 )
 
 /*
  * Return 1 if the given tx ring is empty.
- *
- * @r netmap_ring descriptor pointer.
- * Special case, a negative value in hwavail indicates that the
- * transmit queue is idle.
- * XXX revise
  */
 #define NETMAP_TX_RING_EMPTY(r)	((r)->avail >= (r)->num_slots - 1)
 
diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/route.c
--- a/head/sys/net/route.c	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/route.c	Fri Mar 02 17:15:56 2012 +0200
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)route.c	8.3.1.1 (Berkeley) 2/23/95
- * $FreeBSD: head/sys/net/route.c 230510 2012-01-24 15:20:31Z bz $
+ * $FreeBSD: head/sys/net/route.c 231852 2012-02-17 02:39:58Z bz $
  */
 /************************************************************************
  * Note: In this file a 'fib' is a "forwarding information base"	*
@@ -35,6 +35,7 @@
  ***********************************************************************/
 
 #include "opt_inet.h"
+#include "opt_inet6.h"
 #include "opt_route.h"
 #include "opt_mrouting.h"
 #include "opt_mpath.h"
@@ -72,7 +73,11 @@
 /*
  * Allow the boot code to allow LESS than RT_MAXFIBS to be used.
  * We can't do more because storage is statically allocated for now.
- * (for compatibility reasons.. this will change).
+ * (for compatibility reasons.. this will change. When this changes, code should
+ * be refactored to protocol independent parts and protocol dependent parts,
+ * probably hanging of domain(9) specific storage to not need the full
+ * fib * af RNH allocation etc. but allow tuning the number of tables per
+ * address family).
  */
 TUNABLE_INT("net.fibs", &rt_numfibs);
 
@@ -82,6 +87,9 @@
  * changes for the FIB of the caller when adding a new set of addresses
  * to an interface.  XXX this is a shotgun aproach to a problem that needs
  * a more fine grained solution.. that will come.
+ * XXX also has the problems getting the FIB from curthread which will not
+ * always work given the fib can be overridden and prefixes can be added
+ * from the network stack context.
  */
 u_int rt_add_addr_allfibs = 1;
 SYSCTL_UINT(_net, OID_AUTO, add_addr_allfibs, CTLFLAG_RW,
@@ -196,27 +204,23 @@
 	V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry), NULL, NULL,
 	    NULL, NULL, UMA_ALIGN_PTR, 0);
 	for (dom = domains; dom; dom = dom->dom_next) {
-		if (dom->dom_rtattach)  {
-			for  (table = 0; table < rt_numfibs; table++) {
-				if ( (fam = dom->dom_family) == AF_INET ||
-				    table == 0) {
- 			        	/* for now only AF_INET has > 1 table */
-					/* XXX MRT 
-					 * rtattach will be also called
-					 * from vfs_export.c but the
-					 * offset will be 0
-					 * (only for AF_INET and AF_INET6
-					 * which don't need it anyhow)
-					 */
-					rnh = rt_tables_get_rnh_ptr(table, fam);
-					if (rnh == NULL)
-						panic("%s: rnh NULL", __func__);
-					dom->dom_rtattach((void **)rnh,
-				    	    dom->dom_rtoffset);
-				} else {
-					break;
-				}
-			}
+		if (dom->dom_rtattach == NULL)
+			continue;
+
+		for  (table = 0; table < rt_numfibs; table++) {
+			fam = dom->dom_family;
+			if (table != 0 && fam != AF_INET6 && fam != AF_INET)
+				break;
+
+			/*
+			 * XXX MRT rtattach will be also called from
+			 * vfs_export.c but the offset will be 0 (only for
+			 * AF_INET and AF_INET6 which don't need it anyhow).
+			 */
+			rnh = rt_tables_get_rnh_ptr(table, fam);
+			if (rnh == NULL)
+				panic("%s: rnh NULL", __func__);
+			dom->dom_rtattach((void **)rnh, dom->dom_rtoffset);
 		}
 	}
 }
@@ -233,20 +237,19 @@
 	struct radix_node_head **rnh;
 
 	for (dom = domains; dom; dom = dom->dom_next) {
-		if (dom->dom_rtdetach) {
-			for (table = 0; table < rt_numfibs; table++) {
-				if ( (fam = dom->dom_family) == AF_INET ||
-				    table == 0) {
-					/* For now only AF_INET has > 1 tbl. */
-					rnh = rt_tables_get_rnh_ptr(table, fam);
-					if (rnh == NULL)
-						panic("%s: rnh NULL", __func__);
-					dom->dom_rtdetach((void **)rnh,
-					    dom->dom_rtoffset);
-				} else {
-					break;
-				}
-			}
+		if (dom->dom_rtdetach == NULL)
+			continue;
+
+		for (table = 0; table < rt_numfibs; table++) {
+			fam = dom->dom_family;
+
+			if (table != 0 && fam != AF_INET6 && fam != AF_INET)
+				break;
+
+			rnh = rt_tables_get_rnh_ptr(table, fam);
+			if (rnh == NULL)
+				panic("%s: rnh NULL", __func__);
+			dom->dom_rtdetach((void **)rnh, dom->dom_rtoffset);
 		}
 	}
 }
@@ -274,7 +277,8 @@
 void
 rtalloc(struct route *ro)
 {
-	rtalloc_ign_fib(ro, 0UL, 0);
+
+	rtalloc_ign_fib(ro, 0UL, RT_DEFAULT_FIB);
 }
 
 void
@@ -294,7 +298,7 @@
 		RTFREE(rt);
 		ro->ro_rt = NULL;
 	}
-	ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, ignore, 0);
+	ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, ignore, RT_DEFAULT_FIB);
 	if (ro->ro_rt)
 		RT_UNLOCK(ro->ro_rt);
 }
@@ -324,7 +328,8 @@
 struct rtentry *
 rtalloc1(struct sockaddr *dst, int report, u_long ignflags)
 {
-	return (rtalloc1_fib(dst, report, ignflags, 0));
+
+	return (rtalloc1_fib(dst, report, ignflags, RT_DEFAULT_FIB));
 }
 
 struct rtentry *
@@ -339,8 +344,15 @@
 	int needlock;
 
 	KASSERT((fibnum < rt_numfibs), ("rtalloc1_fib: bad fibnum"));
-	if (dst->sa_family != AF_INET)	/* Only INET supports > 1 fib now */
-		fibnum = 0;
+	switch (dst->sa_family) {
+	case AF_INET6:
+	case AF_INET:
+		/* We support multiple FIBs. */
+		break;
+	default:
+		fibnum = RT_DEFAULT_FIB;
+		break;
+	}
 	rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
 	newrt = NULL;
 	if (rnh == NULL)
@@ -486,7 +498,8 @@
 	int flags,
 	struct sockaddr *src)
 {
-	rtredirect_fib(dst, gateway, netmask, flags, src, 0);
+
+	rtredirect_fib(dst, gateway, netmask, flags, src, RT_DEFAULT_FIB);
 }
 
 void
@@ -617,7 +630,8 @@
 int
 rtioctl(u_long req, caddr_t data)
 {
-	return (rtioctl_fib(req, data, 0));
+
+	return (rtioctl_fib(req, data, RT_DEFAULT_FIB));
 }
 
 /*
@@ -647,7 +661,8 @@
 struct ifaddr *
 ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway)
 {
-	return (ifa_ifwithroute_fib(flags, dst, gateway, 0));
+
+	return (ifa_ifwithroute_fib(flags, dst, gateway, RT_DEFAULT_FIB));
 }
 
 struct ifaddr *
@@ -732,7 +747,9 @@
 	int flags,
 	struct rtentry **ret_nrt)
 {
-	return (rtrequest_fib(req, dst, gateway, netmask, flags, ret_nrt, 0));
+
+	return (rtrequest_fib(req, dst, gateway, netmask, flags, ret_nrt,
+	    RT_DEFAULT_FIB));
 }
 
 int
@@ -771,7 +788,8 @@
 int
 rt_getifa(struct rt_addrinfo *info)
 {
-	return (rt_getifa_fib(info, 0));
+
+	return (rt_getifa_fib(info, RT_DEFAULT_FIB));
 }
 
 /*
@@ -1029,8 +1047,16 @@
 #define senderr(x) { error = x ; goto bad; }
 
 	KASSERT((fibnum < rt_numfibs), ("rtrequest1_fib: bad fibnum"));
-	if (dst->sa_family != AF_INET)	/* Only INET supports > 1 fib now */
-		fibnum = 0;
+	switch (dst->sa_family) {
+	case AF_INET6:
+	case AF_INET:
+		/* We support multiple FIBs. */
+		break;
+	default:
+		fibnum = RT_DEFAULT_FIB;
+		break;
+	}
+
 	/*
 	 * Find the correct routing tree to use for this Address Family
 	 */
@@ -1135,8 +1161,7 @@
 		rt->rt_flags = RTF_UP | flags;
 		rt->rt_fibnum = fibnum;
 		/*
-		 * Add the gateway. Possibly re-malloc-ing the storage for it
-		 * 
+		 * Add the gateway. Possibly re-malloc-ing the storage for it.
 		 */
 		RT_LOCK(rt);
 		if ((error = rt_setgate(rt, dst, gateway)) != 0) {
@@ -1182,12 +1207,15 @@
 
 #ifdef FLOWTABLE
 		rt0 = NULL;
-		/* XXX
-		 * "flow-table" only support IPv4 at the moment.
-		 * XXX-BZ as of r205066 it would support IPv6.
-		 */
+		/* "flow-table" only supports IPv6 and IPv4 at the moment. */
+		switch (dst->sa_family) {
+#ifdef INET6
+		case AF_INET6:
+#endif
 #ifdef INET
-		if (dst->sa_family == AF_INET) {
+		case AF_INET:
+#endif
+#if defined(INET6) || defined(INET)
 			rn = rnh->rnh_matchaddr(dst, rnh);
 			if (rn && ((rn->rn_flags & RNF_ROOT) == 0)) {
 				struct sockaddr *mask;
@@ -1226,9 +1254,9 @@
 					}
 				}
 			}
+#endif/* INET6 || INET */
 		}
-#endif
-#endif
+#endif /* FLOWTABLE */
 
 		/* XXX mtu manipulation will be done in rnh_addaddr -- itojun */
 		rn = rnh->rnh_addaddr(ndst, netmask, rnh, rt->rt_nodes);
@@ -1249,9 +1277,18 @@
 		} 
 #ifdef FLOWTABLE
 		else if (rt0 != NULL) {
+			switch (dst->sa_family) {
+#ifdef INET6
+			case AF_INET6:
+				flowtable_route_flush(V_ip6_ft, rt0);
+				break;
+#endif
 #ifdef INET
-			flowtable_route_flush(V_ip_ft, rt0);
+			case AF_INET:
+				flowtable_route_flush(V_ip_ft, rt0);
+				break;
 #endif
+			}
 			RTFREE(rt0);
 		}
 #endif
@@ -1383,8 +1420,17 @@
 		dst = ifa->ifa_addr;
 		netmask = ifa->ifa_netmask;
 	}
-	if ( dst->sa_family != AF_INET)
-		fibnum = 0;
+	if (dst->sa_len == 0)
+		return(EINVAL);
+	switch (dst->sa_family) {
+	case AF_INET6:
+	case AF_INET:
+		/* We support multiple FIBs. */
+		break;
+	default:
+		fibnum = RT_DEFAULT_FIB;
+		break;
+	}
 	if (fibnum == -1) {
 		if (rt_add_addr_allfibs == 0 && cmd == (int)RTM_ADD) {
 			startfib = endfib = curthread->td_proc->p_fibnum;
@@ -1397,8 +1443,6 @@
 		startfib = fibnum;
 		endfib = fibnum;
 	}
-	if (dst->sa_len == 0)
-		return(EINVAL);
 
 	/*
 	 * If it's a delete, check that if it exists,
@@ -1422,9 +1466,7 @@
 	 * Now go through all the requested tables (fibs) and do the
 	 * requested action. Realistically, this will either be fib 0
 	 * for protocols that don't do multiple tables or all the
-	 * tables for those that do. XXX For this version only AF_INET.
-	 * When that changes code should be refactored to protocol
-	 * independent parts and protocol dependent parts.
+	 * tables for those that do.
 	 */
 	for ( fibnum = startfib; fibnum <= endfib; fibnum++) {
 		if (cmd == RTM_DELETE) {
@@ -1564,12 +1606,14 @@
 	return (error);
 }
 
+#ifndef BURN_BRIDGES
 /* special one for inet internal use. may not use. */
 int
 rtinit_fib(struct ifaddr *ifa, int cmd, int flags)
 {
 	return (rtinit1(ifa, cmd, flags, -1));
 }
+#endif
 
 /*
  * Set up a routing table entry, normally
@@ -1579,7 +1623,7 @@
 rtinit(struct ifaddr *ifa, int cmd, int flags)
 {
 	struct sockaddr *dst;
-	int fib = 0;
+	int fib = RT_DEFAULT_FIB;
 
 	if (flags & RTF_HOST) {
 		dst = ifa->ifa_dstaddr;
@@ -1587,7 +1631,12 @@
 		dst = ifa->ifa_addr;
 	}
 
-	if (dst->sa_family == AF_INET)
+	switch (dst->sa_family) {
+	case AF_INET6:
+	case AF_INET:
+		/* We do support multiple FIBs. */
 		fib = -1;
+		break;
+	}
 	return (rtinit1(ifa, cmd, flags, fib));
 }
diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/route.h
--- a/head/sys/net/route.h	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/route.h	Fri Mar 02 17:15:56 2012 +0200
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)route.h	8.4 (Berkeley) 1/9/95
- * $FreeBSD: head/sys/net/route.h 225837 2011-09-28 13:48:36Z bz $
+ * $FreeBSD: head/sys/net/route.h 231852 2012-02-17 02:39:58Z bz $
  */
 
 #ifndef _NET_ROUTE_H_
@@ -111,6 +111,7 @@
  #endif
 #endif
 
+#define	RT_DEFAULT_FIB	0	/* Explicitly mark fib=0 restricted cases */
 extern u_int rt_numfibs;	/* number fo usable routing tables */
 /*
  * XXX kernel function pointer `rt_output' is visible to applications.
@@ -405,8 +406,10 @@
 int	 rtrequest(int, struct sockaddr *,
 	    struct sockaddr *, struct sockaddr *, int, struct rtentry **);
 
+#ifndef BURN_BRIDGES
 /* defaults to "all" FIBs */
 int	 rtinit_fib(struct ifaddr *, int, int);
+#endif
 
 /* XXX MRT NEW VERSIONS THAT USE FIBs
  * For now the protocol indepedent versions are the same as the AF_INET ones
diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/rtsock.c
--- a/head/sys/net/rtsock.c	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/rtsock.c	Fri Mar 02 17:15:56 2012 +0200
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)rtsock.c	8.7 (Berkeley) 10/12/95
- * $FreeBSD: head/sys/net/rtsock.c 229814 2012-01-08 17:11:53Z glebius $
+ * $FreeBSD: head/sys/net/rtsock.c 231505 2012-02-11 06:02:16Z bz $
  */
 #include "opt_compat.h"
 #include "opt_sctp.h"
@@ -115,7 +115,34 @@
 	uint16_t ifm_index;
 	struct	if_data32 ifm_data;
 };
-#endif
+
+struct if_msghdrl32 {
+	uint16_t ifm_msglen;
+	uint8_t	ifm_version;
+	uint8_t	ifm_type;
+	int32_t	ifm_addrs;
+	int32_t	ifm_flags;
+	uint16_t ifm_index;
+	uint16_t _ifm_spare1;
+	uint16_t ifm_len;
+	uint16_t ifm_data_off;
+	struct	if_data32 ifm_data;
+};
+
+struct ifa_msghdrl32 {
+	uint16_t ifam_msglen;
+	uint8_t	ifam_version;
+	uint8_t	ifam_type;
+	int32_t	ifam_addrs;
+	int32_t	ifam_flags;
+	uint16_t ifam_index;
+	uint16_t _ifam_spare1;
+	uint16_t ifam_len;
+	uint16_t ifam_data_off;
+	int32_t	ifam_metric;
+	struct	if_data32 ifam_data;
+};
+#endif /* COMPAT_FREEBSD32 */
 
 MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables");
 
@@ -1014,6 +1041,9 @@
 	return (0);
 }
 
+/*
+ * Used by the routing socket.
+ */
 static struct mbuf *
 rt_msg1(int type, struct rt_addrinfo *rtinfo)
 {
@@ -1081,6 +1111,9 @@
 	return (m);
 }
 
+/*
+ * Used by the sysctl code and routing socket.
+ */
 static int
 rt_msg2(int type, struct rt_addrinfo *rtinfo, caddr_t cp, struct walkarg *w)
 {
@@ -1094,17 +1127,31 @@
 
 	case RTM_DELADDR:
 	case RTM_NEWADDR:
-		len = sizeof(struct ifa_msghdr);
+		if (w != NULL && w->w_op == NET_RT_IFLISTL) {
+#ifdef COMPAT_FREEBSD32
+			if (w->w_req->flags & SCTL_MASK32)
+				len = sizeof(struct ifa_msghdrl32);
+			else
+#endif
+				len = sizeof(struct ifa_msghdrl);
+		} else
+			len = sizeof(struct ifa_msghdr);
 		break;
 
 	case RTM_IFINFO:
 #ifdef COMPAT_FREEBSD32
 		if (w != NULL && w->w_req->flags & SCTL_MASK32) {
-			len = sizeof(struct if_msghdr32);
+			if (w->w_op == NET_RT_IFLISTL)
+				len = sizeof(struct if_msghdrl32);
+			else
+				len = sizeof(struct if_msghdr32);
 			break;
 		}
 #endif
-		len = sizeof(struct if_msghdr);
+		if (w != NULL && w->w_op == NET_RT_IFLISTL)
+			len = sizeof(struct if_msghdrl);
+		else
+			len = sizeof(struct if_msghdr);
 		break;
 
 	case RTM_NEWMADDR:
@@ -1535,6 +1582,147 @@
 #endif
 
 static int
+sysctl_iflist_ifml(struct ifnet *ifp, struct rt_addrinfo *info,
+    struct walkarg *w, int len)
+{
+	struct if_msghdrl *ifm;
+
+#ifdef COMPAT_FREEBSD32
+	if (w->w_req->flags & SCTL_MASK32) {
+		struct if_msghdrl32 *ifm32;
+
+		ifm32 = (struct if_msghdrl32 *)w->w_tmem;
+		ifm32->ifm_addrs = info->rti_addrs;
+		ifm32->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
+		ifm32->ifm_index = ifp->if_index;
+		ifm32->_ifm_spare1 = 0;
+		ifm32->ifm_len = sizeof(*ifm32);
+		ifm32->ifm_data_off = offsetof(struct if_msghdrl32, ifm_data);
+
+		copy_ifdata32(&ifp->if_data, &ifm32->ifm_data);
+		/* Fixup if_data carp(4) vhid. */
+		if (carp_get_vhid_p != NULL)
+			ifm32->ifm_data.ifi_vhid =
+			    (*carp_get_vhid_p)(ifp->if_addr);
+
+		return (SYSCTL_OUT(w->w_req, (caddr_t)ifm32, len));
+	}
+#endif
+	ifm = (struct if_msghdrl *)w->w_tmem;
+	ifm->ifm_addrs = info->rti_addrs;
+	ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
+	ifm->ifm_index = ifp->if_index;
+	ifm->_ifm_spare1 = 0;
+	ifm->ifm_len = sizeof(*ifm);
+	ifm->ifm_data_off = offsetof(struct if_msghdrl, ifm_data);
+
+	ifm->ifm_data = ifp->if_data;
+	/* Fixup if_data carp(4) vhid. */
+	if (carp_get_vhid_p != NULL)
+		ifm->ifm_data.ifi_vhid = (*carp_get_vhid_p)(ifp->if_addr);
+
+	return (SYSCTL_OUT(w->w_req, (caddr_t)ifm, len));
+}
+
+static int
+sysctl_iflist_ifm(struct ifnet *ifp, struct rt_addrinfo *info,
+    struct walkarg *w, int len)
+{
+	struct if_msghdr *ifm;
+
+#ifdef COMPAT_FREEBSD32
+	if (w->w_req->flags & SCTL_MASK32) {
+		struct if_msghdr32 *ifm32;
+
+		ifm32 = (struct if_msghdr32 *)w->w_tmem;
+		ifm32->ifm_addrs = info->rti_addrs;
+		ifm32->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
+		ifm32->ifm_index = ifp->if_index;
+
+		copy_ifdata32(&ifp->if_data, &ifm32->ifm_data);
+		/* Fixup if_data carp(4) vhid. */
+		if (carp_get_vhid_p != NULL)
+			ifm32->ifm_data.ifi_vhid =
+			    (*carp_get_vhid_p)(ifp->if_addr);
+
+		return (SYSCTL_OUT(w->w_req, (caddr_t)ifm32, len));
+	}
+#endif
+	ifm = (struct if_msghdr *)w->w_tmem;
+	ifm->ifm_addrs = info->rti_addrs;
+	ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
+	ifm->ifm_index = ifp->if_index;
+
+	ifm->ifm_data = ifp->if_data;
+	/* Fixup if_data carp(4) vhid. */
+	if (carp_get_vhid_p != NULL)
+		ifm->ifm_data.ifi_vhid = (*carp_get_vhid_p)(ifp->if_addr);
+
+	return (SYSCTL_OUT(w->w_req, (caddr_t)ifm, len));
+}
+
+static int
+sysctl_iflist_ifaml(struct ifaddr *ifa, struct rt_addrinfo *info,
+    struct walkarg *w, int len)
+{
+	struct ifa_msghdrl *ifam;
+
+#ifdef COMPAT_FREEBSD32
+	if (w->w_req->flags & SCTL_MASK32) {
+		struct ifa_msghdrl32 *ifam32;
+
+		ifam32 = (struct ifa_msghdrl32 *)w->w_tmem;
+		ifam32->ifam_addrs = info->rti_addrs;
+		ifam32->ifam_flags = ifa->ifa_flags;
+		ifam32->ifam_index = ifa->ifa_ifp->if_index;
+		ifam32->_ifam_spare1 = 0;
+		ifam32->ifam_len = sizeof(*ifam32);
+		ifam32->ifam_data_off =
+		    offsetof(struct ifa_msghdrl32, ifam_data);
+		ifam32->ifam_metric = ifa->ifa_metric;
+
+		copy_ifdata32(&ifa->ifa_ifp->if_data, &ifam32->ifam_data);
+		/* Fixup if_data carp(4) vhid. */
+		if (carp_get_vhid_p != NULL)
+			ifam32->ifam_data.ifi_vhid = (*carp_get_vhid_p)(ifa);
+
+		return (SYSCTL_OUT(w->w_req, (caddr_t)ifam32, len));
+	}
+#endif
+
+	ifam = (struct ifa_msghdrl *)w->w_tmem;
+	ifam->ifam_addrs = info->rti_addrs;
+	ifam->ifam_flags = ifa->ifa_flags;
+	ifam->ifam_index = ifa->ifa_ifp->if_index;
+	ifam->_ifam_spare1 = 0;
+	ifam->ifam_len = sizeof(*ifam);
+	ifam->ifam_data_off = offsetof(struct ifa_msghdrl, ifam_data);
+	ifam->ifam_metric = ifa->ifa_metric;
+
+	ifam->ifam_data = ifa->if_data;
+	/* Fixup if_data carp(4) vhid. */
+	if (carp_get_vhid_p != NULL)
+		ifam->ifam_data.ifi_vhid = (*carp_get_vhid_p)(ifa);
+
+	return (SYSCTL_OUT(w->w_req, w->w_tmem, len));
+}
+
+static int
+sysctl_iflist_ifam(struct ifaddr *ifa, struct rt_addrinfo *info,
+    struct walkarg *w, int len)
+{
+	struct ifa_msghdr *ifam;
+
+	ifam = (struct ifa_msghdr *)w->w_tmem;
+	ifam->ifam_addrs = info->rti_addrs;
+	ifam->ifam_flags = ifa->ifa_flags;
+	ifam->ifam_index = ifa->ifa_ifp->if_index;
+	ifam->ifam_metric = ifa->ifa_metric;
+
+	return (SYSCTL_OUT(w->w_req, w->w_tmem, len));
+}
+
+static int
 sysctl_iflist(int af, struct walkarg *w)
 {
 	struct ifnet *ifp;
@@ -1553,38 +1741,10 @@
 		len = rt_msg2(RTM_IFINFO, &info, NULL, w);
 		info.rti_info[RTAX_IFP] = NULL;
 		if (w->w_req && w->w_tmem) {
-			struct if_msghdr *ifm;
-
-#ifdef COMPAT_FREEBSD32
-			if (w->w_req->flags & SCTL_MASK32) {
-				struct if_msghdr32 *ifm32;
-
-				ifm32 = (struct if_msghdr32 *)w->w_tmem;
-				ifm32->ifm_index = ifp->if_index;
-				ifm32->ifm_flags = ifp->if_flags |
-				    ifp->if_drv_flags;
-				copy_ifdata32(&ifp->if_data, &ifm32->ifm_data);
-				if (carp_get_vhid_p != NULL)
-					ifm32->ifm_data.ifi_vhid =
-					    (*carp_get_vhid_p)(ifa);
-				ifm32->ifm_addrs = info.rti_addrs;
-				error = SYSCTL_OUT(w->w_req, (caddr_t)ifm32,
-				    len);
-				goto sysctl_out;
-			}
-#endif
-			ifm = (struct if_msghdr *)w->w_tmem;
-			ifm->ifm_index = ifp->if_index;
-			ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
-			ifm->ifm_data = ifp->if_data;
-			if (carp_get_vhid_p != NULL)
-				ifm->ifm_data.ifi_vhid =
-				    (*carp_get_vhid_p)(ifa);
-			ifm->ifm_addrs = info.rti_addrs;
-			error = SYSCTL_OUT(w->w_req, (caddr_t)ifm, len);
-#ifdef COMPAT_FREEBSD32
-		sysctl_out:
-#endif
+			if (w->w_op == NET_RT_IFLISTL)
+				error = sysctl_iflist_ifml(ifp, &info, w, len);
+			else
+				error = sysctl_iflist_ifm(ifp, &info, w, len);
 			if (error)
 				goto done;
 		}
@@ -1599,18 +1759,12 @@
 			info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr;
 			len = rt_msg2(RTM_NEWADDR, &info, NULL, w);
 			if (w->w_req && w->w_tmem) {
-				struct ifa_msghdr *ifam;
-
-				ifam = (struct ifa_msghdr *)w->w_tmem;
-				ifam->ifam_index = ifa->ifa_ifp->if_index;
-				ifam->ifam_flags = ifa->ifa_flags;
-				ifam->ifam_metric = ifa->ifa_metric;
-				ifam->ifam_addrs = info.rti_addrs;
-				ifam->ifam_data = ifa->if_data;
-				if (carp_get_vhid_p != NULL)
-					ifam->ifam_data.ifi_vhid =
-					    (*carp_get_vhid_p)(ifa);
-				error = SYSCTL_OUT(w->w_req, w->w_tmem, len);
+				if (w->w_op == NET_RT_IFLISTL)
+					error = sysctl_iflist_ifaml(ifa, &info,
+					    w, len);
+				else
+					error = sysctl_iflist_ifam(ifa, &info,
+					    w, len);
 				if (error)
 					goto done;
 			}
@@ -1740,6 +1894,7 @@
 		break;
 
 	case NET_RT_IFLIST:
+	case NET_RT_IFLISTL:
 		error = sysctl_iflist(af, &w);
 		break;
 
diff -r bfc8c4053ba0 -r 4bd6486a01ce head/sys/net/zlib.h
--- a/head/sys/net/zlib.h	Fri Mar 02 17:15:36 2012 +0200
+++ b/head/sys/net/zlib.h	Fri Mar 02 17:15:56 2012 +0200
@@ -1,4 +1,4 @@
-/* $FreeBSD$	*/
+/* $FreeBSD: head/sys/net/zlib.h 231678 2012-02-14 12:50:20Z tijl $	*/
 
 /*
  * This file is derived from zlib.h and zconf.h from the zlib-1.0.4
@@ -109,7 +109,7 @@
 #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
 #  define WIN32
 #endif
-#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(__i386__)
 #  ifndef __32BIT__
 #    define __32BIT__
 #  endif


More information about the Zrouter-src-freebsd mailing list