]>
git.proxmox.com Git - mirror_frr.git/blob - lib/ferr.h
1 // SPDX-License-Identifier: ISC
3 * Copyright (c) 2015-16 David Lamparter, for NetDEF, Inc.
9 /***********************************************************
10 * scroll down to the end of this file for a full example! *
11 ***********************************************************/
23 /* return type when this error indication stuff is used.
25 * guaranteed to have boolean evaluation to "false" when OK, "true" when error
26 * (i.e. can be changed to pointer in the future if necessary)
28 * For checking, always use "if (value)", nothing else.
29 * Do _NOT_ use any integer constant (!= 0), or sign check (< 0).
33 /* rough category of error indication */
38 /* something isn't the way it's supposed to be.
39 * (things that might otherwise be asserts, really)
43 /* user-supplied parameters don't make sense or is inconsistent
44 * if you can express a rule for it (e.g. "holdtime > 2 * keepalive"),
49 /* user-supplied parameters don't line up with reality
50 * (IP address or interface not available, etc.)
51 * NB: these are really TODOs where the code needs to be fixed to
52 * respond to future changes!
56 /* out of some system resource (probably memory)
57 * aka "you didn't spend enough money error" */
60 /* system error (permission denied, etc.) */
63 /* error return from some external library
64 * (FERR_SYSTEM and FERR_LIBRARY are not strongly distinct) */
76 /* unique_id is calculated as a checksum of source filename and error
77 * message format (*before* calling vsnprintf). Line number and
78 * function name are not used; this keeps the number reasonably static
85 /* valid if != 0. note "errno" might be preprocessor foobar. */
87 /* valid if pathname[0] != '\0' */
88 char pathname
[PATH_MAX
];
91 /* Numeric ranges assigned to daemons for use as error codes. */
92 #define BABEL_FERR_START 0x01000001
93 #define BABEL_FRRR_END 0x01FFFFFF
94 #define BGP_FERR_START 0x02000001
95 #define BGP_FERR_END 0x02FFFFFF
96 #define EIGRP_FERR_START 0x03000001
97 #define EIGRP_FERR_END 0x03FFFFFF
98 #define ISIS_FERR_START 0x04000001
99 #define ISIS_FERR_END 0x04FFFFFF
100 #define LDP_FERR_START 0x05000001
101 #define LDP_FERR_END 0x05FFFFFF
102 #define LIB_FERR_START 0x06000001
103 #define LIB_FERR_END 0x06FFFFFF
104 #define NHRP_FERR_START 0x07000001
105 #define NHRP_FERR_END 0x07FFFFFF
106 #define OSPF_FERR_START 0x08000001
107 #define OSPF_FERR_END 0x08FFFFFF
108 #define OSPFV3_FERR_START 0x09000001
109 #define OSPFV3_FERR_END 0x09FFFFFF
110 #define PBR_FERR_START 0x0A000001
111 #define PBR_FERR_END 0x0AFFFFFF
112 #define PIM_FERR_START 0x0B000001
113 #define PIM_FERR_STOP 0x0BFFFFFF
114 #define RIP_FERR_START 0x0C000001
115 #define RIP_FERR_STOP 0x0CFFFFFF
116 #define RIPNG_FERR_START 0x0D000001
117 #define RIPNG_FERR_STOP 0x0DFFFFFF
118 #define SHARP_FERR_START 0x0E000001
119 #define SHARP_FERR_END 0x0EFFFFFF
120 #define VTYSH_FERR_START 0x0F000001
121 #define VTYSH_FRR_END 0x0FFFFFFF
122 #define WATCHFRR_FERR_START 0x10000001
123 #define WATCHFRR_FERR_END 0x10FFFFFF
124 #define PATH_FERR_START 0x11000001
125 #define PATH_FERR_END 0x11FFFFFF
126 #define ZEBRA_FERR_START 0xF1000001
127 #define ZEBRA_FERR_END 0xF1FFFFFF
128 #define END_FERR 0xFFFFFFFF
131 /* Unique error code displayed to end user as a reference. -1 means
132 * this is an uncoded error that does not have reference material. */
134 /* Ultra brief title */
136 /* Brief description of error */
137 const char *description
;
138 /* Remedial suggestion */
139 const char *suggestion
;
142 void log_ref_add(struct log_ref
*ref
);
143 struct log_ref
*log_ref_get(uint32_t code
);
144 void log_ref_display(struct vty
*vty
, uint32_t code
, bool json
);
147 * This function should be called by the
150 void log_ref_init(void);
151 void log_ref_fini(void);
152 void log_ref_vty_init(void);
154 /* get error details.
156 * NB: errval/ferr_r does NOT carry the full error information. It's only
157 * passed around for future API flexibility. ferr_get_last always returns
158 * the last error set in the current thread.
160 const struct ferr
*ferr_get_last(ferr_r errval
);
163 * Can optionally be called at strategic locations.
166 ferr_r
ferr_clear(void);
168 /* do NOT call these functions directly. only for macro use! */
169 ferr_r
ferr_set_internal(const char *file
, int line
, const char *func
,
170 enum ferr_kind kind
, const char *text
, ...)
172 ferr_r
ferr_set_internal_ext(const char *file
, int line
, const char *func
,
173 enum ferr_kind kind
, const char *pathname
,
174 int errno_val
, const char *text
, ...)
181 * If you need to do cleanup (free memory, etc.), save the return value in a
182 * variable of type ferr_r.
184 * Don't put a \n at the end of the error message.
186 #define ferr_code_bug(...) \
187 ferr_set_internal(__FILE__, __LINE__, __func__, FERR_CODE_BUG, \
189 #define ferr_cfg_invalid(...) \
190 ferr_set_internal(__FILE__, __LINE__, __func__, FERR_CONFIG_INVALID, \
192 #define ferr_cfg_reality(...) \
193 ferr_set_internal(__FILE__, __LINE__, __func__, FERR_CONFIG_REALITY, \
195 #define ferr_cfg_resource(...) \
196 ferr_set_internal(__FILE__, __LINE__, __func__, FERR_RESOURCE, \
198 #define ferr_system(...) \
199 ferr_set_internal(__FILE__, __LINE__, __func__, FERR_SYSTEM, \
201 #define ferr_library(...) \
202 ferr_set_internal(__FILE__, __LINE__, __func__, FERR_LIBRARY, \
205 /* extended information variants */
206 #define ferr_system_errno(...) \
207 ferr_set_internal_ext(__FILE__, __LINE__, __func__, FERR_SYSTEM, NULL, \
209 #define ferr_system_path_errno(path, ...) \
210 ferr_set_internal_ext(__FILE__, __LINE__, __func__, FERR_SYSTEM, path, \
214 /* print error message to vty; $ERR is replaced by the error's message */
215 void vty_print_error(struct vty
*vty
, ferr_r err
, const char *msg
, ...)
218 #define CMD_FERR_DO(func, action, ...) \
220 ferr_r cmd_retval = func; \
222 vty_print_error(vty, cmd_retval, __VA_ARGS__); \
227 #define CMD_FERR_RETURN(func, ...) \
228 CMD_FERR_DO(func, return CMD_WARNING_CONFIG_FAILED, __VA_ARGS__)
229 #define CMD_FERR_GOTO(func, label, ...) \
230 CMD_FERR_DO(func, goto label, __VA_ARGS__)
232 /* example: uses bogus #define to keep indent.py happy */
233 #ifdef THIS_IS_AN_EXAMPLE
234 ferr_r
foo_bar_set(struct object
*obj
, int bar
)
236 if (bar
< 1 || bar
>= 100)
237 return ferr_config_invalid("bar setting (%d) must be 0<x<100",
240 if (ioctl(obj
->fd
, bar
))
241 return ferr_system_errno("couldn't set bar to %d", bar
);
248 CMD_FERR_RETURN(foo_bar_set(obj
, atoi(argv
[1])),
249 "command failed: $ERR\n");
253 #endif /* THIS_IS_AN_EXAMPLE */