[Xorp-hackers] [PATCH REVISED] FIB upcall/event support,

Bruce M Simpson bms@spc.org
Fri, 5 Nov 2004 16:36:05 -0800


--azLHFNyN32YCQGCU
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Fri, Nov 05, 2004 at 02:08:52PM -0800, Bruce M Simpson wrote:
> The last part missing is the wiring-up of these upcall notifications to
> the XrlFtiTransactionManager, by way of the FibTableObserver and
> FtiConfigTableObserver::propagate_fib_changes(); that will come next.

I've added this now. Attached.

BMS

--azLHFNyN32YCQGCU
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="fea-rtm-upcalls2.diff"

Revised patch to add the route resolve/miss notifications.

Don't much like having to add new state to Fte, but as we use
Fte for mass-shipping of forwarding table state to FIB clients,
there is no other clean solution.

Fixes a typo where I typed UPCALLS when I meant CHANGES.

Could probably do with using a bit-set vector instead of an
enum where FtiRtmParseType is concerned, as it would save
another downcall to the rtm layer.

What this doesn't do is add the stuff necessary for an external
FIB observer to say 'I'm not interested in route misses'.

Index: fte.hh
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/fea/fte.hh,v
retrieving revision 1.12
diff -u -p -r1.12 fte.hh
--- fte.hh	5 Nov 2004 00:47:27 -0000	1.12
+++ fte.hh	6 Nov 2004 00:29:39 -0000
@@ -45,7 +45,7 @@ public:
 	bool		xorp_route)
 	: _net(net), _nexthop(nexthop), _ifname(ifname), _vifname(vifname),
 	  _metric(metric), _admin_distance(admin_distance),
-	  _xorp_route(xorp_route), _is_deleted(false) {}
+	  _xorp_route(xorp_route), _is_deleted(false), _is_upcall(false) {}
     Fte(const N& net)
 	: _net(net), _nexthop(A::ZERO(net.af())),
 	  _metric(0), _admin_distance(0), _xorp_route(false) {}
@@ -59,6 +59,8 @@ public:
     bool	xorp_route() const 	{ return _xorp_route; }
     bool	is_deleted() const	{ return _is_deleted; }
     void	mark_deleted()		{ _is_deleted = true; }
+    bool	is_upcall() const	{ return _is_upcall; }
+    void	mark_upcall()		{ _is_upcall = true; }
 
     /**
      * Reset all members
@@ -72,6 +74,7 @@ public:
 	_admin_distance = 0;
 	_xorp_route = false;
 	_is_deleted = false;
+	_is_upcall = false;
     }
 
     /**
@@ -90,12 +93,13 @@ public:
     string str() const {
 	return c_format("net = %s nexthop = %s ifname = %s vifname = %s "
 			"metric = %u admin_distance = %u xorp_route = %s "
-			"is_deleted = %s",
+			"is_deleted = %s is_upcall = %s",
 			_net.str().c_str(), _nexthop.str().c_str(),
 			_ifname.c_str(), _vifname.c_str(),
 			_metric, _admin_distance,
 			_xorp_route ? "true" : "false",
-			_is_deleted ? "true" : "false");
+			_is_deleted ? "true" : "false",
+			_is_upcall ? "true" : "false");
     }
 
 private:
@@ -107,6 +111,8 @@ private:
     uint32_t	_admin_distance;	// Route admin distance
     bool	_xorp_route;		// This route was installed by XORP
     bool	_is_deleted;		// True if the entry was deleted
+    bool	_is_upcall;		// True if the entry is actually
+					// an upcall notification
 };
 
 typedef Fte<IPv4, IPv4Net> Fte4;
Index: fticonfig.hh
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/fea/fticonfig.hh,v
retrieving revision 1.23
diff -u -p -r1.23 fticonfig.hh
--- fticonfig.hh	5 Nov 2004 00:47:43 -0000	1.23
+++ fticonfig.hh	6 Nov 2004 00:29:39 -0000
@@ -25,6 +25,15 @@
 #include "libxorp/trie.hh"
 
 #include "fte.hh"
+
+// Knobs for parse_buffer_rtm() in routing socket FtiConfig implementation
+// to denote what caller is interested in.
+enum FtiRtmParseType {
+   CHANGES,		// RTM_ADD, RTM_CHANGE, RTM_DELETE, RTM_GET.
+   GET,			// RTM_GET only.
+   UPCALLS		// RTM_MISS and RTM_RESOLVE.
+};
+
 #include "fticonfig_entry_get.hh"
 #include "fticonfig_entry_set.hh"
 #include "fticonfig_entry_observer.hh"
Index: fticonfig_entry_get.hh
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/fea/fticonfig_entry_get.hh,v
retrieving revision 1.17
diff -u -p -r1.17 fticonfig_entry_get.hh
--- fticonfig_entry_get.hh	26 Oct 2004 23:58:29 -0000	1.17
+++ fticonfig_entry_get.hh	6 Nov 2004 00:29:39 -0000
@@ -110,12 +110,12 @@ public:
      * @param fte the Fte storage to store the parsed information.
      * @param buf the buffer with the data to parse.
      * @param buf_bytes buf_bytes the size of the data in the buffer.
-     * @param is_rtm_get_only if true, consider only the RTM_GET entries.
+     * @param type the subset of RTM messages that caller is interested in.
      * @return true on success, otherwise false.
      * @see FteX.
      */
     bool parse_buffer_rtm(FteX& fte, const uint8_t *buf, size_t buf_bytes,
-			  bool is_rtm_get_only);
+			  FtiRtmParseType type);
 
     /**
      * Parse information about routing entry information received from
Index: fticonfig_entry_get_rtsock.cc
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/fea/fticonfig_entry_get_rtsock.cc,v
retrieving revision 1.21
diff -u -p -r1.21 fticonfig_entry_get_rtsock.cc
--- fticonfig_entry_get_rtsock.cc	26 Oct 2004 23:55:16 -0000	1.21
+++ fticonfig_entry_get_rtsock.cc	6 Nov 2004 00:29:39 -0000
@@ -303,7 +303,7 @@ FtiConfigEntryGetRtsock::lookup_route_by
 	return (false);
     }
     if (parse_buffer_rtm(fte, _rs_reader.buffer(), _rs_reader.buffer_size(),
-			 true)
+			 FtiRtmParseType(GET))
 	!= true) {
 	return (false);
     }
@@ -446,7 +446,7 @@ FtiConfigEntryGetRtsock::lookup_route_by
 	return (false);
     }
     if (parse_buffer_rtm(fte, _rs_reader.buffer(), _rs_reader.buffer_size(),
-			 true)
+			 FtiRtmParseType(GET))
 	!= true) {
 	return (false);
     }
Index: fticonfig_entry_parse_rtm.cc
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/fea/fticonfig_entry_parse_rtm.cc,v
retrieving revision 1.7
diff -u -p -r1.7 fticonfig_entry_parse_rtm.cc
--- fticonfig_entry_parse_rtm.cc	5 Nov 2004 01:27:53 -0000	1.7
+++ fticonfig_entry_parse_rtm.cc	6 Nov 2004 00:29:39 -0000
@@ -39,7 +39,8 @@
 
 #ifndef HAVE_ROUTING_SOCKETS
 bool
-FtiConfigEntryGet::parse_buffer_rtm(FteX& , const uint8_t* , size_t , bool )
+FtiConfigEntryGet::parse_buffer_rtm(FteX& , const uint8_t* , size_t ,
+				    FtiRtmParseType)
 {
     return false;
 }
@@ -48,13 +49,14 @@ FtiConfigEntryGet::parse_buffer_rtm(FteX
 
 bool
 FtiConfigEntryGet::parse_buffer_rtm(FteX& fte, const uint8_t* buf,
-				    size_t buf_bytes, bool is_rtm_get_only)
+				    size_t buf_bytes, FtiRtmParseType type)
 {
-    const struct rt_msghdr* rtm = reinterpret_cast<const struct rt_msghdr*>(buf);
+    const struct rt_msghdr* rtm =
+	reinterpret_cast<const struct rt_msghdr*>(buf);
     const uint8_t* last = buf + buf_bytes;
-    
+
     for (const uint8_t* ptr = buf; ptr < last; ptr += rtm->rtm_msglen) {
-    	rtm = reinterpret_cast<const struct rt_msghdr*>(ptr);
+	rtm = reinterpret_cast<const struct rt_msghdr*>(ptr);
 	if (RTM_VERSION != rtm->rtm_version) {
 	    XLOG_ERROR("RTM version mismatch: expected %d got %d",
 		       RTM_VERSION,
@@ -62,30 +64,35 @@ FtiConfigEntryGet::parse_buffer_rtm(FteX
 	    continue;
 	}
 
-	if (is_rtm_get_only) {
-	    //
-	    // Consider only the RTM_GET entries.
-	    //
-	    if (rtm->rtm_type != RTM_GET)
+	// XXX: ignore entries with an error
+	if (rtm->rtm_errno != 0)
+	    continue;
+
+	if (type == FtiRtmParseType(GET)) {
+	    if ((rtm->rtm_type != RTM_GET) || !(rtm->rtm_flags & RTF_UP))
+		continue;
+	} else if (type == FtiRtmParseType(UPCALLS)) {
+	    // Upcalls may not be supported in some implementations.
+#ifdef RTM_MISS
+	    if (rtm->rtm_type != RTM_MISS)
+		continue;
+#endif
+#ifdef RTM_RESOLVE
+	    if (rtm->rtm_type != RTM_RESOLVE)
 		continue;
-	    if (! (rtm->rtm_flags & RTF_UP))
+#endif
+	} else if (type == FtiRtmParseType(CHANGES)) {
+	    if ((rtm->rtm_type != RTM_ADD) && (rtm->rtm_type != RTM_DELETE) &&
+		(rtm->rtm_type != RTM_CHANGE) && (rtm->rtm_type != RTM_GET))
 		continue;
+	} else {
+		return (false);
 	}
 
-	if ((rtm->rtm_type != RTM_ADD)
-	    && (rtm->rtm_type != RTM_DELETE)
-	    && (rtm->rtm_type != RTM_CHANGE)
-	    && (rtm->rtm_type != RTM_GET)) {
-	    continue;
-        }
-
-	if (rtm->rtm_errno != 0)
-	    continue;		// XXX: ignore entries with an error
-	
 	return (RtmUtils::rtm_get_to_fte_cfg(fte, ftic().iftree(), rtm));
     }
-    
-    return false;
+
+    return (false);
 }
 
 #endif // HAVE_ROUTING_SOCKETS
Index: fticonfig_table_get.hh
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/fea/fticonfig_table_get.hh,v
retrieving revision 1.14
diff -u -p -r1.14 fticonfig_table_get.hh
--- fticonfig_table_get.hh	26 Oct 2004 23:58:29 -0000	1.14
+++ fticonfig_table_get.hh	6 Nov 2004 00:29:39 -0000
@@ -91,12 +91,12 @@ public:
      * @param fte_list the list with the Fte entries to store the result.
      * @param buf the buffer with the data to parse.
      * @param buf_bytes the size of the data in the buffer.
-     * @param is_rtm_get_only if true, consider only the RTM_GET entries.
+     * @param type the subset of RTM messages that caller is interested in.
      * @return true on success, otherwise false.
      * @see FteX.
      */
     bool parse_buffer_rtm(int family, list<FteX>& fte_list, const uint8_t *buf,
-			  size_t buf_bytes, bool is_rtm_get_only);
+			  size_t buf_bytes, FtiRtmParseType type);
 
     /**
      * Parse information about routing table information received from
Index: fticonfig_table_get_sysctl.cc
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/fea/fticonfig_table_get_sysctl.cc,v
retrieving revision 1.13
diff -u -p -r1.13 fticonfig_table_get_sysctl.cc
--- fticonfig_table_get_sysctl.cc	1 Sep 2004 18:12:24 -0000	1.13
+++ fticonfig_table_get_sysctl.cc	6 Nov 2004 00:29:39 -0000
@@ -179,7 +179,8 @@ FtiConfigTableGetSysctl::get_table(int f
 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), table_data, &sz, NULL, 0)
 	    == 0) {
 	    // Parse the result
-	    return (parse_buffer_rtm(family, fte_list, table_data, sz, true));
+	    return (parse_buffer_rtm(family, fte_list, table_data, sz,
+				     FtiRtmParseType(GET)));
 	}
 	
 	// Error
Index: fticonfig_table_observer.cc
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/fea/fticonfig_table_observer.cc,v
retrieving revision 1.7
diff -u -p -r1.7 fticonfig_table_observer.cc
--- fticonfig_table_observer.cc	21 Oct 2004 00:10:25 -0000	1.7
+++ fticonfig_table_observer.cc	6 Nov 2004 00:29:39 -0000
@@ -126,6 +126,8 @@ FtiConfigTableObserver::propagate_fib_ch
 			     ftex.xorp_route());
 	    if (ftex.is_deleted())
 		fte4.mark_deleted();
+	    if (ftex.is_upcall())
+		fte4.mark_upcall();
 	    fte_list4.push_back(fte4);
 	}
 
@@ -140,6 +142,8 @@ FtiConfigTableObserver::propagate_fib_ch
 			     ftex.xorp_route());
 	    if (ftex.is_deleted())
 		fte6.mark_deleted();
+	    if (ftex.is_upcall())
+		fte6.mark_upcall();
 	    fte_list6.push_back(fte6);
 	}
     }
Index: fticonfig_table_observer_rtsock.cc
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/fea/fticonfig_table_observer_rtsock.cc,v
retrieving revision 1.10
diff -u -p -r1.10 fticonfig_table_observer_rtsock.cc
--- fticonfig_table_observer_rtsock.cc	1 Sep 2004 18:12:25 -0000	1.10
+++ fticonfig_table_observer_rtsock.cc	6 Nov 2004 00:29:39 -0000
@@ -93,7 +93,12 @@ FtiConfigTableObserverRtsock::receive_da
     //
     if (ftic().have_ipv4()) {
 	ftic().ftic_table_get_primary().parse_buffer_rtm(AF_INET, fte_list,
-							 data, nbytes, false);
+				 data, nbytes, FtiRtmParseType(CHANGES));
+#if 1
+	// Upcalls too. XXX Change this enum to a set?
+	ftic().ftic_table_get_primary().parse_buffer_rtm(AF_INET, fte_list,
+				 data, nbytes, FtiRtmParseType(UPCALLS));
+#endif
 	if (! fte_list.empty()) {
 	    propagate_fib_changes(fte_list);
 	    fte_list.clear();
@@ -106,7 +111,7 @@ FtiConfigTableObserverRtsock::receive_da
     //
     if (ftic().have_ipv6()) {
 	ftic().ftic_table_get_primary().parse_buffer_rtm(AF_INET6, fte_list,
-							 data, nbytes, false);
+				 data, nbytes, FtiRtmParseType(CHANGES));
 	if (! fte_list.empty()) {
 	    propagate_fib_changes(fte_list);
 	    fte_list.clear();
Index: fticonfig_table_parse_rtm.cc
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/fea/fticonfig_table_parse_rtm.cc,v
retrieving revision 1.10
diff -u -p -r1.10 fticonfig_table_parse_rtm.cc
--- fticonfig_table_parse_rtm.cc	5 Nov 2004 01:27:53 -0000	1.10
+++ fticonfig_table_parse_rtm.cc	6 Nov 2004 00:29:39 -0000
@@ -40,7 +40,7 @@
 #ifndef HAVE_ROUTING_SOCKETS
 bool
 FtiConfigTableGet::parse_buffer_rtm(int, list<FteX>& , const uint8_t* ,
-				    size_t , bool )
+				    size_t , FtiRtmParseType type)
 {
     return false;
 }
@@ -50,13 +50,14 @@ FtiConfigTableGet::parse_buffer_rtm(int,
 bool
 FtiConfigTableGet::parse_buffer_rtm(int family, list<FteX>& fte_list,
 				    const uint8_t* buf, size_t buf_bytes,
-				    bool is_rtm_get_only)
+				    FtiRtmParseType type)
 {
-    const struct rt_msghdr* rtm = reinterpret_cast<const struct rt_msghdr *>(buf);
+    const struct rt_msghdr* rtm =
+	reinterpret_cast<const struct rt_msghdr *>(buf);
     const uint8_t* last = buf + buf_bytes;
-    
+
     for (const uint8_t* ptr = buf; ptr < last; ptr += rtm->rtm_msglen) {
-    	rtm = reinterpret_cast<const struct rt_msghdr *>(ptr);
+	rtm = reinterpret_cast<const struct rt_msghdr *>(ptr);
 	if (RTM_VERSION != rtm->rtm_version) {
 	    XLOG_ERROR("RTM version mismatch: expected %d got %d",
 		       RTM_VERSION,
@@ -64,25 +65,31 @@ FtiConfigTableGet::parse_buffer_rtm(int 
 	    continue;
 	}
 
-	if (is_rtm_get_only) {
-	    //
-	    // Consider only the RTM_GET entries.
-	    //
-	    if (rtm->rtm_type != RTM_GET)
-		continue;
-	    if (! (rtm->rtm_flags & RTF_UP))
+	if (rtm->rtm_errno != 0)
+	    continue;		// XXX: ignore entries with an error
+
+	if (type == FtiRtmParseType(GET)) {
+	    if ((rtm->rtm_type != RTM_GET) || (!(rtm->rtm_flags & RTF_UP)))
 		continue;
 	}
 
-	if ((rtm->rtm_type != RTM_ADD)
-	    && (rtm->rtm_type != RTM_DELETE)
-	    && (rtm->rtm_type != RTM_CHANGE)
-	    && (rtm->rtm_type != RTM_GET)) {
-	    continue;
+	// Upcalls may not be supported in some BSD derived implementations.
+	if (type == FtiRtmParseType(UPCALLS)) {
+#ifdef RTM_MISS
+	    if (rtm->rtm_type != RTM_MISS)
+		continue;
+#endif
+#ifdef RTM_RESOLVE
+	    if (rtm->rtm_type != RTM_RESOLVE)
+		continue;
+#endif
 	}
 
-	if (rtm->rtm_errno != 0)
-	    continue;		// XXX: ignore entries with an error
+	if (type == FtiRtmParseType(CHANGES)) {
+	    if ((rtm->rtm_type != RTM_ADD) && (rtm->rtm_type != RTM_DELETE) &&
+		(rtm->rtm_type != RTM_CHANGE) && (rtm->rtm_type != RTM_GET))
+		    continue;
+	}
 
 #ifdef RTF_LLINFO
 	if (rtm->rtm_flags & RTF_LLINFO)
@@ -104,12 +111,15 @@ FtiConfigTableGet::parse_buffer_rtm(int 
 	if (rtm->rtm_flags & RTF_BROADCAST)
 	    continue;		// XXX: ignore broadcast entries
 #endif
-	
+
 	FteX fte(family);
-	if (RtmUtils::rtm_get_to_fte_cfg(fte, ftic().iftree(), rtm) == true)
+	if (RtmUtils::rtm_get_to_fte_cfg(fte, ftic().iftree(), rtm) == true) {
+	    if (type == FtiRtmParseType(UPCALLS))
+		fte.mark_upcall();
 	    fte_list.push_back(fte);
+	}
     }
-    
+
     return true;
 }
 
Index: xrl_fti.cc
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/fea/xrl_fti.cc,v
retrieving revision 1.10
diff -u -p -r1.10 xrl_fti.cc
--- xrl_fti.cc	3 Aug 2004 03:51:48 -0000	1.10
+++ xrl_fti.cc	6 Nov 2004 00:29:39 -0000
@@ -291,6 +291,44 @@ XrlFtiTransactionManager::send_fib_clien
 	return XORP_ERROR;
 }
 
+int
+XrlFtiTransactionManager::send_fib_client_resolve_route(const string& target_name,
+						       const Fte4& fte)
+{
+    bool success;
+
+    success = _xrl_fea_fib_client.send_resolve_route4(
+	target_name.c_str(),
+	fte.net(),
+	callback(this,
+		 &XrlFtiTransactionManager::send_fib_client_resolve_route4_cb,
+		 target_name));
+
+    if (success)
+	return XORP_OK;
+    else
+	return XORP_ERROR;
+}
+
+int
+XrlFtiTransactionManager::send_fib_client_resolve_route(const string& target_name,
+						       const Fte6& fte)
+{
+    bool success;
+
+    success = _xrl_fea_fib_client.send_resolve_route6(
+	target_name.c_str(),
+	fte.net(),
+	callback(this,
+		 &XrlFtiTransactionManager::send_fib_client_resolve_route6_cb,
+		 target_name));
+
+    if (success)
+	return XORP_OK;
+    else
+	return XORP_ERROR;
+}
+
 void
 XrlFtiTransactionManager::send_fib_client_add_route4_cb(
     const XrlError& xrl_error,
@@ -359,6 +397,40 @@ XrlFtiTransactionManager::send_fib_clien
     fib_client.send_fib_client_route_change_cb(xrl_error);
 }
 
+void
+XrlFtiTransactionManager::send_fib_client_resolve_route4_cb(
+    const XrlError& xrl_error,
+    string target_name)
+{
+    map<string, FibClient4>::iterator iter;
+
+    iter = _fib_clients4.find(target_name);
+    if (iter == _fib_clients4.end()) {
+	// The client has probably gone. Silently ignore.
+	return;
+    }
+
+    FibClient4& fib_client = iter->second;
+    fib_client.send_fib_client_route_change_cb(xrl_error);
+}
+
+void
+XrlFtiTransactionManager::send_fib_client_resolve_route6_cb(
+    const XrlError& xrl_error,
+    string target_name)
+{
+    map<string, FibClient6>::iterator iter;
+
+    iter = _fib_clients6.find(target_name);
+    if (iter == _fib_clients6.end()) {
+	// The client has probably gone. Silently ignore.
+	return;
+    }
+
+    FibClient6& fib_client = iter->second;
+    fib_client.send_fib_client_route_change_cb(xrl_error);
+}
+
 template<class F>
 void
 XrlFtiTransactionManager::FibClient<F>::activate(const list<F>& fte_list)
@@ -394,7 +466,9 @@ XrlFtiTransactionManager::FibClient<F>::
     //
     // Send the appropriate XRLs
     //
-    if (! fte.is_deleted()) {
+    if (fte.is_upcall()) {
+	success = _xftm.send_fib_client_resolve_route(_target_name, fte);
+    } else if (! fte.is_deleted()) {
 	// Add a route
 	success = _xftm.send_fib_client_add_route(_target_name, fte);
     } else {
Index: xrl_fti.hh
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/fea/xrl_fti.hh,v
retrieving revision 1.9
diff -u -p -r1.9 xrl_fti.hh
--- xrl_fti.hh	17 Aug 2004 02:20:11 -0000	1.9
+++ xrl_fti.hh	6 Nov 2004 00:29:39 -0000
@@ -189,6 +189,28 @@ public:
     int send_fib_client_delete_route(const string& target_name,
 				     const Fte6& fte);
 
+    /**
+     * Send an XRL to a FIB client to inform it of an IPv4 route miss.
+     *
+     * @param target_name the target name of the FIB client.
+     * @param fte the Fte with the destination to resolve.
+     * @return XORP_OK on success, otherwise XORP_ERROR.
+     * @see Fte4.
+     */
+    int send_fib_client_resolve_route(const string& target_name,
+				     const Fte4& fte);
+
+    /**
+     * Send an XRL to a FIB client to inform it of an IPv6 route miss.
+     *
+     * @param target_name the target name of the FIB client.
+     * @param fte the Fte with the destination to resolve.
+     * @return XORP_OK on success, otherwise XORP_ERROR.
+     * @see Fte6.
+     */
+    int send_fib_client_resolve_route(const string& target_name,
+				     const Fte6& fte);
+
 protected:
     FtiTransactionManager  _ftm;
     uint32_t		   _max_ops;	// Maximum operations in a transaction
@@ -203,6 +225,10 @@ private:
 					  string target_name);
     void send_fib_client_delete_route6_cb(const XrlError& xrl_error,
 					  string target_name);
+    void send_fib_client_resolve_route4_cb(const XrlError& xrl_error,
+					  string target_name);
+    void send_fib_client_resolve_route6_cb(const XrlError& xrl_error,
+					  string target_name);
 
     /**
      * A template class for storing FIB client information.

--azLHFNyN32YCQGCU--