mirror of
https://gitlab.labs.nic.cz/labs/bird.git
synced 2024-05-11 16:54:54 +00:00
Merge commit '7fb23041a52d01754c53ba963e2282e524813364' into thread-next
This commit is contained in:
@@ -701,16 +701,15 @@ switch_body: /* EMPTY */ { $$ = NULL; }
|
|||||||
| switch_body switch_items ':' cmds_scoped {
|
| switch_body switch_items ':' cmds_scoped {
|
||||||
/* Fill data fields */
|
/* Fill data fields */
|
||||||
struct f_tree *t;
|
struct f_tree *t;
|
||||||
struct f_line *line = f_linearize($4, 0);
|
|
||||||
for (t = $2; t; t = t->left)
|
for (t = $2; t; t = t->left)
|
||||||
t->data = line;
|
t->data = $4;
|
||||||
$$ = f_merge_items($1, $2);
|
$$ = f_merge_items($1, $2);
|
||||||
}
|
}
|
||||||
| switch_body ELSECOL cmds_scoped {
|
| switch_body ELSECOL cmds_scoped {
|
||||||
struct f_tree *t = f_new_tree();
|
struct f_tree *t = f_new_tree();
|
||||||
t->from.type = t->to.type = T_VOID;
|
t->from.type = t->to.type = T_VOID;
|
||||||
t->right = t;
|
t->right = t;
|
||||||
t->data = f_linearize($3, 0);
|
t->data = $3;
|
||||||
$$ = f_merge_items($1, t);
|
$$ = f_merge_items($1, t);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@@ -994,7 +993,7 @@ cmd:
|
|||||||
}
|
}
|
||||||
| function_call ';' { $$ = f_new_inst(FI_DROP_RESULT, $1); }
|
| function_call ';' { $$ = f_new_inst(FI_DROP_RESULT, $1); }
|
||||||
| CASE term '{' switch_body '}' {
|
| CASE term '{' switch_body '}' {
|
||||||
$$ = f_new_inst(FI_SWITCH, $2, build_tree($4));
|
$$ = f_new_inst(FI_SWITCH, $2, $4);
|
||||||
}
|
}
|
||||||
|
|
||||||
| symbol_known '.' EMPTY ';' { $$ = f_generate_empty($1); }
|
| symbol_known '.' EMPTY ';' { $$ = f_generate_empty($1); }
|
||||||
|
@@ -125,6 +125,7 @@ struct f_trie_walk_state
|
|||||||
struct f_tree *f_new_tree(void);
|
struct f_tree *f_new_tree(void);
|
||||||
struct f_tree *build_tree(struct f_tree *);
|
struct f_tree *build_tree(struct f_tree *);
|
||||||
const struct f_tree *find_tree(const struct f_tree *t, const struct f_val *val);
|
const struct f_tree *find_tree(const struct f_tree *t, const struct f_val *val);
|
||||||
|
const struct f_tree *find_tree_linear(const struct f_tree *t, const struct f_val *val);
|
||||||
int same_tree(const struct f_tree *t0, const struct f_tree *t2);
|
int same_tree(const struct f_tree *t0, const struct f_tree *t2);
|
||||||
int tree_node_count(const struct f_tree *t);
|
int tree_node_count(const struct f_tree *t);
|
||||||
void tree_format(const struct f_tree *t, buffer *buf);
|
void tree_format(const struct f_tree *t, buffer *buf);
|
||||||
|
@@ -1265,14 +1265,33 @@
|
|||||||
|
|
||||||
FID_MEMBER(struct f_tree *, tree, [[!same_tree(f1->tree, f2->tree)]], "tree %p", item->tree);
|
FID_MEMBER(struct f_tree *, tree, [[!same_tree(f1->tree, f2->tree)]], "tree %p", item->tree);
|
||||||
|
|
||||||
|
FID_LINEARIZE_BODY()
|
||||||
|
/* Linearize all branches in switch */
|
||||||
|
struct f_inst *last_inst = NULL;
|
||||||
|
struct f_line *last_line = NULL;
|
||||||
|
for (struct f_tree *t = whati->tree; t; t = t->left)
|
||||||
|
{
|
||||||
|
if (t->data != last_inst)
|
||||||
|
{
|
||||||
|
last_inst = t->data;
|
||||||
|
last_line = f_linearize(t->data, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
t->data = last_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Balance the tree */
|
||||||
|
item->tree = build_tree(whati->tree);
|
||||||
|
|
||||||
FID_ITERATE_BODY()
|
FID_ITERATE_BODY()
|
||||||
tree_walk(whati->tree, f_add_tree_lines, fit);
|
tree_walk(whati->tree, f_add_tree_lines, fit);
|
||||||
|
|
||||||
FID_INTERPRET_BODY()
|
FID_INTERPRET_BODY()
|
||||||
const struct f_tree *t = find_tree(tree, &v1);
|
/* In parse-time use find_tree_linear(), in runtime use find_tree() */
|
||||||
|
const struct f_tree *t = FID_HIC(,find_tree,find_tree_linear)(tree, &v1);
|
||||||
if (!t) {
|
if (!t) {
|
||||||
v1.type = T_VOID;
|
v1.type = T_VOID;
|
||||||
t = find_tree(tree, &v1);
|
t = FID_HIC(,find_tree,find_tree_linear)(tree, &v1);
|
||||||
if (!t) {
|
if (!t) {
|
||||||
debug( "No else statement?\n");
|
debug( "No else statement?\n");
|
||||||
FID_HIC(,break,return NULL);
|
FID_HIC(,break,return NULL);
|
||||||
|
@@ -38,6 +38,26 @@ find_tree(const struct f_tree *t, const struct f_val *val)
|
|||||||
return find_tree(t->left, val);
|
return find_tree(t->left, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find_tree_linear
|
||||||
|
* @t: tree to search in
|
||||||
|
* @val: value to find
|
||||||
|
*
|
||||||
|
* Search for given value in the degenerated linear tree, which is generated by
|
||||||
|
* parser before build_tree() is applied. The tree is not sorted and all nodes
|
||||||
|
* are linked by left ptr.
|
||||||
|
*/
|
||||||
|
const struct f_tree *
|
||||||
|
find_tree_linear(const struct f_tree *t, const struct f_val *val)
|
||||||
|
{
|
||||||
|
for (; t; t = t->left)
|
||||||
|
if ((val_compare(&(t->from), val) != 1) &&
|
||||||
|
(val_compare(&(t->to), val) != -1))
|
||||||
|
return t;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static struct f_tree *
|
static struct f_tree *
|
||||||
build_tree_rec(struct f_tree **buf, int l, int h)
|
build_tree_rec(struct f_tree **buf, int l, int h)
|
||||||
{
|
{
|
||||||
|
@@ -180,6 +180,7 @@ void bug(const char *msg, ...) NORET;
|
|||||||
#define L_BUG "\011" /* BIRD bugs */
|
#define L_BUG "\011" /* BIRD bugs */
|
||||||
|
|
||||||
void debug(const char *msg, ...); /* Printf to debug output */
|
void debug(const char *msg, ...); /* Printf to debug output */
|
||||||
|
void debug_safe(const char *msg); /* Printf to debug output, async-safe */
|
||||||
|
|
||||||
/* Debugging */
|
/* Debugging */
|
||||||
|
|
||||||
|
@@ -10,7 +10,7 @@ CF_HDR
|
|||||||
|
|
||||||
CF_DECLS
|
CF_DECLS
|
||||||
|
|
||||||
CF_KEYWORDS(KERNEL, TABLE)
|
CF_KEYWORDS(KERNEL, TABLE, METRIC)
|
||||||
|
|
||||||
CF_GRAMMAR
|
CF_GRAMMAR
|
||||||
|
|
||||||
@@ -25,6 +25,14 @@ kern_sys_item:
|
|||||||
|
|
||||||
THIS_KRT->sys.table_id = $3;
|
THIS_KRT->sys.table_id = $3;
|
||||||
}
|
}
|
||||||
|
| METRIC expr {
|
||||||
|
if ($2 && !krt_max_metric)
|
||||||
|
cf_error("Kernel route metric not supported");
|
||||||
|
if ($2 > krt_max_metric)
|
||||||
|
cf_error("Kernel table id must be in range 0-%u", krt_max_metric);
|
||||||
|
|
||||||
|
THIS_KRT->sys.metric = $2;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
CF_CODE
|
CF_CODE
|
||||||
|
@@ -47,6 +47,11 @@ const int rt_default_ecmp = 0;
|
|||||||
* table_id is specified explicitly as sysctl scan argument, while in FreeBSD it
|
* table_id is specified explicitly as sysctl scan argument, while in FreeBSD it
|
||||||
* is handled implicitly by changing default table using setfib() syscall.
|
* is handled implicitly by changing default table using setfib() syscall.
|
||||||
*
|
*
|
||||||
|
* OpenBSD allows to use route metric. The behavior is controlled by these macro
|
||||||
|
* KRT_USE_METRIC, which enables use of rtm_priority in route send/recevive.
|
||||||
|
* There is also KRT_DEFAULT_METRIC and KRT_MAX_METRIC for default and maximum
|
||||||
|
* metric values.
|
||||||
|
*
|
||||||
* KRT_SHARED_SOCKET - use shared kernel socked instead of one for each krt_proto
|
* KRT_SHARED_SOCKET - use shared kernel socked instead of one for each krt_proto
|
||||||
* KRT_USE_SETFIB_SCAN - use setfib() for sysctl() route scan
|
* KRT_USE_SETFIB_SCAN - use setfib() for sysctl() route scan
|
||||||
* KRT_USE_SETFIB_SOCK - use SO_SETFIB socket option for kernel sockets
|
* KRT_USE_SETFIB_SOCK - use SO_SETFIB socket option for kernel sockets
|
||||||
@@ -63,6 +68,9 @@ const int rt_default_ecmp = 0;
|
|||||||
|
|
||||||
#ifdef __OpenBSD__
|
#ifdef __OpenBSD__
|
||||||
#define KRT_MAX_TABLES (RT_TABLEID_MAX+1)
|
#define KRT_MAX_TABLES (RT_TABLEID_MAX+1)
|
||||||
|
#define KRT_USE_METRIC
|
||||||
|
#define KRT_MAX_METRIC 255
|
||||||
|
#define KRT_DEFAULT_METRIC 56
|
||||||
#define KRT_SHARED_SOCKET
|
#define KRT_SHARED_SOCKET
|
||||||
#define KRT_USE_SYSCTL_7
|
#define KRT_USE_SYSCTL_7
|
||||||
#endif
|
#endif
|
||||||
@@ -71,6 +79,14 @@ const int rt_default_ecmp = 0;
|
|||||||
#define KRT_MAX_TABLES 1
|
#define KRT_MAX_TABLES 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef KRT_MAX_METRIC
|
||||||
|
#define KRT_MAX_METRIC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef KRT_DEFAULT_METRIC
|
||||||
|
#define KRT_DEFAULT_METRIC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Dynamic max number of tables */
|
/* Dynamic max number of tables */
|
||||||
|
|
||||||
@@ -143,6 +159,10 @@ static struct krt_proto *krt_table_map[KRT_MAX_TABLES][2];
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Make it available to parser code */
|
||||||
|
const uint krt_max_metric = KRT_MAX_METRIC;
|
||||||
|
|
||||||
|
|
||||||
/* Route socket message processing */
|
/* Route socket message processing */
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -238,6 +258,10 @@ krt_send_route(struct krt_proto *p, int cmd, const rte *e)
|
|||||||
msg.rtm.rtm_tableid = KRT_CF->sys.table_id;
|
msg.rtm.rtm_tableid = KRT_CF->sys.table_id;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KRT_USE_METRIC
|
||||||
|
msg.rtm.rtm_priority = KRT_CF->sys.metric;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef RTF_REJECT
|
#ifdef RTF_REJECT
|
||||||
if(dest == RTD_UNREACHABLE)
|
if(dest == RTD_UNREACHABLE)
|
||||||
msg.rtm.rtm_flags |= RTF_REJECT;
|
msg.rtm.rtm_flags |= RTF_REJECT;
|
||||||
@@ -603,6 +627,11 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
|
|||||||
ea_set_attr(&e0.attrs,
|
ea_set_attr(&e0.attrs,
|
||||||
EA_LITERAL_EMBEDDED(&ea_krt_source, 0, src2));
|
EA_LITERAL_EMBEDDED(&ea_krt_source, 0, src2));
|
||||||
|
|
||||||
|
#ifdef KRT_USE_METRIC
|
||||||
|
ea_set_attr(&e0.attrs,
|
||||||
|
EA_LITERAL_EMBEDDED(&ea_krt_metric, 0, msg->rtm.rtm_priority));
|
||||||
|
#endif
|
||||||
|
|
||||||
if (scan)
|
if (scan)
|
||||||
krt_got_route(p, &e0, src);
|
krt_got_route(p, &e0, src);
|
||||||
else
|
else
|
||||||
@@ -1163,7 +1192,7 @@ krt_sys_shutdown(struct krt_proto *p)
|
|||||||
int
|
int
|
||||||
krt_sys_reconfigure(struct krt_proto *p UNUSED, struct krt_config *n, struct krt_config *o)
|
krt_sys_reconfigure(struct krt_proto *p UNUSED, struct krt_config *n, struct krt_config *o)
|
||||||
{
|
{
|
||||||
return n->sys.table_id == o->sys.table_id;
|
return (n->sys.table_id == o->sys.table_id) && (n->sys.metric == o->sys.metric);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1176,11 +1205,13 @@ krt_sys_preconfig(struct config *c UNUSED)
|
|||||||
void krt_sys_init_config(struct krt_config *c)
|
void krt_sys_init_config(struct krt_config *c)
|
||||||
{
|
{
|
||||||
c->sys.table_id = 0; /* Default table */
|
c->sys.table_id = 0; /* Default table */
|
||||||
|
c->sys.metric = KRT_DEFAULT_METRIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
void krt_sys_copy_config(struct krt_config *d, struct krt_config *s)
|
void krt_sys_copy_config(struct krt_config *d, struct krt_config *s)
|
||||||
{
|
{
|
||||||
d->sys.table_id = s->sys.table_id;
|
d->sys.table_id = s->sys.table_id;
|
||||||
|
d->sys.metric = s->sys.metric;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -32,9 +32,11 @@ static inline void kif_sys_copy_config(struct kif_config *d UNUSED, struct kif_c
|
|||||||
/* Kernel routes */
|
/* Kernel routes */
|
||||||
|
|
||||||
extern uint krt_max_tables;
|
extern uint krt_max_tables;
|
||||||
|
extern const uint krt_max_metric;
|
||||||
|
|
||||||
struct krt_params {
|
struct krt_params {
|
||||||
int table_id; /* Kernel table ID we sync with */
|
int table_id; /* Kernel table ID we sync with */
|
||||||
|
u32 metric; /* Kernel metric used for all routes */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct krt_state {
|
struct krt_state {
|
||||||
|
@@ -2154,6 +2154,8 @@ watchdog_sigalrm(int sig UNUSED)
|
|||||||
config->latency_limit = 0xffffffff;
|
config->latency_limit = 0xffffffff;
|
||||||
io_update_time();
|
io_update_time();
|
||||||
|
|
||||||
|
debug_safe("Watchdog timer timed out\n");
|
||||||
|
|
||||||
/* We want core dump */
|
/* We want core dump */
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
#include "lib/lists.h"
|
#include "lib/lists.h"
|
||||||
#include "sysdep/unix/unix.h"
|
#include "sysdep/unix/unix.h"
|
||||||
|
|
||||||
|
static int dbg_fd = -1;
|
||||||
static FILE *dbgf;
|
static FILE *dbgf;
|
||||||
static list *current_log_list;
|
static list *current_log_list;
|
||||||
static char *current_syslog_name; /* NULL -> syslog closed */
|
static char *current_syslog_name; /* NULL -> syslog closed */
|
||||||
@@ -341,6 +342,21 @@ debug(const char *msg, ...)
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* debug_safe - async-safe write to debug output
|
||||||
|
* @msg: a string message
|
||||||
|
*
|
||||||
|
* This function prints the message @msg to the debugging output in a
|
||||||
|
* way that is async safe and can be used in signal handlers. No newline
|
||||||
|
* character is appended.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
debug_safe(const char *msg)
|
||||||
|
{
|
||||||
|
if (dbg_fd >= 0)
|
||||||
|
write(dbg_fd, msg, strlen(msg));
|
||||||
|
}
|
||||||
|
|
||||||
static list *
|
static list *
|
||||||
default_log_list(int initial, const char **syslog_name)
|
default_log_list(int initial, const char **syslog_name)
|
||||||
{
|
{
|
||||||
@@ -441,8 +457,10 @@ log_init_debug(char *f)
|
|||||||
{
|
{
|
||||||
clock_gettime(CLOCK_MONOTONIC, &dbg_time_start);
|
clock_gettime(CLOCK_MONOTONIC, &dbg_time_start);
|
||||||
|
|
||||||
|
dbg_fd = -1;
|
||||||
if (dbgf && dbgf != stderr)
|
if (dbgf && dbgf != stderr)
|
||||||
fclose(dbgf);
|
fclose(dbgf);
|
||||||
|
|
||||||
if (!f)
|
if (!f)
|
||||||
dbgf = NULL;
|
dbgf = NULL;
|
||||||
else if (!*f)
|
else if (!*f)
|
||||||
@@ -453,6 +471,10 @@ log_init_debug(char *f)
|
|||||||
fprintf(stderr, "bird: Unable to open debug file %s: %s\n", f, strerror(errno));
|
fprintf(stderr, "bird: Unable to open debug file %s: %s\n", f, strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbgf)
|
if (dbgf)
|
||||||
|
{
|
||||||
setvbuf(dbgf, NULL, _IONBF, 0);
|
setvbuf(dbgf, NULL, _IONBF, 0);
|
||||||
|
dbg_fd = fileno(dbgf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user