xorp

pim_mre.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 
00003 // Copyright (c) 2001-2011 XORP, Inc and Others-2009 XORP, Inc.
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 #ifndef __PIM_PIM_MRE_HH__
00022 #define __PIM_PIM_MRE_HH__
00023 
00024 
00025 //
00026 // PIM Multicast Routing Entry definitions.
00027 //
00028 
00029 
00030 #include "libxorp/timer.hh"
00031 #include "mrt/mifset.hh"
00032 #include "mrt/mrt.hh"
00033 #include "pim_mrib_table.hh"
00034 #include "pim_proto_assert.hh"
00035 
00036 
00037 class AssertMetric;
00038 class PimMre;
00039 class PimMrt;
00040 class PimNbr;
00041 class PimRp;
00042 class PimVif;
00043 
00044 
00045 // PimMre _flags
00046 // TODO: move it inside PimMre class??
00047 enum {
00048     // Multicast Routing Entry type
00049     PIM_MRE_SG          = 1 << 0,   // (S,G) entry
00050     PIM_MRE_SG_RPT      = 1 << 1,   // (S,G,rpt) entry
00051     PIM_MRE_WC          = 1 << 2,   // (*,G) entry
00052     PIM_MRE_RP          = 1 << 3,   // (*,*,RP) entry
00053     // 
00054     PIM_MRE_SPT         = 1 << 4,   // (S,G) entry switched to SPT
00055     PIM_MFC         = 1 << 5,   // Multicast Forwarding Cache
00056                         // entry: enumerated here for
00057                         // consistency.
00058     // State machine
00059     PIM_MRE_JOINED_STATE    = 1 << 8,   // The state is Joined:
00060                         //   (*,*,RP) (*,G) (S,G)
00061     PIM_MRE_PRUNED_STATE    = 1 << 9,   // The state is Pruned:
00062                         //   (S,G,rpt)
00063     PIM_MRE_NOT_PRUNED_STATE    = 1 << 10,  // The state is NotPruned:
00064                         //   (S,G,rpt)
00065     PIM_MRE_REGISTER_JOIN_STATE = 1 << 11,  // The Register tunnel for
00066                         // (S,G) is in Join state
00067     PIM_MRE_REGISTER_PRUNE_STATE = 1 << 12, // The Register tunnel for
00068                         // (S,G) is in Prune state
00069     PIM_MRE_REGISTER_JOIN_PENDING_STATE = 1 << 13, // The Register tunnel for
00070                            // (S,G) is in Join-Pending
00071                            // state
00072     PIM_MRE_COULD_REGISTER_SG   = 1 << 14,   // The macro "CouldRegister(S,G)"
00073                          // is true
00074     // Misc.
00075     PIM_MRE_GRAFTED     = 1 << 16,   // For PIM-DM
00076     PIM_MRE_DIRECTLY_CONNECTED_S = 1 << 18,  // Directly-connected S
00077     PIM_MRE_I_AM_RP      = 1 << 19,  // I am the RP for the group
00078     PIM_MRE_KEEPALIVE_TIMER_IS_SET = 1 << 20,// The (S,G) Keepalive Timer is
00079                          // running
00080     PIM_MRE_TASK_DELETE_PENDING = 1 << 21,   // Entry is pending deletion
00081     PIM_MRE_TASK_DELETE_DONE    = 1 << 22,   // Entry is ready to be deleted
00082     PIM_MRE_SWITCH_TO_SPT_DESIRED = 1 << 23, // SwitchToSptDesired(S,G) is true
00083     PIM_MRE_IS_KAT_SET_TO_RP_KEEPALIVE_PERIOD = 1 << 24 // At the RP, when
00084                                 // Register-Stop is sent
00085 };
00086 
00087 
00088 // PIM-specific Multicast Routing Entry
00089 // XXX: the source_addr() for (*,*,RP) entry contains the RP address
00090 class PimMre : public Mre<PimMre>, BugCatcher, NONCOPYABLE  {
00091 public:
00092     PimMre(PimMrt* pim_mrt, const IPvX& source, const IPvX& group);
00093     virtual ~PimMre();
00094     
00095     void    add_pim_mre_lists();
00096     void    remove_pim_mre_lists();
00097     
00098     // General info: PimNode, PimMrt, family, etc.
00099     PimNode*    pim_node() const;
00100     PimMrt* pim_mrt()   const   { return _pim_mrt; }
00101     int     family()    const;
00102     uint32_t    pim_register_vif_index() const;
00103     
00104     //
00105     // Type of PimMre entry and related info
00106     //
00107     // The four entry types: (S,G), (S,G,rpt), (*,G), (*,*,RP)
00108     bool    is_sg()     const { return (_flags & PIM_MRE_SG);   }
00109     bool    is_sg_rpt() const { return (_flags & PIM_MRE_SG_RPT); }
00110     bool    is_wc()     const { return (_flags & PIM_MRE_WC);   }
00111     bool    is_rp()     const { return (_flags & PIM_MRE_RP);   }
00112     // Entry characteristics
00113     // Note: applies only for (S,G)
00114     bool    is_spt()    const { return (_flags & PIM_MRE_SPT);  }
00115     void    set_sg(bool v);
00116     void    set_sg_rpt(bool v);
00117     void    set_wc(bool v);
00118     void    set_rp(bool v);
00119     // Note: applies only for (S,G)
00120     void    set_spt(bool v);
00121     
00122     const IPvX* rp_addr_ptr() const;    // The RP address
00123     string  rp_addr_string() const; // C++ string with the RP address
00124                     // or "RP_ADDR_UNKNOWN"
00125     
00126     //
00127     // The RP entry
00128     //
00129     PimRp   *pim_rp()   const   { return (_pim_rp);     }
00130     void    set_pim_rp(PimRp *v);   // Used by (*,G) (S,G) (S,G,rpt)
00131     void    uncond_set_pim_rp(PimRp *v); // Used by (*,G) (S,G) (S,G,rpt)
00132     PimRp   *compute_rp() const;    // Used by (*,G) (S,G) (S,G,rpt)
00133     void    recompute_rp_wc();  // Used by (*,G)
00134     void    recompute_rp_sg();  // Used by (S,G)
00135     void    recompute_rp_sg_rpt();  // Used by (S,G,rpt)
00136     //
00137     
00138     //
00139     // MRIB info
00140     //
00141     // Note: mrib_s(), rpf_interface_s() and related *_s() methods
00142     // are used only by (S,G) and (S,G,rpt) entry.
00143     // Note: mrib_rp(), rpf_interface_rp(), set_mrib_rp() apply for all entries
00144     Mrib    *mrib_rp()  const   { return (_mrib_rp);        }
00145     Mrib    *mrib_s()   const   { return (_mrib_s);     }
00146     uint32_t    rpf_interface_rp() const;
00147     uint32_t    rpf_interface_s() const;
00148     void    set_mrib_rp(Mrib *v)    { _mrib_rp = v;         }
00149     void    set_mrib_s(Mrib *v) { _mrib_s = v;          }
00150     Mrib    *compute_mrib_rp() const;
00151     Mrib    *compute_mrib_s() const;
00152     void    recompute_mrib_rp_rp();     // Used by (*,*,RP)
00153     void    recompute_mrib_rp_wc();     // Used by (*,G)
00154     void    recompute_mrib_rp_sg();     // Used by (S,G)
00155     void    recompute_mrib_rp_sg_rpt(); // Used by (S,G,rpt)
00156     void    recompute_mrib_s_sg();      // Used by (S,G)
00157     void    recompute_mrib_s_sg_rpt();  // Used by (S,G,rpt)
00158     //
00159     
00160     //
00161     // RPF and RPF' neighbor info
00162     //
00163     // Note: applies only for (*,*,RP) and (*,G), but works also for (S,G)
00164     // and (S,G,rpt)
00165     PimNbr  *nbr_mrib_next_hop_rp() const;
00166     // Note: applies only for (S,G)
00167     PimNbr  *nbr_mrib_next_hop_s() const { return (_nbr_mrib_next_hop_s); }
00168     // Note: applies only for (*,G) ans (S,G,rpt) but works also for (S,G)
00169     PimNbr  *rpfp_nbr_wc()  const;
00170     // Note: applies only for (S,G)
00171     PimNbr  *rpfp_nbr_sg()  const   { return (_rpfp_nbr_sg);    }
00172     // Note: applies only for (S,G,rpt)
00173     PimNbr  *rpfp_nbr_sg_rpt() const { return (_rpfp_nbr_sg_rpt);   }
00174     // Note: applies for all entries
00175     bool    is_pim_nbr_in_use(const PimNbr *pim_nbr) const;
00176     // Note: applies for all entries
00177     bool    is_pim_nbr_missing() const;
00178     // Note: applies only for (*,*,RP) and (*,G)
00179     void    set_nbr_mrib_next_hop_rp(PimNbr *v);
00180     // Note: applies only for (S,G)
00181     void    set_nbr_mrib_next_hop_s(PimNbr *v);
00182     // Note: applies only for (*,G)
00183     void    set_rpfp_nbr_wc(PimNbr *v);
00184     // Note: applies only for (S,G)
00185     void    set_rpfp_nbr_sg(PimNbr *v);
00186     // Note: applies only for (S,G,rpt)
00187     void    set_rpfp_nbr_sg_rpt(PimNbr *v);
00188     // Note: applies only for (*,*,RP), (*,G), (S,G,rpt), but works also
00189     // for (S,G).
00190     PimNbr  *compute_nbr_mrib_next_hop_rp() const;
00191     // Note: applies only for (S,G)
00192     PimNbr  *compute_nbr_mrib_next_hop_s() const;
00193     // Note: applies only for (*,G)
00194     PimNbr  *compute_rpfp_nbr_wc() const;
00195     // Note: applies only for (S,G)
00196     PimNbr  *compute_rpfp_nbr_sg() const;
00197     // Note: applies only for (S,G,rpt)
00198     PimNbr  *compute_rpfp_nbr_sg_rpt() const;
00199     // (*,*,RP)-related upstream changes
00200     void    recompute_nbr_mrib_next_hop_rp_rp_changed();
00201     void    recompute_nbr_mrib_next_hop_rp_gen_id_changed();
00202     // (*,G)-related upstream changes
00203     void    recompute_nbr_mrib_next_hop_rp_wc_changed();
00204     void    recompute_rpfp_nbr_wc_assert_changed();
00205     void    recompute_rpfp_nbr_wc_not_assert_changed();
00206     void    recompute_rpfp_nbr_wc_gen_id_changed();
00207     // (S,G)-related upstream changes
00208     void    recompute_nbr_mrib_next_hop_s_changed();
00209     void    recompute_rpfp_nbr_sg_assert_changed();
00210     void    recompute_rpfp_nbr_sg_not_assert_changed();
00211     void    recompute_rpfp_nbr_sg_gen_id_changed();
00212     // (S,G,rpt)-related upstream changes
00213     void    recompute_rpfp_nbr_sg_rpt_changed();
00214     // (S,G,rpt)-related upstream changes (recomputed via (S,G) to (S,G,rpt))
00215     void    recompute_rpfp_nbr_sg_rpt_sg_changed();
00216     // Misc. other RPF-related info
00217     // Note: applies for (S,G) and (S,G,rpt)
00218     bool    compute_is_directly_connected_s();
00219     // Note: applies for (S,G)
00220     void    recompute_is_directly_connected_sg();
00221     
00222     //
00223     // Related entries: (*,G), (*,*,RP) (may be NULL).
00224     //
00225     PimMre  *wc_entry() const   { return (_wc_entry);       }
00226     PimMre  *rp_entry() const   {
00227     if (_rp_entry != NULL)
00228         return (_rp_entry);
00229     if (wc_entry() != NULL)
00230         return (wc_entry()->rp_entry());    // XXX: get it through (*,G)
00231     return (NULL);
00232     }
00233     PimMre  *sg_entry() const {
00234     if (is_sg_rpt())
00235         return (_sg_sg_rpt_entry);
00236     return (NULL);
00237     }
00238     PimMre  *sg_rpt_entry() const {
00239     if (is_sg())
00240         return (_sg_sg_rpt_entry);
00241     return (NULL);
00242     }
00243     void    set_wc_entry(PimMre *v) { _wc_entry = v;        }
00244     void    set_rp_entry(PimMre *v) { _rp_entry = v;        }
00245     void    set_sg_entry(PimMre *v) { _sg_sg_rpt_entry = v;     }
00246     void    set_sg_rpt_entry(PimMre *v) { _sg_sg_rpt_entry = v; }
00247     
00248     //
00249     // ASSERT-related route metric and metric preference
00250     //
00251     // Note: applies only for (S,G) and (S,G,rpt)
00252     uint32_t    metric_preference_s() const;
00253     // Note: applies for all entries
00254     uint32_t    metric_preference_rp() const;
00255     // Note: applies only for (S,G) and (S,G,rpt)
00256     uint32_t    metric_s() const;
00257     // Note: applies for all entries
00258     uint32_t    metric_rp() const;
00259     
00260     //
00261     // Local receivers info
00262     //
00263     // Note: applies only for (*,G), (S,G) and (S,G,rpt)
00264     const Mifset& local_receiver_include_wc() const;
00265     // Note: applies only for (S,G)
00266     const Mifset& local_receiver_include_sg() const;
00267     // Note: applies only for (S,G)
00268     const Mifset& local_receiver_exclude_sg() const;
00269     // Note: applies only for (*,G) and (S,G); has only internal PimMre meaning
00270     const Mifset& local_receiver_include() const {
00271     return (_local_receiver_include);
00272     }
00273     const Mifset& local_receiver_exclude() const {
00274     return (_local_receiver_exclude);
00275     }
00276     void    set_local_receiver_include(uint32_t vif_index, bool v);
00277     void    set_local_receiver_exclude(uint32_t vif_index, bool t);
00278 
00279     //
00280     // JOIN/PRUNE info
00281     //
00282     // Note: applies only for (*,*,RP), (*,G), (S,G)
00283     XorpTimer&  join_timer() { return (_join_or_override_timer); }
00284     // Note: applies only for (*,*,RP), (*,G), (S,G)
00285     const XorpTimer& const_join_timer() const {
00286     return (_join_or_override_timer);
00287     }
00288     void    join_timer_timeout();
00289     // Note: applies only for (S,G,rpt)
00290     XorpTimer&  override_timer() { return (_join_or_override_timer); }
00291     // Note: applies only for (S,G,rpt)
00292     const XorpTimer& const_override_timer() const {
00293     return (_join_or_override_timer);
00294     }
00295     void    override_timer_timeout();
00296 
00297     // Note: applies only for (*,*,RP)
00298     void    receive_join_rp(uint32_t vif_index, uint16_t holdtime);
00299     // Note: applies only for (*,*,RP)
00300     void    receive_prune_rp(uint32_t vif_index, uint16_t holdtime);
00301     // Note: applies only for (*,G)
00302     void    receive_join_wc(uint32_t vif_index, uint16_t holdtime);
00303     // Note: applies only for (*,G)
00304     void    receive_prune_wc(uint32_t vif_index, uint16_t holdtime);
00305     // Note: applies only for (S,G)
00306     void    receive_join_sg(uint32_t vif_index, uint16_t holdtime);
00307     // Note: applies only for (S,G)
00308     void    receive_prune_sg(uint32_t vif_index, uint16_t holdtime);
00309     // Note: applies only for (S,G,rpt)
00310     void    receive_join_wc_by_sg_rpt(uint32_t vif_index);
00311     // Note: applies only for (S,G,rpt)
00312     void    receive_join_sg_rpt(uint32_t vif_index, uint16_t holdtime);
00313     // Note: applies only for (S,G,rpt)
00314     void    receive_prune_sg_rpt(uint32_t vif_index, uint16_t holdtime,
00315                      bool is_join_wc_received);
00316     // Note: applies only for (S,G,rpt)
00317     void    receive_end_of_message_sg_rpt(uint32_t vif_index);
00318     // Note: applies only for (*,*,RP)
00319     void    rp_see_join_rp(uint32_t vif_index, uint16_t holdtime,
00320                    const IPvX& target_nbr_addr);
00321     // Note: applies only for (*,*,RP)
00322     void    rp_see_prune_rp(uint32_t vif_index, uint16_t holdtime,
00323                 const IPvX& target_nbr_addr);
00324     // Note: applies only for (*,G)
00325     void    wc_see_join_wc(uint32_t vif_index, uint16_t holdtime,
00326                    const IPvX& target_nbr_addr);
00327     // Note: applies only for (*,G)
00328     void    wc_see_prune_wc(uint32_t vif_index, uint16_t holdtime,
00329                 const IPvX& target_nbr_addr);
00330     // Note: applies only for (S,G)
00331     void    sg_see_join_sg(uint32_t vif_index, uint16_t holdtime,
00332                    const IPvX& target_nbr_addr);
00333     // Note: applies only for (S,G)
00334     void    sg_see_prune_sg(uint32_t vif_index, uint16_t holdtime,
00335                 const IPvX& target_nbr_addr);
00336     // Note: applies only for (S,G)
00337     void    sg_see_prune_wc(uint32_t vif_index,
00338                 const IPvX& target_nbr_addr);
00339     // Note: applies only for (S,G)
00340     void    sg_see_prune_sg_rpt(uint32_t vif_index, uint16_t holdtime,
00341                     const IPvX& target_nbr_addr);
00342     // Note: applies only for (S,G,rpt)
00343     void    sg_rpt_see_join_sg_rpt(uint32_t vif_index, uint16_t holdtime,
00344                        const IPvX& target_nbr_addr);
00345     // Note: applies only for (S,G,rpt)
00346     void    sg_rpt_see_prune_sg_rpt(uint32_t vif_index, uint16_t holdtime,
00347                     const IPvX& target_nbr_addr);
00348     // Note: applies only for (S,G,rpt)
00349     void    sg_rpt_see_prune_sg(uint32_t vif_index, uint16_t holdtime,
00350                     const IPvX& target_nbr_addr);
00351     // Note: applies only for (*,*,RP), (*,G), (S,G), (S,G,rpt)
00352     bool    is_join_desired_rp() const;
00353     // Note: applies only for (*,G), (S,G), (S,G,rpt)
00354     bool    is_join_desired_wc() const;
00355     // Note: applies only for (S,G)
00356     bool    is_join_desired_sg() const;
00357     // Note: applies only for (*,G), (S,G), (S,G,rpt)
00358     bool    is_rpt_join_desired_g() const;
00359     // Note: applies only for (S,G,rpt)
00360     bool    is_prune_desired_sg_rpt() const;
00361     // Note: applies only for (*,*,RP)
00362     bool    recompute_is_join_desired_rp();
00363     // Note: applies only for (*,G)
00364     bool    recompute_is_join_desired_wc();
00365     // Note: applies only for (S,G)
00366     bool    recompute_is_join_desired_sg();
00367     // Note: applies only for (S,G,rpt)
00368     bool    recompute_is_prune_desired_sg_rpt();
00369     // Note: applies only for (S,G) (recomputed via (S,G) to (S,G,rpt))
00370     bool    recompute_is_prune_desired_sg_rpt_sg();
00371     // Note: applies only for (S,G,rpt)
00372     bool    recompute_is_rpt_join_desired_g();
00373 
00374     // Note: applies only for (*,*,RP), (*,G), (S,G), (S,G,rpt)
00375     const Mifset& joins_rp() const;
00376     // Note: works for (*,G), (S,G), (S,G,rpt)
00377     const Mifset& joins_wc() const;
00378     // Note: applies only for (S,G)
00379     const Mifset& joins_sg() const;
00380     // Note: applies only for (S,G,rpt)
00381     const Mifset& prunes_sg_rpt() const;
00382     
00383     //
00384     // J/P (downstream) state (per interface)
00385     //
00386     // Note: each method below applies for (*,*,RP), (*,G), (S,G), (S,G,rpt)
00387     // (except for the *_tmp_* and *_processed_wc_by_sg_rpt*
00388     // methods which apply only for (S,G,rpt))
00389     void    set_downstream_noinfo_state(uint32_t vif_index);
00390     void    set_downstream_join_state(uint32_t vif_index);
00391     void    set_downstream_prune_state(uint32_t vif_index);
00392     void    set_downstream_prune_pending_state(uint32_t vif_index);
00393     void    set_downstream_prune_tmp_state(uint32_t vif_index);
00394     void    set_downstream_prune_pending_tmp_state(uint32_t vif_index);
00395     void    set_downstream_processed_wc_by_sg_rpt(uint32_t vif_index,
00396                               bool v);
00397     bool    is_downstream_noinfo_state(uint32_t vif_index) const;
00398     bool    is_downstream_join_state(uint32_t vif_index) const;
00399     bool    is_downstream_prune_state(uint32_t vif_index) const;
00400     bool    is_downstream_prune_pending_state(uint32_t vif_index) const;
00401     bool    is_downstream_prune_tmp_state(uint32_t vif_index) const;
00402     bool    is_downstream_prune_pending_tmp_state(uint32_t vif_index) const;
00403     bool    is_downstream_processed_wc_by_sg_rpt(uint32_t vif_index) const;
00404     const Mifset& downstream_join_state() const;
00405     const Mifset& downstream_prune_state() const;
00406     const Mifset& downstream_prune_pending_state() const;
00407     const Mifset& downstream_prune_tmp_state() const;
00408     const Mifset& downstream_prune_pending_tmp_state() const;
00409     
00410     // Note: applies only for (*,*,RP)
00411     void    downstream_expiry_timer_timeout_rp(uint32_t vif_index);
00412     // Note: applies only for (*,G)
00413     void    downstream_expiry_timer_timeout_wc(uint32_t vif_index);
00414     // Note: applies only for (S,G)
00415     void    downstream_expiry_timer_timeout_sg(uint32_t vif_index);
00416     // Note: applies only for (S,G,rpt)
00417     void    downstream_expiry_timer_timeout_sg_rpt(uint32_t vif_index);
00418     // Note: applies only for (*,*,RP)
00419     void    downstream_prune_pending_timer_timeout_rp(uint32_t vif_index);
00420     // Note: applies only for (*,G)
00421     void    downstream_prune_pending_timer_timeout_wc(uint32_t vif_index);
00422     // Note: applies only for (S,G)
00423     void    downstream_prune_pending_timer_timeout_sg(uint32_t vif_index);
00424     // Note: applies only for (S,G,rpt)
00425     void    downstream_prune_pending_timer_timeout_sg_rpt(uint32_t vif_index);
00426     
00427     
00428     //
00429     // J/P upstream state for (*,*,RP), (*,G), (S,G)
00430     //
00431     bool    is_joined_state() const {
00432     return (_flags & PIM_MRE_JOINED_STATE);
00433     }
00434     bool    is_not_joined_state() const { return (!is_joined_state()); }
00435     void    set_joined_state();
00436     void    set_not_joined_state();
00437     //
00438     // J/P upstream state for (S,G,rpt)
00439     //
00440     bool    is_rpt_not_joined_state() const;
00441     bool    is_pruned_state() const;
00442     bool    is_not_pruned_state() const;
00443     void    set_rpt_not_joined_state();
00444     void    set_pruned_state();
00445     void    set_not_pruned_state();
00446     //
00447     // J/P state recomputation
00448     //
00449     //
00450     // Note: works for all entries
00451     const Mifset& immediate_olist_rp() const;
00452     // Note: applies for (*,G), (S,G), (S,G,rpt)
00453     const Mifset& immediate_olist_wc() const;
00454     // Note: applies for (S,G)
00455     const Mifset& immediate_olist_sg() const;
00456     // Note: applies for (*,G), (S,G), (S,G,rpt)
00457     const Mifset& pim_include_wc() const;
00458     // Note: applies for (S,G)
00459     const Mifset& pim_include_sg() const;
00460     // Note: applies for (S,G)
00461     const Mifset& pim_exclude_sg() const;
00462     // Note: applies for (*,*,RP), (*,G), (S,G), (S,G,rpt)
00463     const Mifset& inherited_olist_sg() const;
00464     // Note: applies for (*,*,RP), (*,G), (S,G), (S,G,rpt)
00465     const Mifset& inherited_olist_sg_rpt() const;
00466     // Note: applies for (S,G,rpt)
00467     bool    recompute_inherited_olist_sg_rpt();
00468     
00469     
00470     //
00471     // REGISTER info
00472     //
00473     // Note: applies for (S,G)
00474     void    receive_register_stop();
00475     // Perform the "RP changed" action at the (S,G) register state machine
00476     // Note that the RP has already changed and assigned by the method that
00477     // calls this one, hence we unconditionally take the "RP changed" actions.
00478     // Note: applies for (S,G)
00479     void    rp_register_sg_changed();
00480     // Note: applies for (S,G)
00481     void    set_register_noinfo_state();
00482     // Note: applies for (S,G)
00483     void    set_register_join_state();
00484     // Note: applies for (S,G)
00485     void    set_register_prune_state();
00486     // Note: applies for (S,G)
00487     void    set_register_join_pending_state();
00488     // Note: applies for (S,G)
00489     bool    is_register_noinfo_state() const;
00490     // Note: applies for (S,G)
00491     bool    is_register_join_state() const;
00492     // Note: applies for (S,G)
00493     bool    is_register_prune_state() const;
00494     // Note: applies for (S,G)
00495     bool    is_register_join_pending_state() const;
00496     // Note: applies for (S,G)
00497     bool    compute_is_could_register_sg() const;
00498     // Note: applies for (S,G)
00499     bool    recompute_is_could_register_sg();
00500     // Note: applies for (S,G)
00501     void    add_register_tunnel();
00502     // Note: applies for (S,G)
00503     void    remove_register_tunnel();
00504     // Note: applies for (S,G)
00505     void    update_register_tunnel();
00506     // Note: the remaining Register-related methods below should apply
00507     // only for (S,G), but for simplicity we we don't check the entry type.
00508     bool    is_could_register_sg() const {
00509     return (_flags & PIM_MRE_COULD_REGISTER_SG);
00510     }
00511     bool    is_not_could_register_sg() const {
00512     return (! is_could_register_sg());
00513     }
00514     void    set_could_register_sg() {
00515     _flags |= PIM_MRE_COULD_REGISTER_SG;
00516     }
00517     void    set_not_could_register_sg() {
00518     _flags &= ~PIM_MRE_COULD_REGISTER_SG;
00519     }
00520     XorpTimer&  register_stop_timer() { return (_register_stop_timer); }
00521     void    register_stop_timer_timeout();
00522     
00523     
00524     //
00525     // ASSERT info
00526     //
00527     //  Note: applies only for (*,G) and (S,G)
00528     bool    is_assert_noinfo_state(uint32_t vif_index) const;
00529     //  Note: applies only for (*,G) and (S,G)
00530     bool    is_i_am_assert_winner_state(uint32_t vif_index) const;
00531     //  Note: applies only for (*,G) and (S,G)
00532     bool    is_i_am_assert_loser_state(uint32_t vif_index) const;
00533     //  Note: applies only for (*,G) and (S,G)
00534     void    set_assert_noinfo_state(uint32_t vif_index);
00535     //  Note: applies only for (*,G) and (S,G)
00536     void    set_i_am_assert_winner_state(uint32_t vif_index);
00537     //  Note: applies only for (*,G) and (S,G)
00538     void    set_i_am_assert_loser_state(uint32_t vif_index);
00539     // Note: applies only for (*,G) and (S,G)
00540     const Mifset& i_am_assert_winner_state() const {
00541     return (_i_am_assert_winner_state);
00542     }
00543     // Note: applies only for (*,G) and (S,G)
00544     const Mifset& i_am_assert_loser_state() const {
00545     return (_i_am_assert_loser_state);
00546     }
00547     
00548     // Note: works for (*,G), (S,G), (S,G,rpt)
00549     const Mifset& i_am_assert_winner_wc() const;
00550     // Note: works only for (S,G)
00551     const Mifset& i_am_assert_winner_sg() const;
00552     // Note: applies for (*,G), (S,G), (S,G,rpt)
00553     const Mifset& i_am_assert_loser_wc() const;
00554     // Note: applies only for (S,G)
00555     const Mifset& i_am_assert_loser_sg() const;
00556     // Note: applies for (*,G), (S,G), (S,G,rpt)
00557     const Mifset& lost_assert_wc() const;
00558     // Note: applies only for (S,G)
00559     const Mifset& lost_assert_sg() const;
00560     // Note: applies only for (S,G) and (S,G,rpt)
00561     const Mifset& lost_assert_sg_rpt() const;
00562     
00563     // Note: applies only for (*,G)
00564     void    assert_timer_timeout_wc(uint32_t vif_index);
00565     // Note: applies only for (S,G)
00566     void    assert_timer_timeout_sg(uint32_t vif_index);
00567     // Note: works for (*,G), (S,G)
00568     AssertMetric *assert_winner_metric_wc(uint32_t vif_index) const;
00569     // Note: works for (S,G)
00570     AssertMetric *assert_winner_metric_sg(uint32_t vif_index) const;
00571     // Note: applies only for (*,G) and (S,G)
00572     AssertMetric *assert_winner_metric(uint32_t vif_index) const {
00573     return (_assert_winner_metrics[vif_index]);
00574     }
00575     // Note: works for (*,G), (S,G)
00576     void    set_assert_winner_metric_wc(uint32_t vif_index, AssertMetric *v);
00577     // Note: works for (S,G)
00578     void    set_assert_winner_metric_sg(uint32_t vif_index, AssertMetric *v);
00579     // Note: applies only for (*,G) and (S,G)
00580     void    set_assert_winner_metric(uint32_t vif_index, AssertMetric *v);
00581     // Note: works for (*,G), (S,G)
00582     void    delete_assert_winner_metric_wc(uint32_t vif_index);
00583     // Note: works for (S,G)
00584     void    delete_assert_winner_metric_sg(uint32_t vif_index);
00585     // Note: applies only for (*,G) and (S,G)
00586     void    delete_assert_winner_metric(uint32_t vif_index);
00587     // Note: applies only for (S,G)
00588     const Mifset& assert_winner_metric_is_better_than_spt_assert_metric_sg() const {
00589     return (_assert_winner_metric_is_better_than_spt_assert_metric_sg);
00590     }
00591     // Note: applies only for (S,G)
00592     void    set_assert_winner_metric_is_better_than_spt_assert_metric_sg(uint32_t vif_index, bool v);
00593     Mifset  _assert_winner_metric_is_better_than_spt_assert_metric_sg;
00594     
00595     // Note: applies for (*,G)
00596     const Mifset& assert_tracking_desired_wc() const;
00597     // Note: applies for (S,G)
00598     const Mifset& assert_tracking_desired_sg() const;
00599     // Note: applies only for (*,G) and (S,G)
00600     const Mifset& assert_tracking_desired_state() const {
00601     return (_assert_tracking_desired_state);
00602     }
00603     // Note: applies only for (*,G) and (S,G)
00604     void    set_assert_tracking_desired_state(uint32_t vif_index, bool v);
00605     // Note: applies only for (*,G) and (S,G)
00606     bool    is_assert_tracking_desired_state(uint32_t vif_index) const;
00607     
00608     // Note: applies only for (*,G) and (S,G)
00609     const Mifset& could_assert_state() const { return (_could_assert_state); }
00610     // Note: applies only for (*,G) and (S,G)
00611     bool    is_could_assert_state(uint32_t vif_index) const;
00612     // Note: applies only for (*,G) and (S,G)
00613     void    set_could_assert_state(uint32_t vif_index, bool v);
00614     
00615     // Note: applies only for (S,G)
00616     AssertMetric *my_assert_metric_sg(uint32_t vif_index) const;
00617     // Note: applies only for (S,G)
00618     AssertMetric *my_assert_metric_wc(uint32_t vif_index) const;
00619     // Note: applies only for (S,G)
00620     AssertMetric *spt_assert_metric(uint32_t vif_index) const;
00621     // Note: applies only for (*,G) and (S,G)
00622     AssertMetric *rpt_assert_metric(uint32_t vif_index) const;
00623     // Note: applies only for (*,G) and (S,G) (but is used only for (S,G))
00624     AssertMetric *infinite_assert_metric() const;
00625                             // metrics array.
00626     // Note: applies only for (*,G) and (S,G)
00627     int     assert_process(PimVif *pim_vif, AssertMetric *assert_metric);
00628     // Note: applies only for (S,G)
00629     int     assert_process_sg(PimVif *pim_vif,
00630                   AssertMetric *assert_metric,
00631                   assert_state_t assert_state,
00632                   bool i_am_assert_winner);
00633     // Note: applies only for (*,G)
00634     int     assert_process_wc(PimVif *pim_vif,
00635                   AssertMetric *assert_metric,
00636                   assert_state_t state,
00637                   bool i_am_assert_winner);
00638     // Note: applies for all entries
00639     int     data_arrived_could_assert(PimVif *pim_vif,
00640                       const IPvX& src,
00641                       const IPvX& dst,
00642                       bool& is_assert_sent);
00643     // Note: applies only for (S,G)
00644     int     data_arrived_could_assert_sg(PimVif *pim_vif,
00645                          const IPvX& assert_source_addr,
00646                          bool& is_assert_sent);
00647     // Note: applies only for (*,G)
00648     int     data_arrived_could_assert_wc(PimVif *pim_vif,
00649                          const IPvX& assert_source_addr,
00650                          bool& is_assert_sent);
00651     // Note: applies only for (S,G)
00652     int     wrong_iif_data_arrived_sg(PimVif *pim_vif,
00653                       const IPvX& assert_source_addr,
00654                       bool& is_assert_sent);
00655     // Note: applies only for (*,G)
00656     int     wrong_iif_data_arrived_wc(PimVif *pim_vif,
00657                       const IPvX& assert_source_addr,
00658                       bool& is_assert_sent);
00659     // Note: applies only for (S,G)
00660     bool    recompute_assert_tracking_desired_sg();
00661     // Note: applies only for (S,G)
00662     bool    process_assert_tracking_desired_sg(uint32_t vif_index,
00663                            bool new_value);
00664     // Note: applies only for (*,G)
00665     bool    recompute_assert_tracking_desired_wc();
00666     // Note: applies only for (*,G)
00667     bool    process_assert_tracking_desired_wc(uint32_t vif_index,
00668                            bool new_value);
00669     // Note: applies only for (S,G) and (S,G,rpt)
00670     const Mifset& could_assert_sg() const;
00671     // Note: applies only for (S,G)
00672     bool    recompute_could_assert_sg();
00673     // Note: applies only for (S,G)
00674     bool    process_could_assert_sg(uint32_t vif_index, bool new_value);
00675     // Note: applies for all entries
00676     const Mifset& could_assert_wc() const;
00677     // Note: applies only for (*,G)
00678     bool    recompute_could_assert_wc();
00679     // Note: applies only for (*,G)
00680     bool    process_could_assert_wc(uint32_t vif_index, bool new_value);
00681     // Note: applies only for (S,G)
00682     bool    recompute_my_assert_metric_sg(uint32_t vif_index);
00683     // Note: applies only for (*,G)
00684     bool    recompute_my_assert_metric_wc(uint32_t vif_index);
00685     // Note: applies only for (S,G)
00686     bool    recompute_assert_rpf_interface_sg(uint32_t vif_index);
00687     // Note: applies only for (*,G)
00688     bool    recompute_assert_rpf_interface_wc(uint32_t vif_index);
00689     // Note: applies only for (S,G)
00690     bool    recompute_assert_receive_join_sg(uint32_t vif_index);
00691     // Note: applies only for (*,G)
00692     bool    recompute_assert_receive_join_wc(uint32_t vif_index);
00693     // Note: applies only for (S,G)
00694     bool    recompute_assert_winner_nbr_sg_gen_id_changed(
00695     uint32_t vif_index,
00696     const IPvX& nbr_addr);
00697     // Note: applies only for (*,G)
00698     bool    recompute_assert_winner_nbr_wc_gen_id_changed(
00699     uint32_t vif_index,
00700     const IPvX& nbr_addr);
00701     // Note: applies only for (S,G)
00702     bool    recompute_assert_winner_nbr_sg_nlt_expired(
00703     uint32_t vif_index,
00704     const IPvX& nbr_addr);
00705     // Note: applies only for (*,G)
00706     bool    recompute_assert_winner_nbr_wc_nlt_expired(
00707     uint32_t vif_index,
00708     const IPvX& nbr_addr);
00709     
00710     // Assert rate-limiting stuff
00711     void    asserts_rate_limit_timer_timeout();
00712 
00713     //
00714     // PMBR info
00715     //
00716     // PMBR: the first PMBR to send a Register for this source
00717     // with the Border bit set.
00718     // Note: applies only for (S,G)
00719     const IPvX& pmbr_addr() const { return _pmbr_addr; }
00720     void    set_pmbr_addr(const IPvX& v) { _pmbr_addr = v; }
00721     void    clear_pmbr_addr() { _pmbr_addr = IPvX::ZERO(family()); }
00722     bool    is_pmbr_addr_set() const { return (_pmbr_addr != IPvX::ZERO(family())); }
00723 
00724     //
00725     // MISC. info
00726     //
00727     // Note: applies for (*,*,RP), (*,G), (S,G), (S,G,rpt)
00728     const Mifset& i_am_dr() const;
00729     
00730     
00731     //
00732     // Data
00733     //
00734     // Note: applies only for (S,G)
00735     void    update_sptbit_sg(uint32_t iif_vif_index);
00736     // Note: applies for (*,G), (S,G), (S,G,rpt)
00737     bool    is_monitoring_switch_to_spt_desired_sg(const PimMre *pim_mre_sg) const;
00738     // Note: applies for all entries
00739     bool    is_switch_to_spt_desired_sg(uint32_t measured_interval_sec,
00740                         uint32_t measured_bytes) const;
00741     // Note: in theory applies for all entries, but in practice it could
00742     // be true only for (*,G), (S,G), (S,G,rpt)
00743     bool    check_switch_to_spt_sg(const IPvX& src, const IPvX& dst,
00744                        PimMre*& pim_mre_sg,
00745                        uint32_t measured_interval_sec,
00746                        uint32_t measured_bytes);
00747     // Note: applies only for (S,G)
00748     void    set_switch_to_spt_desired_sg(bool v);
00749     // Note: applies only for (S,G)
00750     bool    was_switch_to_spt_desired_sg() const;
00751     
00752     
00753     //
00754     // MISC. timers
00755     //
00756     // The KeepaliveTimer(S,G)
00757     // Note: applies only for (S,G)
00758     void    start_keepalive_timer();
00759     // Note: applies only for (S,G)
00760     void    cancel_keepalive_timer();
00761     // Note: applies only for (S,G)
00762     bool    is_keepalive_timer_running() const;
00763     // Note: applies only for (S,G)
00764     void    keepalive_timer_timeout();
00765     // Note: applies only for (S,G)
00766     void    recompute_set_keepalive_timer_sg();
00767     
00768     //
00769     // MISC. other stuff
00770     //
00771     
00772     // Note: applies for (*,*,RP)
00773     void    recompute_start_vif_rp(uint32_t vif_index);
00774     // Note: applies for (*,G)
00775     void    recompute_start_vif_wc(uint32_t vif_index);
00776     // Note: applies for (S,G)
00777     void    recompute_start_vif_sg(uint32_t vif_index);
00778     // Note: applies for (S,G,rpt)
00779     void    recompute_start_vif_sg_rpt(uint32_t vif_index);
00780     // Note: applies for (*,*,RP)
00781     void    recompute_stop_vif_rp(uint32_t vif_index);
00782     // Note: applies for (*,G)
00783     void    recompute_stop_vif_wc(uint32_t vif_index);
00784     // Note: applies for (S,G)
00785     void    recompute_stop_vif_sg(uint32_t vif_index);
00786     // Note: applies for (S,G,rpt)
00787     void    recompute_stop_vif_sg_rpt(uint32_t vif_index);
00788     
00789     // Note: applies for (*,*,RP), (*,G), (S,G), (S,G,rpt)
00790     bool    entry_try_remove();    // Try to remove the entry if not needed
00791     // Note: applies for (*,*,RP), (*,G), (S,G), (S,G,rpt)
00792     bool    entry_can_remove() const; // Test if OK to remove the entry
00793 
00794     // Actions to take when a related PimMre entry is added or removed
00795     // Note: applies for (*,*,RP), (*,G), (S,G), (S,G,rpt)
00796     void    add_pim_mre_rp_entry();
00797     // Note: applies for (*,G), (S,G), (S,G,rpt)
00798     void    add_pim_mre_wc_entry();
00799     // Note: applies for (S,G), (S,G,rpt)
00800     void    add_pim_mre_sg_entry();
00801     // Note: applies for (S,G), (S,G,rpt)
00802     void    add_pim_mre_sg_rpt_entry();
00803     // Note: applies for (*,*,RP), (*,G), (S,G), (S,G,rpt)
00804     void    remove_pim_mre_rp_entry();
00805     // Note: applies for (*,G), (S,G), (S,G,rpt)
00806     void    remove_pim_mre_wc_entry();
00807     // Note: applies for (S,G), (S,G,rpt)
00808     void    remove_pim_mre_sg_entry();
00809     // Note: applies for (S,G), (S,G,rpt)
00810     void    remove_pim_mre_sg_rpt_entry();
00811     
00812     // Note: applies for (S,G)
00813     bool    is_directly_connected_s() const {
00814     return (_flags & PIM_MRE_DIRECTLY_CONNECTED_S);
00815     }
00816     // Note: applies for (S,G)
00817     void    set_directly_connected_s(bool v) {
00818     if (v)
00819         _flags |= PIM_MRE_DIRECTLY_CONNECTED_S;
00820     else
00821         _flags &= ~PIM_MRE_DIRECTLY_CONNECTED_S;    
00822     }
00823     
00824     // Note: applies for (*,*,RP), (*,G), (S,G), (S,G,rpt)
00825     bool    i_am_rp() const { return (_flags & PIM_MRE_I_AM_RP); }
00826     // Note: applies for (*,*,RP), (*,G), (S,G), (S,G,rpt)
00827     void    set_i_am_rp(bool v) {
00828     if (v) {
00829         _flags |= PIM_MRE_I_AM_RP;
00830     } else {
00831         //
00832         // XXX: Reset the PIM_MRE_IS_KAT_SET_TO_RP_KEEPALIVE_PERIOD flag
00833         // as well, because it applies only at the RP.
00834         //
00835         _flags &= ~(PIM_MRE_I_AM_RP | PIM_MRE_IS_KAT_SET_TO_RP_KEEPALIVE_PERIOD);
00836     }
00837     }
00838 
00839     // Note: applies for (S,G)
00840     bool    is_kat_set_to_rp_keepalive_period() const { return (_flags & PIM_MRE_IS_KAT_SET_TO_RP_KEEPALIVE_PERIOD); }
00841     void    set_is_kat_set_to_rp_keepalive_period(bool v) {
00842     if (v)
00843         _flags |= PIM_MRE_IS_KAT_SET_TO_RP_KEEPALIVE_PERIOD;
00844     else
00845         _flags &= ~PIM_MRE_IS_KAT_SET_TO_RP_KEEPALIVE_PERIOD;
00846     }
00847     
00848     // Note: applies for (*,*,RP), (*,G), (S,G), (S,G,rpt)
00849     bool    is_task_delete_pending() const { return (_flags & PIM_MRE_TASK_DELETE_PENDING); }
00850     // Note: applies for (*,*,RP), (*,G), (S,G), (S,G,rpt)
00851     void    set_is_task_delete_pending(bool v) {
00852     if (v)
00853         _flags |= PIM_MRE_TASK_DELETE_PENDING;
00854     else
00855         _flags &= ~PIM_MRE_TASK_DELETE_PENDING;
00856     }
00857     // Note: applies for (*,*,RP), (*,G), (S,G), (S,G,rpt)
00858     bool    is_task_delete_done() const { return (_flags & PIM_MRE_TASK_DELETE_DONE); }
00859     // Note: applies for (*,*,RP), (*,G), (S,G), (S,G,rpt)
00860     void    set_is_task_delete_done(bool v) {
00861     if (v)
00862         _flags |= PIM_MRE_TASK_DELETE_DONE;
00863     else
00864         _flags &= ~PIM_MRE_TASK_DELETE_DONE;
00865     }
00866     
00867 private:
00868     PimMrt  *_pim_mrt;      // The PIM MRT (yuck!)
00869     PimRp   *_pim_rp;       // The RP entry
00870                     // Used by (*,G) (S,G) (S,G,rpt)
00871     Mrib    *_mrib_rp;      // The MRIB info to the RP
00872                     // Used by all entries
00873     Mrib    *_mrib_s;       // The MRIB info to the source
00874                     // Used by (S,G) (S,G,rpt)
00875     //
00876     PimNbr  *_nbr_mrib_next_hop_rp; // Applies only for (*,*,RP) and (*,G)
00877     PimNbr  *_nbr_mrib_next_hop_s;  // Applies only for (S,G)
00878     PimNbr  *_rpfp_nbr_wc;      // Applies only for (*,G)
00879     PimNbr  *_rpfp_nbr_sg;      // Applies only for (S,G)
00880     PimNbr  *_rpfp_nbr_sg_rpt;  // Applies only for (S,G,rpt)
00881     //
00882     PimMre  *_wc_entry;     // The (*,G) entry
00883     PimMre  *_rp_entry;     // The (*,*,RP) entry
00884     PimMre  *_sg_sg_rpt_entry;  // The (S,G) or (S,G,rpt) entry
00885     Mifset  _local_receiver_include; // The interfaces with IGMP/MLD6 Join
00886     Mifset  _local_receiver_exclude; // The interfaces with IGMP/MLD6 Leave
00887     XorpTimer   _join_or_override_timer; // The Join Timer for
00888                      // (*,*,RP) (*,G) (S,G);
00889                      // Also Override Timer for (S,G,rpt)
00890     Mifset  _downstream_join_state;         // Join state
00891     Mifset  _downstream_prune_pending_state;    // Prune-Pending state
00892     Mifset  _downstream_prune_state;        // Prune state
00893     Mifset  _downstream_tmp_state;          // P' and PP' state
00894     Mifset  _downstream_processed_wc_by_sg_rpt; // (S,G,rpt)J/P processed
00895     XorpTimer   _downstream_expiry_timers[MAX_VIFS];    // Expiry timers
00896     XorpTimer   _downstream_prune_pending_timers[MAX_VIFS]; // Prune-Pending timers
00897 
00898     XorpTimer   _register_stop_timer;
00899     Mifset  _i_am_assert_winner_state; // The interfaces I am Assert winner
00900     Mifset  _i_am_assert_loser_state;  // The interfaces I am Assert loser
00901     XorpTimer   _assert_timers[MAX_VIFS];  // The Assert (winner/loser) timers
00902     Mifset  _assert_tracking_desired_state; // To store the
00903                         // AssertTrackingDesired state
00904     Mifset  _could_assert_state;    // To store the CouldAssert state
00905     AssertMetric *_assert_winner_metrics[MAX_VIFS]; // The Assert winner
00906     Mifset  _asserts_rate_limit;    // Bit-flags for Asserts rate limit
00907     XorpTimer   _asserts_rate_limit_timer;  // Timer for Asserts rate limit
00908                         // support
00909     IPvX    _pmbr_addr;     // The address of the PMBR
00910 
00911     uint32_t    _flags;         // Various flags (see PIM_MRE_* above)
00912 };
00913 
00914 
00915 #endif // __PIM_PIM_MRE_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations