7119945 Update Quagga to version 0.99.19 s11-sru S11SRU4_02
authorBrian Utterback <Brian.Utterback@Oracle.COM>
Tue, 03 Jan 2012 11:08:59 -0800
branchs11-sru
changeset 2239 f0bde9a421fe
parent 2238 cc3545c342fd
child 2240 de14ec92a8a8
7119945 Update Quagga to version 0.99.19 6959678 Problem with network/quagga 7026150 Problem with network/quagga 7026153 Problem with network/quagga 7026154 Problem with network/quagga 7032783 Problem with network/quagga 7033149 Problem with network/quagga 7102678 Problem with network/quagga
components/quagga/Makefile
components/quagga/patches/05-noupg-nolegacy.patch
components/quagga/patches/10-sunw-smf.patch
components/quagga/patches/10-zebra-retain.patch
components/quagga/patches/15-privs-ipinst.patch
components/quagga/patches/20-privs-bgpd.patch
components/quagga/patches/23-cve-2011-3327.patch
components/quagga/patches/25-isisd-dlpi.patch
components/quagga/patches/30-ospfd-nssa-asbr.patch
components/quagga/patches/35-ospfd-spf-sort.patch
components/quagga/patches/40-bgp-capab-cleanup.patch
components/quagga/patches/45-bgpd-capab-typo.patch
components/quagga/patches/50-bgpd-nosub.patch
components/quagga/patches/55-bgpd-rm-assert.patch
components/quagga/patches/60-bgp-comm-crash.patch
components/quagga/patches/65-isisd-iso-checksum.patch
components/quagga/patches/70-isisd-trill.patch
components/quagga/patches/80-ripngd-getopt.patch
components/quagga/patches/95-noautomake.patch
--- a/components/quagga/Makefile	Tue Dec 20 22:26:25 2011 -0800
+++ b/components/quagga/Makefile	Tue Jan 03 11:08:59 2012 -0800
@@ -20,18 +20,18 @@
 #
 
 #
-# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
 #
 
 include ../../make-rules/shared-macros.mk
 
 COMPONENT_NAME=		quagga
-COMPONENT_VERSION=	0.99.8
+COMPONENT_VERSION=	0.99.19
 IPS_COMPONENT_VERSION=	$(COMPONENT_VERSION)
 COMPONENT_SRC=		$(COMPONENT_NAME)-$(COMPONENT_VERSION)
 COMPONENT_ARCHIVE=	$(COMPONENT_SRC).tar.gz
-COMPONENT_ARCHIVE_HASH=	sha1:9576d0ac266d173d2a90b8c6f72da8c6b43583d7
-COMPONENT_ARCHIVE_URL=	http://www.quagga.net/download/attic/$(COMPONENT_ARCHIVE)
+COMPONENT_ARCHIVE_HASH=	sha1:614923aa21415a4d6dc19d4438ccee63548e2a9d
+COMPONENT_ARCHIVE_URL=	http://www.quagga.net/download/$(COMPONENT_ARCHIVE)
 PATCH_LEVEL = 0
 
 # without this we bus error on sparc. Until the code in all of Quagga
@@ -39,7 +39,7 @@
 studio_ALIGN.sparc.32=  -xmemalign=8i
 
 # These options are carried over from the SFW consolidation. Using -xO4 was
-# explicitly commented out, but no reason was docuemnted.
+# explicitly commented out, but no reason was documented.
 
 studio_OPT = -xO3
 
@@ -58,7 +58,6 @@
 include ../../make-rules/configure.mk
 include ../../make-rules/ips.mk
 
-CONFIGURE_OPTIONS +=	--with-tags=""
 CONFIGURE_OPTIONS +=	--with-cflags="$(CFLAGS)"
 CONFIGURE_OPTIONS +=	--enable-opaque-lsa
 CONFIGURE_OPTIONS +=	--localstatedir=$(CFGLOCALSTATEDIR)
@@ -72,6 +71,7 @@
 CONFIGURE_OPTIONS +=	--enable-ripngd
 CONFIGURE_OPTIONS +=	--enable-user=root
 CONFIGURE_OPTIONS +=	--enable-group=root
+CONFIGURE_OPTIONS +=	--enable-solaris
 
 BUILD_PKG_DEPENDENCIES =	$(BUILD_TOOLS)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/quagga/patches/05-noupg-nolegacy.patch	Tue Jan 03 11:08:59 2012 -0800
@@ -0,0 +1,188 @@
+--- solaris/quagga.init.in
++++ solaris/quagga.init.in
+@@ -31,78 +31,6 @@
+ USER=@enable_user@
+ GROUP=@enable_group@
+ 
+-# handle upgrade of daemon-args SMF property to new routeadm properties
+-# used during upgrade too by routeadm.
+-# relevant to S10U4+ only.
+-handle_routeadm_upgrade () {
+-	GLOBAL_OPTIONS="PAfiug"
+-	
+-	daemon_args=`get_daemon_args $SMF_FMRI`
+-	
+-	if [ -n "$daemon_args" ]; then
+-		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
+-			"$GLOBAL_OPTIONS" "P" vty_port 0
+-		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
+-			"$GLOBAL_OPTIONS" "A" vty_address
+-		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
+-			"$GLOBAL_OPTIONS" "f" config_file
+-		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
+-			"$GLOBAL_OPTIONS" "i" pid_file
+-		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
+-			"$GLOBAL_OPTIONS" "u" user
+-		set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
+-			"$GLOBAL_OPTIONS" "g" group
+-		
+-		case "$1" in
+-		zebra)
+-			set_daemon_boolean_property "$SMF_FMRI" "$daemon_args" \
+-				"${GLOBAL_OPTIONS}b" "b" batch true false
+-			;;
+-		ripd|ripngd)
+-			set_daemon_boolean_property "$SMF_FMRI" "$daemon_args" \
+-				"${GLOBAL_OPTIONS}r" "r" retain true false
+-			;;
+-		bgpd)
+-			set_daemon_boolean_property "$SMF_FMRI" "$daemon_args" \
+-				"${GLOBAL_OPTIONS}rnp" "r" retain true false
+-			set_daemon_boolean_property "$SMF_FMRI" "$daemon_args" \
+-				"${GLOBAL_OPTIONS}rnp" "n" no_kernel true false
+-			set_daemon_value_property "$SMF_FMRI" "$daemon_args" \
+-				"${GLOBAL_OPTIONS}rnp" "p" bgp_port
+-		esac
+-		clear_daemon_args $SMF_FMRI
+-	fi
+-}
+-
+-upgrade_config () {
+-	DAEMON=$1
+-	# handle upgrade of SUNWzebra to Quagga
+-	if [ -d "/etc/quagga" -a ! -f "/etc/quagga/${DAEMON}.conf" ] ; then
+-		if [ -f "/etc/sfw/zebra/${DAEMON}.conf" ] ; then
+-			cp "/etc/sfw/zebra/${DAEMON}.conf" \
+-				"/etc/quagga/${DAEMON}.conf.upgrade" \
+-				|| exit $SMF_EXIT_ERR_FATAL
+-			chown "${USER}:${GROUP}" "/etc/quagga/${DAEMON}.conf.upgrade" \
+-				|| exit $SMF_EXIT_ERR_FATAL
+-			chmod 0600 "/etc/quagga/${DAEMON}.conf.upgrade" \
+-				|| exit $SMF_EXIT_ERR_FATAL
+-			mv "/etc/quagga/${DAEMON}.conf.upgrade" "/etc/quagga/${DAEMON}.conf" \
+-				|| exit $SMF_EXIT_ERR_FATAL
+-		fi
+-	fi
+-
+-	if [ ! -f "/etc/quagga/${DAEMON}.conf" ] ; then
+-		touch "/etc/quagga/${DAEMON}.conf.new" \
+-			|| exit $SMF_EXIT_ERR_FATAL
+-		chown "${USER}:${GROUP}" "/etc/quagga/${DAEMON}.conf.new" \
+-			|| exit $SMF_EXIT_ERR_FATAL
+-		chmod 0600 "/etc/quagga/${DAEMON}.conf.new" \
+-			|| exit $SMF_EXIT_ERR_FATAL
+-		mv "/etc/quagga/${DAEMON}.conf.new" "/etc/quagga/${DAEMON}.conf" \
+-			|| exit $SMF_EXIT_ERR_FATAL
+-	fi
+-}
+-
+ # Relevant to S10+
+ quagga_is_globalzone () {
+ 	if [ "${QUAGGA_INIT_ZONENAME:=`/sbin/zonename`}" = "global" \
+@@ -173,35 +101,11 @@
+ 	fi
+ }
+ 
+-# Include smf functions, if available. If not, define smf_present to indicate
+-# there is no SMF. Should allow this script to work pre-S10.
+-if [ -f "$SMFINCLUDE" ] ; then
+-	. "$SMFINCLUDE";
+-	
+-	# source the SMF-routeadm include if present..
+-	if [ -f "$ROUTEADMINCLUDE" ] ; then
+-		. "$ROUTEADMINCLUDE"
+-	fi
+-else
+-	# pre-SMF system, fake up any functions and exit codes
+-	# which SMFINCLUDE usually provides.
+-	smf_present () {
+-		return 1
+-	}
+-	SMF_EXIT_OK=0;
+-	SMF_EXIT_ERR_CONFIG=96;
+-	SMF_EXIT_ERR_FATAL=95;
+-fi
+-	
+-# if there's no SMF, set some default DAEMON_ARGS
+-smf_present || DAEMON_ARGS=""
++. "$SMFINCLUDE";
++. "$ROUTEADMINCLUDE"
+ 
+ usage () {
+-	if smf_present ; then
+-		echo "Usage: $0 <daemon>";
+-	else
+-		echo "Usage: $0 <stop|start> <daemon> <daemon arguments>";
+-	fi
++	echo "Usage: $0 <daemon>";
+ 	echo "The --pid_file argument is implied";
+ 	echo "This help message: $0 <help|usage>";
+ }
+@@ -214,12 +118,7 @@
+ 		;;
+ esac
+ 
+-if smf_present ; then
+-	QUAGGA_METHOD="start"
+-else
+-	QUAGGA_METHOD="$1"
+-	shift;
+-fi
++QUAGGA_METHOD="start"
+ 
+ DAEMON="$1"
+ 
+@@ -243,22 +142,9 @@
+ 	;;
+ esac
+ 
+-# Older Quagga SMF packages pass daemon args on the commandline
+-# Newer SMF routeadm model uses properties for each argument
+-# so we must handle that.
+-if [ smf_present -a -f "$ROUTEADMINCLUDE" ]; then
+-	handle_routeadm_upgrade $DAEMON;
+-	DAEMON_ARGS=`routeadm_daemon_args`;
+-	routeadm_zebra_enable $DAEMON;
+-else
+-	if [ $# -gt 0 ] ; then
+-		shift
+-		DAEMON_ARGS="$@"
+-	fi
+-fi
++DAEMON_ARGS=`routeadm_daemon_args $DAEMON`;
++routeadm_zebra_enable $DAEMON;
+ 
+-upgrade_config "$DAEMON"
+-
+ if [ ! -f "@sysconfdir@/${DAEMON}.conf" ] ; then
+ 	echo "Could not find config file, @sysconfdir@/${DAEMON}.conf"
+ 	exit $SMF_EXIT_ERR_CONFIG
+--- solaris/quagga.xml.in
++++ solaris/quagga.xml.in
+@@ -226,8 +226,6 @@
+ 		<!-- Identifies service as a routing service -->
+ 		<propval name='daemon' type='astring'
+ 			value='@sbindir@/ripd' />
+-		<propval name='legacy-daemon' type='astring'
+-			value='/usr/sfw/sbin/ripdstart' />
+ 		<propval name='value_authorization' type='astring'
+ 			value='solaris.smf.value.routing' />
+ 		<propval name='protocol' type='astring' value='ipv4' />
+@@ -489,8 +487,6 @@
+ 		<!-- Identifies service as a routing service -->
+ 		<propval name='daemon' type='astring'
+ 			value='@sbindir@/ospfd' />
+-		<propval name='legacy-daemon' type='astring'
+-			value='/usr/sfw/sbin/ospfdstart' />
+ 		<propval name='value_authorization' type='astring'
+ 			value='solaris.smf.value.routing' />
+ 		<propval name='protocol' type='astring' value='ipv4'/>
+@@ -752,8 +748,6 @@
+ 		<!-- Identifies service as a routing service -->
+ 		<propval name='daemon' type='astring'
+ 			value='@sbindir@/bgpd' />
+-		<propval name='legacy-daemon' type='astring'
+-			value='/usr/sfw/sbin/bgpdstart' />
+ 		<propval name='value_authorization' type='astring'
+ 			value='solaris.smf.value.routing' />
+ 		<property name='protocol' type='astring'>
--- a/components/quagga/patches/10-sunw-smf.patch	Tue Dec 20 22:26:25 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,983 +0,0 @@
---- solaris/quagga.init.in
-+++ solaris/quagga.init.in
-@@ -1,6 +1,6 @@
- #!/sbin/sh
- #
--# Copyright 2001,2003 Sun Microsystems, Inc. All rights reserved.
-+# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
- # Use is subject to license terms.
- #
- # This file is part of Quagga.
-@@ -25,40 +25,88 @@
- # Starts/stops the given daemon
- 
- SMFINCLUDE=/lib/svc/share/smf_include.sh
-+ROUTEADMINCLUDE=/lib/svc/share/routing_include.sh
-+GLOBAL_OPTIONS="PAfiug"
- DAEMON_PATH=@sbindir@
-+USER=@enable_user@
-+GROUP=@enable_group@
- 
-+# Relevant to S10+
- quagga_is_globalzone () {
--	if [ "${QUAGGA_INIT_ZONENAME:=`/sbin/zonename`}" != "global" ]; then
--		return 1
--	else
-+	if [ "${QUAGGA_INIT_ZONENAME:=`/sbin/zonename`}" = "global" \
-+		-o `/sbin/zonename -t` = "exclusive" ]; then
- 		return 0
-+	else
-+		return 1
- 	fi
- }
- 
--# Include smf functions, if available. If not, define smf_present to indicate
--# there is no SMF. Should allow this script to work pre-S10.
--if [ -f "$SMFINCLUDE" ] ; then
--	. "$SMFINCLUDE";
--else
--	# pre-SMF system, fake up any functions and exit codes
--	# which SMFINCLUDE usually provides.
--	smf_present () {
--		return 1
--	}
--	SMF_EXIT_OK=0;
--	SMF_EXIT_ERR_CONFIG=96;
--	SMF_EXIT_ERR_FATAL=95;
--fi
-+routeadm_daemon_args () {
-+	# globals
-+	args="`get_daemon_option_from_property $SMF_FMRI config_file f`"
-+	args="${args} `get_daemon_option_from_property $SMF_FMRI vty_port P`"
-+	args="${args} `get_daemon_option_from_property $SMF_FMRI vty_address A`"
-+	args="${args} `get_daemon_option_from_property $SMF_FMRI pid_file i`"
- 	
--# if there's no SMF, set some default DAEMON_ARGS
--smf_present || DAEMON_ARGS=""
-+	# user and group we need for config file upgrade..
-+	SMF_USER=`get_routeadm_property $SMF_FMRI user`
-+	SMF_GROUP=`get_routeadm_property()$SMF_FMRI group`
-+	if [ "${SMF_USER}" ] ; then
-+		USER="${SMF_USER}"
-+		args="${args} -u ${SMF_USER}"
-+	fi
-+	if [ "${SMF_GROUP}" ] ; then 
-+		GROUP="${SMF_GROUP}"
-+		args="${args} -g ${SMF_GROUP}"
-+	fi
- 
--usage () {
--	if smf_present ; then
--		echo "Usage: $0 <daemon> <daemon arguments>";
--	else
--		echo "Usage: $0 <stop|start> <daemon> <daemon arguments>";
-+	case $1 in
-+	zebra)
-+		args="${args} `get_daemon_option_from_boolean_property $SMF_FMRI batch -b true`"
-+		args="${args} `get_daemon_option_from_boolean_property $SMF_FMRI retain -r true`"
-+		;;
-+	ripd|ripngd)
-+		args="${args} `get_daemon_option_from_boolean_property $SMF_FMRI retain -r true`"
-+		;;
-+	bgpd)
-+		args="${args} `get_daemon_option_from_boolean_property $SMF_FMRI retain -r true`"
-+		args="${args} `get_daemon_option_from_boolean_property $SMF_FMRI no_kernel -n true`"
-+		args="${args} `get_daemon_option_from_property $SMF_FMRI bgp_port p 179`"
-+		;;
-+	esac
-+	echo ${args}
-+}
-+
-+# certain daemons need zebra
-+routeadm_zebra_enable () {
-+
-+	if [ "$DAEMON" = "zebra" ]; then
-+		return
- 	fi
-+	
-+	enable_zebra=`/usr/bin/svcprop -p \
-+		routing/enable_zebra $SMF_FMRI 2> /dev/null`
-+	if [ "$enable_zebra" != "false" ]; then
-+		zenabled=`/usr/bin/svcprop -p general/enabled zebra:quagga`
-+		zenabledt=`/usr/bin/svcprop -p general_ovr/enabled zebra:quagga`
-+		if [ "$zenabled" = "true" -o "$zenabledt" = "true" ]; then
-+			/usr/sbin/svcadm disable zebra:quagga
-+			/usr/sbin/svcadm enable -st zebra:quagga
-+		else
-+			/usr/sbin/svcadm enable -st zebra:quagga 
-+		fi
-+		if [ "$?" != "0" ]; then
-+			echo "Could not enable zebra:quagga"
-+			exit $SMF_EXIT_ERR_FATAL
-+		fi
-+	fi
-+}
-+
-+. "$SMFINCLUDE";
-+. "$ROUTEADMINCLUDE"
-+	
-+usage () {
-+	echo "Usage: $0 <daemon>";
- 	echo "The --pid_file argument is implied";
- 	echo "This help message: $0 <help|usage>";
- }
-@@ -67,20 +115,13 @@
- case $1 in
- 	'help' | 'usage')
- 		usage
--		exit SMF_EXIT_OK
-+		exit $SMF_EXIT_OK
- 		;;
- esac
- 
--if smf_present ; then
--	QUAGGA_METHOD="start"
--else
--	QUAGGA_METHOD="$1"
--	shift;
--fi
-+QUAGGA_METHOD="start"
- 
- DAEMON="$1"
--shift
--DAEMON_ARGS="$@"
- 
- # daemon path must be given
- if [ -z "$DAEMON_PATH/$DAEMON" ]; then
-@@ -91,12 +132,9 @@
- # only bgpd is suitable for running in a non-global zone, at this
- # time.
- case "${DAEMON}" in
--	zebra)
--		quagga_is_globalzone || exit $SMF_EXIT_OK
--	;;
- 	bgpd)
- 	;;
--	ospfd | ospf6d | ripd | ripngd )
-+	zebra | ospfd | ospf6d | ripd | ripngd )
- 		quagga_is_globalzone || exit $SMF_EXIT_OK
- 	;;
- 	*)
-@@ -105,6 +143,14 @@
- 	;;
- esac
- 
-+DAEMON_ARGS=`routeadm_daemon_args $DAEMON`;
-+routeadm_zebra_enable $DAEMON;
-+
-+if [ ! -f "@sysconfdir@/${DAEMON}.conf" ] ; then
-+	echo "Could not find config file, @sysconfdir@/${DAEMON}.conf"
-+	exit $SMF_EXIT_ERR_CONFIG
-+fi
-+
- # we need @quagga_statedir@ to exist, it probably is on tmpfs.
- if [ ! -d @quagga_statedir@ ] ; then
- 	mkdir -p @quagga_statedir@
-@@ -115,7 +161,11 @@
- PIDFILE="@quagga_statedir@/${DAEMON}.pid"
- 
- start () {
--	$DAEMON_PATH/$DAEMON $DAEMON_ARGS --pid_file ${PIDFILE} &
-+	if [ ! -x "$DAEMON_PATH/$DAEMON" ] ; then
-+		echo "Error, could not find daemon, $DAEMON_PATH/$DAEMON"
-+		exit $SMF_EXIT_ERR_FATAL
-+	fi
-+	eval exec $DAEMON_PATH/$DAEMON $DAEMON_ARGS --pid_file ${PIDFILE} &
- }
- 
- stop () {
-@@ -134,7 +184,7 @@
- 
- *)
- 	usage
--	exit SMF_EXIT_ERR_FATAL
-+	exit $SMF_EXIT_ERR_FATAL
- 	;;
- esac	
- 
---- solaris/quagga.xml.in
-+++ solaris/quagga.xml.in
-@@ -18,18 +18,20 @@
- 	Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 	02111-1307, USA.
- 
--	Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-+	Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
- 	Use is subject to license terms.
- 
- 	ident	"@(#)quagga.xml	1.0	05/03/15 SMI"
- -->
- 
--<service_bundle type='manifest' name='QUAGGAdaemons:quagga'>
-+<service_bundle type='manifest' name='SUNWquagga-daemons:quagga'>
-+
- <service
- 	name='network/routing/zebra'
- 	type='service'
- 	version='1'>
--
-+	
-+	<single_instance />
- 	<instance name='quagga' enabled='false'>
- 	
- 	<dependency name='fs'
-@@ -46,24 +48,24 @@
- 		type='service'>
- 		<service_fmri value='svc:/network/initial' />
- 	</dependency>
--
--	<dependency name='config_data'
-+	
-+	<!-- do not not run unless routing-setup has run -->
-+	<dependency
-+		name='network_routing_setup'
- 		grouping='require_all'
--		restart_on='restart'
--		type='path'>
--		<service_fmri
--			value='file://localhost/@sysconfdir@/zebra.conf' />
-+		restart_on='refresh'
-+		type='service'>
-+		<service_fmri value='svc:/network/routing-setup' />
- 	</dependency>
--	
-+
- 	<exec_method
- 		type='method'
- 		name='start'
--		exec='/lib/svc/method/quagga zebra %{routing/daemon-args}'
-+		exec='/lib/svc/method/quagga zebra'
- 		timeout_seconds='60'>
- 		<method_context>
- 		  <method_credential
--		   user='root' group='root'
--		   privileges='basic,net_icmpaccess,net_rawaccess,sys_admin,sys_net_config'/>
-+		   user='root' group='root'/>
-  		</method_context>
- 	</exec_method>
- 
-@@ -84,11 +86,48 @@
- 		<propval name='ignore_error'
- 		    type='astring' value='core,signal' />
- 	</property_group>
--
-+	
-+	<!-- Properties in this group are used by routeadm (1M) -->
-+	<property_group name='routeadm' type='application'>
-+		<stability value='Unstable' />
-+		<!-- Identifies service as a routing service -->
-+		<propval name='daemon' type='astring'
-+			value='@sbindir@/zebra' />
-+		<propval name='value_authorization' type='astring'
-+			value='solaris.smf.value.routing' />
-+		<!-- zebra should not contribute to ipv4/ipv6 routing state -->
-+		<propval name='protocol' type='astring' value='zebra' />
-+	</property_group>
-+	
-+	<!-- Properties in this group are modifiable via routeadm (1M) -->
- 	<property_group name='routing' type='application'>
-+		<stability value='Evolving' />
- 		<propval name='value_authorization' type='astring' 
--		         value='solaris.smf.modify.routing' />
--		<propval name='daemon-args' type='astring' value='-P 0'/>
-+		         value='solaris.smf.value.routing' />
-+		
-+		<!-- Options common to Quagga daemons
-+		     Property names are equivalent to the long
-+		     option name, consult Quagga documentation -->
-+		<!-- The config file to use, if not the default -->
-+		<propval name='config_file' type='astring' value=''/>
-+		<!-- The vty_port to listen on if not the default.
-+		     0 to disable --> 
-+		<propval name='vty_port' type='integer' value='0' />
-+		<!-- The address to bind the VTY interface to, if not any. -->
-+		<propval name='vty_address' type='astring' value='' />
-+		<!-- The user to switch to after startup, if not the default -->
-+		<propval name='user' type='astring' value='' />
-+		<!-- The group to switch to, if not the default.
-+		     If user is specified, this defaults to a group with
-+		     same name as user -->
-+		<propval name='group' type='astring' value='' />
-+		<!-- The pidfile to use, if not the default of
-+		     @quagga_statedir@ -->
-+		<propval name='pid_file' type='astring' value='' />
-+		
-+		<!-- Options specific to zebra -->
-+		<propval name='batch' type='boolean' value='false' />
-+		<propval name='retain' type='boolean' value='false' />
- 	</property_group>
- 	
- 	<property_group name='general' type='framework'>
-@@ -95,6 +134,8 @@
- 		<!-- to start stop routing services -->
- 		<propval name='action_authorization' type='astring'
- 			 value='solaris.smf.manage.routing' />
-+		<propval name='value_authorization' type='astring'
-+			 value='solaris.smf.manage.routing' />
- 	</property_group>
- 
- 	<template>
-@@ -111,7 +152,7 @@
- 		</documentation>
- 	</template>
- 	</instance>
--	<stability value='Evolving' />
-+	<stability value='Unstable' />
- </service>
- 
- <service
-@@ -129,39 +170,40 @@
- 			value='svc:/system/filesystem/usr:default' />
- 	</dependency>
- 
--	<!-- Depends on Work-In-Progress, not yet in SNV
--	<dependency name='net'
--		grouping='require_all'
--		restart_on='none'
-+	<dependency
-+		name='ipv4-forwarding'
-+		grouping='optional_all'
-+		restart_on='refresh'
- 		type='service'>
--		<service_fmri value='svc:/network/routing/ipv4-routing' />
-+		<service_fmri value='svc:/network/ipv4-forwarding' />
- 	</dependency>
--	-->
- 	
--	<dependency name='zebra'
--			grouping='require_all'
--			restart_on='restart'
--			type='service'>
--			<service_fmri value='svc:/network/routing/zebra:quagga' />
--	</dependency>
--
--	<dependency name='config_data'
-+	<!-- do not not run unless routing-setup has run -->
-+	<dependency
-+		name='network_routing_setup'
- 		grouping='require_all'
--		restart_on='restart'
--		type='path'>
--		<service_fmri
--			value='file://localhost/@sysconfdir@/ripd.conf' />
-+		restart_on='refresh'
-+		type='service'>
-+		<service_fmri value='svc:/network/routing-setup' />
- 	</dependency>
- 	
-+	<!-- ensure that restart of zebra is propogated to daemon -->
-+	<dependency
-+		name='zebra'
-+		grouping='optional_all'
-+		restart_on='restart'
-+		type='service'>
-+		<service_fmri value='svc:/network/routing/zebra:quagga' />
-+	</dependency>
-+
- 	<exec_method
- 		type='method'
- 		name='start'
--		exec='/lib/svc/method/quagga ripd %{routing/daemon-args}'
-+		exec='/lib/svc/method/quagga ripd'
- 		timeout_seconds='60'>
- 		<method_context>
- 		  <method_credential
--		   user='root' group='root'
--		   privileges='basic,net_icmpaccess,net_privaddr,net_rawaccess'/>
-+		   user='root' group='root'/>
-  		</method_context>
- 	</exec_method>
- 
-@@ -179,10 +221,42 @@
- 		    type='astring' value='core,signal' />
- 	</property_group>
- 
-+	<!-- Properties in this group are used by routeadm (1M) -->
-+	<property_group name='routeadm' type='application'>
-+		<stability value='Unstable' />
-+		<!-- Identifies service as a routing service -->
-+		<propval name='daemon' type='astring'
-+			value='@sbindir@/ripd' />
-+		<propval name='value_authorization' type='astring'
-+			value='solaris.smf.value.routing' />
-+		<propval name='protocol' type='astring' value='ipv4' />
-+	</property_group>
-+	
-+	<!-- Properties in this group are modifiable via routeadm (1M) -->
- 	<property_group name='routing' type='application'>
- 		<propval name='value_authorization' type='astring' 
--		         value='solaris.smf.modify.routing' />
--		<propval name='daemon-args' type='astring' value='-P 0'/>
-+		         value='solaris.smf.value.routing' />
-+
-+		<!-- Options common to Quagga daemons -->
-+		<!-- The config file to use, if not the default -->
-+		<propval name='config_file' type='astring' value=''/>
-+		<!-- The vty_port to listen on if not the default.
-+		     0 to disable --> 
-+		<propval name='vty_port' type='integer' value='0' />
-+		<!-- The address to bind the VTY interface to, if not any. -->
-+		<propval name='vty_address' type='astring' value='' />
-+		<!-- The user to switch to after startup, if not the default -->
-+		<propval name='user' type='astring' value='' />
-+		<!-- The group to switch to, if not the default.
-+		     If user is specified, this defaults to a group with
-+		     same name as user -->
-+		<propval name='group' type='astring' value='' />
-+		<!-- The pidfile to use, if not the default of
-+		     @quagga_statedir@ -->
-+		<propval name='pid_file' type='astring' value='' />
-+		
-+		<!-- Options specific to ripd -->
-+		<propval name='retain' type='boolean' value='false' />
- 	</property_group>
- 
- 	<property_group name='general' type='framework'>
-@@ -189,6 +263,8 @@
- 		<!-- to start stop routing services -->
- 		<propval name='action_authorization' type='astring'
- 			 value='solaris.smf.manage.routing' />
-+		<propval name='value_authorization' type='astring'
-+			 value='solaris.smf.manage.routing' />
- 	</property_group>
- 
- 	<template>
-@@ -205,7 +281,7 @@
- 		</documentation>
- 	</template>
- 	</instance>
--	<stability value='Evolving' />
-+	<stability value='Unstable' />
- </service>
- 
- <service
-@@ -223,39 +299,40 @@
- 			value='svc:/system/filesystem/usr:default' />
- 	</dependency>
- 	
--	<!-- Depends on WIP, not yet in SNV
--	<dependency name='net'
--		grouping='require_all'
--		restart_on='none'
-+	<dependency
-+		name='ipv6-forwarding'
-+		grouping='optional_all'
-+		restart_on='refresh'
- 		type='service'>
--		<service_fmri value='svc:/network/routing/ipv6-routing' />
-+		<service_fmri value='svc:/network/ipv6-forwarding' />
- 	</dependency>
--	-->
- 
--	<dependency name='zebra'
--			grouping='require_all'
--			restart_on='restart'
--			type='service'>
--			<service_fmri value='svc:/network/routing/zebra:quagga' />
-+	<!-- do not not run unless routing-setup has run -->
-+	<dependency
-+		name='network_routing_setup'
-+		grouping='require_all'
-+		restart_on='refresh'
-+		type='service'>
-+		<service_fmri value='svc:/network/routing-setup' />
- 	</dependency>
- 
--	<dependency name='config_data'
--		grouping='require_all'
-+	<!-- ensure that restart of zebra is propogated to daemon -->
-+	<dependency
-+		name='zebra'
-+		grouping='optional_all'
- 		restart_on='restart'
--		type='path'>
--		<service_fmri
--			value='file://localhost/@sysconfdir@/ripngd.conf' />
-+		type='service'>
-+		<service_fmri value='svc:/network/routing/zebra:quagga' />
- 	</dependency>
--	
-+
- 	<exec_method
- 		type='method'
- 		name='start'
--		exec='/lib/svc/method/quagga ripngd %{routing/daemon-args}'
-+		exec='/lib/svc/method/quagga ripngd'
- 		timeout_seconds='60'>
- 		<method_context>
- 		  <method_credential
--		   user='root' group='root'
--		   privileges='basic,net_icmpaccess,net_privaddr,net_rawaccess'/>
-+		   user='root' group='root'/>
-  		</method_context>
- 	</exec_method>
- 
-@@ -273,10 +350,42 @@
- 		    type='astring' value='core,signal' />
- 	</property_group>
- 
-+	<!-- Properties in this group are used by routeadm (1M) -->
-+	<property_group name='routeadm' type='application'>
-+		<stability value='Unstable' />
-+		<!-- Identifies service as a routing service -->
-+		<propval name='daemon' type='astring'
-+			value='@sbindir@/ripngd' />
-+		<propval name='value_authorization' type='astring'
-+			value='solaris.smf.value.routing' />
-+		<propval name='protocol' type='astring' value='ipv6'/>
-+	</property_group>
-+	
-+	<!-- Properties in this group are modifiable via routeadm (1M) -->
- 	<property_group name='routing' type='application'>
- 		<propval name='value_authorization' type='astring' 
--		         value='solaris.smf.modify.routing' />
--		<propval name='daemon-args' type='astring' value='-P 0'/>
-+		         value='solaris.smf.value.routing' />
-+
-+		<!-- Options common to Quagga daemons -->
-+		<!-- The config file to use, if not the default -->
-+		<propval name='config_file' type='astring' value=''/>
-+		<!-- The vty_port to listen on if not the default.
-+		     0 to disable --> 
-+		<propval name='vty_port' type='integer' value='0' />
-+		<!-- The address to bind the VTY interface to, if not any. -->
-+		<propval name='vty_address' type='astring' value='' />
-+		<!-- The user to switch to after startup, if not the default -->
-+		<propval name='user' type='astring' value='' />
-+		<!-- The group to switch to, if not the default.
-+		     If user is specified, this defaults to a group with
-+		     same name as user -->
-+		<propval name='group' type='astring' value='' />
-+		<!-- The pidfile to use, if not the default of
-+		     @quagga_statedir@ -->
-+		<propval name='pid_file' type='astring' value='' />
-+
-+		<!-- Options specific to ripngd -->
-+		<propval name='retain' type='boolean' value='false' />
- 	</property_group>
- 
- 	<property_group name='general' type='framework'>
-@@ -283,6 +392,8 @@
- 		<!-- to start stop routing services -->
- 		<propval name='action_authorization' type='astring'
- 			 value='solaris.smf.manage.routing' />
-+		<propval name='value_authorization' type='astring'
-+			 value='solaris.smf.manage.routing' />
- 	</property_group>
- 
- 	<template>
-@@ -299,7 +410,7 @@
- 		</documentation>
- 	</template>
- 	</instance>
--	<stability value='Evolving' />
-+	<stability value='Unstable' />
- </service>
- 
- <service
-@@ -317,47 +428,51 @@
- 			value='svc:/system/filesystem/usr:default' />
- 	</dependency>
- 	
--	<!-- Depends on WIP, not yet in SNV
--	<dependency name='net'
--		grouping='require_all'
--		restart_on='none'
-+	<dependency
-+		name='ipv4-forwarding'
-+		grouping='optional_all'
-+		restart_on='refresh'
- 		type='service'>
--		<service_fmri value='svc:/network/routing/ipv4-routing' />
-+		<service_fmri value='svc:/network/ipv4-forwarding' />
- 	</dependency>
--	-->
- 
--	<dependency name='zebra'
--			grouping='require_all'
--			restart_on='restart'
--			type='service'>
--			<service_fmri value='svc:/network/routing/zebra:quagga' />
-+	<!-- do not not run unless routing-setup has run -->
-+	<dependency
-+		name='network_routing_setup'
-+		grouping='require_all'
-+		restart_on='refresh'
-+		type='service'>
-+		<service_fmri value='svc:/network/routing-setup' />
- 	</dependency>
- 
--	<dependency name='config_data'
--		grouping='require_all'
-+	<!-- ensure that restart of zebra is propogated to daemon -->
-+	<dependency
-+		name='zebra'
-+		grouping='optional_all'
- 		restart_on='restart'
--		type='path'>
--		<service_fmri
--			value='file://localhost/@sysconfdir@/ospfd.conf' />
-+		type='service'>
-+		<service_fmri value='svc:/network/routing/zebra:quagga' />
- 	</dependency>
--	
-+
- 	<exec_method
- 		type='method'
- 		name='start'
--		exec='/lib/svc/method/quagga ospfd %{routing/daemon-args}'
-+		exec='/lib/svc/method/quagga ospfd'
- 		timeout_seconds='60'>
- 		<method_context>
- 		  <method_credential
--		   user='root' group='root'
--		   privileges='basic,net_icmpaccess,net_privaddr,net_rawaccess,sys_net_config'/>
-+		   user='root' group='root'/>
-  		</method_context>
- 	</exec_method>
- 
-+	<!-- ospfd can take a long time to shutdown, due to graceful 
-+	     shutdown 
-+	 -->
- 	<exec_method
- 		type='method'
- 		name='stop'
- 		exec=':kill'
--		timeout_seconds='60'>
-+		timeout_seconds='600'>
- 	</exec_method>
- 
- 	<property_group name='startd'
-@@ -367,10 +482,39 @@
- 		    type='astring' value='core,signal' />
- 	</property_group>
- 
-+	<!-- Properties in this group are used by routeadm (1M) -->
-+	<property_group name='routeadm' type='application'>
-+		<stability value='Unstable' />
-+		<!-- Identifies service as a routing service -->
-+		<propval name='daemon' type='astring'
-+			value='@sbindir@/ospfd' />
-+		<propval name='value_authorization' type='astring'
-+			value='solaris.smf.value.routing' />
-+		<propval name='protocol' type='astring' value='ipv4'/>
-+	</property_group>
-+	
-+	<!-- Properties in this group are modifiable via routeadm (1M) -->
- 	<property_group name='routing' type='application'>
- 		<propval name='value_authorization' type='astring' 
--		         value='solaris.smf.modify.routing' />
--		<propval name='daemon-args' type='astring' value='-P 0'/>
-+		         value='solaris.smf.value.routing' />
-+
-+		<!-- Options common to Quagga daemons -->
-+		<!-- The config file to use, if not the default -->
-+		<propval name='config_file' type='astring' value=''/>
-+		<!-- The vty_port to listen on if not the default.
-+		     0 to disable --> 
-+		<propval name='vty_port' type='integer' value='0' />
-+		<!-- The address to bind the VTY interface to, if not any. -->
-+		<propval name='vty_address' type='astring' value='' />
-+		<!-- The user to switch to after startup, if not the default -->
-+		<propval name='user' type='astring' value='' />
-+		<!-- The group to switch to, if not the default.
-+		     If user is specified, this defaults to a group with
-+		     same name as user -->
-+		<propval name='group' type='astring' value='' />
-+		<!-- The pidfile to use, if not the default of
-+		     @quagga_statedir@ -->
-+		<propval name='pid_file' type='astring' value='' />
- 	</property_group>
- 
- 	<property_group name='general' type='framework'>
-@@ -377,6 +521,8 @@
- 		<!-- to start stop routing services -->
- 		<propval name='action_authorization' type='astring'
- 			 value='solaris.smf.manage.routing' />
-+		<propval name='value_authorization' type='astring'
-+			 value='solaris.smf.manage.routing' />
- 	</property_group>
- 
- 	<template>
-@@ -393,7 +539,7 @@
- 		</documentation>
- 	</template>
- 	</instance>
--	<stability value='Evolving' />
-+	<stability value='Unstable' />
- </service>
- 
- <service
-@@ -411,39 +557,40 @@
- 			value='svc:/system/filesystem/usr:default' />
- 	</dependency>
- 	
--	<!-- Depends on WIP, not yet in SNV
--	<dependency name='net'
--		grouping='require_all'
--		restart_on='none'
-+	<dependency
-+		name='ipv6-forwarding'
-+		grouping='optional_all'
-+		restart_on='refresh'
- 		type='service'>
--		<service_fmri value='svc:/network/routing/ipv6-routing' />
-+		<service_fmri value='svc:/network/ipv6-forwarding' />
- 	</dependency>
--	-->
- 
--	<dependency name='zebra'
--			grouping='require_all'
--			restart_on='restart'
--			type='service'>
--			<service_fmri value='svc:/network/routing/zebra:quagga' />
-+	<!-- do not not run unless routing-setup has run -->
-+	<dependency
-+		name='network_routing_setup'
-+		grouping='require_all'
-+		restart_on='refresh'
-+		type='service'>
-+		<service_fmri value='svc:/network/routing-setup' />
- 	</dependency>
- 
--	<dependency name='config_data'
--		grouping='require_all'
-+	<!-- ensure that restart of zebra is propogated to daemon -->
-+	<dependency
-+		name='zebra'
-+		grouping='optional_all'
- 		restart_on='restart'
--		type='path'>
--		<service_fmri
--			value='file://localhost/@sysconfdir@/ospf6d.conf' />
-+		type='service'>
-+		<service_fmri value='svc:/network/routing/zebra:quagga' />
- 	</dependency>
--	
-+
- 	<exec_method
- 		type='method'
- 		name='start'
--		exec='/lib/svc/method/quagga ospf6d %{routing/daemon-args}'
-+		exec='/lib/svc/method/quagga ospf6d'
- 		timeout_seconds='60'>
- 		<method_context>
- 		  <method_credential
--		   user='root' group='root'
--		   privileges='basic,net_icmpaccess,net_privaddr,net_rawaccess'/>
-+		   user='root' group='root'/>
-  		</method_context>
- 	</exec_method>
- 
-@@ -461,10 +608,39 @@
- 		    type='astring' value='core,signal' />
- 	</property_group>
- 
-+	<!-- Properties in this group are used by routeadm (1M) -->
-+	<property_group name='routeadm' type='application'>
-+		<stability value='Unstable' />
-+		<!-- Identifies service as a routing service -->
-+		<propval name='daemon' type='astring'
-+			value='@sbindir@/ospf6d' />
-+		<propval name='value_authorization' type='astring'
-+			value='solaris.smf.value.routing' />
-+		<propval name='protocol' type='astring' value='ipv6'/>
-+	</property_group>
-+	
-+	<!-- Properties in this group are modifiable via routeadm (1M) -->
- 	<property_group name='routing' type='application'>
- 		<propval name='value_authorization' type='astring' 
--		         value='solaris.smf.modify.routing' />
--		<propval name='daemon-args' type='astring' value='-P 0'/>
-+		         value='solaris.smf.value.routing' />
-+
-+		<!-- Options common to Quagga daemons -->
-+		<!-- The config file to use, if not the default -->
-+		<propval name='config_file' type='astring' value=''/>
-+		<!-- The vty_port to listen on if not the default.
-+		     0 to disable --> 
-+		<propval name='vty_port' type='integer' value='0' />
-+		<!-- The address to bind the VTY interface to, if not any. -->
-+		<propval name='vty_address' type='astring' value='' />
-+		<!-- The user to switch to after startup, if not the default -->
-+		<propval name='user' type='astring' value='' />
-+		<!-- The group to switch to, if not the default.
-+		     If user is specified, this defaults to a group with
-+		     same name as user -->
-+		<propval name='group' type='astring' value='' />
-+		<!-- The pidfile to use, if not the default of
-+		     @quagga_statedir@ -->
-+		<propval name='pid_file' type='astring' value='' />
- 	</property_group>
- 
- 	<property_group name='general' type='framework'>
-@@ -471,12 +647,14 @@
- 		<!-- to start stop routing services -->
- 		<propval name='action_authorization' type='astring'
- 			 value='solaris.smf.manage.routing' />
-+		<propval name='value_authorization' type='astring'
-+			 value='solaris.smf.manage.routing' />
- 	</property_group>
- 
- 	<template>
- 		<common_name>
- 			<loctext xml:lang='C'>
--			Quagga: ospf6d, OSPFv3 IPv6 routing protocol daemon.
-+ 			Quagga: ospf6d, OSPFv3 IPv6 routing protocol daemon.
- 			</loctext>
- 		</common_name>
- 		<documentation>
-@@ -487,7 +665,7 @@
- 		</documentation>
- 	</template>
- 	</instance>
--	<stability value='Evolving' />
-+	<stability value='Unstable' />
- </service>
- 
- 
-@@ -506,40 +684,48 @@
- 			value='svc:/system/filesystem/usr:default' />
- 	</dependency>
- 	
--	<!-- Depends on WIP, not yet in SNV
--	<dependency name='net'
--		grouping='require_any'
--		restart_on='none'
-+	<dependency
-+		name='ipv6-forwarding'
-+		grouping='optional_all'
-+		restart_on='refresh'
- 		type='service'>
--		<service_fmri value='svc:/network/routing/ipv6-routing' />
--		<service_fmri value='svc:/network/routing/ipv4-routing' />
-+		<service_fmri value='svc:/network/ipv6-forwarding' />
- 	</dependency>
--	-->
-+
-+	<dependency
-+		name='ipv4-forwarding'
-+		grouping='optional_all'
-+		restart_on='refresh'
-+		type='service'>
-+		<service_fmri value='svc:/network/ipv4-forwarding' />
-+	</dependency>
- 	
--	<dependency name='zebra'
--			grouping='optional_all'
--			restart_on='restart'
--			type='service'>
--			<service_fmri value='svc:/network/routing/zebra:quagga' />
-+	<!-- do not not run unless routing-setup has run -->
-+	<dependency
-+		name='network_routing_setup'
-+		grouping='require_all'
-+		restart_on='refresh'
-+		type='service'>
-+		<service_fmri value='svc:/network/routing-setup' />
- 	</dependency>
- 
--	<dependency name='config_data'
--		grouping='require_all'
-+	<!-- ensure that restart of zebra is propogated to daemon -->
-+	<dependency
-+		name='zebra'
-+		grouping='optional_all'
- 		restart_on='restart'
--		type='path'>
--		<service_fmri
--			value='file://localhost/@sysconfdir@/bgpd.conf' />
-+		type='service'>
-+		<service_fmri value='svc:/network/routing/zebra:quagga' />
- 	</dependency>
--	
-+
- 	<exec_method
- 		type='method'
- 		name='start'
--		exec='/lib/svc/method/quagga bgpd %{routing/daemon-args}'
-+		exec='/lib/svc/method/quagga bgpd'
- 		timeout_seconds='60'>
- 		<method_context>
- 		  <method_credential
--		   user='root' group='root'
--		   privileges='basic,net_icmpaccess,net_privaddr,net_rawaccess'/>
-+		   user='root' group='root'/>
-  		</method_context>
- 	</exec_method>
- 
-@@ -557,10 +743,55 @@
- 		    type='astring' value='core,signal' />
- 	</property_group>
- 
-+	<!-- Properties in this group are used by routeadm (1M) -->
-+	<property_group name='routeadm' type='application'>
-+		<stability value='Unstable' />
-+		<!-- Identifies service as a routing service -->
-+		<propval name='daemon' type='astring'
-+			value='@sbindir@/bgpd' />
-+		<propval name='value_authorization' type='astring'
-+			value='solaris.smf.value.routing' />
-+		<property name='protocol' type='astring'>
-+			<astring_list>
-+				<value_node value='ipv4'/>
-+				<value_node value='ipv6'/>
-+			</astring_list>
-+		</property>
-+	</property_group>
-+	
-+	<!-- Properties in this group are modifiable via routeadm (1M) -->
- 	<property_group name='routing' type='application'>
- 		<propval name='value_authorization' type='astring' 
--		         value='solaris.smf.modify.routing' />
--		<propval name='daemon-args' type='astring' value='-P 0'/>
-+		         value='solaris.smf.value.routing' />
-+
-+		<!-- Options common to Quagga daemons. -->
-+		<!-- The config file to use, if not the default -->
-+		<propval name='config_file' type='astring' value=''/>
-+		<!-- The vty_port to listen on if not the default.
-+		     0 to disable --> 
-+		<propval name='vty_port' type='integer' value='0' />
-+		<!-- The address to bind the VTY interface to, if not any. -->
-+		<propval name='vty_address' type='astring' value='' />
-+		<!-- The user to switch to after startup, if not the default -->
-+		<propval name='user' type='astring' value='' />
-+		<!-- The group to switch to, if not the default.
-+		     If user is specified, this defaults to a group with
-+		     same name as user -->
-+		<propval name='group' type='astring' value='' />
-+		<!-- The pidfile to use, if not the default of
-+		     @quagga_statedir@ -->
-+		<propval name='pid_file' type='astring' value='' />
-+
-+		<!-- Options specific to bgpd -->
-+		<propval name='retain' type='boolean' value='false' />
-+		<propval name='no_kernel' type='boolean' value='false' />
-+		<propval name='bgp_port' type='astring' value='' />
-+		
-+		<!--
-+			If enable_zebra is false, it will not be switched
-+			on by the start method.
-+		-->
-+		<propval name='enable_zebra' type='boolean' value='true' />
- 	</property_group>
- 
- 	<property_group name='general' type='framework'>
-@@ -567,6 +798,8 @@
- 		<!-- to start stop routing services -->
- 		<propval name='action_authorization' type='astring'
- 			 value='solaris.smf.manage.routing' />
-+		<propval name='value_authorization' type='astring'
-+			 value='solaris.smf.manage.routing' />
- 	</property_group>
- 
- 	<template>
-@@ -583,6 +816,6 @@
- 		</documentation>
- 	</template>
- 	</instance>
--	<stability value='Evolving' />
-+	<stability value='Unstable' />
- </service>
- </service_bundle>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/quagga/patches/10-zebra-retain.patch	Tue Jan 03 11:08:59 2012 -0800
@@ -0,0 +1,20 @@
+--- solaris/quagga.init.in
++++ solaris/quagga.init.in
+@@ -63,6 +63,7 @@
+ 	case $1 in
+ 	zebra)
+ 		args="${args} `get_daemon_option_from_boolean_property $SMF_FMRI batch -b true`"
++		args="${args} `get_daemon_option_from_boolean_property $SMF_FMRI retain -r true`"
+ 		;;
+ 	ripd|ripngd)
+ 		args="${args} `get_daemon_option_from_boolean_property $SMF_FMRI retain -r true`"
+--- solaris/quagga.xml.in
++++ solaris/quagga.xml.in
+@@ -127,6 +127,7 @@
+ 		
+ 		<!-- Options specific to zebra -->
+ 		<propval name='batch' type='boolean' value='false' />
++		<propval name='retain' type='boolean' value='false' />
+ 	</property_group>
+ 	
+ 	<property_group name='general' type='framework'>
--- a/components/quagga/patches/15-privs-ipinst.patch	Tue Dec 20 22:26:25 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
---- lib/privs.c
-+++ lib/privs.c
-@@ -117,7 +117,12 @@
-   /* Quagga -> Solaris privilege mappings */
-   [ZCAP_SETID] =	{ 1, (pvalue_t []) { PRIV_PROC_SETID		}, },
-   [ZCAP_BIND] = 	{ 1, (pvalue_t []) { PRIV_NET_PRIVADDR		}, },
-+  /* IP_CONFIG is a subset of NET_CONFIG and is allowed in zones */
-+#ifdef PRIV_SYS_IP_CONFIG
-+  [ZCAP_NET_ADMIN] =	{ 1, (pvalue_t []) { PRIV_SYS_IP_CONFIG	}, },
-+#else
-   [ZCAP_NET_ADMIN] =	{ 1, (pvalue_t []) { PRIV_SYS_NET_CONFIG	}, },
-+#endif
-   [ZCAP_NET_RAW] = 	{ 2, (pvalue_t []) { PRIV_NET_RAWACCESS,
-                                              PRIV_NET_ICMPACCESS 	}, },
-   [ZCAP_CHROOT] = 	{ 1, (pvalue_t []) { PRIV_PROC_CHROOT		}, },
--- a/components/quagga/patches/20-privs-bgpd.patch	Tue Dec 20 22:26:25 2011 -0800
+++ b/components/quagga/patches/20-privs-bgpd.patch	Tue Jan 03 11:08:59 2012 -0800
@@ -1,7 +1,7 @@
 --- bgpd/bgp_main.c
 +++ bgpd/bgp_main.c
-@@ -103,7 +103,6 @@
- zebra_capabilities_t _caps_p [] =  
+@@ -118,7 +118,6 @@
+ static zebra_capabilities_t _caps_p [] =  
  {
      ZCAP_BIND, 
 -    ZCAP_NET_RAW,
--- a/components/quagga/patches/23-cve-2011-3327.patch	Tue Dec 20 22:26:25 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
---- bgpd/bgp_ecommunity.c
-+++ bgpd/bgp_ecommunity.c
-@@ -568,6 +568,13 @@
- 
-   for (i = 0; i < ecom->size; i++)
-     {
-+      /* Make sure the size is large enough. */
-+      while (str_pnt + ECOMMUNITY_STR_DEFAULT_LEN >= str_size)
-+	{
-+	  str_size *= 2;
-+	  str_buf = XREALLOC (MTYPE_ECOMMUNITY_STR, str_buf, str_size);
-+	}
-+
-       /* Space between each value.  */
-       if (! first)
- 	str_buf[str_pnt++] = ' ';
-@@ -610,13 +617,6 @@
- 	  break;
- 	}
- 
--      /* Make it sure size is enough.  */
--      while (str_pnt + ECOMMUNITY_STR_DEFAULT_LEN >= str_size)
--	{
--	  str_size *= 2;
--	  str_buf = XREALLOC (MTYPE_ECOMMUNITY_STR, str_buf, str_size);
--	}
--
-       /* Put string into buffer.  */
-       if (encode == ECOMMUNITY_ENCODE_AS)
- 	{
--- a/components/quagga/patches/25-isisd-dlpi.patch	Tue Dec 20 22:26:25 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2333 +0,0 @@
-diff --git a/ChangeLog b/ChangeLog
-index 38ea66d..ad1c40c 100644
---- ChangeLog
-+++ ChangeLog
-@@ -1,3 +1,8 @@
-+2007-08-07 James Carlson <[email protected]>
-+
-+	* configure.ac: Added support for separate link-layer access
-+	  mechanisms in isisd.
-+
- 2007-07-27 Paul Jakma <[email protected]>
- 
- 	* configure.ac: Bump version to 0.99.8
-diff --git a/configure.ac b/configure.ac
-index 857f415..437767e 100755
---- configure.ac
-+++ configure.ac
-@@ -750,6 +750,35 @@
- AC_SUBST(KERNEL_METHOD)
- AC_SUBST(OTHER_METHOD)
- 
-+dnl --------------------------
-+dnl Determine IS-IS I/O method
-+dnl --------------------------
-+AC_CHECK_HEADER(net/bpf.h)
-+AC_CHECK_HEADER(sys/dlpi.h)
-+AC_MSG_CHECKING(zebra IS-IS I/O method)
-+if test x"$opsys" = x"gnu-linux"; then
-+  AC_MSG_RESULT(pfpacket)
-+  ISIS_METHOD=isis_pfpacket.o
-+elif test x"$opsys" = x"sol2-6" -o x"$opsys" = x"sol8"; then
-+  AC_MSG_RESULT(DLPI)
-+  ISIS_METHOD="isis_dlpi.o"
-+else
-+  if test $ac_cv_header_net_bpf_h = no; then
-+    if test $ac_cv_header_sys_dlpi_h = no; then
-+      AC_MSG_RESULT(none)
-+      AC_MSG_WARN([*** IS-IS support will not be built ***])
-+      ISISD=""
-+    else
-+      AC_MSG_RESULT(DLPI)
-+    fi
-+    ISIS_METHOD="isis_dlpi.o"
-+  else
-+    AC_MSG_RESULT(BPF)
-+    ISIS_METHOD="isis_bpf.o"
-+  fi
-+fi
-+AC_SUBST(ISIS_METHOD)
-+
- dnl ------------------------------------
- dnl check for broken CMSG_FIRSTHDR macro
- dnl ------------------------------------
-diff --git a/isisd/ChangeLog b/isisd/ChangeLog
-index 8797af1..c2482f0 100644
---- isisd/ChangeLog
-+++ isisd/ChangeLog
-@@ -1,3 +1,20 @@
-+2008-01-29 James Carlson <[email protected]>
-+
-+	* Fix bug #437, assert due to bogus index management 
-+	* isis_flags.c: (flags_initialize) new
-+	* (flags_get_index) fix off by one, leading to list assert
-+	  on null node data.
-+	  (flags_free_index) ditto.
-+	* isisd.c: (isis_area_create) use flags_initialize
-+	  (isis_area_destroy) deconfigure circuits when
-+	  taking down area.
-+
-+2007-07-18 James Carlson <[email protected]>
-+
-+	* isis_network.c: split up into isis_bpf.c, isis_dlpi.c, and
-+	  isis_pfpacket.c, selected by autoconf, and added DLPI support.
-+	* (general) Fixed to allow compilation and use on Solaris.
-+
- 2006-12-08 Hannes Gredler <[email protected]>
- 
- 	* isis_adjacency.c: (isis_new_adj) Allow NULL snpa argument.
-diff --git a/isisd/Makefile.am b/isisd/Makefile.am
-index 1dd5493..859facd 100644
---- isisd/Makefile.am
-+++ isisd/Makefile.am
-@@ -9,9 +9,11 @@ noinst_LIBRARIES = libisis.a
- sbin_PROGRAMS = isisd 
- SUBDIRS = topology
- 
-+isis_method = @ISIS_METHOD@
-+
- libisis_a_SOURCES = \
- 	isis_adjacency.c isis_lsp.c dict.c isis_circuit.c isis_pdu.c \
--	isis_tlv.c isisd.c isis_misc.c isis_network.c isis_zebra.c isis_dr.c \
-+	isis_tlv.c isisd.c isis_misc.c isis_zebra.c isis_dr.c \
- 	isis_flags.c isis_dynhn.c iso_checksum.c isis_csm.c isis_events.c \
- 	isis_spf.c isis_route.c isis_routemap.c
- 
-@@ -26,7 +28,11 @@ noinst_HEADERS = \
- isisd_SOURCES = \
- 	isis_main.c $(libisis_a_SOURCES)
- 
--isisd_LDADD = @ISIS_TOPOLOGY_LIB@ ../lib/libzebra.la @LIBCAP@
-+isisd_LDADD = $(isis_method) @ISIS_TOPOLOGY_LIB@ ../lib/libzebra.la @LIBCAP@
-+
-+isisd_DEPENDENCIES = $(isis_method)
-+
-+EXTRA_DIST = isis_bpf.c isis_dlpi.c isis_pfpacket.c
- 
- examplesdir = $(exampledir)
- dist_examples_DATA = isisd.conf.sample
-diff --git a/isisd/dict.c b/isisd/dict.c
-index a333d3e..6c3e1e7 100644
---- isisd/dict.c
-+++ isisd/dict.c
-@@ -14,12 +14,13 @@
-  * into proprietary software; there is no requirement for such software to
-  * contain a copyright notice related to this source.
-  *
-- * $Id: dict.c,v 1.4 2005/09/25 12:04:25 hasso Exp $
-- * $Name:  $
-+ * $Id$
-+ * $Name$
-  */
- 
- #include <stdlib.h>
- #include <stddef.h>
-+#include "zebra.h"
- #include "zassert.h"
- #define DICT_IMPLEMENTATION
- #include "dict.h"
-diff --git a/isisd/include-netbsd/iso.h b/isisd/include-netbsd/iso.h
-index 714b42d..1a80aec 100644
---- isisd/include-netbsd/iso.h
-+++ isisd/include-netbsd/iso.h
-@@ -192,7 +192,13 @@ extern struct protosw isosw[];
- #else
- /* user utilities definitions from the iso library */
- 
-+#ifdef SUNOS_5
-+#define	__P(x)	x
-+#define	__BEGIN_DECLS
-+#define	__END_DECLS
-+#else
- #include <sys/cdefs.h>
-+#endif
- 
- __BEGIN_DECLS
- struct iso_addr *iso_addr __P((const char *));
-diff --git a/isisd/isisd.c b/isisd/isisd.c
-index 714b42d..1a80aec 100644
---- isisd/isisd.c
-+++ isisd/isisd.c
-@@ -130,7 +130,7 @@
-   area->circuit_list = list_new ();
-   area->area_addrs = list_new ();
-   THREAD_TIMER_ON (master, area->t_tick, lsp_tick, area, 1);
--  area->flags.maxindex = -1;
-+  flags_initialize (&area->flags);
-   /*
-    * Default values
-    */
-@@ -215,7 +215,11 @@
-   if (area->circuit_list)
-     {
-       for (ALL_LIST_ELEMENTS (area->circuit_list, node, nnode, circuit))
--        isis_circuit_del (circuit);
-+	{
-+	  /* The fact that it's in circuit_list means that it was configured */
-+	  isis_circuit_deconfigure (circuit, area);
-+	  isis_circuit_del (circuit);
-+	}
-       
-       list_delete (area->circuit_list);
-     }
-diff --git a/isisd/isis_bpf.c b/isisd/isis_bpf.c
-new file mode 100644
-index 0000000..e66ac98
---- /dev/null
-+++ isisd/isis_bpf.c
-@@ -0,0 +1,340 @@
-+/*
-+ * IS-IS Rout(e)ing protocol - isis_bpf.c
-+ *
-+ * Copyright (C) 2001,2002    Sampo Saaristo
-+ *                            Tampere University of Technology      
-+ *                            Institute of Communications Engineering
-+ *
-+ * This program is free software; you can redistribute it and/or modify it 
-+ * under the terms of the GNU General Public Licenseas published by the Free 
-+ * Software Foundation; either version 2 of the License, or (at your option) 
-+ * any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,but WITHOUT 
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
-+ * more details.
-+
-+ * You should have received a copy of the GNU General Public License along 
-+ * with this program; if not, write to the Free Software Foundation, Inc., 
-+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-+ */
-+
-+#include <zebra.h>
-+#include <net/if.h>
-+#include <netinet/if_ether.h>
-+#include <sys/time.h>
-+#include <sys/ioctl.h>
-+#include <net/bpf.h>
-+
-+#include "log.h"
-+#include "stream.h"
-+#include "if.h"
-+
-+#include "isisd/dict.h"
-+#include "isisd/include-netbsd/iso.h"
-+#include "isisd/isis_constants.h"
-+#include "isisd/isis_common.h"
-+#include "isisd/isis_circuit.h"
-+#include "isisd/isis_flags.h"
-+#include "isisd/isisd.h"
-+#include "isisd/isis_constants.h"
-+#include "isisd/isis_circuit.h"
-+#include "isisd/isis_network.h"
-+
-+#include "privs.h"
-+
-+extern struct zebra_privs_t isisd_privs;
-+
-+struct bpf_insn llcfilter[] = {
-+  BPF_STMT (BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN),	/* check first byte */
-+  BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ISO_SAP, 0, 5),
-+  BPF_STMT (BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN + 1),
-+  BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ISO_SAP, 0, 3),	/* check second byte */
-+  BPF_STMT (BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN + 2),
-+  BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 0x03, 0, 1),	/* check third byte */
-+  BPF_STMT (BPF_RET + BPF_K, (u_int) - 1),
-+  BPF_STMT (BPF_RET + BPF_K, 0)
-+};
-+int readblen = 0;
-+u_char *readbuff = NULL;
-+
-+/*
-+ * Table 9 - Architectural constants for use with ISO 8802 subnetworks
-+ * ISO 10589 - 8.4.8
-+ */
-+
-+u_char ALL_L1_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x14 };
-+u_char ALL_L2_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x15 };
-+u_char ALL_ISS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x05 };
-+u_char ALL_ESS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x04 };
-+
-+static char sock_buff[8192];
-+
-+static int
-+open_bpf_dev (struct isis_circuit *circuit)
-+{
-+  int i = 0, fd;
-+  char bpfdev[128];
-+  struct ifreq ifr;
-+  u_int16_t blen;
-+  int true = 1, false = 0;
-+  struct timeval timeout;
-+  struct bpf_program bpf_prog;
-+
-+  do
-+    {
-+      (void) snprintf (bpfdev, sizeof (bpfdev), "/dev/bpf%d", i++);
-+      fd = open (bpfdev, O_RDWR);
-+    }
-+  while (fd < 0 && errno == EBUSY);
-+
-+  if (fd < 0)
-+    {
-+      zlog_warn ("open_bpf_dev(): failed to create bpf socket: %s",
-+		 safe_strerror (errno));
-+      return ISIS_WARNING;
-+    }
-+
-+  zlog_debug ("Opened BPF device %s", bpfdev);
-+
-+  memcpy (ifr.ifr_name, circuit->interface->name, sizeof (ifr.ifr_name));
-+  if (ioctl (fd, BIOCSETIF, (caddr_t) & ifr) < 0)
-+    {
-+      zlog_warn ("open_bpf_dev(): failed to bind to interface: %s",
-+		 safe_strerror (errno));
-+      return ISIS_WARNING;
-+    }
-+
-+  if (ioctl (fd, BIOCGBLEN, (caddr_t) & blen) < 0)
-+    {
-+      zlog_warn ("failed to get BPF buffer len");
-+      blen = circuit->interface->mtu;
-+    }
-+
-+  readblen = blen;
-+
-+  if (readbuff == NULL)
-+    readbuff = malloc (blen);
-+
-+  zlog_debug ("BPF buffer len = %u", blen);
-+
-+  /*  BPF(4): reads return immediately upon packet reception.
-+   *  Otherwise, a read will block until either the kernel
-+   *  buffer becomes full or a timeout occurs. 
-+   */
-+  if (ioctl (fd, BIOCIMMEDIATE, (caddr_t) & true) < 0)
-+    {
-+      zlog_warn ("failed to set BPF dev to immediate mode");
-+    }
-+
-+#ifdef BIOCSSEESENT
-+  /*
-+   * We want to see only incoming packets
-+   */
-+  if (ioctl (fd, BIOCSSEESENT, (caddr_t) & false) < 0)
-+    {
-+      zlog_warn ("failed to set BPF dev to incoming only mode");
-+    }
-+#endif
-+
-+  /*
-+   * ...but all of them
-+   */
-+  if (ioctl (fd, BIOCPROMISC, (caddr_t) & true) < 0)
-+    {
-+      zlog_warn ("failed to set BPF dev to promiscuous mode");
-+    }
-+
-+  /*
-+   * If the buffer length is smaller than our mtu, lets try to increase it
-+   */
-+  if (blen < circuit->interface->mtu)
-+    {
-+      if (ioctl (fd, BIOCSBLEN, &circuit->interface->mtu) < 0)
-+	{
-+	  zlog_warn ("failed to set BPF buffer len (%u to %u)", blen,
-+		     circuit->interface->mtu);
-+	}
-+    }
-+
-+  /*
-+   * Set a timeout parameter - hope this helps select()
-+   */
-+  timeout.tv_sec = 600;
-+  timeout.tv_usec = 0;
-+  if (ioctl (fd, BIOCSRTIMEOUT, (caddr_t) & timeout) < 0)
-+    {
-+      zlog_warn ("failed to set BPF device timeout");
-+    }
-+
-+  /*
-+   * And set the filter
-+   */
-+  memset (&bpf_prog, 0, sizeof (struct bpf_program));
-+  bpf_prog.bf_len = 8;
-+  bpf_prog.bf_insns = &(llcfilter[0]);
-+  if (ioctl (fd, BIOCSETF, (caddr_t) & bpf_prog) < 0)
-+    {
-+      zlog_warn ("open_bpf_dev(): failed to install filter: %s",
-+		 safe_strerror (errno));
-+      return ISIS_WARNING;
-+    }
-+
-+  assert (fd > 0);
-+
-+  circuit->fd = fd;
-+
-+  return ISIS_OK;
-+}
-+
-+/*
-+ * Create the socket and set the tx/rx funcs
-+ */
-+int
-+isis_sock_init (struct isis_circuit *circuit)
-+{
-+  int retval = ISIS_OK;
-+
-+  if (isisd_privs.change (ZPRIVS_RAISE))
-+    zlog_err ("%s: could not raise privs, %s", __func__, safe_strerror (errno));
-+
-+  retval = open_bpf_dev (circuit);
-+
-+  if (retval != ISIS_OK)
-+    {
-+      zlog_warn ("%s: could not initialize the socket", __func__);
-+      goto end;
-+    }
-+
-+  if (circuit->circ_type == CIRCUIT_T_BROADCAST)
-+    {
-+      circuit->tx = isis_send_pdu_bcast;
-+      circuit->rx = isis_recv_pdu_bcast;
-+    }
-+  else if (circuit->circ_type == CIRCUIT_T_P2P)
-+    {
-+      circuit->tx = isis_send_pdu_p2p;
-+      circuit->rx = isis_recv_pdu_p2p;
-+    }
-+  else
-+    {
-+      zlog_warn ("isis_sock_init(): unknown circuit type");
-+      retval = ISIS_WARNING;
-+      goto end;
-+    }
-+
-+end:
-+  if (isisd_privs.change (ZPRIVS_LOWER))
-+    zlog_err ("%s: could not lower privs, %s", __func__, safe_strerror (errno));
-+
-+  return retval;
-+}
-+
-+int
-+isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa)
-+{
-+  int bytesread = 0, bytestoread, offset, one = 1;
-+  struct bpf_hdr *bpf_hdr;
-+
-+  assert (circuit->fd > 0);
-+
-+  if (ioctl (circuit->fd, FIONREAD, (caddr_t) & bytestoread) < 0)
-+    {
-+      zlog_warn ("ioctl() FIONREAD failed: %s", safe_strerror (errno));
-+    }
-+
-+  if (bytestoread)
-+    {
-+      bytesread = read (circuit->fd, readbuff, readblen);
-+    }
-+  if (bytesread < 0)
-+    {
-+      zlog_warn ("isis_recv_pdu_bcast(): read() failed: %s",
-+		 safe_strerror (errno));
-+      return ISIS_WARNING;
-+    }
-+
-+  if (bytesread == 0)
-+    return ISIS_WARNING;
-+
-+  bpf_hdr = (struct bpf_hdr *) readbuff;
-+
-+  assert (bpf_hdr->bh_caplen == bpf_hdr->bh_datalen);
-+
-+  offset = bpf_hdr->bh_hdrlen + LLC_LEN + ETHER_HDR_LEN;
-+
-+  /* then we lose the BPF, LLC and ethernet headers */
-+  stream_write (circuit->rcv_stream, readbuff + offset, 
-+                bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN);
-+  stream_set_getp (circuit->rcv_stream, 0);
-+
-+  memcpy (ssnpa, readbuff + bpf_hdr->bh_hdrlen + ETHER_ADDR_LEN,
-+	  ETHER_ADDR_LEN);
-+
-+  if (ioctl (circuit->fd, BIOCFLUSH, &one) < 0)
-+    zlog_warn ("Flushing failed: %s", safe_strerror (errno));
-+
-+  return ISIS_OK;
-+}
-+
-+int
-+isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char * ssnpa)
-+{
-+  int bytesread;
-+
-+  bytesread = stream_read (circuit->rcv_stream, circuit->fd, 
-+                           circuit->interface->mtu);
-+
-+  if (bytesread < 0)
-+    {
-+      zlog_warn ("isis_recv_pdu_p2p(): read () failed: %s", safe_strerror (errno));
-+      return ISIS_WARNING;
-+    }
-+
-+  return ISIS_OK;
-+}
-+
-+int
-+isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
-+{
-+  struct ether_header *eth;
-+  int written;
-+
-+  stream_set_getp (circuit->snd_stream, 0);
-+
-+  /*
-+   * First the eth header
-+   */
-+  eth = (struct ether_header *) sock_buff;
-+  if (level == 1)
-+    memcpy (eth->ether_dhost, ALL_L1_ISS, ETHER_ADDR_LEN);
-+  else
-+    memcpy (eth->ether_dhost, ALL_L2_ISS, ETHER_ADDR_LEN);
-+  memcpy (eth->ether_shost, circuit->u.bc.snpa, ETHER_ADDR_LEN);
-+  eth->ether_type = htons (stream_get_endp (circuit->snd_stream) + LLC_LEN);
-+
-+  /*
-+   * Then the LLC
-+   */
-+  sock_buff[ETHER_HDR_LEN] = ISO_SAP;
-+  sock_buff[ETHER_HDR_LEN + 1] = ISO_SAP;
-+  sock_buff[ETHER_HDR_LEN + 2] = 0x03;
-+
-+  /* then we copy the data */
-+  memcpy (sock_buff + (LLC_LEN + ETHER_HDR_LEN), circuit->snd_stream->data,
-+	  stream_get_endp (circuit->snd_stream));
-+
-+  /* now we can send this */
-+  written = write (circuit->fd, sock_buff,
-+		   stream_get_endp (circuit->snd_stream) 
-+		    + LLC_LEN + ETHER_HDR_LEN);
-+
-+  return ISIS_OK;
-+}
-+
-+int
-+isis_send_pdu_p2p (struct isis_circuit *circuit, int level)
-+{
-+  return ISIS_OK;
-+}
-diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
-index fe3eb82..af24988 100644
---- isisd/isis_circuit.c
-+++ isisd/isis_circuit.c
-@@ -26,6 +26,10 @@
- #include <netinet/if_ether.h>
- #endif
- 
-+#ifndef ETHER_ADDR_LEN
-+#define	ETHER_ADDR_LEN	ETHERADDRL
-+#endif
-+
- #include "log.h"
- #include "memory.h"
- #include "if.h"
-@@ -381,11 +385,13 @@ isis_circuit_if_add (struct isis_circuit *circuit, struct interface *ifp)
-        * Get the Hardware Address
-        */
- #ifdef HAVE_STRUCT_SOCKADDR_DL
-+#ifndef SUNOS_5
-       if (circuit->interface->sdl.sdl_alen != ETHER_ADDR_LEN)
- 	zlog_warn ("unsupported link layer");
-       else
- 	memcpy (circuit->u.bc.snpa, LLADDR (&circuit->interface->sdl),
- 		ETH_ALEN);
-+#endif
- #else
-       if (circuit->interface->hw_addr_len != ETH_ALEN)
- 	{
-@@ -447,10 +453,12 @@ isis_circuit_update_params (struct isis_circuit *circuit,
-    * Get the Hardware Address
-    */
- #ifdef HAVE_STRUCT_SOCKADDR_DL
-+#ifndef SUNOS_5
-   if (circuit->interface->sdl.sdl_alen != ETHER_ADDR_LEN)
-     zlog_warn ("unsupported link layer");
-   else
-     memcpy (circuit->u.bc.snpa, LLADDR (&circuit->interface->sdl), ETH_ALEN);
-+#endif
- #else
-   if (circuit->interface->hw_addr_len != ETH_ALEN)
-     {
-diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h
-index b5ef269..a7e719f 100644
---- isisd/isis_circuit.h
-+++ isisd/isis_circuit.h
-@@ -69,6 +69,7 @@ struct isis_circuit
-   struct isis_area *area;	/* back pointer to the area */
-   struct interface *interface;	/* interface info from z */
-   int fd;			/* IS-IS l1/2 socket */
-+  int sap_length;		/* SAP length for DLPI */
-   struct nlpids nlpids;
-   /*
-    * Threads
-diff --git a/isisd/isis_dlpi.c b/isisd/isis_dlpi.c
-new file mode 100644
-index 0000000..db4383b
---- /dev/null
-+++ isisd/isis_dlpi.c
-@@ -0,0 +1,607 @@
-+/*
-+ * IS-IS Rout(e)ing protocol - isis_dlpi.c
-+ *
-+ * Copyright (C) 2001,2002    Sampo Saaristo
-+ *                            Tampere University of Technology      
-+ *                            Institute of Communications Engineering
-+ *
-+ * This program is free software; you can redistribute it and/or modify it 
-+ * under the terms of the GNU General Public Licenseas published by the Free 
-+ * Software Foundation; either version 2 of the License, or (at your option) 
-+ * any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,but WITHOUT 
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
-+ * more details.
-+
-+ * You should have received a copy of the GNU General Public License along 
-+ * with this program; if not, write to the Free Software Foundation, Inc., 
-+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-+ */
-+
-+#include <zebra.h>
-+#include <net/if.h>
-+#include <netinet/if_ether.h>
-+#include <sys/types.h>
-+#include <unistd.h>
-+#include <fcntl.h>
-+#include <stropts.h>
-+#include <poll.h>
-+#include <sys/dlpi.h>
-+#include <sys/pfmod.h>
-+
-+#include "log.h"
-+#include "stream.h"
-+#include "if.h"
-+
-+#include "isisd/dict.h"
-+#include "isisd/include-netbsd/iso.h"
-+#include "isisd/isis_constants.h"
-+#include "isisd/isis_common.h"
-+#include "isisd/isis_circuit.h"
-+#include "isisd/isis_flags.h"
-+#include "isisd/isisd.h"
-+#include "isisd/isis_constants.h"
-+#include "isisd/isis_circuit.h"
-+#include "isisd/isis_network.h"
-+
-+#include "privs.h"
-+
-+extern struct zebra_privs_t isisd_privs;
-+
-+static t_uscalar_t dlpi_ctl[1024];	/* DLPI control messages */
-+
-+/*
-+ * Table 9 - Architectural constants for use with ISO 8802 subnetworks
-+ * ISO 10589 - 8.4.8
-+ */
-+
-+u_char ALL_L1_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x14 };
-+u_char ALL_L2_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x15 };
-+u_char ALL_ISS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x05 };
-+u_char ALL_ESS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x04 };
-+
-+static u_char sock_buff[8192];
-+
-+static u_short pf_filter[] =
-+{
-+  ENF_PUSHWORD + 0,		/* Get the SSAP/DSAP values */
-+  ENF_PUSHLIT | ENF_CAND,	/* Check them */
-+  ISO_SAP | (ISO_SAP << 8),
-+  ENF_PUSHWORD + 1,		/* Get the control value */
-+  ENF_PUSHLIT | ENF_AND,	/* Isolate it */
-+#ifdef _BIG_ENDIAN
-+  0xFF00,
-+#else
-+  0x00FF,
-+#endif
-+  ENF_PUSHLIT | ENF_CAND,	/* Test for expected value */
-+#ifdef _BIG_ENDIAN
-+  0x0300
-+#else
-+  0x0003
-+#endif
-+};
-+
-+/*
-+ * We would like to use something like libdlpi here, but that's not present on
-+ * all versions of Solaris or on any non-Solaris system, so it's nowhere near
-+ * as portable as we'd like.  Thus, we use the standards-conformant DLPI
-+ * interfaces plus the (optional; not needed) Solaris packet filter module.
-+ */
-+
-+static void
-+dlpisend (int fd, const void *cbuf, size_t cbuflen,
-+  const void *dbuf, size_t dbuflen, int flags)
-+{
-+  const struct strbuf *ctlptr = NULL;
-+  const struct strbuf *dataptr = NULL;
-+  struct strbuf ctlbuf, databuf;
-+
-+  if (cbuf != NULL)
-+    {
-+      memset (&ctlbuf, 0, sizeof (ctlbuf));
-+      ctlbuf.len = cbuflen;
-+      ctlbuf.buf = (void *)cbuf;
-+      ctlptr = &ctlbuf;
-+    }
-+
-+  if (dbuf != NULL)
-+    {
-+      memset (&databuf, 0, sizeof (databuf));
-+      databuf.len = dbuflen;
-+      databuf.buf = (void *)dbuf;
-+      dataptr = &databuf;
-+    }
-+
-+  /* We assume this doesn't happen often and isn't operationally significant */
-+  if (putmsg (fd, ctlptr, dataptr, flags) == -1)
-+    zlog_debug ("%s: putmsg: %s", __func__, safe_strerror (errno));
-+}
-+
-+static ssize_t
-+dlpirctl (int fd)
-+{
-+  struct pollfd fds[1];
-+  struct strbuf ctlbuf, databuf;
-+  int flags, retv;
-+
-+  do
-+    {
-+      /* Poll is used here in case the device doesn't speak DLPI correctly */
-+      memset (fds, 0, sizeof (fds));
-+      fds[0].fd = fd;
-+      fds[0].events = POLLIN | POLLPRI;
-+      if (poll (fds, 1, 1000) <= 0)
-+	return -1;
-+
-+      memset (&ctlbuf, 0, sizeof (ctlbuf));
-+      memset (&databuf, 0, sizeof (databuf));
-+      ctlbuf.maxlen = sizeof (dlpi_ctl);
-+      ctlbuf.buf = (void *)dlpi_ctl;
-+      databuf.maxlen = sizeof (sock_buff);
-+      databuf.buf = (void *)sock_buff;
-+      flags = 0;
-+      retv = getmsg (fd, &ctlbuf, &databuf, &flags);
-+
-+      if (retv < 0)
-+	return -1;
-+    }
-+  while (ctlbuf.len == 0);
-+
-+  if (!(retv & MORECTL))
-+    {
-+      while (retv & MOREDATA)
-+	{
-+	  flags = 0;
-+	  retv = getmsg (fd, NULL, &databuf, &flags);
-+	}
-+      return ctlbuf.len;
-+    }
-+
-+  while (retv & MORECTL)
-+    {
-+      flags = 0;
-+      retv = getmsg (fd, &ctlbuf, &databuf, &flags);
-+    }
-+  return -1;
-+}
-+
-+static int
-+dlpiok (int fd, t_uscalar_t oprim)
-+{
-+  int retv;
-+  dl_ok_ack_t *doa = (dl_ok_ack_t *)dlpi_ctl;
-+
-+  retv = dlpirctl (fd);
-+  if (retv < DL_OK_ACK_SIZE || doa->dl_primitive != DL_OK_ACK ||
-+    doa->dl_correct_primitive != oprim)
-+    {
-+      return -1;
-+    }
-+  else
-+    {
-+      return 0;
-+    }
-+}
-+
-+static int
-+dlpiinfo (int fd)
-+{
-+  dl_info_req_t dir;
-+  ssize_t retv;
-+
-+  memset (&dir, 0, sizeof (dir));
-+  dir.dl_primitive = DL_INFO_REQ;
-+  /* Info_req uses M_PCPROTO. */
-+  dlpisend (fd, &dir, sizeof (dir), NULL, 0, RS_HIPRI);
-+  retv = dlpirctl (fd);
-+  if (retv < DL_INFO_ACK_SIZE || dlpi_ctl[0] != DL_INFO_ACK)
-+    return -1;
-+  else
-+    return retv;
-+}
-+
-+static int
-+dlpiopen (const char *devpath, ssize_t *acklen)
-+{
-+  int fd, flags;
-+
-+  fd = open (devpath, O_RDWR | O_NONBLOCK | O_NOCTTY);
-+  if (fd == -1)
-+    return -1;
-+
-+  /* All that we want is for the open itself to be non-blocking, not I/O. */
-+  flags = fcntl (fd, F_GETFL, 0);
-+  if (flags != -1)
-+    fcntl (fd, F_SETFL, flags & ~O_NONBLOCK);
-+
-+  /* After opening, ask for information */
-+  if ((*acklen = dlpiinfo (fd)) == -1)
-+    {
-+      close (fd);
-+      return -1;
-+    }
-+
-+  return fd;
-+}
-+
-+static int
-+dlpiattach (int fd, int unit)
-+{
-+  dl_attach_req_t dar;
-+
-+  memset (&dar, 0, sizeof (dar));
-+  dar.dl_primitive = DL_ATTACH_REQ;
-+  dar.dl_ppa = unit;
-+  dlpisend (fd, &dar, sizeof (dar), NULL, 0, 0);
-+  return dlpiok (fd, dar.dl_primitive);
-+}
-+
-+static int
-+dlpibind (int fd)
-+{
-+  dl_bind_req_t dbr;
-+  int retv;
-+  dl_bind_ack_t *dba = (dl_bind_ack_t *)dlpi_ctl;
-+
-+  memset (&dbr, 0, sizeof (dbr));
-+  dbr.dl_primitive = DL_BIND_REQ;
-+  dbr.dl_service_mode = DL_CLDLS;
-+  dlpisend (fd, &dbr, sizeof (dbr), NULL, 0, 0);
-+
-+  retv = dlpirctl (fd);
-+  if (retv < DL_BIND_ACK_SIZE || dba->dl_primitive != DL_BIND_ACK)
-+    return -1;
-+  else
-+    return 0;
-+}
-+
-+static int
-+dlpimcast (int fd, const u_char *mcaddr)
-+{
-+  struct {
-+    dl_enabmulti_req_t der;
-+    u_char addr[ETHERADDRL];
-+  } dler;
-+
-+  memset (&dler, 0, sizeof (dler));
-+  dler.der.dl_primitive = DL_ENABMULTI_REQ;
-+  dler.der.dl_addr_length = sizeof (dler.addr);
-+  dler.der.dl_addr_offset = dler.addr - (u_char *)&dler;
-+  memcpy (dler.addr, mcaddr, sizeof (dler.addr));
-+  dlpisend (fd, &dler, sizeof (dler), NULL, 0, 0);
-+  return dlpiok (fd, dler.der.dl_primitive);
-+}
-+
-+static int
-+dlpiaddr (int fd, u_char *addr)
-+{
-+  dl_phys_addr_req_t dpar;
-+  dl_phys_addr_ack_t *dpaa = (dl_phys_addr_ack_t *)dlpi_ctl;
-+  int retv;
-+
-+  memset (&dpar, 0, sizeof (dpar));
-+  dpar.dl_primitive = DL_PHYS_ADDR_REQ;
-+  dpar.dl_addr_type = DL_CURR_PHYS_ADDR;
-+  dlpisend (fd, &dpar, sizeof (dpar), NULL, 0, 0);
-+
-+  retv = dlpirctl (fd);
-+  if (retv < DL_PHYS_ADDR_ACK_SIZE || dpaa->dl_primitive != DL_PHYS_ADDR_ACK)
-+    return -1;
-+
-+  if (dpaa->dl_addr_offset < DL_PHYS_ADDR_ACK_SIZE ||
-+    dpaa->dl_addr_length != ETHERADDRL ||
-+    dpaa->dl_addr_offset + dpaa->dl_addr_length > retv)
-+    return -1;
-+
-+  bcopy((char *)dpaa + dpaa->dl_addr_offset, addr, ETHERADDRL);
-+  return 0;
-+}
-+
-+static int
-+open_dlpi_dev (struct isis_circuit *circuit)
-+{
-+  int fd, unit, retval;
-+  char devpath[MAXPATHLEN];
-+  dl_info_ack_t *dia = (dl_info_ack_t *)dlpi_ctl;
-+  ssize_t acklen;
-+
-+  /* Only broadcast-type are supported at the moment */
-+  if (circuit->circ_type != CIRCUIT_T_BROADCAST)
-+    {
-+      zlog_warn ("%s: non-broadcast interface %s", __func__,
-+	circuit->interface->name);
-+      return ISIS_WARNING;
-+    }
-+
-+  /* Try first as Style 1 */
-+  (void) snprintf(devpath, sizeof (devpath), "/dev/%s",
-+    circuit->interface->name);
-+  unit = -1;
-+  fd = dlpiopen (devpath, &acklen);
-+
-+  /* If that fails, try again as Style 2 */
-+  if (fd == -1)
-+    {
-+      char *cp;
-+
-+      cp = devpath + strlen (devpath);
-+      while (--cp >= devpath && isdigit(*cp))
-+	;
-+      unit = strtol(cp, NULL, 0);
-+      *cp = '\0';
-+      fd = dlpiopen (devpath, &acklen);
-+
-+      /* If that too fails, then the device really doesn't exist */
-+      if (fd == -1)
-+	{
-+	  zlog_warn ("%s: unknown interface %s", __func__,
-+	    circuit->interface->name);
-+	  return ISIS_WARNING;
-+	}
-+
-+      /* Double check the DLPI style */
-+      if (dia->dl_provider_style != DL_STYLE2)
-+	{
-+	  zlog_warn ("open_dlpi_dev(): interface %s: %s is not style 2",
-+	    circuit->interface->name, devpath);
-+	  close (fd);
-+	  return ISIS_WARNING;
-+	}
-+
-+      /* If it succeeds, then we need to attach to the unit specified */
-+      dlpiattach (fd, unit);
-+
-+      /* Reget the information, as it may be different per node */
-+      if ((acklen = dlpiinfo (fd)) == -1)
-+	{
-+	  close (fd);
-+	  return ISIS_WARNING;
-+	}
-+    }
-+  else
-+    {
-+      /* Double check the DLPI style */
-+      if (dia->dl_provider_style != DL_STYLE1)
-+	{
-+	  zlog_warn ("open_dlpi_dev(): interface %s: %s is not style 1",
-+	    circuit->interface->name, devpath);
-+	  close (fd);
-+	  return ISIS_WARNING;
-+	}
-+    }
-+
-+  /* Check that the interface we've got is the kind we expect */
-+  if ((dia->dl_sap_length != 2 && dia->dl_sap_length != -2) ||
-+    dia->dl_service_mode != DL_CLDLS || dia->dl_addr_length != ETHERADDRL + 2 ||
-+    dia->dl_brdcst_addr_length != ETHERADDRL)
-+    {
-+      zlog_warn ("%s: unsupported interface type for %s", __func__,
-+	circuit->interface->name);
-+      close (fd);
-+      return ISIS_WARNING;
-+    }
-+  switch (dia->dl_mac_type)
-+    {
-+    case DL_CSMACD:
-+    case DL_ETHER:
-+    case DL_100VG:
-+    case DL_100VGTPR:
-+    case DL_ETH_CSMA:
-+    case DL_100BT:
-+      break;
-+    default:
-+      zlog_warn ("%s: unexpected mac type on %s: %d", __func__,
-+	circuit->interface->name, dia->dl_mac_type);
-+      close (fd);
-+      return ISIS_WARNING;
-+    }
-+
-+  circuit->sap_length = dia->dl_sap_length;
-+
-+  /*
-+   * The local hardware address is something that should be provided by way of
-+   * sockaddr_dl for the interface, but isn't on Solaris.  We set it here based
-+   * on DLPI's reported address to avoid roto-tilling the world.
-+   * (Note that isis_circuit_if_add on Solaris doesn't set the snpa.)
-+   *
-+   * Unfortunately, GLD is broken and doesn't provide the address after attach,
-+   * so we need to be careful and use DL_PHYS_ADDR_REQ instead.
-+   */
-+  if (dlpiaddr (fd, circuit->u.bc.snpa) == -1)
-+    {
-+      zlog_warn ("open_dlpi_dev(): interface %s: unable to get MAC address",
-+	circuit->interface->name);
-+      close (fd);
-+      return ISIS_WARNING;
-+    }
-+
-+  /* Now bind to SAP 0.  This gives us 802-type traffic. */
-+  if (dlpibind (fd) == -1)
-+    {
-+      zlog_warn ("%s: cannot bind SAP 0 on %s", __func__,
-+	circuit->interface->name);
-+      close (fd);
-+      return ISIS_WARNING;
-+    }
-+
-+  /*
-+   * Join to multicast groups according to
-+   * 8.4.2 - Broadcast subnetwork IIH PDUs
-+   */
-+  retval = 0;
-+  if (circuit->circuit_is_type & IS_LEVEL_1)
-+    {
-+      retval |= dlpimcast (fd, ALL_L1_ISS);
-+      retval |= dlpimcast (fd, ALL_ISS);
-+    }
-+  if (circuit->circuit_is_type & IS_LEVEL_2)
-+    retval |= dlpimcast (fd, ALL_L2_ISS);
-+
-+  if (retval != 0)
-+    {
-+      zlog_warn ("%s: unable to join multicast on %s", __func__,
-+	circuit->interface->name);
-+      close (fd);
-+      return ISIS_WARNING;
-+    }
-+
-+  /* Push on the packet filter to avoid stray 802 packets */
-+  if (ioctl (fd, I_PUSH, "pfmod") == 0)
-+    {
-+      struct packetfilt pfil;
-+
-+      pfil.Pf_Priority = 0;
-+      pfil.Pf_FilterLen = sizeof (pf_filter) / sizeof (u_short);
-+      memcpy (pfil.Pf_Filter, pf_filter, sizeof (pf_filter));
-+      ioctl (fd, PFIOCSETF, &pfil);
-+    }
-+
-+  circuit->fd = fd;
-+
-+  return ISIS_OK;
-+}
-+
-+/*
-+ * Create the socket and set the tx/rx funcs
-+ */
-+int
-+isis_sock_init (struct isis_circuit *circuit)
-+{
-+  int retval = ISIS_OK;
-+
-+  if (isisd_privs.change (ZPRIVS_RAISE))
-+    zlog_err ("%s: could not raise privs, %s", __func__, safe_strerror (errno));
-+
-+  retval = open_dlpi_dev (circuit);
-+
-+  if (retval != ISIS_OK)
-+    {
-+      zlog_warn ("%s: could not initialize the socket", __func__);
-+      goto end;
-+    }
-+
-+  if (circuit->circ_type == CIRCUIT_T_BROADCAST)
-+    {
-+      circuit->tx = isis_send_pdu_bcast;
-+      circuit->rx = isis_recv_pdu_bcast;
-+    }
-+  else
-+    {
-+      zlog_warn ("isis_sock_init(): unknown circuit type");
-+      retval = ISIS_WARNING;
-+      goto end;
-+    }
-+
-+end:
-+  if (isisd_privs.change (ZPRIVS_LOWER))
-+    zlog_err ("%s: could not lower privs, %s", __func__, safe_strerror (errno));
-+
-+  return retval;
-+}
-+
-+int
-+isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa)
-+{
-+  struct pollfd fds[1];
-+  struct strbuf ctlbuf, databuf;
-+  int flags, retv;
-+  dl_unitdata_ind_t *dui = (dl_unitdata_ind_t *)dlpi_ctl;
-+
-+  memset (fds, 0, sizeof (fds));
-+  fds[0].fd = circuit->fd;
-+  fds[0].events = POLLIN | POLLPRI;
-+  if (poll (fds, 1, 0) <= 0)
-+    return ISIS_WARNING;
-+
-+  memset (&ctlbuf, 0, sizeof (ctlbuf));
-+  memset (&databuf, 0, sizeof (databuf));
-+  ctlbuf.maxlen = sizeof (dlpi_ctl);
-+  ctlbuf.buf = (void *)dlpi_ctl;
-+  databuf.maxlen = sizeof (sock_buff);
-+  databuf.buf = (void *)sock_buff;
-+  flags = 0;
-+  retv = getmsg (circuit->fd, &ctlbuf, &databuf, &flags);
-+
-+  if (retv < 0)
-+    {
-+      zlog_warn ("isis_recv_pdu_bcast: getmsg failed: %s",
-+		 safe_strerror (errno));
-+      return ISIS_WARNING;
-+    }
-+
-+  if (retv & (MORECTL | MOREDATA))
-+    {
-+      while (retv & (MORECTL | MOREDATA))
-+	{
-+	  flags = 0;
-+	  retv = getmsg (circuit->fd, &ctlbuf, &databuf, &flags);
-+	}
-+      return ISIS_WARNING;
-+    }
-+
-+  if (ctlbuf.len < DL_UNITDATA_IND_SIZE ||
-+    dui->dl_primitive != DL_UNITDATA_IND)
-+    return ISIS_WARNING;
-+
-+  if (dui->dl_src_addr_length != ETHERADDRL + 2 ||
-+    dui->dl_src_addr_offset < DL_UNITDATA_IND_SIZE ||
-+    dui->dl_src_addr_offset + dui->dl_src_addr_length > ctlbuf.len)
-+    return ISIS_WARNING;
-+
-+  memcpy (ssnpa, (char *)dui + dui->dl_src_addr_offset +
-+    (circuit->sap_length > 0 ? circuit->sap_length : 0), ETHERADDRL);
-+
-+  if (databuf.len < LLC_LEN || sock_buff[0] != ISO_SAP ||
-+    sock_buff[1] != ISO_SAP || sock_buff[2] != 3)
-+    return ISIS_WARNING;
-+
-+  stream_write (circuit->rcv_stream, sock_buff + LLC_LEN,
-+                databuf.len - LLC_LEN);
-+  stream_set_getp (circuit->rcv_stream, 0);
-+
-+  return ISIS_OK;
-+}
-+
-+int
-+isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
-+{
-+  dl_unitdata_req_t *dur = (dl_unitdata_req_t *)dlpi_ctl;
-+  char *dstaddr;
-+  u_short *dstsap;
-+
-+  stream_set_getp (circuit->snd_stream, 0);
-+
-+  memset (dur, 0, sizeof (*dur));
-+  dur->dl_primitive = DL_UNITDATA_REQ;
-+  dur->dl_dest_addr_length = ETHERADDRL + 2;
-+  dur->dl_dest_addr_offset = sizeof (*dur);
-+
-+  dstaddr = (char *)(dur + 1);
-+  if (circuit->sap_length < 0)
-+    {
-+      dstsap = (u_short *)(dstaddr + ETHERADDRL);
-+    }
-+  else
-+    {
-+      dstsap = (u_short *)dstaddr;
-+      dstaddr += circuit->sap_length;
-+    }
-+  if (level == 1)
-+    memcpy (dstaddr, ALL_L1_ISS, ETHERADDRL);
-+  else
-+    memcpy (dstaddr, ALL_L2_ISS, ETHERADDRL);
-+  /* Note: DLPI SAP values are in host byte order */
-+  *dstsap = stream_get_endp (circuit->snd_stream) + LLC_LEN;
-+
-+  sock_buff[0] = ISO_SAP;
-+  sock_buff[1] = ISO_SAP;
-+  sock_buff[2] = 0x03;
-+  memcpy (sock_buff + LLC_LEN, circuit->snd_stream->data,
-+	  stream_get_endp (circuit->snd_stream));
-+  dlpisend (circuit->fd, dur, sizeof (*dur) + dur->dl_dest_addr_length,
-+    sock_buff, stream_get_endp (circuit->snd_stream) + LLC_LEN, 0);
-+  return ISIS_OK;
-+}
-diff --git a/isisd/isis_flags.c b/isisd/isis_flags.c
-index 1dd5493..859facd 100644
---- isisd/isis_flags.c
-+++ isisd/isis_flags.c
-@@ -29,6 +29,13 @@
- #include "isisd/isis_common.h"
- #include "isisd/isis_flags.h"
- 
-+void
-+flags_initialize (struct flags *flags)
-+{
-+  flags->maxindex = 0;
-+  flags->free_idcs = NULL;
-+}
-+
- int
- flags_get_index (struct flags *flags)
- {
-@@ -37,8 +44,7 @@
- 
-   if (flags->free_idcs == NULL || flags->free_idcs->count == 0)
-     {
--      flags->maxindex++;
--      index = flags->maxindex;
-+      index = flags->maxindex++;
-     }
-   else
-     {
-@@ -45,6 +51,7 @@
-       node = listhead (flags->free_idcs);
-       index = (int) listgetdata (node);
-       listnode_delete (flags->free_idcs, (void *) index);
-+      index--;
-     }
- 
-   return index;
-@@ -53,12 +60,18 @@
- void
- flags_free_index (struct flags *flags, int index)
- {
-+  if (index + 1 == flags->maxindex)
-+    {
-+      flags->maxindex--;
-+      return;
-+    }
-+
-   if (flags->free_idcs == NULL)
-     {
-       flags->free_idcs = list_new ();
-     }
- 
--  listnode_add (flags->free_idcs, (void *) index);
-+  listnode_add (flags->free_idcs, (void *) (index + 1));
- 
-   return;
- }
-diff --git a/isisd/isis_flags.h b/isisd/isis_flags.h
---- isisd/isis_flags.h
-+++ isisd/isis_flags.h
-index 1dd5493..859facd 100644
-@@ -28,6 +28,7 @@
-  * the support will be achived using the newest drafts */
- #define ISIS_MAX_CIRCUITS 32 /* = 1024 */	/*FIXME:defined in lsp.h as well */
- 
-+void flags_initialize (struct flags *flags);
- struct flags *new_flags (int size);
- int flags_get_index (struct flags *flags);
- void flags_free_index (struct flags *flags, int index);
-diff --git a/isisd/isis_network.c b/isisd/isis_network.c
-deleted file mode 100644
-index 56459ec..0000000
---- isisd/isis_network.c
-+++ /dev/null
-@@ -1,643 +0,0 @@
--/*
-- * IS-IS Rout(e)ing protocol - isis_network.c   
-- *
-- * Copyright (C) 2001,2002    Sampo Saaristo
-- *                            Tampere University of Technology      
-- *                            Institute of Communications Engineering
-- *
-- * This program is free software; you can redistribute it and/or modify it 
-- * under the terms of the GNU General Public Licenseas published by the Free 
-- * Software Foundation; either version 2 of the License, or (at your option) 
-- * any later version.
-- *
-- * This program is distributed in the hope that it will be useful,but WITHOUT 
-- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
-- * more details.
--
-- * You should have received a copy of the GNU General Public License along 
-- * with this program; if not, write to the Free Software Foundation, Inc., 
-- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-- */
--
--#include <zebra.h>
--#ifdef GNU_LINUX
--#include <net/ethernet.h>	/* the L2 protocols */
--#else
--#include <net/if.h>
--#include <netinet/if_ether.h>
--#endif
--
--#include "log.h"
--#include "stream.h"
--#include "if.h"
--
--#include "isisd/dict.h"
--#include "isisd/include-netbsd/iso.h"
--#include "isisd/isis_constants.h"
--#include "isisd/isis_common.h"
--#include "isisd/isis_circuit.h"
--#include "isisd/isis_flags.h"
--#include "isisd/isisd.h"
--#include "isisd/isis_constants.h"
--#include "isisd/isis_circuit.h"
--#include "isisd/isis_network.h"
--
--#include "privs.h"
--
--extern struct zebra_privs_t isisd_privs;
--
--/*
-- * On linux we can use the packet(7) sockets, in other OSs we have to do with
-- * Berkley Packet Filter (BPF). Please tell me if you can think of a better 
-- * way...
-- */
--#ifdef GNU_LINUX
--#include <netpacket/packet.h>
--#else
--#include <sys/time.h>
--#include <sys/ioctl.h>
--#include <net/bpf.h>
--struct bpf_insn llcfilter[] = {
--  BPF_STMT (BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN),	/* check first byte */
--  BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ISO_SAP, 0, 5),
--  BPF_STMT (BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN + 1),
--  BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ISO_SAP, 0, 3),	/* check second byte */
--  BPF_STMT (BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN + 2),
--  BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 0x03, 0, 1),	/* check third byte */
--  BPF_STMT (BPF_RET + BPF_K, (u_int) - 1),
--  BPF_STMT (BPF_RET + BPF_K, 0)
--};
--int readblen = 0;
--u_char *readbuff = NULL;
--#endif /* GNU_LINUX */
--
--/*
-- * Table 9 - Architectural constans for use with ISO 8802 subnetworks
-- * ISO 10589 - 8.4.8
-- */
--
--u_char ALL_L1_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x14 };
--u_char ALL_L2_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x15 };
--u_char ALL_ISS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x05 };
--u_char ALL_ESS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x04 };
--
--#ifdef GNU_LINUX
--static char discard_buff[8192];
--#endif
--static char sock_buff[8192];
--
--/*
-- * if level is 0 we are joining p2p multicast
-- * FIXME: and the p2p multicast being ???
-- */
--#ifdef GNU_LINUX
--static int
--isis_multicast_join (int fd, int registerto, int if_num)
--{
--  struct packet_mreq mreq;
--
--  memset (&mreq, 0, sizeof (mreq));
--  mreq.mr_ifindex = if_num;
--  if (registerto)
--    {
--      mreq.mr_type = PACKET_MR_MULTICAST;
--      mreq.mr_alen = ETH_ALEN;
--      if (registerto == 1)
--	memcpy (&mreq.mr_address, ALL_L1_ISS, ETH_ALEN);
--      else if (registerto == 2)
--	memcpy (&mreq.mr_address, ALL_L2_ISS, ETH_ALEN);
--      else if (registerto == 3)
--	memcpy (&mreq.mr_address, ALL_ISS, ETH_ALEN);
--      else
--	memcpy (&mreq.mr_address, ALL_ESS, ETH_ALEN);
--
--    }
--  else
--    {
--      mreq.mr_type = PACKET_MR_ALLMULTI;
--    }
--#ifdef EXTREME_DEBUG
--  zlog_debug ("isis_multicast_join(): fd=%d, reg_to=%d, if_num=%d, "
--	      "address = %02x:%02x:%02x:%02x:%02x:%02x",
--	      fd, registerto, if_num, mreq.mr_address[0], mreq.mr_address[1],
--	      mreq.mr_address[2], mreq.mr_address[3], mreq.mr_address[4],
--	      mreq.mr_address[5]);
--#endif /* EXTREME_DEBUG */
--  if (setsockopt (fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq,
--		  sizeof (struct packet_mreq)))
--    {
--      zlog_warn ("isis_multicast_join(): setsockopt(): %s", safe_strerror (errno));
--      return ISIS_WARNING;
--    }
--
--  return ISIS_OK;
--}
--
--static int
--open_packet_socket (struct isis_circuit *circuit)
--{
--  struct sockaddr_ll s_addr;
--  int fd, retval = ISIS_OK;
--
--  fd = socket (PF_PACKET, SOCK_DGRAM, htons (ETH_P_ALL));
--  if (fd < 0)
--    {
--      zlog_warn ("open_packet_socket(): socket() failed %s",
--		 safe_strerror (errno));
--      return ISIS_WARNING;
--    }
--
--  /*
--   * Bind to the physical interface
--   */
--  memset (&s_addr, 0, sizeof (struct sockaddr_ll));
--  s_addr.sll_family = AF_PACKET;
--  s_addr.sll_protocol = htons (ETH_P_ALL);
--  s_addr.sll_ifindex = circuit->interface->ifindex;
--
--  if (bind (fd, (struct sockaddr *) (&s_addr),
--	    sizeof (struct sockaddr_ll)) < 0)
--    {
--      zlog_warn ("open_packet_socket(): bind() failed: %s", safe_strerror (errno));
--      return ISIS_WARNING;
--    }
--
--  circuit->fd = fd;
--
--  if (circuit->circ_type == CIRCUIT_T_BROADCAST)
--    {
--      /*
--       * Join to multicast groups
--       * according to
--       * 8.4.2 - Broadcast subnetwork IIH PDUs
--       * FIXME: is there a case only one will fail??
--       */
--      if (circuit->circuit_is_type & IS_LEVEL_1)
--	{
--	  /* joining ALL_L1_ISS */
--	  retval = isis_multicast_join (circuit->fd, 1,
--					circuit->interface->ifindex);
--	  /* joining ALL_ISS */
--	  retval = isis_multicast_join (circuit->fd, 3,
--					circuit->interface->ifindex);
--	}
--      if (circuit->circuit_is_type & IS_LEVEL_2)
--	/* joining ALL_L2_ISS */
--	retval = isis_multicast_join (circuit->fd, 2,
--				      circuit->interface->ifindex);
--    }
--  else
--    {
--      retval =
--	isis_multicast_join (circuit->fd, 0, circuit->interface->ifindex);
--    }
--
--  return retval;
--}
--
--#else
--
--static int
--open_bpf_dev (struct isis_circuit *circuit)
--{
--  int i = 0, fd;
--  char bpfdev[128];
--  struct ifreq ifr;
--  u_int16_t blen;
--  int true = 1, false = 0;
--  struct timeval timeout;
--  struct bpf_program bpf_prog;
--
--  do
--    {
--      (void) snprintf (bpfdev, sizeof (bpfdev), "/dev/bpf%d", i++);
--      fd = open (bpfdev, O_RDWR);
--    }
--  while (fd < 0 && errno == EBUSY);
--
--  if (fd < 0)
--    {
--      zlog_warn ("open_bpf_dev(): failed to create bpf socket: %s",
--		 safe_strerror (errno));
--      return ISIS_WARNING;
--    }
--
--  zlog_debug ("Opened BPF device %s", bpfdev);
--
--  memcpy (ifr.ifr_name, circuit->interface->name, sizeof (ifr.ifr_name));
--  if (ioctl (fd, BIOCSETIF, (caddr_t) & ifr) < 0)
--    {
--      zlog_warn ("open_bpf_dev(): failed to bind to interface: %s",
--		 safe_strerror (errno));
--      return ISIS_WARNING;
--    }
--
--  if (ioctl (fd, BIOCGBLEN, (caddr_t) & blen) < 0)
--    {
--      zlog_warn ("failed to get BPF buffer len");
--      blen = circuit->interface->mtu;
--    }
--
--  readblen = blen;
--
--  if (readbuff == NULL)
--    readbuff = malloc (blen);
--
--  zlog_debug ("BPF buffer len = %u", blen);
--
--  /*  BPF(4): reads return immediately upon packet reception.
--   *  Otherwise, a read will block until either the kernel
--   *  buffer becomes full or a timeout occurs. 
--   */
--  if (ioctl (fd, BIOCIMMEDIATE, (caddr_t) & true) < 0)
--    {
--      zlog_warn ("failed to set BPF dev to immediate mode");
--    }
--
--#ifdef BIOCSSEESENT
--  /*
--   * We want to see only incoming packets
--   */
--  if (ioctl (fd, BIOCSSEESENT, (caddr_t) & false) < 0)
--    {
--      zlog_warn ("failed to set BPF dev to incoming only mode");
--    }
--#endif
--
--  /*
--   * ...but all of them
--   */
--  if (ioctl (fd, BIOCPROMISC, (caddr_t) & true) < 0)
--    {
--      zlog_warn ("failed to set BPF dev to promiscuous mode");
--    }
--
--  /*
--   * If the buffer length is smaller than our mtu, lets try to increase it
--   */
--  if (blen < circuit->interface->mtu)
--    {
--      if (ioctl (fd, BIOCSBLEN, &circuit->interface->mtu) < 0)
--	{
--	  zlog_warn ("failed to set BPF buffer len (%u to %u)", blen,
--		     circuit->interface->mtu);
--	}
--    }
--
--  /*
--   * Set a timeout parameter - hope this helps select()
--   */
--  timeout.tv_sec = 600;
--  timeout.tv_usec = 0;
--  if (ioctl (fd, BIOCSRTIMEOUT, (caddr_t) & timeout) < 0)
--    {
--      zlog_warn ("failed to set BPF device timeout");
--    }
--
--  /*
--   * And set the filter
--   */
--  memset (&bpf_prog, 0, sizeof (struct bpf_program));
--  bpf_prog.bf_len = 8;
--  bpf_prog.bf_insns = &(llcfilter[0]);
--  if (ioctl (fd, BIOCSETF, (caddr_t) & bpf_prog) < 0)
--    {
--      zlog_warn ("open_bpf_dev(): failed to install filter: %s",
--		 safe_strerror (errno));
--      return ISIS_WARNING;
--    }
--
--  assert (fd > 0);
--
--  circuit->fd = fd;
--
--  return ISIS_OK;
--}
--
--#endif /* GNU_LINUX */
--
--/*
-- * Create the socket and set the tx/rx funcs
-- */
--int
--isis_sock_init (struct isis_circuit *circuit)
--{
--  int retval = ISIS_OK;
--
--  if (isisd_privs.change (ZPRIVS_RAISE))
--    zlog_err ("%s: could not raise privs, %s", __func__, safe_strerror (errno));
--
--#ifdef GNU_LINUX
--  retval = open_packet_socket (circuit);
--#else
--  retval = open_bpf_dev (circuit);
--#endif
--
--  if (retval != ISIS_OK)
--    {
--      zlog_warn ("%s: could not initialize the socket", __func__);
--      goto end;
--    }
--
--  if (circuit->circ_type == CIRCUIT_T_BROADCAST)
--    {
--      circuit->tx = isis_send_pdu_bcast;
--      circuit->rx = isis_recv_pdu_bcast;
--    }
--  else if (circuit->circ_type == CIRCUIT_T_P2P)
--    {
--      circuit->tx = isis_send_pdu_p2p;
--      circuit->rx = isis_recv_pdu_p2p;
--    }
--  else
--    {
--      zlog_warn ("isis_sock_init(): unknown circuit type");
--      retval = ISIS_WARNING;
--      goto end;
--    }
--
--end:
--  if (isisd_privs.change (ZPRIVS_LOWER))
--    zlog_err ("%s: could not lower privs, %s", __func__, safe_strerror (errno));
--
--  return retval;
--}
--
--static inline int
--llc_check (u_char * llc)
--{
--  if (*llc != ISO_SAP || *(llc + 1) != ISO_SAP || *(llc + 2) != 3)
--    return 0;
--
--  return 1;
--}
--
--#ifdef GNU_LINUX
--int
--isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa)
--{
--  int bytesread, addr_len;
--  struct sockaddr_ll s_addr;
--  u_char llc[LLC_LEN];
--
--  addr_len = sizeof (s_addr);
--
--  memset (&s_addr, 0, sizeof (struct sockaddr_ll));
--
--  bytesread = recvfrom (circuit->fd, (void *) &llc,
--			LLC_LEN, MSG_PEEK,
--			(struct sockaddr *) &s_addr, (socklen_t *) &addr_len);
--
--  if (bytesread < 0)
--    {
--      zlog_warn ("isis_recv_packet_bcast(): fd %d, recvfrom (): %s",
--		 circuit->fd, safe_strerror (errno));
--      zlog_warn ("circuit is %s", circuit->interface->name);
--      zlog_warn ("circuit fd %d", circuit->fd);
--      zlog_warn ("bytesread %d", bytesread);
--      /* get rid of the packet */
--      bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));
--      return ISIS_WARNING;
--    }
--  /*
--   * Filtering by llc field, discard packets sent by this host (other circuit)
--   */
--  if (!llc_check (llc) || s_addr.sll_pkttype == PACKET_OUTGOING)
--    {
--      /*  Read the packet into discard buff */
--      bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));
--      if (bytesread < 0)
--	zlog_warn ("isis_recv_pdu_bcast(): read() failed");
--      return ISIS_WARNING;
--    }
--
--  /* on lan we have to read to the static buff first */
--  bytesread = recvfrom (circuit->fd, sock_buff, circuit->interface->mtu, 0,
--			(struct sockaddr *) &s_addr, (socklen_t *) &addr_len);
--
--  /* then we lose the LLC */
--  stream_write (circuit->rcv_stream, sock_buff + LLC_LEN, bytesread - LLC_LEN);
--
--  memcpy (ssnpa, &s_addr.sll_addr, s_addr.sll_halen);
--
--  return ISIS_OK;
--}
--
--int
--isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char * ssnpa)
--{
--  int bytesread, addr_len;
--  struct sockaddr_ll s_addr;
--
--  memset (&s_addr, 0, sizeof (struct sockaddr_ll));
--  addr_len = sizeof (s_addr);
--
--  /* we can read directly to the stream */
--  bytesread = stream_recvfrom (circuit->rcv_stream, circuit->fd,
--                               circuit->interface->mtu, 0,
--                               (struct sockaddr *) &s_addr, 
--                               (socklen_t *) &addr_len);
--
--  if (s_addr.sll_pkttype == PACKET_OUTGOING)
--    {
--      /*  Read the packet into discard buff */
--      bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));
--      if (bytesread < 0)
--	zlog_warn ("isis_recv_pdu_p2p(): read() failed");
--      return ISIS_WARNING;
--    }
--
--  /* If we don't have protocol type 0x00FE which is
--   * ISO over GRE we exit with pain :)
--   */
--  if (ntohs (s_addr.sll_protocol) != 0x00FE)
--    {
--      zlog_warn ("isis_recv_pdu_p2p(): protocol mismatch(): %X",
--		 ntohs (s_addr.sll_protocol));
--      return ISIS_WARNING;
--    }
--
--  memcpy (ssnpa, &s_addr.sll_addr, s_addr.sll_halen);
--
--  return ISIS_OK;
--}
--
--int
--isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
--{
--  /* we need to do the LLC in here because of P2P circuits, which will
--   * not need it
--   */
--  int written = 1;
--  struct sockaddr_ll sa;
--
--  stream_set_getp (circuit->snd_stream, 0);
--  memset (&sa, 0, sizeof (struct sockaddr_ll));
--  sa.sll_family = AF_PACKET;
--  sa.sll_protocol = htons (stream_get_endp (circuit->snd_stream) + LLC_LEN);
--  sa.sll_ifindex = circuit->interface->ifindex;
--  sa.sll_halen = ETH_ALEN;
--  if (level == 1)
--    memcpy (&sa.sll_addr, ALL_L1_ISS, ETH_ALEN);
--  else
--    memcpy (&sa.sll_addr, ALL_L2_ISS, ETH_ALEN);
--
--  /* on a broadcast circuit */
--  /* first we put the LLC in */
--  sock_buff[0] = 0xFE;
--  sock_buff[1] = 0xFE;
--  sock_buff[2] = 0x03;
--
--  /* then we copy the data */
--  memcpy (sock_buff + LLC_LEN, circuit->snd_stream->data,
--	  stream_get_endp (circuit->snd_stream));
--
--  /* now we can send this */
--  written = sendto (circuit->fd, sock_buff,
--		    stream_get_endp(circuit->snd_stream) + LLC_LEN, 0,
--		    (struct sockaddr *) &sa, sizeof (struct sockaddr_ll));
--
--  return ISIS_OK;
--}
--
--int
--isis_send_pdu_p2p (struct isis_circuit *circuit, int level)
--{
--
--  int written = 1;
--  struct sockaddr_ll sa;
--
--  stream_set_getp (circuit->snd_stream, 0);
--  memset (&sa, 0, sizeof (struct sockaddr_ll));
--  sa.sll_family = AF_PACKET;
--  sa.sll_protocol = htons (stream_get_endp (circuit->snd_stream) + LLC_LEN);
--  sa.sll_ifindex = circuit->interface->ifindex;
--  sa.sll_halen = ETH_ALEN;
--  if (level == 1)
--    memcpy (&sa.sll_addr, ALL_L1_ISS, ETH_ALEN);
--  else
--    memcpy (&sa.sll_addr, ALL_L2_ISS, ETH_ALEN);
--
--
--  /* lets try correcting the protocol */
--  sa.sll_protocol = htons (0x00FE);
--  written = sendto (circuit->fd, circuit->snd_stream->data,
--		    stream_get_endp (circuit->snd_stream), 0, 
--		    (struct sockaddr *) &sa,
--		    sizeof (struct sockaddr_ll));
--
--  return ISIS_OK;
--}
--
--#else
--
--int
--isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa)
--{
--  int bytesread = 0, bytestoread, offset, one = 1;
--  struct bpf_hdr *bpf_hdr;
--
--  assert (circuit->fd > 0);
--
--  if (ioctl (circuit->fd, FIONREAD, (caddr_t) & bytestoread) < 0)
--    {
--      zlog_warn ("ioctl() FIONREAD failed: %s", safe_strerror (errno));
--    }
--
--  if (bytestoread)
--    {
--      bytesread = read (circuit->fd, readbuff, readblen);
--    }
--  if (bytesread < 0)
--    {
--      zlog_warn ("isis_recv_pdu_bcast(): read() failed: %s",
--		 safe_strerror (errno));
--      return ISIS_WARNING;
--    }
--
--  if (bytesread == 0)
--    return ISIS_WARNING;
--
--  bpf_hdr = (struct bpf_hdr *) readbuff;
--
--  assert (bpf_hdr->bh_caplen == bpf_hdr->bh_datalen);
--
--  offset = bpf_hdr->bh_hdrlen + LLC_LEN + ETHER_HDR_LEN;
--
--  /* then we lose the BPF, LLC and ethernet headers */
--  stream_write (circuit->rcv_stream, readbuff + offset, 
--                bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN);
--  stream_set_getp (circuit->rcv_stream, 0);
--
--  memcpy (ssnpa, readbuff + bpf_hdr->bh_hdrlen + ETHER_ADDR_LEN,
--	  ETHER_ADDR_LEN);
--
--  if (ioctl (circuit->fd, BIOCFLUSH, &one) < 0)
--    zlog_warn ("Flushing failed: %s", safe_strerror (errno));
--
--  return ISIS_OK;
--}
--
--int
--isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char * ssnpa)
--{
--  int bytesread;
--
--  bytesread = stream_read (circuit->rcv_stream, circuit->fd, 
--                           circuit->interface->mtu);
--
--  if (bytesread < 0)
--    {
--      zlog_warn ("isis_recv_pdu_p2p(): read () failed: %s", safe_strerror (errno));
--      return ISIS_WARNING;
--    }
--
--  return ISIS_OK;
--}
--
--int
--isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
--{
--  struct ether_header *eth;
--  int written;
--
--  stream_set_getp (circuit->snd_stream, 0);
--
--  /*
--   * First the eth header
--   */
--  eth = (struct ether_header *) sock_buff;
--  if (level == 1)
--    memcpy (eth->ether_dhost, ALL_L1_ISS, ETHER_ADDR_LEN);
--  else
--    memcpy (eth->ether_dhost, ALL_L2_ISS, ETHER_ADDR_LEN);
--  memcpy (eth->ether_shost, circuit->u.bc.snpa, ETHER_ADDR_LEN);
--  eth->ether_type = htons (stream_get_endp (circuit->snd_stream) + LLC_LEN);
--
--  /*
--   * Then the LLC
--   */
--  sock_buff[ETHER_HDR_LEN] = ISO_SAP;
--  sock_buff[ETHER_HDR_LEN + 1] = ISO_SAP;
--  sock_buff[ETHER_HDR_LEN + 2] = 0x03;
--
--  /* then we copy the data */
--  memcpy (sock_buff + (LLC_LEN + ETHER_HDR_LEN), circuit->snd_stream->data,
--	  stream_get_endp (circuit->snd_stream));
--
--  /* now we can send this */
--  written = write (circuit->fd, sock_buff,
--		   stream_get_endp (circuit->snd_stream) 
--		    + LLC_LEN + ETHER_HDR_LEN);
--
--  return ISIS_OK;
--}
--
--int
--isis_send_pdu_p2p (struct isis_circuit *circuit, int level)
--{
--  return ISIS_OK;
--}
--
--#endif /* GNU_LINUX */
-diff --git a/isisd/isis_pdu.h b/isisd/isis_pdu.h
-index 29c7621..95c1ee4 100644
---- isisd/isis_pdu.h
-+++ isisd/isis_pdu.h
-@@ -24,6 +24,10 @@
- #ifndef _ZEBRA_ISIS_PDU_H
- #define _ZEBRA_ISIS_PDU_H
- 
-+#ifdef __SUNPRO_C
-+#pragma pack(1)
-+#endif
-+
- /*
-  *                    ISO 9542 - 7.5,7.6
-  *
-@@ -222,6 +226,10 @@ struct isis_partial_seqnum_hdr
- };
- #define ISIS_PSNP_HDRLEN 9
- 
-+#ifdef __SUNPRO_C
-+#pragma pack()
-+#endif
-+
- /*
-  * Function for receiving IS-IS PDUs
-  */
-diff --git a/isisd/isis_pfpacket.c b/isisd/isis_pfpacket.c
-new file mode 100644
-index 0000000..8752dba
---- /dev/null
-+++ isisd/isis_pfpacket.c
-@@ -0,0 +1,373 @@
-+/*
-+ * IS-IS Rout(e)ing protocol - isis_pfpacket.c
-+ *
-+ * Copyright (C) 2001,2002    Sampo Saaristo
-+ *                            Tampere University of Technology      
-+ *                            Institute of Communications Engineering
-+ *
-+ * This program is free software; you can redistribute it and/or modify it 
-+ * under the terms of the GNU General Public Licenseas published by the Free 
-+ * Software Foundation; either version 2 of the License, or (at your option) 
-+ * any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,but WITHOUT 
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
-+ * more details.
-+
-+ * You should have received a copy of the GNU General Public License along 
-+ * with this program; if not, write to the Free Software Foundation, Inc., 
-+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-+ */
-+
-+#include <zebra.h>
-+#include <net/ethernet.h>	/* the L2 protocols */
-+#include <netpacket/packet.h>
-+
-+#include "log.h"
-+#include "stream.h"
-+#include "if.h"
-+
-+#include "isisd/dict.h"
-+#include "isisd/include-netbsd/iso.h"
-+#include "isisd/isis_constants.h"
-+#include "isisd/isis_common.h"
-+#include "isisd/isis_circuit.h"
-+#include "isisd/isis_flags.h"
-+#include "isisd/isisd.h"
-+#include "isisd/isis_constants.h"
-+#include "isisd/isis_circuit.h"
-+#include "isisd/isis_network.h"
-+
-+#include "privs.h"
-+
-+extern struct zebra_privs_t isisd_privs;
-+
-+/*
-+ * Table 9 - Architectural constants for use with ISO 8802 subnetworks
-+ * ISO 10589 - 8.4.8
-+ */
-+
-+u_char ALL_L1_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x14 };
-+u_char ALL_L2_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x15 };
-+u_char ALL_ISS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x05 };
-+u_char ALL_ESS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x04 };
-+
-+static char discard_buff[8192];
-+static char sock_buff[8192];
-+
-+/*
-+ * if level is 0 we are joining p2p multicast
-+ * FIXME: and the p2p multicast being ???
-+ */
-+static int
-+isis_multicast_join (int fd, int registerto, int if_num)
-+{
-+  struct packet_mreq mreq;
-+
-+  memset (&mreq, 0, sizeof (mreq));
-+  mreq.mr_ifindex = if_num;
-+  if (registerto)
-+    {
-+      mreq.mr_type = PACKET_MR_MULTICAST;
-+      mreq.mr_alen = ETH_ALEN;
-+      if (registerto == 1)
-+	memcpy (&mreq.mr_address, ALL_L1_ISS, ETH_ALEN);
-+      else if (registerto == 2)
-+	memcpy (&mreq.mr_address, ALL_L2_ISS, ETH_ALEN);
-+      else if (registerto == 3)
-+	memcpy (&mreq.mr_address, ALL_ISS, ETH_ALEN);
-+      else
-+	memcpy (&mreq.mr_address, ALL_ESS, ETH_ALEN);
-+
-+    }
-+  else
-+    {
-+      mreq.mr_type = PACKET_MR_ALLMULTI;
-+    }
-+#ifdef EXTREME_DEBUG
-+  zlog_debug ("isis_multicast_join(): fd=%d, reg_to=%d, if_num=%d, "
-+	      "address = %02x:%02x:%02x:%02x:%02x:%02x",
-+	      fd, registerto, if_num, mreq.mr_address[0], mreq.mr_address[1],
-+	      mreq.mr_address[2], mreq.mr_address[3], mreq.mr_address[4],
-+	      mreq.mr_address[5]);
-+#endif /* EXTREME_DEBUG */
-+  if (setsockopt (fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq,
-+		  sizeof (struct packet_mreq)))
-+    {
-+      zlog_warn ("isis_multicast_join(): setsockopt(): %s", safe_strerror (errno));
-+      return ISIS_WARNING;
-+    }
-+
-+  return ISIS_OK;
-+}
-+
-+static int
-+open_packet_socket (struct isis_circuit *circuit)
-+{
-+  struct sockaddr_ll s_addr;
-+  int fd, retval = ISIS_OK;
-+
-+  fd = socket (PF_PACKET, SOCK_DGRAM, htons (ETH_P_ALL));
-+  if (fd < 0)
-+    {
-+      zlog_warn ("open_packet_socket(): socket() failed %s",
-+		 safe_strerror (errno));
-+      return ISIS_WARNING;
-+    }
-+
-+  /*
-+   * Bind to the physical interface
-+   */
-+  memset (&s_addr, 0, sizeof (struct sockaddr_ll));
-+  s_addr.sll_family = AF_PACKET;
-+  s_addr.sll_protocol = htons (ETH_P_ALL);
-+  s_addr.sll_ifindex = circuit->interface->ifindex;
-+
-+  if (bind (fd, (struct sockaddr *) (&s_addr),
-+	    sizeof (struct sockaddr_ll)) < 0)
-+    {
-+      zlog_warn ("open_packet_socket(): bind() failed: %s", safe_strerror (errno));
-+      return ISIS_WARNING;
-+    }
-+
-+  circuit->fd = fd;
-+
-+  if (circuit->circ_type == CIRCUIT_T_BROADCAST)
-+    {
-+      /*
-+       * Join to multicast groups
-+       * according to
-+       * 8.4.2 - Broadcast subnetwork IIH PDUs
-+       * FIXME: is there a case only one will fail??
-+       */
-+      if (circuit->circuit_is_type & IS_LEVEL_1)
-+	{
-+	  /* joining ALL_L1_ISS */
-+	  retval = isis_multicast_join (circuit->fd, 1,
-+					circuit->interface->ifindex);
-+	  /* joining ALL_ISS */
-+	  retval = isis_multicast_join (circuit->fd, 3,
-+					circuit->interface->ifindex);
-+	}
-+      if (circuit->circuit_is_type & IS_LEVEL_2)
-+	/* joining ALL_L2_ISS */
-+	retval = isis_multicast_join (circuit->fd, 2,
-+				      circuit->interface->ifindex);
-+    }
-+  else
-+    {
-+      retval =
-+	isis_multicast_join (circuit->fd, 0, circuit->interface->ifindex);
-+    }
-+
-+  return retval;
-+}
-+
-+/*
-+ * Create the socket and set the tx/rx funcs
-+ */
-+int
-+isis_sock_init (struct isis_circuit *circuit)
-+{
-+  int retval = ISIS_OK;
-+
-+  if (isisd_privs.change (ZPRIVS_RAISE))
-+    zlog_err ("%s: could not raise privs, %s", __func__, safe_strerror (errno));
-+
-+  retval = open_packet_socket (circuit);
-+
-+  if (retval != ISIS_OK)
-+    {
-+      zlog_warn ("%s: could not initialize the socket", __func__);
-+      goto end;
-+    }
-+
-+  if (circuit->circ_type == CIRCUIT_T_BROADCAST)
-+    {
-+      circuit->tx = isis_send_pdu_bcast;
-+      circuit->rx = isis_recv_pdu_bcast;
-+    }
-+  else if (circuit->circ_type == CIRCUIT_T_P2P)
-+    {
-+      circuit->tx = isis_send_pdu_p2p;
-+      circuit->rx = isis_recv_pdu_p2p;
-+    }
-+  else
-+    {
-+      zlog_warn ("isis_sock_init(): unknown circuit type");
-+      retval = ISIS_WARNING;
-+      goto end;
-+    }
-+
-+end:
-+  if (isisd_privs.change (ZPRIVS_LOWER))
-+    zlog_err ("%s: could not lower privs, %s", __func__, safe_strerror (errno));
-+
-+  return retval;
-+}
-+
-+static inline int
-+llc_check (u_char * llc)
-+{
-+  if (*llc != ISO_SAP || *(llc + 1) != ISO_SAP || *(llc + 2) != 3)
-+    return 0;
-+
-+  return 1;
-+}
-+
-+int
-+isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa)
-+{
-+  int bytesread, addr_len;
-+  struct sockaddr_ll s_addr;
-+  u_char llc[LLC_LEN];
-+
-+  addr_len = sizeof (s_addr);
-+
-+  memset (&s_addr, 0, sizeof (struct sockaddr_ll));
-+
-+  bytesread = recvfrom (circuit->fd, (void *) &llc,
-+			LLC_LEN, MSG_PEEK,
-+			(struct sockaddr *) &s_addr, (socklen_t *) &addr_len);
-+
-+  if (bytesread < 0)
-+    {
-+      zlog_warn ("isis_recv_packet_bcast(): fd %d, recvfrom (): %s",
-+		 circuit->fd, safe_strerror (errno));
-+      zlog_warn ("circuit is %s", circuit->interface->name);
-+      zlog_warn ("circuit fd %d", circuit->fd);
-+      zlog_warn ("bytesread %d", bytesread);
-+      /* get rid of the packet */
-+      bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));
-+      return ISIS_WARNING;
-+    }
-+  /*
-+   * Filtering by llc field, discard packets sent by this host (other circuit)
-+   */
-+  if (!llc_check (llc) || s_addr.sll_pkttype == PACKET_OUTGOING)
-+    {
-+      /*  Read the packet into discard buff */
-+      bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));
-+      if (bytesread < 0)
-+	zlog_warn ("isis_recv_pdu_bcast(): read() failed");
-+      return ISIS_WARNING;
-+    }
-+
-+  /* on lan we have to read to the static buff first */
-+  bytesread = recvfrom (circuit->fd, sock_buff, circuit->interface->mtu, 0,
-+			(struct sockaddr *) &s_addr, (socklen_t *) &addr_len);
-+
-+  /* then we lose the LLC */
-+  stream_write (circuit->rcv_stream, sock_buff + LLC_LEN, bytesread - LLC_LEN);
-+
-+  memcpy (ssnpa, &s_addr.sll_addr, s_addr.sll_halen);
-+
-+  return ISIS_OK;
-+}
-+
-+int
-+isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char * ssnpa)
-+{
-+  int bytesread, addr_len;
-+  struct sockaddr_ll s_addr;
-+
-+  memset (&s_addr, 0, sizeof (struct sockaddr_ll));
-+  addr_len = sizeof (s_addr);
-+
-+  /* we can read directly to the stream */
-+  bytesread = stream_recvfrom (circuit->rcv_stream, circuit->fd,
-+                               circuit->interface->mtu, 0,
-+                               (struct sockaddr *) &s_addr, 
-+                               (socklen_t *) &addr_len);
-+
-+  if (s_addr.sll_pkttype == PACKET_OUTGOING)
-+    {
-+      /*  Read the packet into discard buff */
-+      bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));
-+      if (bytesread < 0)
-+	zlog_warn ("isis_recv_pdu_p2p(): read() failed");
-+      return ISIS_WARNING;
-+    }
-+
-+  /* If we don't have protocol type 0x00FE which is
-+   * ISO over GRE we exit with pain :)
-+   */
-+  if (ntohs (s_addr.sll_protocol) != 0x00FE)
-+    {
-+      zlog_warn ("isis_recv_pdu_p2p(): protocol mismatch(): %X",
-+		 ntohs (s_addr.sll_protocol));
-+      return ISIS_WARNING;
-+    }
-+
-+  memcpy (ssnpa, &s_addr.sll_addr, s_addr.sll_halen);
-+
-+  return ISIS_OK;
-+}
-+
-+int
-+isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
-+{
-+  /* we need to do the LLC in here because of P2P circuits, which will
-+   * not need it
-+   */
-+  int written = 1;
-+  struct sockaddr_ll sa;
-+
-+  stream_set_getp (circuit->snd_stream, 0);
-+  memset (&sa, 0, sizeof (struct sockaddr_ll));
-+  sa.sll_family = AF_PACKET;
-+  sa.sll_protocol = htons (stream_get_endp (circuit->snd_stream) + LLC_LEN);
-+  sa.sll_ifindex = circuit->interface->ifindex;
-+  sa.sll_halen = ETH_ALEN;
-+  if (level == 1)
-+    memcpy (&sa.sll_addr, ALL_L1_ISS, ETH_ALEN);
-+  else
-+    memcpy (&sa.sll_addr, ALL_L2_ISS, ETH_ALEN);
-+
-+  /* on a broadcast circuit */
-+  /* first we put the LLC in */
-+  sock_buff[0] = 0xFE;
-+  sock_buff[1] = 0xFE;
-+  sock_buff[2] = 0x03;
-+
-+  /* then we copy the data */
-+  memcpy (sock_buff + LLC_LEN, circuit->snd_stream->data,
-+	  stream_get_endp (circuit->snd_stream));
-+
-+  /* now we can send this */
-+  written = sendto (circuit->fd, sock_buff,
-+		    stream_get_endp(circuit->snd_stream) + LLC_LEN, 0,
-+		    (struct sockaddr *) &sa, sizeof (struct sockaddr_ll));
-+
-+  return ISIS_OK;
-+}
-+
-+int
-+isis_send_pdu_p2p (struct isis_circuit *circuit, int level)
-+{
-+
-+  int written = 1;
-+  struct sockaddr_ll sa;
-+
-+  stream_set_getp (circuit->snd_stream, 0);
-+  memset (&sa, 0, sizeof (struct sockaddr_ll));
-+  sa.sll_family = AF_PACKET;
-+  sa.sll_protocol = htons (stream_get_endp (circuit->snd_stream) + LLC_LEN);
-+  sa.sll_ifindex = circuit->interface->ifindex;
-+  sa.sll_halen = ETH_ALEN;
-+  if (level == 1)
-+    memcpy (&sa.sll_addr, ALL_L1_ISS, ETH_ALEN);
-+  else
-+    memcpy (&sa.sll_addr, ALL_L2_ISS, ETH_ALEN);
-+
-+
-+  /* lets try correcting the protocol */
-+  sa.sll_protocol = htons (0x00FE);
-+  written = sendto (circuit->fd, circuit->snd_stream->data,
-+		    stream_get_endp (circuit->snd_stream), 0, 
-+		    (struct sockaddr *) &sa,
-+		    sizeof (struct sockaddr_ll));
-+
-+  return ISIS_OK;
-+}
-diff --git a/isisd/isis_tlv.h b/isisd/isis_tlv.h
-index 951a254..fc9f35f 100644
---- isisd/isis_tlv.h
-+++ isisd/isis_tlv.h
-@@ -152,6 +152,10 @@ struct lan_neigh
-   u_char LAN_addr[6];
- };
- 
-+#ifdef __SUNPRO_C
-+#pragma pack(1)
-+#endif
-+
- /* struct for LSP entry */
- struct lsp_entry
- {
-@@ -161,6 +165,10 @@ struct lsp_entry
-   u_int16_t checksum;
- } __attribute__ ((packed));
- 
-+#ifdef __SUNPRO_C
-+#pragma pack()
-+#endif
-+
- /* struct for checksum */
- struct checksum
- {
--- a/components/quagga/patches/30-ospfd-nssa-asbr.patch	Tue Dec 20 22:26:25 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-diff --git a/ospfd/ChangeLog b/ospfd/ChangeLog
-index 24c3d29..bb0e908 100644
---- ospfd/ChangeLog
-+++ ospfd/ChangeLog
-@@ -1,3 +1,8 @@
-+2007-08-06 Paul Jakma <[email protected]>
-+
-+	* ospf_lsa.c: (router_lsa_flags) Bug #331, NSSA regression caused
-+	  caused ASBRs to not advertise E-bit into NSSA areas.
-+
- 2007-05-09 Milan Kocian <[email protected]>
- 
- 	* ospf_vty.c: Fix commands: 'ip ospf authentication A.B.C.D',
-diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
-index b9a70a6..243928f 100644
---- ospfd/ospf_lsa.c
-+++ ospfd/ospf_lsa.c
-@@ -437,8 +437,7 @@ router_lsa_flags (struct ospf_area *area)
- 	SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
- 
-   /* ASBR can't exit in stub area. */
--  if (area->external_routing == OSPF_AREA_STUB
--      || area->external_routing == OSPF_AREA_NSSA)
-+  if (area->external_routing == OSPF_AREA_STUB)
-     UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
-   /* If ASBR set External flag */
-   else if (IS_OSPF_ASBR (area->ospf))
--- a/components/quagga/patches/35-ospfd-spf-sort.patch	Tue Dec 20 22:26:25 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-commit 7591d8b862439dfae8b4b16d148ce567b6ff8cb7
-Author: Paul Jakma <[email protected]>
-Date:   Mon Aug 6 18:52:45 2007 +0000
-
-    [ospfd] Fix bad SPF calculation on some topologies - incorrect sorting
-    
-    2007-08-07 Atis Elsts <[email protected]>
-    
-    	* ospf_spf.c: (ospf_spf_next) Sort heap in correct direction
-    	  after vertex cost is changed, thus fixing incorrect SPF
-    	  calculation on certain topologies.
-    	* lib/pqueue.{c,h}: Export trickle_up
-
-diff --git a/lib/pqueue.c b/lib/pqueue.c
-index a974a49..12a779f 100644
---- lib/pqueue.c
-+++ lib/pqueue.c
-@@ -42,7 +42,7 @@ Boston, MA 02111-1307, USA.  */
- #define RIGHT_OF(x) (2 * x + 2)
- #define HAVE_CHILD(x,q) (x < (q)->size / 2)
- 
--static void
-+void
- trickle_up (int index, struct pqueue *queue)
- {
-   void *tmp;
-diff --git a/lib/pqueue.h b/lib/pqueue.h
-index 1f3201b..be37f98 100644
---- lib/pqueue.h
-+++ lib/pqueue.h
-@@ -40,5 +40,6 @@ extern void pqueue_enqueue (void *data, struct pqueue *queue);
- extern void *pqueue_dequeue (struct pqueue *queue);
- 
- extern void trickle_down (int index, struct pqueue *queue);
-+extern void trickle_up (int index, struct pqueue *queue);
- 
- #endif /* _ZEBRA_PQUEUE_H */
-diff --git a/ospfd/ChangeLog b/ospfd/ChangeLog
-index bb0e908..422208e 100644
---- ospfd/ChangeLog
-+++ ospfd/ChangeLog
-@@ -1,3 +1,9 @@
-+2007-08-07 Atis Elsts <[email protected]>
-+
-+	* ospf_spf.c: (ospf_spf_next) Sort heap in correct direction
-+	  after vertex cost is changed, thus fixing incorrect SPF
-+	  calculation on certain topologies.
-+
- 2007-08-06 Paul Jakma <[email protected]>
- 
- 	* ospf_lsa.c: (router_lsa_flags) Bug #331, NSSA regression caused
-diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
-index 51e3383..41288f1 100644
---- ospfd/ospf_spf.c
-+++ ospfd/ospf_spf.c
-@@ -896,9 +896,12 @@ ospf_spf_next (struct vertex *v, struct ospf_area *area,
-                * will flush the old parents
-                */
-               if (ospf_nexthop_calculation (area, v, w, l, distance))
--                /* Decrease the key of the node in the heap,
--                 * re-sort the heap. */
--                trickle_down (w_lsa->stat, candidate);
-+                /* Decrease the key of the node in the heap.
-+                 * trickle-sort it up towards root, just in case this
-+                 * node should now be the new root due the cost change. 
-+                 * (pqueu_{de,en}queue 
-+                 */
-+                trickle_up (w_lsa->stat, candidate);
-             }
-         } /* end W is already on the candidate list */
-     } /* end loop over the links in V's LSA */
--- a/components/quagga/patches/40-bgp-capab-cleanup.patch	Tue Dec 20 22:26:25 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1298 +0,0 @@
-commit 6d58272b4cf96f0daa846210dd2104877900f921
-Author: Paul Jakma <[email protected]>
-Date:   Mon Aug 6 15:21:45 2007 +0000
-
-    [bgpd] cleanup, compact and consolidate capability parsing code
-    
-    2007-07-26 Paul Jakma <[email protected]>
-    
-    	* (general) Clean up and compact capability parsing slightly.
-    	  Consolidate validation of length and logging of generic TLV, and
-    	  memcpy of capability data, thus removing such from cap specifc
-    	  code (not always present or correct).
-    	* bgp_open.h: Add structures for the generic capability TLV header
-    	  and for the data formats of the various specific capabilities we
-    	  support.  Hence remove the badly named, or else misdefined, struct
-    	  capability.
-    	* bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data.
-    	  Do the length checks *before* memcpy()'ing based on that length
-    	  (stored capability - should have been validated anyway on input,
-    	  but..).
-    	  (bgp_afi_safi_valid_indices) new function to validate (afi,safi)
-    	  which is about to be used as index into arrays, consolidates
-    	  several instances of same, at least one of which appeared to be
-    	  incomplete..
-    	  (bgp_capability_mp) Much condensed.
-    	  (bgp_capability_orf_entry) New, process one ORF entry
-    	  (bgp_capability_orf) Condensed. Fixed to process all ORF entries.
-    	  (bgp_capability_restart) Condensed, and fixed to use a
-    	  cap-specific type, rather than abusing capability_mp.
-    	  (struct message capcode_str) added to aid generic logging.
-    	  (size_t cap_minsizes[]) added to aid generic validation of
-    	  capability length field.
-    	  (bgp_capability_parse) Generic logging and validation of TLV
-    	  consolidated here. Code compacted as much as possible.
-    	* bgp_packet.c: (bgp_open_receive) Capability parsers now use
-    	  streams, so no more need here to manually fudge the input stream
-    	  getp.
-    	  (bgp_capability_msg_parse) use struct capability_mp_data. Validate
-    	  lengths /before/ memcpy. Use bgp_afi_safi_valid_indices.
-    	  (bgp_capability_receive) Exported for use by test harness.
-    	* bgp_vty.c: (bgp_show_summary) fix conversion warning
-    	  (bgp_show_peer) ditto
-    	* bgp_debug.h: Fix storage 'extern' after type 'const'.
-            * lib/log.c: (mes_lookup) warning about code not being in
-              same-number array slot should be debug, not warning. E.g. BGP
-              has several discontigious number spaces, allocating from
-              different parts of a space is not uncommon (e.g. IANA
-              assigned versus vendor-assigned code points in some number
-              space).
-
---- bgpd/bgp_debug.h
-+++ bgpd/bgp_debug.h
-@@ -110,7 +110,7 @@ extern unsigned long term_bgp_debug_zebra;
- #define BGP_DEBUG(a, b)		(term_bgp_debug_ ## a & BGP_DEBUG_ ## b)
- #define CONF_BGP_DEBUG(a, b)    (conf_bgp_debug_ ## a & BGP_DEBUG_ ## b)
- 
--const extern char *bgp_type_str[];
-+extern const char *bgp_type_str[];
- 
- extern int bgp_dump_attr (struct peer *, struct attr *, char *, size_t);
- extern void bgp_notify_print (struct peer *, struct bgp_notify *, const char *);
-diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
-index e44bd2a..d4f7cdf 100644
---- bgpd/bgp_open.c
-+++ bgpd/bgp_open.c
-@@ -26,6 +26,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- #include "thread.h"
- #include "log.h"
- #include "command.h"
-+#include "memory.h"
- 
- #include "bgpd/bgpd.h"
- #include "bgpd/bgp_attr.h"
-@@ -50,25 +51,28 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer)
- {
-   char *pnt;
-   char *end;
--  struct capability cap;
-+  struct capability_mp_data mpc;
-+  struct capability_header *hdr;
- 
-   pnt = peer->notify.data;
-   end = pnt + peer->notify.length;
--
-+  
-   while (pnt < end)
-     {
--      memcpy(&cap, pnt, sizeof(struct capability));
--
--      if (pnt + 2 > end)
-+      if (pnt + sizeof (struct capability_mp_data) + 2 > end)
- 	return;
--      if (pnt + (cap.length + 2) > end)
-+      
-+      hdr = (struct capability_header *)pnt;
-+      if (pnt + hdr->length + 2 > end)
- 	return;
- 
--      if (cap.code == CAPABILITY_CODE_MP)
-+      memcpy (&mpc, pnt + 2, sizeof(struct capability_mp_data));
-+
-+      if (hdr->code == CAPABILITY_CODE_MP)
- 	{
- 	  vty_out (vty, "  Capability error for: Multi protocol ");
- 
--	  switch (ntohs (cap.mpc.afi))
-+	  switch (ntohs (mpc.afi))
- 	    {
- 	    case AFI_IP:
- 	      vty_out (vty, "AFI IPv4, ");
-@@ -77,10 +81,10 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer)
- 	      vty_out (vty, "AFI IPv6, ");
- 	      break;
- 	    default:
--	      vty_out (vty, "AFI Unknown %d, ", ntohs (cap.mpc.afi));
-+	      vty_out (vty, "AFI Unknown %d, ", ntohs (mpc.afi));
- 	      break;
- 	    }
--	  switch (cap.mpc.safi)
-+	  switch (mpc.safi)
- 	    {
- 	    case SAFI_UNICAST:
- 	      vty_out (vty, "SAFI Unicast");
-@@ -95,88 +99,87 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer)
- 	      vty_out (vty, "SAFI MPLS-VPN");
- 	      break;
- 	    default:
--	      vty_out (vty, "SAFI Unknown %d ", cap.mpc.safi);
-+	      vty_out (vty, "SAFI Unknown %d ", mpc.safi);
- 	      break;
- 	    }
- 	  vty_out (vty, "%s", VTY_NEWLINE);
- 	}
--      else if (cap.code >= 128)
-+      else if (hdr->code >= 128)
- 	vty_out (vty, "  Capability error: vendor specific capability code %d",
--		 cap.code);
-+		 hdr->code);
-       else
- 	vty_out (vty, "  Capability error: unknown capability code %d", 
--		 cap.code);
-+		 hdr->code);
- 
--      pnt += cap.length + 2;
-+      pnt += hdr->length + 2;
-     }
- }
- 
--/* Set negotiated capability value. */
--static int
--bgp_capability_mp (struct peer *peer, struct capability *cap)
-+static void 
-+bgp_capability_mp_data (struct stream *s, struct capability_mp_data *mpc)
- {
--  if (ntohs (cap->mpc.afi) == AFI_IP)
--    {
--      if (cap->mpc.safi == SAFI_UNICAST)
--	{
--	  peer->afc_recv[AFI_IP][SAFI_UNICAST] = 1;
--
--	  if (peer->afc[AFI_IP][SAFI_UNICAST])
--	    peer->afc_nego[AFI_IP][SAFI_UNICAST] = 1;
--	  else
--	    return -1;
--	}
--      else if (cap->mpc.safi == SAFI_MULTICAST) 
--	{
--	  peer->afc_recv[AFI_IP][SAFI_MULTICAST] = 1;
--
--	  if (peer->afc[AFI_IP][SAFI_MULTICAST])
--	    peer->afc_nego[AFI_IP][SAFI_MULTICAST] = 1;
--	  else
--	    return -1;
--	}
--      else if (cap->mpc.safi == BGP_SAFI_VPNV4)
--	{
--	  peer->afc_recv[AFI_IP][SAFI_MPLS_VPN] = 1;
-+  mpc->afi = stream_getw (s);
-+  mpc->reserved = stream_getc (s);
-+  mpc->safi = stream_getc (s);
-+}
- 
--	  if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
--	    peer->afc_nego[AFI_IP][SAFI_MPLS_VPN] = 1;
--	  else
--	    return -1;
--	}
--      else
--	return -1;
--    }
--#ifdef HAVE_IPV6
--  else if (ntohs (cap->mpc.afi) == AFI_IP6)
-+int
-+bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi)
-+{
-+  /* VPNvX are AFI specific */
-+  if ((afi == AFI_IP6 && *safi == BGP_SAFI_VPNV4)
-+      || (afi == AFI_IP && *safi == BGP_SAFI_VPNV6))
-     {
--      if (cap->mpc.safi == SAFI_UNICAST)
--	{
--	  peer->afc_recv[AFI_IP6][SAFI_UNICAST] = 1;
--
--	  if (peer->afc[AFI_IP6][SAFI_UNICAST])
--	    peer->afc_nego[AFI_IP6][SAFI_UNICAST] = 1;
--	  else
--	    return -1;
--	}
--      else if (cap->mpc.safi == SAFI_MULTICAST)
--	{
--	  peer->afc_recv[AFI_IP6][SAFI_MULTICAST] = 1;
--
--	  if (peer->afc[AFI_IP6][SAFI_MULTICAST])
--	    peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = 1;
--	  else
--	    return -1;
--	}
--      else
--	return -1;
-+      zlog_warn ("Invalid afi/safi combination (%u/%u)", afi, *safi);
-+      return 0;
-     }
--#endif /* HAVE_IPV6 */
--  else
-+  
-+  switch (afi)
-     {
--      /* Unknown Address Family. */
--      return -1;
-+      case AFI_IP:
-+#ifdef HAVE_IPV6
-+      case AFI_IP6:
-+#endif
-+        switch (*safi)
-+          {
-+            /* BGP VPNvX SAFI isn't contigious with others, remap */
-+            case BGP_SAFI_VPNV4:
-+            case BGP_SAFI_VPNV6:
-+              *safi = SAFI_MPLS_VPN;
-+            case SAFI_UNICAST:
-+            case SAFI_MULTICAST:
-+            case SAFI_MPLS_VPN:
-+              return 1;
-+          }
-     }
-+  zlog_debug ("unknown afi/safi (%u/%u)", afi, *safi);
-+  
-+  return 0;
-+}
-+
-+/* Set negotiated capability value. */
-+static int
-+bgp_capability_mp (struct peer *peer, struct capability_header *hdr)
-+{
-+  struct capability_mp_data mpc;
-+  struct stream *s = BGP_INPUT (peer);
-+  
-+  bgp_capability_mp_data (s, &mpc);
-+  
-+  if (BGP_DEBUG (normal, NORMAL))
-+    zlog_debug ("%s OPEN has MP_EXT CAP for afi/safi: %u/%u",
-+               peer->host, mpc.afi, mpc.safi);
-+  
-+  if (!bgp_afi_safi_valid_indices (mpc.afi, &mpc.safi))
-+    return -1;
-+   
-+  /* Now safi remapped, and afi/safi are valid array indices */
-+  peer->afc_recv[mpc.afi][mpc.safi] = 1;
-+  
-+  if (peer->afc[mpc.afi][mpc.safi])
-+    peer->afc_nego[mpc.safi][mpc.safi] = 1;
-+  else 
-+    return -1;
- 
-   return 0;
- }
-@@ -190,98 +193,133 @@ bgp_capability_orf_not_support (struct peer *peer, afi_t afi, safi_t safi,
- 	       peer->host, afi, safi, type, mode);
- }
- 
-+static struct message orf_type_str[] =
-+{
-+  { ORF_TYPE_PREFIX,		"Prefixlist"		},
-+  { ORF_TYPE_PREFIX_OLD,	"Prefixlist (old)"	},
-+};
-+static int orf_type_str_max = sizeof(orf_type_str)/sizeof(orf_type_str[0]);
-+
-+static struct message orf_mode_str[] =
-+{
-+  { ORF_MODE_RECEIVE,	"Receive"	},
-+  { ORF_MODE_SEND,	"Send"		},
-+  { ORF_MODE_BOTH,	"Both"		},
-+};
-+static int orf_mode_str_max = sizeof(orf_mode_str)/sizeof(orf_mode_str[0]);
-+
- static int
--bgp_capability_orf (struct peer *peer, struct capability *cap,
--		    u_char *pnt)
-+bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
- {
--  afi_t afi = ntohs(cap->mpc.afi);
--  safi_t safi = cap->mpc.safi;
--  u_char number_of_orfs;
-+  struct stream *s = BGP_INPUT (peer);
-+  struct capability_orf_entry entry;
-+  afi_t afi;
-+  safi_t safi;
-   u_char type;
-   u_char mode;
-   u_int16_t sm_cap = 0; /* capability send-mode receive */
-   u_int16_t rm_cap = 0; /* capability receive-mode receive */ 
-   int i;
- 
--  /* Check length. */
--  if (cap->length < 7)
--    {
--      zlog_info ("%s ORF Capability length error %d",
--		 peer->host, cap->length);
--		 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
--      return -1;
--    }
--
-+  /* ORF Entry header */
-+  bgp_capability_mp_data (s, &entry.mpc);
-+  entry.num = stream_getc (s);
-+  afi = entry.mpc.afi;
-+  safi = entry.mpc.safi;
-+  
-   if (BGP_DEBUG (normal, NORMAL))
--    zlog_debug ("%s OPEN has ORF CAP(%s) for afi/safi: %u/%u",
--	       peer->host, (cap->code == CAPABILITY_CODE_ORF ?
--                       "new" : "old"), afi, safi);
-+    zlog_debug ("%s ORF Cap entry for afi/safi: %u/%u",
-+	        peer->host, entry.mpc.afi, entry.mpc.safi);
- 
-   /* Check AFI and SAFI. */
--  if ((afi != AFI_IP && afi != AFI_IP6)
--      || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
--	  && safi != BGP_SAFI_VPNV4))
-+  if (!bgp_afi_safi_valid_indices (entry.mpc.afi, &safi))
-+    {
-+      zlog_info ("%s Addr-family %d/%d not supported."
-+                 " Ignoring the ORF capability",
-+                 peer->host, entry.mpc.afi, entry.mpc.safi);
-+      return 0;
-+    }
-+  
-+  /* validate number field */
-+  if (sizeof (struct capability_orf_entry) + (entry.num * 2) > hdr->length)
-     {
--      zlog_info ("%s Addr-family %d/%d not supported. Ignoring the ORF capability",
--                 peer->host, afi, safi);
-+      zlog_info ("%s ORF Capability entry length error,"
-+                 " Cap length %u, num %u",
-+                 peer->host, hdr->length, entry.num);
-+      bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
-       return -1;
-     }
- 
--  number_of_orfs = *pnt++;
--
--  for (i = 0 ; i < number_of_orfs ; i++)
-+  for (i = 0 ; i < entry.num ; i++)
-     {
--      type = *pnt++;
--      mode = *pnt++;
--
-+      type = stream_getc(s);
-+      mode = stream_getc(s);
-+      
-       /* ORF Mode error check */
--      if (mode != ORF_MODE_BOTH && mode != ORF_MODE_SEND
--	  && mode != ORF_MODE_RECEIVE)
--	{
--	  bgp_capability_orf_not_support (peer, afi, safi, type, mode);
--	  continue;
-+      switch (mode)
-+        {
-+          case ORF_MODE_BOTH:
-+          case ORF_MODE_SEND:
-+          case ORF_MODE_RECEIVE:
-+            break;
-+          default:
-+	    bgp_capability_orf_not_support (peer, afi, safi, type, mode);
-+	    continue;
- 	}
-+      /* ORF Type and afi/safi error checks */
-+      /* capcode versus type */
-+      switch (hdr->code)
-+        {
-+          case CAPABILITY_CODE_ORF:
-+            switch (type)
-+              {
-+                case ORF_TYPE_PREFIX:
-+                  break;
-+                default:
-+                  bgp_capability_orf_not_support (peer, afi, safi, type, mode);
-+                  continue;
-+              }
-+            break;
-+          case CAPABILITY_CODE_ORF_OLD:
-+            switch (type)
-+              {
-+                case ORF_TYPE_PREFIX_OLD:
-+                  break;
-+                default:
-+                  bgp_capability_orf_not_support (peer, afi, safi, type, mode);
-+                  continue;
-+              }
-+            break;
-+          default:
-+            bgp_capability_orf_not_support (peer, afi, safi, type, mode);
-+            continue;
-+        }
-+                
-+      /* AFI vs SAFI */
-+      if (!((afi == AFI_IP && safi == SAFI_UNICAST)
-+            || (afi == AFI_IP && safi == SAFI_MULTICAST)
-+            || (afi == AFI_IP6 && safi == SAFI_UNICAST)))
-+        {
-+          bgp_capability_orf_not_support (peer, afi, safi, type, mode);
-+          continue;
-+        }
-+      
-+      if (BGP_DEBUG (normal, NORMAL))
-+        zlog_debug ("%s OPEN has %s ORF capability"
-+                    " as %s for afi/safi: %d/%d",
-+                    peer->host, LOOKUP (orf_type_str, type),
-+                    LOOKUP (orf_mode_str, mode),
-+                    entry.mpc.afi, safi);
- 
--      /* ORF Type and afi/safi error check */
--      if (cap->code == CAPABILITY_CODE_ORF)
-+      if (hdr->code == CAPABILITY_CODE_ORF)
- 	{
--	  if (type == ORF_TYPE_PREFIX &&
--	      ((afi == AFI_IP && safi == SAFI_UNICAST)
--		|| (afi == AFI_IP && safi == SAFI_MULTICAST)
--		|| (afi == AFI_IP6 && safi == SAFI_UNICAST)))
--	    {
--	      sm_cap = PEER_CAP_ORF_PREFIX_SM_RCV;
--	      rm_cap = PEER_CAP_ORF_PREFIX_RM_RCV;
--	      if (BGP_DEBUG (normal, NORMAL))
--		zlog_debug ("%s OPEN has Prefixlist ORF(%d) capability as %s for afi/safi: %d/%d",
--			   peer->host, ORF_TYPE_PREFIX, (mode == ORF_MODE_SEND ? "SEND" :
--			   mode == ORF_MODE_RECEIVE ? "RECEIVE" : "BOTH") , afi, safi);
--	    }
--	  else
--	    {
--	      bgp_capability_orf_not_support (peer, afi, safi, type, mode);
--	      continue;
--	    }
-+          sm_cap = PEER_CAP_ORF_PREFIX_SM_RCV;
-+          rm_cap = PEER_CAP_ORF_PREFIX_RM_RCV;
- 	}
--      else if (cap->code == CAPABILITY_CODE_ORF_OLD)
-+      else if (hdr->code == CAPABILITY_CODE_ORF_OLD)
- 	{
--	  if (type == ORF_TYPE_PREFIX_OLD &&
--	      ((afi == AFI_IP && safi == SAFI_UNICAST)
--		|| (afi == AFI_IP && safi == SAFI_MULTICAST)
--		|| (afi == AFI_IP6 && safi == SAFI_UNICAST)))
--	    {
--	      sm_cap = PEER_CAP_ORF_PREFIX_SM_OLD_RCV;
--	      rm_cap = PEER_CAP_ORF_PREFIX_RM_OLD_RCV;
--	      if (BGP_DEBUG (normal, NORMAL))
--		zlog_debug ("%s OPEN has Prefixlist ORF(%d) capability as %s for afi/safi: %d/%d",
--			   peer->host, ORF_TYPE_PREFIX_OLD, (mode == ORF_MODE_SEND ? "SEND" :
--			   mode == ORF_MODE_RECEIVE ? "RECEIVE" : "BOTH") , afi, safi);
--	    }
--	  else
--	    {
--	      bgp_capability_orf_not_support (peer, afi, safi, type, mode);
--	      continue;
--	    }
-+          sm_cap = PEER_CAP_ORF_PREFIX_SM_OLD_RCV;
-+          rm_cap = PEER_CAP_ORF_PREFIX_RM_OLD_RCV;
- 	}
-       else
- 	{
-@@ -306,206 +344,258 @@ bgp_capability_orf (struct peer *peer, struct capability *cap,
-   return 0;
- }
- 
--/* Parse given capability. */
- static int
--bgp_capability_parse (struct peer *peer, u_char *pnt, u_char length,
--		      u_char **error)
-+bgp_capability_orf (struct peer *peer, struct capability_header *hdr)
- {
--  int ret;
--  u_char *end;
--  struct capability cap;
--
--  end = pnt + length;
--
--  while (pnt < end)
-+  struct stream *s = BGP_INPUT (peer);
-+  size_t end = stream_get_getp (s) + hdr->length;
-+  
-+  assert (stream_get_getp(s) + sizeof(struct capability_orf_entry) <= end);
-+  
-+  /* We must have at least one ORF entry, as the caller has already done
-+   * minimum length validation for the capability code - for ORF there must
-+   * at least one ORF entry (header and unknown number of pairs of bytes).
-+   */
-+  do
-     {
--      afi_t afi;
--      safi_t safi;
-+      if (bgp_capability_orf_entry (peer, hdr) == -1)
-+        return -1;
-+    } 
-+  while (stream_get_getp(s) + sizeof(struct capability_orf_entry) < end);
-+  
-+  return 0;
-+}
- 
--      /* Fetch structure to the byte stream. */
--      memcpy (&cap, pnt, sizeof (struct capability));
-+static int
-+bgp_capability_restart (struct peer *peer, struct capability_header *caphdr)
-+{
-+  struct stream *s = BGP_INPUT (peer);
-+  u_int16_t restart_flag_time;
-+  int restart_bit = 0;
-+  size_t end = stream_get_getp (s) + caphdr->length;
-+
-+  SET_FLAG (peer->cap, PEER_CAP_RESTART_RCV);
-+  restart_flag_time = stream_getw(s);
-+  if (CHECK_FLAG (restart_flag_time, RESTART_R_BIT))
-+    restart_bit = 1;
-+  UNSET_FLAG (restart_flag_time, 0xF000);
-+  peer->v_gr_restart = restart_flag_time;
- 
--      afi = ntohs(cap.mpc.afi);
--      safi = cap.mpc.safi;
-+  if (BGP_DEBUG (normal, NORMAL))
-+    {
-+      zlog_debug ("%s OPEN has Graceful Restart capability", peer->host);
-+      zlog_debug ("%s Peer has%srestarted. Restart Time : %d",
-+                  peer->host, restart_bit ? " " : " not ",
-+                  peer->v_gr_restart);
-+    }
- 
--      if (BGP_DEBUG (normal, NORMAL))
--	zlog_debug ("%s OPEN has CAPABILITY code: %d, length %d",
--		   peer->host, cap.code, cap.length);
-+  while (stream_get_getp (s) + 4 < end)
-+    {
-+      afi_t afi = stream_getw (s);
-+      safi_t safi = stream_getc (s);
-+      u_char flag = stream_getc (s);
-+      
-+      if (!bgp_afi_safi_valid_indices (afi, &safi))
-+        {
-+          if (BGP_DEBUG (normal, NORMAL))
-+            zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported."
-+                        " Ignore the Graceful Restart capability",
-+                        peer->host, afi, safi);
-+        }
-+      else if (!peer->afc[afi][safi])
-+        {
-+          if (BGP_DEBUG (normal, NORMAL))
-+            zlog_debug ("%s Addr-family %d/%d(afi/safi) not enabled."
-+                        " Ignore the Graceful Restart capability",
-+                        peer->host, afi, safi);
-+        }
-+      else
-+        {
-+          if (BGP_DEBUG (normal, NORMAL))
-+            zlog_debug ("%s Address family %s is%spreserved", peer->host,
-+                        afi_safi_print (afi, safi),
-+                        CHECK_FLAG (peer->af_cap[afi][safi],
-+                                    PEER_CAP_RESTART_AF_PRESERVE_RCV)
-+                        ? " " : " not ");
-+
-+          SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV);
-+          if (CHECK_FLAG (flag, RESTART_F_BIT))
-+            SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV);
-+          
-+        }
-+    }
-+  return 0;
-+}
- 
-+static struct message capcode_str[] =
-+{
-+  { 0,	""},
-+  { CAPABILITY_CODE_MP,			"MultiProtocol Extensions"	},
-+  { CAPABILITY_CODE_REFRESH,		"Route Refresh"			},
-+  { CAPABILITY_CODE_ORF,		"Cooperative Route Filtering" 	},
-+  { CAPABILITY_CODE_RESTART,		"Graceful Restart"		},
-+  { CAPABILITY_CODE_AS4,		"4-octet AS number"		},
-+  { CAPABILITY_CODE_DYNAMIC,		"Dynamic"			},
-+  { CAPABILITY_CODE_REFRESH_OLD,	"Route Refresh (Old)"		},
-+  { CAPABILITY_CODE_ORF_OLD,		"ORF (Old)"			},
-+};
-+int capcode_str_max = sizeof(capcode_str)/sizeof(capcode_str[0]);
-+
-+/* Minimum sizes for length field of each cap (so not inc. the header) */
-+static size_t cap_minsizes[] = 
-+{
-+  [CAPABILITY_CODE_MP]		= sizeof (struct capability_mp_data),
-+  [CAPABILITY_CODE_REFRESH]	= CAPABILITY_CODE_REFRESH_LEN,
-+  [CAPABILITY_CODE_ORF]		= sizeof (struct capability_orf_entry),
-+  [CAPABILITY_CODE_RESTART]	= sizeof (struct capability_gr) - 2,
-+  [CAPABILITY_CODE_AS4]		= CAPABILITY_CODE_AS4_LEN,
-+  [CAPABILITY_CODE_DYNAMIC]	= CAPABILITY_CODE_DYNAMIC_LEN,
-+  [CAPABILITY_CODE_REFRESH_OLD]	= CAPABILITY_CODE_REFRESH_LEN,
-+  [CAPABILITY_CODE_ORF_OLD]	= sizeof (struct capability_orf_entry),
-+};
-+
-+/* Parse given capability.
-+ * XXX: This is reading into a stream, but not using stream API
-+ */
-+static int
-+bgp_capability_parse (struct peer *peer, size_t length, u_char **error)
-+{
-+  int ret;
-+  struct stream *s = BGP_INPUT (peer);
-+  size_t end = stream_get_getp (s) + length;
-+  
-+  assert (STREAM_READABLE (s) >= length);
-+  
-+  while (stream_get_getp (s) < end)
-+    {
-+      size_t start;
-+      u_char *sp = stream_pnt (s);
-+      struct capability_header caphdr;
-+      
-       /* We need at least capability code and capability length. */
--      if (pnt + 2 > end)
-+      if (stream_get_getp(s) + 2 > end)
- 	{
--	  zlog_info ("%s Capability length error", peer->host);
-+	  zlog_info ("%s Capability length error (< header)", peer->host);
- 	  bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
- 	  return -1;
- 	}
--
--      /* Capability length check. */
--      if (pnt + (cap.length + 2) > end)
-+      
-+      caphdr.code = stream_getc (s);
-+      caphdr.length = stream_getc (s);
-+      start = stream_get_getp (s);
-+      
-+      /* Capability length check sanity check. */
-+      if (start + caphdr.length > end)
- 	{
--	  zlog_info ("%s Capability length error", peer->host);
-+	  zlog_info ("%s Capability length error (< length)", peer->host);
- 	  bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
- 	  return -1;
- 	}
--
--      /* We know MP Capability Code. */
--      if (cap.code == CAPABILITY_CODE_MP)
--	{
--	  if (BGP_DEBUG (normal, NORMAL))
--	    zlog_debug ("%s OPEN has MP_EXT CAP for afi/safi: %u/%u",
--		       peer->host, afi, safi);
--
--	  /* Ignore capability when override-capability is set. */
--	  if (! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
--	    {
--	      /* Set negotiated value. */
--	      ret = bgp_capability_mp (peer, &cap);
--
--	      /* Unsupported Capability. */
--	      if (ret < 0)
--		{
--		  /* Store return data. */
--		  memcpy (*error, &cap, cap.length + 2);
--		  *error += cap.length + 2;
--		}
--	    }
--	}
--      else if (cap.code == CAPABILITY_CODE_REFRESH
--	       || cap.code == CAPABILITY_CODE_REFRESH_OLD)
--	{
--	  /* Check length. */
--	  if (cap.length != CAPABILITY_CODE_REFRESH_LEN)
--	    {
--	      zlog_info ("%s Route Refresh Capability length error %d",
--			 peer->host, cap.length);
--	      bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
--	      return -1;
--	    }
--
--	  if (BGP_DEBUG (normal, NORMAL))
--	    zlog_debug ("%s OPEN has ROUTE-REFRESH capability(%s) for all address-families",
--		       peer->host,
--		       cap.code == CAPABILITY_CODE_REFRESH_OLD ? "old" : "new");
--
--	  /* BGP refresh capability */
--	  if (cap.code == CAPABILITY_CODE_REFRESH_OLD)
--	    SET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
--	  else
--	    SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
--	}
--      else if (cap.code == CAPABILITY_CODE_ORF
--	       || cap.code == CAPABILITY_CODE_ORF_OLD)
--	bgp_capability_orf (peer, &cap, pnt + sizeof (struct capability));
--      else if (cap.code == CAPABILITY_CODE_RESTART)
--       {
--         struct graceful_restart_af graf;
--         u_int16_t restart_flag_time;
--         int restart_bit = 0;
--         u_char *restart_pnt;
--         u_char *restart_end;
--
--         /* Check length. */
--         if (cap.length < CAPABILITY_CODE_RESTART_LEN)
--           {
--             zlog_info ("%s Graceful Restart Capability length error %d",
--                        peer->host, cap.length);
--             bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
--             return -1;
--           }
--
--         SET_FLAG (peer->cap, PEER_CAP_RESTART_RCV);
--         restart_flag_time = ntohs(cap.mpc.afi);
--         if (CHECK_FLAG (restart_flag_time, RESTART_R_BIT))
--           restart_bit = 1;
--         UNSET_FLAG (restart_flag_time, 0xF000);
--	 peer->v_gr_restart = restart_flag_time;
--
--         if (BGP_DEBUG (normal, NORMAL))
--           {
--             zlog_debug ("%s OPEN has Graceful Restart capability", peer->host);
--             zlog_debug ("%s Peer has%srestarted. Restart Time : %d",
--                        peer->host, restart_bit ? " " : " not ",
--			peer->v_gr_restart);
--           }
--
--         restart_pnt = pnt + 4;
--         restart_end = pnt + cap.length + 2;
--
--         while (restart_pnt < restart_end)
--           {
--             memcpy (&graf, restart_pnt, sizeof (struct graceful_restart_af));
--
--             afi = ntohs(graf.afi);
--             safi = graf.safi;
--
--             if (CHECK_FLAG (graf.flag, RESTART_F_BIT))
--		SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV);
--
--             if (strcmp (afi_safi_print (afi, safi), "Unknown") == 0)
--               {
--                  if (BGP_DEBUG (normal, NORMAL))
--                    zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported. I gnore the Graceful Restart capability",
--                               peer->host, afi, safi);
--               }
--             else if (! peer->afc[afi][safi])
--               {
--                  if (BGP_DEBUG (normal, NORMAL))
--                     zlog_debug ("%s Addr-family %d/%d(afi/safi) not enabled. Ignore the Graceful Restart capability",
--                                peer->host, afi, safi);
--               }
--             else
--               {
--                 if (BGP_DEBUG (normal, NORMAL))
--                   zlog_debug ("%s Address family %s is%spreserved", peer->host,
--			       afi_safi_print (afi, safi),
--			       CHECK_FLAG (peer->af_cap[afi][safi],
--			       PEER_CAP_RESTART_AF_PRESERVE_RCV)
--			       ? " " : " not ");
--
--                   SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV);
--               }
--             restart_pnt += 4;
--           }
--       }
--      else if (cap.code == CAPABILITY_CODE_DYNAMIC)
--	{
--	  /* Check length. */
--	  if (cap.length != CAPABILITY_CODE_DYNAMIC_LEN)
--	    {
--	      zlog_info ("%s Dynamic Capability length error %d",
--			 peer->host, cap.length);
--	      bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
--	      return -1;
--	    }
--
--	  if (BGP_DEBUG (normal, NORMAL))
--	    zlog_debug ("%s OPEN has DYNAMIC capability", peer->host);
--
--	  SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
--	}
-- 
--      else if (cap.code > 128)
--	{
--	  /* We don't send Notification for unknown vendor specific
--	     capabilities.  It seems reasonable for now...  */
--	  zlog_warn ("%s Vendor specific capability %d",
--		     peer->host, cap.code);
--	}
--      else
--	{
--	  zlog_warn ("%s unrecognized capability code: %d - ignored",
--		     peer->host, cap.code);
--	  memcpy (*error, &cap, cap.length + 2);
--	  *error += cap.length + 2;
--	}
--
--      pnt += cap.length + 2;
-+      
-+      if (BGP_DEBUG (normal, NORMAL))
-+	zlog_debug ("%s OPEN has %s capability (%u), length %u",
-+		   peer->host,
-+		   LOOKUP (capcode_str, caphdr.code),
-+		   caphdr.code, caphdr.length);
-+      
-+      /* Length sanity check, type-specific, for known capabilities */
-+      switch (caphdr.code)
-+        {
-+          case CAPABILITY_CODE_MP:
-+          case CAPABILITY_CODE_REFRESH:
-+          case CAPABILITY_CODE_REFRESH_OLD:
-+          case CAPABILITY_CODE_ORF:
-+          case CAPABILITY_CODE_ORF_OLD:
-+          case CAPABILITY_CODE_RESTART:
-+          case CAPABILITY_CODE_DYNAMIC:
-+              /* Check length. */
-+              if (caphdr.length < cap_minsizes[caphdr.code])
-+                {
-+                  zlog_info ("%s %s Capability length error: got %u,"
-+                             " expected at least %u",
-+                             peer->host, 
-+                             LOOKUP (capcode_str, caphdr.code),
-+                             caphdr.length, cap_minsizes[caphdr.code]);
-+                  bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
-+                  return -1;
-+                }
-+          /* we deliberately ignore unknown codes, see below */
-+          default:
-+            break;
-+        }
-+      
-+      switch (caphdr.code)
-+        {
-+          case CAPABILITY_CODE_MP:
-+            {
-+              /* Ignore capability when override-capability is set. */
-+              if (! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
-+                {
-+                  /* Set negotiated value. */
-+                  ret = bgp_capability_mp (peer, &caphdr);
-+
-+                  /* Unsupported Capability. */
-+                  if (ret < 0)
-+                    {
-+                      /* Store return data. */
-+                      memcpy (*error, sp, caphdr.length + 2);
-+                      *error += caphdr.length + 2;
-+                    }
-+                }
-+            }
-+            break;
-+          case CAPABILITY_CODE_REFRESH:
-+          case CAPABILITY_CODE_REFRESH_OLD:
-+            {
-+              /* BGP refresh capability */
-+              if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
-+                SET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
-+              else
-+                SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
-+            }
-+            break;
-+          case CAPABILITY_CODE_ORF:
-+          case CAPABILITY_CODE_ORF_OLD:
-+            if (bgp_capability_orf (peer, &caphdr))
-+              return -1;
-+            break;
-+          case CAPABILITY_CODE_RESTART:
-+            if (bgp_capability_restart (peer, &caphdr))
-+              return -1;
-+            break;
-+          case CAPABILITY_CODE_DYNAMIC:
-+            SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
-+            break;
-+          default:
-+            if (caphdr.code > 128)
-+              {
-+                /* We don't send Notification for unknown vendor specific
-+                   capabilities.  It seems reasonable for now...  */
-+                zlog_warn ("%s Vendor specific capability %d",
-+                           peer->host, caphdr.code);
-+              }
-+            else
-+              {
-+                zlog_warn ("%s unrecognized capability code: %d - ignored",
-+                           peer->host, caphdr.code);
-+                memcpy (*error, sp, caphdr.length + 2);
-+                *error += caphdr.length + 2;
-+              }
-+          }
-+      if (stream_get_getp(s) != (start + caphdr.length))
-+        {
-+          if (stream_get_getp(s) > (start + caphdr.length))
-+            zlog_warn ("%s Cap-parser for %s read past cap-length, %u!",
-+                       peer->host, LOOKUP (capcode_str, caphdr.code),
-+                       caphdr.length);
-+          stream_set_getp (s, start + caphdr.length);
-+        }
-     }
-   return 0;
- }
- 
- static int
--bgp_auth_parse (struct peer *peer, u_char *pnt, size_t length)
-+bgp_auth_parse (struct peer *peer, size_t length)
- {
-   bgp_notify_send (peer, 
- 		   BGP_NOTIFY_OPEN_ERR, 
-@@ -530,30 +620,25 @@ int
- bgp_open_option_parse (struct peer *peer, u_char length, int *capability)
- {
-   int ret;
--  u_char *end;
--  u_char opt_type;
--  u_char opt_length;
--  u_char *pnt;
-   u_char *error;
-   u_char error_data[BGP_MAX_PACKET_SIZE];
--
--  /* Fetch pointer. */
--  pnt = stream_pnt (peer->ibuf);
-+  struct stream *s = BGP_INPUT(peer);
-+  size_t end = stream_get_getp (s) + length;
- 
-   ret = 0;
--  opt_type = 0;
--  opt_length = 0;
--  end = pnt + length;
-   error = error_data;
- 
-   if (BGP_DEBUG (normal, NORMAL))
-     zlog_debug ("%s rcv OPEN w/ OPTION parameter len: %u",
- 	       peer->host, length);
-   
--  while (pnt < end) 
-+  while (stream_get_getp(s) < end)
-     {
--      /* Check the length. */
--      if (pnt + 2 > end)
-+      u_char opt_type;
-+      u_char opt_length;
-+      
-+      /* Must have at least an OPEN option header */
-+      if (STREAM_READABLE(s) < 2)
- 	{
- 	  zlog_info ("%s Option length error", peer->host);
- 	  bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
-@@ -561,11 +646,11 @@ bgp_open_option_parse (struct peer *peer, u_char length, int *capability)
- 	}
- 
-       /* Fetch option type and length. */
--      opt_type = *pnt++;
--      opt_length = *pnt++;
-+      opt_type = stream_getc (s);
-+      opt_length = stream_getc (s);
-       
-       /* Option length check. */
--      if (pnt + opt_length > end)
-+      if (STREAM_READABLE (s) < opt_length)
- 	{
- 	  zlog_info ("%s Option length error", peer->host);
- 	  bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
-@@ -582,10 +667,10 @@ bgp_open_option_parse (struct peer *peer, u_char length, int *capability)
-       switch (opt_type)
- 	{
- 	case BGP_OPEN_OPT_AUTH:
--	  ret = bgp_auth_parse (peer, pnt, opt_length);
-+	  ret = bgp_auth_parse (peer, opt_length);
- 	  break;
- 	case BGP_OPEN_OPT_CAP:
--	  ret = bgp_capability_parse (peer, pnt, opt_length, &error);
-+	  ret = bgp_capability_parse (peer, opt_length, &error);
- 	  *capability = 1;
- 	  break;
- 	default:
-@@ -602,9 +687,6 @@ bgp_open_option_parse (struct peer *peer, u_char length, int *capability)
-          error and erro_data pointer, like below.  */
-       if (ret < 0)
- 	return -1;
--
--      /* Forward pointer. */
--      pnt += opt_length;
-     }
- 
-   /* All OPEN option is parsed.  Check capability when strict compare
-diff --git a/bgpd/bgp_open.h b/bgpd/bgp_open.h
-index 7515d3f..436eb01 100644
---- bgpd/bgp_open.h
-+++ bgpd/bgp_open.h
-@@ -21,21 +21,32 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- #ifndef _QUAGGA_BGP_OPEN_H
- #define _QUAGGA_BGP_OPEN_H
- 
--/* MP Capability information. */
--struct capability_mp
-+/* Standard header for capability TLV */
-+struct capability_header
-+{
-+  u_char code;
-+  u_char length;
-+};
-+
-+/* Generic MP capability data */
-+struct capability_mp_data
- {
-   u_int16_t afi;
-   u_char reserved;
-   u_char safi;
- };
- 
--/* BGP open message capability. */
--struct capability
-+#pragma pack(1)
-+struct capability_orf_entry 
- {
--  u_char code;
--  u_char length;
--  struct capability_mp mpc;
--};
-+  struct capability_mp_data mpc;
-+  u_char num;
-+  struct {
-+    u_char type;
-+    u_char mode;
-+  } orfs[];
-+} __attribute__ ((packed));
-+#pragma pack()
- 
- struct graceful_restart_af
- {
-@@ -44,12 +55,18 @@ struct graceful_restart_af
-   u_char flag;
- };
- 
-+struct capability_gr
-+{
-+  u_int16_t restart_flag_time;
-+  struct graceful_restart_af gr[];
-+};
-+
- /* Capability Code */
- #define CAPABILITY_CODE_MP              1 /* Multiprotocol Extensions */
- #define CAPABILITY_CODE_REFRESH         2 /* Route Refresh Capability */
- #define CAPABILITY_CODE_ORF             3 /* Cooperative Route Filtering Capability */
- #define CAPABILITY_CODE_RESTART        64 /* Graceful Restart Capability */
--#define CAPABILITY_CODE_4BYTE_AS       65 /* 4-octet AS number Capability */
-+#define CAPABILITY_CODE_AS4            65 /* 4-octet AS number Capability */
- #define CAPABILITY_CODE_DYNAMIC        66 /* Dynamic Capability */
- #define CAPABILITY_CODE_REFRESH_OLD   128 /* Route Refresh Capability(cisco) */
- #define CAPABILITY_CODE_ORF_OLD       130 /* Cooperative Route Filtering Capability(cisco) */
-@@ -59,6 +76,7 @@ struct graceful_restart_af
- #define CAPABILITY_CODE_REFRESH_LEN     0
- #define CAPABILITY_CODE_DYNAMIC_LEN     0
- #define CAPABILITY_CODE_RESTART_LEN     2 /* Receiving only case */
-+#define CAPABILITY_CODE_AS4_LEN         4
- 
- /* Cooperative Route Filtering Capability.  */
- 
-@@ -82,5 +100,6 @@ struct graceful_restart_af
- extern int bgp_open_option_parse (struct peer *, u_char, int *);
- extern void bgp_open_capability (struct stream *, struct peer *);
- extern void bgp_capability_vty_out (struct vty *, struct peer *);
-+extern int bgp_afi_safi_valid_indices (afi_t, safi_t *);
- 
- #endif /* _QUAGGA_BGP_OPEN_H */
-diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
-index 2653201..17ac1f7 100644
---- bgpd/bgp_packet.c
-+++ bgpd/bgp_packet.c
-@@ -1371,8 +1371,6 @@ bgp_open_receive (struct peer *peer, bgp_size_t size)
-       ret = bgp_open_option_parse (peer, optlen, &capability);
-       if (ret < 0)
- 	return ret;
--
--      stream_forward_getp (peer->ibuf, optlen);
-     }
-   else
-     {
-@@ -1991,7 +1989,8 @@ static int
- bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
- {
-   u_char *end;
--  struct capability cap;
-+  struct capability_mp_data mpc;
-+  struct capability_header *hdr;
-   u_char action;
-   struct bgp *bgp;
-   afi_t afi;
-@@ -2001,7 +2000,7 @@ bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
-   end = pnt + length;
- 
-   while (pnt < end)
--    {
-+    {      
-       /* We need at least action, capability code and capability length. */
-       if (pnt + 3 > end)
-         {
-@@ -2009,12 +2008,9 @@ bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
-           bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
-           return -1;
-         }
--
-       action = *pnt;
--
--      /* Fetch structure to the byte stream. */
--      memcpy (&cap, pnt + 1, sizeof (struct capability));
--
-+      hdr = (struct capability_header *)(pnt + 1);
-+      
-       /* Action value check.  */
-       if (action != CAPABILITY_ACTION_SET
- 	  && action != CAPABILITY_ACTION_UNSET)
-@@ -2027,77 +2023,77 @@ bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
- 
-       if (BGP_DEBUG (normal, NORMAL))
- 	zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
--		   peer->host, action, cap.code, cap.length);
-+		   peer->host, action, hdr->code, hdr->length);
- 
-       /* Capability length check. */
--      if (pnt + (cap.length + 3) > end)
-+      if ((pnt + hdr->length + 3) > end)
-         {
-           zlog_info ("%s Capability length error", peer->host);
-           bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
-           return -1;
-         }
- 
-+      /* Fetch structure to the byte stream. */
-+      memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
-+
-       /* We know MP Capability Code. */
--      if (cap.code == CAPABILITY_CODE_MP)
-+      if (hdr->code == CAPABILITY_CODE_MP)
-         {
--	  afi = ntohs (cap.mpc.afi);
--	  safi = cap.mpc.safi;
-+	  afi = ntohs (mpc.afi);
-+	  safi = mpc.safi;
- 
-           /* Ignore capability when override-capability is set. */
-           if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
- 	    continue;
--
-+          
-+          if (!bgp_afi_safi_valid_indices (afi, &safi))
-+            {
-+              if (BGP_DEBUG (normal, NORMAL))
-+                zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid",
-+                            peer->host, afi, safi);
-+              continue;
-+            }
-+          
- 	  /* Address family check.  */
--	  if ((afi == AFI_IP 
--	       || afi == AFI_IP6)
--	      && (safi == SAFI_UNICAST 
--		  || safi == SAFI_MULTICAST 
--		  || safi == BGP_SAFI_VPNV4))
--	    {
--	      if (BGP_DEBUG (normal, NORMAL))
--		zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
--			   peer->host,
--			   action == CAPABILITY_ACTION_SET 
--			   ? "Advertising" : "Removing",
--			   ntohs(cap.mpc.afi) , cap.mpc.safi);
--		  
--	      /* Adjust safi code. */
--	      if (safi == BGP_SAFI_VPNV4)
--		safi = SAFI_MPLS_VPN;
--	      
--	      if (action == CAPABILITY_ACTION_SET)
--		{
--		  peer->afc_recv[afi][safi] = 1;
--		  if (peer->afc[afi][safi])
--		    {
--		      peer->afc_nego[afi][safi] = 1;
--		      bgp_announce_route (peer, afi, safi);
--		    }
--		}
--	      else
--		{
--		  peer->afc_recv[afi][safi] = 0;
--		  peer->afc_nego[afi][safi] = 0;
--
--		  if (peer_active_nego (peer))
--		    bgp_clear_route (peer, afi, safi);
--		  else
--		    BGP_EVENT_ADD (peer, BGP_Stop);
--		} 
--	    }
-+          if (BGP_DEBUG (normal, NORMAL))
-+            zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
-+                       peer->host,
-+                       action == CAPABILITY_ACTION_SET 
-+                       ? "Advertising" : "Removing",
-+                       ntohs(mpc.afi) , mpc.safi);
-+              
-+          if (action == CAPABILITY_ACTION_SET)
-+            {
-+              peer->afc_recv[afi][safi] = 1;
-+              if (peer->afc[afi][safi])
-+                {
-+                  peer->afc_nego[afi][safi] = 1;
-+                  bgp_announce_route (peer, afi, safi);
-+                }
-+            }
-+          else
-+            {
-+              peer->afc_recv[afi][safi] = 0;
-+              peer->afc_nego[afi][safi] = 0;
-+
-+              if (peer_active_nego (peer))
-+                bgp_clear_route (peer, afi, safi);
-+              else
-+                BGP_EVENT_ADD (peer, BGP_Stop);
-+            }
-         }
-       else
-         {
-           zlog_warn ("%s unrecognized capability code: %d - ignored",
--                     peer->host, cap.code);
-+                     peer->host, hdr->code);
-         }
--      pnt += cap.length + 3;
-+      pnt += hdr->length + 3;
-     }
-   return 0;
- }
- 
- /* Dynamic Capability is received. */
--static void
-+int
- bgp_capability_receive (struct peer *peer, bgp_size_t size)
- {
-   u_char *pnt;
-@@ -2130,7 +2126,7 @@ bgp_capability_receive (struct peer *peer, bgp_size_t size)
-     }
- 
-   /* Parse packet. */
--  ret = bgp_capability_msg_parse (peer, pnt, size);
-+  return bgp_capability_msg_parse (peer, pnt, size);
- }
- 
- /* BGP read utility function. */
-diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
-index 1e21c74..3eeb5f9 100644
---- bgpd/bgp_vty.c
-+++ bgpd/bgp_vty.c
-@@ -6681,14 +6681,14 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi)
- 
- 	  vty_out (vty, "4 ");
- 
--	  vty_out (vty, "%5d %7d %7d %8d %4d %4ld ",
-+	  vty_out (vty, "%5d %7d %7d %8d %4d %4lu ",
- 		   peer->as,
- 		   peer->open_in + peer->update_in + peer->keepalive_in
- 		   + peer->notify_in + peer->refresh_in + peer->dynamic_cap_in,
- 		   peer->open_out + peer->update_out + peer->keepalive_out
- 		   + peer->notify_out + peer->refresh_out
- 		   + peer->dynamic_cap_out,
--		   0, 0, peer->obuf->count);
-+		   0, 0, (unsigned long)peer->obuf->count);
- 
- 	  vty_out (vty, "%8s", 
- 		   peer_uptime (peer->uptime, timebuf, BGP_UPTIME_LEN));
-@@ -7403,7 +7403,7 @@ bgp_show_peer (struct vty *vty, struct peer *p)
-   /* Packet counts. */
-   vty_out (vty, "  Message statistics:%s", VTY_NEWLINE);
-   vty_out (vty, "    Inq depth is 0%s", VTY_NEWLINE);
--  vty_out (vty, "    Outq depth is %ld%s", p->obuf->count, VTY_NEWLINE);
-+  vty_out (vty, "    Outq depth is %lu%s", (unsigned long)p->obuf->count, VTY_NEWLINE);
-   vty_out (vty, "                         Sent       Rcvd%s", VTY_NEWLINE);
-   vty_out (vty, "    Opens:         %10d %10d%s", p->open_out, p->open_in, VTY_NEWLINE);
-   vty_out (vty, "    Notifications: %10d %10d%s", p->notify_out, p->notify_in, VTY_NEWLINE);
-diff --git a/lib/log.c b/lib/log.c
-index cbf76af..ff47cae 100644
---- lib/log.c
-+++ lib/log.c
-@@ -769,7 +769,7 @@ mes_lookup (struct message *meslist, int max, int index)
-       {
- 	if (meslist->key == index)
- 	  {
--	    zlog_warn("message index %d [%s] found in position %d (max is %d)",
-+	    zlog_debug ("message index %d [%s] found in position %d (max is %d)",
- 		      index, meslist->str, i, max);
- 	    return meslist->str;
- 	  }
--- a/components/quagga/patches/45-bgpd-capab-typo.patch	Tue Dec 20 22:26:25 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-commit 7b87b33fa53254f14b79e95bb8a0b24f8ef9e1c1
-Author: Paul Jakma <[email protected]>
-Date:   Mon Sep 17 13:51:28 2007 +0100
-
-    [bgpd] Fix typo, which prevented advertisement of MP (non-IPv4) prefixes
-    
-    2007-09-17 Paul Jakma <[email protected]>
-    
-    	* bgp_open.c: (bgp_capability_mp) We were setting
-    	  afc_nego[safi][safi] rather than afc_nego[afi][safi], thus
-    	  failling to announce any non-IPv4 prefixes. Remove the extra,
-    	  typo-ed character.
-    	* tests/bgp_capability_test.c: Test that peer's adv_recv and
-    	  adv_nego get set correctly for MP capability and given AFI/SAFI.
-    	  Colour OK/failed result so it's easier to find them.
-
---- bgpd/bgp_open.c
-+++ bgpd/bgp_open.c
-@@ -177,7 +177,7 @@ bgp_capability_mp (struct peer *peer, struct capability_header *hdr)
-   peer->afc_recv[mpc.afi][mpc.safi] = 1;
-   
-   if (peer->afc[mpc.afi][mpc.safi])
--    peer->afc_nego[mpc.safi][mpc.safi] = 1;
-+    peer->afc_nego[mpc.afi][mpc.safi] = 1;
-   else 
-     return -1;
- 
--- a/components/quagga/patches/50-bgpd-nosub.patch	Tue Dec 20 22:26:25 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-commit 6d134fb4defecb16591adbf4acb020acd165a75a
-Author: Paul Jakma <[email protected]>
-Date:   Thu Aug 23 23:22:02 2007 +0000
-
-    [bgpd] Pass NOSUB to regexec
-    
-    2007-08-23 Paul Jakma <[email protected]>
-    
-    	* bgp_regex.c: (bgp_regcomp) Pass NOSUB flag to regcomp to
-    	  prevent parsing of substitutions, which can have profound
-    	  performance effects on bgpd and are of no use to the CLI
-    	  anyway. How much it helps depends on the regex
-    	  implementation.
-
-diff --git a/bgpd/bgp_regex.c b/bgpd/bgp_regex.c
-index be84d40..9b65f7c 100644
---- bgpd/bgp_regex.c
-+++ bgpd/bgp_regex.c
-@@ -66,7 +66,7 @@ bgp_regcomp (const char *regstr)
- 
-   regex = XMALLOC (MTYPE_BGP_REGEXP, sizeof (regex_t));
- 
--  ret = regcomp (regex, magic_str, REG_EXTENDED);
-+  ret = regcomp (regex, magic_str, REG_EXTENDED|REG_NOSUB);
- 
-   XFREE (MTYPE_TMP, magic_str);
- 
--- a/components/quagga/patches/55-bgpd-rm-assert.patch	Tue Dec 20 22:26:25 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,217 +0,0 @@
-commit 9eda90ce8094683a5315007fbd0f9249a284f36f
-Author: Paul Jakma <[email protected]>
-Date:   Thu Aug 30 13:36:17 2007 +0000
-
-    [bgpd] bug #398 Bogus free on out route-map, and assert() with rsclients
-    
-    2007-08-27 Paul Jakma <[email protected]>
-    
-    	* bgp_route.c: (bgp_announce_check) Fix bug #398, slight
-    	  modification of Vladimir Ivanov's suggested fix - to keep
-    	  memory alloc conditional.
-    	  (bgp_process_announce_selected) Don't take struct attr as
-    	  argument, none of the callers need it and it needlessly
-    	  distances allocation from use.
-    	  Free the extended attr, the attr itself is on the stack.
-    	  Fix bad indentation.
-    	* bgp_attr.c: (bgp_packet_attribute) Remove incorrect assert,
-    	  and adjust conditional to test attr->extra, diagnosis by
-    	  Vladimir Ivanov in bug #398.
-    
-    2007-08-27 Vladimir Ivanov <[email protected]>
-    
-    	* bgp_route.c: (bgp_announce_check_rsclient) copy of
-    	  ri->attr is no longer deep enough, due to addition of
-    	  attr->extra. It should use bgp_attr_dup, as
-    	  bgp_announce_check() does.
-
-diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
-index 23d9586..ee17b6d 100644
---- bgpd/bgp_attr.c
-+++ bgpd/bgp_attr.c
-@@ -1625,8 +1625,6 @@
-       && from
-       && peer_sort (from) == BGP_PEER_IBGP)
-     {
--      assert (attr->extra);
--      
-       /* Originator ID. */
-       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
-       stream_putc (s, BGP_ATTR_ORIGINATOR_ID);
-@@ -1641,7 +1639,7 @@
-       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
-       stream_putc (s, BGP_ATTR_CLUSTER_LIST);
-       
--      if (attr->extra->cluster)
-+      if (attr->extra && attr->extra->cluster)
- 	{
- 	  stream_putc (s, attr->extra->cluster->length + 4);
- 	  /* If this peer configuration's parent BGP has cluster_id. */
-diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
-index 0f4da98..9ddeca5 100644
---- bgpd/bgp_route.c
-+++ bgpd/bgp_route.c
-@@ -999,11 +999,10 @@
-       || (ri->extra && ri->extra->suppress) )
-     {
-       struct bgp_info info;
--      struct attr dummy_attr;
-+      struct attr dummy_attr = { 0 };
-       
-       info.peer = peer;
-       info.attr = attr;
--      
- 
-       /* The route reflector is not allowed to modify the attributes
- 	 of the reflected IBGP routes. */
-@@ -1010,9 +1009,8 @@
-       if (peer_sort (from) == BGP_PEER_IBGP 
- 	  && peer_sort (peer) == BGP_PEER_IBGP)
- 	{
--	  dummy_attr.extra = NULL;
- 	  bgp_attr_dup (&dummy_attr, attr);
--	  info.attr = &dummy_attr; 
-+	  info.attr = &dummy_attr;
- 	}
- 
-       SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT); 
-@@ -1024,7 +1022,8 @@
- 
-       peer->rmap_type = 0;
-       
--      bgp_attr_extra_free (&dummy_attr);
-+      if (dummy_attr.extra)
-+        bgp_attr_extra_free (&dummy_attr);
-       
-       if (ret == RMAP_DENYMATCH)
- 	{
-@@ -1127,7 +1126,7 @@
- #endif /* BGP_SEND_ASPATH_CHECK */
- 
-   /* For modify attribute, copy it to temporary structure. */
--  *attr = *ri->attr;
-+  bgp_attr_dup (attr, ri->attr);
- 
-   /* next-hop-set */
-   if ((p->family == AF_INET && attr->nexthop.s_addr == 0)
-@@ -1329,21 +1328,22 @@
- 
- static int
- bgp_process_announce_selected (struct peer *peer, struct bgp_info *selected,
--        struct bgp_node *rn, struct attr *attr, afi_t afi, safi_t safi)
--    {
-+                               struct bgp_node *rn, afi_t afi, safi_t safi)
-+{
-   struct prefix *p;
-+  struct attr attr = { 0 };
- 
-   p = &rn->p;
- 
--      /* Announce route to Established peer. */
--      if (peer->status != Established)
-+  /* Announce route to Established peer. */
-+  if (peer->status != Established)
-     return 0;
- 
--      /* Address family configuration check. */
--      if (! peer->afc_nego[afi][safi])
-+  /* Address family configuration check. */
-+  if (! peer->afc_nego[afi][safi])
-     return 0;
- 
--      /* First update is deferred until ORF or ROUTE-REFRESH is received */
-+  /* First update is deferred until ORF or ROUTE-REFRESH is received */
-   if (CHECK_FLAG (peer->af_sflags[afi][safi],
-       PEER_STATUS_ORF_WAIT_REFRESH))
-     return 0;
-@@ -1353,8 +1353,8 @@
-       case BGP_TABLE_MAIN:
-       /* Announcement to peer->conf.  If the route is filtered,
-          withdraw it. */
--        if (selected && bgp_announce_check (selected, peer, p, attr, afi, safi))
--          bgp_adj_out_set (rn, peer, p, attr, afi, safi, selected);
-+        if (selected && bgp_announce_check (selected, peer, p, &attr, afi, safi))
-+          bgp_adj_out_set (rn, peer, p, &attr, afi, safi, selected);
-         else
-           bgp_adj_out_unset (rn, peer, p, afi, safi);
-         break;
-@@ -1361,13 +1361,16 @@
-       case BGP_TABLE_RSCLIENT:
-         /* Announcement to peer->conf.  If the route is filtered, 
-            withdraw it. */
--        if (selected && bgp_announce_check_rsclient
--              (selected, peer, p, attr, afi, safi))
--          bgp_adj_out_set (rn, peer, p, attr, afi, safi, selected);
--      else
--	bgp_adj_out_unset (rn, peer, p, afi, safi);
-+        if (selected && 
-+            bgp_announce_check_rsclient (selected, peer, p, &attr, afi, safi))
-+          bgp_adj_out_set (rn, peer, p, &attr, afi, safi, selected);
-+        else
-+	  bgp_adj_out_unset (rn, peer, p, afi, safi);
-         break;
-     }
-+  
-+  bgp_attr_extra_free (&attr);
-+  
-   return 0;
- }
- 
-@@ -1417,8 +1420,7 @@
- 	      bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED);
- 	    }
- 
--	  bgp_process_announce_selected (rsclient, new_select, rn, &attr,
--					 afi, safi);
-+	  bgp_process_announce_selected (rsclient, new_select, rn, afi, safi);
- 	}
-     }
-   else
-@@ -1430,8 +1432,7 @@
- 	  bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED);
- 	  bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED);
- 	}
--      bgp_process_announce_selected (rsclient, new_select, rn,
--				     &attr, afi, safi);
-+      bgp_process_announce_selected (rsclient, new_select, rn, afi, safi);
-     }
- 
-   if (old_select && CHECK_FLAG (old_select->flags, BGP_INFO_REMOVED))
-@@ -1457,10 +1458,7 @@
-   struct bgp_info_pair old_and_new;
-   struct listnode *node, *nnode;
-   struct peer *peer;
--  struct attr attr;
-   
--  memset (&attr, 0, sizeof (struct attr));
--  
-   /* Best path selection. */
-   bgp_best_selection (bgp, rn, &old_and_new);
-   old_select = old_and_new.old;
-@@ -1491,7 +1489,7 @@
-   /* Check each BGP peer. */
-   for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
-     {
--      bgp_process_announce_selected (peer, new_select, rn, &attr, afi, safi);
-+      bgp_process_announce_selected (peer, new_select, rn, afi, safi);
-     }
- 
-   /* FIB update. */
-@@ -1516,8 +1514,6 @@
-   if (old_select && CHECK_FLAG (old_select->flags, BGP_INFO_REMOVED))
-     bgp_info_reap (rn, old_select);
-   
--  bgp_attr_extra_free (&attr);
--  
-   UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
-   return WQ_SUCCESS;
- }
-@@ -5888,7 +5884,7 @@
- 	      {
- 		struct route_map *rmap = output_arg;
- 		struct bgp_info binfo;
--		struct attr dummy_attr; 
-+		struct attr dummy_attr = { 0 }; 
- 		int ret;
- 
- 		bgp_attr_dup (&dummy_attr, ri->attr);
--- a/components/quagga/patches/60-bgp-comm-crash.patch	Tue Dec 20 22:26:25 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-Author: Paul Jakma <[email protected]>
-Date:   Fri Sep 7 14:24:55 2007 +0000
-
-    [bgpd] low-impact DoS: crash on malformed community with debug set
-    
-    2007-09-07 Paul Jakma <[email protected]>
-    
-    	* (general) bgpd can be made crash by remote peers if debug
-    	  bgp updates is set, due to NULL pointer dereference.
-    	  Reported by "Mu Security Research Team",
-    	  <[email protected]>.
-    	* bgp_attr.c: (bgp_attr_community) If community length is 0,
-    	  don't set the community-present attribute bit, just return
-    	  early.
-    	* bgp_debug.c: (community_str,community_com2str) Check com
-    	  pointer before dereferencing.
-
---- bgpd/bgp_attr.c
-+++ bgpd/bgp_attr.c
-@@ -962,7 +962,10 @@
- 		    struct attr *attr, u_char flag)
- {
-   if (length == 0)
--    attr->community = NULL;
-+    {
-+      attr->community = NULL;
-+      return 0;
-+    }
-   else
-     {
-       attr->community = 
---- bgpd/bgp_community.c
-+++ bgpd/bgp_community.c
-@@ -206,6 +206,9 @@ community_com2str  (struct community *com)
-   u_int16_t as;
-   u_int16_t val;
- 
-+  if (!com)
-+    return NULL;
-+  
-   /* When communities attribute is empty.  */
-   if (com->size == 0)
-     {
-@@ -377,6 +380,9 @@ community_dup (struct community *com)
- char *
- community_str (struct community *com)
- {
-+  if (!com)
-+    return NULL;
-+  
-   if (! com->str)
-     com->str = community_com2str (com);
-   return com->str;
--- a/components/quagga/patches/65-isisd-iso-checksum.patch	Tue Dec 20 22:26:25 2011 -0800
+++ b/components/quagga/patches/65-isisd-iso-checksum.patch	Tue Jan 03 11:08:59 2012 -0800
@@ -1,488 +1,3 @@
-diff -ur quagga-0.99.8/ChangeLog quagga-unified-checksum/ChangeLog
---- ChangeLog
-+++ ChangeLog
-@@ -1,3 +1,18 @@
-+2008-06-25 Jingjing Duan <[email protected]>
-+	* lib/checksum.[ch]: Add a consolidated checksum function to be
-+	  used by both OSPF and IS-IS. The consolidated version also fixes
-+	  the checksum byte-order checksum on big-endian architectures.
-+	* isisd/iso_checksum.[ch]: Remove the old checksum implementation
-+	  and use the consolidated version.
-+	* isisd/isis_dlpi.c: Change ioctl from PFIOCSETF (transparent mode)
-+	  to I_STR (non-transparent mode). The old code resulted in no
-+	  filtering at all. 
-+	* isisd/isis_dlpi.c: (open_dlpi_dev) Clearview-UV device nodes are
-+	  under /dev/net, try opening there before attempting style 1 or 2
-+	  names.
-+	* ospfd/ospf_lsa.c: Remove the old checksum implementation and
-+	  use the consolidated version.
-+
- 2007-08-07 James Carlson <[email protected]>
- 
- 	* configure.ac: Added support for separate link-layer access
-diff -ur quagga-0.99.8/isisd/isis_dlpi.c quagga-unified-checksum/isisd/isis_dlpi.c
---- isisd/isis_dlpi.c
-+++ isisd/isis_dlpi.c
-@@ -42,8 +42,6 @@
- #include "isisd/isis_circuit.h"
- #include "isisd/isis_flags.h"
- #include "isisd/isisd.h"
--#include "isisd/isis_constants.h"
--#include "isisd/isis_circuit.h"
- #include "isisd/isis_network.h"
- 
- #include "privs.h"
-@@ -315,13 +313,24 @@
- 	circuit->interface->name);
-       return ISIS_WARNING;
-     }
-+  
-+  /* Try the vanity node first, if permitted */
-+  if (getenv("DLPI_DEVONLY") == NULL)
-+    {
-+      (void) snprintf (devpath, sizeof(devpath), "/dev/net/%s",
-+                      circuit->interface->name);
-+      fd = dlpiopen (devpath, &acklen);
-+    }
-+  
-+  /* Now try as an ordinary Style 1 node */
-+  if (fd == -1)
-+    {
-+      (void) snprintf (devpath, sizeof (devpath), "/dev/%s",
-+                      circuit->interface->name);
-+      unit = -1;
-+      fd = dlpiopen (devpath, &acklen);
-+    }
- 
--  /* Try first as Style 1 */
--  (void) snprintf(devpath, sizeof (devpath), "/dev/%s",
--    circuit->interface->name);
--  unit = -1;
--  fd = dlpiopen (devpath, &acklen);
--
-   /* If that fails, try again as Style 2 */
-   if (fd == -1)
-     {
-@@ -452,11 +461,19 @@
-   if (ioctl (fd, I_PUSH, "pfmod") == 0)
-     {
-       struct packetfilt pfil;
-+      struct strioctl sioc;
- 
-       pfil.Pf_Priority = 0;
-       pfil.Pf_FilterLen = sizeof (pf_filter) / sizeof (u_short);
-       memcpy (pfil.Pf_Filter, pf_filter, sizeof (pf_filter));
--      ioctl (fd, PFIOCSETF, &pfil);
-+      /* pfmod does not support transparent ioctls */
-+      sioc.ic_cmd = PFIOCSETF;
-+      sioc.ic_timout = 5;
-+      sioc.ic_len = sizeof (struct packetfilt);
-+      sioc.ic_dp = (char *)&pfil;
-+      if (ioctl (fd, I_STR, &sioc) == -1)
-+         zlog_warn("%s: could not perform PF_IOCSETF on %s",
-+           __func__, circuit->interface->name);
-     }
- 
-   circuit->fd = fd;
-diff -ur quagga-0.99.8/isisd/isis_lsp.c quagga-unified-checksum/isisd/isis_lsp.c
---- isisd/isis_lsp.c
-+++ isisd/isis_lsp.c
-@@ -33,6 +33,7 @@
- #include "command.h"
- #include "hash.h"
- #include "if.h"
-+#include "checksum.h"
- 
- #include "isisd/dict.h"
- #include "isisd/isis_constants.h"
-@@ -45,7 +46,6 @@
- #include "isisd/isis_dynhn.h"
- #include "isisd/isis_misc.h"
- #include "isisd/isis_flags.h"
--#include "isisd/iso_checksum.h"
- #include "isisd/isis_csm.h"
- #include "isisd/isis_adjacency.h"
- #include "isisd/isis_spf.h"
-@@ -314,7 +314,7 @@
-     newseq = seq_num++;
- 
-   lsp->lsp_header->seq_num = htonl (newseq);
--  iso_csum_create (STREAM_DATA (lsp->pdu) + 12,
-+  fletcher_checksum (STREAM_DATA (lsp->pdu) + 12,
- 		   ntohs (lsp->lsp_header->pdu_len) - 12, 12);
- 
-   return;
-@@ -1803,7 +1803,7 @@
-     tlv_add_is_neighs (lsp->tlv_data.es_neighs, lsp->pdu);
- 
-   lsp->lsp_header->pdu_len = htons (stream_get_endp (lsp->pdu));
--  iso_csum_create (STREAM_DATA (lsp->pdu) + 12,
-+  fletcher_checksum (STREAM_DATA (lsp->pdu) + 12,
- 		   ntohs (lsp->lsp_header->pdu_len) - 12, 12);
- 
-   list_delete (adj_list);
-@@ -2071,7 +2071,7 @@
-       lsp->lsp_header->pdu_len =
- 	htons (ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN);
-       lsp->purged = 0;
--      iso_csum_create (STREAM_DATA (lsp->pdu) + 12,
-+      fletcher_checksum (STREAM_DATA (lsp->pdu) + 12,
- 		       ntohs (lsp->lsp_header->pdu_len) - 12, 12);
-       ISIS_FLAGS_SET_ALL (lsp->SRMflags);
-     }
-diff -ur quagga-0.99.8/isisd/isis_pdu.c quagga-unified-checksum/isisd/isis_pdu.c
---- isisd/isis_pdu.c
-+++ isisd/isis_pdu.c
-@@ -32,6 +32,7 @@
- #include "hash.c"
- #include "prefix.h"
- #include "if.h"
-+#include "checksum.h"
- 
- #include "isisd/dict.h"
- #include "isisd/include-netbsd/iso.h"
-@@ -1121,7 +1122,7 @@
- 		  if (isis->debugs & DEBUG_UPDATE_PACKETS)
- 		    zlog_debug ("LSP LEN: %d",
- 				ntohs (lsp->lsp_header->pdu_len));
--		  iso_csum_create (STREAM_DATA (lsp->pdu) + 12,
-+		  fletcher_checksum (STREAM_DATA (lsp->pdu) + 12,
- 				   ntohs (lsp->lsp_header->pdu_len) - 12, 12);
- 		  ISIS_FLAGS_SET_ALL (lsp->SRMflags);
- 		  if (isis->debugs & DEBUG_UPDATE_PACKETS)
-@@ -1164,7 +1165,7 @@
- 	  /* 7.3.16.1  */
- 	  lsp->lsp_header->seq_num = htonl (ntohl (hdr->seq_num) + 1);
- 
--	  iso_csum_create (STREAM_DATA (lsp->pdu) + 12,
-+	  fletcher_checksum (STREAM_DATA (lsp->pdu) + 12,
- 			   ntohs (lsp->lsp_header->pdu_len) - 12, 12);
- 
- 	  ISIS_FLAGS_SET_ALL (lsp->SRMflags);
-diff -ur quagga-0.99.8/isisd/iso_checksum.c quagga-unified-checksum/isisd/iso_checksum.c
---- isisd/iso_checksum.c
-+++ isisd/iso_checksum.c
-@@ -23,6 +23,7 @@
- 
- #include <zebra.h>
- #include "iso_checksum.h"
-+#include "checksum.h"
- 
- /*
-  * Calculations of the OSI checksum.
-@@ -47,14 +48,10 @@
- int
- iso_csum_verify (u_char * buffer, int len, uint16_t * csum)
- {
--  u_int8_t *p;
-+  u_int16_t checksum;
-   u_int32_t c0;
-   u_int32_t c1;
--  u_int16_t checksum;
--  int i, partial_len;
- 
--  p = buffer;
--  checksum = 0;
-   c0 = *csum & 0xff00;
-   c1 = *csum & 0x00ff;
- 
-@@ -70,124 +69,8 @@
-   if (c0 == 0 || c1 == 0)
-     return 1;
- 
--  /*
--   * Otherwise initialize to zero and calculate...
--   */
--  c0 = 0;
--  c1 = 0;
--
--  while (len)
--    {
--      partial_len = MIN(len, 5803);
--
--      for (i = 0; i < partial_len; i++)
--	{
--	  c0 = c0 + *(p++);
--	  c1 += c0;
--	}
--
--      c0 = c0 % 255;
--      c1 = c1 % 255;
--
--      len -= partial_len;
--    }
--
--  if (c0 == 0 && c1 == 0)
--    return 0;
--
-+  checksum = fletcher_checksum(buffer, len, (u_char *)csum - buffer);
-+  if (checksum == *csum)
-+      return 0;
-   return 1;
- }
--
--/*
-- * Creates the checksum. *csum points to the position of the checksum in the 
-- * PDU. 
-- * Based on Annex C.4 of ISO/IEC 8473
-- */
--#define FIXED_CODE
--u_int16_t
--iso_csum_create (u_char * buffer, int len, u_int16_t n)
--{
--
--  u_int8_t *p;
--  int x;
--  int y;
--  u_int32_t mul;
--  u_int32_t c0;
--  u_int32_t c1;
--  u_int16_t checksum;
--  u_int16_t *csum;
--  int i, init_len, partial_len;
--
--  checksum = 0;
--
--  /*
--   * Zero the csum in the packet.
--   */
--  csum = (u_int16_t *) (buffer + n);
--  *(csum) = checksum;
--
--  p = buffer;
--  c0 = 0;
--  c1 = 0;
--  init_len = len;
--
--  while (len != 0)
--    {
--      partial_len = MIN(len, 5803);
--
--      for (i = 0; i < partial_len; i++)
--	{
--	  c0 = c0 + *(p++);
--	  c1 += c0;
--	}
--
--      c0 = c0 % 255;
--      c1 = c1 % 255;
--
--      len -= partial_len;
--    }
--
--  mul = (init_len - n)*(c0);
--
--#ifdef FIXED_CODE
--  x = mul - c0 - c1;
--  y = c1 - mul - 1;
--
--  if (y > 0)
--    y++;
--  if (x < 0)
--    x--;
--
--  x %= 255;
--  y %= 255;
--
--  if (x == 0)
--    x = 255;
--  if (y == 0)
--    y = 1;
--
--  checksum = (y << 8) | (x & 0xFF);
--
--#else
--  x = mul - c0 - c1;
--  x %= 255;
--
--  y = c1 - mul - 1;
--  y %= 255;
--
--  if (x == 0)
--    x = 255;
--  if (y == 0)
--    y = 255;
--
--  checksum = ((y << 8) | x);
--#endif
--
--  /*
--   * Now we write this to the packet
--   */
--  *(csum) = checksum;
--
--  /* return the checksum for user usage */
--  return checksum;
--}
-diff -ur quagga-0.99.8/isisd/iso_checksum.h quagga-unified-checksum/isisd/iso_checksum.h
---- isisd/iso_checksum.h
-+++ isisd/iso_checksum.h
-@@ -24,6 +24,5 @@
- #define _ZEBRA_ISO_CSUM_H
- 
- int iso_csum_verify (u_char * buffer, int len, uint16_t * csum);
--u_int16_t iso_csum_create (u_char * buffer, int len, u_int16_t n);
- 
- #endif /* _ZEBRA_ISO_CSUM_H */
-diff -ur quagga-0.99.8/lib/checksum.c quagga-unified-checksum/lib/checksum.c
---- lib/checksum.c
-+++ lib/checksum.c
-@@ -45,3 +45,82 @@
- 	answer = ~sum;		/* ones-complement, then truncate to 16 bits */
- 	return(answer);
- }
-+
-+/* Fletcher Checksum -- Refer to RFC1008. */
-+#define MODX                 4102   /* 5802 should be fine */
-+
-+/* To be consistent, offset is 0-based index, rather than the 1-based 
-+   index required in the specification ISO 8473, Annex C.1 */
-+u_int16_t
-+fletcher_checksum(u_char * buffer, int len, u_int16_t offset)
-+{
-+  u_int8_t *p;
-+  int x;
-+  int y;
-+  u_int32_t mul;
-+  u_int32_t c0;
-+  u_int32_t c1;
-+  u_int16_t checksum;
-+  u_int16_t *csum;
-+  int i, init_len, partial_len;
-+
-+  checksum = 0;
-+
-+  /*
-+   * Zero the csum in the packet.
-+   */
-+  csum = (u_int16_t *) (buffer + offset);
-+  *(csum) = checksum;
-+
-+  p = buffer;
-+  c0 = 0;
-+  c1 = 0;
-+  init_len = len;
-+
-+  while (len != 0)
-+    {
-+      partial_len = MIN(len, MODX);
-+
-+      for (i = 0; i < partial_len; i++)
-+	{
-+	  c0 = c0 + *(p++);
-+	  c1 += c0;
-+	}
-+
-+      c0 = c0 % 255;
-+      c1 = c1 % 255;
-+
-+      len -= partial_len;
-+    }
-+
-+  mul = (init_len - offset)*(c0);
-+
-+  x = mul - c0 - c1;
-+  y = c1 - mul - 1;
-+
-+  if (y > 0)
-+    y++;
-+  if (x < 0)
-+    x--;
-+
-+  x %= 255;
-+  y %= 255;
-+
-+  if (x == 0)
-+    x = 255;
-+  if (y == 0)
-+    y = 1;
-+
-+  /*
-+   * Now we write this to the packet.
-+   * We could skip this step too, since the checksum returned would
-+   * be stored into the checksum field by the caller.
-+   */
-+  buffer[offset] = x;
-+  buffer[offset + 1] = y;
-+
-+  /* Take care of the endian issue */
-+  checksum = htons((x << 8) | (y & 0xFF));
-+
-+  return checksum;
-+}
-diff -ur quagga-0.99.8/lib/checksum.h quagga-unified-checksum/lib/checksum.h
---- lib/checksum.h
-+++ lib/checksum.h
-@@ -1 +1,2 @@
- extern int in_cksum(void *, int);
-+extern u_int16_t fletcher_checksum(u_char * buffer, int len, u_int16_t offset);
-diff -ur quagga-0.99.8/ospfd/ospf_lsa.c quagga-unified-checksum/ospfd/ospf_lsa.c
---- ospfd/ospf_lsa.c
-+++ ospfd/ospf_lsa.c
-@@ -32,6 +32,7 @@
- #include "thread.h"
- #include "hash.h"
- #include "sockunion.h"		/* for inet_aton() */
-+#include "checksum.h"
- 
- #include "ospfd/ospfd.h"
- #include "ospfd/ospf_interface.h"
-@@ -172,46 +173,22 @@
- 
- 
- /* Fletcher Checksum -- Refer to RFC1008. */
--#define MODX                 4102
--#define LSA_CHECKSUM_OFFSET    15
- 
-+/* All the offsets are zero-based. The offsets in the RFC1008 are 
-+   one-based. */
- u_int16_t
- ospf_lsa_checksum (struct lsa_header *lsa)
- {
--  u_char *sp, *ep, *p, *q;
--  int c0 = 0, c1 = 0;
--  int x, y;
--  u_int16_t length;
--
--  lsa->checksum = 0;
--  length = ntohs (lsa->length) - 2;
--  sp = (u_char *) &lsa->options;
--
--  for (ep = sp + length; sp < ep; sp = q)
--    {
--      q = sp + MODX;
--      if (q > ep)
--        q = ep;
--      for (p = sp; p < q; p++)
--        {
--          c0 += *p;
--          c1 += c0;
--        }
--      c0 %= 255;
--      c1 %= 255;
--    }
-+  u_char *buffer = (u_char *) &lsa->options;
-+  int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
- 
--  x = (((int)length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
--  if (x <= 0)
--    x += 255;
--  y = 510 - c0 - x;
--  if (y > 255)
--    y -= 255;
-+  /* Skip the AGE field */
-+  u_int16_t len = ntohs(lsa->length) - options_offset; 
- 
--  /* take care endian issue. */
--  lsa->checksum = htons ((x << 8) + y);
-+  /* Checksum offset starts from "options" field, not the beginning of the
-+     lsa_header struct. The offset is 14, rather than 16. */
- 
--  return (lsa->checksum);
-+  return fletcher_checksum(buffer, len, (u_char *) &lsa->checksum - buffer);
- }
- 
- 
 diff -ur quagga-0.99.8/solaris/quagga.init.in quagga-unified-checksum/solaris/quagga.init.in
 --- solaris/quagga.init.in
 +++ solaris/quagga.init.in
@@ -495,24 +10,6 @@
  		quagga_is_globalzone || exit $SMF_EXIT_OK
  	;;
  	*)
-@@ -168,7 +168,7 @@
- 	eval exec $DAEMON_PATH/$DAEMON $DAEMON_ARGS --pid_file ${PIDFILE} &
- }
- 
--stop () {
-+daemonstop () {
- 	if [ -f "${PIDFILE}" ]; then
- 		/usr/bin/kill -TERM `/usr/bin/cat "${PIDFILE}"`
- 	fi
-@@ -179,7 +179,7 @@
- 	start
- 	;;
- 'stop')
--	stop
-+	daemonstop
- 	;;
- 
- *)
 diff -ur quagga-0.99.8/solaris/quagga.xml.in quagga-unified-checksum/solaris/quagga.xml.in
 --- solaris/quagga.xml.in
 +++ solaris/quagga.xml.in
@@ -525,7 +22,7 @@
  	<dependency
  		name='zebra'
  		grouping='optional_all'
-@@ -818,6 +818,148 @@
+@@ -812,6 +812,148 @@
  			<manpage title='bgpd' section='1M'
  				manpath='@mandir@' />
  			<doc_link name='quagga.net' 
@@ -576,7 +73,7 @@
 +		<service_fmri value='svc:/network/routing-setup' />
 +	</dependency>
 +
-+	<!-- ensure that restart of zebra is propogated to daemon -->
++	<!-- ensure that restart of zebra is propagated to daemon -->
 +	<dependency
 +		name='zebra'
 +		grouping='optional_all'
@@ -592,7 +89,7 @@
 +		timeout_seconds='60'>
 +		<method_context>
 +		  <method_credential
-+		   user='root' group='root'/>
++		   user='root' group='root' />
 + 		</method_context>
 +	</exec_method>
 +
@@ -623,8 +120,8 @@
 +			value='solaris.smf.value.routing' />
 +		<property name='protocol' type='astring'>
 +			<astring_list>
-+				<value_node value='ipv4'/>
-+				<value_node value='ipv6'/>
++				<value_node value='ipv4' />
++				<value_node value='ipv6' />
 +			</astring_list>
 +		</property>
 +	</property_group>
@@ -636,7 +133,7 @@
 +
 +		<!-- Options common to Quagga daemons -->
 +		<!-- The config file to use, if not the default -->
-+		<propval name='config_file' type='astring' value=''/>
++		<propval name='config_file' type='astring' value='' />
 +		<!-- The vty_port to listen on if not the default.
 +		     0 to disable --> 
 +		<propval name='vty_port' type='integer' value='0' />
--- a/components/quagga/patches/70-isisd-trill.patch	Tue Dec 20 22:26:25 2011 -0800
+++ b/components/quagga/patches/70-isisd-trill.patch	Tue Jan 03 11:08:59 2012 -0800
@@ -1,19 +1,16 @@
 diff --git configure.ac configure.ac
-index 78198cb..12e9729 100755
 --- configure.ac
 +++ configure.ac
-@@ -197,6 +197,10 @@ AC_ARG_ENABLE(watchquagga,
+@@ -202,6 +202,8 @@
  [  --disable-watchquagga   do not build watchquagga])
  AC_ARG_ENABLE(isisd,
  [  --enable-isisd          build isisd])
 +AC_ARG_ENABLE(trill,
-+[  --enable-trill          include TRILL support])
-+AC_ARG_ENABLE(solaris,
-+[  --enable-solaris          build solaris])
++[  --enable-trill          include trill support])
+ AC_ARG_ENABLE(solaris,
+ [  --enable-solaris          build solaris])
  AC_ARG_ENABLE(bgp-announce,
- [  --disable-bgp-announce, turn off BGP route announcement])
- AC_ARG_ENABLE(netlink,
-@@ -311,6 +315,30 @@ AC_SUBST(ISIS_TOPOLOGY_INCLUDES)
+@@ -328,6 +330,30 @@
  AC_SUBST(ISIS_TOPOLOGY_DIR)
  AC_SUBST(ISIS_TOPOLOGY_LIB)
  
@@ -44,19 +41,19 @@
  if test "${enable_user}" = "yes" || test x"${enable_user}" = x""; then
    enable_user="quagga"
  elif test "${enable_user}" = "no"; then
-@@ -753,28 +781,31 @@ AC_SUBST(OTHER_METHOD)
- dnl --------------------------
- dnl Determine IS-IS I/O method
- dnl --------------------------
+@@ -785,28 +811,31 @@
+ AC_DEFINE(ISIS_METHOD_PFPACKET,	1, [ constant value for isis method pfpacket ])
+ AC_DEFINE(ISIS_METHOD_DLPI,	2, [ constant value for isis method dlpi ])
+ AC_DEFINE(ISIS_METHOD_BPF,	3, [ constant value for isis method bpf ])
 -AC_CHECK_HEADER(net/bpf.h)
 -AC_CHECK_HEADER(sys/dlpi.h)
 -AC_MSG_CHECKING(zebra IS-IS I/O method)
 -if test x"$opsys" = x"gnu-linux"; then
 -  AC_MSG_RESULT(pfpacket)
--  ISIS_METHOD=isis_pfpacket.o
+-  ISIS_METHOD_MACRO="ISIS_METHOD_PFPACKET"
 -elif test x"$opsys" = x"sol2-6" -o x"$opsys" = x"sol8"; then
 -  AC_MSG_RESULT(DLPI)
--  ISIS_METHOD="isis_dlpi.o"
+-  ISIS_METHOD_MACRO="ISIS_METHOD_DLPI"
 -else
 -  if test $ac_cv_header_net_bpf_h = no; then
 -    if test $ac_cv_header_sys_dlpi_h = no; then
@@ -67,54 +64,58 @@
 -      AC_MSG_RESULT(DLPI)
 -    fi
 +if test "${enable_isisd}" = "yes"; then
-+  ISIS_METHOD=
++  ISIS_METHOD_MACRO=
 +  AC_CHECK_HEADER(net/bpf.h)
 +  AC_CHECK_HEADER(sys/dlpi.h)
 +  AC_MSG_CHECKING(zebra IS-IS I/O method)
 +  if test x"$opsys" = x"gnu-linux"; then
 +    AC_MSG_RESULT(pfpacket)
-+    ISIS_METHOD=isis_pfpacket.o
++    ISIS_METHOD_MACRO="ISIS_METHOD_PFPACKET"
 +  elif test x"$opsys" = x"sol2-6" -o x"$opsys" = x"sol8"; then
 +    AC_MSG_RESULT(DLPI)
-     ISIS_METHOD="isis_dlpi.o"
+     ISIS_METHOD_MACRO="ISIS_METHOD_DLPI"
    else
 -    AC_MSG_RESULT(BPF)
--    ISIS_METHOD="isis_bpf.o"
+-    ISIS_METHOD_MACRO="ISIS_METHOD_BPF"
 +    if test $ac_cv_header_net_bpf_h = no; then
 +      if test $ac_cv_header_sys_dlpi_h = no; then
-+	AC_MSG_RESULT(none)
-+	AC_MSG_WARN([*** IS-IS support will not be built ***])
-+	ISISD=""
++        AC_MSG_RESULT(none)
++        AC_MSG_WARN([*** IS-IS support will not be built ***])
++        ISISD=""
 +      else
-+	AC_MSG_RESULT(DLPI)
++        AC_MSG_RESULT(DLPI)
 +      fi
-+      ISIS_METHOD="isis_dlpi.o"
++      ISIS_METHOD_MACRO="ISIS_METHOD_DLPI"
 +    else
 +      AC_MSG_RESULT(BPF)
-+      ISIS_METHOD="isis_bpf.o"
++      ISIS_METHOD_MACRO="ISIS_METHOD_BPF"
 +    fi
    fi
  fi
- AC_SUBST(ISIS_METHOD)
+ AC_DEFINE_UNQUOTED(ISIS_METHOD, $ISIS_METHOD_MACRO, [ selected method for isis, == one of the constants ])
 diff --git isisd/Makefile.am isisd/Makefile.am
 index 859facd..9adcc05 100644
 --- isisd/Makefile.am
 +++ isisd/Makefile.am
-@@ -4,10 +4,11 @@ INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib \
+@@ -4,14 +4,15 @@
  	   @ISIS_TOPOLOGY_INCLUDES@
  DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
  INSTALL_SDATA=@INSTALL@ -m 600
 -LIBS = @LIBS@ 
 +LIBS = @LIBS@ @ISIS_LIBS@
+ 
+ AM_CFLAGS = $(PICFLAGS)
+ AM_LDFLAGS = $(PILDFLAGS)
+ 
  noinst_LIBRARIES = libisis.a
 -sbin_PROGRAMS = isisd 
 +sbin_PROGRAMS = @ISIS_TARGETS@
  SUBDIRS = topology
 +EXTRA_PROGRAMS = isisd trilld
  
- isis_method = @ISIS_METHOD@
- 
-@@ -23,16 +24,24 @@ noinst_HEADERS = \
+ libisis_a_SOURCES = \
+ 	isis_adjacency.c isis_lsp.c dict.c isis_circuit.c isis_pdu.c \
+@@ -25,13 +26,23 @@
  	isis_lsp.h dict.h isis_circuit.h isis_misc.h isis_network.h \
  	isis_zebra.h isis_dr.h isis_flags.h isis_dynhn.h isis_common.h \
  	iso_checksum.h isis_csm.h isis_events.h isis_spf.h isis_route.h \
@@ -122,15 +123,13 @@
  	include-netbsd/clnp.h include-netbsd/esis.h include-netbsd/iso.h
  
  isisd_SOURCES = \
--	isis_main.c $(libisis_a_SOURCES)
-+	isis_main.c $(libisis_a_SOURCES) isis_trilldummy.c
- 
--isisd_LDADD = $(isis_method) @ISIS_TOPOLOGY_LIB@ ../lib/libzebra.la @LIBCAP@
-+isisd_LDADD = $(isis_method) @ISIS_TOPOLOGY_LIB@ ../lib/libzebra.la @LIBCAP@ @LIBM@
- 
- isisd_DEPENDENCIES = $(isis_method)
- 
--EXTRA_DIST = isis_bpf.c isis_dlpi.c isis_pfpacket.c
+ 	isis_main.c $(libisis_a_SOURCES) \
+-	isis_bpf.c isis_dlpi.c isis_pfpacket.c
++	isis_bpf.c isis_dlpi.c isis_pfpacket.c isis_trilldummy.c
+ 
+-isisd_LDADD = @ISIS_TOPOLOGY_LIB@ ../lib/libzebra.la @LIBCAP@
++isisd_LDADD = @ISIS_TOPOLOGY_LIB@ ../lib/libzebra.la @LIBCAP@ @LIBM@
+ 
 +trilld_SOURCES = \
 +	isis_main.c $(libisis_a_SOURCES) isis_trill.c isis_trillio.c \
 +	isis_trillvlans.c isis_trillbpdu.c
@@ -139,7 +138,7 @@
 +
 +EXTRA_DIST = isis_bpf.c isis_dlpi.c isis_pfpacket.c isis_trill.c \
 +	isis_trillio.c isis_trillvlans.c isis_trillbpdu.c
- 
++
  examplesdir = $(exampledir)
  dist_examples_DATA = isisd.conf.sample
 diff --git isisd/bool.h isisd/bool.h
@@ -598,16 +597,15 @@
 index 07ab547..5837201 100644
 --- isisd/isis_dlpi.c
 +++ isisd/isis_dlpi.c
-@@ -21,6 +21,8 @@
+@@ -21,6 +21,7 @@
   */
  
  #include <zebra.h>
 +#include <vty.h>
-+
+ #if ISIS_METHOD == ISIS_METHOD_DLPI
  #include <net/if.h>
  #include <netinet/if_ether.h>
- #include <sys/types.h>
-@@ -301,7 +303,7 @@ dlpiaddr (int fd, u_char *addr)
+@@ -302,7 +303,7 @@
  static int
  open_dlpi_dev (struct isis_circuit *circuit)
  {
@@ -616,7 +614,7 @@
    char devpath[MAXPATHLEN];
    dl_info_ack_t *dia = (dl_info_ack_t *)dlpi_ctl;
    ssize_t acklen;
-@@ -313,20 +315,21 @@ open_dlpi_dev (struct isis_circuit *circuit)
+@@ -314,20 +315,21 @@
  	circuit->interface->name);
        return ISIS_WARNING;
      }
@@ -645,7 +643,7 @@
        unit = -1;
        fd = dlpiopen (devpath, &acklen);
      }
-@@ -402,8 +405,8 @@ open_dlpi_dev (struct isis_circuit *circuit)
+@@ -403,8 +405,8 @@
      case DL_100BT:
        break;
      default:
@@ -656,18 +654,6 @@
        close (fd);
        return ISIS_WARNING;
      }
-@@ -471,9 +474,9 @@ open_dlpi_dev (struct isis_circuit *circuit)
-       sioc.ic_timout = 5;
-       sioc.ic_len = sizeof (struct packetfilt);
-       sioc.ic_dp = (char *)&pfil;
--      if (ioctl (fd, I_STR, &sioc) == -1)
-+      if (ioctl (fd, I_STR, &sioc) == -1) 
-          zlog_warn("%s: could not perform PF_IOCSETF on %s",
--           __func__, circuit->interface->name);
-+   	    __func__, circuit->interface->name);
-     }
- 
-   circuit->fd = fd;
 diff --git isisd/isis_dr.c isisd/isis_dr.c
 index 8d306c8..a481142 100644
 --- isisd/isis_dr.c
@@ -1087,7 +1073,7 @@
  };
  
  struct zebra_privs_t isisd_privs = {
-@@ -66,7 +78,7 @@ struct zebra_privs_t isisd_privs = {
+@@ -66,7 +78,7 @@
    .vty_group = VTY_GROUP,
  #endif
    .caps_p = _caps_p,
@@ -1096,7 +1082,7 @@
    .cap_num_i = 0
  };
  
-@@ -151,7 +163,10 @@ reload ()
+@@ -151,7 +163,10 @@
    zlog_debug ("Reload");
    /* FIXME: Clean up func call here */
    vty_reset ();
@@ -1107,7 +1093,7 @@
  }
  
  static void
-@@ -168,6 +183,9 @@ void
+@@ -168,6 +183,9 @@
  sighup (void)
  {
    zlog_debug ("SIGHUP received");
@@ -1117,7 +1103,7 @@
    reload ();
  
    return;
-@@ -227,6 +245,11 @@ main (int argc, char **argv, char **envp)
+@@ -227,6 +245,11 @@
    char *vty_addr = NULL;
    int dryrun = 0;
  
@@ -1129,7 +1115,7 @@
    /* Get the programname without the preceding path. */
    progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
  
-@@ -319,6 +342,22 @@ main (int argc, char **argv, char **envp)
+@@ -319,6 +342,22 @@
    memory_init ();
    access_list_init();
    isis_init ();
@@ -1152,8 +1138,8 @@
    dyn_cache_init ();
    sort_node ();
  
-@@ -337,7 +376,8 @@ main (int argc, char **argv, char **envp)
-     daemon (0, 0);
+@@ -340,7 +379,8 @@
+     }
  
    /* Process ID file creation. */
 -  pid_output (pid_file);
@@ -7907,60 +7893,11 @@
 +#endif
  
  #endif /* ISISD_H */
-diff --git lib/command.c lib/command.c
-index 270bf0d..2c8d752 100644
---- lib/command.c
-+++ lib/command.c
-@@ -193,8 +193,8 @@ install_node (struct cmd_node *node,
- static int
- cmp_node (const void *p, const void *q)
- {
--  const struct cmd_element *a = *(struct cmd_element **)p;
--  const struct cmd_element *b = *(struct cmd_element **)q;
-+  const struct cmd_element *a = *(struct cmd_element * const *)p;
-+  const struct cmd_element *b = *(struct cmd_element * const *)q;
- 
-   return strcmp (a->string, b->string);
- }
-@@ -202,8 +202,8 @@ cmp_node (const void *p, const void *q)
- static int
- cmp_desc (const void *p, const void *q)
- {
--  const struct desc *a = *(struct desc **)p;
--  const struct desc *b = *(struct desc **)q;
-+  const struct desc *a = *(struct desc * const *)p;
-+  const struct desc *b = *(struct desc * const *)q;
- 
-   return strcmp (a->cmd, b->cmd);
- }
-@@ -491,8 +491,11 @@ install_element (enum node_type ntype, struct cmd_element *cmd)
- 
-   vector_set (cnode->cmd_vector, cmd);
- 
--  cmd->strvec = cmd_make_descvec (cmd->string, cmd->doc);
--  cmd->cmdsize = cmd_cmdsize (cmd->strvec);
-+  if (cmd->strvec == NULL)
-+    {
-+      cmd->strvec = cmd_make_descvec (cmd->string, cmd->doc);
-+      cmd->cmdsize = cmd_cmdsize (cmd->strvec);
-+    }
- }
- 
- static unsigned char itoa64[] =	
-@@ -3497,6 +3500,8 @@ DEFUN (no_banner_motd,
- void
- host_config_set (char *filename)
- {
-+  if (host.config != NULL)
-+    XFREE (MTYPE_HOST, host.config);
-   host.config = XSTRDUP (MTYPE_HOST, filename);
- }
- 
 diff --git lib/command.h lib/command.h
 index a725378..fefa6d3 100644
 --- lib/command.h
 +++ lib/command.h
-@@ -302,6 +302,8 @@ struct desc
+@@ -303,6 +303,8 @@
  #define OSPF6_DUMP_TYPE_LIST \
  "(neighbor|interface|area|lsa|zebra|config|dbex|spf|route|lsdb|redistribute|hook|asbr|prefix|abr)"
  #define ISIS_STR "IS-IS information\n"
@@ -7969,98 +7906,11 @@
  #define AREA_TAG_STR "[area tag]\n"
  
  #define CONF_BACKUP_EXT ".sav"
-@@ -359,5 +361,5 @@ extern void host_config_set (char *);
- extern void print_version (const char *);
- 
- /* struct host global, ick */
--extern struct host host; 
-+extern struct host host;
- #endif /* _ZEBRA_COMMAND_H */
-diff --git lib/linklist.c lib/linklist.c
-index 11e16a8..a16e9e1 100644
---- lib/linklist.c
-+++ lib/linklist.c
-@@ -65,7 +65,9 @@ void
- listnode_add (struct list *list, void *val)
- {
-   struct listnode *node;
--
-+  
-+  assert (val != NULL);
-+  
-   node = listnode_new ();
- 
-   node->prev = list->tail;
-@@ -91,7 +93,9 @@ listnode_add_sort (struct list *list, void *val)
- {
-   struct listnode *n;
-   struct listnode *new;
--
-+  
-+  assert (val != NULL);
-+  
-   new = listnode_new ();
-   new->data = val;
- 
-@@ -130,7 +134,9 @@ void
- listnode_add_after (struct list *list, struct listnode *pp, void *val)
- {
-   struct listnode *nn;
--
-+  
-+  assert (val != NULL);
-+  
-   nn = listnode_new ();
-   nn->data = val;
- 
-@@ -158,6 +164,7 @@ listnode_add_after (struct list *list, struct listnode *pp, void *val)
- 
-       pp->next = nn;
-     }
-+  list->count++;
- }
- 
- 
-@@ -265,7 +272,9 @@ void
- list_add_node_prev (struct list *list, struct listnode *current, void *val)
- {
-   struct listnode *node;
--
-+  
-+  assert (val != NULL);
-+  
-   node = listnode_new ();
-   node->next = current;
-   node->data = val;
-@@ -286,7 +295,9 @@ void
- list_add_node_next (struct list *list, struct listnode *current, void *val)
- {
-   struct listnode *node;
--
-+  
-+  assert (val != NULL);
-+  
-   node = listnode_new ();
-   node->prev = current;
-   node->data = val;
-diff --git lib/memory.c lib/memory.c
-index eb67072..9ed5e10 100644
---- lib/memory.c
-+++ lib/memory.c
-@@ -501,7 +501,7 @@ mtype_memstr (char *buf, size_t len, unsigned long bytes)
-        * Just hacked to make it not warn on 'smaller' machines. 
-        * Static compiler analysis should mean no extra code
-        */
--      if (bytes & (1 << (sizeof (unsigned long) >= 8 ? 39 : 0)))
-+      if (bytes & (1UL << (sizeof (unsigned long) >= 8 ? 39 : 0)))
-         t++;
-       snprintf (buf, len, "%4d TiB", t);
-     }
 diff --git lib/memtypes.c lib/memtypes.c
 index c7028c9..476ad35 100644
 --- lib/memtypes.c
 +++ lib/memtypes.c
-@@ -225,20 +225,32 @@ struct memory_list memory_list_ospf6[] =
+@@ -228,20 +228,32 @@
  
  struct memory_list memory_list_isis[] =
  {
@@ -8107,12 +7957,12 @@
    { -1, NULL },
  };
  
-diff --git lib/memtypes.h lib/memtypes.h
+diff --git lib/memtypes.h /dev/null
 deleted file mode 100644
 index 2d90e80..0000000
 --- lib/memtypes.h
 +++ /dev/null
-@@ -1,206 +0,0 @@
+@@ -1,209 +0,0 @@
 -/* Auto-generated from memtypes.c by gawk. */
 -/* Do not edit! */
 -
@@ -8188,10 +8038,12 @@
 -  MTYPE_STATIC_IPV4,
 -  MTYPE_STATIC_IPV6,
 -  MTYPE_BGP,
+-  MTYPE_BGP_LISTENER,
 -  MTYPE_BGP_PEER,
 -  MTYPE_BGP_PEER_HOST,
 -  MTYPE_PEER_GROUP,
 -  MTYPE_PEER_DESC,
+-  MTYPE_PEER_PASSWORD,
 -  MTYPE_ATTR,
 -  MTYPE_ATTR_EXTRA,
 -  MTYPE_AS_PATH,
@@ -8202,6 +8054,7 @@
 -  MTYPE_BGP_NODE,
 -  MTYPE_BGP_ROUTE,
 -  MTYPE_BGP_ROUTE_EXTRA,
+-  MTYPE_BGP_CONN,
 -  MTYPE_BGP_STATIC,
 -  MTYPE_BGP_ADVERTISE_ATTR,
 -  MTYPE_BGP_ADVERTISE,
@@ -8384,12 +8237,12 @@
 index acccbdb..3520bc5 100644
 --- solaris/Makefile.am
 +++ solaris/Makefile.am
-@@ -12,7 +12,7 @@ pkg_depends := $(pkg_names:%=depend.%)
- pkg_packages := $(pkg_names:%=@PACKAGE_TARNAME@-%-$(pkg_name_rev).pkg)
- pkg_pkginfos := $(pkg_names:%=pkginfo.%.full)
- pkg_prototypes := $(pkg_names:%=prototype.%)
--pkg_manifests := quagga.xml
-+pkg_manifests := quagga.xml trill.xml
+@@ -14,7 +14,7 @@
+ pkg_packages = $(pkg_names:%=@PACKAGE_TARNAME@-%-$(pkg_name_rev).pkg)
+ pkg_pkginfos = $(pkg_names:%=pkginfo.%.full)
+ pkg_prototypes = $(pkg_names:%=prototype.%)
+-pkg_manifests = quagga.xml
++pkg_manifests = quagga.xml trill.xml
  
  # pkgmk variable substitutions wont grok ${variable} in prototype
  # file, so we cant let autoconf generate the file sadly
@@ -8458,7 +8311,7 @@
 +		timeout_seconds='60'>
 +		<method_context>
 +		  <method_credential
-+		   user='root' group='root'/>
++		   user='root' group='root' />
 + 		</method_context>
 +	</exec_method>
 +
--- a/components/quagga/patches/80-ripngd-getopt.patch	Tue Dec 20 22:26:25 2011 -0800
+++ b/components/quagga/patches/80-ripngd-getopt.patch	Tue Jan 03 11:08:59 2012 -0800
@@ -1,19 +1,11 @@
 *** ripngd/ripng_main.c
 --- ripngd/ripng_main.c
-***************
-*** 207,213 ****
-      {
-        int opt;
-  
-!       opt = getopt_long (argc, argv, "dlf:i:hA:P:u:g:vC", longopts, 0);
-      
-        if (opt == EOF)
-  	break;
---- 207,213 ----
-      {
-        int opt;
-  
-!       opt = getopt_long (argc, argv, "dlf:i:hA:P:ru:g:vC", longopts, 0);
-      
-        if (opt == EOF)
-  	break;
+@@ -205,7 +205,7 @@
+     {
+       int opt;
+ 
+-      opt = getopt_long (argc, argv, "df:i:hA:P:u:g:vC", longopts, 0);
++      opt = getopt_long (argc, argv, "df:i:hA:P:ru:g:vC", longopts, 0);
+     
+       if (opt == EOF)
+ 	break;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/quagga/patches/95-noautomake.patch	Tue Jan 03 11:08:59 2012 -0800
@@ -0,0 +1,351 @@
+diff -r -u Makefile.in Makefile.in
+--- Makefile.in
++++ Makefile.in
+@@ -147,6 +147,8 @@
+ IOCTL_METHOD = @IOCTL_METHOD@
+ IPFORWARD = @IPFORWARD@
+ ISISD = @ISISD@
++ISIS_LIBS = @ISIS_LIBS@
++ISIS_TARGETS = @ISIS_TARGETS@
+ ISIS_TOPOLOGY_DIR = @ISIS_TOPOLOGY_DIR@
+ ISIS_TOPOLOGY_INCLUDES = @ISIS_TOPOLOGY_INCLUDES@
+ ISIS_TOPOLOGY_LIB = @ISIS_TOPOLOGY_LIB@
+diff -r -u config.h.in config.h.in
+--- config.h.in
++++ config.h.in
+@@ -512,6 +512,9 @@
+ /* Define to 1 if you have the <time.h> header file. */
+ #undef HAVE_TIME_H
+ 
++/* Enable TRILL support */
++#undef HAVE_TRILL
++
+ /* Define to 1 if you have the <ucontext.h> header file. */
+ #undef HAVE_UCONTEXT_H
+ 
+diff -r -u configure configure
+--- configure
++++ configure
+@@ -658,6 +658,8 @@
+ enable_vty_group
+ enable_group
+ enable_user
++ISIS_LIBS
++ISIS_TARGETS
+ ISIS_TOPOLOGY_LIB
+ ISIS_TOPOLOGY_DIR
+ ISIS_TOPOLOGY_INCLUDES
+@@ -801,6 +803,7 @@
+ enable_ospf6d
+ enable_watchquagga
+ enable_isisd
++enable_trill
+ enable_solaris
+ enable_bgp_announce
+ enable_netlink
+@@ -1482,6 +1485,7 @@
+   --disable-ospf6d        do not build ospf6d
+   --disable-watchquagga   do not build watchquagga
+   --enable-isisd          build isisd
++  --enable-trill          include trill support
+   --enable-solaris          build solaris
+   --disable-bgp-announce, turn off BGP route announcement
+   --enable-netlink        force to use Linux netlink interface
+@@ -12125,6 +12129,11 @@
+   enableval=$enable_isisd;
+ fi
+ 
++# Check whether --enable-trill was given.
++if test "${enable_trill+set}" = set; then :
++  enableval=$enable_trill;
++fi
++
+ # Check whether --enable-solaris was given.
+ if test "${enable_solaris+set}" = set; then :
+   enableval=$enable_solaris;
+@@ -12362,6 +12371,80 @@
+ 
+ 
+ 
++if test "${enable_trill}" = "yes"; then
++  ac_fn_c_check_header_mongrel "$LINENO" "net/trill.h" "ac_cv_header_net_trill_h" "$ac_includes_default"
++if test "x$ac_cv_header_net_trill_h" = xyes; then :
++
++fi
++
++
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dladm_valid_bridgename in -ldladm" >&5
++$as_echo_n "checking for dladm_valid_bridgename in -ldladm... " >&6; }
++if ${ac_cv_lib_dladm_dladm_valid_bridgename+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_check_lib_save_LIBS=$LIBS
++LIBS="-ldladm  $LIBS"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++/* Override any GCC internal prototype to avoid an error.
++   Use char because int might match the return type of a GCC
++   builtin and then its argument prototype would still apply.  */
++#ifdef __cplusplus
++extern "C"
++#endif
++char dladm_valid_bridgename ();
++int
++main ()
++{
++return dladm_valid_bridgename ();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_lib_dladm_dladm_valid_bridgename=yes
++else
++  ac_cv_lib_dladm_dladm_valid_bridgename=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dladm_dladm_valid_bridgename" >&5
++$as_echo "$ac_cv_lib_dladm_dladm_valid_bridgename" >&6; }
++if test "x$ac_cv_lib_dladm_dladm_valid_bridgename" = xyes; then :
++  libdladm=yes
++fi
++
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking TRILL IS-IS support" >&5
++$as_echo_n "checking TRILL IS-IS support... " >&6; }
++  if test $ac_cv_header_net_trill_h = no || \
++    test $ac_cv_lib_dladm_dladm_valid_bridgename = no; then
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
++$as_echo "none" >&6; }
++    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** TRILL IS-IS support will not be built ***" >&5
++$as_echo "$as_me: WARNING: *** TRILL IS-IS support will not be built ***" >&2;}
++    enable_trill=no
++  else
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++$as_echo "yes" >&6; }
++
++$as_echo "#define HAVE_TRILL /**/" >>confdefs.h
++
++  fi
++fi
++if test "${enable_trill}" = "yes"; then
++  ISIS_TARGETS="isisd trilld"
++  ISIS_LIBS=-ldladm
++else
++  ISIS_TARGETS="isisd"
++  ISIS_LIBS=
++fi
++
++
++
+ if test "${enable_user}" = "yes" || test x"${enable_user}" = x""; then
+   enable_user="quagga"
+ elif test "${enable_user}" = "no"; then
+@@ -15985,45 +16068,48 @@
+ 
+ $as_echo "#define ISIS_METHOD_BPF 3" >>confdefs.h
+ 
+-ac_fn_c_check_header_mongrel "$LINENO" "net/bpf.h" "ac_cv_header_net_bpf_h" "$ac_includes_default"
++if test "${enable_isisd}" = "yes"; then
++  ISIS_METHOD_MACRO=
++  ac_fn_c_check_header_mongrel "$LINENO" "net/bpf.h" "ac_cv_header_net_bpf_h" "$ac_includes_default"
+ if test "x$ac_cv_header_net_bpf_h" = xyes; then :
+ 
+ fi
+ 
+ 
+-ac_fn_c_check_header_mongrel "$LINENO" "sys/dlpi.h" "ac_cv_header_sys_dlpi_h" "$ac_includes_default"
++  ac_fn_c_check_header_mongrel "$LINENO" "sys/dlpi.h" "ac_cv_header_sys_dlpi_h" "$ac_includes_default"
+ if test "x$ac_cv_header_sys_dlpi_h" = xyes; then :
+ 
+ fi
+ 
+ 
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking zebra IS-IS I/O method" >&5
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking zebra IS-IS I/O method" >&5
+ $as_echo_n "checking zebra IS-IS I/O method... " >&6; }
+-if test x"$opsys" = x"gnu-linux"; then
+-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: pfpacket" >&5
++  if test x"$opsys" = x"gnu-linux"; then
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: pfpacket" >&5
+ $as_echo "pfpacket" >&6; }
+-  ISIS_METHOD_MACRO="ISIS_METHOD_PFPACKET"
+-elif test x"$opsys" = x"sol2-6" -o x"$opsys" = x"sol8"; then
+-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: DLPI" >&5
++    ISIS_METHOD_MACRO="ISIS_METHOD_PFPACKET"
++  elif test x"$opsys" = x"sol2-6" -o x"$opsys" = x"sol8"; then
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: DLPI" >&5
+ $as_echo "DLPI" >&6; }
+-  ISIS_METHOD_MACRO="ISIS_METHOD_DLPI"
+-else
+-  if test $ac_cv_header_net_bpf_h = no; then
+-    if test $ac_cv_header_sys_dlpi_h = no; then
+-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
++    ISIS_METHOD_MACRO="ISIS_METHOD_DLPI"
++  else
++    if test $ac_cv_header_net_bpf_h = no; then
++      if test $ac_cv_header_sys_dlpi_h = no; then
++        { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+ $as_echo "none" >&6; }
+-      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** IS-IS support will not be built ***" >&5
++        { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** IS-IS support will not be built ***" >&5
+ $as_echo "$as_me: WARNING: *** IS-IS support will not be built ***" >&2;}
+-      ISISD=""
+-    else
+-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: DLPI" >&5
++        ISISD=""
++      else
++        { $as_echo "$as_me:${as_lineno-$LINENO}: result: DLPI" >&5
+ $as_echo "DLPI" >&6; }
+-    fi
+-    ISIS_METHOD_MACRO="ISIS_METHOD_DLPI"
+-  else
+-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: BPF" >&5
++      fi
++      ISIS_METHOD_MACRO="ISIS_METHOD_DLPI"
++    else
++      { $as_echo "$as_me:${as_lineno-$LINENO}: result: BPF" >&5
+ $as_echo "BPF" >&6; }
+-    ISIS_METHOD_MACRO="ISIS_METHOD_BPF"
++      ISIS_METHOD_MACRO="ISIS_METHOD_BPF"
++    fi
+   fi
+ fi
+ 
+diff -r -u isisd/Makefile.in isisd/Makefile.in
+--- isisd/Makefile.in
++++ isisd/Makefile.in
+@@ -38,7 +38,7 @@
+ build_triplet = @build@
+ host_triplet = @host@
+ target_triplet = @target@
+-sbin_PROGRAMS = isisd$(EXEEXT)
++EXTRA_PROGRAMS = isisd$(EXEEXT) trilld$(EXEEXT)
+ subdir = isisd
+ DIST_COMMON = README $(dist_examples_DATA) $(noinst_HEADERS) \
+ 	$(srcdir)/Makefile.am $(srcdir)/Makefile.in AUTHORS
+@@ -75,9 +75,15 @@
+ 	isis_events.$(OBJEXT) isis_spf.$(OBJEXT) isis_route.$(OBJEXT) \
+ 	isis_routemap.$(OBJEXT)
+ am_isisd_OBJECTS = isis_main.$(OBJEXT) $(am__objects_1) \
+-	isis_bpf.$(OBJEXT) isis_dlpi.$(OBJEXT) isis_pfpacket.$(OBJEXT)
++	isis_bpf.$(OBJEXT) isis_dlpi.$(OBJEXT) isis_pfpacket.$(OBJEXT) \
++	isis_trilldummy.$(OBJEXT)
+ isisd_OBJECTS = $(am_isisd_OBJECTS)
+ isisd_DEPENDENCIES = ../lib/libzebra.la
++am_trilld_OBJECTS = isis_main.$(OBJEXT) $(am__objects_1) \
++	isis_trill.$(OBJEXT) isis_trillio.$(OBJEXT) \
++	isis_trillvlans.$(OBJEXT) isis_trillbpdu.$(OBJEXT)
++trilld_OBJECTS = $(am_trilld_OBJECTS)
++trilld_DEPENDENCIES = ../lib/libzebra.la
+ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+ depcomp = $(SHELL) $(top_srcdir)/depcomp
+ am__depfiles_maybe = depfiles
+@@ -91,8 +97,8 @@
+ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ 	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ 	$(LDFLAGS) -o $@
+-SOURCES = $(libisis_a_SOURCES) $(isisd_SOURCES)
+-DIST_SOURCES = $(libisis_a_SOURCES) $(isisd_SOURCES)
++SOURCES = $(libisis_a_SOURCES) $(isisd_SOURCES) $(trilld_SOURCES)
++DIST_SOURCES = $(libisis_a_SOURCES) $(isisd_SOURCES) $(trilld_SOURCES)
+ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ 	html-recursive info-recursive install-data-recursive \
+ 	install-dvi-recursive install-exec-recursive \
+@@ -201,6 +207,8 @@
+ IOCTL_METHOD = @IOCTL_METHOD@
+ IPFORWARD = @IPFORWARD@
+ ISISD = @ISISD@
++ISIS_LIBS = @ISIS_LIBS@
++ISIS_TARGETS = @ISIS_TARGETS@
+ ISIS_TOPOLOGY_DIR = @ISIS_TOPOLOGY_DIR@
+ ISIS_TOPOLOGY_INCLUDES = @ISIS_TOPOLOGY_INCLUDES@
+ ISIS_TOPOLOGY_LIB = @ISIS_TOPOLOGY_LIB@
+@@ -212,7 +220,7 @@
+ LIBOBJS = @LIBOBJS@
+ LIBPAM = @LIBPAM@
+ LIBREADLINE = @LIBREADLINE@
+-LIBS = @LIBS@ 
++LIBS = @LIBS@ @ISIS_LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_IPV6 = @LIB_IPV6@
+ LIB_REGEX = @LIB_REGEX@
+@@ -327,6 +335,7 @@
+ AM_CFLAGS = $(PICFLAGS)
+ AM_LDFLAGS = $(PILDFLAGS)
+ noinst_LIBRARIES = libisis.a
++sbin_PROGRAMS = @ISIS_TARGETS@
+ SUBDIRS = topology
+ libisis_a_SOURCES = \
+ 	isis_adjacency.c isis_lsp.c dict.c isis_circuit.c isis_pdu.c \
+@@ -339,13 +348,22 @@
+ 	isis_lsp.h dict.h isis_circuit.h isis_misc.h isis_network.h \
+ 	isis_zebra.h isis_dr.h isis_flags.h isis_dynhn.h isis_common.h \
+ 	iso_checksum.h isis_csm.h isis_events.h isis_spf.h isis_route.h \
++	isis_trill.h \
+ 	include-netbsd/clnp.h include-netbsd/esis.h include-netbsd/iso.h
+ 
+ isisd_SOURCES = \
+ 	isis_main.c $(libisis_a_SOURCES) \
+-	isis_bpf.c isis_dlpi.c isis_pfpacket.c
++	isis_bpf.c isis_dlpi.c isis_pfpacket.c isis_trilldummy.c
+ 
+-isisd_LDADD = @ISIS_TOPOLOGY_LIB@ ../lib/libzebra.la @LIBCAP@
++isisd_LDADD = @ISIS_TOPOLOGY_LIB@ ../lib/libzebra.la @LIBCAP@ @LIBM@
++trilld_SOURCES = \
++	isis_main.c $(libisis_a_SOURCES) isis_trill.c isis_trillio.c \
++	isis_trillvlans.c isis_trillbpdu.c
++
++trilld_LDADD = @ISIS_TOPOLOGY_LIB@ ../lib/libzebra.la @LIBCAP@ @LIBM@
++EXTRA_DIST = isis_bpf.c isis_dlpi.c isis_pfpacket.c isis_trill.c \
++	isis_trillio.c isis_trillvlans.c isis_trillbpdu.c
++
+ examplesdir = $(exampledir)
+ dist_examples_DATA = isisd.conf.sample
+ all: all-recursive
+@@ -435,6 +453,9 @@
+ isisd$(EXEEXT): $(isisd_OBJECTS) $(isisd_DEPENDENCIES) 
+ 	@rm -f isisd$(EXEEXT)
+ 	$(LINK) $(isisd_OBJECTS) $(isisd_LDADD) $(LIBS)
++trilld$(EXEEXT): $(trilld_OBJECTS) $(trilld_DEPENDENCIES) 
++	@rm -f trilld$(EXEEXT)
++	$(LINK) $(trilld_OBJECTS) $(trilld_LDADD) $(LIBS)
+ 
+ mostlyclean-compile:
+ 	-rm -f *.$(OBJEXT)
+@@ -461,6 +482,11 @@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_routemap.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_spf.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_tlv.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_trill.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_trillbpdu.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_trilldummy.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_trillio.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_trillvlans.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_zebra.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isisd.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iso_checksum.Po@am__quote@
+diff -r -u solaris/Makefile.in solaris/Makefile.in
+--- solaris/Makefile.in
++++ solaris/Makefile.in
+@@ -97,6 +97,8 @@
+ IOCTL_METHOD = @IOCTL_METHOD@
+ IPFORWARD = @IPFORWARD@
+ ISISD = @ISISD@
++ISIS_LIBS = @ISIS_LIBS@
++ISIS_TARGETS = @ISIS_TARGETS@
+ ISIS_TOPOLOGY_DIR = @ISIS_TOPOLOGY_DIR@
+ ISIS_TOPOLOGY_INCLUDES = @ISIS_TOPOLOGY_INCLUDES@
+ ISIS_TOPOLOGY_LIB = @ISIS_TOPOLOGY_LIB@
+@@ -229,7 +231,7 @@
+ pkg_packages = $(pkg_names:%=@PACKAGE_TARNAME@-%-$(pkg_name_rev).pkg)
+ pkg_pkginfos = $(pkg_names:%=pkginfo.%.full)
+ pkg_prototypes = $(pkg_names:%=prototype.%)
+-pkg_manifests = quagga.xml
++pkg_manifests = quagga.xml trill.xml
+ 
+ # pkgmk variable substitutions wont grok ${variable} in prototype
+ # file, so we cant let autoconf generate the file sadly