Index: fea/xrl_target.cc =================================================================== RCS file: /usr/local/share/doc/apache/cvs/xorp/fea/xrl_target.cc,v retrieving revision 1.82 diff -u -p -r1.82 xrl_target.cc --- fea/xrl_target.cc 15 Jun 2006 06:04:36 -0000 1.82 +++ fea/xrl_target.cc 21 Jul 2006 18:22:30 -0000 @@ -44,6 +44,29 @@ #include "xrl_target.hh" #include "profile_vars.hh" +typedef enum batch_request_op { + BATCH_OP_ADD = 1, + BATCH_OP_DELETE, + BATCH_OP_REPLACE +} BatchRequestOp; + +template +class BatchRequest { +public: + BatchRequest(const BatchRequestOp op) {} + ~BatchRequest() {} + +public: /* XXX should make private */ + BatchRequestOp _op; + IPNet _net; + A _nexthop; + uint32_t _metric; + uint32_t _admin_distance; + char _ifname[16]; + char _vifname[16]; + char _protocol[16]; +}; + XrlFeaTarget::XrlFeaTarget(EventLoop& e, XrlRouter& r, FtiConfig& ftic, @@ -2139,6 +2162,80 @@ XrlFeaTarget::redist_transaction4_0_1_de } XrlCmdError +XrlFeaTarget::redist_transaction4_0_1_batch( + // Input values, + const vector& payload) +{ + static uint32_t adds = 0; + static uint32_t dels = 0; + uint32_t tid = 0; + + BatchRequest *br = reinterpret_cast *>(const_cast(&payload[0])); + +#ifndef ONE_BY_ONE + _xftm.start_transaction(tid); +#endif + +#if 0 +fprintf(stderr, + "redist_transaction4_0_1_batch(): tid=%d payload.size=%d req_cnt=%d\n", + tid, payload.size(), payload.size() / sizeof(BatchRequest)); +#endif + + while (br < reinterpret_cast *>(const_cast(&payload[payload.size()]))) { + +#if 0 +fprintf(stderr, "FEA: type=%d dst=%s nexthop=%s\n", + br->_op, br->_net.str().c_str(), br->_nexthop.str().c_str()); +#endif + bool is_connected = string(br->_protocol) == "connected"; + +#ifdef ONE_BY_ONE + _xftm.start_transaction(tid); +#endif + if (br->_op == BATCH_OP_ADD) { + adds++; + FtiTransactionManager::Operation op( + new FtiAddEntry4(_xftm.ftic(), + br->_net, br->_nexthop, + string(br->_ifname), string(br->_vifname), + br->_metric, br->_admin_distance, + /*is_xorp_route*/ true, + is_connected) + ); + _xftm.add(tid, op); + } else if (br->_op == BATCH_OP_DELETE) { + dels++; + FtiTransactionManager::Operation op( + new FtiDeleteEntry4(_xftm.ftic(), + br->_net, br->_nexthop, + string(br->_ifname), string(br->_vifname), + br->_metric, br->_admin_distance, + /*is_xorp_route*/ true, + is_connected) + ); + _xftm.add(tid, op); + } else + XLOG_FATAL("Unsupported operation"); + +#ifdef ONE_BY_ONE + _xftm.commit_transaction(tid); +#endif + *br++; + } + +#if 0 +fprintf(stderr, "FEA: adds=%d dels=%d delta=%d\n", + adds, dels, adds-dels); +#endif +#ifndef ONE_BY_ONE + return _xftm.commit_transaction(tid); +#else + return XrlCmdError::OKAY(); +#endif +} + +XrlCmdError XrlFeaTarget::redist_transaction4_0_1_delete_all_routes( // Input values, const uint32_t& tid, Index: fea/xrl_target.hh =================================================================== RCS file: /usr/local/share/doc/apache/cvs/xorp/fea/xrl_target.hh,v retrieving revision 1.59 diff -u -p -r1.59 xrl_target.hh --- fea/xrl_target.hh 15 Jun 2006 06:04:36 -0000 1.59 +++ fea/xrl_target.hh 21 Jul 2006 18:22:30 -0000 @@ -928,6 +928,13 @@ public: const string& protocol_origin); /** + * Batch multiple add / delete requests in a single XRL. + */ + XrlCmdError redist_transaction4_0_1_batch( + // Input values, + const vector& payload); + + /** * Delete all routing entries. * * @param tid the transaction ID of this transaction. Index: pim/xrl_pim_node.cc =================================================================== RCS file: /usr/local/share/doc/apache/cvs/xorp/pim/xrl_pim_node.cc,v retrieving revision 1.95 diff -u -p -r1.95 xrl_pim_node.cc --- pim/xrl_pim_node.cc 3 Jul 2006 23:33:39 -0000 1.95 +++ pim/xrl_pim_node.cc 21 Jul 2006 18:22:33 -0000 @@ -3716,6 +3716,17 @@ XrlPimNode::redist_transaction4_0_1_dele } XrlCmdError +XrlPimNode::redist_transaction4_0_1_batch( + // Input values, + const vector& payload) +{ + UNUSED(payload); + + debug_msg("redist_transaction4_0_1_batch(): "); + return XrlCmdError::OKAY(); +} + +XrlCmdError XrlPimNode::redist_transaction4_0_1_delete_all_routes( // Input values, const uint32_t& tid, Index: pim/xrl_pim_node.hh =================================================================== RCS file: /usr/local/share/doc/apache/cvs/xorp/pim/xrl_pim_node.hh,v retrieving revision 1.67 diff -u -p -r1.67 xrl_pim_node.hh --- pim/xrl_pim_node.hh 3 Jul 2006 23:33:39 -0000 1.67 +++ pim/xrl_pim_node.hh 21 Jul 2006 18:22:34 -0000 @@ -567,6 +567,13 @@ protected: const string& protocol_origin); /** + * Batch multiple add / delete requests in a single XRL. + */ + XrlCmdError redist_transaction4_0_1_batch( + // Input values, + const vector& payload); + + /** * Delete all routing entries. * * @param tid the transaction ID of this transaction. Index: rib/redist_xrl.cc =================================================================== RCS file: /usr/local/share/doc/apache/cvs/xorp/rib/redist_xrl.cc,v retrieving revision 1.29 diff -u -p -r1.29 redist_xrl.cc --- rib/redist_xrl.cc 11 Jul 2006 21:31:57 -0000 1.29 +++ rib/redist_xrl.cc 21 Jul 2006 18:22:34 -0000 @@ -35,6 +35,30 @@ #include "redist_xrl.hh" #include "profile_vars.hh" + +typedef enum batch_request_op { + BATCH_OP_ADD = 1, + BATCH_OP_DELETE, + BATCH_OP_REPLACE +} BatchRequestOp; + +template +class BatchRequest { +public: + BatchRequest(const BatchRequestOp op) {} + ~BatchRequest() {} + +public: /* XXX should make private */ + BatchRequestOp _op; + IPNet _net; + A _nexthop; + uint32_t _metric; + uint32_t _admin_distance; + char _ifname[16]; + char _vifname[16]; + char _protocol[16]; +}; + /** * Base class for RedistXrlOutput Tasks. Classes derived from this * store enough state to dispatch XRL, or other task, at some @@ -56,6 +80,12 @@ public: virtual bool dispatch(XrlRouter& xrl_router, Profile& profile) = 0; /** + * @return true if task is a batch container. Only class Batch + * should override the default! + */ + virtual bool is_batch_container() { return false; } + + /** * Get number of times dispatch() invoked on instance. */ inline uint32_t dispatch_attempts() const { return _attempts; } @@ -112,6 +142,20 @@ protected: }; template +class Batch : public RedistXrlTask +{ +public: + Batch(RedistXrlOutput* parent); + void enqueue_request(BatchRequestOp op, const IPRouteEntry& ipr); + virtual bool dispatch(XrlRouter& xrl_router, Profile& profile); + void dispatch_complete(const XrlError& xe); + virtual bool is_batch_container() { return true; } +protected: + uint32_t _req_cnt; + vector _payload; +}; + +template class StartingRouteDump : public RedistXrlTask { public: @@ -299,6 +343,88 @@ DeleteRoute::dispatch_complete(const // ---------------------------------------------------------------------------- +// Batch implementation + +template +Batch::Batch(RedistXrlOutput* parent) + : RedistXrlTask(parent), _req_cnt(0) +{ +} + +template +void +Batch::enqueue_request(BatchRequestOp op, const IPRouteEntry& ipr) +{ +#define REQSIZE sizeof(BatchRequest) + + if (_payload.size() - _payload.capacity() < REQSIZE) { + _payload.reserve(_payload.capacity() + REQSIZE * 32); + } + BatchRequest *br = + reinterpret_cast *>(&_payload[_payload.size()]); + _payload.resize(_payload.size() + REQSIZE); + + // XXX a constructor should fill in those bellow! + br->_op = op; + br->_net = ipr.net(); + br->_nexthop = ipr.nexthop_addr(); + br->_metric = ipr.metric(); + br->_admin_distance = ipr.admin_distance(); + strncpy(&br->_ifname[0], ipr.vif()->ifname().c_str(), 16); + strncpy(&br->_vifname[0], ipr.vif()->name().c_str(), 16); + strncpy(&br->_protocol[0], ipr.protocol().name().c_str(), 16); + + _req_cnt++; +} + +template <> +bool +Batch::dispatch(XrlRouter& xrl_router, Profile& profile) +{ + UNUSED(profile); + RedistXrlOutput* p = this->parent(); + +//fprintf(stderr, "Batch::dispatch: req_cnt=%d\n", _req_cnt); + XrlRedistTransaction4V0p1Client cl(&xrl_router); + return cl.send_batch(p->xrl_target_name().c_str(), + _payload, + callback(this, + &Batch::dispatch_complete) + ); +} + +template <> +bool +Batch::dispatch(XrlRouter& xrl_router, Profile& profile) +{ + UNUSED(xrl_router); + UNUSED(profile); + +fprintf(stderr, "Batch::dispatch: req_cnt=%d\n", _req_cnt); + return true; /* XXX or false? */ +} + +template +void +Batch::dispatch_complete(const XrlError& xe) +{ + if (xe == XrlError::OKAY()) { + this->signal_complete_ok(); + return; + } else if (xe == XrlError::COMMAND_FAILED()) { + XLOG_ERROR("Batch failed: %s", + xe.str().c_str()); + this->signal_complete_ok(); + return; + } + // XXX For now all errors signalled as fatal + XLOG_ERROR("Fatal error during route redistribution: %s", + xe.str().c_str()); + this->signal_fatal_failure(); +} + + +// ---------------------------------------------------------------------------- // StartingRouteDump implementation template @@ -543,7 +669,7 @@ RedistXrlOutput::start_next_task() if (t->dispatch(_xrl_router, _profile) == false) { // Dispatch of task failed. XrlRouter is presumeably // backlogged. - XLOG_WARNING("Dispatch failed, %d XRLs inflight", _inflight); + XLOG_FATAL("Dispatch failed, %d XRLs inflight", _inflight); if (_inflight == 0) { // Insert a delay and dispatch that to cause later // attempt at failing task. @@ -622,6 +748,16 @@ public: }; template +class TransactionBatch : public Batch { +public: + TransactionBatch(RedistTransactionXrlOutput* parent) + : Batch(parent) { + parent->incr_transaction_size(); + } + //virtual bool dispatch(XrlRouter& xrl_router, Profile& profile); +}; + +template class StartTransaction : public RedistXrlTask { public: StartTransaction(RedistTransactionXrlOutput* parent) @@ -1018,6 +1154,32 @@ RedistTransactionXrlOutput::add_route bool no_running_tasks = (this->_queued == 0); +#define BATCHING +#ifdef BATCHING + +/* + * If SINGLE_REQUEST_PER_XRL is defined, no requests will be batched + * together, thus any performance gains we would see would be solely due + * to inefficiencies in standard vs. binary XRL encoding / parsing. + * + * This is one of those tests that Atanu hates a lot. + */ + +//#define SINGLE_REQUEST_PER_XRL + + // Make sure that the last task in the queue is a batch container. + class TransactionBatch *batch = + reinterpret_cast*>(this->_taskq.back()); +#ifdef SINGLE_REQUEST_PER_XRL + if ( 1 ) { +#else + if (batch == NULL || !batch->is_batch_container()) { +#endif + batch = new TransactionBatch(this); + enqueue_task(batch); + } + batch->enqueue_request(BATCH_OP_ADD, ipr); +#else if (this->transaction_size() == 0) this->enqueue_task(new StartTransaction(this)); @@ -1031,6 +1193,7 @@ RedistTransactionXrlOutput::add_route } enqueue_task(new AddTransactionRoute(this, ipr)); +#endif if (no_running_tasks) this->start_next_task(); } @@ -1047,6 +1210,16 @@ RedistTransactionXrlOutput::delete_ro bool no_running_tasks = (this->_queued == 0); +#ifdef BATCHING + // Make sure that the last task in the queue is a batch container. + class TransactionBatch *batch = + reinterpret_cast*>(this->_taskq.back()); + if (batch == NULL || !batch->is_batch_container()) { + batch = new TransactionBatch(this); + enqueue_task(batch); + } + batch->enqueue_request(BATCH_OP_DELETE, ipr); +#else if (this->transaction_size() == 0) enqueue_task(new StartTransaction(this)); @@ -1060,6 +1233,7 @@ RedistTransactionXrlOutput::delete_ro } enqueue_task(new DeleteTransactionRoute(this, ipr)); +#endif if (no_running_tasks) this->start_next_task(); } Index: xrl/interfaces/redist4_xif.cc =================================================================== RCS file: /usr/local/share/doc/apache/cvs/xorp/xrl/interfaces/redist4_xif.cc,v retrieving revision 1.14 diff -u -p -r1.14 redist4_xif.cc --- xrl/interfaces/redist4_xif.cc 30 Mar 2006 02:21:15 -0000 1.14 +++ xrl/interfaces/redist4_xif.cc 21 Jul 2006 18:22:35 -0000 @@ -7,7 +7,7 @@ * Generated by 'clnt-gen'. */ -#ident "$XORP: xorp/xrl/interfaces/redist4_xif.cc,v 1.14 2006/03/30 02:21:15 pavlin Exp $" +#ident "$XORP$" #include "redist4_xif.hh" Index: xrl/interfaces/redist_transaction4.xif =================================================================== RCS file: /usr/local/share/doc/apache/cvs/xorp/xrl/interfaces/redist_transaction4.xif,v retrieving revision 1.9 diff -u -p -r1.9 redist_transaction4.xif --- xrl/interfaces/redist_transaction4.xif 30 Mar 2006 02:21:16 -0000 1.9 +++ xrl/interfaces/redist_transaction4.xif 21 Jul 2006 18:22:35 -0000 @@ -66,6 +66,11 @@ interface redist_transaction4/0.1 { & protocol_origin:txt /** + * Batch multiple add / delete requests in a single XRL. + */ + batch ? payload:binary + + /** * Delete all routing entries. * * @param tid the transaction ID of this transaction. Index: xrl/interfaces/redist_transaction4_xif.cc =================================================================== RCS file: /usr/local/share/doc/apache/cvs/xorp/xrl/interfaces/redist_transaction4_xif.cc,v retrieving revision 1.13 diff -u -p -r1.13 redist_transaction4_xif.cc --- xrl/interfaces/redist_transaction4_xif.cc 30 Mar 2006 02:21:16 -0000 1.13 +++ xrl/interfaces/redist_transaction4_xif.cc 21 Jul 2006 18:22:35 -0000 @@ -210,6 +210,38 @@ XrlRedistTransaction4V0p1Client::unmarsh } bool +XrlRedistTransaction4V0p1Client::send_batch( + const char* dst_xrl_target_name, + const vector& payload, + const BatchCB& cb +) +{ + Xrl x(dst_xrl_target_name, "redist_transaction4/0.1/batch"); + x.args().add("payload", payload); + return _sender->send(x, callback(this, &XrlRedistTransaction4V0p1Client::unmarshall_batch, cb)); +} + + +/* Unmarshall batch */ +void +XrlRedistTransaction4V0p1Client::unmarshall_batch( + const XrlError& e, + XrlArgs* a, + BatchCB cb +) +{ + if (e != XrlError::OKAY()) { + cb->dispatch(e); + return; + } else if (a && a->size() != 0) { + XLOG_ERROR("Wrong number of arguments (%u != %u)", XORP_UINT_CAST(a->size()), XORP_UINT_CAST(0)); + cb->dispatch(XrlError::BAD_ARGS()); + return; + } + cb->dispatch(e); +} + +bool XrlRedistTransaction4V0p1Client::send_delete_all_routes( const char* dst_xrl_target_name, const uint32_t& tid, Index: xrl/interfaces/redist_transaction4_xif.hh =================================================================== RCS file: /usr/local/share/doc/apache/cvs/xorp/xrl/interfaces/redist_transaction4_xif.hh,v retrieving revision 1.13 diff -u -p -r1.13 redist_transaction4_xif.hh --- xrl/interfaces/redist_transaction4_xif.hh 30 Mar 2006 02:21:16 -0000 1.13 +++ xrl/interfaces/redist_transaction4_xif.hh 21 Jul 2006 18:22:35 -0000 @@ -132,6 +132,20 @@ public: const DeleteRouteCB& cb ); + typedef XorpCallback1::RefPtr BatchCB; + /** + * Send Xrl intended to: + * + * Batch multiple add / delete requests in a single XRL. + * + * @param dst_xrl_target_name the Xrl target name of the destination. + */ + bool send_batch( + const char* dst_xrl_target_name, + const vector& payload, + const BatchCB& cb + ); + typedef XorpCallback1::RefPtr DeleteAllRoutesCB; /** * Send Xrl intended to: @@ -186,6 +200,12 @@ private: DeleteRouteCB cb ); + void unmarshall_batch( + const XrlError& e, + XrlArgs* a, + BatchCB cb + ); + void unmarshall_delete_all_routes( const XrlError& e, XrlArgs* a, Index: xrl/targets/fea.xrls =================================================================== RCS file: /usr/local/share/doc/apache/cvs/xorp/xrl/targets/fea.xrls,v retrieving revision 1.57 diff -u -p -r1.57 fea.xrls --- xrl/targets/fea.xrls 15 Jun 2006 06:02:44 -0000 1.57 +++ xrl/targets/fea.xrls 21 Jul 2006 18:22:35 -0000 @@ -553,6 +553,11 @@ finder://fea/redist_transaction4/0.1/add finder://fea/redist_transaction4/0.1/delete_route?tid:u32&dst:ipv4net&nexthop:ipv4&ifname:txt&vifname:txt&metric:u32&admin_distance:u32&cookie:txt&protocol_origin:txt /** + * Batch multiple add / delete requests in a single XRL. + */ +finder://fea/redist_transaction4/0.1/batch?payload:binary + +/** * Delete all routing entries. * * @param tid the transaction ID of this transaction. Index: xrl/targets/fea_base.cc =================================================================== RCS file: /usr/local/share/doc/apache/cvs/xorp/xrl/targets/fea_base.cc,v retrieving revision 1.61 diff -u -p -r1.61 fea_base.cc --- xrl/targets/fea_base.cc 15 Jun 2006 06:02:44 -0000 1.61 +++ xrl/targets/fea_base.cc 21 Jul 2006 18:22:36 -0000 @@ -3883,6 +3883,31 @@ XrlFeaTargetBase::handle_redist_transact } const XrlCmdError +XrlFeaTargetBase::handle_redist_transaction4_0_1_batch(const XrlArgs& xa_inputs, XrlArgs* /* pxa_outputs */) +{ + if (xa_inputs.size() != 1) { + XLOG_ERROR("Wrong number of arguments (%u != %u) handling %s", + XORP_UINT_CAST(1), XORP_UINT_CAST(xa_inputs.size()), "redist_transaction4/0.1/batch"); + return XrlCmdError::BAD_ARGS(); + } + + /* Return value declarations */ + try { + XrlCmdError e = redist_transaction4_0_1_batch( + xa_inputs.get_binary("payload")); + if (e != XrlCmdError::OKAY()) { + XLOG_WARNING("Handling method for %s failed: %s", + "redist_transaction4/0.1/batch", e.str().c_str()); + return e; + } + } catch (const XrlArgs::XrlAtomNotFound& e) { + XLOG_ERROR("Argument not found"); + return XrlCmdError::BAD_ARGS(); + } + return XrlCmdError::OKAY(); +} + +const XrlCmdError XrlFeaTargetBase::handle_redist_transaction4_0_1_delete_all_routes(const XrlArgs& xa_inputs, XrlArgs* /* pxa_outputs */) { if (xa_inputs.size() != 2) { @@ -5058,6 +5083,10 @@ XrlFeaTargetBase::add_handlers() callback(this, &XrlFeaTargetBase::handle_redist_transaction4_0_1_delete_route)) == false) { XLOG_ERROR("Failed to xrl handler finder://%s/%s", "fea", "redist_transaction4/0.1/delete_route"); } + if (_cmds->add_handler("redist_transaction4/0.1/batch", + callback(this, &XrlFeaTargetBase::handle_redist_transaction4_0_1_batch)) == false) { + XLOG_ERROR("Failed to xrl handler finder://%s/%s", "fea", "redist_transaction4/0.1/batch"); + } if (_cmds->add_handler("redist_transaction4/0.1/delete_all_routes", callback(this, &XrlFeaTargetBase::handle_redist_transaction4_0_1_delete_all_routes)) == false) { XLOG_ERROR("Failed to xrl handler finder://%s/%s", "fea", "redist_transaction4/0.1/delete_all_routes"); @@ -5273,6 +5302,7 @@ XrlFeaTargetBase::remove_handlers() _cmds->remove_handler("redist_transaction4/0.1/abort_transaction"); _cmds->remove_handler("redist_transaction4/0.1/add_route"); _cmds->remove_handler("redist_transaction4/0.1/delete_route"); + _cmds->remove_handler("redist_transaction4/0.1/batch"); _cmds->remove_handler("redist_transaction4/0.1/delete_all_routes"); _cmds->remove_handler("redist_transaction6/0.1/start_transaction"); _cmds->remove_handler("redist_transaction6/0.1/commit_transaction"); Index: xrl/targets/fea_base.hh =================================================================== RCS file: /usr/local/share/doc/apache/cvs/xorp/xrl/targets/fea_base.hh,v retrieving revision 1.64 diff -u -p -r1.64 fea_base.hh --- xrl/targets/fea_base.hh 15 Jun 2006 06:02:44 -0000 1.64 +++ xrl/targets/fea_base.hh 21 Jul 2006 18:22:36 -0000 @@ -1184,6 +1184,15 @@ protected: /** * Pure-virtual function that needs to be implemented to: * + * Batch multiple add / delete requests in a single XRL. + */ + virtual XrlCmdError redist_transaction4_0_1_batch( + // Input values, + const vector& payload) = 0; + + /** + * Pure-virtual function that needs to be implemented to: + * * Delete all routing entries. * * @param tid the transaction ID of this transaction. @@ -1898,6 +1907,8 @@ private: const XrlCmdError handle_redist_transaction4_0_1_delete_route(const XrlArgs& in, XrlArgs* out); + const XrlCmdError handle_redist_transaction4_0_1_batch(const XrlArgs& in, XrlArgs* out); + const XrlCmdError handle_redist_transaction4_0_1_delete_all_routes(const XrlArgs& in, XrlArgs* out); const XrlCmdError handle_redist_transaction6_0_1_start_transaction(const XrlArgs& in, XrlArgs* out); Index: xrl/targets/pim.xrls =================================================================== RCS file: /usr/local/share/doc/apache/cvs/xorp/xrl/targets/pim.xrls,v retrieving revision 1.51 diff -u -p -r1.51 pim.xrls --- xrl/targets/pim.xrls 3 Jul 2006 23:33:42 -0000 1.51 +++ xrl/targets/pim.xrls 21 Jul 2006 18:22:36 -0000 @@ -300,6 +300,11 @@ finder://pim/redist_transaction4/0.1/add finder://pim/redist_transaction4/0.1/delete_route?tid:u32&dst:ipv4net&nexthop:ipv4&ifname:txt&vifname:txt&metric:u32&admin_distance:u32&cookie:txt&protocol_origin:txt /** + * Batch multiple add / delete requests in a single XRL. + */ +finder://pim/redist_transaction4/0.1/batch?payload:binary + +/** * Delete all routing entries. * * @param tid the transaction ID of this transaction. Index: xrl/targets/pim_base.cc =================================================================== RCS file: /usr/local/share/doc/apache/cvs/xorp/xrl/targets/pim_base.cc,v retrieving revision 1.54 diff -u -p -r1.54 pim_base.cc --- xrl/targets/pim_base.cc 3 Jul 2006 23:33:43 -0000 1.54 +++ xrl/targets/pim_base.cc 21 Jul 2006 18:22:38 -0000 @@ -911,6 +911,31 @@ XrlPimTargetBase::handle_redist_transact } const XrlCmdError +XrlPimTargetBase::handle_redist_transaction4_0_1_batch(const XrlArgs& xa_inputs, XrlArgs* /* pxa_outputs */) +{ + if (xa_inputs.size() != 1) { + XLOG_ERROR("Wrong number of arguments (%u != %u) handling %s", + XORP_UINT_CAST(1), XORP_UINT_CAST(xa_inputs.size()), "redist_transaction4/0.1/batch"); + return XrlCmdError::BAD_ARGS(); + } + + /* Return value declarations */ + try { + XrlCmdError e = redist_transaction4_0_1_batch( + xa_inputs.get_binary("payload")); + if (e != XrlCmdError::OKAY()) { + XLOG_WARNING("Handling method for %s failed: %s", + "redist_transaction4/0.1/batch", e.str().c_str()); + return e; + } + } catch (const XrlArgs::XrlAtomNotFound& e) { + XLOG_ERROR("Argument not found"); + return XrlCmdError::BAD_ARGS(); + } + return XrlCmdError::OKAY(); +} + +const XrlCmdError XrlPimTargetBase::handle_redist_transaction4_0_1_delete_all_routes(const XrlArgs& xa_inputs, XrlArgs* /* pxa_outputs */) { if (xa_inputs.size() != 2) { @@ -9046,6 +9071,10 @@ XrlPimTargetBase::add_handlers() callback(this, &XrlPimTargetBase::handle_redist_transaction4_0_1_delete_route)) == false) { XLOG_ERROR("Failed to xrl handler finder://%s/%s", "pim", "redist_transaction4/0.1/delete_route"); } + if (_cmds->add_handler("redist_transaction4/0.1/batch", + callback(this, &XrlPimTargetBase::handle_redist_transaction4_0_1_batch)) == false) { + XLOG_ERROR("Failed to xrl handler finder://%s/%s", "pim", "redist_transaction4/0.1/batch"); + } if (_cmds->add_handler("redist_transaction4/0.1/delete_all_routes", callback(this, &XrlPimTargetBase::handle_redist_transaction4_0_1_delete_all_routes)) == false) { XLOG_ERROR("Failed to xrl handler finder://%s/%s", "pim", "redist_transaction4/0.1/delete_all_routes"); @@ -10023,6 +10052,7 @@ XrlPimTargetBase::remove_handlers() _cmds->remove_handler("redist_transaction4/0.1/abort_transaction"); _cmds->remove_handler("redist_transaction4/0.1/add_route"); _cmds->remove_handler("redist_transaction4/0.1/delete_route"); + _cmds->remove_handler("redist_transaction4/0.1/batch"); _cmds->remove_handler("redist_transaction4/0.1/delete_all_routes"); _cmds->remove_handler("redist_transaction6/0.1/start_transaction"); _cmds->remove_handler("redist_transaction6/0.1/commit_transaction"); Index: xrl/targets/pim_base.hh =================================================================== RCS file: /usr/local/share/doc/apache/cvs/xorp/xrl/targets/pim_base.hh,v retrieving revision 1.58 diff -u -p -r1.58 pim_base.hh --- xrl/targets/pim_base.hh 3 Jul 2006 23:33:43 -0000 1.58 +++ xrl/targets/pim_base.hh 21 Jul 2006 18:22:38 -0000 @@ -561,6 +561,15 @@ protected: /** * Pure-virtual function that needs to be implemented to: * + * Batch multiple add / delete requests in a single XRL. + */ + virtual XrlCmdError redist_transaction4_0_1_batch( + // Input values, + const vector& payload) = 0; + + /** + * Pure-virtual function that needs to be implemented to: + * * Delete all routing entries. * * @param tid the transaction ID of this transaction. @@ -2285,6 +2294,8 @@ private: const XrlCmdError handle_redist_transaction4_0_1_delete_route(const XrlArgs& in, XrlArgs* out); + const XrlCmdError handle_redist_transaction4_0_1_batch(const XrlArgs& in, XrlArgs* out); + const XrlCmdError handle_redist_transaction4_0_1_delete_all_routes(const XrlArgs& in, XrlArgs* out); const XrlCmdError handle_redist_transaction6_0_1_start_transaction(const XrlArgs& in, XrlArgs* out);