#include "zebra/zserv.h"
#include "zebra/zebra_ns.h"
#include "zebra/zebra_vrf.h"
+#include "zebra/zebra_routemap.h"
#include "zebra/redistribute.h"
#include "zebra/debug.h"
#include "zebra/router-id.h"
}
int
-zebra_add_import_table_entry (struct route_node *rn, struct rib *rib)
+zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char *rmap_name)
{
struct rib *newrib;
struct prefix_ipv4 p4;
struct nexthop *nhop;
struct in_addr *gate;
+ route_map_result_t ret = RMAP_MATCH;
- if (rn->p.family == AF_INET)
+ if (rmap_name)
+ ret = zebra_import_table_route_map_check (AFI_IP, rib->type, &rn->p, rib->nexthop, rib->vrf_id,
+ rib->tag, rmap_name);
+
+ if (ret == RMAP_MATCH)
{
- p4.family = AF_INET;
- p4.prefixlen = rn->p.prefixlen;
- p4.prefix = rn->p.u.prefix4;
+ if (rn->p.family == AF_INET)
+ {
+ p4.family = AF_INET;
+ p4.prefixlen = rn->p.prefixlen;
+ p4.prefix = rn->p.u.prefix4;
- if (rib->nexthop_num == 1)
- {
- nhop = rib->nexthop;
- if (nhop->type == NEXTHOP_TYPE_IFINDEX)
- gate = NULL;
- else
- gate = &nhop->gate.ipv4;
-
- rib_add_ipv4(ZEBRA_ROUTE_TABLE, rib->table, 0, &p4,
- gate, &nhop->src.ipv4,
- nhop->ifindex, rib->vrf_id, zebrad.rtm_table_default,
- rib->metric,
- zebra_import_table_distance[AFI_IP][rib->table],
- SAFI_UNICAST);
- }
- else if (rib->nexthop_num > 1)
- {
- newrib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
- newrib->type = ZEBRA_ROUTE_TABLE;
- newrib->distance = zebra_import_table_distance[AFI_IP][rib->table];
- newrib->flags = rib->flags;
- newrib->metric = rib->metric;
- newrib->table = zebrad.rtm_table_default;
- newrib->nexthop_num = 0;
- newrib->uptime = time(NULL);
- newrib->instance = rib->table;
-
- /* Assuming these routes are never recursive */
- for (nhop = rib->nexthop; nhop; nhop = nhop->next)
- rib_copy_nexthops(newrib, nhop);
-
- rib_add_ipv4_multipath(&p4, newrib, SAFI_UNICAST);
- }
+ if (rib->nexthop_num == 1)
+ {
+ nhop = rib->nexthop;
+ if (nhop->type == NEXTHOP_TYPE_IFINDEX)
+ gate = NULL;
+ else
+ gate = &nhop->gate.ipv4;
+
+ rib_add_ipv4(ZEBRA_ROUTE_TABLE, rib->table, 0, &p4,
+ gate, &nhop->src.ipv4,
+ nhop->ifindex, rib->vrf_id, zebrad.rtm_table_default,
+ rib->metric,
+ zebra_import_table_distance[AFI_IP][rib->table],
+ SAFI_UNICAST);
+ }
+ else if (rib->nexthop_num > 1)
+ {
+ newrib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
+ newrib->type = ZEBRA_ROUTE_TABLE;
+ newrib->distance = zebra_import_table_distance[AFI_IP][rib->table];
+ newrib->flags = rib->flags;
+ newrib->metric = rib->metric;
+ newrib->table = zebrad.rtm_table_default;
+ newrib->nexthop_num = 0;
+ newrib->uptime = time(NULL);
+ newrib->instance = rib->table;
+
+ /* Assuming these routes are never recursive */
+ for (nhop = rib->nexthop; nhop; nhop = nhop->next)
+ rib_copy_nexthops(newrib, nhop);
+
+ rib_add_ipv4_multipath(&p4, newrib, SAFI_UNICAST);
+ }
+ }
+ }
+ else
+ {
+ zebra_del_import_table_entry (rn, rib);
}
/* DD: Add IPv6 code */
return 0;
/* Assuming no one calls this with the main routing table */
int
-zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, int add)
+zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, const char *rmap_name, int add)
{
struct route_table *table;
struct rib *rib;
if (add)
{
+ if (rmap_name)
+ zebra_add_import_table_route_map (afi, rmap_name, table_id);
+ else
+ {
+ rmap_name = zebra_get_import_table_route_map (afi, table_id);
+ if (rmap_name)
+ zebra_del_import_table_route_map (afi, table_id);
+ }
+
SET_FLAG(zebra_import_table_used[table_id], afi);
zebra_import_table_distance[afi][table_id] = distance;
}
{
UNSET_FLAG(zebra_import_table_used[table_id], (u_char)afi);
zebra_import_table_distance[afi][table_id] = ZEBRA_TABLE_DISTANCE_DEFAULT;
+
+ rmap_name = zebra_get_import_table_route_map (afi, table_id);
+ if (rmap_name)
+ zebra_del_import_table_route_map (afi, table_id);
}
for (rn = route_top(table); rn; rn = route_next(rn))
((afi == AFI_IP6) && (rn->p.family == AF_INET6)))
{
if (add)
- zebra_add_import_table_entry (rn, rib);
+ zebra_add_import_table_entry (rn, rib, rmap_name);
else
zebra_del_import_table_entry (rn, rib);
}
afi_t afi;
int write = 0;
char afi_str[AFI_MAX][6] = {"", "ip", "ipv6"};
+ const char *rmap_name;
for (afi = AFI_IP; afi < AFI_MAX; afi++)
{
{
if (zebra_import_table_distance[afi][i] != ZEBRA_TABLE_DISTANCE_DEFAULT)
{
- vty_out(vty, "%s import-table %d distance %d%s", afi_str[afi],
- i, zebra_import_table_distance[afi][i], VTY_NEWLINE);
+ vty_out(vty, "%s import-table %d distance %d", afi_str[afi],
+ i, zebra_import_table_distance[afi][i]);
}
else
{
- vty_out(vty, "%s import-table %d%s", afi_str[afi], i,
- VTY_NEWLINE);
+ vty_out(vty, "%s import-table %d", afi_str[afi], i);
}
+
+ rmap_name = zebra_get_import_table_route_map (afi, i);
+ if (rmap_name)
+ vty_out(vty, " route-map %s", rmap_name);
+
+ vty_out(vty, "%s", VTY_NEWLINE);
write = 1;
}
}
return write;
}
+
+void
+zebra_import_table_rm_update ()
+{
+ afi_t afi;
+ int i;
+ struct route_table *table;
+ struct rib *rib;
+ struct route_node *rn;
+ const char *rmap_name;
+
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ {
+ for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++)
+ {
+ if (is_zebra_import_table_enabled(afi, i))
+ {
+ rmap_name = zebra_get_import_table_route_map (afi, i);
+ if (!rmap_name)
+ return;
+
+ table = zebra_vrf_other_route_table(afi, i, VRF_DEFAULT);
+ for (rn = route_top(table); rn; rn = route_next(rn))
+ {
+ /* For each entry in the non-default routing table,
+ * add the entry in the main table
+ */
+ if (!rn->info)
+ continue;
+
+ RNODE_FOREACH_RIB (rn, rib)
+ {
+ if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
+ continue;
+ break;
+ }
+
+ if (!rib)
+ continue;
+
+ if (((afi == AFI_IP) && (rn->p.family == AF_INET)) ||
+ ((afi == AFI_IP6) && (rn->p.family == AF_INET6)))
+ zebra_add_import_table_entry (rn, rib, rmap_name);
+ }
+ }
+ }
+ }
+
+ return;
+}
struct connected *c);
extern void zebra_interface_vrf_update_del (struct interface *, vrf_id_t new_vrf_id);
extern void zebra_interface_vrf_update_add (struct interface *, vrf_id_t old_vrf_id);
+
extern int zebra_import_table (afi_t afi, u_int32_t table_id,
- u_int32_t metric, int add);
+ u_int32_t distance, const char *rmap_name, int add);
extern int zebra_add_import_table_entry (struct route_node *rn,
- struct rib *rib);
+ struct rib *rib, const char *rmap_name);
extern int zebra_del_import_table_entry (struct route_node *rn,
struct rib *rib);
extern int is_zebra_import_table_enabled(afi_t, u_int32_t table_id);
extern int zebra_import_table_config(struct vty *);
+extern void zebra_import_table_rm_update(void);
+
extern int is_default (struct prefix *);
#endif /* _ZEBRA_REDISTRIBUTE_H */
void zebra_interface_vrf_update_add (struct interface *a, vrf_id_t old_vrf_id)
{ return; }
-int zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t metric,
- int add)
+int zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance,
+ const char *rmap_name, int add)
{ return 0; }
-int zebra_add_import_table_entry (struct route_node *rn, struct rib *rib)
+int zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char *rmap_name)
{ return 0; }
int zebra_del_import_table_entry (struct route_node *rn, struct rib *rib)
int zebra_import_table_config(struct vty *vty)
{ return 0; }
+
+void zebra_import_table_rm_update()
+{ return; }
#include "zebra/zserv.h"
#include "zebra/zebra_vrf.h"
#include "zebra/redistribute.h"
+#include "zebra/zebra_routemap.h"
#include "zebra/debug.h"
#include "zebra/zebra_fpm.h"
#include "zebra/zebra_rnh.h"
rib_dest_t *dest;
char buf[INET6_ADDRSTRLEN];
afi_t afi;
+ const char *rmap_name;
assert (rib && rn);
afi = (rn->p.family == AF_INET) ? AFI_IP :
(rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX;
if (is_zebra_import_table_enabled (afi, rib->table))
- zebra_add_import_table_entry(rn, rib);
+ {
+ rmap_name = zebra_get_import_table_route_map (afi, rib->table);
+ zebra_add_import_table_entry(rn, rib, rmap_name);
+ }
else
if (process)
rib_queue_add (rn);
#include "zebra/redistribute.h"
#include "zebra/debug.h"
#include "zebra/zebra_rnh.h"
+#include "zebra/zebra_routemap.h"
#include "zebra/interface.h"
static void free_state(vrf_id_t vrf_id, struct rib *rib, struct route_node *rn);
#include "vrf.h"
#include "zebra/zserv.h"
+#include "zebra/redistribute.h"
#include "zebra/debug.h"
#include "zebra/zebra_rnh.h"
#include "zebra/zebra_routemap.h"
char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1]; /* "any" == ZEBRA_ROUTE_MAX */
/* NH Tracking route map */
char *nht_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1]; /* "any" == ZEBRA_ROUTE_MAX */
+char *zebra_import_table_routemap[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
struct nh_rmap_obj
{
zlog_debug ("%u: Routemap update-timer fired, scheduling RIB processing",
VRF_DEFAULT);
+ zebra_import_table_rm_update ();
rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
return (ret);
}
+char *
+zebra_get_import_table_route_map (afi_t afi, uint32_t table)
+{
+ return zebra_import_table_routemap[afi][table];
+}
+
+void
+zebra_add_import_table_route_map (afi_t afi, const char *rmap_name, uint32_t table)
+{
+ zebra_import_table_routemap[afi][table] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, rmap_name);
+}
+
+void
+zebra_del_import_table_route_map (afi_t afi, uint32_t table)
+{
+ XFREE (MTYPE_ROUTE_MAP_NAME, zebra_import_table_routemap[afi][table]);
+}
+
+route_map_result_t
+zebra_import_table_route_map_check (int family, int rib_type, struct prefix *p,
+ struct nexthop *nexthop, vrf_id_t vrf_id, u_short tag, const char *rmap_name)
+{
+ struct route_map *rmap = NULL;
+ route_map_result_t ret = RMAP_DENYMATCH;
+ struct nh_rmap_obj nh_obj;
+
+ nh_obj.nexthop = nexthop;
+ nh_obj.vrf_id = vrf_id;
+ nh_obj.source_protocol = rib_type;
+ nh_obj.metric = 0;
+ nh_obj.tag = tag;
+
+ if (rib_type >= 0 && rib_type < ZEBRA_ROUTE_MAX)
+ rmap = route_map_lookup_by_name (rmap_name);
+ if (rmap) {
+ ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj);
+ }
+
+ return (ret);
+}
+
route_map_result_t
zebra_nht_route_map_check (int family, int client_proto, struct prefix *p,
struct rib * rib, struct nexthop *nexthop)
#define __ZEBRA_ROUTEMAP_H__
extern void zebra_routemap_config_write_protocol(struct vty *vty);
+extern char *zebra_get_import_table_route_map (afi_t afi, uint32_t table);
+extern void zebra_add_import_table_route_map (afi_t afi, const char *rmap_name, uint32_t table);
+extern void zebra_del_import_table_route_map (afi_t afi, uint32_t table);
+
+extern void zebra_route_map_write_delay_timer(struct vty *);
+
+extern route_map_result_t zebra_import_table_route_map_check (int family, int rib_type,
+ struct prefix *p,
+ struct nexthop *nexthop,
+ vrf_id_t vrf_id,
+ u_short tag,
+ const char *rmap_name);
+extern route_map_result_t zebra_route_map_check (int family, int rib_type,
+ struct prefix *p,
+ struct nexthop *nexthop,
+ vrf_id_t vrf_id,
+ u_short tag);
+extern route_map_result_t zebra_nht_route_map_check (int family,
+ int client_proto,
+ struct prefix *p,
+ struct rib *,
+ struct nexthop *nexthop);
+
#endif
return CMD_WARNING;
}
- if (is_zebra_import_table_enabled(AFI_IP, table_id))
- return CMD_SUCCESS;
-
if (argc > 1)
VTY_GET_INTEGER_RANGE("distance", distance, argv[1], 1, 255);
-
- return (zebra_import_table(AFI_IP, table_id, distance, 1));
+ return (zebra_import_table(AFI_IP, table_id, distance, NULL, 1));
}
"import routes from non-main kernel table\n"
"kernel routing table id\n")
+DEFUN (ip_zebra_import_table_distance_routemap,
+ ip_zebra_import_table_distance_routemap_cmd,
+ "ip import-table <1-252> distance <1-255> route-map WORD",
+ IP_STR
+ "import routes from non-main kernel table\n"
+ "kernel routing table id\n"
+ "Distance for imported routes\n"
+ "Default distance value\n"
+ "route-map for filtering\n"
+ "route-map name\n")
+{
+ u_int32_t table_id = 0;
+ int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
+ const char *rmap_name;
+
+ if (argc)
+ VTY_GET_INTEGER("table", table_id, argv[0]);
+
+ if (!is_zebra_valid_kernel_table(table_id))
+ {
+ vty_out(vty, "Invalid routing table ID, %d. Must be in range 1-252%s",
+ table_id, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (is_zebra_main_routing_table(table_id))
+ {
+ vty_out(vty, "Invalid routing table ID, %d. Must be non-default table%s",
+ table_id, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (argc > 2)
+ {
+ VTY_GET_INTEGER_RANGE("distance", distance, argv[1], 1, 255);
+ rmap_name = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[2]);
+ }
+ else
+ rmap_name = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
+
+ return (zebra_import_table(AFI_IP, table_id, distance, rmap_name, 1));
+}
+
+ALIAS (ip_zebra_import_table_distance_routemap,
+ ip_zebra_import_table_routemap_cmd,
+ "ip import-table <1-252> route-map WORD",
+ IP_STR
+ "import routes from non-main kernel table\n"
+ "kernel routing table id\n"
+ "route-map for filtering\n"
+ "route-map name\n")
+
DEFUN (no_ip_zebra_import_table,
no_ip_zebra_import_table_cmd,
- "no ip import-table <1-252>",
+ "no ip import-table <1-252> {route-map NAME}",
NO_STR
IP_STR
"import routes from non-main kernel table\n"
if (!is_zebra_import_table_enabled(AFI_IP, table_id))
return CMD_SUCCESS;
- return (zebra_import_table(AFI_IP, table_id, 0, 0));
+ return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0));
}
ALIAS (no_ip_zebra_import_table,
no_ip_zebra_import_table_distance_cmd,
- "no ip import-table <1-252> distance <1-255>",
+ "no ip import-table <1-252> distance <1-255> {route-map NAME}",
IP_STR
"import routes from non-main kernel table to main table"
"kernel routing table id\n"
install_element (CONFIG_NODE, &no_ip_route_mask_flags_tag_distance2_cmd);
install_element (CONFIG_NODE, &ip_zebra_import_table_cmd);
install_element (CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
+ install_element (CONFIG_NODE, &ip_zebra_import_table_routemap_cmd);
+ install_element (CONFIG_NODE, &ip_zebra_import_table_distance_routemap_cmd);
install_element (CONFIG_NODE, &no_ip_zebra_import_table_cmd);
install_element (CONFIG_NODE, &no_ip_zebra_import_table_distance_cmd);
extern void zserv_nexthop_num_warn(const char *, const struct prefix *, const u_char);
extern int zebra_server_send_message(struct zserv *client);
-extern void zebra_route_map_write_delay_timer(struct vty *);
-extern route_map_result_t zebra_route_map_check (int family, int rib_type,
- struct prefix *p,
- struct nexthop *nexthop,
- vrf_id_t vrf_id,
- u_short tag);
-extern route_map_result_t zebra_nht_route_map_check (int family,
- int client_proto,
- struct prefix *p,
- struct rib *,
- struct nexthop *nexthop);
-
#endif /* _ZEBRA_ZEBRA_H */