Annotation of embedaddon/bird/doc/prog-3.html, revision 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>