xorp

iftree.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 // vim:set sts=4 ts=8:
00003 
00004 // Copyright (c) 2001-2012 XORP, Inc and Others
00005 //
00006 // This program is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License, Version 2, June
00008 // 1991 as published by the Free Software Foundation. Redistribution
00009 // and/or modification of this program under the terms of any other
00010 // version of the GNU General Public License is not permitted.
00011 // 
00012 // This program is distributed in the hope that it will be useful, but
00013 // WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00015 // see the GNU General Public License, Version 2, a copy of which can be
00016 // found in the XORP LICENSE.gpl file.
00017 // 
00018 // XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00019 // http://xorp.net
00020 
00021 
00022 #ifndef __FEA_IFTREE_HH__
00023 #define __FEA_IFTREE_HH__
00024 
00025 #include "libxorp/ipv4.hh"
00026 #include "libxorp/ipv6.hh"
00027 #include "libxorp/mac.hh"
00028 
00029 class IPvX;
00030 
00036 class IfTreeItem :
00037     public NONCOPYABLE
00038 {
00039 public:
00040     IfTreeItem() : _st(CREATED), _soft(false) {}
00041     virtual ~IfTreeItem() {}
00042 
00043 public:
00044     enum State {
00045     NO_CHANGE   = 0x00,
00046     CREATED     = 0x01,
00047     DELETED     = 0x02,
00048     CHANGED     = 0x04
00049     };
00050 
00051     int set_state(State st) {
00052     if (bits(st) > 1) {
00053         return (XORP_ERROR);
00054     }
00055     _st = st;
00056     return (XORP_OK);
00057     }
00058 
00059     State state() const         { return _st; }
00060 
00061     virtual int mark(State st) {
00062     if (bits(st) > 1) {
00063         return (XORP_ERROR);
00064     }
00065     if (st & (CREATED | DELETED)) {
00066         _st = st;
00067         return (XORP_OK);
00068     }
00069     if (_st & (CREATED | DELETED)) {
00070         return (XORP_OK);
00071     }
00072     _st = st;
00073     return (XORP_OK);
00074     }
00075     bool is_marked(State st) const  { return st == _st; }
00076 
00077     void set_soft(bool en)      { _soft = en; }
00078 
00079     bool is_soft() const        { return _soft; }
00080 
00087     virtual void finalize_state() = 0;
00088 
00089     string str() const;
00090 
00091 protected:
00092     static uint32_t bits(State st) {
00093     uint32_t c;
00094     for (c = 0; st != NO_CHANGE; c += st & 0x01)
00095         st = State(st >> 1);
00096     return c;
00097     }
00098 
00099     State _st;
00100     bool  _soft;
00101 };
00102 
00103 
00104 // Classes derived from IfTreeItem
00105 class IfTree;
00106 class IfTreeInterface;
00107 class IfTreeVif;
00108 class IfTreeAddr4;
00109 class IfTreeAddr6;
00110 
00111 
00112 enum IfTreeIfaceEventE {
00113     IFTREE_DELETE_IFACE, // marked deleted
00114     IFTREE_ERASE_IFACE //erased entirely
00115 };
00116 
00117 enum IfTreeVifEventE {
00118     IFTREE_DELETE_VIF, // marked deleted
00119     IFTREE_ERASE_VIF //erased entirely
00120 };
00121 
00125 class IfTreeListener {
00126 public:
00127     virtual ~IfTreeListener() { }
00128 
00129     virtual void notifyDeletingIface(const string& ifname) = 0; // marking iface deleted
00130     virtual void notifyErasingIface(const string& ifname) = 0; // erasing iface memory
00131 
00132     // These may not be called if the parrent iface is being deleted, so
00133     // alwaysclean up all VIFs in the iface handler.
00134     virtual void notifyDeletingVif(const string& ifname, const string& vifname) = 0; // marking vif deleted
00135     virtual void notifyErasingVif(const string& ifname, const string& vifname) = 0; // erasing vif memory
00136 
00137     // Add more as are needed.
00138 };
00139 
00143 class IfTree : public IfTreeItem {
00144 public:
00145     typedef map<string, IfTreeInterface*> IfMap;
00146     typedef map<uint32_t, IfTreeInterface*> IfIndexMap;
00147     //
00148     // XXX: We use a multimap for the index->vif mapping, because a VLAN
00149     // vif could be listed in two places: with its parent physical interface,
00150     // or along as its own parent interface.
00151     //
00152     typedef multimap<uint32_t, IfTreeVif*> VifIndexMap;
00153 
00157     IfTree(const char* tree_name);
00158 
00164     IfTree(const IfTree& other);
00165 
00169     virtual ~IfTree();
00170 
00176     IfTree& operator=(const IfTree& other);
00177 
00181     void clear();
00182 
00186     void registerListener(IfTreeListener* l) const;
00187 
00191     void unregisterListener(IfTreeListener* l) const;
00192 
00193 
00201     void add_recursive_interface(const IfTreeInterface& other_iface,
00202                  bool mark_state);
00203 
00210     int add_interface(const string& ifname);
00211 
00219     int remove_interface(const string& ifname);
00220 
00228     int update_interface(const IfTreeInterface& other_iface);
00229 
00237     IfTreeInterface* find_interface(const string& ifname);
00238 
00246     const IfTreeInterface* find_interface(const string& ifname) const;
00247 
00255     IfTreeInterface* find_interface(uint32_t pif_index);
00256 
00264     const IfTreeInterface* find_interface(uint32_t pif_index) const;
00265 
00273     IfTreeVif* find_vif(const string& ifname, const string& vifname);
00274 
00283     const IfTreeVif* find_vif(const string& ifname,
00284                   const string& vifname) const;
00285 
00292     IfTreeVif* find_vif(uint32_t pif_index);
00293 
00301     const IfTreeVif* find_vif(uint32_t pif_index) const;
00302 
00311     IfTreeAddr4* find_addr(const string& ifname, const string& vifname,
00312                const IPv4& addr);
00313 
00323     const IfTreeAddr4* find_addr(const string& ifname, const string& vifname,
00324                  const IPv4& addr) const;
00325 
00334     IfTreeAddr6* find_addr(const string& ifname, const string& vifname,
00335                const IPv6& addr);
00336 
00345     const IfTreeAddr6* find_addr(const string& ifname, const string& vifname,
00346                  const IPv6& addr) const;
00347 
00357     bool find_interface_vif_by_addr(const IPvX& addr,
00358                     const IfTreeInterface*& ifp,
00359                     const IfTreeVif*& vifp) const;
00360 
00370     bool find_interface_vif_same_subnet_or_p2p(const IPvX& addr,
00371                            const IfTreeInterface*& ifp,
00372                            const IfTreeVif*& vifp) const;
00373 
00379     IfMap& interfaces() { return _interfaces; }
00380 
00386     const IfMap& interfaces() const { return _interfaces; }
00387 
00425     IfTree& align_with_pulled_changes(const IfTree& other,
00426                       const IfTree& user_config);
00427 
00479     IfTree& align_with_observed_changes(const IfTree& other,
00480                     const IfTree& user_config);
00481 
00513     IfTree& align_with_user_config(const IfTree& other);
00514 
00530     IfTree& prepare_replacement_state(const IfTree& other);
00531 
00541     IfTree& prune_bogus_deleted_state(const IfTree& old_iftree);
00542 
00547     void finalize_state();
00548 
00552     string str() const;
00553 
00554     const string& getName() const { return name; }
00555 
00556     void markVifDeleted(IfTreeVif* ifp);
00557     void markIfaceDeleted(IfTreeInterface* ifp);
00558 
00559 protected:
00560     friend class IfTreeInterface;
00561     friend class IfTreeVif;
00562 
00563     void insert_ifindex(IfTreeInterface* ifp);
00564     void erase_ifindex(IfTreeInterface* ifp);
00565     void insert_vifindex(IfTreeVif* vifp);
00566     void erase_vifindex(IfTreeVif* vifp);
00567 
00568     void sendEvent(IfTreeVifEventE e, IfTreeVif* vifp);
00569     void sendEvent(IfTreeIfaceEventE e, IfTreeInterface* ifp);
00570 
00571 private:
00572     string name; // identifier for this tree
00573     IfMap   _interfaces;
00574     IfIndexMap  _ifindex_map;       // Map of pif_index to interface
00575     VifIndexMap _vifindex_map;      // Map of pif_index to vif
00576 
00577     // Make this mutable so that we can past const references to other classes,
00578     // but still let them be listeners.
00579     mutable list<IfTreeListener*> listeners;
00580 };
00581 
00582 
00586 class IfTreeInterface :
00587     public IfTreeItem
00588 {
00589 public:
00590     typedef map<string, IfTreeVif*> VifMap;
00591     typedef set<Mac>              MacSet;
00592 
00593     IfTreeInterface(IfTree& iftree, const string& ifname);
00594     virtual ~IfTreeInterface();
00595 
00596     IfTree& iftree()            { return _iftree; }
00597     const string& ifname() const    { return _ifname; }
00598 
00599     uint32_t pif_index() const      { return _pif_index; }
00600     void set_pif_index(uint32_t v)  {
00601     iftree().erase_ifindex(this);
00602     _pif_index = v;
00603     mark(CHANGED);
00604     iftree().insert_ifindex(this);
00605     }
00606 
00607     virtual int mark(State st) {
00608     int rv = IfTreeItem::mark(st);
00609     if (st == DELETED) {
00610         set_probed_vlan(false); // need to reprobe if this ever goes un-deleted
00611     }
00612     return rv;
00613     }
00614 
00615     // This relates to vlans.
00616     bool cr_by_xorp() const { return _created_by_xorp; }
00617     void set_cr_by_xorp(bool b) { _created_by_xorp = b; }
00618 
00619     bool probed_vlan() const { return _probed_vlan; }
00620     void set_probed_vlan(bool b) { _probed_vlan = b; }
00621 
00622     bool enabled() const        { return _enabled; }
00623     void set_enabled(bool en)       { _enabled = en; mark(CHANGED); }
00624 
00625     uint32_t mtu() const        { return _mtu; }
00626     void set_mtu(uint32_t mtu)      { _mtu = mtu; mark(CHANGED); }
00627 
00628     const Mac& mac() const      { return _mac; }
00629     void set_mac(const Mac& mac)    { _mac = mac; mark(CHANGED); }
00630 
00631     MacSet& macs()          { return _macs; }
00632     const MacSet& macs() const      { return _macs; }
00633 
00634     bool no_carrier() const     { return _no_carrier; }
00635     void set_no_carrier(bool v)     { _no_carrier = v; mark(CHANGED); }
00636 
00637     uint64_t baudrate() const       { return _baudrate; }
00638     void set_baudrate(uint64_t v)   { _baudrate = v; mark(CHANGED); }
00639 
00640     const string& parent_ifname() const { return _parent_ifname; }
00641     void set_parent_ifname(string& v) { if (v != _parent_ifname) { _parent_ifname = v; mark(CHANGED); }}
00642 
00643     bool is_vlan() const;
00644     const string& iface_type() const { return _iface_type; }
00645     void set_iface_type(string& v) { if (v != _iface_type) { _iface_type = v; mark(CHANGED); }}
00646 
00647     const string& vid() const { return _vid; }
00648     void set_vid(string& v) { if (v != _vid) { _vid = v; mark(CHANGED); }}
00649 
00650     bool discard() const        { return _discard; }
00651     void set_discard(bool discard)  { _discard = discard; mark(CHANGED); }
00652 
00653     bool unreachable() const        { return _unreachable; }
00654     void set_unreachable(bool v)    { _unreachable = v; mark(CHANGED); }
00655 
00656     bool management() const     { return _management; }
00657     void set_management(bool v)     { _management = v; mark(CHANGED); }
00658 
00659     bool default_system_config() const  { return _default_system_config; }
00660     void set_default_system_config(bool v) { _default_system_config = v; mark(CHANGED); }
00661 
00670     uint32_t interface_flags() const    { return _interface_flags; }
00671 
00680     void set_interface_flags(uint32_t v)    {
00681     _interface_flags = v;
00682     mark(CHANGED);
00683     }
00684 
00685 
00686     const VifMap& vifs() const      { return _vifs; }
00687     VifMap& vifs()          { return _vifs; }
00688 
00696     void add_recursive_vif(const IfTreeVif& other_vif, bool mark_state);
00697 
00704     int add_vif(const string& vifname);
00705 
00713     int remove_vif(const string& vifname);
00714 
00721     IfTreeVif* find_vif(const string& vifname);
00722 
00730     const IfTreeVif* find_vif(const string& vifname) const;
00731 
00739     IfTreeVif* find_vif(uint32_t pif_index);
00740 
00748     const IfTreeVif* find_vif(uint32_t pif_index) const;
00749 
00757     IfTreeAddr4* find_addr(const string& vifname, const IPv4& addr);
00758 
00767     const IfTreeAddr4* find_addr(const string& vifname,
00768                  const IPv4& addr) const;
00769 
00777     IfTreeAddr6* find_addr(const string& vifname, const IPv6& addr);
00778 
00786     const IfTreeAddr6* find_addr(const string& vifname,
00787                  const IPv6& addr) const;
00788 
00796     void copy_state(const IfTreeInterface& o, bool copy_user_config);
00797 
00804     bool is_same_state(const IfTreeInterface& o);
00805 
00806     void finalize_state();
00807 
00808     string str() const;
00809 
00810 private:
00811     IfTree& _iftree;
00812     const string _ifname;
00813 
00814     /* virtual interface info */
00815     string _parent_ifname;
00816     string _iface_type;
00817     string _vid;
00818 
00819     uint32_t    _pif_index;
00820     bool        _created_by_xorp; // for vlans
00821     bool        _probed_vlan;
00822     bool    _enabled;
00823     bool    _discard;
00824     bool    _unreachable;
00825     bool    _management;
00826     bool    _default_system_config;
00827     uint32_t    _mtu;
00828     Mac     _mac;
00829     bool    _no_carrier;
00830     uint64_t    _baudrate;      // The link baudrate
00831     uint32_t    _interface_flags;   // The system-specific interface flags
00832     VifMap  _vifs;
00833     MacSet  _macs; // XXX: not part of user config, but used by processes
00834 };
00835 
00836 
00840 class IfTreeVif :
00841     public IfTreeItem
00842 {
00843 public:
00844     typedef map<IPv4, IfTreeAddr4*> IPv4Map;
00845     typedef map<IPv6, IfTreeAddr6*> IPv6Map;
00846 
00847     IfTreeVif(IfTreeInterface& iface, const string& vifname);
00848     virtual ~IfTreeVif();
00849 
00850     IfTree& iftree()            { return _iface.iftree(); }
00851     const string& ifname() const    { return _iface.ifname(); }
00852     const string& vifname() const   { return _vifname; }
00853 
00854     uint32_t pif_index() const      { return _pif_index; }
00855     void set_pif_index(uint32_t v)  {
00856     iftree().erase_vifindex(this);
00857     _pif_index = v;
00858     mark(CHANGED);
00859     iftree().insert_vifindex(this);
00860     }
00861 
00862     uint32_t vif_index() const      { return _vif_index; }
00863     void set_vif_index(uint32_t v)  { _vif_index = v; mark(CHANGED); }
00864 
00865     bool enabled() const        { return _enabled; }
00866     bool broadcast() const      { return _broadcast; }
00867     bool loopback() const       { return _loopback; }
00868     bool point_to_point() const     { return _point_to_point; }
00869     bool multicast() const      { return _multicast; }
00870     bool pim_register() const       { return _pim_register; }
00871 
00872     void set_enabled(bool en)       { _enabled = en; mark(CHANGED); }
00873     void set_broadcast(bool v)      { _broadcast = v; mark(CHANGED); }
00874     void set_loopback(bool v)       { _loopback = v; mark(CHANGED); }
00875     void set_point_to_point(bool v) { _point_to_point = v; mark(CHANGED); }
00876     void set_multicast(bool v)      { _multicast = v; mark(CHANGED); }
00877     void set_pim_register(bool v)   { _pim_register = v; mark(CHANGED); }
00878 
00887     uint32_t vif_flags() const      { return _vif_flags; }
00888 
00897     void set_vif_flags(uint32_t v)  { _vif_flags = v; mark(CHANGED); }
00898 
00899     const IPv4Map& ipv4addrs() const    { return _ipv4addrs; }
00900     IPv4Map& ipv4addrs()        { return _ipv4addrs; }
00901 
00902     const IPv6Map& ipv6addrs() const    { return _ipv6addrs; }
00903     IPv6Map& ipv6addrs()        { return _ipv6addrs; }
00904 
00910     void copy_recursive_vif(const IfTreeVif& other_vif);
00911 
00919     void add_recursive_addr(const IfTreeAddr4& other_addr, bool mark_state);
00920 
00928     void add_recursive_addr(const IfTreeAddr6& other_addr, bool mark_state);
00929 
00936     int add_addr(const IPv4& addr);
00937 
00946     int remove_addr(const IPv4& addr);
00947 
00954     int add_addr(const IPv6& addr);
00955 
00964     int remove_addr(const IPv6& addr);
00965 
00972     IfTreeAddr4* find_addr(const IPv4& addr);
00973 
00981     const IfTreeAddr4* find_addr(const IPv4& addr) const;
00982 
00989     IfTreeAddr6* find_addr(const IPv6& addr);
00990 
00997     const IfTreeAddr6* find_addr(const IPv6& addr) const;
00998 
01002     void propagate_flags_to_addresses();
01003 
01007     void copy_state(const IfTreeVif& o) {
01008     set_pif_index(o.pif_index());
01009     set_vif_index(o.vif_index());
01010     set_enabled(o.enabled());
01011     set_broadcast(o.broadcast());
01012     set_loopback(o.loopback());
01013     set_point_to_point(o.point_to_point());
01014     set_multicast(o.multicast());
01015     set_pim_register(o.pim_register());
01016     set_vif_flags(o.vif_flags());
01017     }
01018 
01025     bool is_same_state(const IfTreeVif& o) {
01026     return ((pif_index() == o.pif_index())
01027         && (vif_index() == o.vif_index())
01028         && (enabled() == o.enabled())
01029         && (broadcast() == o.broadcast())
01030         && (loopback() == o.loopback())
01031         && (point_to_point() == o.point_to_point())
01032         && (multicast() == o.multicast())
01033         && (pim_register() == o.pim_register())
01034         && (vif_flags() == o.vif_flags()));
01035     }
01036 
01037     void finalize_state();
01038 
01039     string str() const;
01040 
01041 private:
01042     IfTreeInterface& _iface;
01043     const string _vifname;
01044 
01045     uint32_t    _pif_index;
01046     uint32_t    _vif_index;
01047     bool    _enabled;
01048     bool    _broadcast;
01049     bool    _loopback;
01050     bool    _point_to_point;
01051     bool    _multicast;
01052     bool    _pim_register;
01053     uint32_t    _vif_flags;     // The system-specific vif flags
01054 
01055     IPv4Map  _ipv4addrs;
01056     IPv6Map  _ipv6addrs;
01057 };
01058 
01059 
01063 class IfTreeAddr4 :
01064     public IfTreeItem
01065 {
01066 public:
01067     IfTreeAddr4(const IPv4& addr)
01068     : IfTreeItem(),
01069       _addr(addr),
01070       _enabled(false),
01071       _broadcast(false),
01072       _loopback(false),
01073       _point_to_point(false),
01074       _multicast(false),
01075       _prefix_len(0)
01076     {}
01077 
01078     const IPv4& addr() const        { return _addr; }
01079 
01080     bool enabled() const        { return _enabled; }
01081     bool broadcast() const      { return _broadcast; }
01082     bool loopback() const       { return _loopback; }
01083     bool point_to_point() const     { return _point_to_point; }
01084     bool multicast() const      { return _multicast; }
01085 
01086     void set_enabled(bool en)       { _enabled = en; mark(CHANGED); }
01087     void set_broadcast(bool v)      { _broadcast = v; mark(CHANGED); }
01088     void set_loopback(bool v)       { _loopback = v; mark(CHANGED); }
01089     void set_point_to_point(bool v) { _point_to_point = v; mark(CHANGED); }
01090     void set_multicast(bool v)      { _multicast = v; mark(CHANGED); }
01091 
01095     uint32_t prefix_len() const     { return _prefix_len; }
01096 
01102     int set_prefix_len(uint32_t prefix_len);
01103 
01110     IPv4 bcast() const;
01111 
01116     void set_bcast(const IPv4& baddr);
01117 
01123     IPv4 endpoint() const;
01124 
01129     void set_endpoint(const IPv4& oaddr);
01130 
01134     void copy_state(const IfTreeAddr4& o) {
01135     set_enabled(o.enabled());
01136     set_broadcast(o.broadcast());
01137     set_loopback(o.loopback());
01138     set_point_to_point(o.point_to_point());
01139     set_multicast(o.multicast());
01140     if (o.broadcast())
01141         set_bcast(o.bcast());
01142     if (o.point_to_point())
01143         set_endpoint(o.endpoint());
01144     set_prefix_len(o.prefix_len());
01145     }
01146 
01153     bool is_same_state(const IfTreeAddr4& o) {
01154     return ((enabled() == o.enabled())
01155         && (broadcast() == o.broadcast())
01156         && (loopback() == o.loopback())
01157         && (point_to_point() == o.point_to_point())
01158         && (multicast() == o.multicast())
01159         && (bcast() == o.bcast())
01160         && (endpoint() == o.endpoint())
01161         && (prefix_len() == o.prefix_len()));
01162     }
01163 
01164     void finalize_state();
01165 
01166     string str() const;
01167 
01168 private:
01169     IPv4    _addr;
01170 
01171     bool    _enabled;
01172     bool    _broadcast;
01173     bool    _loopback;
01174     bool    _point_to_point;
01175     bool    _multicast;
01176 
01177     IPv4    _oaddr;     // Other address - p2p endpoint or bcast addr
01178     uint32_t    _prefix_len;    // The prefix length
01179 };
01180 
01181 
01185 class IfTreeAddr6 :
01186     public IfTreeItem
01187 {
01188 public:
01189     IfTreeAddr6(const IPv6& addr)
01190     : IfTreeItem(),
01191       _addr(addr),
01192       _enabled(false),
01193       _loopback(false),
01194       _point_to_point(false),
01195       _multicast(false),
01196       _prefix_len(0)
01197     {}
01198 
01199     const IPv6& addr() const        { return _addr; }
01200 
01201     bool enabled() const        { return _enabled; }
01202     bool loopback() const       { return _loopback; }
01203     bool point_to_point() const     { return _point_to_point; }
01204     bool multicast() const      { return _multicast; }
01205 
01206     void set_enabled(bool en)       { _enabled = en; mark(CHANGED); }
01207     void set_loopback(bool v)       { _loopback = v; mark(CHANGED); }
01208     void set_point_to_point(bool v) { _point_to_point = v; mark(CHANGED); }
01209     void set_multicast(bool v)      { _multicast = v; mark(CHANGED); }
01210 
01214     uint32_t prefix_len() const     { return _prefix_len; }
01215 
01221     int set_prefix_len(uint32_t prefix_len);
01222 
01223     IPv6 endpoint() const;
01224 
01225     void set_endpoint(const IPv6& oaddr);
01226 
01230     void copy_state(const IfTreeAddr6& o) {
01231     set_enabled(o.enabled());
01232     set_loopback(o.loopback());
01233     set_point_to_point(o.point_to_point());
01234     set_multicast(o.multicast());
01235     if (o.point_to_point())
01236         set_endpoint(o.endpoint());
01237     set_prefix_len(o.prefix_len());
01238     }
01239 
01246     bool is_same_state(const IfTreeAddr6& o) {
01247     return ((enabled() == o.enabled())
01248         && (loopback() == o.loopback())
01249         && (point_to_point() == o.point_to_point())
01250         && (multicast() == o.multicast())
01251         && (endpoint() == o.endpoint())
01252         && (prefix_len() == o.prefix_len()));
01253     }
01254 
01255     void finalize_state();
01256 
01257     string str() const;
01258 
01259 private:
01260     IPv6    _addr;
01261 
01262     bool    _enabled;
01263     bool    _loopback;
01264     bool    _point_to_point;
01265     bool    _multicast;
01266 
01267     IPv6    _oaddr;     // Other address - p2p endpoint
01268     uint32_t    _prefix_len;    // The prefix length
01269 };
01270 
01271 #endif // __FEA_IFTREE_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations