diff --git a/trunk/xorp/SConscript b/trunk/xorp/SConscript index 7eef942..ee9c65f 100644 --- a/trunk/xorp/SConscript +++ b/trunk/xorp/SConscript @@ -41,6 +41,7 @@ subdirs = [ 'rip', 'rtrmgr', 'static_routes', + 'utils', 'vrrp', 'bgp', ] diff --git a/trunk/xorp/bgp/SConscript b/trunk/xorp/bgp/SConscript index e83f8e3..0a0cd1f 100644 --- a/trunk/xorp/bgp/SConscript +++ b/trunk/xorp/bgp/SConscript @@ -21,25 +21,23 @@ import os Import('env') subdirs = [ - #'harness', - 'tests', 'tools', + 'tests', + 'harness', ] SConscript(dirs = subdirs, exports='env') -env = env.Clone() +bgp_env = env.Clone() -# XXX Not used, bgp linkage must remain static until we fix the -# dependency graph in here. -#is_shared = env.has_key('SHAREDLIBS') +is_shared = bgp_env.has_key('SHAREDLIBS') -env.AppendUnique(CPPPATH = [ +bgp_env.AppendUnique(CPPPATH = [ '#', '$BUILDDIR', ]) -env.PrependUnique(LIBPATH = [ +bgp_env.PrependUnique(LIBPATH = [ '.', '$BUILDDIR/policy/backend', '$BUILDDIR/policy/common', @@ -51,7 +49,7 @@ env.PrependUnique(LIBPATH = [ '$BUILDDIR/libcomm', ]) -env.AppendUnique(LIBS = [ +bgp_env.AppendUnique(LIBS = [ 'xorp_policy_backend', 'xorp_policy_common', 'xorp_fea_client', @@ -59,7 +57,6 @@ env.AppendUnique(LIBS = [ 'xst_fea_ifmgr_mirror', 'xif_rib', 'xif_finder_event_notifier', - 'xif_profile_client', 'xif_fea_ifmgr_mirror', 'xif_fea_ifmgr_replicator', 'xorp_ipc', @@ -67,17 +64,21 @@ env.AppendUnique(LIBS = [ 'xorp_comm', ]) -env.Replace(RPATH = [ - env.Literal(env['xorp_module_rpath']) +if not (bgp_env.has_key('disable_profile') and bgp_env['disable_profile']): + bgp_env.AppendUnique(LIBS = [ 'xif_profile_client' ]) + +bgp_env.Replace(RPATH = [ + bgp_env.Literal(bgp_env['xorp_module_rpath']) ]) ### libxorp_bgp -libxorp_bgp_env = env.Clone() +libxorp_bgp_env = bgp_env.Clone() libxorp_bgp_srcs = [ 'aspath.cc', 'attribute_manager.cc', + 'bgp.cc', 'bgp_trie.cc', 'bgp_varrw.cc', 'bgp_varrw_export.cc', @@ -99,7 +100,6 @@ libxorp_bgp_srcs = [ 'peer_list.cc', 'plumbing.cc', 'process_watch.cc', - 'profile_vars.cc', 'rib_ipc_handler.cc', 'route_queue.cc', 'route_table_aggregation.cc', @@ -126,29 +126,43 @@ libxorp_bgp_srcs = [ 'xrl_target.cc', ] -#libxorp_bgp = libxorp_bgp_env.SharedLibrary(target = 'libxorp_bgp', source = libxorp_bgp_srcs) - -# XXX Static until ASPath and other objects are dealt with. -libxorp_bgp = libxorp_bgp_env.StaticLibrary(target = 'libxorp_bgp', - source = libxorp_bgp_srcs) - -#env.Alias('install', -# env.InstallLibrary('$libdir', libxorp_bgp)) +if not (bgp_env.has_key('disable_profile') and bgp_env['disable_profile']): + libxorp_bgp_srcs.append('profile_vars.cc') + +if is_shared: + libxorp_bgp = bgp_env.SharedLibrary(target = 'libxorp_bgp', + source = libxorp_bgp_srcs, + LIBS = '') + if bgp_env['rtld_origin']: + for obj in libxorp_bgp: + bgp_env.AddPostAction(libxorp_bgp, + bgp_env.Symlink(obj.abspath, + os.path.join(bgp_env['xorp_alias_libdir'], str(obj)))) +else: + libxorp_ospf = bgp_env.StaticLibrary(target = 'libxorp_bgp', + source = libxorp_bgp_srcs, + LIBS = '') ### xorp_bgp -bgp_env = env.Clone() +#bgp_env2 = bgp_env.Clone() bgp_env.PrependUnique(LIBS = [ 'xorp_bgp', ]) bgpsrcs = [ - 'bgp.cc', - 'main.cc', - ] + 'main.cc', + ] bgp = bgp_env.Program(target = 'xorp_bgp', source = bgpsrcs) -env.Alias('install', env.InstallProgram(env['xorp_moduledir'], bgp)) +bgp_env.Alias('install', bgp_env.InstallProgram(bgp_env['xorp_moduledir'], bgp)) + + +if is_shared: + bgp_env.Alias('install', env.InstallLibrary(bgp_env['xorp_libdir'], libxorp_bgp)) + +# Install scripts +env.Alias('install', env.InstallProgram('$exec_prefix/sbin/', env.Entry('bgp_xrl_shell_funcs.sh'))) -Default(libxorp_bgp, bgp) +Default(bgp) diff --git a/trunk/xorp/bgp/bgp_xrl_shell_funcs.sh b/trunk/xorp/bgp/bgp_xrl_shell_funcs.sh index bb41b77..b7b9d15 100755 --- a/trunk/xorp/bgp/bgp_xrl_shell_funcs.sh +++ b/trunk/xorp/bgp/bgp_xrl_shell_funcs.sh @@ -28,8 +28,13 @@ set_damping() add_peer() { echo "add_peer" $* -# $CALLXRL "finder://bgp/bgp/0.1/add_peer?peer:txt=$1&as:i32=$2&port:i32=$3&next_hop:ipv4=$4" - $CALLXRL "finder://bgp/bgp/0.3/add_peer?local_ip:txt=$1&local_port:u32=$2&peer_ip:txt=$3&peer_port:u32=$4&as:txt=$5&next_hop:ipv4=$6&holdtime:u32=$7" + if [ $1 == "lo" ] + then + # This is using xorp.ct syntax..easier this small hack than changing all the test harness scripts. + $CALLXRL "finder://bgp/bgp/0.3/add_peer?local_ip:txt=$2&local_port:u32=$3&peer_ip:txt=$4&peer_port:u32=$5&as:txt=$6&next_hop:ipv4=$7&holdtime:u32=$8" + else + $CALLXRL "finder://bgp/bgp/0.3/add_peer?local_ip:txt=$1&local_port:u32=$2&peer_ip:txt=$3&peer_port:u32=$4&as:txt=$5&next_hop:ipv4=$6&holdtime:u32=$7" + fi } delete_peer() diff --git a/trunk/xorp/bgp/configure_bgp.sh b/trunk/xorp/bgp/configure_bgp.sh index dfbfd11..dd67a51 100755 --- a/trunk/xorp/bgp/configure_bgp.sh +++ b/trunk/xorp/bgp/configure_bgp.sh @@ -8,7 +8,7 @@ # Send configuration commands to a running bgp process. # -. ./xrl_shell_funcs.sh +. ./bgp_xrl_shell_funcs.sh case `hostname` in aardvark) diff --git a/trunk/xorp/bgp/harness/SConscript b/trunk/xorp/bgp/harness/SConscript index d3a5731..bdb2dfa 100644 --- a/trunk/xorp/bgp/harness/SConscript +++ b/trunk/xorp/bgp/harness/SConscript @@ -31,8 +31,13 @@ env.AppendUnique(LIBPATH = [ '$BUILDDIR/libxorp', '$BUILDDIR/libcomm', '$BUILDDIR/libxipc', + '$BUILDDIR/libfeaclient', '$BUILDDIR/xrl/interfaces', '$BUILDDIR/xrl/targets', + '$BUILDDIR/policy/backend', + '$BUILDDIR/policy/common', + '$BUILDDIR/bgp', + '$BUILDDIR/fea', '.', ]) @@ -41,6 +46,114 @@ env.AppendUnique(LIBS = [ 'xorp_ipc', 'xorp_core', 'xorp_comm', + 'xst_test_peer', + 'xorp_bgp', + 'xif_test_peer', + 'xst_coord', + 'xif_coord', + 'xif_rib', + 'xif_datain', + 'xorp_fea_client', + 'xorp_policy_backend', + 'xorp_policy_common', + 'xif_fea_ifmgr_mirror', + 'xif_fea_ifmgr_replicator', + 'xst_fea_ifmgr_mirror', + 'xst_bgp', + 'xif_profile_client', + 'xif_finder_event_notifier', ]) -# XXX FIXME +coord_srcs = [ + 'bgppp.cc', + 'command.cc', + 'coord.cc', + 'peer.cc', + 'trie.cc', + ] + +test_peer_srcs = [ + 'test_peer.cc', + 'bgppp.cc', + ] + +test_trie_srcs = [ + 'test_peer.cc', + 'bgppp.cc', + ] + +script_srcs = [ + 'args.sh', + 'test_path_attribute1.sh', + 'test_rib1.sh', + 'test_routing2.sh', + 'inject.sh', + 'test_path_attribute2.sh', + 'test_rib_fea1.sh', + 'test_terminate.sh', + 'notification_codes.sh', + 'test_path_attribute3.sh', + 'test_route_flap_damping1.sh', + 'xrl_shell_funcs.sh', + 'setup_paths.sh', + 'soak.sh', + 'test_peering1.sh', + 'test_route_reflection1.sh', + 'test1.sh', + 'test_peering2.sh', + 'test_route_reflection2.sh', + 'test2.sh', + 'test_peering3.sh', + 'test_routing1.sh', + 'harness.py', + 'lookup.py', + 'NOTES', + 'originate_routes.pl', + ] + + +coord = env.Program(target = 'coord', source = coord_srcs) +test_peer = env.Program(target = 'test_peer', source = test_peer_srcs) +test_trie = env.Program(target = 'test_trie', source = test_trie_srcs) + +harnesspath = '$exec_prefix/bgp/harness' + +#if env['WITH_TESTS']: +# env.Alias('install', env.InstallProgram(harnesspath, coord)) +# env.Alias('install', env.InstallProgram(harnesspath, test_peer)) +# env.Alias('install', env.InstallProgram(harnesspath, test_trie)) + +# for ss in script_srcs: +# env.Alias('install', env.InstallProgram(harnesspath, env.Entry('%s' % ss))) + +if 'check' in COMMAND_LINE_TARGETS: + from subprocess import call + + for ss in script_srcs: + env.Alias('check', env.Execute(Copy('%s' % ss, '../../../../bgp/harness/%s' %ss))) + + # Tests to run automatically with 'scons test' + # This 'Execute' recipe doesn't work right, because if a program fails, + # then scons will exit. Use 'call' instead to force them to be run. + #env.Alias('check', env.Execute(env.Action('./test_peering1.sh'))) + + call("./test_peering1.sh") + call("./test_peering2.sh") + call('./test_peering3.sh') + call('./test_routing1.sh') + call('./test_routing2.sh') + call('./test_rib1.sh') + call('./test_rib_fea1.sh') + call('./test_path_attribute1.sh') + call('./test_path_attribute2.sh') + call('./test_path_attribute3.sh') + call('./test_route_reflection1.sh') + call('./test_route_reflection2.sh') + call('./test_route_flap_damping1.sh') + call('./test_terminate.sh') + +#for t in tests: +# test_targets.append(env.AutoTest(target = 'test_%s' % t, +# source = 'test_%s.cc' % t)) + +Default(coord, test_peer, test_trie) diff --git a/trunk/xorp/bgp/harness/args.sh b/trunk/xorp/bgp/harness/args.sh index a151c57..4bf275c 100644 --- a/trunk/xorp/bgp/harness/args.sh +++ b/trunk/xorp/bgp/harness/args.sh @@ -14,7 +14,12 @@ RESTART="yes" # Perform Win32 path conversion for runit if required. RUNIT="runit" -RUNITDIR="../../utils" +if [ -x ../../utils/runit ] +then + RUNITDIR="../../utils" +else + RUNITDIR="../../lib/xorp/bin/" +fi RUNITPRE="" if [ x"$OSTYPE" = xmsys ]; then RUNITPRE="cmd //c" diff --git a/trunk/xorp/bgp/harness/coord.hh b/trunk/xorp/bgp/harness/coord.hh index 7db952c..2af52f4 100644 --- a/trunk/xorp/bgp/harness/coord.hh +++ b/trunk/xorp/bgp/harness/coord.hh @@ -72,6 +72,8 @@ public: uint32_t& status, string& reason); + XrlCmdError common_0_1_startup() { return XrlCmdError::OKAY(); } + /** * shutdown target */ diff --git a/trunk/xorp/bgp/harness/harness.py b/trunk/xorp/bgp/harness/harness.py index 234e848..8877e88 100755 --- a/trunk/xorp/bgp/harness/harness.py +++ b/trunk/xorp/bgp/harness/harness.py @@ -16,8 +16,11 @@ import time import sys import getopt -CALL_XRL_LOCATION="../../libxipc/call_xrl" +CALL_XRL_LOCATION="../../sbin/call_xrl" +if (not os.path.isfile(CALL_XRL_LOCATION)): + CALL_XRL_LOCATION="../../libxipc/call_xrl" + def call_xrl(command): """ Call an XRL diff --git a/trunk/xorp/bgp/harness/inject.sh b/trunk/xorp/bgp/harness/inject.sh index c5eec9a..9f03cc1 100755 --- a/trunk/xorp/bgp/harness/inject.sh +++ b/trunk/xorp/bgp/harness/inject.sh @@ -19,6 +19,8 @@ set -e +. ./setup_paths.sh + # Configure an interface and re-write all next hops to go through this # interface VIF0="dc0" @@ -28,7 +30,14 @@ NEXT_HOP_REWRITE1="10.1.0.2" NEXT_HOP_REWRITE2="10.1.0.3" LOCALHOST=$(hostname) -MY_IP=$(host $LOCALHOST | cut -f 4 -d ' ') +if host $LOCALHOST +then + MY_IP=$(host $LOCALHOST | cut -f 4 -d ' '|head -1) +else + LOCALHOST=localhost + MY_IP=127.0.0.1 +fi +echo "MY_IP: $MY_IP" MY_AS=65008 MY_ID=$MY_IP @@ -46,6 +55,15 @@ TEST_PEER_PORT=9001 TREETOP=${PWD}/../../../xorp DUMPNAME=${DUMPNAME:-$TREETOP/../data/bgp/icsi1.mrtd} +if [ ! -f $DUMPNAME ] +then + DUMPNAME=/root/icsi1.mrtd + if [ ! -f $DUMPNAME ] + then + echo "ERROR: Cannot find iscsi1.mrtd file." + exit 1 + fi +fi # # Start all the required processes @@ -53,7 +71,7 @@ DUMPNAME=${DUMPNAME:-$TREETOP/../data/bgp/icsi1.mrtd} start_processes() { (cd $TREETOP - for i in libxipc/xorp_finder fea/xorp_fea_dummy rib/xorp_rib bgp/xorp_bgp \ + for i in lib/xorp/sbin/xorp_finder lib/xorp/sbin/xorp_fea_dummy lib/xorp/sbin/xorp_rib lib/xorp/sbin/xorp_bgp \ "bgp/harness/test_peer -s peer1 -v" \ "bgp/harness/test_peer -s peer2 -v" \ bgp/harness/coord @@ -70,8 +88,6 @@ fea() { echo "Configuring fea" - export CALLXRL=$TREETOP/libxipc/call_xrl - FEA_FUNCS=$TREETOP/fea/xrl_shell_funcs.sh local tid=$($FEA_FUNCS start_fea_transaction) $FEA_FUNCS create_interface $tid $VIF0 @@ -92,36 +108,35 @@ fea() bgp() { - echo "Configuring bgp" - export CALLXRL=$TREETOP/libxipc/call_xrl - BGP_FUNCS=$TREETOP/bgp/xrl_shell_funcs.sh - PORT=$MY_PORT AS=$MY_AS ID=$MY_ID USE4BYTEAS=false HOLDTIME=0 + echo "Configuring bgp, AS: $AS ID: $ID USE4BYTEAS: $USE4BYTEAS" $BGP_FUNCS local_config $AS $ID $USE4BYTEAS # register_rib "rib" # Test peer used for route injection - - PEER=$LOCALHOST + + MY_DEV="lo" + PEER=$MY_IP PEER_AS=$INJECT_PEER_AS PEER_PORT=$INJECT_PEER_PORT - IPTUPLE="$LOCALHOST $MY_INJECT_PORT $PEER $PEER_PORT" - $BGP_FUNCS add_peer $IPTUPLE $PEER_AS $NEXT_HOP $HOLDTIME + IPTUPLE="$MY_IP $MY_INJECT_PORT $PEER $PEER_PORT" + $BGP_FUNCS add_peer $MY_DEV $IPTUPLE $PEER_AS $NEXT_HOP $HOLDTIME # Rewrite the next hop onto our test net $BGP_FUNCS next_hop_rewrite_filter $IPTUPLE $NEXT_HOP_REWRITE1 $BGP_FUNCS enable_peer $IPTUPLE # Our test peer. - PEER=$LOCALHOST + + PEER=$MY_IP PEER_AS=$TEST_PEER_AS PEER_PORT=$TEST_PEER_PORT - IPTUPLE="$LOCALHOST $PORT $PEER $PEER_PORT" - $BGP_FUNCS add_peer $IPTUPLE $PEER_AS $NEXT_HOP $HOLDTIME + IPTUPLE="$MY_IP $PORT $PEER $PEER_PORT" + $BGP_FUNCS add_peer $MY_DEV $IPTUPLE $PEER_AS $NEXT_HOP $HOLDTIME # Rewrite the next hop onto our test net $BGP_FUNCS next_hop_rewrite_filter $IPTUPLE $NEXT_HOP_REWRITE2 $BGP_FUNCS enable_peer $IPTUPLE @@ -130,9 +145,6 @@ bgp() bgp_enable() { echo "Enable peering to main router" - export CALLXRL=$TREETOP/libxipc/call_xrl - BGP_FUNCS=$TREETOP/bgp/xrl_shell_funcs.sh - PORT=$MY_PORT PEER=$BORDER_ROUTER_NAME PEER_AS=$BORDER_ROUTER_AS @@ -144,9 +156,6 @@ bgp_enable() bgp_disable() { echo "Disable peering to main router" - export CALLXRL=$TREETOP/libxipc/call_xrl - BGP_FUNCS=$TREETOP/bgp/xrl_shell_funcs.sh - PORT=$MY_PORT PEER=$BORDER_ROUTER_NAME PEER_AS=$BORDER_ROUTER_AS @@ -159,7 +168,6 @@ reset() { echo "Resetting coordinator" - export CALLXRL=$TREETOP/libxipc/call_xrl TEST_FUNCS=$TREETOP/bgp/harness/xrl_shell_funcs.sh $TEST_FUNCS coord reset @@ -168,7 +176,6 @@ reset() test_peer() { echo "Configuring test peer" - export CALLXRL=$TREETOP/libxipc/call_xrl TEST_FUNCS=$TREETOP/bgp/harness/xrl_shell_funcs.sh PEER=$LOCALHOST @@ -192,7 +199,6 @@ test_peer_inject() return fi - export CALLXRL=$TREETOP/libxipc/call_xrl TEST_FUNCS=$TREETOP/bgp/harness/xrl_shell_funcs.sh PEER=$LOCALHOST diff --git a/trunk/xorp/bgp/harness/test_path_attribute1.sh b/trunk/xorp/bgp/harness/test_path_attribute1.sh index 2e3bb89..8d76dd8 100755 --- a/trunk/xorp/bgp/harness/test_path_attribute1.sh +++ b/trunk/xorp/bgp/harness/test_path_attribute1.sh @@ -21,11 +21,12 @@ # 8) Run "./coord" # set -e +. ./setup_paths.sh # srcdir is set by make for check target if [ "X${srcdir}" = "X" ] ; then srcdir=`dirname $0` ; fi . ${srcdir}/xrl_shell_funcs.sh "" -. ${srcdir}/../xrl_shell_funcs.sh "" +. $BGP_FUNCS "" onexit() { @@ -75,19 +76,19 @@ configure_bgp() PEER=$HOST IPTUPLE="$LOCALHOST $PORT1 $PEER $PEER1_PORT" - add_peer $IPTUPLE $PEER1_AS $NEXT_HOP $HOLDTIME + add_peer lo $IPTUPLE $PEER1_AS $NEXT_HOP $HOLDTIME set_parameter $IPTUPLE MultiProtocol.IPv4.Unicast true enable_peer $IPTUPLE PEER=$HOST IPTUPLE="$LOCALHOST $PORT2 $PEER $PEER2_PORT" - add_peer $IPTUPLE $PEER2_AS $NEXT_HOP $HOLDTIME + add_peer lo $IPTUPLE $PEER2_AS $NEXT_HOP $HOLDTIME set_parameter $IPTUPLE MultiProtocol.IPv4.Unicast true enable_peer $IPTUPLE PEER=$HOST IPTUPLE="$LOCALHOST $PORT3 $PEER $PEER3_PORT" - add_peer $IPTUPLE $PEER3_AS $NEXT_HOP $HOLDTIME + add_peer lo $IPTUPLE $PEER3_AS $NEXT_HOP $HOLDTIME set_parameter $IPTUPLE MultiProtocol.IPv4.Unicast true enable_peer $IPTUPLE } @@ -456,10 +457,10 @@ if [ $START_PROGRAMS = "yes" ] then CXRL="$CALLXRL -r 10" runit $QUIET $VERBOSE -c "$0 -s -c $*" < NextHopAttribute::NextHopAttribute(const A& n) + throw(CorruptMessage) : PathAttribute(Transitive, NEXT_HOP), _next_hop(n) { + verify(); } template @@ -300,6 +302,23 @@ NextHopAttribute::clone() const return new NextHopAttribute(_next_hop); } +/* Throw exception if there are problems...do nothing + * otherwise. + */ +template +void +NextHopAttribute::verify() + throw(CorruptMessage) +{ + if (!_next_hop.is_unicast()) { + //XLOG_ASSERT(0); + xorp_throw(CorruptMessage, + c_format("NextHop %s is not a unicast address", + _next_hop.str().c_str()), + UPDATEMSGERR, INVALNHATTR); + } +} + template NextHopAttribute::NextHopAttribute(const uint8_t* d) throw(CorruptMessage) @@ -318,11 +337,7 @@ NextHopAttribute::NextHopAttribute(const uint8_t* d) _next_hop = A(payload(d)); - if (!_next_hop.is_unicast()) - xorp_throw(CorruptMessage, - c_format("NextHop %s is not a unicast address", - _next_hop.str().c_str()), - UPDATEMSGERR, INVALNHATTR, d, total_tlv_length(d)); + verify(); } template @@ -2852,6 +2867,8 @@ FastPathAttributeList::load_raw_data(const uint8_t *data, } } } + +#ifdef HAVE_IPV6 MPReachNLRIAttribute* mp6_reach_att = dynamic_cast*>(_att[MP_REACH_NLRI]); if (mp6_reach_att) { @@ -2876,6 +2893,7 @@ FastPathAttributeList::load_raw_data(const uint8_t *data, } } } +#endif MPUNReachNLRIAttribute* mp4_unreach_att = dynamic_cast*>(_att[MP_UNREACH_NLRI]); if (mp4_unreach_att) { @@ -3407,13 +3425,18 @@ FastPathAttributeList::str() const if (_att[type]) { s += "\n\t" + _att[type]->str(); } else if(_att_lengths[type]>0) { - // we're got data for an attribute, but not decoded it yet - size_t used = _att_lengths[type]; - PathAttribute *pa = PathAttribute::create(_att_bytes[type], - _att_lengths[type], - used, NULL, A::ip_version()); - _att[type] = pa; - s += "\n\t" + _att[type]->str(); + try { + // we've got data for an attribute, but not decoded it yet + size_t used = _att_lengths[type]; + PathAttribute *pa = PathAttribute::create(_att_bytes[type], + _att_lengths[type], + used, NULL, A::ip_version()); + _att[type] = pa; + s += "\n\t" + _att[type]->str(); + } + catch (const XorpException& e) { + s += "\n\tException: " + e.str(); + } } } return s; diff --git a/trunk/xorp/bgp/path_attribute.hh b/trunk/xorp/bgp/path_attribute.hh index d78d7fa..32d8057 100644 --- a/trunk/xorp/bgp/path_attribute.hh +++ b/trunk/xorp/bgp/path_attribute.hh @@ -35,6 +35,7 @@ #include + #include #include "exceptions.hh" // for CorruptMessage exception @@ -349,10 +350,15 @@ template class NextHopAttribute : public PathAttribute { public: - NextHopAttribute(const A& n); + NextHopAttribute(const A& n) throw(CorruptMessage); NextHopAttribute(const uint8_t* d) throw(CorruptMessage); PathAttribute *clone() const; + /* Throw exception if there are problems...do nothing + * otherwise. + */ + void verify() throw(CorruptMessage); + string str() const { return "Next Hop Attribute " + _next_hop.str(); } diff --git a/trunk/xorp/bgp/plumbing.cc b/trunk/xorp/bgp/plumbing.cc index ff48241..5d015bd 100644 --- a/trunk/xorp/bgp/plumbing.cc +++ b/trunk/xorp/bgp/plumbing.cc @@ -1105,7 +1105,14 @@ BGPPlumbingAF::add_route(const IPNet& net, pretty_string_safi(_master.safi())); rib_in = iter->second; - result = rib_in->add_route(net, pa_list, policy_tags); + try { + result = rib_in->add_route(net, pa_list, policy_tags); + } + catch(XorpException &e) { + XLOG_WARNING("Exception in add_route: %s, assuming failure\n", + e.str().c_str()); + result = ADD_FAILURE; + } if (result == ADD_USED || result == ADD_UNUSED) { _awaits_push = true; diff --git a/trunk/xorp/bgp/route_table_filter.cc b/trunk/xorp/bgp/route_table_filter.cc index 0cc3f68..0295d2b 100644 --- a/trunk/xorp/bgp/route_table_filter.cc +++ b/trunk/xorp/bgp/route_table_filter.cc @@ -201,14 +201,18 @@ NexthopRewriteFilter::filter(InternalMessage& rtmsg) const return true; } - //Form a new path attribute list containing the new nexthop - FPAListRef& palist = rtmsg.attributes(); - palist->replace_nexthop(_local_nexthop); + // This check is needed to fix crash in test2-ipv6 of test_routing1.sh + // TODO: This needs review. --Ben + if (_local_nexthop.is_unicast()) { + //Form a new path attribute list containing the new nexthop + FPAListRef& palist = rtmsg.attributes(); + palist->replace_nexthop(_local_nexthop); - //note that we changed the route - rtmsg.set_changed(); - + //note that we changed the route + rtmsg.set_changed(); + } + return true; } @@ -235,12 +239,17 @@ NexthopPeerCheckFilter::filter(InternalMessage& rtmsg) const return true; } - // The nexthop matches the peer's address so rewrite it. - FPAListRef& palist = rtmsg.attributes(); - palist->replace_nexthop(_local_nexthop); - - //note that we changed the route - rtmsg.set_changed(); + // Make sure we don't throw an exception due to :: for nexthop. + // See similar change in NexthopRewriteFilter::filter. + // TODO: This needs review. --Ben + if (_local_nexthop.is_unicast()) { + // The nexthop matches the peer's address so rewrite it. + FPAListRef& palist = rtmsg.attributes(); + palist->replace_nexthop(_local_nexthop); + + //note that we changed the route + rtmsg.set_changed(); + } return true; } diff --git a/trunk/xorp/bgp/route_table_ribin.cc b/trunk/xorp/bgp/route_table_ribin.cc index 74fbae7..ab57579 100644 --- a/trunk/xorp/bgp/route_table_ribin.cc +++ b/trunk/xorp/bgp/route_table_ribin.cc @@ -369,14 +369,22 @@ RibInTable::dump_next_route(DumpIterator& dump_iter) if (chained_rt->is_winner() || dump_iter.peer_to_dump_to() == NULL) { InternalMessage rt_msg(chained_rt, _peer, _genid); - log("dump route: " + rt_msg.net().str()); - int res = this->_next_table->route_dump(rt_msg, (BGPRouteTable*)this, - dump_iter.peer_to_dump_to()); - if(res == ADD_FILTERED) - chained_rt->set_filtered(true); - else - chained_rt->set_filtered(false); - + //XLOG_WARNING("dump route: %s", rt_msg.str().c_str()); + try { + int res = this->_next_table->route_dump(rt_msg, (BGPRouteTable*)this, + dump_iter.peer_to_dump_to()); + if(res == ADD_FILTERED) + chained_rt->set_filtered(true); + else + chained_rt->set_filtered(false); + } + catch (const XorpException& e) { + //TODO: Make sure bad routes never get into the table in the first place + // (was an IPv6 zero default route that triggered this bug initially) + // See test 28-ipv6 in harness/test_peering1.sh --Ben + XLOG_WARNING("Exception in dump_next_route: %s\n", e.str().c_str()); + XLOG_WARNING(" rt_msg: %s\n", rt_msg.str().c_str()); + } break; } } diff --git a/trunk/xorp/bgp/run_tests b/trunk/xorp/bgp/run_tests index 23dd2ec..7f5eb67 100755 --- a/trunk/xorp/bgp/run_tests +++ b/trunk/xorp/bgp/run_tests @@ -81,7 +81,7 @@ if [ $# != 1 ] then ./BGPTest $CONFIG_FILE else - . ./xrl_shell_funcs.sh + . ./bgp_xrl_shell_funcs.sh # Start a finder in the background. $FINDER & # Start a bgp process and then send it the XRL config commands. diff --git a/trunk/xorp/bgp/socket.cc b/trunk/xorp/bgp/socket.cc index e65af78..07e8976 100644 --- a/trunk/xorp/bgp/socket.cc +++ b/trunk/xorp/bgp/socket.cc @@ -230,6 +230,10 @@ SocketClient::connected(XorpFd s) XLOG_ASSERT(!get_sock().is_valid()); XLOG_ASSERT(!_connecting); + // Clean up any old reader/writers we might have around. + // This can happen if you kill network connection between two peers + // for 10 seconds and then re-start it. + async_remove(); set_sock(s); async_add(s); } @@ -528,6 +532,9 @@ SocketClient::connect_socket_complete(XorpFd sock, IoEventType type, debug_msg("connect suceeded %s\n", sock.str().c_str()); + // Clean up any old reader/writers we might have around. + // Not sure exactly how this one was triggered. + async_remove(); async_add(sock); cb->dispatch(true); return; @@ -543,7 +550,6 @@ SocketClient::connect_socket_complete(XorpFd sock, IoEventType type, void SocketClient::connect_socket_break() { - XLOG_ASSERT(_connecting); _connecting = false; eventloop().remove_ioevent_cb(get_sock()); diff --git a/trunk/xorp/bgp/tools/SConscript b/trunk/xorp/bgp/tools/SConscript index 045d9dd..ca4cf41 100644 --- a/trunk/xorp/bgp/tools/SConscript +++ b/trunk/xorp/bgp/tools/SConscript @@ -31,6 +31,9 @@ env.AppendUnique(LIBPATH = [ '$BUILDDIR/libxorp', '$BUILDDIR/libcomm', '$BUILDDIR/libxipc', + '$BUILDDIR/libfeaclient', + '$BUILDDIR/policy/backend', + '$BUILDDIR/policy/common', '$BUILDDIR/xrl/interfaces', '$BUILDDIR/xrl/targets', '$BUILDDIR/bgp', @@ -40,9 +43,19 @@ env.AppendUnique(LIBPATH = [ env.AppendUnique(LIBS = [ 'xorp_bgp', # for ASPath 'xif_bgp', + 'xorp_policy_backend', + 'xorp_policy_common', 'xorp_ipc', 'xorp_core', 'xorp_comm', + 'xif_rib', + 'xorp_fea_client', + 'xif_fea_ifmgr_mirror', + 'xst_fea_ifmgr_mirror', + 'xif_fea_ifmgr_replicator', + 'xst_bgp', + 'xif_profile_client', + 'xif_finder_event_notifier', ]) env.Replace(RPATH = [ diff --git a/trunk/xorp/libxipc/SConscript b/trunk/xorp/libxipc/SConscript index 349282b..db025c1 100644 --- a/trunk/xorp/libxipc/SConscript +++ b/trunk/xorp/libxipc/SConscript @@ -20,16 +20,19 @@ import os Import("env") -subdirs = [ 'tests' ] +env = env.Clone(); + +libxipc_env = env.Clone() -SConscript(dirs = subdirs, exports='env') +#if env['WITH_TESTS']: +subdirs = [ 'tests' ] +SConscript(dirs=subdirs, exports='env') is_shared = env.has_key('SHAREDLIBS') # # XIPC Library # -libxipc_env = env.Clone() libxipc_env.AppendUnique(CPPPATH = [ "#", @@ -217,7 +220,12 @@ xorp_finder = env.Program(target = 'xorp_finder', call_xrl = env.Program(target = 'call_xrl', source = [ 'call_xrl.cc']) -# XXX The finder and call_xrl binaries are now no longer installed -# by default, as they are not used in deployment. +# call_xrl is not required for normal use, but can be useful for +# applications wanting to configure XRL via shell scripts. +env.Alias('install', env.InstallProgram('$exec_prefix/sbin/', call_xrl)) + +#if env['WITH_TESTS']: +# env.Alias('install', env.InstallProgram(env['xorp_moduledir'], xorp_finder)) + +Default(libxipc, libfinder, call_xrl, xorp_finder) -Default(libxipc, libfinder) diff --git a/trunk/xorp/libxipc/call_xrl.cc b/trunk/xorp/libxipc/call_xrl.cc index 077bb38..31b4209 100644 --- a/trunk/xorp/libxipc/call_xrl.cc +++ b/trunk/xorp/libxipc/call_xrl.cc @@ -62,7 +62,7 @@ response_handler(const XrlError& e, if (e != XrlError::OKAY()) { XLOG_ERROR("Failed. Reason: %s (\"%s\")", e.str().c_str(), xrl->str().c_str()); - exit(-1); + exit(3); } if (!response->str().empty()) { printf("%s\n", response->str().c_str()); @@ -114,6 +114,7 @@ call_xrl(EventLoop& e, XrlRouter& router, const char* request) tries++; if (resolve_failed) { + sleep(1); continue; } @@ -303,12 +304,12 @@ main(int argc, char* const argv[]) if (true == router.failed()) { XLOG_ERROR("Router failed to communicate with finder.\n"); - exit(-1); + exit(1); } if (false == router.ready()) { XLOG_ERROR("Connected to finder, but did not become ready.\n"); - exit(-1); + exit(2); } if (fileinput) { diff --git a/trunk/xorp/libxipc/finder.cc b/trunk/xorp/libxipc/finder.cc index e9c8789..0fd3c9b 100644 --- a/trunk/xorp/libxipc/finder.cc +++ b/trunk/xorp/libxipc/finder.cc @@ -862,14 +862,21 @@ Finder::primary_instance(const string& instance_or_class) const bool Finder::add_class_watch(const string& target, - const string& class_to_watch) + const string& class_to_watch, + string& err_msg) { TargetTable::iterator i = _targets.find(target); + if (i == _targets.end()) { + err_msg += c_format("could not find target: %s in Finder::add_class_watch\n", + target.c_str()); + return false; + } - if (i != _targets.end() && i->second.add_class_watch(class_to_watch)) { + if (i->second.add_class_watch(class_to_watch)) { announce_class_instances(target, class_to_watch); return true; } + err_msg += "Class watch already existed.\n"; return false; } @@ -886,15 +893,22 @@ Finder::remove_class_watch(const string& target, bool Finder::add_instance_watch(const string& target, - const string& instance_to_watch) + const string& instance_to_watch, + string& err_msg) { TargetTable::iterator watcher_i = _targets.find(target); - if (watcher_i == _targets.end()) + if (watcher_i == _targets.end()) { + err_msg += "Could not find target: "; + err_msg += target; return false; // watcher does not exist + } TargetTable::const_iterator watched_i = _targets.find(instance_to_watch); - if (watched_i == _targets.end()) + if (watched_i == _targets.end()) { + err_msg += "Could not find instance-to-watch: "; + err_msg += instance_to_watch; return false; // watched does not exist + } FinderTarget& watcher = watcher_i->second; if (watcher.add_instance_watch(instance_to_watch)) { @@ -907,6 +921,7 @@ Finder::add_instance_watch(const string& target, watched.name()); return true; } + err_msg += "Watcher failed to add_instance_watch.\n"; return false; } diff --git a/trunk/xorp/libxipc/finder.hh b/trunk/xorp/libxipc/finder.hh index b9a6636..7e65345 100644 --- a/trunk/xorp/libxipc/finder.hh +++ b/trunk/xorp/libxipc/finder.hh @@ -91,13 +91,15 @@ public: const string& key); bool add_class_watch(const string& target, - const string& class_to_watch); + const string& class_to_watch, + string& err_msg); bool remove_class_watch(const string& target, const string& class_to_watch); bool add_instance_watch(const string& target, - const string& instance_to_watch); + const string& instance_to_watch, + string& err_msg); bool remove_instance_watch(const string& target, const string& instance_to_watch); diff --git a/trunk/xorp/libxipc/finder_xrl_target.cc b/trunk/xorp/libxipc/finder_xrl_target.cc index 0c8559b..b25a7b2 100644 --- a/trunk/xorp/libxipc/finder_xrl_target.cc +++ b/trunk/xorp/libxipc/finder_xrl_target.cc @@ -443,13 +443,16 @@ FinderXrlTarget::finder_event_notifier_0_1_register_class_event_interest( { finder_trace_init("register_class_event_interest (who = %s, class = %s)", who.c_str(), class_name.c_str()); + string err_msg; if (_finder.active_messenger_represents_target(who) == false) { finder_trace_result("messenger does not represent target."); return XrlCmdError::COMMAND_FAILED("failed (not originator)."); } - if (_finder.add_class_watch(who, class_name) == false) { - finder_trace_result("failed to add watch."); - return XrlCmdError::COMMAND_FAILED("failed to add watch"); + if (_finder.add_class_watch(who, class_name, err_msg) == false) { + string em = c_format("failed to add class event watch, who: %s class_name: %s err: %s\n", + who.c_str(), class_name.c_str(), err_msg.c_str()); + finder_trace_result("%s", em.c_str()); + return XrlCmdError::COMMAND_FAILED(em); } finder_trace_result("okay"); return XrlCmdError::OKAY(); @@ -481,15 +484,18 @@ FinderXrlTarget::finder_event_notifier_0_1_register_instance_event_interest( const string& instance_name ) { + string err_msg; finder_trace_init("register_instance_event_interest (who = %s, instance = %s)", who.c_str(), instance_name.c_str()); if (_finder.active_messenger_represents_target(who) == false) { finder_trace_result("messenger does not represent target."); return XrlCmdError::COMMAND_FAILED("failed (not originator)."); } - if (_finder.add_instance_watch(who, instance_name) == false) { - finder_trace_result("failed to add watch."); - return XrlCmdError::COMMAND_FAILED("failed to add watch"); + if (_finder.add_instance_watch(who, instance_name, err_msg) == false) { + string em = c_format("failed to add instance event watch, who: %s instance_name: %s err: %s\n", + who.c_str(), instance_name.c_str(), err_msg.c_str()); + finder_trace_result("%s", em.c_str()); + return XrlCmdError::COMMAND_FAILED(em.c_str()); } finder_trace_result("okay"); return XrlCmdError::OKAY(); diff --git a/trunk/xorp/utils/runit.cc b/trunk/xorp/utils/runit.cc index 2843d03..eb10fc4 100644 --- a/trunk/xorp/utils/runit.cc +++ b/trunk/xorp/utils/runit.cc @@ -136,8 +136,15 @@ xorp_spawn(const string& process, const char *output = NULL) exit(-1); } - execv(argv[0], argv); - cerr << "Failed to exec: " << process << endl; + errno = 0; + execvp(argv[0], argv); + cerr << "\nFailed to exec: " << process << " errno: " + << strerror(errno) << " argv[0]: " << argv[0] + << " argv: "; + + for (unsigned int i = 0; i