xorp

pim_proto_join_prune_message.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 
00003 // Copyright (c) 2001-2011 XORP, Inc and Others
00004 //
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License, Version 2, June
00007 // 1991 as published by the Free Software Foundation. Redistribution
00008 // and/or modification of this program under the terms of any other
00009 // version of the GNU General Public License is not permitted.
00010 // 
00011 // This program is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00014 // see the GNU General Public License, Version 2, a copy of which can be
00015 // found in the XORP LICENSE.gpl file.
00016 // 
00017 // XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00018 // http://xorp.net
00019 
00020 
00021 
00022 #ifndef __PIM_PIM_PROTO_JOIN_PRUNE_MESSAGE_HH__
00023 #define __PIM_PIM_PROTO_JOIN_PRUNE_MESSAGE_HH__
00024 
00025 
00026 //
00027 // PIM Join/Prune message creation implementation-specific definitions.
00028 //
00029 
00030 
00031 
00032 #include "mrt/buffer.h"
00033 #include "mrt/multicast_defs.h"
00034 #include "pim_proto.h"
00035 #include "pim_mre.hh"
00036 
00037 
00038 //
00039 // Constants definitions
00040 //
00041 
00042 //
00043 // When we compute the Join/Prune message size whether it fits within
00044 // a buffer, we need to take into account the expected max. number of
00045 // multicast sources. Here we define this number.
00046 // TODO: get rid of this predefined number
00047 //
00048 #define PIM_JP_EXTRA_SOURCES_N      32
00049 
00050 
00051 //
00052 // Structures/classes, typedefs and macros
00053 //
00054 // The type of entries: (*,*,RP), (*,G), (S,G), (S,G,rpt)
00055 enum mrt_entry_type_t {
00056     MRT_ENTRY_UNKNOWN = 0,
00057     MRT_ENTRY_RP = PIM_MRE_RP,
00058     MRT_ENTRY_WC = PIM_MRE_WC,
00059     MRT_ENTRY_SG = PIM_MRE_SG,
00060     MRT_ENTRY_SG_RPT = PIM_MRE_SG_RPT
00061 };
00062 
00063 //
00064 // Various structures to handle the assembly of source-group entries
00065 // that are pending to be (re)send to a neighbor in a Join/Prune (or a Graft)
00066 // message.
00067 // XXX: the various numbers fields in a PIM Join/Prune message are no
00068 // larger than 16 bits. The purpose of the structures below
00069 // is to collect all necessary information about the pending source-group
00070 // entries instead of completely spliting them according to the protocol
00071 // messages they are going to be included into. Thus, the final job of
00072 // assigning which entries go into which J/P protocol message can be
00073 // performed by an independent block which may take care of controlling
00074 // the overall control bandwidth for example.
00075 //
00076 
00077 //
00078 // Class to keep list of the source-group entries that are pending
00079 // to be (re)send to a neighbor in a Join-Prune (or Graft) message.
00080 //
00081 
00082 class IPvX;
00083 class PimJpGroup;
00084 class PimMrt;
00085 class PimNbr;
00086 class PimNode;
00087 
00088 class PimJpHeader {
00089 public:
00090     PimJpHeader(PimNode* pim_node);
00091 #ifdef XORP_USE_USTL
00092     PimJpHeader();
00093 #endif
00094     ~PimJpHeader();
00095     void    reset();
00096     
00097     PimNode*    pim_node() const    { return _pim_node; }
00098     int     family() const      { return (_family); }
00099     PimMrt& pim_mrt() const;
00100     
00101     size_t message_size() const {
00102         return ( sizeof(struct pim) + ENCODED_UNICAST_ADDR_SIZE(_family)
00103              + 2 * sizeof(uint8_t) + sizeof(uint16_t)
00104              + _jp_groups_n * (ENCODED_GROUP_ADDR_SIZE(_family)
00105                        + 2 * sizeof(uint16_t))
00106              + _jp_sources_n * (ENCODED_SOURCE_ADDR_SIZE(_family)));
00107     }
00108     size_t extra_source_size() const {
00109     return (ENCODED_SOURCE_ADDR_SIZE(_family));
00110     }
00111     
00112     int     jp_entry_add(const IPvX& source_addr, const IPvX& group_addr,
00113                  uint8_t group_mask_len,
00114                  mrt_entry_type_t mrt_entry_type,
00115                  action_jp_t action_jp, uint16_t holdtime,
00116                  bool is_new_group);
00117     int     mrt_commit(PimVif *pim_vif, const IPvX& target_nbr_addr);
00118     int     network_commit(PimVif *pim_vif, const IPvX& target_nbr_addr,
00119                    string& error_msg);
00120     int     network_send(PimVif *pim_vif, const IPvX& target_nbr_addr,
00121                  string& error_msg);
00122     
00123     uint32_t    jp_groups_n() const     { return (_jp_groups_n);  }
00124     uint32_t    jp_sources_n() const        { return (_jp_sources_n); }
00125     void    set_jp_groups_n(uint32_t v) { _jp_groups_n = v; }
00126     void    incr_jp_groups_n()      { _jp_groups_n++;   }
00127     void    decr_jp_groups_n()      { _jp_groups_n--;   }
00128     void    set_jp_sources_n(uint32_t v)    { _jp_sources_n = v;    }
00129     void    incr_jp_sources_n()     { _jp_sources_n++;  }
00130     void    decr_jp_sources_n()     { _jp_sources_n--;  }
00131     
00132 private:
00133     PimNode*    _pim_node;      // The PIM node
00134     int     _family;        // The address family
00135     list<PimJpGroup *> _jp_groups_list;// The list of groups
00136     uint32_t    _jp_groups_n;       // Total number of groups
00137     uint32_t    _jp_sources_n;      // Total number of sources (all groups)
00138     uint16_t    _holdtime;      // The Holdtime in the J/P message
00139 };
00140 
00141 //
00142 // Class to keep info about the list of sources entries to Join/Prune
00143 //
00144 class PimJpSources {
00145 public:
00146     PimJpSources() : _j_n(0), _p_n(0) {}
00147     ~PimJpSources() {}
00148     
00149     list<IPvX>& j_list()        { return (_j_list);     }
00150     list<IPvX>& p_list()        { return (_p_list);     }
00151     bool    j_list_found(const IPvX& ipaddr);
00152     bool    p_list_found(const IPvX& ipaddr);
00153     bool    j_list_remove(const IPvX& ipaddr);
00154     bool    p_list_remove(const IPvX& ipaddr);
00155     uint32_t    j_n()   const       { return (_j_n);        }
00156     void    set_j_n(uint32_t v) { _j_n = v;         }
00157     void    incr_j_n()      { _j_n++;           }
00158     void    decr_j_n()      { _j_n--;           }
00159     uint32_t    p_n()   const       { return (_p_n);        }
00160     void    set_p_n(uint32_t v) { _p_n = v;         }
00161     void    incr_p_n()      { _p_n++;           }
00162     void    decr_p_n()      { _p_n--;           }
00163     
00164 private:
00165     list<IPvX>  _j_list;        // List of Join entries
00166     list<IPvX>  _p_list;        // List of Prune entries
00167     uint32_t    _j_n;           // Number of Join entries
00168     uint32_t    _p_n;           // Number of Prune entries
00169 };
00170 
00171 //
00172 // Class to keep info about a group entry that is pending to be
00173 // (re)send to a neighbor in a Join-Prune (or Graft) message,
00174 // or to be commited to the Multicast Routing Table.
00175 //
00176 class PimJpGroup {
00177 public:
00178     PimJpGroup(PimJpHeader& jp_header, int family);
00179     int     family()    const   { return (_family);     }
00180     PimJpHeader& jp_header()        { return (_jp_header);      }
00181     const IPvX& group_addr()    const   { return (_group_addr);     }
00182     void    set_group_addr(const IPvX& v) { _group_addr = v;    }
00183     uint8_t group_mask_len() const  { return (_group_mask_len); }
00184     void    set_group_mask_len(uint8_t v) { _group_mask_len = v;    }
00185     void    incr_jp_groups_n()  { jp_header().incr_jp_groups_n();  }
00186     void    decr_jp_groups_n()  { jp_header().decr_jp_groups_n();  }
00187     uint32_t    j_sources_n()   const   { return (_j_sources_n);    }
00188     uint32_t    p_sources_n()   const   { return (_p_sources_n);    }
00189     void    set_j_sources_n(uint32_t v) { _j_sources_n = v; }
00190     void    set_p_sources_n(uint32_t v) { _p_sources_n = v; }
00191     void    incr_j_sources_n()  { _j_sources_n++; jp_header().incr_jp_sources_n(); }
00192     void    decr_j_sources_n()  { _j_sources_n--; jp_header().decr_jp_sources_n(); }
00193     void    incr_p_sources_n()  { _p_sources_n++; jp_header().incr_jp_sources_n(); }
00194     void    decr_p_sources_n()  { _p_sources_n--; jp_header().decr_jp_sources_n(); }
00195     PimJpSources *rp()          { return (&_rp);        }
00196     PimJpSources *wc()          { return (&_wc);        }
00197     PimJpSources *sg()          { return (&_sg);        }
00198     PimJpSources *sg_rpt()      { return (&_sg_rpt);        }
00199     
00200     size_t message_size() const {
00201     return ( ENCODED_GROUP_ADDR_SIZE(_family)
00202          + 2 * sizeof(uint16_t)
00203          + (ENCODED_SOURCE_ADDR_SIZE(_family)
00204             * (_rp.j_n() + _rp.p_n()
00205                + _wc.j_n() + _wc.p_n()
00206                + _sg.j_n() + _sg.p_n()
00207                + _sg_rpt.j_n() + _sg_rpt.p_n())));
00208     }
00209     
00210 private:
00211     PimJpHeader& _jp_header;        // The J/P header for the groups
00212                     //   to (re)send
00213     int     _family;        // The address family
00214     IPvX    _group_addr;        // The address of the multicast group
00215     uint8_t _group_mask_len;    // The 'group_addr' mask length
00216     uint32_t    _j_sources_n;       // The total number of Joined sources
00217     uint32_t    _p_sources_n;       // The total number of Pruned sources
00218     // The lists for each type of entry: (*,*,RP), (*,G), (S,G), (S,G,rpt)
00219     PimJpSources _rp;           // The (*,*,RP)  Join/Prune entries
00220     PimJpSources _wc;           // The (*,G)     Join/Prune entries
00221     PimJpSources _sg;           // The (S,G)     Join/Prune entries
00222     PimJpSources _sg_rpt;       // The (S,G,rpt) Join/Prune entries
00223 };
00224 
00225 //
00226 // Global variables
00227 //
00228 
00229 //
00230 // Global functions prototypes
00231 //
00232 
00233 #endif // __PIM_PIM_PROTO_JOIN_PRUNE_MESSAGE_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations