]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
tbf: logging rate is settable for rtables, protocol rip, ospf and babel. It can se...
authorKaterina Kubecova <katerina.kubecova@nic.cz>
Tue, 7 May 2024 10:09:52 +0000 (12:09 +0200)
committerKaterina Kubecova <katerina.kubecova@nic.cz>
Tue, 7 May 2024 10:47:28 +0000 (12:47 +0200)
17 files changed:
conf/confbase.Y
lib/birdlib.h
lib/tbf.c
nest/config.Y
nest/proto.c
nest/protocol.h
nest/route.h
nest/rt-table.c
proto/babel/babel.c
proto/babel/babel.h
proto/babel/config.Y
proto/ospf/config.Y
proto/ospf/ospf.c
proto/ospf/ospf.h
proto/rip/config.Y
proto/rip/rip.c
proto/rip/rip.h

index ed3c1e6e117f77f2fb25ac7f27303106da89f1fe..b29abf4c1950528a1b70a3d2def6487892d72f09 100644 (file)
@@ -95,11 +95,15 @@ CF_DECLS
   btime time;
   struct f_prefix px;
   struct proto_spec ps;
+  struct table_spec ts;
   struct channel_limit cl;
   struct timeformat *tf;
   mpls_label_stack *mls;
   const struct adata *bs;
   struct aggr_item_node *ai;
+  struct logging_rate_targets *lrt;
+  struct tbf_config *tc;
+  enum tbf_targets tt;
 }
 
 %token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT
index b722641116cf4b55406b3bd3dfbbc8359fa0567b..8fba8ae458bddd8c416d97f7235da028dd99e2fc 100644 (file)
@@ -108,16 +108,46 @@ typedef s64 btime;
 
 /* Rate limiting */
 
+struct tbf_config {
+   u16 burst;                  /* Max number of tokens */
+   u16 rate;                   /* Rate of replenishment (tokens / sec) */
+ };
+
 struct tbf {
   btime timestamp;                     /* Last update */
   u64 count;                           /* Available micro-tokens */
-  u16 burst;                           /* Max number of tokens */
-  u16 rate;                            /* Rate of replenishment (tokens / sec) */
   u32 drop;                            /* Number of failed request since last successful */
+  struct tbf_config cf;                        /* Configuration */
+};
+
+enum tbf_targets {
+  TBF_INVALID = 0,
+  TBF_OSPF_PKT,
+  TBF_OSPF_LSA,
+  TBF_RIP_PKT,
+  TBF_RIP_RTE,
+  TBF_BABEL_PKT,
+  TBF_ALL
+};
+
+struct logging_rate_targets {
+  enum tbf_targets target;
+  struct logging_rate_targets *next;
+};
+
+struct cmd_logging_rate_info {
+    struct tbf_config *tbfc;
+    struct logging_rate_targets *targets;
+};
+
+
+struct table_spec {
+  const void *ptr;
+  int patt;
 };
 
 /* Default TBF values for rate limiting log messages */
-#define TBF_DEFAULT_LOG_LIMITS { .rate = 1, .burst = 5 }
+#define TBF_DEFAULT_LOG_LIMITS { .cf.rate = 1, .cf.burst = 5 }
 
 int tbf_limit(struct tbf *f);
 
index e6e84b4f9b057fc8c109ca8290a9ab4cfd161e2f..7e1cfabf1261fd173676a277feb7824bd9b0c830 100644 (file)
--- a/lib/tbf.c
+++ b/lib/tbf.c
@@ -17,8 +17,8 @@ tbf_limit(struct tbf *f)
 
   if (delta > 0)
   {
-    u64 next = f->count + delta * f->rate;
-    u64 burst = (u64) f->burst << 20;
+    u64 next = f->count + delta * f->cf.rate;
+    u64 burst = (u64) f->cf.burst << 20;
     f->count = MIN(next, burst);
     f->timestamp += delta;
   }
index 20186ece66a4bb2e992bc9e819d85ba15576eb87..a89509c97eb29a25c3ab90949cbddbc352aaae80 100644 (file)
@@ -15,6 +15,7 @@ CF_HDR
 #include "nest/mpls.h"
 #include "lib/lists.h"
 #include "lib/mac.h"
+#include "lib/birdlib.h"
 
 CF_DEFINES
 
@@ -128,6 +129,9 @@ CF_KEYWORDS(MIN, IDLE, RX, TX, INTERVAL, MULTIPLIER, PASSIVE)
 CF_KEYWORDS(CHECK, LINK)
 CF_KEYWORDS(SORTED, TRIE, MIN, MAX, SETTLE, TIME, GC, THRESHOLD, PERIOD)
 CF_KEYWORDS(MPLS_LABEL, MPLS_POLICY, MPLS_CLASS)
+CF_KEYWORDS(ASPA_PROVIDERS)
+CF_KEYWORDS(LOGGING, RATE)
+CF_KEYWORDS( OSPF_PKT, OSPF_LSA, RIP_PKT, RIP_RTE, BABEL_PKT)
 
 /* For r_args_channel */
 CF_KEYWORDS(IPV4, IPV4_MC, IPV4_MPLS, IPV6, IPV6_MC, IPV6_MPLS, IPV6_SADR, VPN4, VPN4_MC, VPN4_MPLS, VPN6, VPN6_MC, VPN6_MPLS, ROA4, ROA6, FLOW4, FLOW6, MPLS, PRI, SEC)
@@ -149,12 +153,16 @@ CF_ENUM(T_ENUM_MPLS_POLICY, MPLS_POLICY_, NONE, STATIC, PREFIX, AGGREGATE, VRF)
 %type <sd> sym_args
 %type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_mode limit_action net_type net_type_base tos password_algorithm
 %type <ps> proto_patt proto_patt2
+%type <ts> table_patt
 %type <cc> channel_start proto_channel
 %type <cl> limit_spec
 %type <net> r_args_for_val
 %type <net_ptr> r_args_for
 %type <t> channel_sym
 %type <c> channel_arg
+%type <lrt> logging_rate_targets
+%type <tc> logging_rate
+%type <tt> tbf_target
 
 CF_GRAMMAR
 
@@ -220,6 +228,8 @@ table: table_start table_sorted table_opt_list ;
 
 table_start: net_type TABLE symbol {
    this_table = rt_new_table($3, $1);
+   this_table->log_tbf_cf.rate = 1;
+   this_table->log_tbf_cf.burst = 5;
    }
  ;
 
@@ -240,6 +250,7 @@ table_opt:
  | MAX SETTLE TIME expr_us { this_table->max_settle_time = $4; }
  | GC THRESHOLD expr { this_table->gc_threshold = $3; }
  | GC PERIOD expr_us { this_table->gc_period = (uint) $3; if ($3 > 3600 S_) cf_error("GC period must be at most 3600 s"); }
+ | LOGGING RATE expr expr      { this_table->log_tbf_cf.rate = $3; this_table->log_tbf_cf.burst = $4; }
  ;
 
 table_opts:
@@ -937,6 +948,49 @@ CF_CLI_HELP(DEBUG, ..., [[Control protocol debugging via BIRD logs]])
 CF_CLI(DEBUG, debug_args, (<protocol> | <channel> | \"<pattern>\" | all) (all | off | { states|routes|filters|interfaces|events|packets [, ...] }), [[Control protocol debugging via BIRD logs]])
 { /* Done in debug_args */  };
 
+logging_rate_target: PIPE ;
+
+tbf_target:
+  OSPF_PKT { $$ = TBF_OSPF_PKT; }
+ |OSPF_LSA { $$ = TBF_OSPF_LSA; }
+ |RIP_PKT  { $$ = TBF_RIP_PKT; }
+ |RIP_RTE { $$ = TBF_RIP_RTE; }
+ |BABEL_PKT { $$ = TBF_BABEL_PKT; }
+ |ALL { $$ = TBF_ALL; }
+
+logging_rate_targets:
+  logging_rate_targets tbf_target {
+    $$ = (struct logging_rate_targets *) cfg_allocz(sizeof(struct logging_rate_targets));
+    $$->next = $1;
+    $$->target = $2;
+  } | tbf_target {
+    $$ = cfg_allocz(sizeof(struct logging_rate_targets));
+    $$->next = NULL;
+    $$->target = $1;
+  };
+
+logging_rate: expr expr
+{
+  $$ = cfg_allocz(sizeof(struct tbf_config));
+  $$->rate = $1;
+  $$->burst = $2;
+};
+
+CF_CLI(LOGGING RATE PROTOCOL, proto_patt logging_rate_targets logging_rate, (<protocol> | \"<pattern>\" | all) targets <rate> <burst>, [[Set logging rate for given protocols and targets]])
+{
+  struct cmd_logging_rate_info info = {
+    .tbfc = $6,
+    .targets = $5,
+  };
+  proto_apply_cmd($4, proto_cmd_logging_rate, 1, (uintptr_t) &info);
+};
+
+CF_CLI(LOGGING RATE TABLE, table_patt logging_rate, (<table> | \"<pattern>\" | all) <rate> <burst>, [[Set logging rate for given tables and targets]])
+{
+  table_logging_cmd($4, $5);
+};
+
+
 CF_CLI_OPT(DEBUG ALL)
 CF_CLI_OPT(DEBUG OFF)
 CF_CLI_OPT(DEBUG STATES)
@@ -970,6 +1024,12 @@ proto_patt2:
  | TEXT { $$.ptr = $1; $$.patt = 1; }
  ;
 
+table_patt:
+   CF_SYM_KNOWN { cf_assert_symbol($1, SYM_TABLE); $$.ptr = $1; $$.patt = 0; }
+ | ALL  { $$.ptr = NULL; $$.patt = 1; }
+ | TEXT { $$.ptr = $1; $$.patt = 1; }
+ ;
+
 dynamic_attr: IGP_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_GEN_IGP_METRIC); } ;
 
 dynamic_attr: MPLS_LABEL  { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_MPLS_LABEL); } ;
index 88f4813ef572de5ca5a92cd360e4ca3dbf062815..a2eb56a9fe20fd8b68161ddf10a55f5760dbe44e 100644 (file)
@@ -2280,6 +2280,15 @@ proto_cmd_mrtdump(struct proto *p, uintptr_t mask, int cnt UNUSED)
   p->mrtdump = mask;
 }
 
+void
+proto_cmd_logging_rate(struct proto *p, uintptr_t arg, int cnt UNUSED)
+{
+  if (p->set_logging_rate)
+    p->set_logging_rate(p, arg);
+  else
+    cli_msg(9002, "protocol %s does not support logging rate changes", p->name);
+}
+
 static void
 proto_apply_cmd_symbol(const struct symbol *s, void (* cmd)(struct proto *, uintptr_t, int), uintptr_t arg)
 {
index c87d38148005deaea1ced73545fb291540031335..9e70fefb0fbe44750d13a866111d7962bd037f9c 100644 (file)
@@ -243,6 +243,7 @@ struct proto {
   void (*rte_insert)(struct network *, struct rte *);
   void (*rte_remove)(struct network *, struct rte *);
   u32 (*rte_igp_metric)(struct rte *);
+  void (*set_logging_rate)(struct proto *P, uintptr_t arg);
 
   /* Hic sunt protocol-specific data */
 };
@@ -293,6 +294,7 @@ void proto_cmd_restart(struct proto *, uintptr_t, int);
 void proto_cmd_reload(struct proto *, uintptr_t, int);
 void proto_cmd_debug(struct proto *, uintptr_t, int);
 void proto_cmd_mrtdump(struct proto *, uintptr_t, int);
+void proto_cmd_logging_rate(struct proto *, uintptr_t, int);
 
 void proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uintptr_t, int), int restricted, uintptr_t arg);
 struct proto *proto_get_named(struct symbol *, struct protocol *);
index 12e85006d1e17b1afac570cd2b30568a2e20c655..53bccdd4c014aefb8a84a7094831ccc9550804f4 100644 (file)
@@ -156,6 +156,7 @@ struct rtable_config {
   byte trie_used;                      /* Rtable has attached trie */
   btime min_settle_time;               /* Minimum settle time for notifications */
   btime max_settle_time;               /* Maximum settle time for notifications */
+  struct tbf_config log_tbf_cf;                /* Config logging rate for rtable */
 };
 
 typedef struct rtable {
@@ -203,6 +204,7 @@ typedef struct rtable {
   list flowspec_links;                 /* List of flowspec links, src for NET_IPx and dst for NET_FLOWx */
   struct f_trie *flowspec_trie;                /* Trie for evaluation of flowspec notifications */
   // struct mpls_domain *mpls_domain;  /* Label allocator for MPLS */
+  struct tbf log_tbf;                  /* Actual logging rate for rtable (might be changed in cmd) */
 } rtable;
 
 struct rt_subscription {
@@ -719,6 +721,8 @@ void rta_dump(rta *);
 void rta_dump_all(void);
 void rta_show(struct cli *, rta *);
 
+void table_logging_cmd(struct table_spec ts, struct tbf_config *rate);
+
 u32 rt_get_igp_metric(rte *rt);
 struct hostentry * rt_get_hostentry(rtable *tab, ip_addr a, ip_addr ll, rtable *dep);
 void rta_apply_hostentry(rta *a, struct hostentry *he, mpls_label_stack *mls);
index 1b30e7dc794e84a4ea994e66ad94d774d10952cb..81104673c6394e7607a14be3a362ff5e67f71eef 100644 (file)
 #include "lib/string.h"
 #include "lib/alloca.h"
 #include "lib/flowspec.h"
+#include "nest/cli.h"
 
 #ifdef CONFIG_BGP
 #include "proto/bgp/bgp.h"
@@ -1029,7 +1030,6 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
   struct proto *p = c->proto;
   struct rtable *table = c->table;
   struct proto_stats *stats = &c->stats;
-  static struct tbf rl_pipe = TBF_DEFAULT_LOG_LIMITS;
   rte *before_old = NULL;
   rte *old_best = net->routes;
   rte *old = NULL;
@@ -1053,7 +1053,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
            {
              if (new)
                {
-                 log_rl(&rl_pipe, L_ERR "Pipe collision detected when sending %N to table %s",
+                 log_rl(&table->log_tbf, L_ERR "Pipe collision detected when sending %N to table %s",
                      net->n.addr, table->name);
                  rte_free_quick(new);
                }
@@ -1960,6 +1960,8 @@ rt_setup(pool *pp, struct rtable_config *cf)
   t->config = cf;
   t->addr_type = cf->addr_type;
   t->debug = cf->debug;
+  t->log_tbf.cf.rate = cf->log_tbf_cf.rate;
+  t->log_tbf.cf.burst = cf->log_tbf_cf.burst;
 
   fib_init(&t->fib, p, t->addr_type, sizeof(net), OFFSETOF(net, n), 0, NULL);
 
@@ -2731,6 +2733,8 @@ rt_reconfigure(rtable *tab, struct rtable_config *new, struct rtable_config *old
   tab->name = new->name;
   tab->config = new;
   tab->debug = new->debug;
+  tab->log_tbf.cf.rate = new->log_tbf_cf.rate;
+  tab->log_tbf.cf.burst = new->log_tbf_cf.burst;
 
   return 1;
 }
@@ -3482,6 +3486,47 @@ rt_get_hostentry(rtable *tab, ip_addr a, ip_addr ll, rtable *dep)
   return he;
 }
 
+void
+cmd_logging_rate(rtable *table, struct tbf_config *rate)
+{
+  table->log_tbf.cf.rate = rate->rate;
+  table->log_tbf.cf.burst = rate->burst;
+}
+
+void
+table_logging_cmd(struct table_spec ts, struct tbf_config *rate)
+{
+  if (ts.patt)
+  {
+    const char *patt = (void *) ts.ptr;
+    int cnt = 0;
+    rtable *t;
+    node *n;
+
+    WALK_LIST2(t, n, routing_tables, n)
+      if (!ts.ptr || patmatch(patt, t->name))
+      {
+        cmd_logging_rate(t, rate);
+        cnt++;
+      }
+
+    if (!cnt)
+      cli_msg(8003, "No tables match");
+    else
+      cli_msg(0, "");
+  }
+  else
+  {
+    const struct symbol *s = (struct symbol*) ts.ptr;
+    if (s->table->table)
+    {
+      cmd_logging_rate(s->table->table, rate);
+      cli_msg(0, "");
+    }
+    else
+      cli_msg(9002, "%s does not exist", s->name);
+  }
+}
 
 /*
  *  Documentation for functions declared inline in route.h
index 4187d258aa3b596f710217d2c8500909c8d1b2dc..7508a5e67eed710e17a6b8ff8e6ccd5b80c93c8c 100644 (file)
@@ -2582,7 +2582,8 @@ babel_start(struct proto *P)
   p->msg_slab = sl_new(P->pool, sizeof(struct babel_msg_node));
   p->seqno_slab = sl_new(P->pool, sizeof(struct babel_seqno_request));
 
-  p->log_pkt_tbf = (struct tbf){ .rate = 1, .burst = 5 };
+  P->set_logging_rate = babel_set_logging_rate;
+  p->log_pkt_tbf = (struct tbf){ .cf.rate = cf->log_pkt_tbf.rate, .cf.burst = cf->log_pkt_tbf.burst };
 
   return PS_UP;
 }
@@ -2634,6 +2635,8 @@ babel_reconfigure(struct proto *P, struct proto_config *CF)
 
   p->p.cf = CF;
   babel_reconfigure_ifaces(p, new);
+  p->log_pkt_tbf.cf.rate = new->log_pkt_tbf.rate;
+  p->log_pkt_tbf.cf.burst = new->log_pkt_tbf.burst;
 
   babel_trigger_update(p);
   babel_kick_timer(p);
@@ -2641,6 +2644,26 @@ babel_reconfigure(struct proto *P, struct proto_config *CF)
   return 1;
 }
 
+void
+babel_set_logging_rate(struct proto *P, uintptr_t arg)
+{
+  struct babel_proto *p = (void *) P;
+  struct cmd_logging_rate_info *info = (struct cmd_logging_rate_info*) arg;
+  struct logging_rate_targets *targets = info->targets;
+  while (targets)
+  {
+    if (targets->target == TBF_BABEL_PKT || targets->target == TBF_ALL)
+    {
+      p->log_pkt_tbf.cf.rate = info->tbfc->rate;
+      p->log_pkt_tbf.cf.burst = info->tbfc->burst;
+    }
+    else
+      cli_msg(9002, "protocol %s: wrong logging rate change type for babel protocol", P->name);
+    targets = targets->next;
+  }
+}
+
+
 
 struct protocol proto_babel = {
   .name =              "Babel",
index edde4cabe6b13a00be914fbf349de955f34bdb60..65e9c9035d8cebfb844e1cf4d61c771cbc0e3185 100644 (file)
@@ -136,6 +136,8 @@ struct babel_config {
 
   struct channel_config *ip4_channel;
   struct channel_config *ip6_channel;
+
+  struct tbf_config log_pkt_tbf;
 };
 
 struct babel_iface_config {
@@ -455,6 +457,7 @@ void babel_show_routes(struct proto *P);
 
 void babel_auth_reset_index(struct babel_iface *ifa);
 int babel_auth_check_pc(struct babel_iface *ifa, struct babel_msg_auth *msg);
+void babel_set_logging_rate(struct proto *P, uintptr_t arg);
 
 /* packets.c */
 void babel_enqueue(union babel_msg *msg, struct babel_iface *ifa);
index d412a54b575feca507438e9807739052a92f1daa..23fd7f792cbe0a3b4857ef271ac0717a3e328bd1 100644 (file)
@@ -26,7 +26,8 @@ CF_KEYWORDS(BABEL, INTERFACE, METRIC, RXCOST, HELLO, UPDATE, INTERVAL, PORT,
        TYPE, WIRED, WIRELESS, RX, TX, BUFFER, PRIORITY, LENGTH, CHECK, LINK,
        NEXT, HOP, IPV4, IPV6, BABEL_METRIC, SHOW, INTERFACES, NEIGHBORS,
        ENTRIES, RANDOMIZE, ROUTER, ID, AUTHENTICATION, NONE, MAC, PERMISSIVE,
-       EXTENDED, TUNNEL, RTT, MIN, MAX, DECAY, SEND, TIMESTAMPS, COST, DELAY)
+       EXTENDED, TUNNEL, RTT, MIN, MAX, DECAY, SEND, TIMESTAMPS, COST, DELAY,
+       PKT, LOGGING, RATE, BURST)
 
 CF_GRAMMAR
 
@@ -37,6 +38,8 @@ babel_proto_start: proto_start BABEL
   this_proto = proto_config_new(&proto_babel, $1);
   init_list(&BABEL_CFG->iface_list);
   BABEL_CFG->hold_time = 1 S_;
+  BABEL_CFG->log_pkt_tbf.rate = 1;
+  BABEL_CFG->log_pkt_tbf.burst = 5;
 };
 
 babel_proto_item:
@@ -44,6 +47,7 @@ babel_proto_item:
  | proto_channel
  | INTERFACE babel_iface
  | RANDOMIZE ROUTER ID bool { BABEL_CFG->randomize_router_id = $4; }
+ | LOGGING RATE PKT expr expr  { BABEL_CFG->log_pkt_tbf.rate = $4; BABEL_CFG->log_pkt_tbf.burst = $5; }
  ;
 
 babel_proto_opts:
index 7d35304a6bbf92cbc771c189f56155796ca98a29..a193c2bacbf20e4cdd8b8d016d798f34c9241d16 100644 (file)
@@ -202,6 +202,7 @@ CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT, NSSA, TRANSLATOR, STABILITY
 CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF, INSTANCE, REAL, NETMASK, TX, PRIORITY, LENGTH)
 CF_KEYWORDS(MERGE, LSA, SUPPRESSION, MULTICAST, RFC5838, VPN, PE, ADDRESS)
 CF_KEYWORDS(GRACEFUL, RESTART, AWARE, TIME)
+CF_KEYWORDS(PKT, LSA, LOGGING, RATE, BURST)
 
 %type <ld> lsadb_args
 %type <i> ospf_variant ospf_af_mc nbma_eligible
@@ -230,6 +231,10 @@ ospf_proto_start: proto_start ospf_variant
   OSPF_CFG->af_ext = !$2;
   OSPF_CFG->gr_mode = OSPF_GR_AWARE;
   OSPF_CFG->gr_time = OSPF_DEFAULT_GR_TIME;
+  OSPF_CFG->log_pkt_tbf.rate = 1;
+  OSPF_CFG->log_lsa_tbf.rate = 4;
+  OSPF_CFG->log_pkt_tbf.burst = 5;
+  OSPF_CFG->log_lsa_tbf.burst = 20;
 };
 
 ospf_proto:
@@ -270,6 +275,8 @@ ospf_proto_item:
  | TICK expr { OSPF_CFG->tick = $2; if($2 <= 0) cf_error("Tick must be greater than zero"); }
  | INSTANCE ID expr { OSPF_CFG->instance_id = $3; OSPF_CFG->instance_id_set = 1; if ($3 > 255) cf_error("Instance ID must be in range 0-255"); }
  | ospf_area
+ | LOGGING RATE PKT expr expr  { OSPF_CFG->log_pkt_tbf.rate = $4; OSPF_CFG->log_pkt_tbf.burst = $5; }
+ | LOGGING RATE LSA expr expr  { OSPF_CFG->log_lsa_tbf.rate = $4; OSPF_CFG->log_lsa_tbf.burst = $4; }
  ;
 
 ospf_area_start: AREA idval {
@@ -568,6 +575,8 @@ lsadb_args:
  | lsadb_args CF_SYM_KNOWN { cf_assert_symbol($2, SYM_PROTO); $$ = $1; $$->proto = (struct ospf_proto *) proto_get_named($2, &proto_ospf); }
  ;
 
+logging_rate_target: OSPF_PKT | OSPF_LSA ;
+
 CF_CODE
 
 CF_END
index ad4b2d14ddcb73bce601848e6b1b40cc87a8ad56..0a133bfcd84b440c98d2a02dcd474a64adb79399 100644 (file)
@@ -311,8 +311,9 @@ ospf_start(struct proto *P)
 
   p->flood_event = ev_new_init(P->pool, ospf_flood_event, p);
 
-  p->log_pkt_tbf = (struct tbf){ .rate = 1, .burst = 5 };
-  p->log_lsa_tbf = (struct tbf){ .rate = 4, .burst = 20 };
+  p->log_pkt_tbf = (struct tbf){ .cf.rate = c->log_pkt_tbf.rate, .cf.burst = c->log_pkt_tbf.burst };
+  p->log_lsa_tbf = (struct tbf){ .cf.rate = c->log_lsa_tbf.rate, .cf.burst = c->log_lsa_tbf.burst };
+  P->set_logging_rate = ospf_set_logging_rate; // for setting logging tbf temporarily from cmd
 
   /* Lock the channel when in GR recovery mode */
   if (p->p.gr_recovery && (p->gr_mode == OSPF_GR_ABLE))
@@ -773,6 +774,30 @@ ospf_reconfigure(struct proto *P, struct proto_config *CF)
   return 1;
 }
 
+void
+ospf_set_logging_rate(struct proto *P, uintptr_t arg)
+{
+  struct ospf_proto *p = (void *) P;
+  struct cmd_logging_rate_info *info = (struct cmd_logging_rate_info*) arg;
+  struct logging_rate_targets *targets = info->targets;
+  while (targets)
+  {
+    if (targets->target == TBF_OSPF_PKT || targets->target == TBF_ALL)
+    {
+      p->log_pkt_tbf.cf.rate = info->tbfc->rate;
+      p->log_pkt_tbf.cf.burst = info->tbfc->burst;
+    }
+    else if (targets->target == TBF_OSPF_LSA || targets->target == TBF_ALL)
+    {
+      p->log_lsa_tbf.cf.rate = info->tbfc->rate;
+      p->log_lsa_tbf.cf.burst = info->tbfc->burst;
+    }
+    else
+      cli_msg(9002, "protocol %s: wrong logging rate change type for ospf protocol", P->name);
+    targets = targets->next;
+  }
+}
+
 
 void
 ospf_sh_neigh(struct proto *P, const char *iff)
index 3e704ae82e8dc95328ee55fb18c63ec8b59da7de..ccf842c6552cf7d053ed1b461d8e02e551ee11f4 100644 (file)
@@ -106,6 +106,8 @@ struct ospf_config
   uint ecmp;
   list area_list;              /* list of area configs (struct ospf_area_config) */
   list vlink_list;             /* list of configured vlinks (struct ospf_iface_patt) */
+  struct tbf_config log_pkt_tbf;
+  struct tbf_config log_lsa_tbf;
 };
 
 struct ospf_area_config
@@ -1021,6 +1023,7 @@ void ospf_iface_remove(struct ospf_iface *ifa);
 void ospf_iface_shutdown(struct ospf_iface *ifa);
 int ospf_iface_assure_bufsize(struct ospf_iface *ifa, uint plen);
 int ospf_iface_reconfigure(struct ospf_iface *ifa, struct ospf_iface_patt *new);
+void ospf_set_logging_rate(struct proto *P, uintptr_t arg);
 void ospf_reconfigure_ifaces(struct ospf_proto *p);
 void ospf_open_vlink_sk(struct ospf_proto *p);
 struct nbma_node *find_nbma_node_(list *nnl, ip_addr ip);
index 44f2742cf9d09804b0d416232387944fa186b58d..84b0f49d8f02e2fb01b29192bf83b9e9d6d98f5c 100644 (file)
@@ -38,7 +38,7 @@ CF_KEYWORDS(RIP, ECMP, LIMIT, WEIGHT, INFINITY, METRIC, UPDATE, TIMEOUT,
            PASSIVE, VERSION, SPLIT, HORIZON, POISON, REVERSE, CHECK, ZERO,
            TIME, BFD, AUTHENTICATION, NONE, PLAINTEXT, CRYPTOGRAPHIC, MD5,
            TTL, SECURITY, RX, TX, BUFFER, LENGTH, PRIORITY, ONLY, LINK,
-           DEMAND, CIRCUIT, RIP_METRIC, RIP_TAG)
+           DEMAND, CIRCUIT, RIP_METRIC, RIP_TAG, PKT, RTE, LOGGING, RATE, BURST)
 
 %type <i> rip_variant rip_auth
 
@@ -62,6 +62,10 @@ rip_proto_start: proto_start rip_variant
   RIP_CFG->infinity = RIP_DEFAULT_INFINITY;
   RIP_CFG->min_timeout_time = 60 S_;
   RIP_CFG->max_garbage_time = 60 S_;
+  RIP_CFG->log_pkt_tbf.rate = 1;
+  RIP_CFG->log_rte_tbf.rate = 4;
+  RIP_CFG->log_pkt_tbf.burst = 5;
+  RIP_CFG->log_rte_tbf.burst = 20;
 };
 
 rip_proto_item:
@@ -71,6 +75,8 @@ rip_proto_item:
  | ECMP bool LIMIT expr        { RIP_CFG->ecmp = $2 ? $4 : 0; }
  | INFINITY expr       { RIP_CFG->infinity = $2; }
  | INTERFACE rip_iface
+ | LOGGING RATE PKT expr expr  { RIP_CFG->log_pkt_tbf.rate = $4; RIP_CFG->log_pkt_tbf.burst = $5; }
+ | LOGGING RATE RTE expr expr  { RIP_CFG->log_rte_tbf.rate = $4; RIP_CFG->log_rte_tbf.burst = $4; }
  ;
 
 rip_proto_opts:
@@ -202,6 +208,8 @@ CF_CLI(SHOW RIP INTERFACES, optproto opttext, [<name>] [\"<interface>\"], [[Show
 CF_CLI(SHOW RIP NEIGHBORS, optproto opttext, [<name>] [\"<interface>\"], [[Show information about RIP neighbors]])
 { PROTO_WALK_CMD($4, &proto_rip, p) rip_show_neighbors(p, $5); };
 
+logging_rate_target: RIP_PKT | RIP_RTE ;
+
 
 CF_CODE
 
index 4bfb57561be93ac200b020a5125f3317b1f24bc9..d4c8eaa0ebc752eefa92c9bc74cb418ab16b4276 100644 (file)
@@ -1161,8 +1161,9 @@ rip_start(struct proto *P)
   p->infinity = cf->infinity;
   p->triggered = 0;
 
-  p->log_pkt_tbf = (struct tbf){ .rate = 1, .burst = 5 };
-  p->log_rte_tbf = (struct tbf){ .rate = 4, .burst = 20 };
+  p->log_pkt_tbf = (struct tbf){ .cf.rate = cf->log_pkt_tbf.rate, .cf.burst = cf->log_pkt_tbf.burst };
+  p->log_rte_tbf = (struct tbf){ .cf.rate = cf->log_rte_tbf.rate, .cf.burst = cf->log_pkt_tbf.burst };
+  P->set_logging_rate = rip_set_logging_rate;
 
   tm_start(p->timer, MIN(cf->min_timeout_time, cf->max_garbage_time));
 
@@ -1204,6 +1205,10 @@ rip_reconfigure(struct proto *P, struct proto_config *CF)
   p->p.cf = CF;
   p->ecmp = new->ecmp;
   rip_reconfigure_ifaces(p, new);
+  p->log_pkt_tbf.cf.rate = new->log_pkt_tbf.rate;
+  p->log_pkt_tbf.cf.burst = new->log_pkt_tbf.burst;
+  p->log_rte_tbf.cf.rate = new->log_rte_tbf.rate;
+  p->log_rte_tbf.cf.burst = new->log_rte_tbf.burst;
 
   p->rt_reload = 1;
   rip_kick_timer(p);
@@ -1211,6 +1216,30 @@ rip_reconfigure(struct proto *P, struct proto_config *CF)
   return 1;
 }
 
+void
+rip_set_logging_rate(struct proto *P, uintptr_t arg)
+{
+  struct rip_proto *p = (void *) P;
+  struct cmd_logging_rate_info *info = (struct cmd_logging_rate_info*) arg;
+  struct logging_rate_targets *targets = info->targets;
+  while (targets)
+  {
+    if (targets->target == TBF_RIP_PKT || targets->target == TBF_ALL)
+    {
+      p->log_pkt_tbf.cf.rate = info->tbfc->rate;
+      p->log_pkt_tbf.cf.burst = info->tbfc->burst;
+    }
+    else if (targets->target == TBF_RIP_RTE || targets->target == TBF_ALL)
+    {
+      p->log_rte_tbf.cf.rate = info->tbfc->rate;
+      p->log_rte_tbf.cf.burst = info->tbfc->burst;
+    }
+    else
+      cli_msg(9002, "protocol %s: wrong logging rate change type for rip protocol", P->name);
+    targets = targets->next;
+  }
+}
+
 static void
 rip_get_route_info(rte *rte, byte *buf)
 {
index f8713c4a76c72890ccb439ef25d84d2acecd83b9..c8d174d9c1d221bbb54ec2b6e5a573be7618f071 100644 (file)
@@ -55,6 +55,8 @@ struct rip_config
 
   btime min_timeout_time;              /* Minimum of interface timeout_time */
   btime max_garbage_time;              /* Maximum of interface garbage_time */
+  struct tbf_config log_pkt_tbf;
+  struct tbf_config log_rte_tbf;
 };
 
 struct rip_iface_config
@@ -224,6 +226,7 @@ struct rip_neighbor * rip_get_neighbor(struct rip_proto *p, ip_addr *a, struct r
 void rip_update_bfd(struct rip_proto *p, struct rip_neighbor *n);
 void rip_show_interfaces(struct proto *P, const char *iff);
 void rip_show_neighbors(struct proto *P, const char *iff);
+void rip_set_logging_rate(struct proto *P, uintptr_t arg);
 
 /* packets.c */
 void rip_send_request(struct rip_proto *p, struct rip_iface *ifa);