1 /* 2 * FRR switchable defaults. 3 * Copyright (C) 2017-2019 David Lamparter for NetDEF, Inc. 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #ifndef _FRR_DEFAULTS_H 19 #define _FRR_DEFAULTS_H 20 21 #include <stdbool.h> 22 23 #include "compiler.h" 24 25 #ifdef __cplusplus 26 extern "C" { 27 #endif 28 29 /* frr_default wraps information about a default that has different 30 * values depending on FRR version or default-set 31 * 32 * frr_default_entry describes one match rule and the resulting value; 33 * entries are evaluated in order and the first matching is used. 34 * 35 * If both match_version and match_profile are specified, they must both 36 * match. A NULL value matches everything. 37 */ 38 struct frr_default_entry { 39 /* syntax: "(<|<=|==|>=|>) [whitespace] version", e.g. 40 * ">= 6.1-dev" "<6.0" 41 */ 42 const char *match_version; 43 /* exact profile string to compare against */ 44 const char *match_profile; 45 46 /* value to use */ 47 bool val_bool; 48 const char *val_str; 49 long val_long; 50 unsigned long val_ulong; 51 float val_float; 52 }; 53 54 /* one struct frr_default exists for each malleable default value */ 55 struct frr_default { 56 struct frr_default *next; 57 58 /* for UI/debug use */ 59 const char *name; 60 61 /* the following two sets of variables differ because the written 62 * config always targets the *current* FRR version 63 * 64 * e.g. if you load a config that has "frr version 5.0" on 6.0 65 * *dflt_long => set to the default value in 5.0 66 * *save_long => set to the default value in 6.0 67 * config save will write "frr version 6.0" with 6.0 defaults 68 */ 69 70 /* variable holding the default value for reading/use */ 71 bool *dflt_bool; 72 const char **dflt_str; 73 long *dflt_long; 74 unsigned long *dflt_ulong; 75 float *dflt_float; 76 77 /* variable to use when comparing for config save */ 78 bool *save_bool; 79 const char **save_str; 80 long *save_long; 81 unsigned long *save_ulong; 82 float *save_float; 83 84 struct frr_default_entry entries[]; 85 }; 86 87 #define _FRR_CFG_DEFAULT(type, typname, varname, ...) \ 88 static type DFLT_##varname; \ 89 static type SAVE_##varname; \ 90 static struct frr_default _dflt_##varname = { \ 91 .name = #varname, \ 92 .dflt_##typname = &DFLT_##varname, \ 93 .save_##typname = &SAVE_##varname, \ 94 .entries = { __VA_ARGS__ }, \ 95 }; \ 96 static void _dfltinit_##varname(void) \ 97 __attribute__((_CONSTRUCTOR(1000))); \ 98 static void _dfltinit_##varname(void) \ 99 { \ 100 frr_default_add(&_dflt_##varname); \ 101 } 102 103 /* use: 104 * FRR_CFG_DEFAULT_LONG(SHARP_BLUNTNESS, 105 * { .val_long = 2, .match_version = ">= 10.0" }, 106 * { .val_long = 1, .match_profile = "datacenter" }, 107 * { .val_long = 0 }, 108 * ) 109 * 110 * This will create DFLT_SHARP_BLUNTNESS and SAVE_SHARP_BLUNTNESS variables. 111 * 112 * Note: preprocessor defines cannot be used as variable names because they 113 * will be expanded and blow up with a compile error. Use an enum or add an 114 * extra _ at the beginning (e.g. _SHARP_BLUNTNESS => DFLT__SHARP_BLUNTNESS) 115 */ 116 #define FRR_CFG_DEFAULT_BOOL(varname, ...) \ 117 _FRR_CFG_DEFAULT(bool, bool, varname, ## __VA_ARGS__) 118 #define FRR_CFG_DEFAULT_LONG(varname, ...) \ 119 _FRR_CFG_DEFAULT(long, long, varname, ## __VA_ARGS__) 120 #define FRR_CFG_DEFAULT_ULONG(varname, ...) \ 121 _FRR_CFG_DEFAULT(unsigned long, ulong, varname, ## __VA_ARGS__) 122 #define FRR_CFG_DEFAULT_FLOAT(varname, ...) \ 123 _FRR_CFG_DEFAULT(float, float, varname, ## __VA_ARGS__) 124 #define FRR_CFG_DEFAULT_STR(varname, ...) \ 125 _FRR_CFG_DEFAULT(const char *, str, varname, ## __VA_ARGS__) 126 127 128 /* daemons don't need to call any of these, libfrr handles that */ 129 extern void frr_default_add(struct frr_default *dflt); 130 extern void frr_defaults_version_set(const char *version); 131 extern void frr_defaults_profile_set(const char *profile); 132 extern const char *frr_defaults_version(void); 133 extern const char *frr_defaults_profile(void); 134 extern void frr_defaults_apply(void); 135 136 extern const char *frr_defaults_profiles[]; 137 extern bool frr_defaults_profile_valid(const char *profile); 138 139 /* like strcmp(), but with version ordering */ 140 extern int frr_version_cmp(const char *aa, const char *bb); 141 142 #ifdef __cplusplus 143 } 144 #endif 145 146 #endif /* _FRR_DEFAULTS_H */ 147