summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/command.c202
-rw-r--r--lib/if_rmap.c30
-rw-r--r--lib/memory.c27
-rw-r--r--lib/memory.h9
-rw-r--r--lib/sockunion.c13
-rw-r--r--lib/zclient.c56
-rw-r--r--lib/zebra.h7
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. */