]> git.puffer.fish Git - matthieu/frr.git/commitdiff
Merge branch 'cmaster-next' into vtysh-grammar
authorQuentin Young <qlyoung@cumulusnetworks.com>
Thu, 20 Oct 2016 16:31:49 +0000 (16:31 +0000)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Thu, 20 Oct 2016 16:31:49 +0000 (16:31 +0000)
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Conflicts:
isisd/isis_routemap.c
zebra/rt_netlink.c

28 files changed:
1  2 
bgpd/bgp_aspath.c
bgpd/bgp_attr.c
bgpd/bgp_dump.c
bgpd/bgp_mplsvpn.c
bgpd/bgp_nexthop.c
bgpd/bgp_route.c
bgpd/bgp_routemap.c
bgpd/bgpd.c
configure.ac
isisd/isis_routemap.c
lib/Makefile.am
lib/command.c
lib/command.h
lib/route_types.txt
lib/routemap.c
lib/routemap.h
ospf6d/ospf6_asbr.c
ospfd/ospf_routemap.c
pimd/pim_routemap.c
ripd/rip_routemap.c
ripngd/ripng_routemap.c
vtysh/vtysh.c
zebra/if_netlink.c
zebra/kernel_null.c
zebra/rt_netlink.c
zebra/zebra_fpm_netlink.c
zebra/zebra_routemap.c
zebra/zserv.c

Simple merge
diff --cc bgpd/bgp_attr.c
Simple merge
diff --cc bgpd/bgp_dump.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc bgpd/bgpd.c
Simple merge
diff --cc configure.ac
Simple merge
index 93267afe92145a2dcbfa2c4feb78dacd621c14f5,1f947fb04754a7bd63ceb46a3b84026d7278db42..1d734fbc2f0f73c60734c855c70d724f163910fb
@@@ -250,30 -250,314 +250,29 @@@ static struct route_map_rule_cmd route_
    route_set_metric_free
  };
  
 -/* ------------------------------------------------------------*/
 -
 -static int
 -isis_route_match_add(struct vty *vty,
 -                      const char *command, const char *arg)
 -{
 -  VTY_DECLVAR_CONTEXT (route_map_index, index);
 -  int ret;
 -
 -  ret = route_map_add_match (index, command, arg);
 -  if (ret)
 -    {
 -      switch (ret)
 -        {
 -        case RMAP_RULE_MISSING:
 -          vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
 -          return CMD_WARNING;
 -        case RMAP_COMPILE_ERROR:
 -          vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
 -          return CMD_WARNING;
 -        }
 -    }
 -  return CMD_SUCCESS;
 -}
 -
 -static int
 -isis_route_match_delete(struct vty *vty,
 -                        const char *command, const char *arg)
 -{
 -  VTY_DECLVAR_CONTEXT (route_map_index, index);
 -  int ret;
 -
 -  ret = route_map_delete_match (index, command, arg);
 -  if (ret)
 -    {
 -      switch (ret)
 -        {
 -        case RMAP_RULE_MISSING:
 -          vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
 -          return CMD_WARNING;
 -        case RMAP_COMPILE_ERROR:
 -          vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
 -          return CMD_WARNING;
 -        }
 -    }
 -  return CMD_SUCCESS;
 -}
 -
 -static int
 -isis_route_set_add(struct vty *vty,
 -                   const char *command, const char *arg)
 -{
 -  VTY_DECLVAR_CONTEXT (route_map_index, index);
 -  int ret;
 -
 -  ret = route_map_add_set(index, command, arg);
 -  if (ret)
 -    {
 -      switch (ret)
 -        {
 -        case RMAP_RULE_MISSING:
 -          vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
 -          return CMD_WARNING;
 -        case RMAP_COMPILE_ERROR:
 -          vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
 -          return CMD_WARNING;
 -        }
 -    }
 -
 -  return CMD_SUCCESS;
 -}
 -
 -static int
 -isis_route_set_delete (struct vty *vty,
 -                     const char *command, const char *arg)
 -{
 -  VTY_DECLVAR_CONTEXT (route_map_index, index);
 -  int ret;
 -
 -  ret = route_map_delete_set (index, command, arg);
 -  if (ret)
 -    {
 -      switch (ret)
 -        {
 -        case RMAP_RULE_MISSING:
 -          vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
 -          return CMD_WARNING;
 -        case RMAP_COMPILE_ERROR:
 -          vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
 -          return CMD_WARNING;
 -        }
 -    }
 -
 -  return CMD_SUCCESS;
 -}
 -
 -/* ------------------------------------------------------------*/
 -
 -DEFUN (match_ip_address,
 -       match_ip_address_cmd,
 -       "match ip address (<1-199>|<1300-2699>|WORD)",
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n"
 -       "IP access-list number\n"
 -       "IP access-list number (expanded range)\n"
 -       "IP Access-list name\n")
 -{
 -  return isis_route_match_add(vty, "ip address", argv[0]);
 -}
 -
 -DEFUN (no_match_ip_address,
 -       no_match_ip_address_val_cmd,
 -       "no match ip address (<1-199>|<1300-2699>|WORD)",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n"
 -       "IP access-list number\n"
 -       "IP access-list number (expanded range)\n"
 -       "IP Access-list name\n")
 -{
 -  if (argc == 0)
 -    return isis_route_match_delete(vty, "ip address", NULL);
 -  return isis_route_match_delete(vty, "ip address", argv[0]);
 -}
 -
 -ALIAS (no_match_ip_address,
 -       no_match_ip_address_cmd,
 -       "no match ip address",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n")
 -
 -/* ------------------------------------------------------------*/
 -
 -DEFUN (match_ip_address_prefix_list,
 -       match_ip_address_prefix_list_cmd,
 -       "match ip address prefix-list WORD",
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n"
 -       "Match entries of prefix-lists\n"
 -       "IP prefix-list name\n")
 -{
 -  return isis_route_match_add(vty, "ip address prefix-list", argv[0]);
 -}
 -
 -DEFUN (no_match_ip_address_prefix_list,
 -       no_match_ip_address_prefix_list_cmd,
 -       "no match ip address prefix-list",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n"
 -       "Match entries of prefix-lists\n")
 -{
 -  if (argc == 0)
 -    return isis_route_match_delete (vty, "ip address prefix-list", NULL);
 -  return isis_route_match_delete (vty, "ip address prefix-list", argv[0]);
 -}
 -
 -ALIAS (no_match_ip_address_prefix_list,
 -       no_match_ip_address_prefix_list_val_cmd,
 -       "no match ip address prefix-list WORD",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n"
 -       "Match entries of prefix-lists\n"
 -       "IP prefix-list name\n")
 -
 -/* ------------------------------------------------------------*/
 -
 -DEFUN (match_ipv6_address,
 -       match_ipv6_address_cmd,
 -       "match ipv6 address WORD",
 -       MATCH_STR
 -       IPV6_STR
 -       "Match IPv6 address of route\n"
 -       "IPv6 access-list name\n")
 -{
 -  return isis_route_match_add(vty, "ipv6 address", argv[0]);
 -}
 -
 -DEFUN (no_match_ipv6_address,
 -       no_match_ipv6_address_val_cmd,
 -       "no match ipv6 address WORD",
 -       NO_STR
 -       MATCH_STR
 -       IPV6_STR
 -       "Match IPv6 address of route\n"
 -       "IPv6 access-list name\n")
 -{
 -  if (argc == 0)
 -    return isis_route_match_delete(vty, "ipv6 address", NULL);
 -  return isis_route_match_delete(vty, "ipv6 address", argv[0]);
 -}
 -
 -ALIAS (no_match_ipv6_address,
 -       no_match_ipv6_address_cmd,
 -       "no match ipv6 address",
 -       NO_STR
 -       MATCH_STR
 -       IPV6_STR
 -       "Match IPv6 address of route\n")
 -
 -/* ------------------------------------------------------------*/
 -
 -DEFUN (match_ipv6_address_prefix_list,
 -       match_ipv6_address_prefix_list_cmd,
 -       "match ipv6 address prefix-list WORD",
 -       MATCH_STR
 -       IPV6_STR
 -       "Match address of route\n"
 -       "Match entries of prefix-lists\n"
 -       "IP prefix-list name\n")
 -{
 -  return isis_route_match_add(vty, "ipv6 address prefix-list", argv[0]);
 -}
 -
 -DEFUN (no_match_ipv6_address_prefix_list,
 -       no_match_ipv6_address_prefix_list_cmd,
 -       "no match ipv6 address prefix-list",
 -       NO_STR
 -       MATCH_STR
 -       IPV6_STR
 -       "Match address of route\n"
 -       "Match entries of prefix-lists\n")
 +void
 +isis_route_map_init(void)
  {
 -  if (argc == 0)
 -    return isis_route_match_delete (vty, "ipv6 address prefix-list", NULL);
 -  return isis_route_match_delete (vty, "ipv6 address prefix-list", argv[0]);
 -}
 +  route_map_init();
-   route_map_init_vty();
  
 -ALIAS (no_match_ipv6_address_prefix_list,
 -       no_match_ipv6_address_prefix_list_val_cmd,
 -       "no match ipv6 address prefix-list WORD",
 -       NO_STR
 -       MATCH_STR
 -       IPV6_STR
 -       "Match address of route\n"
 -       "Match entries of prefix-lists\n"
 -       "IP prefix-list name\n")
 +  route_map_match_ip_address_hook (generic_match_add);
 +  route_map_no_match_ip_address_hook (generic_match_delete);
  
 -/* ------------------------------------------------------------*/
 +  route_map_match_ip_address_prefix_list_hook (generic_match_add);
 +  route_map_no_match_ip_address_prefix_list_hook (generic_match_delete);
  
 -/* set metric already exists e.g. in the ospf routemap. vtysh doesn't cope well with different
 - * commands at the same node, therefore add set metric with the same 32-bit range as ospf and
 - * verify that the input is a valid isis metric */
 -DEFUN (set_metric,
 -      set_metric_cmd,
 -      "set metric <0-4294967295>",
 -      SET_STR
 -      "Metric vale for destination routing protocol\n"
 -      "Metric value\n")
 -{
 -  return isis_route_set_add(vty, "metric", argv[0]);
 -}
 +  route_map_match_ipv6_address_hook (generic_match_add);
 +  route_map_no_match_ipv6_address_hook (generic_match_delete);
  
 -DEFUN (no_set_metric,
 -      no_set_metric_val_cmd,
 -      "no set metric <0-4294967295>",
 -      NO_STR
 -      SET_STR
 -      "Metric value for destination routing protocol\n"
 -      "Metric value\n")
 -{
 -  if (argc == 0)
 -    return isis_route_set_delete(vty, "metric", NULL);
 -  return isis_route_set_delete(vty, "metric", argv[0]);
 -}
 +  route_map_match_ipv6_address_prefix_list_hook (generic_match_add);
 +  route_map_no_match_ipv6_address_prefix_list_hook (generic_match_delete);
  
 -ALIAS (no_set_metric,
 -       no_set_metric_cmd,
 -       "no set metric",
 -       NO_STR
 -       SET_STR
 -       "Metric vale for destination routing protocol\n");
 -
 -void
 -isis_route_map_init(void)
 -{
 -  route_map_init();
 +  route_map_set_metric_hook (generic_set_add);
 +  route_map_no_set_metric_hook (generic_set_delete);
  
    route_map_install_match(&route_match_ip_address_cmd);
 -  install_element(RMAP_NODE, &match_ip_address_cmd);
 -  install_element(RMAP_NODE, &no_match_ip_address_val_cmd);
 -  install_element(RMAP_NODE, &no_match_ip_address_cmd);
 -
    route_map_install_match(&route_match_ip_address_prefix_list_cmd);
 -  install_element(RMAP_NODE, &match_ip_address_prefix_list_cmd);
 -  install_element(RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
 -  install_element(RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
 -
    route_map_install_match(&route_match_ipv6_address_cmd);
 -  install_element(RMAP_NODE, &match_ipv6_address_cmd);
 -  install_element(RMAP_NODE, &no_match_ipv6_address_val_cmd);
 -  install_element(RMAP_NODE, &no_match_ipv6_address_cmd);
 -
    route_map_install_match(&route_match_ipv6_address_prefix_list_cmd);
 -  install_element(RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
 -  install_element(RMAP_NODE, &no_match_ipv6_address_prefix_list_val_cmd);
 -  install_element(RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
 -
    route_map_install_set(&route_set_metric_cmd);
 -  install_element(RMAP_NODE, &set_metric_cmd);
 -  install_element(RMAP_NODE, &no_set_metric_val_cmd);
 -  install_element(RMAP_NODE, &no_set_metric_cmd);
  }
diff --cc lib/Makefile.am
index dbf1a82be28a32d82ff7f8e11f615a3276cf8b5a,1c0906837a2c58a3418729dfadca599ffa2891b4..f0d5bd53db569f5ea0a360c5a6a230cfa9b2dddb
@@@ -20,9 -17,10 +20,10 @@@ libzebra_la_SOURCES = 
        sigevent.c pqueue.c jhash.c workqueue.c nexthop.c json.c \
        ptm_lib.c csv.c bfd.c vrf.c systemd.c ns.c memory.c memory_vty.c \
        imsg-buffer.c imsg.c skiplist.c \
-       qobj.c
+       qobj.c \
+       event_counter.c
  
 -BUILT_SOURCES = route_types.h gitversion.h
 +BUILT_SOURCES = route_types.h gitversion.h command_parse.h
  
  libzebra_la_DEPENDENCIES = @LIB_REGEX@
  
diff --cc lib/command.c
Simple merge
diff --cc lib/command.h
Simple merge
Simple merge
diff --cc lib/routemap.c
Simple merge
diff --cc lib/routemap.h
index 86d72ce47421f507386be68fc84eee296ff3cc46,b5cdd27277d0a1859799e90d0798a28a81b40ca9..b52f7289b061eb5db45155c70ab9d776b9acc1b0
@@@ -25,6 -25,6 +25,8 @@@
  #include "prefix.h"
  #include "memory.h"
  #include "qobj.h"
++#include "vty.h"
++
  DECLARE_MTYPE(ROUTE_MAP_NAME)
  DECLARE_MTYPE(ROUTE_MAP_RULE)
  DECLARE_MTYPE(ROUTE_MAP_COMPILED)
Simple merge
Simple merge
Simple merge
index 60ce66265ebc64f657d93db1a065a6f4f494388c,8b48adfd556aac4e31fff70a6cfc79f332ec91bc..6fd647596cf1fe6052bd9874b5a858dd287e96dd
@@@ -588,50 -685,394 +588,50 @@@ static struct route_map_rule_cmd route_
  #define MATCH_STR "Match values from routing table\n"
  #define SET_STR "Set values in destination routing protocol\n"
  
 -DEFUN (match_metric, 
 -       match_metric_cmd,
 -       "match metric <0-4294967295>",
 -       MATCH_STR
 -       "Match metric of route\n"
 -       "Metric value\n")
 -{
 -  return rip_route_match_add (vty, vty->index, "metric", argv[0]);
 -}
 -
 -DEFUN (no_match_metric,
 -       no_match_metric_cmd,
 -       "no match metric",
 -       NO_STR
 -       MATCH_STR
 -       "Match metric of route\n")
 -{
 -  if (argc == 0)
 -    return rip_route_match_delete (vty, vty->index, "metric", NULL);
 -
 -  return rip_route_match_delete (vty, vty->index, "metric", argv[0]);
 -}
 -
 -ALIAS (no_match_metric,
 -       no_match_metric_val_cmd,
 -       "no match metric <0-4294967295>",
 -       NO_STR
 -       MATCH_STR
 -       "Match metric of route\n"
 -       "Metric value\n")
 -
 -DEFUN (match_interface,
 -       match_interface_cmd,
 -       "match interface WORD",
 -       MATCH_STR
 -       "Match first hop interface of route\n"
 -       "Interface name\n")
 -{
 -  return rip_route_match_add (vty, vty->index, "interface", argv[0]);
 -}
 -
 -DEFUN (no_match_interface,
 -       no_match_interface_cmd,
 -       "no match interface",
 -       NO_STR
 -       MATCH_STR
 -       "Match first hop interface of route\n")
 -{
 -  if (argc == 0)
 -    return rip_route_match_delete (vty, vty->index, "interface", NULL);
 -
 -  return rip_route_match_delete (vty, vty->index, "interface", argv[0]);
 -}
 -
 -ALIAS (no_match_interface,
 -       no_match_interface_val_cmd,
 -       "no match interface WORD",
 -       NO_STR
 -       MATCH_STR
 -       "Match first hop interface of route\n"
 -       "Interface name\n")
 -
 -DEFUN (match_ip_next_hop,
 -       match_ip_next_hop_cmd,
 -       "match ip next-hop (<1-199>|<1300-2699>|WORD)",
 -       MATCH_STR
 -       IP_STR
 -       "Match next-hop address of route\n"
 -       "IP access-list number\n"
 -       "IP access-list number (expanded range)\n"
 -       "IP Access-list name\n")
 -{
 -  return rip_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
 -}
 -
 -DEFUN (no_match_ip_next_hop,
 -       no_match_ip_next_hop_cmd,
 -       "no match ip next-hop",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match next-hop address of route\n")
 -{
 -  if (argc == 0)
 -    return rip_route_match_delete (vty, vty->index, "ip next-hop", NULL);
 -
 -  return rip_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
 -}
 -
 -ALIAS (no_match_ip_next_hop,
 -       no_match_ip_next_hop_val_cmd,
 -       "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match next-hop address of route\n"
 -       "IP access-list number\n"
 -       "IP access-list number (expanded range)\n"
 -       "IP Access-list name\n")
 -
 -DEFUN (match_ip_next_hop_prefix_list,
 -       match_ip_next_hop_prefix_list_cmd,
 -       "match ip next-hop prefix-list WORD",
 -       MATCH_STR
 -       IP_STR
 -       "Match next-hop address of route\n"
 -       "Match entries of prefix-lists\n"
 -       "IP prefix-list name\n")
 -{
 -  return rip_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
 -}
 -
 -DEFUN (no_match_ip_next_hop_prefix_list,
 -       no_match_ip_next_hop_prefix_list_cmd,
 -       "no match ip next-hop prefix-list",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match next-hop address of route\n"
 -       "Match entries of prefix-lists\n")
 -{
 -  if (argc == 0)
 -    return rip_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
 -
 -  return rip_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
 -}
 -
 -ALIAS (no_match_ip_next_hop_prefix_list,
 -       no_match_ip_next_hop_prefix_list_val_cmd,
 -       "no match ip next-hop prefix-list WORD",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match next-hop address of route\n"
 -       "Match entries of prefix-lists\n"
 -       "IP prefix-list name\n")
 -
 -DEFUN (match_ip_address,
 -       match_ip_address_cmd,
 -       "match ip address (<1-199>|<1300-2699>|WORD)",
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n"
 -       "IP access-list number\n"
 -       "IP access-list number (expanded range)\n"
 -       "IP Access-list name\n")
 -
 -{
 -  return rip_route_match_add (vty, vty->index, "ip address", argv[0]);
 -}
 -
 -DEFUN (no_match_ip_address, 
 -       no_match_ip_address_cmd,
 -       "no match ip address",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n")
 -{
 -  if (argc == 0)
 -    return rip_route_match_delete (vty, vty->index, "ip address", NULL);
 -
 -  return rip_route_match_delete (vty, vty->index, "ip address", argv[0]);
 -}
 -
 -ALIAS (no_match_ip_address,
 -       no_match_ip_address_val_cmd,
 -       "no match ip address (<1-199>|<1300-2699>|WORD)",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n"
 -       "IP access-list number\n"
 -       "IP access-list number (expanded range)\n"
 -       "IP Access-list name\n")
 -
 -DEFUN (match_ip_address_prefix_list, 
 -       match_ip_address_prefix_list_cmd,
 -       "match ip address prefix-list WORD",
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n"
 -       "Match entries of prefix-lists\n"
 -       "IP prefix-list name\n")
 -{
 -  return rip_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
 -}
 -
 -DEFUN (no_match_ip_address_prefix_list,
 -       no_match_ip_address_prefix_list_cmd,
 -       "no match ip address prefix-list",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n"
 -       "Match entries of prefix-lists\n")
 -{
 -  if (argc == 0)
 -    return rip_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
 -
 -  return rip_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
 -}
 -
 -ALIAS (no_match_ip_address_prefix_list,
 -       no_match_ip_address_prefix_list_val_cmd,
 -       "no match ip address prefix-list WORD",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n"
 -       "Match entries of prefix-lists\n"
 -       "IP prefix-list name\n")
 -
 -DEFUN (match_tag, 
 -       match_tag_cmd,
 -       "match tag <1-4294967295>",
 -       MATCH_STR
 -       "Match tag of route\n"
 -       "Metric value\n")
 -{
 -  return rip_route_match_add (vty, vty->index, "tag", argv[0]);
 -}
 -
 -DEFUN (no_match_tag,
 -       no_match_tag_cmd,
 -       "no match tag",
 -       NO_STR
 -       MATCH_STR
 -       "Match tag of route\n")
 -{
 -  if (argc == 0)
 -    return rip_route_match_delete (vty, vty->index, "tag", NULL);
 -
 -  return rip_route_match_delete (vty, vty->index, "tag", argv[0]);
 -}
 -
 -ALIAS (no_match_tag,
 -       no_match_tag_val_cmd,
 -       "no match tag <1-4294967295>",
 -       NO_STR
 -       MATCH_STR
 -       "Match tag of route\n"
 -       "Metric value\n")
 -
 -/* set functions */
 -
 -DEFUN (set_metric,
 -       set_metric_cmd,
 -       "set metric <0-4294967295>",
 -       SET_STR
 -       "Metric value for destination routing protocol\n"
 -       "Metric value\n")
 +void
 +rip_route_map_reset ()
  {
 -  return rip_route_set_add (vty, vty->index, "metric", argv[0]);
 +  ;
  }
  
 -ALIAS (set_metric,
 -       set_metric_addsub_cmd,
 -       "set metric <+/-metric>",
 -       SET_STR
 -       "Metric value for destination routing protocol\n"
 -       "Add or subtract metric\n")
 -
 -DEFUN (no_set_metric,
 -       no_set_metric_cmd,
 -       "no set metric",
 -       NO_STR
 -       SET_STR
 -       "Metric value for destination routing protocol\n")
 +/* Route-map init */
 +void
 +rip_route_map_init ()
  {
 -  if (argc == 0)
 -    return rip_route_set_delete (vty, vty->index, "metric", NULL);
 +  route_map_init ();
-   route_map_init_vty ();
 -  return rip_route_set_delete (vty, vty->index, "metric", argv[0]);
 -}
 +  route_map_add_hook (rip_route_map_update);
 +  route_map_delete_hook (rip_route_map_update);
  
 -ALIAS (no_set_metric,
 -       no_set_metric_val_cmd,
 -       "no set metric <0-4294967295>",
 -       NO_STR
 -       SET_STR
 -       "Metric value for destination routing protocol\n"
 -       "Metric value\n")
 -
 -ALIAS (no_set_metric,
 -       no_set_metric_addsub_cmd,
 -       "no set metric <+/-metric>",
 -       NO_STR
 -       SET_STR
 -       "Metric value for destination routing protocol\n"
 -       "Add or subtract metric\n")
 -
 -DEFUN (set_ip_nexthop,
 -       set_ip_nexthop_cmd,
 -       "set ip next-hop A.B.C.D",
 -       SET_STR
 -       IP_STR
 -       "Next hop address\n"
 -       "IP address of next hop\n")
 -{
 -  union sockunion su;
 -  int ret;
 +  route_map_match_interface_hook (generic_match_add);
 +  route_map_no_match_interface_hook (generic_match_delete);
  
 -  ret = str2sockunion (argv[0], &su);
 -  if (ret < 0)
 -    {
 -      vty_out (vty, "%% Malformed next-hop address%s", VTY_NEWLINE);
 -      return CMD_WARNING;
 -    }
 -  if (su.sin.sin_addr.s_addr == 0 ||
 -      IPV4_CLASS_DE(su.sin.sin_addr.s_addr))
 -    {
 -      vty_out (vty, "%% nexthop address cannot be 0.0.0.0, multicast "
 -               "or reserved%s", VTY_NEWLINE);
 -      return CMD_WARNING;
 -    }
 +  route_map_match_ip_address_hook (generic_match_add);
 +  route_map_no_match_ip_address_hook (generic_match_delete);
  
 -  return rip_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
 -}
 +  route_map_match_ip_address_prefix_list_hook (generic_match_add);
 +  route_map_no_match_ip_address_prefix_list_hook (generic_match_delete);
  
 -DEFUN (no_set_ip_nexthop,
 -       no_set_ip_nexthop_cmd,
 -       "no set ip next-hop",
 -       NO_STR
 -       SET_STR
 -       IP_STR
 -       "Next hop address\n")
 -{
 -  if (argc == 0)
 -    return rip_route_set_delete (vty, vty->index, "ip next-hop", NULL);
 -  
 -  return rip_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
 -}
 +  route_map_match_ip_next_hop_hook (generic_match_add);
 +  route_map_no_match_ip_next_hop_hook (generic_match_delete);
  
 -ALIAS (no_set_ip_nexthop,
 -       no_set_ip_nexthop_val_cmd,
 -       "no set ip next-hop A.B.C.D",
 -       NO_STR
 -       SET_STR
 -       IP_STR
 -       "Next hop address\n"
 -       "IP address of next hop\n")
 -
 -DEFUN (set_tag,
 -       set_tag_cmd,
 -       "set tag <1-4294967295>",
 -       SET_STR
 -       "Tag value for routing protocol\n"
 -       "Tag value\n")
 -{
 -  return rip_route_set_add (vty, vty->index, "tag", argv[0]);
 -}
 +  route_map_match_ip_next_hop_prefix_list_hook (generic_match_add);
 +  route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete);
  
 -DEFUN (no_set_tag,
 -       no_set_tag_cmd,
 -       "no set tag",
 -       NO_STR
 -       SET_STR
 -       "Tag value for routing protocol\n")
 -{
 -  if (argc == 0)
 -    return rip_route_set_delete (vty, vty->index, "tag", NULL);
 -  
 -  return rip_route_set_delete (vty, vty->index, "tag", argv[0]);
 -}
 +  route_map_match_metric_hook (generic_match_add);
 +  route_map_no_match_metric_hook (generic_match_delete);
  
 -ALIAS (no_set_tag,
 -       no_set_tag_val_cmd,
 -       "no set tag <1-4294967295>",
 -       NO_STR
 -       SET_STR
 -       "Tag value for routing protocol\n"
 -       "Tag value\n")
 +  route_map_match_tag_hook (generic_match_add);
 +  route_map_no_match_tag_hook (generic_match_delete);
  
 -void
 -rip_route_map_reset ()
 -{
 -  ;
 -}
 +  route_map_set_ip_nexthop_hook (generic_set_add);
 +  route_map_no_set_ip_nexthop_hook (generic_set_delete);
  
 -/* Route-map init */
 -void
 -rip_route_map_init ()
 -{
 -  route_map_init ();
 +  route_map_set_metric_hook (generic_set_add);
 +  route_map_no_set_metric_hook (generic_set_delete);
  
 -  route_map_add_hook (rip_route_map_update);
 -  route_map_delete_hook (rip_route_map_update);
 +  route_map_set_tag_hook (generic_set_add);
 +  route_map_no_set_tag_hook (generic_set_delete);
  
    route_map_install_match (&route_match_metric_cmd);
    route_map_install_match (&route_match_interface_cmd);
index 61900408ff036c2a43697d2bddcd8831ee797ec2,19fa70227dfc4254544bd3ac246dc85f37ebd43f..7cab5861bfe4fc6a9d5d88aeb8c33bd1bedcc6ee
@@@ -385,26 -683,7 +385,25 @@@ voi
  ripng_route_map_init ()
  {
    route_map_init ();
-   route_map_init_vty ();
  
 +  route_map_match_interface_hook (generic_match_add);
 +  route_map_no_match_interface_hook (generic_match_delete);
 +
 +  route_map_match_metric_hook (generic_match_add);
 +  route_map_no_match_metric_hook (generic_match_delete);
 +
 +  route_map_match_tag_hook (generic_match_add);
 +  route_map_no_match_tag_hook (generic_match_delete);
 +
 +  route_map_set_ipv6_nexthop_local_hook (generic_set_add);
 +  route_map_no_set_ipv6_nexthop_local_hook (generic_set_delete);
 +
 +  route_map_set_metric_hook (generic_set_add);
 +  route_map_no_set_metric_hook (generic_set_delete);
 +
 +  route_map_set_tag_hook (generic_set_add);
 +  route_map_no_set_tag_hook (generic_set_delete);
 +
    route_map_install_match (&route_match_metric_cmd);
    route_map_install_match (&route_match_interface_cmd);
    route_map_install_match (&route_match_tag_cmd);
diff --cc vtysh/vtysh.c
Simple merge
index 09268d3518f18f31618de4c6d5bf89a2e24172ba,c44219a4958abbf99fb6971adb639c850f5d629f..f7f6334a7755c3415a9483fa7295650ea02cf5d2
   */
  
  #include <zebra.h>
+ #include <net/if_arp.h>
+ #include "linklist.h"
+ #include "if.h"
+ #include "log.h"
+ #include "prefix.h"
+ #include "connected.h"
+ #include "table.h"
+ #include "memory.h"
+ #include "zebra_memory.h"
+ #include "rib.h"
+ #include "thread.h"
+ #include "privs.h"
+ #include "nexthop.h"
+ #include "vrf.h"
+ #include "mpls.h"
  
 +#include "vty.h"
  #include "zebra/zserv.h"
- #include "zebra/rt_netlink.h"
+ #include "zebra/zebra_ns.h"
+ #include "zebra/zebra_vrf.h"
+ #include "zebra/rt.h"
+ #include "zebra/redistribute.h"
+ #include "zebra/interface.h"
+ #include "zebra/debug.h"
+ #include "zebra/rtadv.h"
+ #include "zebra/zebra_ptm.h"
+ #include "zebra/zebra_mpls.h"
+ #include "zebra/kernel_netlink.h"
+ #include "zebra/if_netlink.h"
+ /* Note: on netlink systems, there should be a 1-to-1 mapping between interface
+    names and ifindex values. */
+ static void
+ set_ifindex(struct interface *ifp, ifindex_t ifi_index, struct zebra_ns *zns)
+ {
+   struct interface *oifp;
+   if (((oifp = if_lookup_by_index_per_ns (zns, ifi_index)) != NULL) && (oifp != ifp))
+     {
+       if (ifi_index == IFINDEX_INTERNAL)
+         zlog_err("Netlink is setting interface %s ifindex to reserved "
+                "internal value %u", ifp->name, ifi_index);
+       else
+         {
+         if (IS_ZEBRA_DEBUG_KERNEL)
+           zlog_debug("interface index %d was renamed from %s to %s",
+                       ifi_index, oifp->name, ifp->name);
+         if (if_is_up(oifp))
+           zlog_err("interface rename detected on up interface: index %d "
+                    "was renamed from %s to %s, results are uncertain!",
+                     ifi_index, oifp->name, ifp->name);
+         if_delete_update(oifp);
+         }
+     }
+   ifp->ifindex = ifi_index;
+ }
+ /* Utility function to parse hardware link-layer address and update ifp */
+ static void
+ netlink_interface_update_hw_addr (struct rtattr **tb, struct interface *ifp)
+ {
+   int i;
+   if (tb[IFLA_ADDRESS])
+     {
+       int hw_addr_len;
+       hw_addr_len = RTA_PAYLOAD (tb[IFLA_ADDRESS]);
+       if (hw_addr_len > INTERFACE_HWADDR_MAX)
+         zlog_warn ("Hardware address is too large: %d", hw_addr_len);
+       else
+         {
+           ifp->hw_addr_len = hw_addr_len;
+           memcpy (ifp->hw_addr, RTA_DATA (tb[IFLA_ADDRESS]), hw_addr_len);
+           for (i = 0; i < hw_addr_len; i++)
+             if (ifp->hw_addr[i] != 0)
+               break;
+           if (i == hw_addr_len)
+             ifp->hw_addr_len = 0;
+           else
+             ifp->hw_addr_len = hw_addr_len;
+         }
+     }
+ }
+ static enum zebra_link_type
+ netlink_to_zebra_link_type (unsigned int hwt)
+ {
+   switch (hwt)
+   {
+     case ARPHRD_ETHER: return ZEBRA_LLT_ETHER;
+     case ARPHRD_EETHER: return ZEBRA_LLT_EETHER;
+     case ARPHRD_AX25: return ZEBRA_LLT_AX25;
+     case ARPHRD_PRONET: return ZEBRA_LLT_PRONET;
+     case ARPHRD_IEEE802: return ZEBRA_LLT_IEEE802;
+     case ARPHRD_ARCNET: return ZEBRA_LLT_ARCNET;
+     case ARPHRD_APPLETLK: return ZEBRA_LLT_APPLETLK;
+     case ARPHRD_DLCI: return ZEBRA_LLT_DLCI;
+     case ARPHRD_ATM: return ZEBRA_LLT_ATM;
+     case ARPHRD_METRICOM: return ZEBRA_LLT_METRICOM;
+     case ARPHRD_IEEE1394: return ZEBRA_LLT_IEEE1394;
+     case ARPHRD_EUI64: return ZEBRA_LLT_EUI64;
+     case ARPHRD_INFINIBAND: return ZEBRA_LLT_INFINIBAND;
+     case ARPHRD_SLIP: return ZEBRA_LLT_SLIP;
+     case ARPHRD_CSLIP: return ZEBRA_LLT_CSLIP;
+     case ARPHRD_SLIP6: return ZEBRA_LLT_SLIP6;
+     case ARPHRD_CSLIP6: return ZEBRA_LLT_CSLIP6;
+     case ARPHRD_RSRVD: return ZEBRA_LLT_RSRVD;
+     case ARPHRD_ADAPT: return ZEBRA_LLT_ADAPT;
+     case ARPHRD_ROSE: return ZEBRA_LLT_ROSE;
+     case ARPHRD_X25: return ZEBRA_LLT_X25;
+     case ARPHRD_PPP: return ZEBRA_LLT_PPP;
+     case ARPHRD_CISCO: return ZEBRA_LLT_CHDLC;
+     case ARPHRD_LAPB: return ZEBRA_LLT_LAPB;
+     case ARPHRD_RAWHDLC: return ZEBRA_LLT_RAWHDLC;
+     case ARPHRD_TUNNEL: return ZEBRA_LLT_IPIP;
+     case ARPHRD_TUNNEL6: return ZEBRA_LLT_IPIP6;
+     case ARPHRD_FRAD: return ZEBRA_LLT_FRAD;
+     case ARPHRD_SKIP: return ZEBRA_LLT_SKIP;
+     case ARPHRD_LOOPBACK: return ZEBRA_LLT_LOOPBACK;
+     case ARPHRD_LOCALTLK: return ZEBRA_LLT_LOCALTLK;
+     case ARPHRD_FDDI: return ZEBRA_LLT_FDDI;
+     case ARPHRD_SIT: return ZEBRA_LLT_SIT;
+     case ARPHRD_IPDDP: return ZEBRA_LLT_IPDDP;
+     case ARPHRD_IPGRE: return ZEBRA_LLT_IPGRE;
+     case ARPHRD_PIMREG: return ZEBRA_LLT_PIMREG;
+     case ARPHRD_HIPPI: return ZEBRA_LLT_HIPPI;
+     case ARPHRD_ECONET: return ZEBRA_LLT_ECONET;
+     case ARPHRD_IRDA: return ZEBRA_LLT_IRDA;
+     case ARPHRD_FCPP: return ZEBRA_LLT_FCPP;
+     case ARPHRD_FCAL: return ZEBRA_LLT_FCAL;
+     case ARPHRD_FCPL: return ZEBRA_LLT_FCPL;
+     case ARPHRD_FCFABRIC: return ZEBRA_LLT_FCFABRIC;
+     case ARPHRD_IEEE802_TR: return ZEBRA_LLT_IEEE802_TR;
+     case ARPHRD_IEEE80211: return ZEBRA_LLT_IEEE80211;
+     case ARPHRD_IEEE802154: return ZEBRA_LLT_IEEE802154;
+ #ifdef ARPHRD_IP6GRE
+     case ARPHRD_IP6GRE: return ZEBRA_LLT_IP6GRE;
+ #endif
+ #ifdef ARPHRD_IEEE802154_PHY
+     case ARPHRD_IEEE802154_PHY: return ZEBRA_LLT_IEEE802154_PHY;
+ #endif
+     default: return ZEBRA_LLT_UNKNOWN;
+   }
+ }
+ #define parse_rtattr_nested(tb, max, rta) \
+           netlink_parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta))
+ static void
+ netlink_vrf_change (struct nlmsghdr *h, struct rtattr *tb, const char *name)
+ {
+   struct ifinfomsg *ifi;
+   struct rtattr *linkinfo[IFLA_INFO_MAX+1];
+   struct rtattr *attr[IFLA_VRF_MAX+1];
+   struct vrf *vrf;
+   struct zebra_vrf *zvrf;
+   u_int32_t nl_table_id;
+   ifi = NLMSG_DATA (h);
+   memset (linkinfo, 0, sizeof linkinfo);
+   parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb);
+   if (!linkinfo[IFLA_INFO_DATA]) {
+     if (IS_ZEBRA_DEBUG_KERNEL)
+       zlog_debug ("%s: IFLA_INFO_DATA missing from VRF message: %s", __func__, name);
+     return;
+   }
+   memset (attr, 0, sizeof attr);
+   parse_rtattr_nested(attr, IFLA_VRF_MAX, linkinfo[IFLA_INFO_DATA]);
+   if (!attr[IFLA_VRF_TABLE]) {
+     if (IS_ZEBRA_DEBUG_KERNEL)
+       zlog_debug ("%s: IFLA_VRF_TABLE missing from VRF message: %s", __func__, name);
+     return;
+   }
+   nl_table_id = *(u_int32_t *)RTA_DATA(attr[IFLA_VRF_TABLE]);
+   if (h->nlmsg_type == RTM_NEWLINK)
+     {
+       /* If VRF already exists, we just return; status changes are handled
+        * against the VRF "interface".
+        */
+       vrf = vrf_lookup ((vrf_id_t)ifi->ifi_index);
+       if (vrf && vrf->info)
+         return;
+       if (IS_ZEBRA_DEBUG_KERNEL)
+         zlog_debug ("RTM_NEWLINK for VRF %s(%u) table %u",
+                     name, ifi->ifi_index, nl_table_id);
+       /*
+        * vrf_get is implied creation if it does not exist
+        */
+       vrf = vrf_get((vrf_id_t)ifi->ifi_index, name); // It would create vrf
+       if (!vrf)
+         {
+           zlog_err ("VRF %s id %u not created", name, ifi->ifi_index);
+           return;
+         }
+       /* Enable the created VRF. */
+       if (!vrf_enable (vrf))
+         {
+           zlog_err ("Failed to enable VRF %s id %u", name, ifi->ifi_index);
+           return;
+         }
+       /*
+        * This is the only place that we get the actual kernel table_id
+        * being used.  We need it to set the table_id of the routes
+        * we are passing to the kernel.... And to throw some totally
+        * awesome parties. that too.
+        */
+       zvrf = (struct zebra_vrf *)vrf->info;
+       zvrf->table_id = nl_table_id;
+     }
+   else //h->nlmsg_type == RTM_DELLINK
+     {
+       if (IS_ZEBRA_DEBUG_KERNEL)
+         zlog_debug ("RTM_DELLINK for VRF %s(%u)", name, ifi->ifi_index);
+       vrf = vrf_lookup ((vrf_id_t)ifi->ifi_index);
+       if (!vrf)
+         {
+         zlog_warn ("%s: vrf not found", __func__);
+         return;
+       }
+       vrf_delete (vrf);
+     }
+ }
+ /* Called from interface_lookup_netlink().  This function is only used
+    during bootstrap. */
+ static int
+ netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h,
+                    ns_id_t ns_id)
+ {
+   int len;
+   struct ifinfomsg *ifi;
+   struct rtattr *tb[IFLA_MAX + 1];
+   struct rtattr *linkinfo[IFLA_MAX + 1];
+   struct interface *ifp;
+   char *name = NULL;
+   char *kind = NULL;
+   char *slave_kind = NULL;
+   int vrf_device = 0;
+   struct zebra_ns *zns;
+   vrf_id_t vrf_id = VRF_DEFAULT;
+   zns = zebra_ns_lookup (ns_id);
+   ifi = NLMSG_DATA (h);
+   if (h->nlmsg_type != RTM_NEWLINK)
+     return 0;
+   len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg));
+   if (len < 0)
+     return -1;
+   if (ifi->ifi_family == AF_BRIDGE)
+     return 0;
+   /* Looking up interface name. */
+   memset (tb, 0, sizeof tb);
+   netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
+ #ifdef IFLA_WIRELESS
+   /* check for wireless messages to ignore */
+   if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0))
+     {
+       if (IS_ZEBRA_DEBUG_KERNEL)
+         zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__);
+       return 0;
+     }
+ #endif /* IFLA_WIRELESS */
+   if (tb[IFLA_IFNAME] == NULL)
+     return -1;
+   name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
+   if (tb[IFLA_LINKINFO])
+     {
+       memset (linkinfo, 0, sizeof linkinfo);
+       parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
+       if (linkinfo[IFLA_INFO_KIND])
+         kind = RTA_DATA(linkinfo[IFLA_INFO_KIND]);
+ #if HAVE_DECL_IFLA_INFO_SLAVE_KIND
+       if (linkinfo[IFLA_INFO_SLAVE_KIND])
+          slave_kind = RTA_DATA(linkinfo[IFLA_INFO_SLAVE_KIND]);
+ #endif
+       if (kind && strcmp(kind, "vrf") == 0)
+         {
+           vrf_device = 1;
+           netlink_vrf_change(h, tb[IFLA_LINKINFO], name);
+           vrf_id = (vrf_id_t)ifi->ifi_index;
+         }
+     }
+   if (tb[IFLA_MASTER])
+     {
+       if (slave_kind && (strcmp(slave_kind, "vrf") == 0))
+         vrf_id = *(u_int32_t *)RTA_DATA(tb[IFLA_MASTER]);
+     }
+   /* Add interface. */
+   ifp = if_get_by_name_vrf (name, vrf_id);
+   set_ifindex(ifp, ifi->ifi_index, zns);
+   ifp->flags = ifi->ifi_flags & 0x0000fffff;
+   if (vrf_device)
+     SET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
+   ifp->mtu6 = ifp->mtu = *(uint32_t *) RTA_DATA (tb[IFLA_MTU]);
+   ifp->metric = 0;
+   ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
+   /* Hardware type and address. */
+   ifp->ll_type = netlink_to_zebra_link_type (ifi->ifi_type);
+   netlink_interface_update_hw_addr (tb, ifp);
+   if_add_update (ifp);
+   return 0;
+ }
+ /* Interface lookup by netlink socket. */
+ int
+ interface_lookup_netlink (struct zebra_ns *zns)
+ {
+   int ret;
+   /* Get interface information. */
+   ret = netlink_request (AF_PACKET, RTM_GETLINK, &zns->netlink_cmd);
+   if (ret < 0)
+     return ret;
+   ret = netlink_parse_info (netlink_interface, &zns->netlink_cmd, zns, 0);
+   if (ret < 0)
+     return ret;
+   /* Get IPv4 address of the interfaces. */
+   ret = netlink_request (AF_INET, RTM_GETADDR, &zns->netlink_cmd);
+   if (ret < 0)
+     return ret;
+   ret = netlink_parse_info (netlink_interface_addr, &zns->netlink_cmd, zns, 0);
+   if (ret < 0)
+     return ret;
+ #ifdef HAVE_IPV6
+   /* Get IPv6 address of the interfaces. */
+   ret = netlink_request (AF_INET6, RTM_GETADDR, &zns->netlink_cmd);
+   if (ret < 0)
+     return ret;
+   ret = netlink_parse_info (netlink_interface_addr, &zns->netlink_cmd, zns, 0);
+   if (ret < 0)
+     return ret;
+ #endif /* HAVE_IPV6 */
+   return 0;
+ }
+ /* Interface address modification. */
+ static int
+ netlink_address (int cmd, int family, struct interface *ifp,
+                  struct connected *ifc)
+ {
+   int bytelen;
+   struct prefix *p;
+   struct
+   {
+     struct nlmsghdr n;
+     struct ifaddrmsg ifa;
+     char buf[NL_PKT_BUF_SIZE];
+   } req;
+   struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT);
+   p = ifc->address;
+   memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
+   bytelen = (family == AF_INET ? 4 : 16);
+   req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg));
+   req.n.nlmsg_flags = NLM_F_REQUEST;
+   req.n.nlmsg_type = cmd;
+   req.ifa.ifa_family = family;
+   req.ifa.ifa_index = ifp->ifindex;
+   req.ifa.ifa_prefixlen = p->prefixlen;
+   addattr_l (&req.n, sizeof req, IFA_LOCAL, &p->u.prefix, bytelen);
+   if (family == AF_INET && cmd == RTM_NEWADDR)
+     {
+       if (!CONNECTED_PEER(ifc) && ifc->destination)
+         {
+           p = ifc->destination;
+           addattr_l (&req.n, sizeof req, IFA_BROADCAST, &p->u.prefix,
+                      bytelen);
+         }
+     }
+   if (CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
+     SET_FLAG (req.ifa.ifa_flags, IFA_F_SECONDARY);
+   if (ifc->label)
+     addattr_l (&req.n, sizeof req, IFA_LABEL, ifc->label,
+                strlen (ifc->label) + 1);
+   return netlink_talk (&req.n, &zns->netlink_cmd, zns);
+ }
+ int
+ kernel_address_add_ipv4 (struct interface *ifp, struct connected *ifc)
+ {
+   return netlink_address (RTM_NEWADDR, AF_INET, ifp, ifc);
+ }
+ int
+ kernel_address_delete_ipv4 (struct interface *ifp, struct connected *ifc)
+ {
+   return netlink_address (RTM_DELADDR, AF_INET, ifp, ifc);
+ }
+ int
+ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h,
+                         ns_id_t ns_id)
+ {
+   int len;
+   struct ifaddrmsg *ifa;
+   struct rtattr *tb[IFA_MAX + 1];
+   struct interface *ifp;
+   void *addr;
+   void *broad;
+   u_char flags = 0;
+   char *label = NULL;
+   struct zebra_ns *zns;
+   zns = zebra_ns_lookup (ns_id);
+   ifa = NLMSG_DATA (h);
+   if (ifa->ifa_family != AF_INET
+ #ifdef HAVE_IPV6
+       && ifa->ifa_family != AF_INET6
+ #endif /* HAVE_IPV6 */
+     )
+     return 0;
+   if (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR)
+     return 0;
+   len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifaddrmsg));
+   if (len < 0)
+     return -1;
+   memset (tb, 0, sizeof tb);
+   netlink_parse_rtattr (tb, IFA_MAX, IFA_RTA (ifa), len);
+   ifp = if_lookup_by_index_per_ns (zns, ifa->ifa_index);
+   if (ifp == NULL)
+     {
+       zlog_err ("netlink_interface_addr can't find interface by index %d",
+                 ifa->ifa_index);
+       return -1;
+     }
+   if (IS_ZEBRA_DEBUG_KERNEL)    /* remove this line to see initial ifcfg */
+     {
+       char buf[BUFSIZ];
+       zlog_debug ("netlink_interface_addr %s %s flags 0x%x:",
+                  nl_msg_type_to_str (h->nlmsg_type), ifp->name,
+                  ifa->ifa_flags);
+       if (tb[IFA_LOCAL])
+         zlog_debug ("  IFA_LOCAL     %s/%d",
+                   inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_LOCAL]),
+                              buf, BUFSIZ), ifa->ifa_prefixlen);
+       if (tb[IFA_ADDRESS])
+         zlog_debug ("  IFA_ADDRESS   %s/%d",
+                   inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_ADDRESS]),
+                                buf, BUFSIZ), ifa->ifa_prefixlen);
+       if (tb[IFA_BROADCAST])
+         zlog_debug ("  IFA_BROADCAST %s/%d",
+                   inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_BROADCAST]),
+                              buf, BUFSIZ), ifa->ifa_prefixlen);
+       if (tb[IFA_LABEL] && strcmp (ifp->name, RTA_DATA (tb[IFA_LABEL])))
+         zlog_debug ("  IFA_LABEL     %s", (char *)RTA_DATA (tb[IFA_LABEL]));
+       if (tb[IFA_CACHEINFO])
+         {
+           struct ifa_cacheinfo *ci = RTA_DATA (tb[IFA_CACHEINFO]);
+           zlog_debug ("  IFA_CACHEINFO pref %d, valid %d",
+                       ci->ifa_prefered, ci->ifa_valid);
+         }
+     }
+   /* logic copied from iproute2/ip/ipaddress.c:print_addrinfo() */
+   if (tb[IFA_LOCAL] == NULL)
+     tb[IFA_LOCAL] = tb[IFA_ADDRESS];
+   if (tb[IFA_ADDRESS] == NULL)
+     tb[IFA_ADDRESS] = tb[IFA_LOCAL];
+   /* local interface address */
+   addr = (tb[IFA_LOCAL] ? RTA_DATA(tb[IFA_LOCAL]) : NULL);
+   /* is there a peer address? */
+   if (tb[IFA_ADDRESS] &&
+       memcmp(RTA_DATA(tb[IFA_ADDRESS]), RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_ADDRESS])))
+     {
+       broad = RTA_DATA(tb[IFA_ADDRESS]);
+       SET_FLAG (flags, ZEBRA_IFA_PEER);
+     }
+   else
+     /* seeking a broadcast address */
+     broad = (tb[IFA_BROADCAST] ? RTA_DATA(tb[IFA_BROADCAST]) : NULL);
+   /* addr is primary key, SOL if we don't have one */
+   if (addr == NULL)
+     {
+       zlog_debug ("%s: NULL address", __func__);
+       return -1;
+     }
+   /* Flags. */
+   if (ifa->ifa_flags & IFA_F_SECONDARY)
+     SET_FLAG (flags, ZEBRA_IFA_SECONDARY);
+   /* Label */
+   if (tb[IFA_LABEL])
+     label = (char *) RTA_DATA (tb[IFA_LABEL]);
+   if (ifp && label && strcmp (ifp->name, label) == 0)
+     label = NULL;
+   /* Register interface address to the interface. */
+   if (ifa->ifa_family == AF_INET)
+     {
+       if (h->nlmsg_type == RTM_NEWADDR)
+         connected_add_ipv4 (ifp, flags,
+                             (struct in_addr *) addr, ifa->ifa_prefixlen,
+                             (struct in_addr *) broad, label);
+       else
+         connected_delete_ipv4 (ifp, flags,
+                                (struct in_addr *) addr, ifa->ifa_prefixlen,
+                                (struct in_addr *) broad);
+     }
+ #ifdef HAVE_IPV6
+   if (ifa->ifa_family == AF_INET6)
+     {
+       if (h->nlmsg_type == RTM_NEWADDR)
+         {
+           /* Only consider valid addresses; we'll not get a notification from
+            * the kernel till IPv6 DAD has completed, but at init time, Quagga
+            * does query for and will receive all addresses.
+            */
+           if (!(ifa->ifa_flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)))
+             connected_add_ipv6 (ifp, flags, (struct in6_addr *) addr,
+                     ifa->ifa_prefixlen, (struct in6_addr *) broad, label);
+         }
+       else
+         connected_delete_ipv6 (ifp,
+                                (struct in6_addr *) addr, ifa->ifa_prefixlen,
+                                (struct in6_addr *) broad);
+     }
+ #endif /* HAVE_IPV6 */
+   return 0;
+ }
+ int
+ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
+                      ns_id_t ns_id)
+ {
+   int len;
+   struct ifinfomsg *ifi;
+   struct rtattr *tb[IFLA_MAX + 1];
+   struct rtattr *linkinfo[IFLA_MAX + 1];
+   struct interface *ifp;
+   char *name = NULL;
+   char *kind = NULL;
+   char *slave_kind = NULL;
+   int vrf_device = 0;
+   struct zebra_ns *zns;
+   vrf_id_t vrf_id = VRF_DEFAULT;
+   zns = zebra_ns_lookup (ns_id);
+   ifi = NLMSG_DATA (h);
+   if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK))
+     {
+       /* If this is not link add/delete message so print warning. */
+       zlog_warn ("netlink_link_change: wrong kernel message %d",
+                  h->nlmsg_type);
+       return 0;
+     }
+   len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg));
+   if (len < 0)
+     return -1;
+   if (ifi->ifi_family == AF_BRIDGE)
+     return 0;
+   /* Looking up interface name. */
+   memset (tb, 0, sizeof tb);
+   netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
+ #ifdef IFLA_WIRELESS
+   /* check for wireless messages to ignore */
+   if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0))
+     {
+       if (IS_ZEBRA_DEBUG_KERNEL)
+         zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__);
+       return 0;
+     }
+ #endif /* IFLA_WIRELESS */
+   if (tb[IFLA_IFNAME] == NULL)
+     return -1;
+   name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
+   if (tb[IFLA_LINKINFO])
+     {
+       memset (linkinfo, 0, sizeof linkinfo);
+       parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
+       if (linkinfo[IFLA_INFO_KIND])
+         kind = RTA_DATA(linkinfo[IFLA_INFO_KIND]);
+ #if HAVE_DECL_IFLA_INFO_SLAVE_KIND
+       if (linkinfo[IFLA_INFO_SLAVE_KIND])
+           slave_kind = RTA_DATA(linkinfo[IFLA_INFO_SLAVE_KIND]);
+ #endif
+       if (kind && strcmp(kind, "vrf") == 0)
+         {
+           vrf_device = 1;
+           netlink_vrf_change(h, tb[IFLA_LINKINFO], name);
+           vrf_id = (vrf_id_t)ifi->ifi_index;
+         }
+     }
+   /* See if interface is present. */
+   ifp = if_lookup_by_index_per_ns (zns, ifi->ifi_index);
+   if (h->nlmsg_type == RTM_NEWLINK)
+     {
+       if (tb[IFLA_MASTER])
+       {
+           if (slave_kind && (strcmp(slave_kind, "vrf") == 0))
+             vrf_id = *(u_int32_t *)RTA_DATA(tb[IFLA_MASTER]);
+       }
+       if (ifp == NULL || !CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
+         {
+           /* Add interface notification from kernel */
+           if (IS_ZEBRA_DEBUG_KERNEL)
+             zlog_debug ("RTM_NEWLINK for %s(%u) (ifp %p) vrf_id %u flags 0x%x",
+                         name, ifi->ifi_index, ifp, vrf_id, ifi->ifi_flags);
+           if (ifp == NULL)
+             {
+               /* unknown interface */
+               ifp = if_get_by_name_vrf (name, vrf_id);
+             }
+           else
+             {
+               /* pre-configured interface, learnt now */
+               if (ifp->vrf_id != vrf_id)
+                 if_update_vrf (ifp, name, strlen(name), vrf_id);
+             }
+           /* Update interface information. */
+           set_ifindex(ifp, ifi->ifi_index, zns);
+           ifp->flags = ifi->ifi_flags & 0x0000fffff;
+           if (vrf_device)
+             SET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
+           ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
+           ifp->metric = 0;
+           ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
+           netlink_interface_update_hw_addr (tb, ifp);
+           /* Inform clients, install any configured addresses. */
+           if_add_update (ifp);
+         }
+       else if (ifp->vrf_id != vrf_id)
+         {
+           /* VRF change for an interface. */
+           if (IS_ZEBRA_DEBUG_KERNEL)
+             zlog_debug ("RTM_NEWLINK vrf-change for %s(%u) "
+                         "vrf_id %u -> %u flags 0x%x",
+                         name, ifp->ifindex, ifp->vrf_id,
+                         vrf_id, ifi->ifi_flags);
+           if_handle_vrf_change (ifp, vrf_id);
+         }
+       else
+         {
+           /* Interface status change. */
+           if (IS_ZEBRA_DEBUG_KERNEL)
+              zlog_debug ("RTM_NEWLINK status for %s(%u) flags 0x%x",
+                           name, ifp->ifindex, ifi->ifi_flags);
+           set_ifindex(ifp, ifi->ifi_index, zns);
+           ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
+           ifp->metric = 0;
+           netlink_interface_update_hw_addr (tb, ifp);
+           if (if_is_no_ptm_operative (ifp))
+             {
+               ifp->flags = ifi->ifi_flags & 0x0000fffff;
+               if (!if_is_no_ptm_operative (ifp))
+                 if_down (ifp);
+             else if (if_is_operative (ifp))
+               /* Must notify client daemons of new interface status. */
+               zebra_interface_up_update (ifp);
+             }
+           else
+             {
+               ifp->flags = ifi->ifi_flags & 0x0000fffff;
+               if (if_is_operative (ifp))
+                 if_up (ifp);
+             }
+         }
+     }
+   else
+     {
+       /* Delete interface notification from kernel */
+       if (ifp == NULL)
+         {
+           zlog_warn ("RTM_DELLINK for unknown interface %s(%u)",
+                      name, ifi->ifi_index);
+           return 0;
+         }
+       if (IS_ZEBRA_DEBUG_KERNEL)
+         zlog_debug ("RTM_DELLINK for %s(%u)", name, ifp->ifindex);
+       UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
+       if (!vrf_device)
+         if_delete_update (ifp);
+     }
+   return 0;
+ }
  
  /* Interface information read by netlink. */
  void
Simple merge
index afcd5f02357fc90dabd5e77192e1abb4c4891af8,f16fd55c981f13bb3d05749bb2ef39a9e59f1883..90d71e6351e80993848525cbfa6024548350b295
@@@ -1178,7 -312,8 +313,7 @@@ netlink_route_change (struct sockaddr_n
    struct rtattr *tb[RTA_MAX + 1];
    u_char zebra_flags = 0;
    struct prefix p;
+   vrf_id_t vrf_id = VRF_DEFAULT;
 -  
    char anyaddr[16] = { 0 };
  
    int index;
index c5a6a4969151dcadb8d97a3c44c2242f5b0b7bc9,6543298605e719374465eb890383920b99d13127..f2cba10943021fda2691206dca7fe16a9035e92f
  
  #include "log.h"
  #include "rib.h"
 +#include "vty.h"
  
- #include "zserv.h"
- #include "zebra_ns.h"
- #include "zebra_vrf.h"
- #include "rt_netlink.h"
+ #include "zebra/zserv.h"
+ #include "zebra/zebra_ns.h"
+ #include "zebra/zebra_vrf.h"
+ #include "zebra/kernel_netlink.h"
+ #include "zebra/rt_netlink.h"
  #include "nexthop.h"
  
- #include "zebra_fpm_private.h"
+ #include "zebra/zebra_fpm_private.h"
  
  /*
   * addr_to_a
index 9b407ed3921d8a131f21929b1b5cd47b94156484,21fd6a4db97b3c324d2b8bbf683e2160aa25cb95..59725561f5ce801597e7cf41681d842cd3741e24
@@@ -1462,21 -1788,29 +1462,20 @@@ zebra_route_map_init (
  {
    install_element (CONFIG_NODE, &ip_protocol_cmd);
    install_element (CONFIG_NODE, &no_ip_protocol_cmd);
 -  install_element (CONFIG_NODE, &no_ip_protocol_val_cmd);
    install_element (VIEW_NODE, &show_ip_protocol_cmd);
 -  install_element (ENABLE_NODE, &show_ip_protocol_cmd);
    install_element (CONFIG_NODE, &ipv6_protocol_cmd);
    install_element (CONFIG_NODE, &no_ipv6_protocol_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_protocol_val_cmd);
    install_element (VIEW_NODE, &show_ipv6_protocol_cmd);
 -  install_element (ENABLE_NODE, &show_ipv6_protocol_cmd);
    install_element (CONFIG_NODE, &ip_protocol_nht_rmap_cmd);
    install_element (CONFIG_NODE, &no_ip_protocol_nht_rmap_cmd);
 -  install_element (CONFIG_NODE, &no_ip_protocol_nht_rmap_val_cmd);
    install_element (VIEW_NODE, &show_ip_protocol_nht_cmd);
 -  install_element (ENABLE_NODE, &show_ip_protocol_nht_cmd);
    install_element (CONFIG_NODE, &ipv6_protocol_nht_rmap_cmd);
    install_element (CONFIG_NODE, &no_ipv6_protocol_nht_rmap_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_protocol_nht_rmap_val_cmd);
    install_element (VIEW_NODE, &show_ipv6_protocol_nht_cmd);
 -  install_element (ENABLE_NODE, &show_ipv6_protocol_nht_cmd);
    install_element (CONFIG_NODE, &zebra_route_map_timer_cmd);
    install_element (CONFIG_NODE, &no_zebra_route_map_timer_cmd);
 -  install_element (CONFIG_NODE, &no_zebra_route_map_timer_val_cmd);
  
    route_map_init ();
-   route_map_init_vty ();
  
    route_map_add_hook (zebra_route_map_add);
    route_map_delete_hook (zebra_route_map_delete);
diff --cc zebra/zserv.c
Simple merge