diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/command.c | 202 | ||||
-rw-r--r-- | lib/if_rmap.c | 30 | ||||
-rw-r--r-- | lib/memory.c | 27 | ||||
-rw-r--r-- | lib/memory.h | 9 | ||||
-rw-r--r-- | lib/sockunion.c | 13 | ||||
-rw-r--r-- | lib/zclient.c | 56 | ||||
-rw-r--r-- | lib/zebra.h | 7 |
7 files changed, 286 insertions, 58 deletions
diff --git a/lib/command.c b/lib/command.c index 8cbecce1..5d429338 100644 --- a/lib/command.c +++ b/lib/command.c @@ -24,6 +24,7 @@ Boston, MA 02111-1307, USA. */ #include "memory.h" #include "log.h" #include "version.h" +#include "thread.h" /* Command vector which includes some level of command lists. Normally each daemon maintains each own cmdvec. */ @@ -717,6 +718,8 @@ cmd_ipv6_match (char *str) int state = STATE_START; int colons = 0, nums = 0, double_colon = 0; char *sp = NULL; + struct sockaddr_in6 sin6_dummy; + int ret; if (str == NULL) return partly_match; @@ -724,6 +727,15 @@ cmd_ipv6_match (char *str) if (strspn (str, IPV6_ADDR_STR) != strlen (str)) return no_match; + /* use inet_pton that has a better support, + * for example inet_pton can support the automatic addresses: + * ::1.2.3.4 + */ + ret = inet_pton(AF_INET6, str, &sin6_dummy.sin6_addr); + + if (ret == 1) + return exact_match; + while (*str != '\0') { switch (state) @@ -1411,9 +1423,21 @@ desc_unique_string (vector v, char *str) return 0; } +int +cmd_try_do_shortcut (enum node_type node, char* first_word) { + if ( first_word != NULL && + node != AUTH_NODE && + node != VIEW_NODE && + node != AUTH_ENABLE_NODE && + node != ENABLE_NODE && + 0 == strcmp( "do", first_word ) ) + return 1; + return 0; +} + /* '?' describe command support. */ vector -cmd_describe_command (vector vline, struct vty *vty, int *status) +cmd_describe_command_real (vector vline, struct vty *vty, int *status) { int i; vector cmd_vector; @@ -1536,6 +1560,40 @@ cmd_describe_command (vector vline, struct vty *vty, int *status) return matchvec; } +vector +cmd_describe_command (vector vline, struct vty *vty, int *status) +{ + vector ret; + + if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) ) + { + enum node_type onode; + vector shifted_vline; + int index; + + onode = vty->node; + vty->node = ENABLE_NODE; + /* We can try it on enable node, cos' the vty is authenticated */ + + shifted_vline = vector_init (vector_count(vline)); + /* use memcpy? */ + for (index = 1; index < vector_max (vline); index++) + { + vector_set_index (shifted_vline, index-1, vector_lookup(vline, index)); + } + + ret = cmd_describe_command_real (shifted_vline, vty, status); + + vector_free(shifted_vline); + vty->node = onode; + return ret; + } + + + return cmd_describe_command_real (vline, vty, status); +} + + /* Check LCD of matched command. */ int cmd_lcd (char **matched) @@ -1571,7 +1629,7 @@ cmd_lcd (char **matched) /* Command line completion support. */ char ** -cmd_complete_command (vector vline, struct vty *vty, int *status) +cmd_complete_command_real (vector vline, struct vty *vty, int *status) { int i; vector cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty->node)); @@ -1717,9 +1775,68 @@ cmd_complete_command (vector vline, struct vty *vty, int *status) return match_str; } +char ** +cmd_complete_command (vector vline, struct vty *vty, int *status) +{ + char **ret; + + if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) ) + { + enum node_type onode; + vector shifted_vline; + int index; + + onode = vty->node; + vty->node = ENABLE_NODE; + /* We can try it on enable node, cos' the vty is authenticated */ + + shifted_vline = vector_init (vector_count(vline)); + /* use memcpy? */ + for (index = 1; index < vector_max (vline); index++) + { + vector_set_index (shifted_vline, index-1, vector_lookup(vline, index)); + } + + ret = cmd_complete_command_real (shifted_vline, vty, status); + + vector_free(shifted_vline); + vty->node = onode; + return ret; + } + + + return cmd_complete_command_real (vline, vty, status); +} + +/* return parent node */ +/* MUST eventually converge on CONFIG_NODE */ +enum node_type node_parent ( enum node_type node ) +{ + enum node_type ret; + + assert (node > CONFIG_NODE); + + switch (node) + { + case BGP_VPNV4_NODE: + case BGP_IPV4_NODE: + case BGP_IPV4M_NODE: + case BGP_IPV6_NODE: + ret = BGP_NODE; + break; + case KEYCHAIN_KEY_NODE: + ret = KEYCHAIN_NODE; + break; + default: + ret = CONFIG_NODE; + } + + return ret; +} + /* Execute command by argument vline vector. */ int -cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd) +cmd_execute_command_real (vector vline, struct vty *vty, struct cmd_element **cmd) { int i; int index; @@ -1842,6 +1959,60 @@ cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd) return (*matched_element->func) (matched_element, vty, argc, argv); } + +int +cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd) { + int ret, saved_ret, tried = 0; + enum node_type onode, try_node; + + onode = try_node = vty->node; + + if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) ) + { + vector shifted_vline; + int index; + + vty->node = ENABLE_NODE; + /* We can try it on enable node, cos' the vty is authenticated */ + + shifted_vline = vector_init (vector_count(vline)); + /* use memcpy? */ + for (index = 1; index < vector_max (vline); index++) + { + vector_set_index (shifted_vline, index-1, vector_lookup(vline, index)); + } + + ret = cmd_execute_command_real (shifted_vline, vty, cmd); + + vector_free(shifted_vline); + vty->node = onode; + return ret; + } + + + saved_ret = ret = cmd_execute_command_real (vline, vty, cmd); + + /* This assumes all nodes above CONFIG_NODE are childs of CONFIG_NODE */ + while ( ret != CMD_SUCCESS && ret != CMD_WARNING + && vty->node > CONFIG_NODE ) + { + try_node = node_parent(try_node); + vty->node = try_node; + ret = cmd_execute_command_real (vline, vty, cmd); + tried = 1; + if (ret == CMD_SUCCESS || ret == CMD_WARNING) + { + /* succesfull command, leave the node as is */ + return ret; + } + } + /* no command succeeded, reset the vty to the original node and + return the error for this node */ + if ( tried ) + vty->node = onode; + return saved_ret; +} + /* Execute command by argument readline. */ int cmd_execute_command_strict (vector vline, struct vty *vty, @@ -1981,26 +2152,12 @@ config_from_file (struct vty *vty, FILE *fp) ret = cmd_execute_command_strict (vline, vty, NULL); /* Try again with setting node to CONFIG_NODE */ - if (ret != CMD_SUCCESS && ret != CMD_WARNING) - { - if (vty->node == KEYCHAIN_KEY_NODE) - { - vty->node = KEYCHAIN_NODE; - - ret = cmd_execute_command_strict (vline, vty, NULL); - - if (ret != CMD_SUCCESS && ret != CMD_WARNING) + while (ret != CMD_SUCCESS && ret != CMD_WARNING + && vty->node != CONFIG_NODE) { - vty->node = CONFIG_NODE; + vty->node = node_parent(vty->node); ret = cmd_execute_command_strict (vline, vty, NULL); } - } - else - { - vty->node = CONFIG_NODE; - ret = cmd_execute_command_strict (vline, vty, NULL); - } - } cmd_free_strvec (vline); @@ -2977,5 +3134,10 @@ cmd_init (int terminal) install_element (CONFIG_NODE, &no_service_terminal_length_cmd); } + if (terminal) + { + install_element(VIEW_NODE, &show_thread_cpu_cmd); + install_element(ENABLE_NODE, &show_thread_cpu_cmd); + } srand(time(NULL)); } diff --git a/lib/if_rmap.c b/lib/if_rmap.c index 42271025..4cf8ad9a 100644 --- a/lib/if_rmap.c +++ b/lib/if_rmap.c @@ -219,7 +219,16 @@ DEFUN (if_rmap, if_rmap = if_rmap_set (argv[2], type, argv[0]); return CMD_SUCCESS; -} +} + +ALIAS (if_rmap, + if_ipv6_rmap_cmd, + "route-map RMAP_NAME (in|out) IFNAME", + "Route map set\n" + "Route map name\n" + "Route map set for input filtering\n" + "Route map set for output filtering\n" + "Route map interface name\n") DEFUN (no_if_rmap, no_if_rmap_cmd, @@ -251,7 +260,17 @@ DEFUN (no_if_rmap, return CMD_WARNING; } return CMD_SUCCESS; -} +} + +ALIAS (no_if_rmap, + no_if_ipv6_rmap_cmd, + "no route-map ROUTEMAP_NAME (in|out) IFNAME", + NO_STR + "Route map unset\n" + "Route map name\n" + "Route map for input filtering\n" + "Route map for output filtering\n" + "Route map interface name\n") /* Configuration write function. */ int @@ -300,7 +319,10 @@ if_rmap_init (int node) { ifrmaphash = hash_create (if_rmap_hash_make, if_rmap_hash_cmp); if (node == RIPNG_NODE) { - install_element (RIPNG_NODE, &if_rmap_cmd); - install_element (RIPNG_NODE, &no_if_rmap_cmd); + install_element (RIPNG_NODE, &if_ipv6_rmap_cmd); + install_element (RIPNG_NODE, &no_if_ipv6_rmap_cmd); + } else if (node == RIP_NODE) { + install_element (RIP_NODE, &if_rmap_cmd); + install_element (RIP_NODE, &no_if_rmap_cmd); } } diff --git a/lib/memory.c b/lib/memory.c index bf142dcf..93833113 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -255,6 +255,7 @@ struct memory_list memory_list_lib[] = { MTYPE_ROUTE_MAP_INDEX, "Route map index " }, { MTYPE_ROUTE_MAP_RULE, "Route map rule " }, { MTYPE_ROUTE_MAP_RULE_STR, "Route map rule str" }, + { MTYPE_ROUTE_MAP_COMPILED, "Route map compiled" }, { MTYPE_DESC, "Command desc " }, { MTYPE_BUFFER, "Buffer " }, { MTYPE_BUFFER_DATA, "Buffer data " }, @@ -323,6 +324,17 @@ struct memory_list memory_list_rip[] = { -1, NULL } }; +struct memory_list memory_list_ripng[] = +{ + { MTYPE_RIPNG, "RIPng structure " }, + { MTYPE_RIPNG_ROUTE, "RIPng route info" }, + { MTYPE_RIPNG_AGGREGATE, "RIPng aggregate " }, + { MTYPE_RIPNG_PEER, "RIPng peer " }, + { MTYPE_RIPNG_OFFSET_LIST, "RIPng offset lst" }, + { MTYPE_RIPNG_RTE_DATA, "RIPng rte data " }, + { -1, NULL } +}; + struct memory_list memory_list_ospf[] = { { MTYPE_OSPF_TOP, "OSPF top " }, @@ -402,6 +414,8 @@ DEFUN (show_memory_all, show_memory_vty (vty, memory_list_separator); show_memory_vty (vty, memory_list_rip); show_memory_vty (vty, memory_list_separator); + show_memory_vty (vty, memory_list_ripng); + show_memory_vty (vty, memory_list_separator); show_memory_vty (vty, memory_list_ospf); show_memory_vty (vty, memory_list_separator); show_memory_vty (vty, memory_list_ospf6); @@ -439,6 +453,17 @@ DEFUN (show_memory_rip, return CMD_SUCCESS; } +DEFUN (show_memory_ripng, + show_memory_ripng_cmd, + "show memory ripng", + SHOW_STR + "Memory statistics\n" + "RIPng memory\n") +{ + show_memory_vty (vty, memory_list_ripng); + return CMD_SUCCESS; +} + DEFUN (show_memory_bgp, show_memory_bgp_cmd, "show memory bgp", @@ -479,6 +504,7 @@ memory_init () install_element (VIEW_NODE, &show_memory_all_cmd); install_element (VIEW_NODE, &show_memory_lib_cmd); install_element (VIEW_NODE, &show_memory_rip_cmd); + install_element (VIEW_NODE, &show_memory_ripng_cmd); install_element (VIEW_NODE, &show_memory_bgp_cmd); install_element (VIEW_NODE, &show_memory_ospf_cmd); install_element (VIEW_NODE, &show_memory_ospf6_cmd); @@ -487,6 +513,7 @@ memory_init () install_element (ENABLE_NODE, &show_memory_all_cmd); install_element (ENABLE_NODE, &show_memory_lib_cmd); install_element (ENABLE_NODE, &show_memory_rip_cmd); + install_element (ENABLE_NODE, &show_memory_ripng_cmd); install_element (ENABLE_NODE, &show_memory_bgp_cmd); install_element (ENABLE_NODE, &show_memory_ospf_cmd); install_element (ENABLE_NODE, &show_memory_ospf6_cmd); diff --git a/lib/memory.h b/lib/memory.h index 06681bd1..925f6b65 100644 --- a/lib/memory.h +++ b/lib/memory.h @@ -58,8 +58,6 @@ enum MTYPE_HASH, MTYPE_HASH_INDEX, MTYPE_HASH_BACKET, - MTYPE_RIPNG_ROUTE, - MTYPE_RIPNG_AGGREGATE, MTYPE_ROUTE_TABLE, MTYPE_ROUTE_NODE, MTYPE_ACCESS_LIST, @@ -179,6 +177,13 @@ enum MTYPE_KEYCHAIN, MTYPE_KEY, + MTYPE_RIPNG, + MTYPE_RIPNG_ROUTE, + MTYPE_RIPNG_AGGREGATE, + MTYPE_RIPNG_PEER, + MTYPE_RIPNG_OFFSET_LIST, + MTYPE_RIPNG_RTE_DATA, + MTYPE_VTYSH_CONFIG, MTYPE_VTYSH_CONFIG_LINE, diff --git a/lib/sockunion.c b/lib/sockunion.c index 21371624..e4b311c7 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -302,16 +302,16 @@ sockunion_log (union sockunion *su) switch (su->sa.sa_family) { case AF_INET: - snprintf (buf, BUFSIZ, "%s", inet_ntoa (su->sin.sin_addr)); + snprintf (buf, SU_ADDRSTRLEN, "%s", inet_ntoa (su->sin.sin_addr)); break; #ifdef HAVE_IPV6 case AF_INET6: - snprintf (buf, BUFSIZ, "%s", - inet_ntop (AF_INET6, &(su->sin6.sin6_addr), buf, BUFSIZ)); + snprintf (buf, SU_ADDRSTRLEN, "%s", + inet_ntop (AF_INET6, &(su->sin6.sin6_addr), buf, SU_ADDRSTRLEN)); break; #endif /* HAVE_IPV6 */ default: - snprintf (buf, BUFSIZ, "af_unknown %d ", su->sa.sa_family); + snprintf (buf, SU_ADDRSTRLEN, "af_unknown %d ", su->sa.sa_family); break; } return buf; @@ -344,8 +344,13 @@ sockunion_connect (int fd, union sockunion *peersu, unsigned short port, { #ifdef HAVE_SIN6_SCOPE_ID /* su.sin6.sin6_scope_id = ifindex; */ +#ifdef MUSICA + su.sin6.sin6_scope_id = ifindex; +#endif #endif /* HAVE_SIN6_SCOPE_ID */ +#ifndef MUSICA SET_IN6_LINKLOCAL_IFINDEX (su.sin6.sin6_addr, ifindex); +#endif } #endif /* KAME */ break; diff --git a/lib/zclient.c b/lib/zclient.c index 5e371546..bb7747fa 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -318,23 +318,23 @@ zapi_ipv4_add (struct zclient *zclient, struct prefix_ipv4 *p, if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP)) { if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE)) - { - stream_putc (s, 1); - stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE); - } + { + stream_putc (s, 1); + stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE); + } else - stream_putc (s, api->nexthop_num + api->ifindex_num); - + stream_putc (s, api->nexthop_num + api->ifindex_num); + for (i = 0; i < api->nexthop_num; i++) - { - stream_putc (s, ZEBRA_NEXTHOP_IPV4); - stream_put_in_addr (s, api->nexthop[i]); - } + { + stream_putc (s, ZEBRA_NEXTHOP_IPV4); + stream_put_in_addr (s, api->nexthop[i]); + } for (i = 0; i < api->ifindex_num; i++) - { - stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); - stream_putl (s, api->ifindex[i]); - } + { + stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); + stream_putl (s, api->ifindex[i]); + } } if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE)) @@ -378,23 +378,23 @@ zapi_ipv4_delete (struct zclient *zclient, struct prefix_ipv4 *p, if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP)) { if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE)) - { - stream_putc (s, 1); - stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE); - } + { + stream_putc (s, 1); + stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE); + } else - stream_putc (s, api->nexthop_num + api->ifindex_num); + stream_putc (s, api->nexthop_num + api->ifindex_num); for (i = 0; i < api->nexthop_num; i++) - { - stream_putc (s, ZEBRA_NEXTHOP_IPV4); - stream_put_in_addr (s, api->nexthop[i]); - } + { + stream_putc (s, ZEBRA_NEXTHOP_IPV4); + stream_put_in_addr (s, api->nexthop[i]); + } for (i = 0; i < api->ifindex_num; i++) - { - stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); - stream_putl (s, api->ifindex[i]); - } + { + stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); + stream_putl (s, api->ifindex[i]); + } } if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE)) @@ -564,6 +564,7 @@ zebra_interface_add_read (struct stream *s) ifp->ifindex = stream_getl (s); /* Read interface's value. */ + ifp->status = stream_getc (s); ifp->flags = stream_getl (s); ifp->metric = stream_getl (s); ifp->mtu = stream_getl (s); @@ -600,6 +601,7 @@ zebra_interface_state_read (struct stream *s) ifp->ifindex = stream_getl (s); /* Read interface's value. */ + ifp->status = stream_getc (s); ifp->flags = stream_getl (s); ifp->metric = stream_getl (s); ifp->mtu = stream_getl (s); diff --git a/lib/zebra.h b/lib/zebra.h index 6a60b94b..2ac491d1 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -149,6 +149,10 @@ typedef int socklen_t; #include <netinet/in_var.h> #endif /* HAVE_NETINET_IN_VAR_H */ +#ifdef HAVE_NETINET6_IN6_VAR_H +#include <netinet6/in6_var.h> +#endif /* HAVE_NETINET6_IN6_VAR_H */ + #ifdef HAVE_NETINET_IN6_VAR_H #include <netinet/in6_var.h> #endif /* HAVE_NETINET_IN6_VAR_H */ @@ -262,6 +266,7 @@ struct in_pktinfo #define ZEBRA_FLAG_SELECTED 0x10 #define ZEBRA_FLAG_CHANGED 0x20 #define ZEBRA_FLAG_STATIC 0x40 +#define ZEBRA_FLAG_REJECT 0x80 /* Zebra nexthop flags. */ #define ZEBRA_NEXTHOP_IFINDEX 1 @@ -272,7 +277,7 @@ struct in_pktinfo #define ZEBRA_NEXTHOP_IPV6 6 #define ZEBRA_NEXTHOP_IPV6_IFINDEX 7 #define ZEBRA_NEXTHOP_IPV6_IFNAME 8 -#define ZEBRA_NEXTHOP_BLACKHOLE 9 +#define ZEBRA_NEXTHOP_BLACKHOLE 9 #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK 0x7f000001 /* Internet address 127.0.0.1. */ |