Source: ../../rib/register_server.hh


Annotated List
Files
Globals
Hierarchy
Index
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-

// Copyright (c) 2001,2002 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/register_server.hh,v 1.1.1.1 2002/12/11 23:56:13 hodson Exp $

#ifndef __RIB_REGISTER_SERVER_HH__
#define __RIB_REGISTER_SERVER_HH__

#include <map>
#include <list>
#include "libxorp/xorp.h"
#include "libxorp/ipv4.hh"
#include "libxorp/ipv6.hh"
#include "libxorp/ipnet.hh"
#include "xrl/interfaces/rib_client_xif.hh"

class XrlRouter;
class NotifyQueueEntry;

typedef XrlRibClientV0p1Client ResponseSender;

/**
 * @short Queue of route event notifications
 *
 * A NotfiyQueue holds a queue of route event notifications waiting
 * transmission to the XORP process that registered interest in route
 * changes that affected one or more routes.  When a lot of routes
 * change, we need to queue the changes because we may generate them
 * faster than the recipient can handle being told about them.
 */
class NotifyQueue {
public:
    /**
     * NotifyQueue constructor
     *
     * @param modname the XRL module target name for the process that
     * this queue holds notifications for.  
     */
    NotifyQueue(const string& modname);

    /**
     * Add an notification entry to the queue.
     *
     * @param e the notification entry to be queued.
     */
    void add_entry(NotifyQueueEntry *e);

    /**
     * Send the next entry in the queue to this queue's XRL target.
     */
    void send_next();

    /**
     * Flush is an indication to the queue that the changes since the
     * last flush can be checked for consolidation.  Several add_entry
     * events might occur in rapid succession affecting the same
     * route.  A flush indicates that it is OK to start sending this
     * batch of changes (and to consolidate those changes to avoid
     * thrashing, but we don't currently do this).
     */
    void flush(ResponseSender* response_sender);
    typedef XorpCallback1<void, const XrlError&>::RefPtr XrlCompleteCB;

    /**
     * XRL transmit complete callback.  We use this to cause the next
     * item in the queue to be sent.  
     *
     * @param e the XRL completion status code. 
     */
    void xrl_done(const XrlError& e);
private:
    string _modname;
    list <NotifyQueueEntry*> _queue;
    bool _active;
    ResponseSender* _response_sender;
};


/**
 * Base class for a queue entry to be held in a @ref NotifyQueue.
 */
class NotifyQueueEntry {
public:
    /**
     * The type of notifcation: either the data (nexthop, metric)
     * associated with the registered route changed, or the data has
     * changed enough that the registration has been invalidated and
     * the client needs to register again to find out what happened 
     */
    typedef enum EntryType { CHANGED, INVALIDATE };

    /**
     * NotifyQueueEntry constructor
     */
    NotifyQueueEntry() {}

    /**
     * NotifyQueueEntry destructor
     */
    virtual ~NotifyQueueEntry() {};

    /** 
     * Send the queue entry (pure virtual)
     */
    virtual void send(ResponseSender* response_sender,
		      const string& modname,
		      NotifyQueue::XrlCompleteCB& cb) = 0;

    /**
     * @return The type of queue entry
     * @see NotifyQueueEntry::EntryType
     */
    virtual EntryType type() const = 0;
private:
};

/**
 * Notification Queue entry indicating that a change occured to the
 * metric or nexthop of a route in which interest was registered.  
 *
 * The template class A is the address family: either the IPv4 class
 * or the IPv6 class.  
 */
template <class A>
class NotifyQueueChangedEntry : public NotifyQueueEntry {
 public:
    /**
     * NotifyQueueChangedEntry Constructor
     *
     * @param net the destination subnet of the route that changed.
     * @param nexthop the new nexthop of the route that changed.
     * @param metric the new routing protocol metric of the route that changed.
     * @param multicast true indicates that the change occured in the
     * multicast RIB, false indicates that it occured in the unicast
     * RIB.
     */
    NotifyQueueChangedEntry(IPNet<A> net, A nexthop,
			    uint32_t metric, bool multicast) 
    {
	_net = net;
	_nexthop = nexthop;
	_metric = metric;
	_multicast = multicast;
    }

    /**
     * @return CHANGED
     * @see NotifyQueueEntry::EntryType
     */
    EntryType type() const { return CHANGED; }

    /**
     * Actually send the XRL that communicates this change to the
     * registered process.
     *
     * @param response_sender the auto-generated stub class instance
     * that will do the parameter marchalling.
     * @param modname the XRL module target name to send this information to.
     * @param cb the method to call back when this XRL completes.
     */
    void send(ResponseSender* response_sender,
	      const string& modname,
	      NotifyQueue::XrlCompleteCB& cb);
 private:
    IPNet<A> _net; // the route's full subnet (not the valid_subnet)
    A _nexthop;
    uint32_t _metric;
    bool _multicast;
};

/**
 * Notification Queue entry indicating that a change occured which has
 * caused a route registration to become invalid.  The client must
 * re-register to find out what actually happened.
 *
 * The template class A is the address family: either the IPv4 class
 * or the IPv6 class.  
 */
template <class A>
class NotifyQueueInvalidateEntry : public NotifyQueueEntry {
public:
    /**
     * NotifyQueueInvalidateEntry Constructor
     *
     * @param net the valid_subnet of the route registration that is
     * now invalid.
     * @param multicast true indicates that the change occured in the
     * multicast RIB, false indicates that it occured in the unicast
     * RIB.  
     */
    NotifyQueueInvalidateEntry(IPNet<A> net,
			    bool multicast) {
	_net = net;
	_multicast = multicast;
    }

    /**
     * @return INVALIDATE
     * @see NotifyQueueEntry::EntryType
     */
    EntryType type() const { return INVALIDATE; }

    /**
     * Actually send the XRL that communicates this change to the
     * registered process.
     *
     * @param response_sender the auto-generated stub class instance
     * that will do the parameter marchalling.
     * @param modname the XRL module target name to send this information to.
     * @param cb the method to call back when this XRL completes.
     */
    void send(ResponseSender* response_sender,
	      const string& modname,
	      NotifyQueue::XrlCompleteCB& cb);
private:
    IPNet<A> _net; /* the valid_subnet from the RouteRegister
		    * instance.  The other end already knows the
		    * route's full subnet */
    bool _multicast;
};


/**
 * @short RegisterServer handles communication of notifications to the
 * clients that registered interest in changes affecting specific
 * routes.
 *
 * RegisterServer handles communication of notifications to the
 * clients that registered interest in changes affecting specific
 * routes.  As these notifications can sometimes be generated faster
 * than the recipient can handle them, the notifications can be queued
 * here. 
 */
class RegisterServer {
public:
    /**
     * RegisterServer constructor
     *
     * @param xrl_router the XRL router instance used to send and
     * receive XRLs in this process.
     */
    RegisterServer(XrlRouter* xrl_router);

    /**
     * RegisterServer destructor
     */
    virtual ~RegisterServer() {}

    /** 
     * send_route_changed is called to communicate to another XRL
     * module that routing information in which it had registered an
     * interest has changed its nexthop or metric
     *
     * @param modname the XRL target name of the module to notify.
     * @param net the destination subnet of the route that changed.
     * @param nexthop the new nexthop of the route that changed.
     * @param metric the new routing protocol metric of the route that changed.
     * @param multicast true indicates that the change occured in the
     * multicast RIB, false indicates that it occured in the unicast
     * RIB.
     */
    virtual void send_route_changed(const string& modname,
			    IPNet<IPv4> net,
			    IPv4 nexthop,
			    uint32_t metric,
			    bool multicast);
    virtual void send_invalidate(const string& modname,
			 IPNet<IPv4> net,
			 bool multicast);

    /** 
     * send_route_changed is called to communicate to another XRL
     * module that routing information in which it had registered an
     * interest has changed its nexthop or metric
     *
     * @param modname the XRL target name of the module to notify.
     * @param net the destination subnet of the route that changed.
     * @param nexthop the new nexthop of the route that changed.
     * @param metric the new routing protocol metric of the route that changed.
     * @param multicast true indicates that the change occured in the
     * multicast RIB, false indicates that it occured in the unicast
     * RIB.
     */
    virtual void send_route_changed(const string& modname,
			    IPNet<IPv6> net,
			    IPv6 nexthop,
			    uint32_t metric,
			    bool multicast);
    /**
     * send_invalidate is called to communicate to another XRL module
     * that routing information in which it had registered an interest
     * has changed in some unspecified way that has caused the
     * registration to become invalid.  The client must re-register to
     * find out what really happened.
     *
     * @param modname the XRL target name of the module to notify.
     * @param net the valid_subnet of the route registration that is
     * now invalid.
     * @param multicast true indicates that the change occured in the
     * multicast RIB, false indicates that it occured in the unicast
     * RIB.  
     */
    virtual void send_invalidate(const string& modname,
			 IPNet<IPv6> net,
			 bool multicast);

    /**
     * @see NotifyQueue::flush
     */
    virtual void flush();
protected:
    void add_entry_to_queue(const string& modname, NotifyQueueEntry *e);
    map <string, NotifyQueue*> _queuemap;
    ResponseSender _response_sender;
};

#endif // __RIB_REGISTER_SERVER_HH__

Generated by: pavlin on possum.icir.org on Wed Dec 11 16:51:00 2002, using kdoc 2.0a54+XORP.