]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Finishes 'route reload' feature.
authorOndrej Zajicek <santiago@crfreenet.org>
Mon, 14 Dec 2009 00:32:37 +0000 (01:32 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Mon, 14 Dec 2009 00:32:37 +0000 (01:32 +0100)
doc/bird.sgml
doc/reply_codes
nest/config.Y
nest/proto.c
nest/protocol.h
nest/rt-table.c

index 1f494cce99f92eb6f7381986a4b98d6b161a7065..3905a29ee010a8555e239ebc2a899cbb669c3ad3 100644 (file)
@@ -497,6 +497,24 @@ This argument can be omitted if there exists only a single instance.
        <tag>enable|disable|restart <m/name/|"<m/pattern/"|all</tag>
        Enable, disable or restart a given protocol instance, instances matching the <cf><m/pattern/</cf> or <cf/all/ instances.
 
+       <tag>reload [in|out] <m/name/|"<m/pattern/"|all</tag>
+       
+       Reload a given protocol instance, that means re-import routes
+       from the protocol instance and re-export preferred routes to
+       the instance. If <cf/in/ or <cf/out/ options are used, the
+       command is restricted to one direction (re-import or
+       re-export).
+
+       This command is useful if appropriate filters have changed but
+       the protocol instance was not restarted (or reloaded),
+       therefore it still propagates the old set of routes. For example
+       when <cf/configure soft/ command was used to change filters.
+
+       Re-export always succeeds, but re-import is protocol-dependent
+       and might fail (for example, if BGP neighbor does not support
+       route-refresh extension). In that case, re-export is also
+       skipped.
+
        <tag/down/
        Shut BIRD down.
 
index e4330a2e0b3442cb85b26576d37fb9ed7314eeae..4588182b6b88db01726f95a68c2808e8b54618ac 100644 (file)
@@ -23,6 +23,7 @@ Reply codes of BIRD command-line interface
 0012   Restarted
 0013   Status report
 0014   Route count
+0015   Reloading
 
 1000   BIRD version
 1001   Interface list
@@ -40,6 +41,7 @@ Reply codes of BIRD command-line interface
 1013   Show ospf neighbors
 1014   Show ospf
 1015   Show ospf interface
+1016   Show ospf state/topology
 
 8000   Reply too long
 8001   Route not found
@@ -47,6 +49,7 @@ Reply codes of BIRD command-line interface
 8003   No protocols match
 8004   Stopped due to reconfiguration
 8005   Protocol is down => cannot dump
+8006   Reload failed
 
 9000   Command too long
 9001   Parse error
index dde20c5a803d49849c264b81f27c916de15b2ddf..dbb10adabe460042e0a9f9a65ad5da65ec27cb9a 100644 (file)
@@ -45,7 +45,7 @@ CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILT
 CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
 CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE)
 CF_KEYWORDS(LISTEN, BGP, V6ONLY, ADDRESS, PORT, PASSWORDS, DESCRIPTION)
-CF_KEYWORDS(RELOAD, REFEED)
+CF_KEYWORDS(RELOAD, IN, OUT)
 
 CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
        RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE)
@@ -438,17 +438,17 @@ echo_size:
  ;
 
 CF_CLI(DISABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Disable protocol]])
-{ proto_xxable($2, 0); } ;
+{ proto_xxable($2, XX_DISABLE); } ;
 CF_CLI(ENABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Enable protocol]])
-{ proto_xxable($2, 1); } ;
+{ proto_xxable($2, XX_ENABLE); } ;
 CF_CLI(RESTART, proto_patt, <protocol> | \"<pattern>\" | all, [[Restart protocol]])
-{ proto_xxable($2, 2); } ;
+{ proto_xxable($2, XX_RESTART); } ;
 CF_CLI(RELOAD, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol]])
-{ proto_xxable($2, 3); } ;
-CF_CLI(REFEED, proto_patt, <protocol> | \"<pattern>\" | all, [[Refeed protocol BROKEN]])
-{ proto_xxable($2, 4); } ;
-
-
+{ proto_xxable($2, XX_RELOAD); } ;
+CF_CLI(RELOAD IN, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just imported routes)]])
+{ proto_xxable($3, XX_RELOAD_IN); } ;
+CF_CLI(RELOAD OUT, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just exported routes)]])
+{ proto_xxable($3, XX_RELOAD_OUT); } ;
 
 CF_CLI_HELP(DEBUG, ..., [[Control protocol debugging]])
 CF_CLI(DEBUG, proto_patt debug_mask, (<protocol> | <pattern> | all) (all | off | { states | routes | filters | events | packets }), [[Control protocol debugging]])
index b23011d75ff3260fbc261b40f854983f3c67f3e9..4f352a6fbe532a356953368356d9673fa71dad5b 100644 (file)
@@ -586,6 +586,11 @@ proto_schedule_feed(struct proto *p, int initial)
   DBG("%s: Scheduling meal\n", p->name);
   p->core_state = FS_FEEDING;
   p->refeeding = !initial;
+
+  /* Hack: reset exp_routes during refeed, and do not decrease it later */
+  if (!initial)
+    p->stats.exp_routes = 0;
+
   proto_relink(p);
   p->attn->hook = initial ? proto_feed_initial : proto_feed_more;
   ev_schedule(p->attn);
@@ -825,7 +830,7 @@ proto_xxable(char *pattern, int xx)
        cnt++;
        switch (xx)
          {
-         case 0:
+         case XX_DISABLE:
            if (p->disabled)
              cli_msg(-8, "%s: already disabled", p->name);
            else
@@ -835,7 +840,8 @@ proto_xxable(char *pattern, int xx)
                proto_rethink_goal(p);
              }
            break;
-         case 1:
+
+         case XX_ENABLE:
            if (!p->disabled)
              cli_msg(-10, "%s: already enabled", p->name);
            else
@@ -845,7 +851,8 @@ proto_xxable(char *pattern, int xx)
                proto_rethink_goal(p);
              }
            break;
-         case 2:
+
+         case XX_RESTART:
            if (p->disabled)
              cli_msg(-8, "%s: already disabled", p->name);
            else
@@ -857,24 +864,29 @@ proto_xxable(char *pattern, int xx)
                cli_msg(-12, "%s: restarted", p->name);
              }
            break;
-         case 3:
-           // FIXME change msg number
-           if (p->disabled)
-             cli_msg(-8, "%s: already disabled", p->name);
-           else if (p->reload_routes && p->reload_routes(p))
-             cli_msg(-12, "%s: reloading", p->name);
-           else
-             cli_msg(-12, "%s: reload failed", p->name);
-           break;
-         case 4:
-           // FIXME change msg number
+
+         case XX_RELOAD:
+         case XX_RELOAD_IN:
+         case XX_RELOAD_OUT:
            if (p->disabled)
-             cli_msg(-8, "%s: already disabled", p->name);
-           else
              {
-               proto_request_feeding(p);
-               cli_msg(-12, "%s: reexport failed", p->name);
+               cli_msg(-8, "%s: already disabled", p->name);
+               break;
              }
+
+           /* re-importing routes */
+           if (xx != XX_RELOAD_OUT)
+             if (! (p->reload_routes && p->reload_routes(p)))
+               {
+                 cli_msg(-8006, "%s: reload failed", p->name);
+                 break;
+               }
+                
+           /* re-exporting routes */
+           if (xx != XX_RELOAD_IN)
+             proto_request_feeding(p);
+
+           cli_msg(-15, "%s: reloading", p->name);
            break;
 
          default:
index e1adc525c97e42cefca08525186a8705b899ab42..21a1c1b438ea49c73f2b0dc6d267bd82f47a245f 100644 (file)
@@ -201,6 +201,13 @@ struct proto *proto_get_named(struct symbol *, struct protocol *);
 void proto_xxable(char *, int);
 void proto_debug(char *, unsigned int);
 
+#define XX_DISABLE     0
+#define XX_ENABLE      1
+#define XX_RESTART     2
+#define XX_RELOAD      3
+#define XX_RELOAD_IN   4
+#define XX_RELOAD_OUT  5
+
 static inline u32
 proto_get_router_id(struct proto_config *pc)
 {
index 8efc0a618dd0ccd6b973849c132c4f412ec564eb..df2834a615d54667e46ef51f200056fb42917860 100644 (file)
@@ -165,6 +165,8 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old,
   rte *old0 = old;
   int ok;
 
+  int fast_exit_hack = 0;
+
   if (new)
     {
       p->stats.exp_updates_received++;
@@ -174,6 +176,7 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old,
        {
          p->stats.exp_updates_rejected++;
          drop_reason = "out of scope";
+         fast_exit_hack = 1;
        }
       else if ((ok = p->import_control ? p->import_control(p, &new, &tmpa, rte_update_pool) : 0) < 0)
        {
@@ -199,6 +202,11 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old,
   else
     p->stats.exp_withdraws_received++;
 
+  /* Hack: This is here to prevent 'spurious withdraws'
+     for loopback addresses during reload. */
+  if (fast_exit_hack)
+    return;
+
   /*
    * This is a tricky part - we don't know whether route 'old' was
    * exported to protocol 'p' or was filtered by the export filter.
@@ -245,9 +253,11 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old,
   else
     p->stats.exp_withdraws_accepted++;
 
+  /* Hack: We do not decrease exp_routes during refeed, we instead
+     reset exp_routes at the start of refeed. */
   if (new)
     p->stats.exp_routes++;
-  if (old)
+  if (old && !refeed)
     p->stats.exp_routes--;
 
   if (p->debug & D_ROUTES)