xorp

io_link_manager.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 // vim:set sts=4 ts=8:
00003 
00004 // Copyright (c) 2007-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 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 // $XORP: xorp/fea/io_link_manager.hh,v 1.14 2008/10/10 01:23:53 pavlin Exp $
00022 
00023 #ifndef __FEA_IO_LINK_MANAGER_HH__
00024 #define __FEA_IO_LINK_MANAGER_HH__
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 #include "libxorp/callback.hh"
00033 #include "libxorp/mac.hh"
00034 
00035 #include "fea_io.hh"
00036 #include "io_link.hh"
00037 
00038 class FeaDataPlaneManager;
00039 class FeaNode;
00040 class IoLinkManager;
00041 
00042 
00046 struct MacHeaderInfo {
00047     string  if_name;
00048     string  vif_name;
00049     Mac     src_address;
00050     Mac     dst_address;
00051     uint16_t    ether_type;
00052 };
00053 
00060 class IoLinkComm :
00061     public NONCOPYABLE,
00062     public IoLinkReceiver
00063 {
00064 public:
00068     class InputFilter {
00069     public:
00070     InputFilter(IoLinkManager&  io_link_manager,
00071             const string&   receiver_name,
00072             const string&   if_name,
00073             const string&   vif_name,
00074             uint16_t        ether_type,
00075             const string&   filter_program)
00076         : _io_link_manager(io_link_manager),
00077           _receiver_name(receiver_name),
00078           _if_name(if_name),
00079           _vif_name(vif_name),
00080           _ether_type(ether_type),
00081           _filter_program(filter_program)
00082     {}
00083     virtual ~InputFilter() {}
00084 
00090     IoLinkManager& io_link_manager() { return (_io_link_manager); }
00091 
00097     const IoLinkManager& io_link_manager() const { return (_io_link_manager); }
00098 
00104     const string& receiver_name() const { return (_receiver_name); }
00105 
00111     const string& if_name() const { return (_if_name); }
00112 
00118     const string& vif_name() const { return (_vif_name); }
00119 
00125     uint16_t ether_type() const { return (_ether_type); }
00126 
00132     const string& filter_program() const { return (_filter_program); }
00133 
00137     virtual void recv(const struct MacHeaderInfo& header,
00138               const vector<uint8_t>& payload) = 0;
00139 
00147     virtual void bye() = 0;
00148 
00149     private:
00150     IoLinkManager&  _io_link_manager;
00151     string      _receiver_name;
00152     string      _if_name;
00153     string      _vif_name;
00154     uint16_t    _ether_type;
00155     string      _filter_program;
00156     };
00157 
00161     class JoinedMulticastGroup {
00162     public:
00163     JoinedMulticastGroup(const Mac& group_address)
00164         : _group_address(group_address)
00165     {}
00166 #ifdef XORP_USE_USTL
00167     JoinedMulticastGroup() { }
00168 #endif
00169     virtual ~JoinedMulticastGroup() {}
00170 
00171     const Mac& group_address() const { return _group_address; }
00172 
00180     bool operator<(const JoinedMulticastGroup& other) const {
00181         return (_group_address < other._group_address);
00182     }
00183 
00191     bool operator==(const JoinedMulticastGroup& other) const {
00192         return (_group_address == other._group_address);
00193     }
00194 
00200     void add_receiver(const string& receiver_name) {
00201         _receivers.insert(receiver_name);
00202     }
00203 
00209     void delete_receiver(const string& receiver_name) {
00210         _receivers.erase(receiver_name);
00211     }
00212 
00216     bool empty() const { return _receivers.empty(); }
00217 
00218     set<string>& get_receivers() { return _receivers; }
00219 
00220     private:
00221     Mac     _group_address;
00222     set<string> _receivers;
00223     };
00224 
00225 public:
00238     IoLinkComm(IoLinkManager& io_link_manager, const IfTree& iftree,
00239            const string& if_name, const string& vif_name,
00240            uint16_t ether_type, const string& filter_program);
00241 
00245     virtual ~IoLinkComm();
00246 
00250     void allocate_io_link_plugins();
00251 
00255     void deallocate_io_link_plugins();
00256 
00262     void allocate_io_link_plugin(FeaDataPlaneManager* fea_data_plane_manager);
00263 
00269     void deallocate_io_link_plugin(FeaDataPlaneManager* fea_data_plane_manager);
00270 
00274     void start_io_link_plugins();
00275 
00279     void stop_io_link_plugins();
00280 
00291     int add_filter(InputFilter* filter);
00292 
00299     int remove_filter(InputFilter* filter);
00300 
00304     bool no_input_filters() const { return _input_filters.empty(); }
00305 
00316     int     send_packet(const Mac&      src_address,
00317                 const Mac&      dst_address,
00318                 uint16_t        ether_type,
00319                 const vector<uint8_t>& payload,
00320                 string&     error_msg);
00321 
00330     virtual void recv_packet(const Mac&     src_address,
00331                  const Mac&     dst_address,
00332                  uint16_t       ether_type,
00333                  const vector<uint8_t>& payload);
00334 
00343     int     join_multicast_group(const Mac&     group_address,
00344                      const string&  receiver_name,
00345                      string&        error_msg);
00346 
00355     int     leave_multicast_group(const Mac&    group_address,
00356                       const string& receiver_name,
00357                       string&       error_msg);
00358     
00364     const string& if_name() const { return (_if_name); }
00365 
00371     const string& vif_name() const { return (_vif_name); }
00372 
00378     uint16_t ether_type() const { return (_ether_type); }
00379 
00385     const string& filter_program() const { return (_filter_program); }
00386 
00387 private:
00388     IoLinkComm(const IoLinkComm&);      // Not implemented.
00389     IoLinkComm& operator=(const IoLinkComm&);   // Not implemented.
00390 
00391     IoLinkManager&      _io_link_manager;
00392     const IfTree&       _iftree;
00393     const string        _if_name;
00394     const string        _vif_name;
00395     const uint16_t      _ether_type;
00396     const string        _filter_program;
00397 
00398     typedef list<pair<FeaDataPlaneManager*, IoLink*> >IoLinkPlugins;
00399     IoLinkPlugins       _io_link_plugins;
00400 
00401     list<InputFilter*>      _input_filters;
00402     typedef map<JoinedMulticastGroup, JoinedMulticastGroup> JoinedGroupsTable;
00403     JoinedGroupsTable       _joined_groups_table;
00404 };
00405 
00410 class IoLinkManagerReceiver {
00411 public:
00415     virtual ~IoLinkManagerReceiver() {}
00416 
00425     virtual void recv_event(const string&       receiver_name,
00426                 const struct MacHeaderInfo& header,
00427                 const vector<uint8_t>&  payload) = 0;
00428 };
00429 
00440 class IoLinkManager : public IoLinkManagerReceiver,
00441               public InstanceWatcher {
00442 public:
00443     typedef XorpCallback2<int, const uint8_t*, size_t>::RefPtr UpcallReceiverCb;
00444 
00448     IoLinkManager(FeaNode& fea_node, const IfTree& iftree);
00449 
00453     virtual ~IoLinkManager();
00454 
00469     int send(const string&  if_name,
00470          const string&  vif_name,
00471          const Mac&     src_address,
00472          const Mac&     dst_address,
00473          uint16_t       ether_type,
00474          const vector<uint8_t>& payload,
00475          string&        error_msg);
00476 
00496     int register_receiver(const string& receiver_name,
00497               const string& if_name,
00498               const string& vif_name,
00499               uint16_t  ether_type,
00500               const string& filter_program,
00501               bool      enable_multicast_loopback,
00502               string&   error_msg);
00503 
00521     int unregister_receiver(const string&   receiver_name,
00522                 const string&   if_name,
00523                 const string&   vif_name,
00524                 uint16_t        ether_type,
00525                 const string&   filter_program,
00526                 string&     error_msg);
00527 
00545     int join_multicast_group(const string&  receiver_name,
00546                  const string&  if_name,
00547                  const string&  vif_name,
00548                  uint16_t       ether_type,
00549                  const string&  filter_program,
00550                  const Mac&     group_address,
00551                  string&        error_msg);
00552 
00571     int leave_multicast_group(const string& receiver_name,
00572                   const string& if_name,
00573                   const string& vif_name,
00574                   uint16_t      ether_type,
00575                   const string& filter_program,
00576                   const Mac&    group_address,
00577                   string&       error_msg);
00578 
00587     void recv_event(const string&       receiver_name,
00588             const struct MacHeaderInfo& header,
00589             const vector<uint8_t>&  payload);
00590 
00596     void instance_birth(const string& instance_name);
00597 
00603     void instance_death(const string& instance_name);
00604 
00609     void set_io_link_manager_receiver(IoLinkManagerReceiver* v) {
00610     _io_link_manager_receiver = v;
00611     }
00612 
00618     const IfTree&   iftree() const { return _iftree; }
00619 
00628     int register_data_plane_manager(FeaDataPlaneManager* fea_data_plane_manager,
00629                     bool is_exclusive);
00630 
00637     int unregister_data_plane_manager(FeaDataPlaneManager* fea_data_plane_manager);
00638 
00644     list<FeaDataPlaneManager*>& fea_data_plane_managers() {
00645     return _fea_data_plane_managers;
00646     }
00647 
00656     int add_multicast_mac(const string& if_name, const Mac& mac,
00657               string& error_msg);
00658 
00667     int remove_multicast_mac(const string& if_name, const Mac& mac,
00668                  string& error_msg);
00669 
00670 private:
00671     class CommTableKey {
00672     public:
00673     CommTableKey(const string& if_name, const string& vif_name,
00674              uint16_t ether_type, const string& filter_program)
00675         : _if_name(if_name),
00676           _vif_name(vif_name),
00677           _ether_type(ether_type),
00678           _filter_program(filter_program)
00679     {}
00680 #ifdef XORP_USE_USTL
00681     CommTableKey() { }
00682 #endif
00683     bool operator<(const CommTableKey& other) const {
00684         if (_ether_type != other._ether_type)
00685         return (_ether_type < other._ether_type);
00686         if (_if_name != other._if_name)
00687         return (_if_name < other._if_name);
00688         if (_vif_name != other._vif_name)
00689         return (_vif_name < other._vif_name);
00690         return (_filter_program < other._filter_program);
00691     }
00692 
00693     private:
00694     string      _if_name;
00695     string      _vif_name;
00696     uint16_t    _ether_type;
00697     string      _filter_program;
00698     };
00699 
00700     typedef map<CommTableKey, IoLinkComm*> CommTable;
00701     typedef multimap<string, IoLinkComm::InputFilter*> FilterBag;
00702 
00708     void erase_filters_by_receiver_name(const string& receiver_name);
00709 
00717     bool has_filter_by_receiver_name(const string& receiver_name) const;
00718 
00729     void erase_filters(CommTable& comm_table, FilterBag& filters,
00730                const FilterBag::iterator& begin,
00731                const FilterBag::iterator& end);
00732 
00742     IoLinkComm& add_iolink_comm_txonly(const string& if_name,
00743                        const string& vif_name,
00744                        uint16_t ether_type);
00745 
00758     IoLinkComm& find_iolink_comm(const string& if_name, const string& vif_name,
00759                  uint16_t ether_type);
00760 
00770     int add_remove_multicast_mac(bool add, const string& if_name,
00771                  const Mac& mac, string& error_msg);
00772 
00773     FeaNode&        _fea_node;
00774     EventLoop&      _eventloop;
00775     const IfTree&   _iftree;
00776 
00777     // Collection of raw link-level communication handlers keyed by protocol.
00778     CommTable       _comm_table;
00779 
00780     // Collection of input filters created by IoLinkManager
00781     FilterBag       _filters;
00782 
00783     IoLinkManagerReceiver* _io_link_manager_receiver;
00784 
00785     list<FeaDataPlaneManager*> _fea_data_plane_managers;
00786 };
00787 
00788 #endif // __FEA_IO_LINK_MANAGER_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations