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 19:31] – 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 56: | Line 56: | ||
| == Step 2 : adding menu entries for global RSTP support == | == Step 2 : adding menu entries for global RSTP support == | ||
| - | == Step 2 : adding menu entries for enabling RSTP on a specific interface == | + | 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/ | 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/ | ||
| Line 128: | Line 215: | ||
| Notice that the routine called when the entries are selected is cmd_rstp_if_set. So... | Notice that the routine called when the entries are selected is cmd_rstp_if_set. So... | ||
| - | == Step 3 : implementing | + | == Step 5 : implementing |
| - | The //run// field from struct menu_node represents | + | The cmd_rstp_if_set routine' |
| - | + | ||
| - | The routine's implementation will reside in **cli/ | + | |
| - | <code c> | + | |
| - | int cmd_rstp_if_set(struct cli_context *ctx, int argc, char **argv, struct menu_node **nodev) | + | |
| - | { | + | |
| - | struct rstp_session *rstp; | + | |
| - | struct rstp_configuration cfg; | + | |
| - | struct swcli_context *uc = SWCLI_CTX(ctx); | + | |
| - | int enable = 1; | + | |
| - | int err; | + | |
| - | + | ||
| - | shared_get_rstp(& | + | |
| - | if (!cfg.enabled) | + | |
| - | return 0; | + | |
| - | + | ||
| - | if (!strcmp(nodev[0]-> | + | |
| - | enable = 0; | + | |
| - | + | ||
| - | if (!RSTP_SESSION_OPEN(ctx, | + | |
| - | EX_STATUS_REASON(ctx, | + | |
| - | return CLI_EX_REJECTED; | + | |
| - | } | + | |
| - | err = rstp_set_interface(rstp, | + | |
| - | RSTP_SESSION_CLOSE(ctx, | + | |
| - | + | ||
| - | return err; | + | |
| - | } | + | |
| - | </ | + | |
cli_entry.1244910701.txt.gz · Last modified: by andrei
