#include "plist.h"
#include "nexthop.h"
#include "vrf.h"
+#include "frrstr.h"
#include "zebra/zserv.h"
#include "zebra/redistribute.h"
struct nexthop *nexthop;
vrf_id_t vrf_id;
uint32_t source_protocol;
+ uint8_t instance;
int metric;
route_tag_t tag;
};
/* 'match tag TAG'
* Match function return 1 if match is success else return 0
*/
-static route_map_result_t route_match_tag(void *rule, struct prefix *prefix,
+static route_map_result_t route_match_tag(void *rule,
+ const struct prefix *prefix,
route_map_object_t type, void *object)
{
route_tag_t *tag;
/* `match interface IFNAME' */
/* Match function return 1 if match is success else return zero. */
static route_map_result_t route_match_interface(void *rule,
- struct prefix *prefix,
+ const struct prefix *prefix,
route_map_object_t type,
void *object)
{
DEFUN (match_source_protocol,
match_source_protocol_cmd,
- "match source-protocol <bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static>",
+ "match source-protocol <bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static|sharp>",
MATCH_STR
"Match protocol via which the route was learnt\n"
"BGP protocol\n"
"Routes from directly connected peer\n"
"Routes from system configuration\n"
"Routes from kernel\n"
- "Statically configured routes\n")
+ "Statically configured routes\n"
+ "SHARP process\n")
{
char *proto = argv[2]->text;
int i;
DEFUN (no_match_source_protocol,
no_match_source_protocol_cmd,
- "no match source-protocol [<bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static>]",
+ "no match source-protocol [<bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static|sharp>]",
NO_STR
MATCH_STR
"No match protocol via which the route was learnt\n"
"Routes from directly connected peer\n"
"Routes from system configuration\n"
"Routes from kernel\n"
- "Statically configured routes\n")
+ "Statically configured routes\n"
+ "SHARP process\n")
{
char *proto = (argc == 4) ? argv[3]->text : NULL;
return zebra_route_match_delete(vty, "source-protocol", proto,
RMAP_EVENT_MATCH_DELETED);
}
+DEFUN (match_source_instance,
+ match_source_instance_cmd,
+ "match source-instance (0-255)",
+ MATCH_STR
+ "Match the protocol's instance number\n"
+ "The instance number\n")
+{
+ char *instance = argv[2]->arg;
+
+ return zebra_route_match_add(vty, "source-instance", instance,
+ RMAP_EVENT_MATCH_ADDED);
+}
+
+DEFUN (no_match_source_instance,
+ no_match_source_instance_cmd,
+ "no match source-instance [(0-255)]",
+ NO_STR MATCH_STR
+ "Match the protocol's instance number\n"
+ "The instance number\n")
+{
+ char *instance = (argc == 4) ? argv[3]->arg : NULL;
+
+ return zebra_route_match_delete(vty, "source-instance", instance,
+ RMAP_EVENT_MATCH_ADDED);
+}
+
/* set functions */
DEFUN (set_src,
/* Match function return 1 if match is success else return zero. */
static route_map_result_t route_match_ip_next_hop(void *rule,
- struct prefix *prefix,
+ const struct prefix *prefix,
route_map_object_t type,
void *object)
{
/* `match ip next-hop prefix-list PREFIX_LIST' */
static route_map_result_t
-route_match_ip_next_hop_prefix_list(void *rule, struct prefix *prefix,
+route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
struct prefix_list *plist;
/* Match function should return 1 if match is success else return
zero. */
static route_map_result_t route_match_ip_address(void *rule,
- struct prefix *prefix,
+ const struct prefix *prefix,
route_map_object_t type,
void *object)
{
/* `match ip address prefix-list PREFIX_LIST' */
static route_map_result_t
-route_match_ip_address_prefix_list(void *rule, struct prefix *prefix,
+route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
struct prefix_list *plist;
/* `match ip address prefix-len PREFIXLEN' */
static route_map_result_t
-route_match_address_prefix_len(void *rule, struct prefix *prefix,
+route_match_address_prefix_len(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
uint32_t *prefixlen = (uint32_t *)rule;
/* `match ip nexthop prefix-len PREFIXLEN' */
static route_map_result_t
-route_match_ip_nexthop_prefix_len(void *rule, struct prefix *prefix,
+route_match_ip_nexthop_prefix_len(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
uint32_t *prefixlen = (uint32_t *)rule;
/* `match source-protocol PROTOCOL' */
static route_map_result_t route_match_source_protocol(void *rule,
- struct prefix *prefix,
+ const struct prefix *p,
route_map_object_t type,
void *object)
{
"source-protocol", route_match_source_protocol,
route_match_source_protocol_compile, route_match_source_protocol_free};
+/* `source-instance` */
+static route_map_result_t route_match_source_instance(void *rule,
+ const struct prefix *p,
+ route_map_object_t type,
+ void *object)
+{
+ uint8_t *instance = (uint8_t *)rule;
+ struct nh_rmap_obj *nh_data;
+
+ if (type != RMAP_ZEBRA)
+ return RMAP_NOMATCH;
+
+ nh_data = (struct nh_rmap_obj *)object;
+ if (!nh_data)
+ return RMAP_DENYMATCH;
+
+ return (nh_data->instance == *instance) ? RMAP_MATCH : RMAP_NOMATCH;
+}
+
+static void *route_match_source_instance_compile(const char *arg)
+{
+ uint8_t *instance;
+ int i;
+
+ i = atoi(arg);
+ instance = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint8_t));
+
+ *instance = i;
+
+ return instance;
+}
+
+static void route_match_source_instance_free(void *rule)
+{
+ XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+static struct route_map_rule_cmd route_match_source_instance_cmd = {
+ "source-instance", route_match_source_instance,
+ route_match_source_instance_compile, route_match_source_instance_free};
+
/* `set src A.B.C.D' */
/* Set src. */
-static route_map_result_t route_set_src(void *rule, struct prefix *prefix,
+static route_map_result_t route_set_src(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
struct nh_rmap_obj *nh_data;
"src", route_set_src, route_set_src_compile, route_set_src_free,
};
+static void zebra_route_map_process_update_cb(char *rmap_name)
+{
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug("Event handler for route-map: %s",
+ rmap_name);
+}
+
static int zebra_route_map_update_timer(struct thread *thread)
{
zebra_t_rmap_update = NULL;
"%u: Routemap update-timer fired, scheduling RIB processing",
VRF_DEFAULT);
+ route_map_walk_update_list(zebra_route_map_process_update_cb);
+
+ /*
+ * This code needs to be updated to be:
+ * 1) VRF Aware <sigh>
+ * 2) Route-map aware
+ */
zebra_import_table_rm_update();
rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
}
route_map_result_t zebra_route_map_check(int family, int rib_type,
- struct prefix *p,
+ uint8_t instance,
+ const struct prefix *p,
struct nexthop *nexthop,
vrf_id_t vrf_id, route_tag_t tag)
{
nh_obj.nexthop = nexthop;
nh_obj.vrf_id = vrf_id;
nh_obj.source_protocol = rib_type;
+ nh_obj.instance = instance;
nh_obj.metric = 0;
nh_obj.tag = tag;
}
route_map_result_t
-zebra_import_table_route_map_check(int family, int re_type, struct prefix *p,
- struct nexthop *nexthop, vrf_id_t vrf_id,
- route_tag_t tag, const char *rmap_name)
+zebra_import_table_route_map_check(int family, int re_type, uint8_t instance,
+ const struct prefix *p,
+ struct nexthop *nexthop,
+ vrf_id_t vrf_id, route_tag_t tag,
+ const char *rmap_name)
{
struct route_map *rmap = NULL;
route_map_result_t ret = RMAP_DENYMATCH;
nh_obj.nexthop = nexthop;
nh_obj.vrf_id = vrf_id;
nh_obj.source_protocol = re_type;
+ nh_obj.instance = instance;
nh_obj.metric = 0;
nh_obj.tag = tag;
}
route_map_result_t zebra_nht_route_map_check(int family, int client_proto,
- struct prefix *p,
+ const struct prefix *p,
struct route_entry *re,
struct nexthop *nexthop)
{
nh_obj.nexthop = nexthop;
nh_obj.vrf_id = nexthop->vrf_id;
nh_obj.source_protocol = re->type;
+ nh_obj.instance = re->instance;
nh_obj.metric = re->metric;
nh_obj.tag = re->tag;
if (!rmap && nht_rm[family][ZEBRA_ROUTE_MAX])
rmap = route_map_lookup_by_name(
nht_rm[family][ZEBRA_ROUTE_MAX]);
- if (rmap) {
+ if (rmap)
ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj);
- }
- return (ret);
+ return ret;
}
static void zebra_route_map_mark_update(const char *rmap_name)
static void zebra_route_map_add(const char *rmap_name)
{
- zebra_route_map_mark_update(rmap_name);
+ if (route_map_mark_updated(rmap_name) == 0)
+ zebra_route_map_mark_update(rmap_name);
+
route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
}
static void zebra_route_map_delete(const char *rmap_name)
{
- zebra_route_map_mark_update(rmap_name);
+ if (route_map_mark_updated(rmap_name) == 0)
+ zebra_route_map_mark_update(rmap_name);
+
route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_DELETED);
}
static void zebra_route_map_event(route_map_event_t event,
const char *rmap_name)
{
- zebra_route_map_mark_update(rmap_name);
+ if (route_map_mark_updated(rmap_name) == 0)
+ zebra_route_map_mark_update(rmap_name);
+
route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
}
route_map_install_match(&route_match_ipv6_address_prefix_len_cmd);
route_map_install_match(&route_match_ip_nexthop_prefix_len_cmd);
route_map_install_match(&route_match_source_protocol_cmd);
+ route_map_install_match(&route_match_source_instance_cmd);
+
/* */
route_map_install_set(&route_set_src_cmd);
/* */
install_element(RMAP_NODE, &no_match_ip_address_prefix_len_cmd);
install_element(RMAP_NODE, &match_source_protocol_cmd);
install_element(RMAP_NODE, &no_match_source_protocol_cmd);
+ install_element(RMAP_NODE, &match_source_instance_cmd);
+ install_element(RMAP_NODE, &no_match_source_instance_cmd);
+
/* */
install_element(RMAP_NODE, &set_src_cmd);
install_element(RMAP_NODE, &no_set_src_cmd);