// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
// vim:set sts=4 ts=8:
// Copyright (c) 2001-2005 International Computer Science Institute
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software")
// to deal in the Software without restriction, subject to the conditions
// listed in the XORP LICENSE file. These conditions include: you must
// preserve this copyright notice, and you cannot mention the copyright
// holders in advertising related to the Software without their permission.
// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
// notice is a summary of the XORP LICENSE file; the license in that file is
// legally binding.
// $XORP: xorp/rib/rib.hh,v 1.34 2005/11/02 01:33:14 pavlin Exp $
#ifndef __RIB_RIB_HH__
#define __RIB_RIB_HH__
#include <string>
#include "libxorp/xorp.h"
#include "libxorp/ipv4.hh"
#include "libxorp/ipv6.hh"
#include "libxorp/ipnet.hh"
#include "libxorp/nexthop.hh"
#include "libxorp/vif.hh"
#include "route.hh"
#include "rt_tab_base.hh"
#include "rt_tab_origin.hh"
#include "rt_tab_merged.hh"
#include "rt_tab_extint.hh"
#include "rt_tab_redist.hh"
#include "rt_tab_pol_redist.hh"
#include "rt_tab_register.hh"
#include "rt_tab_pol_conn.hh"
#include "policy/backend/policytags.hh"
#include "policy/backend/policy_redist_map.hh"
class RegisterServer;
class RibManager;
enum RibTransportType {
UNICAST = 1,
MULTICAST = 2
};
enum RibVerifyType {
MISS = 0, // No route to destination
DISCARD = 1, // Discard route for destination
IP = 2 // Protocol route to destination
};
/**
* @short Master class for a RIB.
*
* RIB is the master class for a Routing Information Base. It holds
* the Vif table, routing tables for each protocol, etc. Typically we
* would have one RIB for IPv4 unicast, one for IPv4 multicast
* topology, one for IPv6 unicast and one for IPv6 multicast.
*
* Note that the XRL commands assume some level of filtering has already
* taken place to route to command to the right RIB.
*/
template<class A>
class RIB {
public:
/**
* RIB Constructor.
*
* @param rib_type indicates whether this RIB holds UNICAST or
* MULTICAST routing information. In the case of multicast, this
* is the topology information, not the forwarding information.
* @param rib_manager the main RIB manager process holding stuff
* that's common to all the individual RIBs.
* @param eventloop the main event loop.
*/
RIB(RibTransportType rib_type, RibManager& rib_manager,
EventLoop& eventloop);
/**
* RIB Destructor.
*/
virtual ~RIB();
/**
* Set test-mode: abort on some errors that we'd normally mask.
*/
void set_errors_are_fatal() { _errors_are_fatal = true; }
/**
* Get the list with the registered protocol names.
*
* @return the list with the registered protocol names.
*/
list<string> registered_protocol_names() const;
/**
* Initialize the RIB.
* Note that it is an error to initialize the table twice.
*
* @param register_server the @ref RegisterServer to initialize
* the Rib with.
*/
void initialize(RegisterServer& register_server);
/**
* Initialize the RIB's RedistTable at the end so that the
* winning routes are exported to the RIB clients (e.g., the FEA).
* Note that it is an error to initialize the table twice.
*
* @see RedistTable
* @param all a keyword string which can be used by RIB clients
* to register with the RIB to receive the winning routes from
* the RedistTable.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int initialize_redist_all(const string& all);
/**
* Initialize the RIB's PolicyRedistTable. The PolicyRedistTable enables
* route redistribution according to policy configuration. Based on the
* policy tags of routes passing through this table, a redistribution
* request is sent to the relevant protocols. If routes are being deleted,
* protocols are informed to stop advertising the route.
*
*/
int initialize_policy_redist();
/**
* Initialize the RIB's RegisterTable. The RegisterTable allows
* routing protocols such as BGP to register interest in routing
* information that affects specfic addresses.
* Note that it is an error to initialize the table twice.
*
* @param register_server the @ref RegisterServer to initialize
* the Rib with.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int initialize_register(RegisterServer& register_server);
/**
* Add a new OriginTable. Use is deprecated, except in test suites.
*
* @see OriginTable
* @param tablename human-readable name for this table to help in
* debugging.
* @param target_class the XRL target class of the routing
* protocol that will supply routes to this OriginTable.
* @param target_instance the XRL target instance of the routing
* protocol that will supply routes to this OriginTable.
* @param admin_distance default administrative distance to be
* applied to routes that enter the RIB through this OriginTable.
* @param protocol_type the routing protocol type (@ref ProtocolType).
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int new_origin_table(const string& tablename,
const string& target_class,
const string& target_instance,
uint32_t admin_distance,
ProtocolType protocol_type);
/**
* Inform the RIB about the existence of a Virtual Interface.
* Note that it is an error to add twice a vif with the same vifname.
*
* @see Vif
* @param vifname the name of the VIF, as understood by the FEA.
* @param vif Vif class instance giving the information about this vif.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
virtual int new_vif(const string& vifname, const Vif& vif);
/**
* Inform the RIB that a VIF no longer exists.
*
* @param vifname the name of the VIF, as previously indicated by new_vif.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
virtual int delete_vif(const string& vifname);
/**
* Set the vif flags of a configured vif.
*
* @param vifname the name of the vif.
* @param is_pim_register true if the vif is a PIM Register interface.
* @param is_p2p true if the vif is point-to-point interface.
* @param is_loopback true if the vif is a loopback interface.
* @param is_multicast true if the vif is multicast capable.
* @param is_broadcast true if the vif is broadcast capable.
* @param is_up true if the underlying vif is UP.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
virtual int set_vif_flags(const string& vifname,
bool is_p2p,
bool is_loopback,
bool is_multicast,
bool is_broadcast,
bool is_up);
/**
* Add an address and subnet to a existing VIF. Each VIF may have
* multiple addresses and associated subnets.
*
* @param vifname the name of the VIF the address will be added to.
* @param addr the address to be added. This must be one of the
* addresses of this router.
* @param subnet the subnet that is connected to this VIF
* corresponding to the address addr.
* @param broadcast the broadcast address to add. In case of IPv6
* this address is ignored.
* @param peer the peer address to add.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
virtual int add_vif_address(const string& vifname,
const A& addr,
const IPNet<A>& subnet,
const A& broadcast_addr,
const A& peer_addr);
/**
* Remove an address and the associated subnet from an existing VIF.
* @param vifname the name of the VIF the address will be removed from.
* @param addr the address to be removed. This must be an address
* previously added by add_vif_address.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
virtual int delete_vif_address(const string& vifname, const A& addr);
/**
* Add a route to the "connected" OriginTable.
*
* @param vif the vif with the connected route.
* @param net the subnet (address and prefix length) of the route.
* @param nexthop_addr the nexthop address of the route to add.
* @param peer_addr the peer address for the route to add
* (if a point-to-point interface).
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int add_connected_route(const Vif& vif,
const IPNet<A>& net,
const A& nexthop_addr,
const A& peer_addr);
/**
* Delete a route from the "connected" OriginTable.
*
* @param vif the vif with the connected route.
* @param net the subnet (address and prefix length) of the route.
* @param peer_addr the peer address for the route to delete
* (if a point-to-point interface).
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int delete_connected_route(const Vif& vif,
const IPNet<A>& net,
const A& peer_addr);
/**
* Add a route via the OriginTable called tablename.
*
* @param tablename the name of the OriginTable into which the
* route should be inserted.
* @param net the subnet (address and prefix length) of the route.
* @param nexthop_addr the nexthop that packets destined for net should be
* forwarded to.
* @param ifname the name of the physical interface toward the
* destination. If an empty string the interface will be chosen by RIB.
* @param vifname the name of the virtual interface toward the
* destination. If an empty string the interface will be chosen by RIB.
* @param metric the routing protocol metric associated with this route.
* @param policytags the policy-tags for this route.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
virtual int add_route(const string& tablename,
const IPNet<A>& net,
const A& nexthop_addr,
const string& ifname,
const string& vifname,
uint32_t metric,
const PolicyTags& policytags);
/**
* Replace an existing route via the OriginTable called tablename.
*
* @param tablename the name of the OriginTable in which the
* route should be replaced.
* @param net the subnet (address and prefix length) of the route.
* @param nexthop_addr the new nexthop that packets destined for @ref net
* should be forwarded to.
* @param ifname the name of the physical interface toward the
* destination. If an empty string the interface will be chosen by RIB.
* @param vifname the name of the virtual interface toward the
* destination. If an empty string the interface will be chosen by RIB.
* @param metric the new routing protocol metric associated with this
* @param policytags the policy-tags for this route.
* route.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
virtual int replace_route(const string& tablename,
const IPNet<A>& net,
const A& nexthop_addr,
const string& ifname,
const string& vifname,
uint32_t metric,
const PolicyTags& policytags);
/**
* Verify the result of a route lookup in the RIB matches the
* parameters we expect. Intended for testing purposes only.
*
* @param lookupaddr the destination to be verified.
* @param nexthop_addr the expected next hop address.
* @param ifname the expected interface.
* @param metric the expected routing protocol metric.
* @param type the expected type of match.
*
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
virtual int verify_route(const A& lookupaddr,
const string& ifname,
const A& nexthop_addr,
uint32_t metric,
RibVerifyType matchtype);
/**
* Delete an existing route via the OriginTable called tablename.
*
* @param tablename the name of the OriginTable in which the
* route should be deleted.
* @param subnet the subnet (address and prefix length) of the
* route to be deleted.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
virtual int delete_route(const string& tablename,
const IPNet<A>& subnet);
/**
* Lookup an address in the RIB to determine the nexthop router to
* which packets for this address will be forwarded.
*
* @param lookupaddr the address to be looked up.
* @return pointer to address of next hop for @ref lookupaddr if
* available, otherwise A::ZERO().
*/
virtual const A& lookup_route(const A& lookupaddr);
/**
* Used for debugging only
*/
virtual RouteRange<A>* route_range_lookup(const A& lookupaddr);
/**
* Register interest in being notified about all changes to
* routing information that would affect traffic destined for a
* particular address.
*
* @param lookupaddr the address to register interest in.
* @param module the XRL module name to which notifications of
* changes should be sent.
*/
virtual RouteRegister<A>* route_register(const A& lookupaddr,
const string& module);
/**
* De-register interest in being notified about all changes to
* routing information for a particular address.
*
* @see RIB<A>::route_register
*
* @param lookupaddr the address to de-register interest in.
* @param module the XRL module name to which notifications of
* changes should no longer be sent.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
virtual int route_deregister(const IPNet<A>& subnet, const string& module);
/**
* Find a routing protocol, given its protocol name.
*
* @param protocol the name of the table to search for.
* @return pointer to table if exists, NULL otherwise.
*/
Protocol* find_protocol(const string& protocol);
/**
* Get route redistribution table for specified routing protocol.
*/
RedistTable<A>* protocol_redist_table(const string& protocol);
/**
* Create the OriginTable for an IGP protocol and plumb it into
* the RIB. Typically this will be called when a new instance of
* an IGP routing protocol such as OSPF starts up.
*
* @param tablename the routing protocol name. This should be one
* of the list of names the RIB knows about, or the incorrect
* default administrative distance will be applied.
* @param target_class the XRL target class of the routing
* protocol that will supply routes to this OriginTable.
* @param target_instance the XRL target instance of the routing
* protocol that will supply routes to this OriginTable.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
virtual int add_igp_table(const string& tablename,
const string& target_class,
const string& target_instance);
/**
* Delete the OriginTable for an IGP protocol and unplumb it from
* the RIB. Typically this will be called when an instance of
* an IGP routing protocol such as OSPF exits.
*
* @param tablename the routing protocol name, previously
* registered using @ref add_igp_table.
* @param target_class the XRL target class of the routing
* protocol that supplied routes to this OriginTable.
* @param target_instance the XRL target instance of the routing
* protocol that supplied routes to this OriginTable.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
virtual int delete_igp_table(const string& tablename,
const string& target_class,
const string& target_instance);
/**
* Create the OriginTable for an EGP protocol and plumb it into
* the RIB. Typically this will be called when a new instance of
* an EGP routing protocol such as EBGP or IBGP starts up. Note
* that EBGP and IBGP should register separately.
*
* @param tablename the routing protocol name. This should be one
* of the list of names the RIB knows about, or the incorrect
* default administrative distance will be applied.
* @param target_class the XRL target class of the routing
* protocol that will supply routes to this OriginTable.
* @param target_instance the XRL target instance of the routing
* protocol that will supply routes to this OriginTable.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
virtual int add_egp_table(const string& tablename,
const string& target_class,
const string& target_instance);
/**
* Delete the OriginTable for an EGP protocol and unplumb it from
* the RIB. Typically this will be called when an instance of
* an EGP routing protocol such as BGP exits.
*
* @param tablename the routing protocol name, previously
* registered using @ref add_igp_table.
* @param target_class the XRL target class of the routing
* protocol that supplied routes to this OriginTable.
* @param target_instance the XRL target instance of the routing
* protocol that supplied routes to this OriginTable.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
virtual int delete_egp_table(const string& tablename,
const string& target_class,
const string& target_instance);
/**
* An XRL Target died. We need to check if it's a routing
* protocol, and if it was, clean up after it.
*
* @param target_class the XRL Class of the target that died.
* @param target_instance the XRL Class Instance of the target that died.
*/
void target_death(const string& target_class,
const string& target_instance);
/**
* Print the RIB structure for debugging
*/
void print_rib() const;
/**
* Get RIB name.
*/
string name() const;
/**
* Push routes through policy filters for re-filtering.
*/
void push_routes();
private:
/**
* Used to implement @ref add_igp_table and @ref add_egp_table.
*
* @param tablename the routing protocol name.
* @param target_class the XRL target class of the routing
* protocol that will supply routes to this OriginTable.
* @param target_instance the XRL target instance of the routing
* protocol that will supply routes to this OriginTable.
* @param protocol_type the routing protocol type (@ref ProtocolType).
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int add_origin_table(const string& tablename,
const string& target_class,
const string& target_instance,
ProtocolType protocol_type);
/**
* Used to implement @ref delete_igp_table and @ref delete_egp_table.
*
* @param tablename the routing protocol name.
* @param target_class the XRL target class of the routing
* protocol that will supply routes to this OriginTable.
* @param target_instance the XRL target instance of the routing
* protocol that supplied routes to this OriginTable.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int delete_origin_table(const string& tablename,
const string& target_class,
const string& target_instance);
/**
* Add a table for policy filtering of connected routes.
*
* This is used to enable route redistribution of connected routes.
*
* @param origin_tablename The name of the origin table.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int add_policy_connected_table(const string& origin_tablename);
/**
* Add a RedistTable behind OriginTable. This allows routes
* associated with the OriginTable to be redistributed in future.
*
* @param origin_tablename Name of OriginTable.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int add_redist_table(const string& origin_tablename);
/**
* track_back trough the RouteTables' parent pointers to find the
* last (i.e, nearest the OriginTable) table that matches the mask
* in @ref typemask. If the table given by @ref rt doesn't match
* the mask, return it anyway. If a table has more than one
* parent, then this is an error.
*
* @param rt the routing table to start with.
* @param typemask the bitwise-or of the routing table types that
* we may track back through.
* @return the last matching table, or @ref rt if rt itself doesn't match.
*/
RouteTable<A>* track_back(RouteTable<A>* rt, int typemask) const;
/**
* track_forward trough the RouteTables' child pointers to find
* the last able that matches the mask in @ref typemask.
* Unlike track_back, if @ref rt doesn't match, but the next does,
* the track forward anyway.
*
* @param rt the routing table to start with.
* @param typemask the bitwise-or of the routing table types that
* we may track forward through.
* @return the last matching table.
*/
RouteTable<A>* track_forward(RouteTable<A>* rt, int typemask) const;
/**
* Find a routing table, given its table name
*
* @param tablename the name of the table to search for.
* @return pointer to table if exists, NULL otherwise.
*/
inline RouteTable<A>* find_table(const string& tablename);
/**
* Find a routing table, given its protocol name and XRL target
* instance name.
*
* @param tablename the name of the protocol to search for.
* @param target_class the name of the target class to search for.
* @param target_instance the name of the target instance to search for.
* @return pointer to table if exists, NULL otherwise.
*/
inline OriginTable<A>* find_table_by_instance(const string& tablename,
const string& target_class,
const string& target_instance);
/**
* Add table to RIB, but don't do any plumbing.
*
* It is an error to add the same table twice or multiple tables
* with the same name.
*
* @param table the table to be added.
*
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
inline int add_table(RouteTable<A>* table);
/**
* Remove table from RIB, but don't do any unplumbing.
* The table is not deleted by this.
*
* @param tablename the name of the table to be removed.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
inline int remove_table(const string& tablename);
/**
* Lookup the default admin distance associated with a routing
* protocol name.
*
* @param protocol_name the canonical name of a routing protocol,
* in lower case. Eg "ospf", "ibgp", etc.
* @return the admin distance.
*/
inline uint32_t admin_distance(const string& protocol_name);
/**
* Find the virtual interface associated with one of this router's
* addresses.
*
* @param addr the IP address to lookup.
* @return pointer to Vif on success, NULL otherwise.
*/
inline Vif* find_vif(const A& addr);
/**
* Find the IP External Nexthop class instance associated with an IP
* address.
*
* @param addr the IP address of the nexthop router.
* @return pointer to external next hop if it exists, NULL otherwise.
*/
inline IPExternalNextHop<A>* find_external_nexthop(const A& addr);
/**
* Find the IP Peer Nexthop class instance associated with an IP
* address.
*
* @param addr the IP address of the nexthop router.
* @return pointer to peer next hop if it exists, NULL otherwise.
*/
inline IPPeerNextHop<A>* find_peer_nexthop(const A& addr);
/**
* Find or create the IP External Nexthop class instance
* associated with an IP address.
*
* @param addr the IP address of the nexthop router.
* @return the IPExternalNextHop class instance for @ref addr
*/
inline IPExternalNextHop<A>* find_or_create_external_nexthop(const A& addr);
/**
* Find or create the IP Peer Nexthop class instance
* associated with an IP address.
*
* @param addr the IP address of the nexthop router.
* @return the IPPeerNextHop class instance for @ref addr.
*/
inline IPPeerNextHop<A>* find_or_create_peer_nexthop(const A& addr);
/**
* not implemented - force use of default copy constuctor to fail.
*/
RIB(const RIB& );
/**
* not implemented - force use of default assignment operator to fail.
*/
RIB& operator=(const RIB& );
/**
* Flush out routing table changes to other processes.
*/
void flush();
protected:
RibManager& _rib_manager;
EventLoop& _eventloop;
RouteTable<A>* _final_table;
RegisterTable<A>* _register_table;
bool _multicast;
bool _errors_are_fatal;
PolicyRedistTable<A>* _policy_redist_table;
list<RouteTable<A>* > _tables;
map<string, Protocol* > _protocols;
map<string, OriginTable<A>* > _routing_protocol_instances;
map<string, Vif> _vifs;
map<string, uint32_t> _admin_distances;
map<A, IPExternalNextHop<A> > _external_nexthops;
map<A, IPPeerNextHop<A> > _peer_nexthops;
};
typedef RIB<IPv4> IPv4RIB;
typedef RIB<IPv6> IPv6RIB;
#endif // __RIB_RIB_HH__
Generated by: pavlin on possum.icir.org on Thu Mar 9 04:43:48 2006, using kdoc $.