enum tbf_targets {
TBF_INVALID = 0,
- TBF_OSPF_PKT,
- TBF_OSPF_LSA,
- TBF_RIP_PKT,
- TBF_RIP_RTE,
- TBF_BABEL_PKT,
+ TBF_PKT,
+ TBF_LSA,
+ TBF_RTE,
TBF_ALL
};
};
struct cmd_logging_rate_info {
- struct tbf_config *tbfc;
- struct logging_rate_targets *targets;
+ int all_protos;
+ struct tbf_config *tbfc;
+ struct logging_rate_targets *targets;
};
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)
+CF_KEYWORDS(PKT, LSA, RTE)
/* 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)
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; }
+ PKT { $$ = TBF_PKT; }
+ |LSA { $$ = TBF_LSA; }
+ |RTE { $$ = TBF_RTE; }
|ALL { $$ = TBF_ALL; }
logging_rate_targets:
struct cmd_logging_rate_info info = {
.tbfc = $6,
.targets = $5,
+ .all_protos = $4.ptr == NULL
};
proto_apply_cmd($4, proto_cmd_logging_rate, 1, (uintptr_t) &info);
};
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);
+ struct cmd_logging_rate_info *args = (struct cmd_logging_rate_info *) arg;
+ struct logging_rate_targets *targets = args->targets;
+ while (targets)
+ {
+ int rate_changed = 0;
+ if ((targets->target == TBF_PKT || targets->target == TBF_ALL) && p->tbfs.pkt)
+ {
+ p->tbfs.pkt->cf.rate = args->tbfc->rate;
+ p->tbfs.pkt->cf.burst = args->tbfc->burst;
+ rate_changed++;
+ }
+ if ((targets->target == TBF_LSA || targets->target == TBF_ALL) && p->tbfs.lsa)
+ {
+ p->tbfs.lsa->cf.rate = args->tbfc->rate;
+ p->tbfs.lsa->cf.burst = args->tbfc->burst;
+ rate_changed++;
+ }
+ if ((targets->target == TBF_RTE || targets->target == TBF_ALL) && p->tbfs.rte)
+ {
+ p->tbfs.rte->cf.rate = args->tbfc->rate;
+ p->tbfs.rte->cf.burst = args->tbfc->burst;
+ rate_changed++;
+ }
+ if (rate_changed == 0 && args->all_protos == 0)
+ {
+ if (p->tbfs.pkt || p->tbfs.lsa || p->tbfs.rte)
+ cli_msg(9002, "%s supports rated logging only for%s%s%s", p->name, p->tbfs.pkt? " PKT":"", p->tbfs.lsa? " LSA":"", p->tbfs.rte? " RTE":"");
+ else
+ cli_msg(9002, "%s does not use rated logging", p->name);
+ }
+ targets = targets->next;
+ }
}
static void
/* Protocol-specific data follow... */
};
+struct proto_tbfs
+{
+ /* Pointers to rate limiting logging structures */
+ struct tbf *pkt;
+ struct tbf *lsa;
+ struct tbf *rte;
+};
+
/* Protocol statistics */
struct proto_stats {
/* Import - from protocol to core */
btime last_state_change; /* Time of last state transition */
char *last_state_name_announced; /* Last state name we've announced to the user */
char *message; /* State-change message, allocated from proto_pool */
+ struct proto_tbfs tbfs; /* Pointers to rate limiting logging structures */
/*
* General protocol hooks:
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 */
};
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->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 };
+ P->tbfs.pkt = &p->log_pkt_tbf;
+ P->tbfs.rte = NULL;
+ P->tbfs.lsa = NULL;
return PS_UP;
}
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",
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);
| 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
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
+ P->tbfs.pkt = &p->log_pkt_tbf;
+ P->tbfs.rte = NULL;
+ P->tbfs.lsa = &p->log_lsa_tbf;
/* Lock the channel when in GR recovery mode */
if (p->p.gr_recovery && (p->gr_mode == OSPF_GR_ABLE))
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)
{
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);
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
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;
+ P->tbfs.pkt = &p->log_pkt_tbf;
+ P->tbfs.rte = &p->log_rte_tbf;
+ P->tbfs.lsa = NULL;
tm_start(p->timer, MIN(cf->min_timeout_time, cf->max_garbage_time));
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)
{
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);