xorp

proto_node.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-2011 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 Lesser General Public License, Version
00008 // 2.1, June 1999 as published by the Free Software Foundation.
00009 // Redistribution and/or modification of this program under the terms of
00010 // any other version of the GNU Lesser General Public License is not
00011 // permitted.
00012 // 
00013 // This program is distributed in the hope that it will be useful, but
00014 // WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00016 // see the GNU Lesser General Public License, Version 2.1, a copy of
00017 // which can be found in the XORP LICENSE.lgpl file.
00018 // 
00019 // XORP, Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00020 // http://xorp.net
00021 
00022 
00023 #ifndef __LIBPROTO_PROTO_NODE_HH__
00024 #define __LIBPROTO_PROTO_NODE_HH__
00025 
00026 
00027 
00028 
00029 
00030 #include "libxorp/xorp.h"
00031 #include "libxorp/xlog.h"
00032 #include "libxorp/callback.hh"
00033 #include "libxorp/eventloop.hh"
00034 #include "libxorp/status_codes.h"
00035 #include "libxorp/vif.hh"
00036 
00037 #include "proto_unit.hh"
00038 
00039 
00040 //
00041 // Protocol node generic functionality
00042 //
00043 
00044 
00045 class EventLoop;
00046 class IPvX;
00047 class IPvXNet;
00048 
00052 template<class V>
00053 class ProtoNode : public ProtoUnit {
00054 public:
00063     ProtoNode(int init_family, xorp_module_id init_module_id,
00064           EventLoop& init_eventloop)
00065     : ProtoUnit(init_family, init_module_id),
00066       _eventloop(init_eventloop),
00067       _node_status(PROC_NULL),
00068       _startup_requests_n(0),
00069       _shutdown_requests_n(0) {}
00070     
00074     virtual ~ProtoNode() {
00075     // TODO: free vifs (after they are added, etc.
00076     }
00077     
00084     uint32_t vif_name2vif_index(const string& vif_name) const;
00085     
00092     uint32_t find_unused_vif_index() const;
00093     
00101     V *vif_find_by_name(const string& name) const;
00102     
00114     V *vif_find_by_addr(const IPvX& ipaddr_test) const;
00115     
00123     V *vif_find_by_pif_index(uint32_t pif_index) const;
00124     
00132     V *vif_find_by_vif_index(uint32_t vif_index) const;
00133 
00147     V *vif_find_same_subnet_or_p2p(const IPvX& ipaddr_test) const;
00148 
00160      bool is_my_addr(const IPvX& ipaddr_test) const {
00161     return (vif_find_by_addr(ipaddr_test) != NULL);
00162     }
00163 
00170     int add_vif(V *vif);
00171     
00181     int delete_vif(const V *vif);
00182     
00188     vector<V *>& proto_vifs() { return (_proto_vifs);   }
00189 
00195     const vector<V *>& const_proto_vifs() const { return (_proto_vifs); }
00196     
00205     uint32_t    maxvifs() const { return (_proto_vifs.size()); }
00206 
00212     EventLoop& eventloop() { return (_eventloop); }
00213 
00236     virtual int proto_recv(const string& if_name,
00237                const string& vif_name,
00238                const IPvX& src_address,
00239                const IPvX& dst_address,
00240                uint8_t ip_protocol,
00241                int32_t ip_ttl,
00242                int32_t ip_tos,
00243                bool ip_router_alert,
00244                bool ip_internet_control,
00245                const vector<uint8_t>& payload,
00246                string& error_msg) = 0;
00247     
00275     virtual int proto_send(const string& if_name,
00276                const string& vif_name,
00277                const IPvX& src_address,
00278                const IPvX& dst_address,
00279                uint8_t ip_protocol,
00280                int32_t ip_ttl,
00281                int32_t ip_tos,
00282                bool ip_router_alert,
00283                bool ip_internet_control,
00284                const uint8_t* sndbuf,
00285                size_t sndlen,
00286                string& error_msg) = 0;
00287 
00315     virtual int signal_message_recv(const string& src_module_instance_name,
00316                     int message_type,
00317                     uint32_t vif_index,
00318                     const IPvX& src,
00319                     const IPvX& dst,
00320                     const uint8_t *rcvbuf,
00321                     size_t rcvlen) = 0;
00322     
00350     virtual int signal_message_send(const string& dst_module_instance_name,
00351                     int message_type,
00352                     uint32_t vif_index,
00353                     const IPvX& src,
00354                     const IPvX& dst,
00355                     const uint8_t *sndbuf,
00356                     size_t sndlen) = 0;
00357 
00363     bool    is_done() const { return (_node_status == PROC_DONE); }
00364 
00370     ProcessStatus node_status() const { return (_node_status); }
00371     
00377     void set_node_status(ProcessStatus v) { _node_status = v; }
00378     
00387     int     start_config(string& error_msg);
00388     
00397     int     end_config(string& error_msg);
00398 
00405     uint32_t find_unused_config_vif_index() const;
00406 
00414     int     add_config_vif(const Vif& vif, string& error_msg);
00415     
00424     int     add_config_vif(const string& vif_name, uint32_t vif_index,
00425                    string& error_msg);
00426 
00434     int     delete_config_vif(const string& vif_name, string& error_msg);
00435 
00447     int     add_config_vif_addr(const string& vif_name,
00448                     const IPvX& addr,
00449                     const IPvXNet& subnet,
00450                     const IPvX& broadcast,
00451                     const IPvX& peer,
00452                     string& error_msg);
00453     
00462     int     delete_config_vif_addr(const string& vif_name,
00463                        const IPvX& addr,
00464                        string& error_msg);
00465     
00474     int     set_config_pif_index(const string& vif_name,
00475                      uint32_t pif_index,
00476                      string& error_msg);
00477     
00492     int     set_config_vif_flags(const string& vif_name,
00493                      bool is_pim_register,
00494                      bool is_p2p,
00495                      bool is_loopback,
00496                      bool is_multicast,
00497                      bool is_broadcast,
00498                      bool is_up,
00499                      uint32_t mtu,
00500                      string& error_msg);
00501 
00507     map<string, Vif>& configured_vifs() { return (_configured_vifs); }
00508 
00516     const Vif *configured_vif_find_by_name(const string& name) const;
00517 
00525     ProcessStatus   node_status(string& reason_msg);
00526 
00530     void incr_startup_requests_n();
00531 
00535     void decr_startup_requests_n();
00536 
00540     void incr_shutdown_requests_n();
00541 
00545     void decr_shutdown_requests_n();
00546     
00547 protected:
00548     void update_status();
00549     
00550 private:
00551     // TODO: add vifs, etc
00552     
00553     vector<V *> _proto_vifs;    // The array with all protocol vifs
00554     EventLoop&  _eventloop; // The event loop to use
00555     
00556     map<string, uint32_t> _vif_name2vif_index_map;
00557     
00558     ProcessStatus   _node_status;       // The node status
00559 
00560     //
00561     // Status-related state
00562     //
00563     size_t      _startup_requests_n;
00564     size_t      _shutdown_requests_n;
00565     
00566     //
00567     // Config-related state
00568     //
00569     map<string, Vif>    _configured_vifs;   // Configured vifs
00570 };
00571 
00572 //
00573 // Deferred definitions
00574 //
00575 
00576 template<class V>
00577 ProcessStatus
00578 ProtoNode<V>::node_status(string& reason_msg)
00579 {
00580     ProcessStatus status = _node_status;
00581 
00582     // Set the return message with the reason
00583     reason_msg = "";
00584     switch (status) {
00585     case PROC_NULL:
00586     // Can't be running and in this state
00587     XLOG_UNREACHABLE();
00588     break;
00589     case PROC_STARTUP:
00590     // Get the message about the startup progress
00591     reason_msg = c_format("Waiting for %u startup events",
00592                   XORP_UINT_CAST(_startup_requests_n));
00593     break;
00594     case PROC_NOT_READY:
00595     reason_msg = c_format("Waiting for configuration completion");
00596     break;
00597     case PROC_READY:
00598     reason_msg = c_format("Node is READY");
00599     break;
00600     case PROC_SHUTDOWN:
00601     // Get the message about the shutdown progress
00602     reason_msg = c_format("Waiting for %u shutdown events",
00603                   XORP_UINT_CAST(_shutdown_requests_n));
00604     break;
00605     case PROC_FAILED:
00606     reason_msg = c_format("Node is PROC_FAILED");
00607     break;
00608     case PROC_DONE:
00609     // Process has completed operation
00610     break;
00611     default:
00612     // Unknown status
00613     XLOG_UNREACHABLE();
00614     break;
00615     }
00616     
00617     return (status);
00618 }
00619 
00620 template<class V>
00621 inline void
00622 ProtoNode<V>::incr_startup_requests_n()
00623 {
00624     _startup_requests_n++;
00625     XLOG_ASSERT(_startup_requests_n > 0);
00626 }
00627 
00628 template<class V>
00629 inline void
00630 ProtoNode<V>::decr_startup_requests_n()
00631 {
00632     XLOG_ASSERT(_startup_requests_n > 0);
00633     _startup_requests_n--;
00634 
00635     update_status();
00636 }
00637 
00638 template<class V>
00639 inline void
00640 ProtoNode<V>::incr_shutdown_requests_n()
00641 {
00642     _shutdown_requests_n++;
00643     XLOG_ASSERT(_shutdown_requests_n > 0);
00644 }
00645 
00646 template<class V>
00647 inline void
00648 ProtoNode<V>::decr_shutdown_requests_n()
00649 {
00650     XLOG_ASSERT(_shutdown_requests_n > 0);
00651     _shutdown_requests_n--;
00652 
00653     update_status();
00654 }
00655 
00656 template<class V>
00657 inline void
00658 ProtoNode<V>::update_status()
00659 {
00660     //
00661     // Test if the startup process has completed
00662     //
00663     if (ServiceBase::status() == SERVICE_STARTING) {
00664     if (_startup_requests_n > 0)
00665         return;
00666 
00667     // The startup process has completed
00668     ServiceBase::set_status(SERVICE_RUNNING);
00669     set_node_status(PROC_READY);
00670     return;
00671     }
00672 
00673     //
00674     // Test if the shutdown process has completed
00675     //
00676     if (ServiceBase::status() == SERVICE_SHUTTING_DOWN) {
00677     if (_shutdown_requests_n > 0)
00678         return;
00679 
00680     // The shutdown process has completed
00681     ServiceBase::set_status(SERVICE_SHUTDOWN);
00682     set_node_status(PROC_DONE);
00683     return;
00684     }
00685 
00686     //
00687     // Test if we have failed
00688     //
00689     if (ServiceBase::status() == SERVICE_FAILED) {
00690     set_node_status(PROC_DONE);
00691     return;
00692     }
00693 }
00694 
00695 template<class V>
00696 inline uint32_t
00697 ProtoNode<V>::vif_name2vif_index(const string& vif_name) const
00698 {
00699     map<string, uint32_t>::const_iterator iter;
00700     
00701     iter = _vif_name2vif_index_map.find(vif_name);
00702     if (iter != _vif_name2vif_index_map.end())
00703     return (iter->second);
00704     return (Vif::VIF_INDEX_INVALID);
00705 }
00706 
00707 template<class V>
00708 inline uint32_t
00709 ProtoNode<V>::find_unused_vif_index() const
00710 {
00711     for (uint32_t i = 0; i < _proto_vifs.size(); i++) {
00712     if (_proto_vifs[i] == NULL)
00713         return (i);
00714     }
00715     
00716     if (maxvifs() + 1 >= Vif::VIF_INDEX_MAX)
00717     return (Vif::VIF_INDEX_INVALID);
00718     
00719     return (maxvifs());
00720 }
00721 
00722 template<class V>
00723 inline V *
00724 ProtoNode<V>::vif_find_by_name(const string& name) const
00725 {
00726     typename vector<V *>::const_iterator iter;
00727     
00728     for (iter = _proto_vifs.begin(); iter != _proto_vifs.end(); ++iter) {
00729     V *vif = *iter;
00730     if (vif == NULL)
00731         continue;
00732     if (vif->name() == name)
00733         return (vif);
00734     }
00735     
00736     return (NULL);
00737 }
00738 
00739 template<class V>
00740 inline V *
00741 ProtoNode<V>::vif_find_by_addr(const IPvX& ipaddr_test) const
00742 {
00743     typename vector<V *>::const_iterator iter;
00744     
00745     for (iter = _proto_vifs.begin(); iter != _proto_vifs.end(); ++iter) {
00746     V *vif = *iter;
00747     if (vif == NULL)
00748         continue;
00749     //
00750     // XXX: exclude the PIM Register vifs, because they are special
00751     //
00752     if (vif->is_pim_register())
00753         continue;
00754     if (vif->is_my_addr(ipaddr_test))
00755         return (vif);
00756     }
00757     
00758     return (NULL);
00759 }
00760 
00761 template<class V>
00762 inline V *
00763 ProtoNode<V>::vif_find_by_pif_index(uint32_t pif_index) const
00764 {
00765     typename vector<V *>::const_iterator iter;
00766     
00767     for (iter = _proto_vifs.begin(); iter != _proto_vifs.end(); ++iter) {
00768     V *vif = *iter;
00769     if (vif == NULL)
00770         continue;
00771     if (vif->pif_index() == pif_index)
00772         return (vif);
00773     }
00774     
00775     return (NULL);
00776 }
00777 
00778 template<class V>
00779 inline V *
00780 ProtoNode<V>::vif_find_by_vif_index(uint32_t vif_index) const
00781 {
00782     if (vif_index < _proto_vifs.size()) {
00783     // XXX: if vif_index becomes signed, we must check (vif_index >= 0)
00784     return (_proto_vifs[vif_index]);
00785     }
00786     return (NULL);
00787 }
00788 
00789 template<class V>
00790 inline V *
00791 ProtoNode<V>::vif_find_same_subnet_or_p2p(const IPvX& ipaddr_test) const
00792 {
00793     typename vector<V *>::const_iterator iter;
00794     
00795     for (iter = _proto_vifs.begin(); iter != _proto_vifs.end(); ++iter) {
00796     V *vif = *iter;
00797     if (vif == NULL)
00798         continue;
00799     //
00800     // XXX: exclude the PIM Register vifs, because they are special
00801     //
00802     if (vif->is_pim_register())
00803         continue;
00804     if (vif->is_same_subnet(ipaddr_test) || vif->is_same_p2p(ipaddr_test))
00805         return (vif);
00806     }
00807     
00808     return (NULL);
00809 }
00810 
00811 template<class V>
00812 inline int
00813 ProtoNode<V>::add_vif(V *vif)
00814 {
00815     if (vif == NULL) {
00816     XLOG_ERROR("Cannot add NULL vif");
00817     return (XORP_ERROR);
00818     }
00819     
00820     if (vif_find_by_name(vif->name()) != NULL) {
00821     XLOG_ERROR("Cannot add vif %s: already exist",
00822            vif->name().c_str());
00823     return (XORP_ERROR);
00824     }
00825     if (vif_find_by_vif_index(vif->vif_index()) != NULL) {
00826     XLOG_ERROR("Cannot add vif %s with vif_index = %d: "
00827            "already exist vif with such vif_index",
00828            vif->name().c_str(), vif->vif_index());
00829     return (XORP_ERROR);
00830     }
00831     // XXX: we should check for the pif_index as well, but on older
00832     // systems the kernel doesn't assign pif_index to the interfaces
00833     
00834     //
00835     // Add enough empty entries for the new vif
00836     //
00837     while (vif->vif_index() >= maxvifs()) {
00838     _proto_vifs.push_back(NULL);
00839     }
00840     XLOG_ASSERT(_proto_vifs[vif->vif_index()] == NULL);
00841     
00842     //
00843     // Add the new vif
00844     //
00845     _proto_vifs[vif->vif_index()] = vif;
00846     
00847     // Add the entry to the vif_name2vif_index map
00848     _vif_name2vif_index_map.insert(
00849     pair<string, uint32_t>(vif->name(), vif->vif_index()));
00850     
00851     return (XORP_OK);
00852 }
00853 
00854 template<class V>
00855 inline int
00856 ProtoNode<V>::delete_vif(const V *vif)
00857 {
00858     if (vif == NULL) {
00859     XLOG_ERROR("Cannot delete NULL vif");
00860     return (XORP_ERROR);
00861     }
00862     
00863     if (vif_find_by_name(vif->name()) != vif) {
00864     XLOG_ERROR("Cannot delete vif %s: inconsistent data pointers",
00865            vif->name().c_str());
00866     return (XORP_ERROR);
00867     }
00868     if (vif_find_by_vif_index(vif->vif_index()) != vif) {
00869     XLOG_ERROR("Cannot delete vif %s with vif_index = %d: "
00870            "inconsistent data pointers",
00871            vif->name().c_str(), vif->vif_index());
00872     return (XORP_ERROR);
00873     }
00874     
00875     XLOG_ASSERT(vif->vif_index() < maxvifs());
00876     XLOG_ASSERT(_proto_vifs[vif->vif_index()] == vif);
00877     
00878     _proto_vifs[vif->vif_index()] = NULL;
00879     
00880     //
00881     // Remove unused vif pointers from the back of the vif array
00882     //
00883     while (_proto_vifs.size()) {
00884     size_t i = _proto_vifs.size() - 1;
00885     if (_proto_vifs[i] != NULL)
00886         break;
00887     _proto_vifs.pop_back();
00888     }
00889     
00890     // Remove the entry from the vif_name2vif_index map
00891     map<string, uint32_t>::iterator iter;
00892     iter = _vif_name2vif_index_map.find(vif->name());
00893     XLOG_ASSERT(iter != _vif_name2vif_index_map.end());
00894     _vif_name2vif_index_map.erase(iter);
00895     
00896     return (XORP_OK);
00897 }
00898 
00899 template<class V>
00900 inline int
00901 ProtoNode<V>::start_config(string& error_msg)
00902 {
00903     switch (node_status()) {
00904     case PROC_NOT_READY:
00905     break;  // OK, probably the first set of configuration changes,
00906         // or a batch of configuration changes that call end_config()
00907         // at the end.
00908     case PROC_READY:
00909     set_node_status(PROC_NOT_READY);
00910     break;  // OK, start a set of configuration changes
00911     case PROC_STARTUP:
00912     break;  // OK, we are still in the startup state
00913     case PROC_SHUTDOWN:
00914     error_msg = "invalid start config in PROC_SHUTDOWN state";
00915     return (XORP_ERROR);
00916     case PROC_FAILED:
00917     error_msg = "invalid start config in PROC_FAILED state";
00918     return (XORP_ERROR);
00919     case PROC_DONE:
00920     error_msg = "invalid start config in PROC_DONE state";
00921     return (XORP_ERROR);
00922     case PROC_NULL:
00923     // FALLTHROUGH
00924     default:
00925     XLOG_UNREACHABLE();
00926     return (XORP_ERROR);
00927     }
00928     
00929     return (XORP_OK);
00930 }
00931 
00932 template<class V>
00933 inline int
00934 ProtoNode<V>::end_config(string& error_msg)
00935 {
00936     switch (node_status()) {
00937     case PROC_NOT_READY:
00938     set_node_status(PROC_READY);
00939     break;  // OK, end a set of configuration changes
00940     case PROC_READY:
00941     break;  // OK, maybe we got into PROC_READY directly from PROC_STARTUP
00942     case PROC_STARTUP:
00943     break;  // OK, we are still in the startup state
00944     case PROC_SHUTDOWN:
00945     error_msg = "invalid end config in PROC_SHUTDOWN state";
00946     return (XORP_ERROR);
00947     case PROC_FAILED:
00948     error_msg = "invalid end config in PROC_FAILED state";
00949     return (XORP_ERROR);
00950     case PROC_DONE:
00951     error_msg = "invalid end config in PROC_DONE state";
00952     return (XORP_ERROR);
00953     case PROC_NULL:
00954     // FALLTHROUGH
00955     default:
00956     XLOG_UNREACHABLE();
00957     return (XORP_ERROR);
00958     }
00959     
00960     return (XORP_OK);
00961 }
00962 
00963 template<class V>
00964 inline uint32_t
00965 ProtoNode<V>::find_unused_config_vif_index() const
00966 {
00967     map<string, Vif>::const_iterator iter;
00968     
00969     for (uint32_t i = 0; i < Vif::VIF_INDEX_INVALID; i++) {
00970     bool is_avail = true;
00971     // Check if this vif index is in use
00972     for (iter = _configured_vifs.begin();
00973          iter != _configured_vifs.end();
00974          ++iter) {
00975         const Vif& vif = iter->second;
00976         if (vif.vif_index() == i) {
00977         is_avail = false;
00978         break;
00979         }
00980     }
00981     if (is_avail)
00982         return (i);
00983     }
00984     
00985     return (Vif::VIF_INDEX_INVALID);
00986 }
00987 
00988 template<class V>
00989 inline int
00990 ProtoNode<V>::add_config_vif(const Vif& vif, string& error_msg)
00991 {
00992     if (start_config(error_msg) != XORP_OK)
00993     return (XORP_ERROR);
00994     
00995     if (add_config_vif(vif.name(), vif.vif_index(), error_msg) != XORP_OK)
00996     return (XORP_ERROR);
00997     
00998     list<VifAddr>::const_iterator vif_addr_iter;
00999     for (vif_addr_iter = vif.addr_list().begin();
01000      vif_addr_iter != vif.addr_list().end();
01001      ++vif_addr_iter) {
01002     const VifAddr& vif_addr = *vif_addr_iter;
01003     if (add_config_vif_addr(vif.name(),
01004                 vif_addr.addr(),
01005                 vif_addr.subnet_addr(),
01006                 vif_addr.broadcast_addr(),
01007                 vif_addr.peer_addr(),
01008                 error_msg)
01009         != XORP_OK) {
01010         string dummy_error_msg;
01011         delete_config_vif(vif.name(), dummy_error_msg);
01012         return (XORP_ERROR);
01013     }
01014     }
01015     
01016     if (set_config_pif_index(vif.name(), vif.pif_index(), error_msg)
01017     != XORP_OK) {
01018     string dummy_error_msg;
01019     delete_config_vif(vif.name(), dummy_error_msg);
01020     return (XORP_ERROR);
01021     }
01022     
01023     if (set_config_vif_flags(vif.name(),
01024                  vif.is_pim_register(),
01025                  vif.is_p2p(),
01026                  vif.is_loopback(),
01027                  vif.is_multicast_capable(),
01028                  vif.is_broadcast_capable(),
01029                  vif.is_underlying_vif_up(),
01030                  vif.mtu(),
01031                  error_msg)
01032     != XORP_OK) {
01033     string dummy_error_msg;
01034     delete_config_vif(vif.name(), dummy_error_msg);
01035     return (XORP_ERROR);
01036     }
01037     
01038     return (XORP_OK);
01039 }
01040 
01041 template<class V>
01042 inline int
01043 ProtoNode<V>::add_config_vif(const string& vif_name, uint32_t vif_index,
01044                  string& error_msg)
01045 {
01046     map<string, Vif>::iterator iter;
01047     
01048     if (start_config(error_msg) != XORP_OK)
01049     return (XORP_ERROR);
01050     
01051     // Check whether we have vif with same name
01052     iter = _configured_vifs.find(vif_name);
01053     if (iter != _configured_vifs.end()) {
01054     error_msg = c_format("Cannot add vif %s: already have such vif",
01055                  vif_name.c_str());
01056     XLOG_ERROR("%s", error_msg.c_str());
01057     return (XORP_ERROR);
01058     }
01059     
01060     // Check whether we have vif with same vif_index
01061     for (iter = _configured_vifs.begin();
01062      iter != _configured_vifs.end();
01063      ++iter) {
01064     Vif* tmp_vif = &iter->second;
01065     if (tmp_vif->vif_index() == vif_index) {
01066         error_msg = c_format("Cannot add vif %s with vif_index %d: "
01067                  "already have vif %s with same vif_index",
01068                  vif_name.c_str(), vif_index,
01069                  tmp_vif->name().c_str());
01070         XLOG_ERROR("%s", error_msg.c_str());
01071         return (XORP_ERROR);
01072     }
01073     }
01074     
01075     // Insert the new vif
01076     Vif vif(vif_name);
01077     vif.set_vif_index(vif_index);
01078     _configured_vifs.insert(make_pair(vif_name, vif));
01079     
01080     return (XORP_OK);
01081 }
01082 
01083 template<class V>
01084 inline int
01085 ProtoNode<V>::delete_config_vif(const string& vif_name, string& error_msg)
01086 {
01087     map<string, Vif>::iterator iter;
01088     
01089     if (start_config(error_msg) != XORP_OK)
01090     return (XORP_ERROR);
01091     
01092     // Find the vif
01093     iter = _configured_vifs.find(vif_name);
01094     if (iter == _configured_vifs.end()) {
01095     error_msg = c_format("Cannot delete vif %s: no such vif",
01096                  vif_name.c_str());
01097     XLOG_ERROR("%s", error_msg.c_str());
01098     return (XORP_ERROR);
01099     }
01100     
01101     // Delete the vif
01102     _configured_vifs.erase(iter);
01103     
01104     return (XORP_OK);
01105 }
01106 
01107 template<class V>
01108 inline int
01109 ProtoNode<V>::add_config_vif_addr(const string& vif_name, const IPvX& addr,
01110                   const IPvXNet& subnet, const IPvX& broadcast,
01111                   const IPvX& peer, string& error_msg)
01112 {
01113     map<string, Vif>::iterator iter;
01114     
01115     if (start_config(error_msg) != XORP_OK)
01116     return (XORP_ERROR);
01117     
01118     // Find the vif
01119     iter = _configured_vifs.find(vif_name);
01120     if (iter == _configured_vifs.end()) {
01121     error_msg = c_format("Cannot add address to vif %s: no such vif",
01122                  vif_name.c_str());
01123     XLOG_ERROR("%s", error_msg.c_str());
01124     return (XORP_ERROR);
01125     }
01126     
01127     Vif* vif = &iter->second;
01128     
01129     // Test if we have same address
01130     if (vif->find_address(addr) != NULL) {
01131     error_msg = c_format("Cannot add address %s to vif %s: "
01132                  "already have such address",
01133                  cstring(addr), vif_name.c_str());
01134     XLOG_ERROR("%s", error_msg.c_str());
01135     return (XORP_ERROR);
01136     }
01137     
01138     // Add the address
01139     vif->add_address(addr, subnet, broadcast, peer);
01140     
01141     return (XORP_OK);
01142 }
01143 
01144 template<class V>
01145 inline int
01146 ProtoNode<V>::delete_config_vif_addr(const string& vif_name, const IPvX& addr,
01147                      string& error_msg)
01148 {
01149     map<string, Vif>::iterator iter;
01150     
01151     if (start_config(error_msg) != XORP_OK)
01152     return (XORP_ERROR);
01153     
01154     // Find the vif
01155     iter = _configured_vifs.find(vif_name);
01156     if (iter == _configured_vifs.end()) {
01157     error_msg = c_format("Cannot delete address from vif %s: no such vif",
01158                  vif_name.c_str());
01159     XLOG_ERROR("%s", error_msg.c_str());
01160     return (XORP_ERROR);
01161     }
01162     
01163     Vif* vif = &iter->second;
01164     
01165     // Test if we have this address
01166     if (vif->find_address(addr) == NULL) {
01167     error_msg = c_format("Cannot delete address %s from vif %s: "
01168                  "no such address",
01169                  cstring(addr), vif_name.c_str());
01170     XLOG_ERROR("%s", error_msg.c_str());
01171     }
01172     
01173     // Delete the address
01174     vif->delete_address(addr);
01175     
01176     return (XORP_OK);
01177 }
01178 
01179 template<class V>
01180 inline int
01181 ProtoNode<V>::set_config_pif_index(const string& vif_name,
01182                    uint32_t pif_index,
01183                    string& error_msg)
01184 {
01185     map<string, Vif>::iterator iter;
01186     
01187     if (start_config(error_msg) != XORP_OK)
01188     return (XORP_ERROR);
01189 
01190     // Find the vif
01191     iter = _configured_vifs.find(vif_name);
01192     if (iter == _configured_vifs.end()) {
01193     error_msg = c_format("Cannot set pif_index for vif %s: no such vif",
01194                  vif_name.c_str());
01195     XLOG_ERROR("%s", error_msg.c_str());
01196     return (XORP_ERROR);
01197     }
01198     
01199     Vif* vif = &iter->second;
01200     
01201     vif->set_pif_index(pif_index);
01202     
01203     return (XORP_OK);
01204 }
01205 
01206 template<class V>
01207 inline int
01208 ProtoNode<V>::set_config_vif_flags(const string& vif_name,
01209                    bool is_pim_register,
01210                    bool is_p2p,
01211                    bool is_loopback,
01212                    bool is_multicast,
01213                    bool is_broadcast,
01214                    bool is_up,
01215                    uint32_t mtu,
01216                    string& error_msg)
01217 {
01218     map<string, Vif>::iterator iter;
01219     
01220     if (start_config(error_msg) != XORP_OK)
01221     return (XORP_ERROR);
01222     
01223     // Find the vif
01224     iter = _configured_vifs.find(vif_name);
01225     if (iter == _configured_vifs.end()) {
01226     error_msg = c_format("Cannot set flags for vif %s: no such vif",
01227                  vif_name.c_str());
01228     XLOG_ERROR("%s", error_msg.c_str());
01229     return (XORP_ERROR);
01230     }
01231     
01232     Vif* vif = &iter->second;
01233     
01234     vif->set_pim_register(is_pim_register);
01235     vif->set_p2p(is_p2p);
01236     vif->set_loopback(is_loopback);
01237     vif->set_multicast_capable(is_multicast);
01238     vif->set_broadcast_capable(is_broadcast);
01239     vif->set_underlying_vif_up(is_up);
01240     vif->set_mtu(mtu);
01241     
01242     return (XORP_OK);
01243 }
01244 
01245 template<class V>
01246 inline const Vif *
01247 ProtoNode<V>::configured_vif_find_by_name(const string& name) const
01248 {
01249     map<string, Vif>::const_iterator iter;
01250 
01251     iter = _configured_vifs.find(name);
01252     if (iter != _configured_vifs.end())
01253     return (&iter->second);
01254 
01255     return (NULL);
01256 }
01257 
01258 //
01259 // Global variables
01260 //
01261 
01262 //
01263 // Global functions prototypes
01264 //
01265 
01266 #endif // __LIBPROTO_PROTO_NODE_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations