diff options
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/ChangeLog | 36 | ||||
-rw-r--r-- | zebra/Makefile.am | 2 | ||||
-rw-r--r-- | zebra/connected.c | 4 | ||||
-rw-r--r-- | zebra/kernel_socket.c | 2 | ||||
-rw-r--r-- | zebra/main.c | 2 | ||||
-rw-r--r-- | zebra/rib.h | 33 | ||||
-rw-r--r-- | zebra/rt_netlink.c | 84 | ||||
-rw-r--r-- | zebra/rtread_getmsg.c | 2 | ||||
-rw-r--r-- | zebra/rtread_proc.c | 2 | ||||
-rw-r--r-- | zebra/zebra_rib.c | 57 | ||||
-rw-r--r-- | zebra/zebra_vty.c | 158 | ||||
-rw-r--r-- | zebra/zserv.c | 5 | ||||
-rw-r--r-- | zebra/zserv.h | 1 |
13 files changed, 341 insertions, 47 deletions
diff --git a/zebra/ChangeLog b/zebra/ChangeLog index 11e406d4..c08bbe4e 100644 --- a/zebra/ChangeLog +++ b/zebra/ChangeLog @@ -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. diff --git a/zebra/Makefile.am b/zebra/Makefile.am index 7527562a..5d8db411 100644 --- a/zebra/Makefile.am +++ b/zebra/Makefile.am @@ -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 diff --git a/zebra/connected.c b/zebra/connected.c index 74e10ac6..53aa2543 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -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 (); } diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 52812367..b7c7ccc1 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -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); diff --git a/zebra/main.c b/zebra/main.c index ed45bd13..7d895799 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -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(); diff --git a/zebra/rib.h b/zebra/rib.h index 04fbbecf..7b2bd426 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -28,6 +28,14 @@ #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 *); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index e2f1f9d9..3b602c45 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -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), diff --git a/zebra/rtread_getmsg.c b/zebra/rtread_getmsg.c index 1b0c8965..3e065c6f 100644 --- a/zebra/rtread_getmsg.c +++ b/zebra/rtread_getmsg.c @@ -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 diff --git a/zebra/rtread_proc.c b/zebra/rtread_proc.c index 93ec238f..1de435a4 100644 --- a/zebra/rtread_proc.c +++ b/zebra/rtread_proc.c @@ -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); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 02c73d12..693b3331 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -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) } -#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); diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 68e6f920..1487745b 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -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); diff --git a/zebra/zserv.c b/zebra/zserv.c index 1703d3f5..22a6bed2 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -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 (); } diff --git a/zebra/zserv.h b/zebra/zserv.h index 9a570fb3..68c26f23 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -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); |