Line | Count | Source |
1 | | // SPDX-License-Identifier: ISC |
2 | | /* |
3 | | * FRR switchable defaults. |
4 | | * Copyright (C) 2017-2019 David Lamparter for NetDEF, Inc. |
5 | | */ |
6 | | |
7 | | #ifndef _FRR_DEFAULTS_H |
8 | | #define _FRR_DEFAULTS_H |
9 | | |
10 | | #include <stdbool.h> |
11 | | |
12 | | #include "compiler.h" |
13 | | |
14 | | #ifdef __cplusplus |
15 | | extern "C" { |
16 | | #endif |
17 | | |
18 | | /* frr_default wraps information about a default that has different |
19 | | * values depending on FRR version or default-set |
20 | | * |
21 | | * frr_default_entry describes one match rule and the resulting value; |
22 | | * entries are evaluated in order and the first matching is used. |
23 | | * |
24 | | * If both match_version and match_profile are specified, they must both |
25 | | * match. A NULL value matches everything. |
26 | | */ |
27 | | struct frr_default_entry { |
28 | | /* syntax: "(<|<=|==|>=|>) [whitespace] version", e.g. |
29 | | * ">= 6.1-dev" "<6.0" |
30 | | */ |
31 | | const char *match_version; |
32 | | /* exact profile string to compare against */ |
33 | | const char *match_profile; |
34 | | |
35 | | /* value to use */ |
36 | | bool val_bool; |
37 | | const char *val_str; |
38 | | long val_long; |
39 | | unsigned long val_ulong; |
40 | | float val_float; |
41 | | }; |
42 | | |
43 | | /* one struct frr_default exists for each malleable default value */ |
44 | | struct frr_default { |
45 | | struct frr_default *next; |
46 | | |
47 | | /* for UI/debug use */ |
48 | | const char *name; |
49 | | |
50 | | /* the following two sets of variables differ because the written |
51 | | * config always targets the *current* FRR version |
52 | | * |
53 | | * e.g. if you load a config that has "frr version 5.0" on 6.0 |
54 | | * *dflt_long => set to the default value in 5.0 |
55 | | * *save_long => set to the default value in 6.0 |
56 | | * config save will write "frr version 6.0" with 6.0 defaults |
57 | | */ |
58 | | |
59 | | /* variable holding the default value for reading/use */ |
60 | | bool *dflt_bool; |
61 | | const char **dflt_str; |
62 | | long *dflt_long; |
63 | | unsigned long *dflt_ulong; |
64 | | float *dflt_float; |
65 | | |
66 | | /* variable to use when comparing for config save */ |
67 | | bool *save_bool; |
68 | | const char **save_str; |
69 | | long *save_long; |
70 | | unsigned long *save_ulong; |
71 | | float *save_float; |
72 | | |
73 | | struct frr_default_entry entries[]; |
74 | | }; |
75 | | |
76 | | #define _FRR_CFG_DEFAULT(type, typname, varname, ...) \ |
77 | | static type DFLT_##varname; \ |
78 | | static type SAVE_##varname; \ |
79 | | static struct frr_default _dflt_##varname = { \ |
80 | | .name = #varname, \ |
81 | | .dflt_##typname = &DFLT_##varname, \ |
82 | | .save_##typname = &SAVE_##varname, \ |
83 | | .entries = { __VA_ARGS__ }, \ |
84 | | }; \ |
85 | | static void _dfltinit_##varname(void) \ |
86 | | __attribute__((_CONSTRUCTOR(1000))); \ |
87 | | static void _dfltinit_##varname(void) \ |
88 | 26 | { \ |
89 | 26 | frr_default_add(&_dflt_##varname); \ |
90 | 26 | } \ ospf_vty.c:_dfltinit_OSPF_LOG_ADJACENCY_CHANGES Line | Count | Source | 88 | 2 | { \ | 89 | 2 | frr_default_add(&_dflt_##varname); \ | 90 | 2 | } \ |
bgp_vty.c:_dfltinit_BGP_IMPORT_CHECK Line | Count | Source | 88 | 2 | { \ | 89 | 2 | frr_default_add(&_dflt_##varname); \ | 90 | 2 | } \ |
bgp_vty.c:_dfltinit_BGP_SHOW_HOSTNAME Line | Count | Source | 88 | 2 | { \ | 89 | 2 | frr_default_add(&_dflt_##varname); \ | 90 | 2 | } \ |
bgp_vty.c:_dfltinit_BGP_SHOW_NEXTHOP_HOSTNAME Line | Count | Source | 88 | 2 | { \ | 89 | 2 | frr_default_add(&_dflt_##varname); \ | 90 | 2 | } \ |
bgp_vty.c:_dfltinit_BGP_LOG_NEIGHBOR_CHANGES Line | Count | Source | 88 | 2 | { \ | 89 | 2 | frr_default_add(&_dflt_##varname); \ | 90 | 2 | } \ |
bgp_vty.c:_dfltinit_BGP_DETERMINISTIC_MED Line | Count | Source | 88 | 2 | { \ | 89 | 2 | frr_default_add(&_dflt_##varname); \ | 90 | 2 | } \ |
bgp_vty.c:_dfltinit_BGP_CONNECT_RETRY Line | Count | Source | 88 | 2 | { \ | 89 | 2 | frr_default_add(&_dflt_##varname); \ | 90 | 2 | } \ |
bgp_vty.c:_dfltinit_BGP_HOLDTIME Line | Count | Source | 88 | 2 | { \ | 89 | 2 | frr_default_add(&_dflt_##varname); \ | 90 | 2 | } \ |
bgp_vty.c:_dfltinit_BGP_KEEPALIVE Line | Count | Source | 88 | 2 | { \ | 89 | 2 | frr_default_add(&_dflt_##varname); \ | 90 | 2 | } \ |
bgp_vty.c:_dfltinit_BGP_EBGP_REQUIRES_POLICY Line | Count | Source | 88 | 2 | { \ | 89 | 2 | frr_default_add(&_dflt_##varname); \ | 90 | 2 | } \ |
bgp_vty.c:_dfltinit_BGP_SUPPRESS_DUPLICATES Line | Count | Source | 88 | 2 | { \ | 89 | 2 | frr_default_add(&_dflt_##varname); \ | 90 | 2 | } \ |
bgp_vty.c:_dfltinit_BGP_GRACEFUL_NOTIFICATION Line | Count | Source | 88 | 2 | { \ | 89 | 2 | frr_default_add(&_dflt_##varname); \ | 90 | 2 | } \ |
bgp_vty.c:_dfltinit_BGP_HARD_ADMIN_RESET Line | Count | Source | 88 | 2 | { \ | 89 | 2 | frr_default_add(&_dflt_##varname); \ | 90 | 2 | } \ |
|
91 | | MACRO_REQUIRE_SEMICOLON() /* end */ |
92 | | |
93 | | /* use: |
94 | | * FRR_CFG_DEFAULT_LONG(SHARP_BLUNTNESS, |
95 | | * { .val_long = 2, .match_version = ">= 10.0" }, |
96 | | * { .val_long = 1, .match_profile = "datacenter" }, |
97 | | * { .val_long = 0 }, |
98 | | * ) |
99 | | * |
100 | | * This will create DFLT_SHARP_BLUNTNESS and SAVE_SHARP_BLUNTNESS variables. |
101 | | * |
102 | | * Note: preprocessor defines cannot be used as variable names because they |
103 | | * will be expanded and blow up with a compile error. Use an enum or add an |
104 | | * extra _ at the beginning (e.g. _SHARP_BLUNTNESS => DFLT__SHARP_BLUNTNESS) |
105 | | */ |
106 | | #define FRR_CFG_DEFAULT_BOOL(varname, ...) \ |
107 | | _FRR_CFG_DEFAULT(bool, bool, varname, ## __VA_ARGS__) |
108 | | #define FRR_CFG_DEFAULT_LONG(varname, ...) \ |
109 | | _FRR_CFG_DEFAULT(long, long, varname, ## __VA_ARGS__) |
110 | | #define FRR_CFG_DEFAULT_ULONG(varname, ...) \ |
111 | | _FRR_CFG_DEFAULT(unsigned long, ulong, varname, ## __VA_ARGS__) |
112 | | #define FRR_CFG_DEFAULT_FLOAT(varname, ...) \ |
113 | | _FRR_CFG_DEFAULT(float, float, varname, ## __VA_ARGS__) |
114 | | #define FRR_CFG_DEFAULT_STR(varname, ...) \ |
115 | | _FRR_CFG_DEFAULT(const char *, str, varname, ## __VA_ARGS__) |
116 | | |
117 | | |
118 | | /* daemons don't need to call any of these, libfrr handles that */ |
119 | | extern void frr_default_add(struct frr_default *dflt); |
120 | | extern void frr_defaults_version_set(const char *version); |
121 | | extern void frr_defaults_profile_set(const char *profile); |
122 | | extern const char *frr_defaults_version(void); |
123 | | extern const char *frr_defaults_profile(void); |
124 | | extern void frr_defaults_apply(void); |
125 | | |
126 | | extern const char *frr_defaults_profiles[]; |
127 | | extern bool frr_defaults_profile_valid(const char *profile); |
128 | | |
129 | | /* like strcmp(), but with version ordering */ |
130 | | extern int frr_version_cmp(const char *aa, const char *bb); |
131 | | |
132 | | #ifdef __cplusplus |
133 | | } |
134 | | #endif |
135 | | |
136 | | #endif /* _FRR_DEFAULTS_H */ |