Annotation of embedaddon/bird/doc/prog-3.html, revision 1.1.1.1
1.1 misho 1: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
2: <HTML>
3: <HEAD>
4: <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 1.0.9">
5: <TITLE>BIRD Programmer's Documentation: Configuration</TITLE>
6: <LINK HREF="prog-4.html" REL=next>
7: <LINK HREF="prog-2.html" REL=previous>
8: <LINK HREF="prog.html#toc3" REL=contents>
9: </HEAD>
10: <BODY>
11: <A HREF="prog-4.html">Next</A>
12: <A HREF="prog-2.html">Previous</A>
13: <A HREF="prog.html#toc3">Contents</A>
14: <HR>
15: <H2><A NAME="s3">3.</A> <A HREF="prog.html#toc3">Configuration</A></H2>
16:
17: <H2><A NAME="ss3.1">3.1</A> <A HREF="prog.html#toc3.1">Configuration manager</A>
18: </H2>
19:
20: <P>
21: <P>Configuration of BIRD is complex, yet straightforward. There are three
22: modules taking care of the configuration: config manager (which takes care
23: of storage of the config information and controls switching between configs),
24: lexical analyzer and parser.
25: <P>The configuration manager stores each config as a <I>config</I> structure
26: accompanied by a linear pool from which all information associated
27: with the config and pointed to by the <I>config</I> structure is allocated.
28: <P>There can exist up to four different configurations at one time: an active
29: one (pointed to by <B>config</B>), configuration we are just switching from
30: (<B>old_config</B>), one queued for the next reconfiguration (<B>future_config</B>; if
31: there is one and the user wants to reconfigure once again, we just free the
32: previous queued config and replace it with the new one) and finally a config
33: being parsed (<B>new_config</B>). The stored <B>old_config</B> is also used for undo
34: reconfiguration, which works in a similar way. Reconfiguration could also
35: have timeout (using <B>config_timer</B>) and undo is automatically called if the
36: new configuration is not confirmed later. The new config (<B>new_config</B>) and
37: associated linear pool (<B>cfg_mem</B>) is non-NULL only during parsing.
38: <P>Loading of new configuration is very simple: just call <B>config_alloc()</B> to get
39: a new <I>config</I> structure, then use <B>config_parse()</B> to parse a configuration
40: file and fill all fields of the structure and finally ask the config manager
41: to switch to the new config by calling <B>config_commit()</B>.
42: <P>CLI commands are parsed in a very similar way -- there is also a stripped-down
43: <I>config</I> structure associated with them and they are lex-ed and parsed by the
44: same functions, only a special fake token is prepended before the command
45: text to make the parser recognize only the rules corresponding to CLI commands.
46: <P>
47: <P><HR><H3>Function</H3>
48: <P><I>struct config *</I>
49: <B>config_alloc</B>
50: (<I>const byte *</I> <B>name</B>) -- allocate a new configuration
51: <P>
52: <H3>Arguments</H3>
53: <P>
54: <DL>
55: <DT><I>const byte *</I> <B>name</B><DD><P>name of the config
56: </DL>
57: <H3>Description</H3>
58: <P>This function creates new <I>config</I> structure, attaches a resource
59: pool and a linear memory pool to it and makes it available for
60: further use. Returns a pointer to the structure.
61:
62:
63: <HR><H3>Function</H3>
64: <P><I>int</I>
65: <B>config_parse</B>
66: (<I>struct config *</I> <B>c</B>) -- parse a configuration
67: <P>
68: <H3>Arguments</H3>
69: <P>
70: <DL>
71: <DT><I>struct config *</I> <B>c</B><DD><P>configuration
72: </DL>
73: <H3>Description</H3>
74: <P><B>config_parse()</B> reads input by calling a hook function pointed to
75: by <B>cf_read_hook</B> and parses it according to the configuration
76: grammar. It also calls all the preconfig and postconfig hooks
77: before, resp. after parsing.
78: <H3>Result</H3>
79: <P>1 if the config has been parsed successfully, 0 if any
80: error has occurred (such as anybody calling <B>cf_error()</B>) and
81: the <B>err_msg</B> field has been set to the error message.
82:
83:
84: <HR><H3>Function</H3>
85: <P><I>int</I>
86: <B>cli_parse</B>
87: (<I>struct config *</I> <B>c</B>) -- parse a CLI command
88: <P>
89: <H3>Arguments</H3>
90: <P>
91: <DL>
92: <DT><I>struct config *</I> <B>c</B><DD><P>temporary config structure
93: </DL>
94: <H3>Description</H3>
95: <P><B>cli_parse()</B> is similar to <B>config_parse()</B>, but instead of a configuration,
96: it parses a CLI command. See the CLI module for more information.
97:
98:
99: <HR><H3>Function</H3>
100: <P><I>void</I>
101: <B>config_free</B>
102: (<I>struct config *</I> <B>c</B>) -- free a configuration
103: <P>
104: <H3>Arguments</H3>
105: <P>
106: <DL>
107: <DT><I>struct config *</I> <B>c</B><DD><P>configuration to be freed
108: </DL>
109: <H3>Description</H3>
110: <P>This function takes a <I>config</I> structure and frees all resources
111: associated with it.
112:
113:
114: <HR><H3>Function</H3>
115: <P><I>int</I>
116: <B>config_commit</B>
117: (<I>struct config *</I> <B>c</B>, <I>int</I> <B>type</B>, <I>int</I> <B>timeout</B>) -- commit a configuration
118: <P>
119: <H3>Arguments</H3>
120: <P>
121: <DL>
122: <DT><I>struct config *</I> <B>c</B><DD><P>new configuration
123: <DT><I>int</I> <B>type</B><DD><P>type of reconfiguration (RECONFIG_SOFT or RECONFIG_HARD)
124: <DT><I>int</I> <B>timeout</B><DD><P>timeout for undo (or 0 for no timeout)
125: </DL>
126: <H3>Description</H3>
127: <P>When a configuration is parsed and prepared for use, the
128: <B>config_commit()</B> function starts the process of reconfiguration.
129: It checks whether there is already a reconfiguration in progress
130: in which case it just queues the new config for later processing.
131: Else it notifies all modules about the new configuration by calling
132: their <B>commit()</B> functions which can either accept it immediately
133: or call <B>config_add_obstacle()</B> to report that they need some time
134: to complete the reconfiguration. After all such obstacles are removed
135: using <B>config_del_obstacle()</B>, the old configuration is freed and
136: everything runs according to the new one.
137: <P>When <B>timeout</B> is nonzero, the undo timer is activated with given
138: timeout. The timer is deactivated when <B>config_commit()</B>,
139: <B>config_confirm()</B> or <B>config_undo()</B> is called.
140: <H3>Result</H3>
141: <P><I>CONF_DONE</I> if the configuration has been accepted immediately,
142: <I>CONF_PROGRESS</I> if it will take some time to switch to it, <I>CONF_QUEUED</I>
143: if it's been queued due to another reconfiguration being in progress now
144: or <I>CONF_SHUTDOWN</I> if BIRD is in shutdown mode and no new configurations
145: are accepted.
146:
147:
148: <HR><H3>Function</H3>
149: <P><I>int</I>
150: <B>config_confirm</B>
151: (<B>void</B>) -- confirm a commited configuration
152: <P>
153: <H3>Description</H3>
154: <P>
155: <P>When the undo timer is activated by <B>config_commit()</B> with nonzero timeout,
156: this function can be used to deactivate it and therefore confirm
157: the current configuration.
158: <H3>Result</H3>
159: <P><I>CONF_CONFIRM</I> when the current configuration is confirmed,
160: <I>CONF_NONE</I> when there is nothing to confirm (i.e. undo timer is not active).
161:
162:
163: <HR><H3>Function</H3>
164: <P><I>int</I>
165: <B>config_undo</B>
166: (<B>void</B>) -- undo a configuration
167: <P>
168: <H3>Description</H3>
169: <P>
170: <P>Function <B>config_undo()</B> can be used to change the current
171: configuration back to stored <I>old_config</I>. If no reconfiguration is
172: running, this stored configuration is commited in the same way as a
173: new configuration in <B>config_commit()</B>. If there is already a
174: reconfiguration in progress and no next reconfiguration is
175: scheduled, then the undo is scheduled for later processing as
176: usual, but if another reconfiguration is already scheduled, then
177: such reconfiguration is removed instead (i.e. undo is applied on
178: the last commit that scheduled it).
179: <H3>Result</H3>
180: <P><I>CONF_DONE</I> if the configuration has been accepted immediately,
181: <I>CONF_PROGRESS</I> if it will take some time to switch to it, <I>CONF_QUEUED</I>
182: if it's been queued due to another reconfiguration being in progress now,
183: <I>CONF_UNQUEUED</I> if a scheduled reconfiguration is removed, <I>CONF_NOTHING</I>
184: if there is no relevant configuration to undo (the previous config request
185: was <B>config_undo()</B> too) or <I>CONF_SHUTDOWN</I> if BIRD is in shutdown mode and
186: no new configuration changes are accepted.
187:
188:
189: <HR><H3>Function</H3>
190: <P><I>void</I>
191: <B>order_shutdown</B>
192: (<B>void</B>) -- order BIRD shutdown
193: <P>
194: <H3>Description</H3>
195: <P>
196: <P>This function initiates shutdown of BIRD. It's accomplished by asking
197: for switching to an empty configuration.
198:
199:
200: <HR><H3>Function</H3>
201: <P><I>void</I>
202: <B>cf_error</B>
203: (<I>char *</I> <B>msg</B>, <I>...</I> <B>...</B>) -- report a configuration error
204: <P>
205: <H3>Arguments</H3>
206: <P>
207: <DL>
208: <DT><I>char *</I> <B>msg</B><DD><P>printf-like format string
209: <DT><I>...</I> <B>...</B><DD><P>variable arguments
210: </DL>
211: <H3>Description</H3>
212: <P><B>cf_error()</B> can be called during execution of <B>config_parse()</B>, that is
213: from the parser, a preconfig hook or a postconfig hook, to report an
214: error in the configuration.
215:
216:
217: <HR><H3>Function</H3>
218: <P><I>char *</I>
219: <B>cfg_strdup</B>
220: (<I>const char *</I> <B>c</B>) -- copy a string to config memory
221: <P>
222: <H3>Arguments</H3>
223: <P>
224: <DL>
225: <DT><I>const char *</I> <B>c</B><DD><P>string to copy
226: </DL>
227: <H3>Description</H3>
228: <P><B>cfg_strdup()</B> creates a new copy of the string in the memory
229: pool associated with the configuration being currently parsed.
230: It's often used when a string literal occurs in the configuration
231: and we want to preserve it for further use.
232:
233: <H2><A NAME="ss3.2">3.2</A> <A HREF="prog.html#toc3.2">Lexical analyzer</A>
234: </H2>
235:
236: <P>
237: <P>The lexical analyzer used for configuration files and CLI commands
238: is generated using the <CODE>flex</CODE> tool accompanied by a couple of
239: functions maintaining the hash tables containing information about
240: symbols and keywords.
241: <P>Each symbol is represented by a <I>symbol</I> structure containing name
242: of the symbol, its lexical scope, symbol class (<I>SYM_PROTO</I> for a
243: name of a protocol, <I>SYM_CONSTANT</I> for a constant etc.) and class
244: dependent data. When an unknown symbol is encountered, it's
245: automatically added to the symbol table with class <I>SYM_VOID</I>.
246: <P>The keyword tables are generated from the grammar templates
247: using the <CODE>gen_keywords.m4</CODE> script.
248: <P>
249: <P><HR><H3>Function</H3>
250: <P><I>void</I>
251: <B>cf_lex_unwind</B>
252: (<B>void</B>) -- unwind lexer state during error
253: <P>
254: <H3>Lexical analyzer</H3>
255: <P>
256: <P><B>cf_lex_unwind()</B> frees the internal state on IFS stack when the lexical
257: analyzer is terminated by <B>cf_error()</B>.
258:
259:
260: <HR><H3>Function</H3>
261: <P><I>struct symbol *</I>
262: <B>cf_find_symbol</B>
263: (<I>struct config *</I> <B>cfg</B>, <I>byte *</I> <B>c</B>) -- find a symbol by name
264: <P>
265: <H3>Arguments</H3>
266: <P>
267: <DL>
268: <DT><I>struct config *</I> <B>cfg</B><DD><P>specificed config
269: <DT><I>byte *</I> <B>c</B><DD><P>symbol name
270: </DL>
271: <H3>Description</H3>
272: <P>This functions searches the symbol table in the config <B>cfg</B> for a symbol of
273: given name. First it examines the current scope, then the second recent one
274: and so on until it either finds the symbol and returns a pointer to its
275: <I>symbol</I> structure or reaches the end of the scope chain and returns <I>NULL</I> to
276: signify no match.
277:
278:
279: <HR><H3>Function</H3>
280: <P><I>struct symbol *</I>
281: <B>cf_get_symbol</B>
282: (<I>byte *</I> <B>c</B>) -- get a symbol by name
283: <P>
284: <H3>Arguments</H3>
285: <P>
286: <DL>
287: <DT><I>byte *</I> <B>c</B><DD><P>symbol name
288: </DL>
289: <H3>Description</H3>
290: <P>This functions searches the symbol table of the currently parsed config
291: (<B>new_config</B>) for a symbol of given name. It returns either the already
292: existing symbol or a newly allocated undefined (<I>SYM_VOID</I>) symbol if no
293: existing symbol is found.
294:
295:
296: <HR><H3>Function</H3>
297: <P><I>struct symbol *</I>
298: <B>cf_define_symbol</B>
299: (<I>struct symbol *</I> <B>sym</B>, <I>int</I> <B>type</B>, <I>void *</I> <B>def</B>) -- define meaning of a symbol
300: <P>
301: <H3>Arguments</H3>
302: <P>
303: <DL>
304: <DT><I>struct symbol *</I> <B>sym</B><DD><P>symbol to be defined
305: <DT><I>int</I> <B>type</B><DD><P>symbol class to assign
306: <DT><I>void *</I> <B>def</B><DD><P>class dependent data
307: </DL>
308: <H3>Description</H3>
309: <P>Defines new meaning of a symbol. If the symbol is an undefined
310: one (<I>SYM_VOID</I>), it's just re-defined to the new type. If it's defined
311: in different scope, a new symbol in current scope is created and the
312: meaning is assigned to it. If it's already defined in the current scope,
313: an error is reported via <B>cf_error()</B>.
314: <H3>Result</H3>
315: <P>Pointer to the newly defined symbol. If we are in the top-level
316: scope, it's the same <B>sym</B> as passed to the function.
317:
318:
319: <HR><H3>Function</H3>
320: <P><I>void</I>
321: <B>cf_lex_init</B>
322: (<I>int</I> <B>is_cli</B>, <I>struct config *</I> <B>c</B>) -- initialize the lexer
323: <P>
324: <H3>Arguments</H3>
325: <P>
326: <DL>
327: <DT><I>int</I> <B>is_cli</B><DD><P>true if we're going to parse CLI command, false for configuration
328: <DT><I>struct config *</I> <B>c</B><DD><P>configuration structure
329: </DL>
330: <H3>Description</H3>
331: <P><B>cf_lex_init()</B> initializes the lexical analyzer and prepares it for
332: parsing of a new input.
333:
334:
335: <HR><H3>Function</H3>
336: <P><I>void</I>
337: <B>cf_push_scope</B>
338: (<I>struct symbol *</I> <B>sym</B>) -- enter new scope
339: <P>
340: <H3>Arguments</H3>
341: <P>
342: <DL>
343: <DT><I>struct symbol *</I> <B>sym</B><DD><P>symbol representing scope name
344: </DL>
345: <H3>Description</H3>
346: <P>If we want to enter a new scope to process declarations inside
347: a nested block, we can just call <B>cf_push_scope()</B> to push a new
348: scope onto the scope stack which will cause all new symbols to be
349: defined in this scope and all existing symbols to be sought for
350: in all scopes stored on the stack.
351:
352:
353: <HR><H3>Function</H3>
354: <P><I>void</I>
355: <B>cf_pop_scope</B>
356: (<B>void</B>) -- leave a scope
357: <P>
358: <H3>Description</H3>
359: <P>
360: <P><B>cf_pop_scope()</B> pops the topmost scope from the scope stack,
361: leaving all its symbols in the symbol table, but making them
362: invisible to the rest of the config.
363:
364:
365: <HR><H3>Function</H3>
366: <P><I>char *</I>
367: <B>cf_symbol_class_name</B>
368: (<I>struct symbol *</I> <B>sym</B>) -- get name of a symbol class
369: <P>
370: <H3>Arguments</H3>
371: <P>
372: <DL>
373: <DT><I>struct symbol *</I> <B>sym</B><DD><P>symbol
374: </DL>
375: <H3>Description</H3>
376: <P>This function returns a string representing the class
377: of the given symbol.
378:
379: <H2><A NAME="ss3.3">3.3</A> <A HREF="prog.html#toc3.3">Parser</A>
380: </H2>
381:
382: <P>
383: <P>Both the configuration and CLI commands are analyzed using a syntax
384: driven parser generated by the <CODE>bison</CODE> tool from a grammar which
385: is constructed from information gathered from grammar snippets by
386: the <CODE>gen_parser.m4</CODE> script.
387: <P>Grammar snippets are files (usually with extension <CODE>.Y</CODE>) contributed
388: by various BIRD modules in order to provide information about syntax of their
389: configuration and their CLI commands. Each snipped consists of several
390: sections, each of them starting with a special keyword: <CODE>CF_HDR</CODE> for
391: a list of <CODE>#include</CODE> directives needed by the C code, <CODE>CF_DEFINES</CODE>
392: for a list of C declarations, <CODE>CF_DECLS</CODE> for <CODE>bison</CODE> declarations
393: including keyword definitions specified as <CODE>CF_KEYWORDS</CODE>, <CODE>CF_GRAMMAR</CODE>
394: for the grammar rules, <CODE>CF_CODE</CODE> for auxiliary C code and finally
395: <CODE>CF_END</CODE> at the end of the snippet.
396: <P>To create references between the snippets, it's possible to define
397: multi-part rules by utilizing the <CODE>CF_ADDTO</CODE> macro which adds a new
398: alternative to a multi-part rule.
399: <P>CLI commands are defined using a <CODE>CF_CLI</CODE> macro. Its parameters are:
400: the list of keywords determining the command, the list of parameters,
401: help text for the parameters and help text for the command.
402: <P>Values of <CODE>enum</CODE> filter types can be defined using <CODE>CF_ENUM</CODE> with
403: the following parameters: name of filter type, prefix common for all
404: literals of this type and names of all the possible values.
405: <P>
406: <P>
407: <HR>
408: <A HREF="prog-4.html">Next</A>
409: <A HREF="prog-2.html">Previous</A>
410: <A HREF="prog.html#toc3">Contents</A>
411: </BODY>
412: </HTML>
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>