]>
git.proxmox.com Git - mirror_frr.git/blob - lib/defaults.c
1 // SPDX-License-Identifier: ISC
3 * FRR switchable defaults.
4 * Copyright (c) 2017-2019 David Lamparter, for NetDEF, Inc.
10 #include "lib/version.h"
12 static char df_version
[128] = FRR_VER_SHORT
, df_profile
[128] = DFLT_NAME
;
13 static struct frr_default
*dflt_first
= NULL
, **dflt_next
= &dflt_first
;
15 /* these are global for all FRR daemons. they have to be, since we write an
16 * integrated config with the same value for all daemons.
18 const char *frr_defaults_profiles
[] = {
24 static int version_value(int ch
)
26 /* non-ASCII shouldn't happen */
27 if (ch
< 0 || ch
>= 128)
30 /* ~foo sorts older than nothing */
36 return 0x100 + tolower(ch
);
38 /* punctuation and digits (and everything else) */
42 int frr_version_cmp(const char *aa
, const char *bb
)
44 const char *apos
= aa
, *bpos
= bb
;
46 /* || is correct, we won't scan past the end of a string since that
47 * doesn't compare equal to anything else */
48 while (apos
[0] || bpos
[0]) {
49 if (isdigit((unsigned char)apos
[0]) &&
50 isdigit((unsigned char)bpos
[0])) {
52 char *aend
= NULL
, *bend
= NULL
;
54 av
= strtoul(apos
, &aend
, 10);
55 bv
= strtoul(bpos
, &bend
, 10);
66 int a
= version_value(*apos
++);
67 int b
= version_value(*bpos
++);
77 static void frr_default_apply_one(struct frr_default
*dflt
, bool check
);
79 void frr_default_add(struct frr_default
*dflt
)
83 dflt_next
= &dflt
->next
;
85 frr_default_apply_one(dflt
, true);
88 static bool frr_match_version(const char *name
, const char *vspec
,
89 const char *version
, bool check
)
92 static const struct spec
{
104 const struct spec
*s
;
107 /* NULL = all versions */
110 for (s
= specs
; s
->str
; s
++)
111 if (!strncmp(s
->str
, vspec
, strlen(s
->str
)))
115 fprintf(stderr
, "invalid version specifier for %s: %s",
117 /* invalid version spec, never matches */
121 vspec
+= strlen(s
->str
);
122 while (isspace((unsigned char)*vspec
))
125 cmp
= frr_version_cmp(version
, vspec
);
126 if (cmp
== s
->dir
|| (s
->eq
&& cmp
== 0))
132 static void frr_default_apply_one(struct frr_default
*dflt
, bool check
)
134 struct frr_default_entry
*entry
= dflt
->entries
;
135 struct frr_default_entry
*dfltentry
= NULL
, *saveentry
= NULL
;
137 for (; entry
->match_version
|| entry
->match_profile
; entry
++) {
138 if (entry
->match_profile
139 && strcmp(entry
->match_profile
, df_profile
))
142 if (!dfltentry
&& frr_match_version(dflt
->name
,
143 entry
->match_version
, df_version
, check
))
145 if (!saveentry
&& frr_match_version(dflt
->name
,
146 entry
->match_version
, FRR_VER_SHORT
, check
))
149 if (dfltentry
&& saveentry
&& !check
)
152 /* found default or arrived at last entry that has NULL,NULL spec */
160 *dflt
->dflt_bool
= dfltentry
->val_bool
;
162 *dflt
->dflt_str
= dfltentry
->val_str
;
164 *dflt
->dflt_long
= dfltentry
->val_long
;
165 if (dflt
->dflt_ulong
)
166 *dflt
->dflt_ulong
= dfltentry
->val_ulong
;
167 if (dflt
->dflt_float
)
168 *dflt
->dflt_float
= dfltentry
->val_float
;
170 *dflt
->save_bool
= saveentry
->val_bool
;
172 *dflt
->save_str
= saveentry
->val_str
;
174 *dflt
->save_long
= saveentry
->val_long
;
175 if (dflt
->save_ulong
)
176 *dflt
->save_ulong
= saveentry
->val_ulong
;
177 if (dflt
->save_float
)
178 *dflt
->save_float
= saveentry
->val_float
;
181 void frr_defaults_apply(void)
183 struct frr_default
*dflt
;
185 for (dflt
= dflt_first
; dflt
; dflt
= dflt
->next
)
186 frr_default_apply_one(dflt
, false);
189 bool frr_defaults_profile_valid(const char *profile
)
193 for (p
= frr_defaults_profiles
; *p
; p
++)
194 if (!strcmp(profile
, *p
))
199 const char *frr_defaults_version(void)
204 const char *frr_defaults_profile(void)
209 void frr_defaults_version_set(const char *version
)
211 strlcpy(df_version
, version
, sizeof(df_version
));
212 frr_defaults_apply();
215 void frr_defaults_profile_set(const char *profile
)
217 strlcpy(df_profile
, profile
, sizeof(df_profile
));
218 frr_defaults_apply();