]> git.puffer.fish Git - mirror/frr.git/commitdiff
[zebra] Routemap support on received routes, with 'set src' command (linux)
authorPaul Jakma <paul.jakma@sun.com>
Wed, 2 May 2007 16:05:35 +0000 (16:05 +0000)
committerPaul Jakma <paul.jakma@sun.com>
Wed, 2 May 2007 16:05:35 +0000 (16:05 +0000)
2007-05-01 David L Stevens <dlstevens@us.ibm.com>

* (general) These changes collectively add route-map and
  prefix-list support to zebra and fix a bug in "show
  route-map" (with no argument).
* doc/main.texi: added route-map, prefix-list, ip protocol
  and set src documentation
* lib/command.h: added PROTOCOL_NODE type
* lib/log.c: (proto_name2num) new function, protocol name to
  number translation.
* lib/routemap.c: (vty_show_route_map) fixed "show route-map"
  without route-map name
* lib/routemap.h: added RMAP_ZEBRA type
* lib/zebra.h: added proto_name2num() prototype
* vtysh/extract.pl.in: added VTYSH_ZEBRA flag for route-map and
  plist
* vtysh/Makefile.am: added zebra_routemap.c
* vtysh/vtysh.h: added VTYSH_ZEBRA flag to VTYSH_RMAP
* zebra/connected.c: (connected_up_ipv4) added src preference argument
  to rib_add_ipv4()
* zebra/kernel_socket.c: (rtm_read) ditto
* zebra/main.c: added prefix list initialization
* zebra/Makefile.am: added zebra_routemap.c source file
* zebra/rib.h: added generic address union "g_addr" and use in
  existing places that had an explicit union.
  Added "src" to struct nexthop.
  Added preferred src arg to nexthop_ipv4_add and rib_add_ipv4.
* zebra/rt_netlink.c: (netlink_routing_table) set preferred source on
  netlink messages.
  (netlink_route_change) ditto
  (netlink_route_multipath) ditto.
* zebra/rtread_getmsg.c: (handle_route_entry) added (NULL) src to
  rib_add_ipv4() call.
* zebra/rtread_proc.c: (proc_route_read) ditto
* zebra/zebra_rib.c: (nexthop_ipv4_add) add src argument.
  (nexthop_ipv4_ifindex_add) ditto
  (rib_add_ipv4) ditto
  (nexthop_active_check) Add route-map processing.
* zebra/zebra_routemap.c: new file for zebra route-map commands.
* zebra/zebra_vty.c: (ip_protocol_cmd) Apply route-map to protocol
  (vty_show_ip_route_detail) added "src" printing
  (vty_show_ip_route) ditto
  (show_ip_protocol_cmd) new command, list routemaps.
  (config_write_protocol) write out routemap protocl config.
  (zebra_vty_init) Install the new routemap protocol commands.
* zebra/zserv.c: (zread_ipv4_add) added (NULL) src arg
  (zebra_init) init zebra route-maps.
* zebra/zserv.h: add zebra_route_map_init

24 files changed:
doc/ChangeLog
doc/main.texi
lib/ChangeLog
lib/command.h
lib/log.c
lib/routemap.c
lib/routemap.h
lib/zebra.h
vtysh/ChangeLog
vtysh/extract.pl.in
vtysh/vtysh.h
zebra/ChangeLog
zebra/Makefile.am
zebra/connected.c
zebra/kernel_socket.c
zebra/main.c
zebra/rib.h
zebra/rt_netlink.c
zebra/rtread_getmsg.c
zebra/rtread_proc.c
zebra/zebra_rib.c
zebra/zebra_vty.c
zebra/zserv.c
zebra/zserv.h

index 586852c6ea4b731bd1fcd71703132363591627b7..b8c81e74964f882b4e56887d05ad924adfba315c 100644 (file)
@@ -1,3 +1,8 @@
+2007-05-01 David L Stevens <dlstevens@us.ibm.com>
+
+       * main.texi: added route-map, prefix-list, ip protocol
+         and set src documentation
+
 2007-04-30 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
 
        * ospfd.texi: Add a paragraph to the description of the OSPFv2
index b76a636b396e5249291cddae4820fc186b2b0081..9966b356d35432c198af6abdf4a23ad2c0c324ee 100644 (file)
@@ -10,6 +10,7 @@ different routing protocols.
 * Invoking zebra::              Running the program
 * Interface Commands::          Commands for zebra interfaces
 * Static Route Commands::       Commands for adding static routes
+* zebra Route Filtering::       Commands for zebra route filtering
 * zebra Terminal Mode Commands::  Commands for zebra's VTY
 @end menu
 
@@ -183,6 +184,49 @@ and later).  After setting @var{tableno} with this command,
 static routes defined after this are added to the specified table.
 @end deffn
 
+@node zebra Route Filtering
+@section zebra Route Filtering
+Zebra supports @command{prefix-list} and @command{route-map} to match
+routes received from other quagga components.  The
+@command{permit}/@command{deny} facilities provided by these commands
+can be used to filter which routes zebra will install in the kernel.
+
+@deffn Command {ip protocol @var{protocol} route-map @var{routemap}} {}
+Apply a route-map filter to routes for the specified protocol. @var{protocol}
+can be @b{any} or one of
+@b{system},
+@b{kernel},
+@b{connected},
+@b{static},
+@b{rip},
+@b{ripng},
+@b{ospf},
+@b{ospf6},
+@b{isis},
+@b{bgp},
+@b{hsls}.
+@end deffn
+
+@deffn {Route Map} {set src @var{address}}
+Within a route-map, set the preferred source address for matching routes
+when installing in the kernel.
+@end deffn
+
+@example
+The following creates a prefix-list that matches all addresses, a route-map
+that sets the preferred source address, and applies the route-map to all
+@command{rip} routes.
+
+@group
+ip prefix-list ANY permit 0.0.0.0/0 le 32
+route-map RM1 permit 10
+     match ip address prefix-list ANY
+     set src 10.0.0.1
+
+ip protocol rip route-map RM1
+@end group
+@end example
+
 @node zebra Terminal Mode Commands
 @section zebra Terminal Mode Commands
 
@@ -209,6 +253,15 @@ C* 203.181.89.240/28      eth0
 @deffn Command {show interface} {}
 @end deffn
 
+@deffn Command {show ip prefix-list [@var{name}]} {}
+@end deffn
+
+@deffn Command {show route-map [@var{name}]} {}
+@end deffn
+
+@deffn Command {show ip protocol} {}
+@end deffn
+
 @deffn Command {show ipforward} {}
 Display whether the host's IP forwarding function is enabled or not.
 Almost any UNIX kernel can be configured with IP forwarding disabled.
index f8fdd11ef525b595a92f830e9c4496be21c95bce..3787b68cbf048758aa590654e659e44e3b4eeab4 100644 (file)
@@ -1,3 +1,16 @@
+2007-05-01 David L Stevens <dlstevens@us.ibm.com>
+
+       * (general) These changes collectively add route-map and
+         prefix-list support to zebra and fix a bug in "show
+         route-map" (with no argument).
+       * command.h: added PROTOCOL_NODE type
+       * log.c: (proto_name2num) new function, protocol name to
+         number translation.
+       * routemap.c: (vty_show_route_map) fixed "show route-map"
+         without route-map name
+       * routemap.h: added RMAP_ZEBRA type
+       * zebra.h: added proto_name2num() prototype
+
 2007-04-29 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
 
        * log.c: (quagga_timestamp) Optimize the subsecond timestamp generation.
index ce18731e6763ccf5e1f7787ab948e56feaa8cc9c..a72537881d4105c85acb3b55a62115b6ede858fa 100644 (file)
@@ -99,6 +99,7 @@ enum node_type
   SMUX_NODE,                   /* SNMP configuration node. */
   DUMP_NODE,                   /* Packet dump node. */
   FORWARDING_NODE,             /* IP forwarding node. */
+  PROTOCOL_NODE,                /* protocol filtering node */
   VTY_NODE                     /* Vty node. */
 };
 
index 21bf3f2f6b6d88ccf2088bc1efa21ab9f801890f..cbf76af9921bff955526b92d5f2de8ee1f1cde9e 100644 (file)
--- a/lib/log.c
+++ b/lib/log.c
@@ -886,3 +886,17 @@ zserv_command_string (unsigned int command)
     }
   return command_types[command].string;
 }
+
+#define RTSIZE (sizeof(route_types)/sizeof(route_types[0]))
+
+int
+proto_name2num(const char *s)
+{
+   unsigned i;
+
+   for (i=0; i<RTSIZE; ++i)
+     if (strcasecmp(s, route_types[i].string) == 0)
+       return route_types[i].type;
+   return -1;
+}
+#undef RTSIZE
index 55cc33c775fa8bd26d7cd6865df21b63e25e4d1e..58ed09a7cf7a049360796131e18195a04a3aa381 100644 (file)
@@ -268,6 +268,11 @@ vty_show_route_map (struct vty *vty, const char *name)
           return CMD_WARNING;
         }
     }
+  else
+    {
+      for (map = route_map_master.head; map; map = map->next)
+       vty_show_route_map_entry (vty, map);
+    }
   return CMD_SUCCESS;
 }
 
@@ -1135,23 +1140,17 @@ ALIAS (no_rmap_onmatch_goto,
        "Continue on a different entry within the route-map\n"
        "Route-map entry sequence number\n")
 
-DEFUN (rmap_show,
-       rmap_show_cmd,
-       "show route-map",
-       SHOW_STR
-       "route-map information\n")
-{
-    return vty_show_route_map (vty, NULL);
-}
-
 DEFUN (rmap_show_name,
        rmap_show_name_cmd,
-       "show route-map WORD",
+       "show route-map [WORD]",
        SHOW_STR
        "route-map information\n"
        "route-map name\n")
 {
-    return vty_show_route_map (vty, argv[0]);
+    const char *name = NULL;
+    if (argc)
+      name = argv[0];
+    return vty_show_route_map (vty, name);
 }
 
 ALIAS (rmap_onmatch_goto,
@@ -1322,6 +1321,5 @@ route_map_init_vty (void)
   install_element (RMAP_NODE, &no_rmap_description_cmd);
    
   /* Install show command */
-  install_element (ENABLE_NODE, &rmap_show_cmd);
   install_element (ENABLE_NODE, &rmap_show_name_cmd);
 }
index c9cf44105acf36b62af934da59de11e5f6ee69b7..321e1927aa64a8bf09f8cb75f8abf81db412c6c0 100644 (file)
@@ -45,7 +45,8 @@ typedef enum
   RMAP_RIPNG,
   RMAP_OSPF,
   RMAP_OSPF6,
-  RMAP_BGP
+  RMAP_BGP,
+  RMAP_ZEBRA
 } route_map_object_t;
 
 typedef enum
index 2e2f8cda03b2ed3e7159ee694ebc7fd86e78b6f8..8553739942636149f406ec6832cf0a828624152e 100644 (file)
@@ -444,6 +444,9 @@ extern const char *zebra_route_string(unsigned int route_type);
 extern char zebra_route_char(unsigned int route_type);
 /* Map a zserv command type to the same string, 
  * e.g. ZEBRA_INTERFACE_ADD -> "ZEBRA_INTERFACE_ADD" */
+/* Map a protocol name to its number. e.g. ZEBRA_ROUTE_BGP->9*/
+extern int proto_name2num(const char *s);
+
 extern const char *zserv_command_string (unsigned int command);
 
 /* Zebra's family types. */
index 4ca5df9451520031f87c53a7c6b4fee38808130f..a582b959e278bd9468c05310e5f20c46fc6fa56c 100644 (file)
@@ -1,3 +1,10 @@
+2007-05-01 David L Stevens <dlstevens@us.ibm.com>
+
+       * vtysh/extract.pl.in: added VTYSH_ZEBRA flag for route-map and
+         plist
+       * vtysh/Makefile.am: added zebra_routemap.c
+       * vtysh/vtysh.h: added VTYSH_ZEBRA flag to VTYSH_RMAP
+
 2007-04-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
 
        * vtysh.c: (vtysh_log_timestamp_precision,
index 98a9ddde81ec827cebf9b6f7e8e281ddaa8aff60..723fe8d613b1f7d389c1e9cae66cfe4f240a82a9 100755 (executable)
@@ -94,16 +94,16 @@ foreach (@ARGV) {
               $protocol = "VTYSH_RIPD";
            }
            if ($file =~ /routemap.c/) {
-              $protocol = "VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD";
+              $protocol = "VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA";
            }
            if ($file =~ /filter.c/) {
               $protocol = "VTYSH_ALL";
            }
            if ($file =~ /plist.c/) {
              if ($defun_array[1] =~ m/ipv6/) {
-                 $protocol = "VTYSH_RIPNGD|VTYSH_OSPF6D|VTYSH_BGPD";
+                 $protocol = "VTYSH_RIPNGD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA";
               } else {
-                 $protocol = "VTYSH_RIPD|VTYSH_OSPFD|VTYSH_BGPD";
+                 $protocol = "VTYSH_RIPD|VTYSH_OSPFD|VTYSH_BGPD|VTYSH_ZEBRA";
               }
            }
            if ($file =~ /distribute.c/) {
index dd2bcbd0a03f281ac0e8d9c08748443751204934..3ed0dd328ed13e180af0474e5f0dfbf00e2af085 100644 (file)
@@ -30,7 +30,7 @@
 #define VTYSH_BGPD   0x20
 #define VTYSH_ISISD  0x40
 #define VTYSH_ALL        VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD
-#define VTYSH_RMAP       VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD
+#define VTYSH_RMAP       VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD
 #define VTYSH_INTERFACE          VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD
 
 /* vtysh local configuration file. */
index 11e406d499396f0a1ae6a1b8e2d046a831038908..c08bbe4e3ad2efb682e0787b5eb00f3a320bbff4 100644 (file)
@@ -1,3 +1,39 @@
+2007-05-01 David L Stevens <dlstevens@us.ibm.com>
+
+       * (general) These changes collectively add route-map and
+         prefix-list support to zebra and fix a bug in "show
+         route-map" (with no argument).
+       * connected.c: (connected_up_ipv4) added src preference argument
+         to rib_add_ipv4()
+       * kernel_socket.c: (rtm_read) ditto
+       * main.c: added prefix list initialization
+       * Makefile.am: added zebra_routemap.c source file
+       * rib.h: added generic address union "g_addr" and use in
+         existing places that had an explicit union.
+         Added "src" to struct nexthop.
+         Added preferred src arg to nexthop_ipv4_add and rib_add_ipv4.
+       * rt_netlink.c: (netlink_routing_table) set preferred source on 
+         netlink messages.
+         (netlink_route_change) ditto
+         (netlink_route_multipath) ditto.
+       * rtread_getmsg.c: (handle_route_entry) added (NULL) src to
+         rib_add_ipv4() call.
+       * rtread_proc.c: (proc_route_read) ditto
+       * zebra_rib.c: (nexthop_ipv4_add) add src argument.
+         (nexthop_ipv4_ifindex_add) ditto
+         (rib_add_ipv4) ditto
+         (nexthop_active_check) Add route-map processing.
+       * zebra_routemap.c: new file for zebra route-map commands.
+       * zebra_vty.c: (ip_protocol_cmd) Apply route-map to protocol
+         (vty_show_ip_route_detail) added "src" printing
+         (vty_show_ip_route) ditto
+         (show_ip_protocol_cmd) new command, list routemaps.
+         (config_write_protocol) write out routemap protocl config.
+         (zebra_vty_init) Install the new routemap protocol commands.
+       * zserv.c: (zread_ipv4_add) added (NULL) src arg
+         (zebra_init) init zebra route-maps.
+       * zserv.h: add zebra_route_map_init
+       
 2007-04-29 Paul Jakma <paul.jakma@sun.com>
 
        * ioctl{_solaris,}.c: (if_get_mtu) Fix missing ; in last commit.
index 7527562a03d0c4bad9b7bc29b6c6a59cf28e65aa..5d8db4115c788c5232863a4aeecd62a4d6f7e490 100644 (file)
@@ -24,7 +24,7 @@ sbin_PROGRAMS = zebra
 noinst_PROGRAMS = testzebra
 
 zebra_SOURCES = \
-       zserv.c main.c interface.c connected.c zebra_rib.c \
+       zserv.c main.c interface.c connected.c zebra_rib.c zebra_routemap.c \
        redistribute.c debug.c rtadv.c zebra_snmp.c zebra_vty.c \
        irdp_main.c irdp_interface.c irdp_packet.c router-id.c
 
index 74e10ac681b26983f3c177a2a237a1c76fcef27a..53aa25432fa4eb76c865f8231ff4c0e46fa54e27 100644 (file)
@@ -187,8 +187,8 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
   if (prefix_ipv4_any (&p))
     return;
 
-  rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, RT_TABLE_MAIN, 
-                ifp->metric, 0);
+  rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex,
+       RT_TABLE_MAIN, ifp->metric, 0);
 
   rib_update ();
 }
index 5281236769044245cce937d42316d82598520a98..b7c7ccc1d512b11f921370f404c723fd6bfe18ce 100644 (file)
@@ -775,7 +775,7 @@ rtm_read (struct rt_msghdr *rtm)
           || rtm->rtm_type == RTM_ADD
           || rtm->rtm_type == RTM_CHANGE)
        rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, 
-                     &p, &gate.sin.sin_addr, 0, 0, 0, 0);
+                     &p, &gate.sin.sin_addr, NULL, 0, 0, 0, 0);
       else
        rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, 
                      &p, &gate.sin.sin_addr, 0, 0);
index ed45bd13f7a80e73553345c8df679b62071f51ec..7d895799b42e4648a0157b25e1f19dfb25ec83f1 100644 (file)
@@ -29,6 +29,7 @@
 #include "memory.h"
 #include "prefix.h"
 #include "log.h"
+#include "plist.h"
 #include "privs.h"
 #include "sigevent.h"
 
@@ -324,6 +325,7 @@ main (int argc, char **argv)
   router_id_init();
   zebra_vty_init ();
   access_list_init ();
+  prefix_list_init ();
   rtadv_init ();
 #ifdef HAVE_IRDP
   irdp_init();
index 04fbbecf9e0c68aa86b234f55ab05230f145960e..7b2bd426a8915f460c799a87a350219281d7cd08 100644 (file)
 #define DISTANCE_INFINITY  255
 
 /* Routing information base. */
+
+union g_addr {
+  struct in_addr ipv4;
+#ifdef HAVE_IPV6
+  struct in6_addr ipv6;
+#endif /* HAVE_IPV6 */
+};
+
 struct rib
 {
   /* Status Flags for the *route_node*, but kept in the head RIB.. */
@@ -167,24 +175,13 @@ struct nexthop
 #define NEXTHOP_FLAG_RECURSIVE  (1 << 2) /* Recursive nexthop. */
 
   /* Nexthop address or interface name. */
-  union
-  {
-    struct in_addr ipv4;
-#ifdef HAVE_IPV6
-    struct in6_addr ipv6;
-#endif /* HAVE_IPV6*/
-  } gate;
+  union g_addr gate;
 
   /* Recursive lookup nexthop. */
   u_char rtype;
   unsigned int rifindex;
-  union
-  {
-    struct in_addr ipv4;
-#ifdef HAVE_IPV6
-    struct in6_addr ipv6;
-#endif /* HAVE_IPV6 */
-  } rgate;
+  union g_addr rgate;
+  union g_addr src;
 };
 
 /* Routing table instance.  */
@@ -212,7 +209,8 @@ struct vrf
 extern struct nexthop *nexthop_ifindex_add (struct rib *, unsigned int);
 extern struct nexthop *nexthop_ifname_add (struct rib *, char *);
 extern struct nexthop *nexthop_blackhole_add (struct rib *);
-extern struct nexthop *nexthop_ipv4_add (struct rib *, struct in_addr *);
+extern struct nexthop *nexthop_ipv4_add (struct rib *, struct in_addr *,
+                                        struct in_addr *);
 #ifdef HAVE_IPV6
 extern struct nexthop *nexthop_ipv6_add (struct rib *, struct in6_addr *);
 #endif /* HAVE_IPV6 */
@@ -225,8 +223,9 @@ extern struct route_table *vrf_static_table (afi_t afi, safi_t safi, u_int32_t i
  * All rib_add_ipv[46]* functions will not just add prefix into RIB, but
  * also implicitly withdraw equal prefix of same type. */
 extern int rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p, 
-                        struct in_addr *gate, unsigned int ifindex, 
-                        u_int32_t vrf_id, u_int32_t, u_char);
+                        struct in_addr *gate, struct in_addr *src,
+                        unsigned int ifindex, u_int32_t vrf_id,
+                        u_int32_t, u_char);
 
 extern int rib_add_ipv4_multipath (struct prefix_ipv4 *, struct rib *);
 
index e2f1f9d9336a5f416e3953b35ec9219a0ae96212..3b602c45ed41dcc3852b2bcaeaf5de202cf85bb0 100644 (file)
@@ -725,6 +725,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
 
   void *dest;
   void *gate;
+  void *src;
 
   rtm = NLMSG_DATA (h);
 
@@ -764,6 +765,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
   metric = 0;
   dest = NULL;
   gate = NULL;
+  src = NULL;
 
   if (tb[RTA_OIF])
     index = *(int *) RTA_DATA (tb[RTA_OIF]);
@@ -773,6 +775,9 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
   else
     dest = anyaddr;
 
+  if (tb[RTA_PREFSRC])
+    src = RTA_DATA (tb[RTA_PREFSRC]);
+
   /* Multipath treatment is needed. */
   if (tb[RTA_GATEWAY])
     gate = RTA_DATA (tb[RTA_GATEWAY]);
@@ -787,7 +792,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
       memcpy (&p.prefix, dest, 4);
       p.prefixlen = rtm->rtm_dst_len;
 
-      rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table, metric, 0);
+      rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, src, index, table, metric, 0);
     }
 #ifdef HAVE_IPV6
   if (rtm->rtm_family == AF_INET6)
@@ -834,6 +839,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
   int table;
   void *dest;
   void *gate;
+  void *src;
 
   rtm = NLMSG_DATA (h);
 
@@ -890,6 +896,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
   index = 0;
   dest = NULL;
   gate = NULL;
+  src = NULL;
 
   if (tb[RTA_OIF])
     index = *(int *) RTA_DATA (tb[RTA_OIF]);
@@ -902,6 +909,9 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
   if (tb[RTA_GATEWAY])
     gate = RTA_DATA (tb[RTA_GATEWAY]);
 
+  if (tb[RTA_PREFSRC])
+    src = RTA_DATA (tb[RTA_PREFSRC]);
+
   if (rtm->rtm_family == AF_INET)
     {
       struct prefix_ipv4 p;
@@ -920,7 +930,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
         }
 
       if (h->nlmsg_type == RTM_NEWROUTE)
-        rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, 0, 0);
+        rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, src, index, table, 0, 0);
       else
         rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table);
     }
@@ -1489,7 +1499,9 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
                    {
                      addattr_l (&req.n, sizeof req, RTA_GATEWAY,
                                 &nexthop->rgate.ipv4, bytelen);
-
+                      if (nexthop->src.ipv4.s_addr)
+                         addattr_l(&req.n, sizeof req, RTA_PREFSRC,
+                                    &nexthop->src.ipv4, bytelen);
                      if (IS_ZEBRA_DEBUG_KERNEL)
                        zlog_debug("netlink_route_multipath() (recursive, "
                                   "1 hop): nexthop via %s if %u",
@@ -1519,6 +1531,11 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
                    {
                      addattr32 (&req.n, sizeof req, RTA_OIF,
                                 nexthop->rifindex);
+                      if ((nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX
+                           || nexthop->rtype == NEXTHOP_TYPE_IFINDEX)
+                          && nexthop->src.ipv4.s_addr)
+                        addattr_l (&req.n, sizeof req, RTA_PREFSRC,
+                                &nexthop->src.ipv4, bytelen);
 
                      if (IS_ZEBRA_DEBUG_KERNEL)
                        zlog_debug("netlink_route_multipath() (recursive, "
@@ -1547,6 +1564,9 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
                    {
                      addattr_l (&req.n, sizeof req, RTA_GATEWAY,
                                 &nexthop->gate.ipv4, bytelen);
+                     if (nexthop->src.ipv4.s_addr)
+                        addattr_l (&req.n, sizeof req, RTA_PREFSRC,
+                                &nexthop->src.ipv4, bytelen);
 
                      if (IS_ZEBRA_DEBUG_KERNEL)
                        zlog_debug("netlink_route_multipath() (single hop): "
@@ -1571,8 +1591,19 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
 #endif /* HAVE_IPV6 */
                   if (nexthop->type == NEXTHOP_TYPE_IFINDEX
                       || nexthop->type == NEXTHOP_TYPE_IFNAME
-                      || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
-                      || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
+                      || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
+                   {
+                     addattr32 (&req.n, sizeof req, RTA_OIF, nexthop->ifindex);
+
+                     if (nexthop->src.ipv4.s_addr)
+                        addattr_l (&req.n, sizeof req, RTA_PREFSRC,
+                                &nexthop->src.ipv4, bytelen);
+
+                     if (IS_ZEBRA_DEBUG_KERNEL)
+                       zlog_debug("netlink_route_multipath() (single hop): "
+                                  "nexthop via if %u", nexthop->ifindex);
+                   }
+                  else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
                       || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
                    {
                      addattr32 (&req.n, sizeof req, RTA_OIF, nexthop->ifindex);
@@ -1596,6 +1627,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
       char buf[1024];
       struct rtattr *rta = (void *) buf;
       struct rtnexthop *rtnh;
+      union g_addr *src = NULL;
 
       rta->rta_type = RTA_MULTIPATH;
       rta->rta_len = RTA_LENGTH (0);
@@ -1640,6 +1672,9 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
                                      &nexthop->rgate.ipv4, bytelen);
                       rtnh->rtnh_len += sizeof (struct rtattr) + 4;
 
+                     if (nexthop->src.ipv4.s_addr)
+                        src = &nexthop->src;
+
                      if (IS_ZEBRA_DEBUG_KERNEL)
                        zlog_debug("netlink_route_multipath() (recursive, "
                                   "multihop): nexthop via %s if %u",
@@ -1662,10 +1697,20 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
                    }
 #endif /* HAVE_IPV6 */
                   /* ifindex */
-                  if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
-                      || nexthop->rtype == NEXTHOP_TYPE_IFNAME
-                      || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX
-                      || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX
+                  if (nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX
+                     || nexthop->rtype == NEXTHOP_TYPE_IFINDEX
+                      || nexthop->rtype == NEXTHOP_TYPE_IFNAME)
+                   {
+                     rtnh->rtnh_ifindex = nexthop->rifindex;
+                      if (nexthop->src.ipv4.s_addr)
+                        src = &nexthop->src;
+
+                     if (IS_ZEBRA_DEBUG_KERNEL)
+                       zlog_debug("netlink_route_multipath() (recursive, "
+                                  "multihop): nexthop via if %u",
+                                  nexthop->rifindex);
+                   }
+                 else if (nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX
                       || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME)
                    {
                      rtnh->rtnh_ifindex = nexthop->rifindex;
@@ -1701,6 +1746,9 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
                                     &nexthop->gate.ipv4, bytelen);
                      rtnh->rtnh_len += sizeof (struct rtattr) + 4;
 
+                     if (nexthop->src.ipv4.s_addr)
+                        src = &nexthop->src;
+
                       if (IS_ZEBRA_DEBUG_KERNEL)
                        zlog_debug("netlink_route_multipath() (multihop): "
                                   "nexthop via %s if %u",
@@ -1723,10 +1771,18 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
                    }
 #endif /* HAVE_IPV6 */
                   /* ifindex */
-                  if (nexthop->type == NEXTHOP_TYPE_IFINDEX
-                      || nexthop->type == NEXTHOP_TYPE_IFNAME
-                      || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
-                      || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
+                  if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
+                     || nexthop->type == NEXTHOP_TYPE_IFINDEX
+                      || nexthop->type == NEXTHOP_TYPE_IFNAME)
+                    {
+                     rtnh->rtnh_ifindex = nexthop->ifindex;
+                     if (nexthop->src.ipv4.s_addr)
+                       src = &nexthop->src;
+                     if (IS_ZEBRA_DEBUG_KERNEL)
+                       zlog_debug("netlink_route_multipath() (multihop): "
+                                  "nexthop via if %u", nexthop->ifindex);
+                   }
+                  else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
                       || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
                    {
                      rtnh->rtnh_ifindex = nexthop->ifindex;
@@ -1746,6 +1802,8 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
                 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
             }
         }
+      if (src)
+        addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src->ipv4, bytelen);
 
       if (rta->rta_len > RTA_LENGTH (0))
         addattr_l (&req.n, 1024, RTA_MULTIPATH, RTA_DATA (rta),
index 1b0c8965f919135be1d582672f7cda0d16d58afc..3e065c6f4ff6ea51fb0c97bd283f38ebfde8e8e0 100644 (file)
@@ -90,7 +90,7 @@ handle_route_entry (mib2_ipRouteEntry_t *routeEntry)
        gateway.s_addr = routeEntry->ipRouteNextHop;
 
        rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &prefix,
-                     &gateway, 0, 0, 0, 0);
+                     &gateway, NULL, 0, 0, 0, 0);
 }
 
 void
index 93ec238fffd012eaa17cac16f33e2b8abe38cb9e..1de435a494255fa757d5bb6aeb3532c7e2dce394 100644 (file)
@@ -96,7 +96,7 @@ proc_route_read (void)
       p.prefixlen = ip_masklen (tmpmask);
       sscanf (gate, "%lX", (unsigned long *)&gateway);
 
-      rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gateway, 0, 0, 0, 0);
+      rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gateway, NULL, 0, 0, 0, 0);
     }
 
   fclose (fp);
index 02c73d1296dc7585752fee5408824634e3dd4114..693b3331389776ab6c0509ee32eab61274c58aaf 100644 (file)
@@ -32,6 +32,8 @@
 #include "linklist.h"
 #include "thread.h"
 #include "workqueue.h"
+#include "prefix.h"
+#include "routemap.h"
 
 #include "zebra/rib.h"
 #include "zebra/rt.h"
@@ -233,7 +235,7 @@ nexthop_ifname_add (struct rib *rib, char *ifname)
 }
 
 struct nexthop *
-nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4)
+nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
 {
   struct nexthop *nexthop;
 
@@ -241,6 +243,8 @@ nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4)
   memset (nexthop, 0, sizeof (struct nexthop));
   nexthop->type = NEXTHOP_TYPE_IPV4;
   nexthop->gate.ipv4 = *ipv4;
+  if (src)
+    nexthop->src.ipv4 = *src;
 
   nexthop_add (rib, nexthop);
 
@@ -249,7 +253,7 @@ nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4)
 
 static struct nexthop *
 nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4, 
-                         unsigned int ifindex)
+                          struct in_addr *src, unsigned int ifindex)
 {
   struct nexthop *nexthop;
 
@@ -257,6 +261,8 @@ nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
   memset (nexthop, 0, sizeof (struct nexthop));
   nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
   nexthop->gate.ipv4 = *ipv4;
+  if (src)
+    nexthop->src.ipv4 = *src;
   nexthop->ifindex = ifindex;
 
   nexthop_add (rib, nexthop);
@@ -685,12 +691,20 @@ rib_match_ipv6 (struct in6_addr *addr)
 }
 #endif /* HAVE_IPV6 */
 
+#define RIB_SYSTEM_ROUTE(R) \
+        ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
+
 static int
 nexthop_active_check (struct route_node *rn, struct rib *rib,
                      struct nexthop *nexthop, int set)
 {
   struct interface *ifp;
+  route_map_result_t ret = RMAP_MATCH;
+  extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
+  struct route_map *rmap;
+  int family;
 
+  family = 0;
   switch (nexthop->type)
     {
     case NEXTHOP_TYPE_IFINDEX:
@@ -700,8 +714,9 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
       else
        UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
       break;
-    case NEXTHOP_TYPE_IFNAME:
     case NEXTHOP_TYPE_IPV6_IFNAME:
+      family = AFI_IP6;
+    case NEXTHOP_TYPE_IFNAME:
       ifp = if_lookup_by_name (nexthop->ifname);
       if (ifp && if_is_up (ifp))
        {
@@ -718,6 +733,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
       break;
     case NEXTHOP_TYPE_IPV4:
     case NEXTHOP_TYPE_IPV4_IFINDEX:
+      family = AFI_IP;
       if (nexthop_active_ipv4 (rib, nexthop, set, rn))
        SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
       else
@@ -725,12 +741,14 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
       break;
 #ifdef HAVE_IPV6
     case NEXTHOP_TYPE_IPV6:
+      family = AFI_IP6;
       if (nexthop_active_ipv6 (rib, nexthop, set, rn))
        SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
       else
        UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
       break;
     case NEXTHOP_TYPE_IPV6_IFINDEX:
+      family = AFI_IP6;
       if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
        {
          ifp = if_lookup_by_index (nexthop->ifindex);
@@ -754,6 +772,26 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
     default:
       break;
     }
+  if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
+    return 0;
+
+  if (RIB_SYSTEM_ROUTE(rib) ||
+      (family == AFI_IP && rn->p.family != AF_INET) ||
+      (family == AFI_IP6 && rn->p.family != AF_INET6))
+    return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+
+  rmap = 0;
+  if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
+               proto_rm[family][rib->type])
+    rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
+  if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
+    rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
+  if (rmap) {
+      ret = route_map_apply(rmap, &rn->p, RMAP_ZEBRA, nexthop);
+  }
+
+  if (ret == RMAP_DENYMATCH)
+    UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
   return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
 }
 
@@ -782,8 +820,6 @@ nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
 }
 
 \f
-#define RIB_SYSTEM_ROUTE(R) \
-        ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
 
 static void
 rib_install_kernel (struct route_node *rn, struct rib *rib)
@@ -1231,7 +1267,8 @@ rib_delnode (struct route_node *rn, struct rib *rib)
 
 int
 rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p, 
-             struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
+             struct in_addr *gate, struct in_addr *src,
+             unsigned int ifindex, u_int32_t vrf_id,
              u_int32_t metric, u_char distance)
 {
   struct rib *rib;
@@ -1300,9 +1337,9 @@ rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
   if (gate)
     {
       if (ifindex)
-       nexthop_ipv4_ifindex_add (rib, gate, ifindex);
+       nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
       else
-       nexthop_ipv4_add (rib, gate);
+       nexthop_ipv4_add (rib, gate, src);
     }
   else
     nexthop_ifindex_add (rib, ifindex);
@@ -1539,7 +1576,7 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
       switch (si->type)
         {
           case STATIC_IPV4_GATEWAY:
-            nexthop_ipv4_add (rib, &si->gate.ipv4);
+            nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
             break;
           case STATIC_IPV4_IFNAME:
             nexthop_ifname_add (rib, si->gate.ifname);
@@ -1563,7 +1600,7 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
       switch (si->type)
         {
           case STATIC_IPV4_GATEWAY:
-            nexthop_ipv4_add (rib, &si->gate.ipv4);
+            nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
             break;
           case STATIC_IPV4_IFNAME:
             nexthop_ifname_add (rib, si->gate.ifname);
index 68e6f920795f58ef7612e2bd43f8b97abd629b31..1487745b1546a2d19cfc44087429b0fd60bf092a 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <zebra.h>
 
+#include "memory.h"
 #include "if.h"
 #include "prefix.h"
 #include "command.h"
@@ -474,6 +475,59 @@ DEFUN (no_ip_route_mask_flags_distance2,
   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
 }
 
+char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];    /* "any" == ZEBRA_ROUTE_MAX */
+
+DEFUN (ip_protocol,
+       ip_protocol_cmd,
+       "ip protocol PROTO route-map ROUTE-MAP",
+       NO_STR
+       "Apply route map to PROTO\n"
+       "Protocol name\n"
+       "Route map name\n")
+{
+  int i;
+
+  if (strcasecmp(argv[0], "any") == 0)
+    i = ZEBRA_ROUTE_MAX;
+  else
+    i = proto_name2num(argv[0]);
+  if (i < 0)
+    {
+      vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
+               VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+  if (proto_rm[AFI_IP][i])
+    XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]);
+  proto_rm[AFI_IP][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_ip_protocol,
+       no_ip_protocol_cmd,
+       "no ip protocol PROTO",
+       NO_STR
+       "Remove route map from PROTO\n"
+       "Protocol name\n")
+{
+  int i;
+
+  if (strcasecmp(argv[0], "any") == 0)
+    i = ZEBRA_ROUTE_MAX;
+  else
+    i = proto_name2num(argv[0]);
+  if (i < 0)
+    {
+      vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
+               VTY_NEWLINE);
+     return CMD_WARNING;
+    }
+  if (proto_rm[AFI_IP][i])
+    XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]);
+  proto_rm[AFI_IP][i] = NULL;
+  return CMD_SUCCESS;
+}
+
 /* New RIB.  Detailed information for IPv4 route. */
 static void
 vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
@@ -529,6 +583,8 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
 
       for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
        {
+          char addrstr[32];
+
          vty_out (vty, "  %c",
                   CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
 
@@ -575,6 +631,31 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
                  break;
                }
            }
+         switch (nexthop->type)
+            {
+            case NEXTHOP_TYPE_IPV4:
+            case NEXTHOP_TYPE_IPV4_IFINDEX:
+            case NEXTHOP_TYPE_IPV4_IFNAME:
+              if (nexthop->src.ipv4.s_addr)
+                {
+                 if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr,
+                     sizeof addrstr))
+                    vty_out (vty, ", src %s", addrstr);
+                }
+              break;
+            case NEXTHOP_TYPE_IPV6:
+            case NEXTHOP_TYPE_IPV6_IFINDEX:
+            case NEXTHOP_TYPE_IPV6_IFNAME:
+              if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
+                {
+                 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, addrstr,
+                     sizeof addrstr))
+                    vty_out (vty, ", src %s", addrstr);
+                }
+              break;
+            default:
+              break;
+            }
          vty_out (vty, "%s", VTY_NEWLINE);
        }
       vty_out (vty, "%s", VTY_NEWLINE);
@@ -658,6 +739,29 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
              break;
            }
        }
+      switch (nexthop->type)
+        {
+          case NEXTHOP_TYPE_IPV4:
+          case NEXTHOP_TYPE_IPV4_IFINDEX:
+          case NEXTHOP_TYPE_IPV4_IFNAME:
+            if (nexthop->src.ipv4.s_addr)
+              {
+               if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
+                  vty_out (vty, ", src %s", buf);
+              }
+            break;
+          case NEXTHOP_TYPE_IPV6:
+          case NEXTHOP_TYPE_IPV6_IFINDEX:
+          case NEXTHOP_TYPE_IPV6_IFNAME:
+            if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
+              {
+               if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
+                  vty_out (vty, ", src %s", buf);
+              }
+            break;
+          default:
+           break;
+        }
 
       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
                vty_out (vty, ", bh");
@@ -1805,6 +1909,34 @@ DEFUN (show_ipv6_route_prefix,
   return CMD_SUCCESS;
 }
 
+DEFUN (show_ip_protocol,
+       show_ip_protocol_cmd,
+       "show ip protocol",
+        SHOW_STR
+        IP_STR
+       "IP protocol filtering status\n")
+{
+    int i; 
+
+    vty_out(vty, "Protocol    : route-map %s", VTY_NEWLINE);
+    vty_out(vty, "------------------------%s", VTY_NEWLINE);
+    for (i=0;i<ZEBRA_ROUTE_MAX;i++)
+    {
+        if (proto_rm[AFI_IP][i])
+          vty_out (vty, "%-10s  : %-10s%s", zebra_route_string(i),
+                                       proto_rm[AFI_IP][i],
+                                       VTY_NEWLINE);
+        else
+          vty_out (vty, "%-10s  : none%s", zebra_route_string(i), VTY_NEWLINE);
+    }
+    if (proto_rm[AFI_IP][i])
+      vty_out (vty, "%-10s  : %-10s%s", "any", proto_rm[AFI_IP][i],
+                                       VTY_NEWLINE);
+    else
+      vty_out (vty, "%-10s  : none%s", "any", VTY_NEWLINE);
+
+    return CMD_SUCCESS;
+}
 
 /* Write IPv6 static route configuration. */
 static int
@@ -1874,6 +2006,27 @@ zebra_ip_config (struct vty *vty)
   return write;
 }
 
+/* ip protocol configuration write function */
+static int config_write_protocol(struct vty *vty)
+{  
+  int i;
+
+  for (i=0;i<ZEBRA_ROUTE_MAX;i++)
+    {
+      if (proto_rm[AFI_IP][i])
+        vty_out (vty, "ip protocol %s route-map %s%s", zebra_route_string(i),
+                 proto_rm[AFI_IP][i], VTY_NEWLINE);
+    }
+  if (proto_rm[AFI_IP][ZEBRA_ROUTE_MAX])
+      vty_out (vty, "ip protocol %s route-map %s%s", "any",
+               proto_rm[AFI_IP][ZEBRA_ROUTE_MAX], VTY_NEWLINE);
+
+  return 1;
+}   
+
+/* table node for protocol filtering */
+struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
+
 /* IP node for static routes. */
 struct cmd_node ip_node = { IP_NODE,  "",  1 };
 
@@ -1882,7 +2035,12 @@ void
 zebra_vty_init (void)
 {
   install_node (&ip_node, zebra_ip_config);
+  install_node (&protocol_node, config_write_protocol);
 
+  install_element (CONFIG_NODE, &ip_protocol_cmd);
+  install_element (CONFIG_NODE, &no_ip_protocol_cmd);
+  install_element (VIEW_NODE, &show_ip_protocol_cmd);
+  install_element (ENABLE_NODE, &show_ip_protocol_cmd);
   install_element (CONFIG_NODE, &ip_route_cmd);
   install_element (CONFIG_NODE, &ip_route_flags_cmd);
   install_element (CONFIG_NODE, &ip_route_flags2_cmd);
index 1703d3f569258718906ea84371d721c200a2bcba..22a6bed26e9a3ccafa74c4f706b7d357b28c01f8 100644 (file)
@@ -781,7 +781,7 @@ zread_ipv4_add (struct zserv *client, u_short length)
              break;
            case ZEBRA_NEXTHOP_IPV4:
              nexthop.s_addr = stream_get_ipv4 (s);
-             nexthop_ipv4_add (rib, &nexthop);
+             nexthop_ipv4_add (rib, &nexthop, NULL);
              break;
            case ZEBRA_NEXTHOP_IPV6:
              stream_forward_getp (s, IPV6_MAX_BYTELEN);
@@ -1733,4 +1733,7 @@ zebra_init (void)
   install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
   install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
 #endif /* HAVE_IPV6 */
+
+  /* Route-map */
+  zebra_route_map_init ();
 }
index 9a570fb3bea19ef8e8587e490576a7256c0b879d..68c26f234d5782de4529564995c16707f889f362 100644 (file)
@@ -93,6 +93,7 @@ extern void rib_init (void);
 extern void interface_list (void);
 extern void kernel_init (void);
 extern void route_read (void);
+extern void zebra_route_map_init (void);
 extern void zebra_snmp_init (void);
 extern void zebra_vty_init (void);