# HG changeset patch # User Brian Utterback # Date 1325617739 28800 # Node ID f0bde9a421fec2cd5d9a42a2df520ac15ec740ad # Parent cc3545c342fd1379b900cb27419f11194b2530c1 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 diff -r cc3545c342fd -r f0bde9a421fe components/quagga/Makefile --- 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) diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/05-noupg-nolegacy.patch --- /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 "; +- else +- echo "Usage: $0 "; +- fi ++ echo "Usage: $0 "; + echo "The --pid_file argument is implied"; + echo "This help message: $0 "; + } +@@ -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 @@ + + +- + + +@@ -489,8 +487,6 @@ + + +- + + +@@ -752,8 +748,6 @@ + + +- + + diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/10-sunw-smf.patch --- 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 "; -- else -- echo "Usage: $0 "; -+ 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 "; - echo "The --pid_file argument is implied"; - echo "This help message: $0 "; - } -@@ -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" - --> - -- -+ -+ - -- -+ -+ - - - - - -- -- -+ -- -+ restart_on='refresh' -+ type='service'> -+ - -- -+ - - - -+ user='root' group='root'/> - - - -@@ -84,11 +86,48 @@ - - -- -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - -+ - -- -+ value='solaris.smf.value.routing' /> -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -@@ -95,6 +134,8 @@ - - -+ - - - - -- -+ - - - - - -- - -- -- -- -- -- -+ -- -+ restart_on='refresh' -+ type='service'> -+ - - -+ -+ -+ -+ -+ - - - -+ user='root' group='root'/> - - - -@@ -179,10 +221,42 @@ - type='astring' value='core,signal' /> - - -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - -- -+ value='solaris.smf.value.routing' /> -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -@@ -189,6 +263,8 @@ - - -+ - - - - -- -+ - - - - - -- - -- -- -+ -+ -+ - - -- -+ -- -+ type='service'> -+ - -- -+ - - - -+ user='root' group='root'/> - - - -@@ -273,10 +350,42 @@ - type='astring' value='core,signal' /> - - -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - -- -+ value='solaris.smf.value.routing' /> -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -@@ -283,6 +392,8 @@ - - -+ - - - - -- -+ - - - - - -- - -- -- -+ -+ -+ - - -- -+ -- -+ type='service'> -+ - -- -+ - - - -+ user='root' group='root'/> - - - -+ - -+ timeout_seconds='600'> - - - - - -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - -- -+ value='solaris.smf.value.routing' /> -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -@@ -377,6 +521,8 @@ - - -+ - - - - -- -+ - - - - - -- - -- -- -+ -+ -+ - - -- -+ -- -+ type='service'> -+ - -- -+ - - - -+ user='root' group='root'/> - - - -@@ -461,10 +608,39 @@ - type='astring' value='core,signal' /> - - -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - -- -+ value='solaris.smf.value.routing' /> -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -@@ -471,12 +647,14 @@ - - -+ - - - - -- -+ - - - -@@ -506,40 +684,48 @@ - value='svc:/system/filesystem/usr:default' /> - - -- -+ -+ -+ -+ - -- -- -+ -+ -+ - - -- -+ -- -+ type='service'> -+ - -- -+ - - - -+ user='root' group='root'/> - - - -@@ -557,10 +743,55 @@ - type='astring' value='core,signal' /> - - -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - -- -+ value='solaris.smf.value.routing' /> -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -@@ -567,6 +798,8 @@ - - -+ - - - - -- -+ - - diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/10-zebra-retain.patch --- /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 @@ + + + ++ + + + diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/15-privs-ipinst.patch --- 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 }, }, diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/20-privs-bgpd.patch --- 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, diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/23-cve-2011-3327.patch --- 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) - { diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/25-isisd-dlpi.patch --- 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 -+ -+ * configure.ac: Added support for separate link-layer access -+ mechanisms in isisd. -+ - 2007-07-27 Paul Jakma - - * 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 -+ -+ * 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 -+ -+ * 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 - - * 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 - #include -+#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 -+#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 -+#include -+#include -+#include -+#include -+#include -+ -+#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 - #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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 --#ifdef GNU_LINUX --#include /* the L2 protocols */ --#else --#include --#include --#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 --#else --#include --#include --#include --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 -+#include /* the L2 protocols */ -+#include -+ -+#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 - { diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/30-ospfd-nssa-asbr.patch --- 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 -+ -+ * 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 - - * 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)) diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/35-ospfd-spf-sort.patch --- 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 -Date: Mon Aug 6 18:52:45 2007 +0000 - - [ospfd] Fix bad SPF calculation on some topologies - incorrect sorting - - 2007-08-07 Atis Elsts - - * 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 -+ -+ * 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 - - * 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 */ diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/40-bgp-capab-cleanup.patch --- 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 -Date: Mon Aug 6 15:21:45 2007 +0000 - - [bgpd] cleanup, compact and consolidate capability parsing code - - 2007-07-26 Paul Jakma - - * (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; - } diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/45-bgpd-capab-typo.patch --- 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 -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 - - * 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; - diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/50-bgpd-nosub.patch --- 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 -Date: Thu Aug 23 23:22:02 2007 +0000 - - [bgpd] Pass NOSUB to regexec - - 2007-08-23 Paul Jakma - - * 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); - diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/55-bgpd-rm-assert.patch --- 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 -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 - - * 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 - - * 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); diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/60-bgp-comm-crash.patch --- 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 -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 - - * (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", - . - * 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; diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/65-isisd-iso-checksum.patch --- 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 -+ * 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 - - * 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 - #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 @@ + + -+ ++ + + + ++ user='root' group='root' /> + + + @@ -623,8 +120,8 @@ + value='solaris.smf.value.routing' /> + + -+ -+ ++ ++ + + + @@ -636,7 +133,7 @@ + + + -+ ++ + + diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/70-isisd-trill.patch --- 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 +#include -+ + #if ISIS_METHOD == ISIS_METHOD_DLPI #include #include - #include -@@ -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'> + + ++ user='root' group='root' /> + + + diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/80-ripngd-getopt.patch --- 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; diff -r cc3545c342fd -r f0bde9a421fe components/quagga/patches/95-noautomake.patch --- /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 header file. */ + #undef HAVE_TIME_H + ++/* Enable TRILL support */ ++#undef HAVE_TRILL ++ + /* Define to 1 if you have the 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