Samuel Lucas Vaz de Mello <[EMAIL PROTECTED]> wrote:

> > If I remember correctly, I used bsr_stop()/bsr_start() because there
> > was lots of complexity when I tried to do the incremental update.
> > Though, I don't remember whether this applied to the first version
> > of the BSR implementation or to the (almost complete) rewrite I had
> > to do after I discovered major issues with the first version.
> 
> The code in CVS is the rewritten code?

Yes.

> > Another reason for the bsr_stop()/bsr_start() was because I wanted
> > atomic update (e.g., transaction like), otherwise during
> > reconfiguration there will be lots of flux with potentially
> > dangerous results (remember that consistent Cand-RP set across
> > all PIM-SM routers is critical).
> > At that time there was no easy way to apply some transaction-based
> > mechanism to achieve the atomic update, so the
> > bsr_stop()/bsr_start() was the simple work-around (e.g., note that
> > it is in the etc/templates/pimsm*.tp template files).
> > 
> > If you can find a simple way to do the update atomically without
> > bsr_stop()/bsr_start(), then give it a try and see how well it
> > works.
> > Otherwise, please submit a Bugzilla entry about the issue.
> 
> I played around a bit with this. 
> 
> I've tried to keep as close as possible to the stop()/start() approach. 
> My idea was:
> 
> - Add a boolean parameter to bsr_start()/bsr_stop that is true during restarts
> - Create a bsr_restart() method that calls bsr_stop(true) and then 
> bsr_start(true)
> - In stop(true), instead deleting the whole _active_bsr_zone_list delete only 
> the non-elected zones. For the elected zones, delete all groupprefix (which 
> contains the rps).
> - In start(true) it will reuse the existing elected zone and add all 
> configured groupprefix (and rps)
> - In start(true), check if any elected zone was deleted from config and 
> vanish them.
> - After that, I put the elected zones back in the PENDING state and expire 
> the bsr timer. The timer will put it back in the ELECTED state, compute the 
> rp-set and send BSR Messages with the new rp-set.
> 
> In my tests it seems to work fine.
> I'm sending the patch attached.
> 
> Can you have a look on it and check if I've forgotten something?

Samuel,

I took your patch and refactored it a bit: now there is an explicit
XRL apply_bsr_changes, and there is an explicit method
PimBsr::apply_bsr_changes().
In that method I basically merged your code from stop_bsr() and
start_bsr().
Thus, we don't overload the original stop_bsr() and start_bsr(),
and we can do all that is needed in one place.

However, I have to admit that I didn't look into the details of what
you are doing when the BSR is restarted, so I cannot comment whether
it is the right thing or whether something is missing.
I intend to do this in the future, but unfortunately I cannot do
this right now (see below).

Currently we are in the process of code freeze, so I am afraid
this fix has to wait (strictly speaking it is an
optimization so it is not critical).
In the mean time please have a look in my refactoring of your patch
in case I messed-up something.. If it is OK for you and if it works,
please create a Bugzilla entry about the issue, and add that patch
to the entry. Thus we can track its status, update the patch, etc.

Thanks,
Pavlin

Index: etc/templates/pimsm4.tp
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/etc/templates/pimsm4.tp,v
retrieving revision 1.35
diff -u -p -r1.35 pimsm4.tp
--- etc/templates/pimsm4.tp     2 May 2008 00:00:53 -0000       1.35
+++ etc/templates/pimsm4.tp     29 Oct 2008 23:47:33 -0000
@@ -209,8 +209,7 @@ protocols {
            %help:      short "Configure the IPv4 Bootstrap mechanism";
            %activate:  xrl "$(pimsm4.targetname)/pim/0.1/stop_bsr";
            %activate:  xrl "$(pimsm4.targetname)/pim/0.1/start_bsr";
-           %update:    xrl "$(pimsm4.targetname)/pim/0.1/stop_bsr";
-           %update:    xrl "$(pimsm4.targetname)/pim/0.1/start_bsr";
+           %update:    xrl "$(pimsm4.targetname)/pim/0.1/apply_bsr_changes";
            %delete:    xrl "$(pimsm4.targetname)/pim/0.1/stop_bsr";
 
            disable {
Index: etc/templates/pimsm6.tp
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/etc/templates/pimsm6.tp,v
retrieving revision 1.35
diff -u -p -r1.35 pimsm6.tp
--- etc/templates/pimsm6.tp     2 May 2008 00:00:53 -0000       1.35
+++ etc/templates/pimsm6.tp     29 Oct 2008 23:47:33 -0000
@@ -209,8 +209,7 @@ protocols {
            %help:      short "Configure the IPv6 Bootstrap mechanism";
            %activate:  xrl "$(pimsm6.targetname)/pim/0.1/stop_bsr";
            %activate:  xrl "$(pimsm6.targetname)/pim/0.1/start_bsr";
-           %update:    xrl "$(pimsm6.targetname)/pim/0.1/stop_bsr";
-           %update:    xrl "$(pimsm6.targetname)/pim/0.1/start_bsr";
+           %update:    xrl "$(pimsm6.targetname)/pim/0.1/apply_bsr_changes";
            %delete:    xrl "$(pimsm6.targetname)/pim/0.1/stop_bsr";
 
            disable {
Index: pim/pim_bsr.cc
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/pim/pim_bsr.cc,v
retrieving revision 1.57
diff -u -p -r1.57 pim_bsr.cc
--- pim/pim_bsr.cc      28 Oct 2008 00:21:18 -0000      1.57
+++ pim/pim_bsr.cc      29 Oct 2008 23:47:35 -0000
@@ -316,6 +316,123 @@ PimBsr::disable()
     XLOG_INFO("Bootstrap mechanism disabled");
 }
 
+int
+PimBsr::apply_bsr_changes(string& error_msg)
+{
+    list<BsrZone *>::iterator iter;
+    list<BsrZone*> del_list;
+
+    if (! is_enabled())
+       return (XORP_OK);
+
+    //
+    // Preserve any elected BSR zones
+    //
+    for (list<BsrZone*>::iterator iter = _active_bsr_zone_list.begin();
+        iter != _active_bsr_zone_list.end();
+        iter++) {
+       BsrZone* tmp_zone = *iter;
+       // If the BSR zone is not elected BSR, just remove it
+       if (tmp_zone->bsr_zone_state() != BsrZone::STATE_ELECTED_BSR) {
+           del_list.push_back(tmp_zone);
+       } else {
+           //
+           // It is an Elected BSR. We will keep the BSR zone in the list
+           // but remove all Cand RPs. Some of them may have been deleted.
+           // The Cand RPs that were not deleted will be added again below.
+           //
+           delete_pointers_list(tmp_zone->bsr_group_prefix_list());
+       }
+    }
+    for (list<BsrZone*>::iterator iter = del_list.begin();
+        iter != del_list.end(); ++iter) {
+       _active_bsr_zone_list.remove(*iter);
+    }
+    delete_pointers_list(del_list);
+
+    //
+    // Clean up any deleted zone
+    //
+    for (iter = _active_bsr_zone_list.begin();
+        iter != _active_bsr_zone_list.end();
+        ++iter) {
+       BsrZone *active_bsr_zone = *iter;
+       if (active_bsr_zone->bsr_zone_state() == BsrZone::STATE_ELECTED_BSR) {
+           BsrZone *config_bsr_zone;
+           config_bsr_zone = find_config_bsr_zone(active_bsr_zone->zone_id());
+           if (config_bsr_zone == NULL) {
+               // Zone removed from config
+               del_list.push_back(active_bsr_zone);
+               continue;
+           }
+
+           //
+           // Zone is no longer BSR candidate (i.e., removed from Cand-BSR but
+           // still has some Cand-RP state).
+           //
+           // Remove it too, as the Cand-RP state is re-added below
+           if (! config_bsr_zone->i_am_candidate_bsr()) {
+               del_list.push_back(active_bsr_zone);
+               continue;
+           }
+       }
+    }
+
+    //
+    // Delete the vanished items
+    //
+    for (iter = del_list.begin(); iter != del_list.end(); ++iter) {
+       BsrZone *active_bsr_zone = *iter;
+       _active_bsr_zone_list.remove(active_bsr_zone);
+    }
+    delete_pointers_list(del_list);
+
+    //
+    // Activate all configured BSR zones
+    //
+    for (iter = _config_bsr_zone_list.begin();
+        iter != _config_bsr_zone_list.end();
+        ++iter) {
+       BsrZone *config_bsr_zone = *iter;
+       
+       if (config_bsr_zone->i_am_candidate_bsr()) {
+           if (add_active_bsr_zone(*config_bsr_zone, error_msg) == NULL) {
+               XLOG_ERROR("Cannot add configured Bootstrap zone %s: %s",
+                          cstring(config_bsr_zone->zone_id()),
+                          error_msg.c_str());
+               stop();
+               return (XORP_ERROR);
+           }
+       }
+       config_bsr_zone->start_candidate_rp_advertise_timer();
+    }
+
+    //
+    // When restarting we want to keep any previously enabled BSR.
+    // Set it to PENDING and expire the bsr_timer immediately.
+    // As soon as the timer runs, it puts the zone back in the ELECTED
+    // state and run the needed actions (calculate RP-Set and send a
+    // BSR Message with the new RP-Set).
+    //
+    for (iter = _active_bsr_zone_list.begin();
+        iter != _active_bsr_zone_list.end();
+        ++iter) {
+       BsrZone *active_bsr_zone = *iter;
+       if (active_bsr_zone->bsr_zone_state() == BsrZone::STATE_ELECTED_BSR) {
+           if (active_bsr_zone->i_am_candidate_bsr()) {
+               // zone was not changed
+               active_bsr_zone->set_bsr_zone_state(BsrZone::STATE_PENDING_BSR);
+           } else {
+               // zone is no longer Cand-BSR, but contains Cand-RPs
+               active_bsr_zone->set_bsr_zone_state(BsrZone::STATE_ACCEPT_ANY);
+           }
+           active_bsr_zone->expire_bsr_timer();
+       }
+    }
+
+    return (XORP_OK);
+}
+
 // Unicast the Bootstrap message(s) to a (new) neighbor
 int
 PimBsr::unicast_pim_bootstrap(PimVif *pim_vif, const IPvX& nbr_addr) const
Index: pim/pim_bsr.hh
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/pim/pim_bsr.hh,v
retrieving revision 1.24
diff -u -p -r1.24 pim_bsr.hh
--- pim/pim_bsr.hh      28 Oct 2008 00:21:18 -0000      1.24
+++ pim/pim_bsr.hh      29 Oct 2008 23:47:35 -0000
@@ -93,6 +93,14 @@ public:
      */
     void       disable();
 
+    /**
+     * Apply BSR configuration changes.
+     *
+     * @param error_msg the error message (if error).
+     * @return XORP_OK on success, otherwise XORP_ERROR.
+     */
+    int                apply_bsr_changes(string& error_msg);
+
     PimNode&   pim_node()      const   { return (_pim_node); }
     
     int                unicast_pim_bootstrap(PimVif *pim_vif,
Index: pim/pim_node.hh
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/pim/pim_node.hh,v
retrieving revision 1.70
diff -u -p -r1.70 pim_node.hh
--- pim/pim_node.hh     2 Oct 2008 21:57:54 -0000       1.70
+++ pim/pim_node.hh     29 Oct 2008 23:47:35 -0000
@@ -872,7 +872,17 @@ public:
      * @return XORP_OK on success, otherwise XORP_ERROR.
      */
     int                stop_bsr() { return (pim_bsr().stop()); }
-    
+
+    /**
+     * Apply BSR configuration changes.
+     *
+     * @param error_msg the error message (if error).
+     * @return XORP_OK on success, otherwise XORP_ERROR.
+     */
+    int                apply_bsr_changes(string& error_msg) {
+       return (pim_bsr().apply_bsr_changes(error_msg));
+    }
+
     //
     // Configuration methods
     //
Index: pim/xrl_pim_node.cc
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/pim/xrl_pim_node.cc,v
retrieving revision 1.105
diff -u -p -r1.105 xrl_pim_node.cc
--- pim/xrl_pim_node.cc 2 Oct 2008 21:57:56 -0000       1.105
+++ pim/xrl_pim_node.cc 29 Oct 2008 23:47:36 -0000
@@ -3930,6 +3930,17 @@ XrlPimNode::pim_0_1_stop_bsr()
     return XrlCmdError::OKAY();
 }
 
+XrlCmdError
+XrlPimNode::pim_0_1_apply_bsr_changes()
+{
+    string error_msg;
+    
+    if (PimNode::apply_bsr_changes(error_msg) != XORP_OK)
+       return XrlCmdError::COMMAND_FAILED(error_msg);
+
+    return XrlCmdError::OKAY();
+}
+
 //
 // PIM configuration
 //
Index: pim/xrl_pim_node.hh
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/pim/xrl_pim_node.hh,v
retrieving revision 1.80
diff -u -p -r1.80 xrl_pim_node.hh
--- pim/xrl_pim_node.hh 2 Oct 2008 21:57:56 -0000       1.80
+++ pim/xrl_pim_node.hh 29 Oct 2008 23:47:36 -0000
@@ -709,6 +709,11 @@ protected:    
     XrlCmdError pim_0_1_stop_bsr();
 
     /**
+     *  Apply BSR configuration changes.
+     */
+    XrlCmdError pim_0_1_apply_bsr_changes();
+
+    /**
      *  Add/delete scope zone.
      *  
      *  @param scope_zone_id the ID of the configured zone.
Index: xrl/interfaces/pim.xif
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/xrl/interfaces/pim.xif,v
retrieving revision 1.25
diff -u -p -r1.25 pim.xif
--- xrl/interfaces/pim.xif      2 May 2008 00:00:54 -0000       1.25
+++ xrl/interfaces/pim.xif      29 Oct 2008 23:47:38 -0000
@@ -59,6 +59,11 @@ interface pim/0.1 {
        stop_bsr
 
        /**
+        * Apply BSR configuration changes.
+        */
+        apply_bsr_changes
+
+       /**
         * Add/delete scope zone.
         *
         * @param scope_zone_id the ID of the configured zone.
Index: xrl/interfaces/pim_xif.cc
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/xrl/interfaces/pim_xif.cc,v
retrieving revision 1.45
diff -u -p -r1.45 pim_xif.cc
--- xrl/interfaces/pim_xif.cc   2 Oct 2008 21:58:37 -0000       1.45
+++ xrl/interfaces/pim_xif.cc   29 Oct 2008 23:47:39 -0000
@@ -607,6 +607,44 @@ XrlPimV0p1Client::unmarshall_stop_bsr(
 }
 
 bool
+XrlPimV0p1Client::send_apply_bsr_changes(
+       const char*     dst_xrl_target_name,
+       const ApplyBsrChangesCB&        cb
+)
+{
+    static Xrl* x = NULL;
+
+    if (!x) {
+        x = new Xrl(dst_xrl_target_name, "pim/0.1/apply_bsr_changes");
+    }
+
+    x->set_target(dst_xrl_target_name);
+
+
+    return _sender->send(*x, callback(this, 
&XrlPimV0p1Client::unmarshall_apply_bsr_changes, cb));
+}
+
+
+/* Unmarshall apply_bsr_changes */
+void
+XrlPimV0p1Client::unmarshall_apply_bsr_changes(
+       const XrlError& e,
+       XrlArgs*        a,
+       ApplyBsrChangesCB               cb
+)
+{
+    if (e != XrlError::OKAY()) {
+       cb->dispatch(e);
+       return;
+    } else if (a && a->size() != 0) {
+       XLOG_ERROR("Wrong number of arguments (%u != %u)", 
XORP_UINT_CAST(a->size()), XORP_UINT_CAST(0));
+       cb->dispatch(XrlError::BAD_ARGS());
+       return;
+    }
+    cb->dispatch(e);
+}
+
+bool
 XrlPimV0p1Client::send_add_config_scope_zone_by_vif_name4(
        const char*     dst_xrl_target_name,
        const IPv4Net&  scope_zone_id,
Index: xrl/interfaces/pim_xif.hh
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/xrl/interfaces/pim_xif.hh,v
retrieving revision 1.43
diff -u -p -r1.43 pim_xif.hh
--- xrl/interfaces/pim_xif.hh   2 Oct 2008 21:58:37 -0000       1.43
+++ xrl/interfaces/pim_xif.hh   29 Oct 2008 23:47:39 -0000
@@ -186,6 +186,19 @@ public:
        const StopBsrCB&        cb
     );
 
+    typedef XorpCallback1<void, const XrlError&>::RefPtr ApplyBsrChangesCB;
+    /**
+     *  Send Xrl intended to:
+     *
+     *  Apply BSR configuration changes.
+     *
+     *  @param dst_xrl_target_name the Xrl target name of the destination.
+     */
+    bool send_apply_bsr_changes(
+       const char*     dst_xrl_target_name,
+       const ApplyBsrChangesCB&        cb
+    );
+
     typedef XorpCallback1<void, const XrlError&>::RefPtr 
AddConfigScopeZoneByVifName4CB;
     /**
      *  Send Xrl intended to:
@@ -2205,6 +2218,12 @@ private:
        StopBsrCB               cb
     );
 
+    void unmarshall_apply_bsr_changes(
+       const XrlError& e,
+       XrlArgs*        a,
+       ApplyBsrChangesCB               cb
+    );
+
     void unmarshall_add_config_scope_zone_by_vif_name4(
        const XrlError& e,
        XrlArgs*        a,
Index: xrl/targets/pim.xrls
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/xrl/targets/pim.xrls,v
retrieving revision 1.62
diff -u -p -r1.62 pim.xrls
--- xrl/targets/pim.xrls        2 Oct 2008 21:58:48 -0000       1.62
+++ xrl/targets/pim.xrls        29 Oct 2008 23:47:39 -0000
@@ -396,6 +396,11 @@ finder://pim/pim/0.1/start_bsr
 finder://pim/pim/0.1/stop_bsr
 
 /**
+ *  Apply BSR configuration changes.
+ */
+finder://pim/pim/0.1/apply_bsr_changes
+
+/**
  *  Add/delete scope zone.
  *
  *  @param scope_zone_id the ID of the configured zone.
Index: xrl/targets/pim_base.cc
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/xrl/targets/pim_base.cc,v
retrieving revision 1.67
diff -u -p -r1.67 pim_base.cc
--- xrl/targets/pim_base.cc     2 Oct 2008 21:58:48 -0000       1.67
+++ xrl/targets/pim_base.cc     29 Oct 2008 23:47:40 -0000
@@ -1343,6 +1343,30 @@ XrlPimTargetBase::handle_pim_0_1_stop_bs
 }
 
 const XrlCmdError
+XrlPimTargetBase::handle_pim_0_1_apply_bsr_changes(const XrlArgs& xa_inputs, 
XrlArgs* /* pxa_outputs */)
+{
+    if (xa_inputs.size() != 0) {
+       XLOG_ERROR("Wrong number of arguments (%u != %u) handling %s",
+            XORP_UINT_CAST(0), XORP_UINT_CAST(xa_inputs.size()), 
"pim/0.1/apply_bsr_changes");
+       return XrlCmdError::BAD_ARGS();
+    }
+
+    /* Return value declarations */
+    try {
+       XrlCmdError e = pim_0_1_apply_bsr_changes();
+       if (e != XrlCmdError::OKAY()) {
+           XLOG_WARNING("Handling method for %s failed: %s",
+                        "pim/0.1/apply_bsr_changes", e.str().c_str());
+           return e;
+        }
+    } catch (const XrlArgs::BadArgs& e) {
+       XLOG_ERROR("Error decoding the arguments: %s", e.str().c_str());
+       return XrlCmdError::BAD_ARGS(e.str());
+    }
+    return XrlCmdError::OKAY();
+}
+
+const XrlCmdError
 XrlPimTargetBase::handle_pim_0_1_add_config_scope_zone_by_vif_name4(const 
XrlArgs& xa_inputs, XrlArgs* /* pxa_outputs */)
 {
     if (xa_inputs.size() != 2) {
@@ -8766,6 +8790,10 @@ XrlPimTargetBase::add_handlers()
            callback(this, &XrlPimTargetBase::handle_pim_0_1_stop_bsr)) == 
false) {
            XLOG_ERROR("Failed to xrl handler finder://%s/%s", "pim", 
"pim/0.1/stop_bsr");
        }
+       if (_cmds->add_handler("pim/0.1/apply_bsr_changes",
+           callback(this, 
&XrlPimTargetBase::handle_pim_0_1_apply_bsr_changes)) == false) {
+           XLOG_ERROR("Failed to xrl handler finder://%s/%s", "pim", 
"pim/0.1/apply_bsr_changes");
+       }
        if (_cmds->add_handler("pim/0.1/add_config_scope_zone_by_vif_name4",
            callback(this, 
&XrlPimTargetBase::handle_pim_0_1_add_config_scope_zone_by_vif_name4)) == 
false) {
            XLOG_ERROR("Failed to xrl handler finder://%s/%s", "pim", 
"pim/0.1/add_config_scope_zone_by_vif_name4");
@@ -9644,6 +9672,7 @@ XrlPimTargetBase::remove_handlers()
        _cmds->remove_handler("pim/0.1/enable_bsr");
        _cmds->remove_handler("pim/0.1/start_bsr");
        _cmds->remove_handler("pim/0.1/stop_bsr");
+       _cmds->remove_handler("pim/0.1/apply_bsr_changes");
        _cmds->remove_handler("pim/0.1/add_config_scope_zone_by_vif_name4");
        _cmds->remove_handler("pim/0.1/add_config_scope_zone_by_vif_name6");
        _cmds->remove_handler("pim/0.1/add_config_scope_zone_by_vif_addr4");
Index: xrl/targets/pim_base.hh
===================================================================
RCS file: /usr/local/www/data/cvs/xorp/xrl/targets/pim_base.hh,v
retrieving revision 1.71
diff -u -p -r1.71 pim_base.hh
--- xrl/targets/pim_base.hh     2 Oct 2008 21:58:48 -0000       1.71
+++ xrl/targets/pim_base.hh     29 Oct 2008 23:47:40 -0000
@@ -705,6 +705,13 @@ protected:
     /**
      *  Pure-virtual function that needs to be implemented to:
      *
+     *  Apply BSR configuration changes.
+     */
+    virtual XrlCmdError pim_0_1_apply_bsr_changes() = 0;
+
+    /**
+     *  Pure-virtual function that needs to be implemented to:
+     *
      *  Add/delete scope zone.
      *
      *  @param scope_zone_id the ID of the configured zone.
@@ -2174,6 +2181,8 @@ private:
 
     const XrlCmdError handle_pim_0_1_stop_bsr(const XrlArgs& in, XrlArgs* out);
 
+    const XrlCmdError handle_pim_0_1_apply_bsr_changes(const XrlArgs& in, 
XrlArgs* out);
+
     const XrlCmdError handle_pim_0_1_add_config_scope_zone_by_vif_name4(const 
XrlArgs& in, XrlArgs* out);
 
     const XrlCmdError handle_pim_0_1_add_config_scope_zone_by_vif_name6(const 
XrlArgs& in, XrlArgs* out);
_______________________________________________
Xorp-hackers mailing list
[email protected]
http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers

Reply via email to