From 7514fb7739f74311830e9ddd1381d0d228224f61 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Wed, 2 May 2007 16:05:35 +0000 Subject: [zebra] Routemap support on received routes, with 'set src' command (linux) 2007-05-01 David L Stevens * (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 --- zebra/zebra_rib.c | 57 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 10 deletions(-) (limited to 'zebra/zebra_rib.c') 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); -- cgit v1.2.1