Source: ../../fea/iftree.hh
|
|
|
|
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
// vim:set sts=4 ts=8:
// Copyright (c) 2001-2009 XORP, Inc.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License, Version 2, June
// 1991 as published by the Free Software Foundation. Redistribution
// and/or modification of this program under the terms of any other
// version of the GNU General Public License is not permitted.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
// see the GNU General Public License, Version 2, a copy of which can be
// found in the XORP LICENSE.gpl file.
//
// XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
// http://xorp.net
// $XORP: xorp/fea/iftree.hh,v 1.72 2009/01/05 18:30:49 jtc Exp $
#ifndef __FEA_IFTREE_HH__
#define __FEA_IFTREE_HH__
#include <map>
#include <string>
#include <set>
#include "libxorp/ipv4.hh"
#include "libxorp/ipv6.hh"
#include "libxorp/mac.hh"
class IPvX;
/**
* Base class for FEA configurable items where the modifications need
* to be held over and propagated later, ie changes happen during a
* transaction but are propagated during the commit.
*/
class IfTreeItem {
public:
IfTreeItem() : _st(CREATED), _soft(false) {}
virtual ~IfTreeItem() {}
public:
enum State {
NO_CHANGE = 0x00,
CREATED = 0x01,
DELETED = 0x02,
CHANGED = 0x04
};
int set_state(State st) {
if (bits(st) > 1) {
return (XORP_ERROR);
}
_st = st;
return (XORP_OK);
}
State state() const { return _st; }
int mark(State st) {
if (bits(st) > 1) {
return (XORP_ERROR);
}
if (st & (CREATED | DELETED)) {
_st = st;
return (XORP_OK);
}
if (_st & (CREATED | DELETED)) {
return (XORP_OK);
}
_st = st;
return (XORP_OK);
}
bool is_marked(State st) const { return st == _st; }
void set_soft(bool en) { _soft = en; }
bool is_soft() const { return _soft; }
/**
* Virtual method to be implemented to flush out state associated
* objects, ie if an object is marked CREATED or CHANGED it should be
* marked NO_CHANGE, if an object is marked DELETED, it should be
* removed from the relevant container and destructed.
*/
virtual void finalize_state() = 0;
string str() const;
protected:
static uint32_t bits(State st) {
uint32_t c;
for (c = 0; st != NO_CHANGE; c += st & 0x01)
st = State(st >> 1);
return c;
}
State _st;
bool _soft;
};
// Classes derived from IfTreeItem
class IfTree;
class IfTreeInterface;
class IfTreeVif;
class IfTreeAddr4;
class IfTreeAddr6;
/**
* Container class for FEA Interface objects in a system.
*/
class IfTree : public IfTreeItem {
public:
typedef map<const string, IfTreeInterface*> IfMap;
typedef map<uint32_t, IfTreeInterface*> IfIndexMap;
//
// XXX: We use a multimap for the index->vif mapping, because a VLAN
// vif could be listed in two places: with its parent physical interface,
// or along as its own parent interface.
//
typedef multimap<uint32_t, IfTreeVif*> VifIndexMap;
/**
* Default constructor.
*/
IfTree();
/**
* Constructor from another IfTree.
*
* @param other the other IfTree.
*/
IfTree(const IfTree& other);
/**
* Destructor.
*/
~IfTree();
/**
* Assignment operator.
*
* @param other the other IfTree.
*/
IfTree& operator=(const IfTree& other);
/**
* Remove all interface state from the interface tree.
*/
void clear();
/**
* Add recursively a new interface.
*
* @param other_iface the interface to add recursively.
* @param mark_state if true, then mark the state same as the state
* from the other interface, otherwise the state will be CREATED.
*/
void add_recursive_interface(const IfTreeInterface& other_iface,
bool mark_state);
/**
* Create a new interface.
*
* @param ifname the interface name.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int add_interface(const string& ifname);
/**
* Label interface as ready for deletion. Deletion does not occur
* until finalize_state() is called.
*
* @param ifname the name of the interface to be labelled.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int remove_interface(const string& ifname);
/**
* Recursively create a new interface or update its state if it already
* exists.
*
* @param other_iface the interface with the state to copy from.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int update_interface(const IfTreeInterface& other_iface);
/**
* Find an interface.
*
* @param ifname the interface name to search for.
* @return a pointer to the interface (@ref IfTreeInterface) or NULL
* if not found.
*/
IfTreeInterface* find_interface(const string& ifname);
/**
* Find a const interface.
*
* @param ifname the interface name to search for.
* @return a const pointer to the interface (@ref IfTreeInterface) or NULL
* if not found.
*/
const IfTreeInterface* find_interface(const string& ifname) const;
/**
* Find an interface for a given physical index.
*
* @param pif_index the physical interface index to search for.
* @return a pointer to the interface (@ref IfTreeInterface) or NULL
* if not found.
*/
IfTreeInterface* find_interface(uint32_t pif_index);
/**
* Find a const interface for a given physical index.
*
* @param pif_index the physical interface index to search for.
* @return a const pointer to the interface (@ref IfTreeInterface) or NULL
* if not found.
*/
const IfTreeInterface* find_interface(uint32_t pif_index) const;
/**
* Find a vif.
*
* @param ifname the interface name to search for.
* @param vifname the vif name to search for.
* @return a pointer to the vif (@ref IfTreeVif) or NULL if not found.
*/
IfTreeVif* find_vif(const string& ifname, const string& vifname);
/**
* Find a const vif.
*
* @param ifname the interface name to search for.
* @param vifname the vif name to search for.
* @return a const pointer to the vif (@ref IfTreeVif) or NULL
* if not found.
*/
const IfTreeVif* find_vif(const string& ifname,
const string& vifname) const;
/**
* Find a vif for a given physical index.
*
* @param pif_index the physical interface index to search for.
* @return a pointer to the vif (@ref IfTreeVif) or NULL if not found.
*/
IfTreeVif* find_vif(uint32_t pif_index);
/**
* Find a const vif for a given physical index.
*
* @param pif_index the physical interface index to search for.
* @return a const pointer to the vif (@ref IfTreeVif) or NULL
* if not found.
*/
const IfTreeVif* find_vif(uint32_t pif_index) const;
/**
* Find an IPv4 address.
*
* @param ifname the interface name to search for.
* @param vifname the vif name to search for.
* @param addr the address to search for.
* @return a pointer to the vif (@ref IfTreeAddr4) or NULL if not found.
*/
IfTreeAddr4* find_addr(const string& ifname, const string& vifname,
const IPv4& addr);
/**
* Find a const IPv4 address.
*
* @param ifname the interface name to search for.
* @param vifname the vif name to search for.
* @param addr the address to search for.
* @return a const pointer to the vif (@ref IfTreeAddr4) or NULL
* if not found.
*/
const IfTreeAddr4* find_addr(const string& ifname, const string& vifname,
const IPv4& addr) const;
/**
* Find an IPv6 address.
*
* @param ifname the interface name to search for.
* @param vifname the vif name to search for.
* @param addr the address to search for.
* @return a pointer to the vif (@ref IfTreeAddr6) or NULL if not found.
*/
IfTreeAddr6* find_addr(const string& ifname, const string& vifname,
const IPv6& addr);
/**
* Find a const IPv6 address.
*
* @param ifname the interface name to search for.
* @param vifname the vif name to search for.
* @param addr the address to search for.
* @return a pointer to the vif (@ref IfTreeAddr6) or NULL if not found.
*/
const IfTreeAddr6* find_addr(const string& ifname, const string& vifname,
const IPv6& addr) const;
/**
* Find an interface and a vif by an address that belongs to that
* interface and vif.
*
* @param addr the address.
* @param ifp return-by-reference a pointer to the interface.
* @param vifp return-by-reference a pointer to the vif.
* @return true if a match is found, otherwise false.
*/
bool find_interface_vif_by_addr(const IPvX& addr,
const IfTreeInterface*& ifp,
const IfTreeVif*& vifp) const;
/**
* Find an interface and a vif by an address that shares the same subnet
* or p2p address.
*
* @param addr the address.
* @param ifp return-by-reference a pointer to the interface.
* @param vifp return-by-reference a pointer to the vif.
* @return true if a match is found, otherwise false.
*/
bool find_interface_vif_same_subnet_or_p2p(const IPvX& addr,
const IfTreeInterface*& ifp,
const IfTreeVif*& vifp) const;
/**
* Get the map with the stored interfaces.
*
* @return the map with the stored interfaces.
*/
IfMap& interfaces() { return _interfaces; }
/**
* Get the const map with the stored interfaces.
*
* @return the const map with the stored interfaces.
*/
const IfMap& interfaces() const { return _interfaces; }
/**
* Align system-user merged configuration with the pulled changes
* in the system configuration.
*
* Inside the FEA there may be multiple configuration representations,
* typically one the user modifies, one that mirrors the hardware,
* and one that merges those two (e.g., some of the merged information
* comes from the user configuration while other might come
* from the underlying system).
* Errors may occur pushing the user config down onto the hardware and
* we need a method to update the merged config from the h/w config that
* exists after the config push. We can't just copy the h/w config since
* the user config is restricted to configuration set by the user.
*
* The alignment works as follows:
* 1. If an interface in the local tree is marked as "soft", its
* state is not modified and the rest of the processing is ignored.
* 2. If an interface in the local tree is marked as
* "default_system_config", the rest of the processing is not
* applied, and the following rules are used instead:
* (a) If the interface is not in the other tree, it is marked
* as "disabled" and its vifs are marked for deletion.
* (b) Otherwise, its state (and the subtree below it) is copied
* as-is from the other tree.
* 3. If an item in the local tree is not in the other tree, it is
* marked as "disabled" in the local tree.
* 4. If an item in the local tree is in the other tree, and its state
* is different in the local and the other tree, the state
* is copied from the other tree to the local tree.
* Also, if the item is disabled in the user config tree, it is
* marked as "disabled" in the local tree.
*
* @param other the configuration tree to align state with.
* @param user_config the user configuration tree to reference during
* the alignment.
* @return modified configuration structure.
*/
IfTree& align_with_pulled_changes(const IfTree& other,
const IfTree& user_config);
/**
* Align system-user merged configuration with the observed changes
* in the system configuration.
*
* Inside the FEA there may be multiple configuration representations,
* typically one the user modifies, one that mirrors the hardware,
* and one that merges those two (e.g., some of the merged information
* comes from the user configuration while other might come
* from the underlying system).
* On certain systems there could be asynchronous updates originated
* by the system that are captured by the FEA interface observer
* (e.g., a cable is unplugged, a tunnel interface is added/deleted, etc).
*
* This method is used to align those updates with the merged
* configuration.
*
* 1. If an interface in the other tree is not in the local tree, it is
* tested whether is in the user configuration tree. If not, the
* rest of the processing is not applied and the interface is ignored.
* Otherwise it is created, its state is merged from the user config
* and other tree, and is marked as "CREATED".
* 2. If an interface in the local tree is marked as "soft", its
* state is not modified and the rest of the processing is ignored.
* 3. If an interface in the local tree is marked as
* "default_system_config", the rest of the processing is not
* applied, and its state (and the subtree below it) is copied
* as-is from the other tree.
* 4. If an item in the other tree is not in the local tree, it is
* tested whether is in the user configuration tree. If not, the
* rest of the processing is not applied and the item is ignored.
* Otherwise it is created, its state is merged from the user config
* and the other tree, and is marked as "CREATED".
* 5. If an item in the other tree is marked as:
* (a) "NO_CHANGE": The state of the entry in the other tree is not
* propagated to the local tree, but its subtree entries are
* processed.
* (b) "DELETED": The item in the local tree is disabled, and the
* subtree entries are ignored.
* (c) "CREATED" or "CHANGED": If the state of the entry is different
* in the other and the local tree, it is copied to the local tree,
* and the item in the local tree is marked as "CREATED" or
* "CHANGED".
* unless it was marked earlier as "CREATED".
* Also, if the item is disabled in the user config tree, it is
* marked as "disabled" in the local tree.
*
* @param other the configuration tree to align state with.
* @param user_config the user configuration tree to reference during
* the alignment.
* @return modified configuration structure.
*/
IfTree& align_with_observed_changes(const IfTree& other,
const IfTree& user_config);
/**
* Align system-user merged configuration with the user configuration
* changes.
*
* Inside the FEA there may be multiple configuration representations,
* typically one the user modifies, one that mirrors the hardware,
* and one that merges those two (e.g., some of the merged information
* comes from the user configuration while other might come
* from the underlying system).
*
* This method is used to align the user configuration changes with the
* merged configuration.
*
* The alignment works as follows:
* 1. If an item in the other tree is not in the local tree, it is
* created in the local tree and its state (and the subtree below it)
* is copied as-is from the other tree, and the rest of the processing
* is ignored.
* 2. If an item in the other tree is marked as:
* (a) "DELETED": The item in the local tree is marked as "DELETED",
* and the subtree entries are ignored.
* (b) All other: If the state of the item is different in the other
* and the local tree, it is copied to the local tree.
* Note that we compare the state even for "NO_CHANGE" items in
* case a previous change to a parent item in the merged tree
* has affected the entry (e.g., disabled interface would
* disable the vifs and addresses as well).
*
* @param other the configuration tree to align state with.
* @return modified configuration structure.
*/
IfTree& align_with_user_config(const IfTree& other);
/**
* Prepare configuration for pushing and replacing previous configuration.
*
* If the previous configuration is to be replaced with new configuration,
* we need to prepare the state that will delete, update, and add the
* new state as appropriate.
* The preparation works as follows:
* - All items in the local tree are preserved and marked as created.
* - All items in the other tree that are not in the local tree are
* added to the local tree and are marked as deleted.
*
* @param other the configuration tree to be used to prepare the
* replacement state.
* @return modified configuration structure.
*/
IfTree& prepare_replacement_state(const IfTree& other);
/**
* Prune bogus deleted state.
*
* If an item in the local tree is marked as deleted, but is not
* in the other tree, then it is removed.
*
* @param old_iftree the old tree with the state that is used as reference.
* @return the modified configuration tree.
*/
IfTree& prune_bogus_deleted_state(const IfTree& old_iftree);
/**
* Delete interfaces labelled as ready for deletion, call finalize_state()
* on remaining interfaces, and set state to NO_CHANGE.
*/
void finalize_state();
/**
* @return string representation of IfTree.
*/
string str() const;
protected:
friend class IfTreeInterface;
friend class IfTreeVif;
void insert_ifindex(IfTreeInterface* ifp);
void erase_ifindex(IfTreeInterface* ifp);
void insert_vifindex(IfTreeVif* vifp);
void erase_vifindex(IfTreeVif* vifp);
private:
IfMap _interfaces;
IfIndexMap _ifindex_map; // Map of pif_index to interface
VifIndexMap _vifindex_map; // Map of pif_index to vif
};
/**
* FEA class for holding physical interface state.
*/
class IfTreeInterface : public IfTreeItem {
public:
typedef map<const string, IfTreeVif*> VifMap;
typedef set<Mac> MacSet;
IfTreeInterface(IfTree& iftree, const string& ifname);
~IfTreeInterface();
IfTree& iftree() { return _iftree; }
const string& ifname() const { return _ifname; }
uint32_t pif_index() const { return _pif_index; }
void set_pif_index(uint32_t v) {
iftree().erase_ifindex(this);
_pif_index = v;
mark(CHANGED);
iftree().insert_ifindex(this);
}
bool enabled() const { return _enabled; }
void set_enabled(bool en) { _enabled = en; mark(CHANGED); }
uint32_t mtu() const { return _mtu; }
void set_mtu(uint32_t mtu) { _mtu = mtu; mark(CHANGED); }
const Mac& mac() const { return _mac; }
void set_mac(const Mac& mac) { _mac = mac; mark(CHANGED); }
MacSet& macs() { return _macs; }
const MacSet& macs() const { return _macs; }
bool no_carrier() const { return _no_carrier; }
void set_no_carrier(bool v) { _no_carrier = v; mark(CHANGED); }
uint64_t baudrate() const { return _baudrate; }
void set_baudrate(uint64_t v) { _baudrate = v; mark(CHANGED); }
bool discard() const { return _discard; }
void set_discard(bool discard) { _discard = discard; mark(CHANGED); }
bool unreachable() const { return _unreachable; }
void set_unreachable(bool v) { _unreachable = v; mark(CHANGED); }
bool management() const { return _management; }
void set_management(bool v) { _management = v; mark(CHANGED); }
bool default_system_config() const { return _default_system_config; }
void set_default_system_config(bool v) { _default_system_config = v; mark(CHANGED); }
/**
* Get the system-specific interface flags.
*
* Typically, this value is read from the underlying system, and is
* used only for internal purpose.
*
* @return the system-specific interface flags.
*/
uint32_t interface_flags() const { return _interface_flags; }
/**
* Store the system-specific interface flags.
*
* Typically, this value is read from the underlying system, and is
* used only for internal purpose.
*
* @param v the value of the system-specific interface flags to store.
*/
void set_interface_flags(uint32_t v) {
_interface_flags = v;
mark(CHANGED);
}
const VifMap& vifs() const { return _vifs; }
VifMap& vifs() { return _vifs; }
/**
* Add recursively a new vif.
*
* @param other_vif the vif to add recursively.
* @param mark_state if true, then mark the state same as the state
* from the other vif, otherwise the state will be CREATED.
*/
void add_recursive_vif(const IfTreeVif& other_vif, bool mark_state);
/**
* Create a new vif.
*
* @param vifname the vif name.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int add_vif(const string& vifname);
/**
* Label vif as ready for deletion. Deletion does not occur
* until finalize_state() is called.
*
* @param vifname the name of the vif to be labelled.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int remove_vif(const string& vifname);
/**
* Find a vif.
*
* @param vifname the vif name to search for.
* @return a pointer to the vif (@ref IfTreeVif) or NULL if not found.
*/
IfTreeVif* find_vif(const string& vifname);
/**
* Find a const vif.
*
* @param vifname the vif name to search for.
* @return a const pointer to the vif (@ref IfTreeVif) or NULL
* if not found.
*/
const IfTreeVif* find_vif(const string& vifname) const;
/**
* Find a vif for a given physical index.
*
* @param pif_index the physical interface index to search for.
* @return a pointer to the interface (@ref IfTreeVif) or NULL
* if not found.
*/
IfTreeVif* find_vif(uint32_t pif_index);
/**
* Find a const vif for a given physical index.
*
* @param pif_index the physical interface index to search for.
* @return a const pointer to the interface (@ref IfTreeVif) or NULL
* if not found.
*/
const IfTreeVif* find_vif(uint32_t pif_index) const;
/**
* Find an IPv4 address.
*
* @param vifname the vif name to search for.
* @param addr the address to search for.
* @return a pointer to the vif (@ref IfTreeAddr4) or NULL if not found.
*/
IfTreeAddr4* find_addr(const string& vifname, const IPv4& addr);
/**
* Find a const IPv4 address.
*
* @param vifname the vif name to search for.
* @param addr the address to search for.
* @return a const pointer to the vif (@ref IfTreeAddr4) or NULL
* if not found.
*/
const IfTreeAddr4* find_addr(const string& vifname,
const IPv4& addr) const;
/**
* Find an IPv6 address.
*
* @param vifname the vif name to search for.
* @param addr the address to search for.
* @return a pointer to the vif (@ref IfTreeAddr6) or NULL if not found.
*/
IfTreeAddr6* find_addr(const string& vifname, const IPv6& addr);
/**
* Find a const IPv6 address.
*
* @param vifname the vif name to search for.
* @param addr the address to search for.
* @return a pointer to the vif (@ref IfTreeAddr6) or NULL if not found.
*/
const IfTreeAddr6* find_addr(const string& vifname,
const IPv6& addr) const;
/**
* Copy state of internal variables from another IfTreeInterface.
*
* @param o the interface to copy from.
* @param copy_user_config if true then copy the flags from the
* user's configuration.
*/
void copy_state(const IfTreeInterface& o, bool copy_user_config) {
//
// XXX: Explicitly don't consider the discard, unreachable,
// management, and default_system_config flags, because they
// are always set from user's configuration.
//
set_pif_index(o.pif_index());
set_enabled(o.enabled());
set_mtu(o.mtu());
set_mac(o.mac());
set_no_carrier(o.no_carrier());
set_baudrate(o.baudrate());
set_interface_flags(o.interface_flags());
if (copy_user_config) {
// Copy the flags from the user configuration
set_discard(o.discard());
set_unreachable(o.unreachable());
set_management(o.management());
set_default_system_config(o.default_system_config());
}
}
/**
* Test if the interface-specific internal state is same.
*
* @param o the IfTreeInterface to compare against.
* @return true if the interface-specific internal state is same.
*/
bool is_same_state(const IfTreeInterface& o) {
//
// XXX: Explicitly don't consider the discard, unreachable,
// management, and default_system_config flags, because they
// are always set from user's configuration.
//
return ((pif_index() == o.pif_index())
&& (enabled() == o.enabled())
&& (mtu() == o.mtu())
&& (mac() == o.mac())
&& (no_carrier() == o.no_carrier())
&& (baudrate() == o.baudrate())
&& (interface_flags() == o.interface_flags()));
}
void finalize_state();
string str() const;
private:
IfTreeInterface(const IfTreeInterface&); // Not implemented
IfTreeInterface& operator=(const IfTreeInterface&); // Not implemented
IfTree& _iftree;
const string _ifname;
uint32_t _pif_index;
bool _enabled;
bool _discard;
bool _unreachable;
bool _management;
bool _default_system_config;
uint32_t _mtu;
Mac _mac;
bool _no_carrier;
uint64_t _baudrate; // The link baudrate
uint32_t _interface_flags; // The system-specific interface flags
VifMap _vifs;
MacSet _macs; // XXX: not part of user config, but used by processes
};
/**
* FEA class for virtual (logical) interface state.
*/
class IfTreeVif : public IfTreeItem {
public:
typedef map<const IPv4, IfTreeAddr4*> IPv4Map;
typedef map<const IPv6, IfTreeAddr6*> IPv6Map;
IfTreeVif(IfTreeInterface& iface, const string& vifname);
~IfTreeVif();
IfTree& iftree() { return _iface.iftree(); }
const string& ifname() const { return _iface.ifname(); }
const string& vifname() const { return _vifname; }
uint32_t pif_index() const { return _pif_index; }
void set_pif_index(uint32_t v) {
iftree().erase_vifindex(this);
_pif_index = v;
mark(CHANGED);
iftree().insert_vifindex(this);
}
uint32_t vif_index() const { return _vif_index; }
void set_vif_index(uint32_t v) { _vif_index = v; mark(CHANGED); }
bool enabled() const { return _enabled; }
bool broadcast() const { return _broadcast; }
bool loopback() const { return _loopback; }
bool point_to_point() const { return _point_to_point; }
bool multicast() const { return _multicast; }
bool pim_register() const { return _pim_register; }
void set_enabled(bool en) { _enabled = en; mark(CHANGED); }
void set_broadcast(bool v) { _broadcast = v; mark(CHANGED); }
void set_loopback(bool v) { _loopback = v; mark(CHANGED); }
void set_point_to_point(bool v) { _point_to_point = v; mark(CHANGED); }
void set_multicast(bool v) { _multicast = v; mark(CHANGED); }
void set_pim_register(bool v) { _pim_register = v; mark(CHANGED); }
/**
* Get the system-specific vif flags.
*
* Typically, this value is read from the underlying system, and is
* used only for internal purpose.
*
* @return the system-specific vif flags.
*/
uint32_t vif_flags() const { return _vif_flags; }
/**
* Store the system-specific vif flags.
*
* Typically, this value is read from the underlying system, and is
* used only for internal purpose.
*
* @param v the value of the system-specific vif flags to store.
*/
void set_vif_flags(uint32_t v) { _vif_flags = v; mark(CHANGED); }
bool is_vlan() const { return _is_vlan; }
void set_vlan(bool v) { _is_vlan = v; mark(CHANGED); }
uint16_t vlan_id() const { return _vlan_id; }
void set_vlan_id(uint16_t v) { _vlan_id = v; mark(CHANGED); }
const IPv4Map& ipv4addrs() const { return _ipv4addrs; }
IPv4Map& ipv4addrs() { return _ipv4addrs; }
const IPv6Map& ipv6addrs() const { return _ipv6addrs; }
IPv6Map& ipv6addrs() { return _ipv6addrs; }
/**
* Copy recursively from another vif.
*
* @param other_vif the vif to copy recursively from.
*/
void copy_recursive_vif(const IfTreeVif& other_vif);
/**
* Add recursively a new IPv4 address.
*
* @param other_addr the address to add recursively.
* @param mark_state if true, then mark the state same as the state
* from the other address, otherwise the state will be CREATED.
*/
void add_recursive_addr(const IfTreeAddr4& other_addr, bool mark_state);
/**
* Add recursively a new IPv6 address.
*
* @param other_addr the address to add recursively.
* @param mark_state if true, then mark the state same as the state
* from the other address, otherwise the state will be CREATED.
*/
void add_recursive_addr(const IfTreeAddr6& other_addr, bool mark_state);
/**
* Add IPv4 address.
*
* @param addr address to be added.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int add_addr(const IPv4& addr);
/**
* Mark IPv4 address as DELETED.
*
* Deletion occurs when finalize_state is called.
*
* @param addr address to labelled.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int remove_addr(const IPv4& addr);
/**
* Add IPv6 address.
*
* @param addr address to be added.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int add_addr(const IPv6& addr);
/**
* Mark IPv6 address as DELETED.
*
* Deletion occurs when finalize_state is called.
*
* @param addr address to labelled.
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int remove_addr(const IPv6& addr);
/**
* Find an IPv4 address.
*
* @param addr the address to search for.
* @return a pointer to the vif (@ref IfTreeAddr4) or NULL if not found.
*/
IfTreeAddr4* find_addr(const IPv4& addr);
/**
* Find a const IPv4 address.
*
* @param addr the address to search for.
* @return a const pointer to the vif (@ref IfTreeAddr4) or NULL
* if not found.
*/
const IfTreeAddr4* find_addr(const IPv4& addr) const;
/**
* Find an IPv6 address.
*
* @param addr the address to search for.
* @return a pointer to the vif (@ref IfTreeAddr6) or NULL if not found.
*/
IfTreeAddr6* find_addr(const IPv6& addr);
/**
* Find a const IPv6 address.
*
* @param addr the address to search for.
* @return a pointer to the vif (@ref IfTreeAddr6) or NULL if not found.
*/
const IfTreeAddr6* find_addr(const IPv6& addr) const;
/**
* Propagate vif flags to the addresses.
*/
void propagate_flags_to_addresses();
/**
* Copy state of internal variables from another IfTreeVif.
*/
void copy_state(const IfTreeVif& o) {
set_pif_index(o.pif_index());
set_vif_index(o.vif_index());
set_enabled(o.enabled());
set_broadcast(o.broadcast());
set_loopback(o.loopback());
set_point_to_point(o.point_to_point());
set_multicast(o.multicast());
set_pim_register(o.pim_register());
set_vif_flags(o.vif_flags());
set_vlan(o.is_vlan());
set_vlan_id(o.vlan_id());
}
/**
* Test if the vif-specific internal state is same.
*
* @param o the IfTreeVif to compare against.
* @return true if the vif-specific internal state is same.
*/
bool is_same_state(const IfTreeVif& o) {
return ((pif_index() == o.pif_index())
&& (vif_index() == o.vif_index())
&& (enabled() == o.enabled())
&& (broadcast() == o.broadcast())
&& (loopback() == o.loopback())
&& (point_to_point() == o.point_to_point())
&& (multicast() == o.multicast())
&& (pim_register() == o.pim_register())
&& (vif_flags() == o.vif_flags())
&& (is_vlan() == o.is_vlan())
&& (vlan_id() == o.vlan_id()));
}
void finalize_state();
string str() const;
private:
IfTreeVif(const IfTreeVif&); // Not implemented
IfTreeVif& operator=(const IfTreeVif&); // Not implemented
IfTreeInterface& _iface;
const string _vifname;
uint32_t _pif_index;
uint32_t _vif_index;
bool _enabled;
bool _broadcast;
bool _loopback;
bool _point_to_point;
bool _multicast;
bool _pim_register;
uint32_t _vif_flags; // The system-specific vif flags
bool _is_vlan;
uint16_t _vlan_id;
IPv4Map _ipv4addrs;
IPv6Map _ipv6addrs;
};
/**
* Class for holding an IPv4 interface address and address related items.
*/
class IfTreeAddr4 : public IfTreeItem {
public:
IfTreeAddr4(const IPv4& addr)
: IfTreeItem(),
_addr(addr),
_enabled(false),
_broadcast(false),
_loopback(false),
_point_to_point(false),
_multicast(false),
_prefix_len(0)
{}
const IPv4& addr() const { return _addr; }
bool enabled() const { return _enabled; }
bool broadcast() const { return _broadcast; }
bool loopback() const { return _loopback; }
bool point_to_point() const { return _point_to_point; }
bool multicast() const { return _multicast; }
void set_enabled(bool en) { _enabled = en; mark(CHANGED); }
void set_broadcast(bool v) { _broadcast = v; mark(CHANGED); }
void set_loopback(bool v) { _loopback = v; mark(CHANGED); }
void set_point_to_point(bool v) { _point_to_point = v; mark(CHANGED); }
void set_multicast(bool v) { _multicast = v; mark(CHANGED); }
/**
* Get prefix length associates with address.
*/
uint32_t prefix_len() const { return _prefix_len; }
/**
* Set prefix length associate with address.
*
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int set_prefix_len(uint32_t prefix_len);
/**
* Get the broadcast address.
*
* @return the broadcast address or IPv4::ZERO() if there is no
* broadcast address set.
*/
IPv4 bcast() const;
/**
* Set the broadcast address.
* @param baddr the broadcast address.
*/
void set_bcast(const IPv4& baddr);
/**
* Get the endpoint address of a point-to-point link.
* @return the broadcast address or IPv4::ZERO() if there is no
* broadcast address set.
*/
IPv4 endpoint() const;
/**
* Set the endpoint address of a point-to-point link.
* @param oaddr the endpoint address.
*/
void set_endpoint(const IPv4& oaddr);
/**
* Copy state of internal variables from another IfTreeAddr4.
*/
void copy_state(const IfTreeAddr4& o) {
set_enabled(o.enabled());
set_broadcast(o.broadcast());
set_loopback(o.loopback());
set_point_to_point(o.point_to_point());
set_multicast(o.multicast());
if (o.broadcast())
set_bcast(o.bcast());
if (o.point_to_point())
set_endpoint(o.endpoint());
set_prefix_len(o.prefix_len());
}
/**
* Test if the address-specific internal state is same.
*
* @param o the IfTreeAddr4 to compare against.
* @return true if the address-specific internal state is same.
*/
bool is_same_state(const IfTreeAddr4& o) {
return ((enabled() == o.enabled())
&& (broadcast() == o.broadcast())
&& (loopback() == o.loopback())
&& (point_to_point() == o.point_to_point())
&& (multicast() == o.multicast())
&& (bcast() == o.bcast())
&& (endpoint() == o.endpoint())
&& (prefix_len() == o.prefix_len()));
}
void finalize_state();
string str() const;
private:
IfTreeAddr4(const IfTreeAddr4&); // Not implemented
IfTreeAddr4& operator=(const IfTreeAddr4&); // Not implemented
IPv4 _addr;
bool _enabled;
bool _broadcast;
bool _loopback;
bool _point_to_point;
bool _multicast;
IPv4 _oaddr; // Other address - p2p endpoint or bcast addr
uint32_t _prefix_len; // The prefix length
};
/**
* Class for holding an IPv6 interface address and address related items.
*/
class IfTreeAddr6 : public IfTreeItem
{
public:
IfTreeAddr6(const IPv6& addr)
: IfTreeItem(),
_addr(addr),
_enabled(false),
_loopback(false),
_point_to_point(false),
_multicast(false),
_prefix_len(0)
{}
const IPv6& addr() const { return _addr; }
bool enabled() const { return _enabled; }
bool loopback() const { return _loopback; }
bool point_to_point() const { return _point_to_point; }
bool multicast() const { return _multicast; }
void set_enabled(bool en) { _enabled = en; mark(CHANGED); }
void set_loopback(bool v) { _loopback = v; mark(CHANGED); }
void set_point_to_point(bool v) { _point_to_point = v; mark(CHANGED); }
void set_multicast(bool v) { _multicast = v; mark(CHANGED); }
/**
* Get prefix length associated with address.
*/
uint32_t prefix_len() const { return _prefix_len; }
/**
* Set prefix length associate with address.
*
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int set_prefix_len(uint32_t prefix_len);
IPv6 endpoint() const;
void set_endpoint(const IPv6& oaddr);
/**
* Copy state of internal variables from another IfTreeAddr6.
*/
void copy_state(const IfTreeAddr6& o) {
set_enabled(o.enabled());
set_loopback(o.loopback());
set_point_to_point(o.point_to_point());
set_multicast(o.multicast());
if (o.point_to_point())
set_endpoint(o.endpoint());
set_prefix_len(o.prefix_len());
}
/**
* Test if the address-specific internal state is same.
*
* @param o the IfTreeAddr6 to compare against.
* @return true if the address-specific internal state is same.
*/
bool is_same_state(const IfTreeAddr6& o) {
return ((enabled() == o.enabled())
&& (loopback() == o.loopback())
&& (point_to_point() == o.point_to_point())
&& (multicast() == o.multicast())
&& (endpoint() == o.endpoint())
&& (prefix_len() == o.prefix_len()));
}
void finalize_state();
string str() const;
private:
IfTreeAddr6(const IfTreeAddr6&); // Not implemented
IfTreeAddr6& operator=(const IfTreeAddr6&); // Not implemented
IPv6 _addr;
bool _enabled;
bool _loopback;
bool _point_to_point;
bool _multicast;
IPv6 _oaddr; // Other address - p2p endpoint
uint32_t _prefix_len; // The prefix length
};
#endif // __FEA_IFTREE_HH__
Generated by: pavlin on kobe.xorp.net on Wed Jan 7 19:10:56 2009, using kdoc 2.0a54+XORP.