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>