cli_entry
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| cli_entry [2009/06/13 18:12] – andrei | cli_entry [2009/06/13 20:31] (current) – andrei | ||
|---|---|---|---|
| Line 5: | Line 5: | ||
| == Step 1 : setting up protocol information == | == Step 1 : setting up protocol information == | ||
| - | Most protocols have a small number of configurable parameters that influence the protocol' | + | Most protocols have a small number of configurable parameters that influence the protocol' |
| <code c> | <code c> | ||
| struct rstp_configuration { | struct rstp_configuration { | ||
| Line 11: | Line 11: | ||
| }; | }; | ||
| </ | </ | ||
| - | Next, add an entry of this type in the shared memory structure found in **lib/ | + | The //enabled// field represents a global option telling us if RSTP support is enabled for the switch. |
| <code c> | <code c> | ||
| struct shared { | struct shared { | ||
| Line 41: | Line 41: | ||
| </ | </ | ||
| - | == Step 2 : adding menu entries == | + | Finally, add the two definitions in **include/ |
| - | Now that we have the protocol infrastructure in place, we can add the menu entry. We want the menu entry to be available only for the selected interface. Only after we've given the commands //conf t// and //int EthX// should the entry become available. So we have to edit the **cli/ | + | <code c> |
| + | //... | ||
| + | |||
| + | /* Sets the RSTP global configuration */ | ||
| + | void shared_set_rstp(struct rstp_configuration *rstp); | ||
| + | |||
| + | /* Gets the RSTP global configuration */ | ||
| + | void shared_get_rstp(struct rstp_configuration *rstp); | ||
| + | |||
| + | </ | ||
| + | |||
| + | == Step 2 : adding menu entries for global RSTP support == | ||
| + | |||
| + | Creating menu entries requires adding struct menu_node fields to the existing menu structure. Adding a global option for enabling RSTP means adding the following code to the config_main structure found in **cli/ | ||
| + | <code c> | ||
| + | struct menu_node config_main = { | ||
| + | /* Root node, .name is used as prompt */ | ||
| + | .name = " | ||
| + | .subtree | ||
| + | /* #rstp */ | ||
| + | & (struct menu_node){ | ||
| + | .name = " | ||
| + | .help = " | ||
| + | .mask = CLI_MASK(PRIV(15)), | ||
| + | .tokenize = NULL, | ||
| + | .run = NULL, | ||
| + | .subtree | ||
| + | /* #cdp run */ | ||
| + | & (struct menu_node){ | ||
| + | .name = " | ||
| + | .help = "", | ||
| + | .mask = CLI_MASK(PRIV(15)), | ||
| + | .tokenize = NULL, | ||
| + | .run = cmd_rstp_run, | ||
| + | .subtree | ||
| + | }, | ||
| + | |||
| + | NULL | ||
| + | } /*}}}*/ | ||
| + | }, | ||
| + | //... | ||
| + | </ | ||
| + | |||
| + | Also, add an option for disabling RSTP on the switch. This is done Cisco-like by adding //no// in front of the option. So basically we add an entry in the //no// subtree. | ||
| + | <code c> | ||
| + | /* #no */ | ||
| + | & (struct menu_node){ | ||
| + | .name = " | ||
| + | .help = " | ||
| + | .mask = CLI_MASK(PRIV(15)), | ||
| + | .tokenize = NULL, | ||
| + | .run = NULL, | ||
| + | .subtree | ||
| + | /* #no rstp */ | ||
| + | & (struct menu_node){ | ||
| + | .name = " | ||
| + | .help = " | ||
| + | .mask = CLI_MASK(PRIV(15)), | ||
| + | .tokenize = NULL, | ||
| + | .run = NULL, | ||
| + | .subtree | ||
| + | /* #no rstp run */ | ||
| + | & (struct menu_node){ | ||
| + | .name = " | ||
| + | .help = "", | ||
| + | .mask = CLI_MASK(PRIV(15)), | ||
| + | .tokenize = NULL, | ||
| + | .run = cmd_rstp_run, | ||
| + | .subtree | ||
| + | }, | ||
| + | |||
| + | NULL | ||
| + | } /*}}}*/ | ||
| + | }, | ||
| + | //... | ||
| + | </ | ||
| + | |||
| + | The position of the entry in the code reflects its position in the actual menu. That is, if the first entry in the subtree of config_main is the struct menu_node rstp then it will also be the first entry in the CLI menu. Notice than when one of the entries is selected then the cmd_rstp_run routine is called. | ||
| + | |||
| + | == Step 3: implementing the global RSTP enable routine == | ||
| + | |||
| + | The //run// field from struct menu_node represents a pointer to a function having the following signature : int (struct cli_context *, int, char **, struct menu_node **). For a detailed description see the struct menu_node definition in **cli/ | ||
| + | |||
| + | The routine' | ||
| + | <code c> | ||
| + | int cmd_rstp_run(struct cli_context *ctx, int argc, char **argv, struct menu_node **nodev) | ||
| + | { | ||
| + | struct rstp_configuration rstp; | ||
| + | int enabled = 1; | ||
| + | |||
| + | if (!strcmp(nodev[0]-> | ||
| + | enabled = 0; | ||
| + | shared_get_rstp(& | ||
| + | rstp.enabled = enabled; | ||
| + | shared_set_rstp(& | ||
| + | |||
| + | return CLI_EX_OK; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | == Step 4 : adding menu entries for enabling RSTP on a specific interface == | ||
| + | |||
| + | Now that we have the protocol infrastructure in place, we can add menu entries for enabling RSTP on a certain interface. We want the menu entry to be available only for the selected interface. Only after we've given the commands //conf t// and //int EthX// should the entry become available. So we have to edit the **cli/ | ||
| <code c> | <code c> | ||
| //... | //... | ||
| Line 75: | Line 177: | ||
| //... | //... | ||
| </ | </ | ||
| - | The result of this is that the first entry from the config-if submenu is rstp enable. To position the entry elsewhere (that is, to make it be the 2nd,3rd entry etc.) simply move the piece of code after the similar entries found in struct config_if_main. Of course we also have to add the disable option. To keep things similar to Cisco commands, we add the following piece of code under the //no// submenu: | + | The result of this is that the first entry from the config-if submenu is rstp enable. To position the entry elsewhere (that is, to make it be the 2nd,3rd entry etc.) simply move the piece of code after the similar entries found in struct config_if_main. Of course we also have to add the disable option. To keep things similar to Cisco commands, we add the following piece of code under the //no// submenu |
| - | < | + | < |
| //... | //... | ||
| /* #no */ | /* #no */ | ||
| Line 110: | Line 212: | ||
| //... | //... | ||
| </ | </ | ||
| + | |||
| + | Notice that the routine called when the entries are selected is cmd_rstp_if_set. So... | ||
| + | |||
| + | == Step 5 : implementing the interface enable/ | ||
| + | |||
| + | The cmd_rstp_if_set routine' | ||
| + | |||
cli_entry.1244905963.txt.gz · Last modified: by andrei
