]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/routemap.c
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[mirror_frr.git] / lib / routemap.c
index 9e3dd3c0ae50a2a25dd11b3c7b75e500df7d0f6c..5c6d106d8392bfb8b985caf4019239e8fdda2c28 100644 (file)
@@ -111,6 +111,20 @@ struct route_map_match_set_hooks {
                                                const char *arg,
                                                route_map_event_t type);
 
+       /* match ip next hop type */
+       int (*match_ip_next_hop_type)(struct vty *vty,
+                                            struct route_map_index *index,
+                                            const char *command,
+                                            const char *arg,
+                                            route_map_event_t type);
+
+       /* no match ip next hop type */
+       int (*no_match_ip_next_hop_type)(struct vty *vty,
+                                               struct route_map_index *index,
+                                               const char *command,
+                                               const char *arg,
+                                               route_map_event_t type);
+
        /* match ipv6 address */
        int (*match_ipv6_address)(struct vty *vty,
                                  struct route_map_index *index,
@@ -138,6 +152,19 @@ struct route_map_match_set_hooks {
                                                 const char *arg,
                                                 route_map_event_t type);
 
+       /* match ipv6 next-hop type */
+       int (*match_ipv6_next_hop_type)(struct vty *vty,
+                                             struct route_map_index *index,
+                                             const char *command,
+                                             const char *arg,
+                                             route_map_event_t type);
+
+       /* no match ipv6next-hop type */
+       int (*no_match_ipv6_next_hop_type)(struct vty *vty,
+                                          struct route_map_index *index,
+                                          const char *command, const char *arg,
+                                          route_map_event_t type);
+
        /* match metric */
        int (*match_metric)(struct vty *vty, struct route_map_index *index,
                            const char *command, const char *arg,
@@ -275,6 +302,22 @@ void route_map_no_match_ip_next_hop_prefix_list_hook(int (*func)(
        rmap_match_set_hook.no_match_ip_next_hop_prefix_list = func;
 }
 
+/* match ip next hop type */
+void route_map_match_ip_next_hop_type_hook(int (*func)(
+       struct vty *vty, struct route_map_index *index, const char *command,
+       const char *arg, route_map_event_t type))
+{
+       rmap_match_set_hook.match_ip_next_hop_type = func;
+}
+
+/* no match ip next hop type */
+void route_map_no_match_ip_next_hop_type_hook(int (*func)(
+       struct vty *vty, struct route_map_index *index, const char *command,
+       const char *arg, route_map_event_t type))
+{
+       rmap_match_set_hook.no_match_ip_next_hop_type = func;
+}
+
 /* match ipv6 address */
 void route_map_match_ipv6_address_hook(int (*func)(
        struct vty *vty, struct route_map_index *index, const char *command,
@@ -308,6 +351,22 @@ void route_map_no_match_ipv6_address_prefix_list_hook(int (*func)(
        rmap_match_set_hook.no_match_ipv6_address_prefix_list = func;
 }
 
+/* match ipv6 next-hop type */
+void route_map_match_ipv6_next_hop_type_hook(int (*func)(
+       struct vty *vty, struct route_map_index *index, const char *command,
+       const char *arg, route_map_event_t type))
+{
+       rmap_match_set_hook.match_ipv6_next_hop_type = func;
+}
+
+/* no match ipv6 next-hop type */
+void route_map_no_match_ipv6_next_hop_type_hook(int (*func)(
+       struct vty *vty, struct route_map_index *index, const char *command,
+       const char *arg, route_map_event_t type))
+{
+       rmap_match_set_hook.no_match_ipv6_next_hop_type = func;
+}
+
 /* match metric */
 void route_map_match_metric_hook(int (*func)(
        struct vty *vty, struct route_map_index *index, const char *command,
@@ -572,7 +631,7 @@ static unsigned int route_map_hash_key_make(void *p)
        return string_hash_make(map->name);
 }
 
-static int route_map_hash_cmp(const void *p1, const void *p2)
+static bool route_map_hash_cmp(const void *p1, const void *p2)
 {
        const struct route_map *map1 = p1;
        const struct route_map *map2 = p2;
@@ -580,14 +639,14 @@ static int route_map_hash_cmp(const void *p1, const void *p2)
        if (map1->deleted == map2->deleted) {
                if (map1->name && map2->name) {
                        if (!strcmp(map1->name, map2->name)) {
-                               return 1;
+                               return true;
                        }
                } else if (!map1->name && !map2->name) {
-                       return 1;
+                       return true;
                }
        }
 
-       return 0;
+       return false;
 }
 
 enum route_map_upd8_type {
@@ -617,7 +676,6 @@ struct route_map_dep {
 struct hash *route_map_dep_hash[ROUTE_MAP_DEP_MAX];
 
 static unsigned int route_map_dep_hash_make_key(void *p);
-static int route_map_dep_hash_cmp(const void *p1, const void *p2);
 static void route_map_clear_all_references(char *rmap_name);
 static void route_map_rule_delete(struct route_map_rule_list *,
                                  struct route_map_rule *);
@@ -752,6 +810,18 @@ struct route_map *route_map_lookup_by_name(const char *name)
        return map;
 }
 
+/* Simple helper to warn if route-map does not exist. */
+struct route_map *route_map_lookup_warn_noexist(struct vty *vty, const char *name)
+{
+       struct route_map *route_map = route_map_lookup_by_name(name);
+
+       if (!route_map)
+               if (vty_shell_serv(vty))
+                       vty_out(vty, "The route-map '%s' does not exist.\n", name);
+
+       return route_map;
+}
+
 int route_map_mark_updated(const char *name)
 {
        struct route_map *map;
@@ -854,11 +924,13 @@ static void vty_show_route_map_entry(struct vty *vty, struct route_map *map)
        struct route_map_index *index;
        struct route_map_rule *rule;
 
-       vty_out(vty, "%s:\n", frr_protonameinst);
+       vty_out(vty, "route-map: %s Invoked: %" PRIu64 "\n",
+               map->name, map->applied);
 
        for (index = map->head; index; index = index->next) {
-               vty_out(vty, "route-map %s, %s, sequence %d\n", map->name,
-                       route_map_type_str(index->type), index->pref);
+               vty_out(vty, " %s, sequence %d Invoked %" PRIu64 "\n",
+                       route_map_type_str(index->type), index->pref,
+                       index->applied);
 
                /* Description */
                if (index->description)
@@ -904,6 +976,8 @@ static int vty_show_route_map(struct vty *vty, const char *name)
 {
        struct route_map *map;
 
+       vty_out(vty, "%s:\n", frr_protonameinst);
+
        if (name) {
                map = route_map_lookup_by_name(name);
 
@@ -928,7 +1002,7 @@ static int vty_show_route_map(struct vty *vty, const char *name)
                for (ALL_LIST_ELEMENTS_RO(maplist, ln, map))
                        vty_show_route_map_entry(vty, map);
 
-               list_delete_and_null(&maplist);
+               list_delete(&maplist);
        }
        return CMD_SUCCESS;
 }
@@ -1447,7 +1521,7 @@ route_map_result_t route_map_apply(struct route_map *map,
 
        if (recursion > RMAP_RECURSION_LIMIT) {
                flog_warn(
-                       LIB_WARN_RMAP_RECURSION_LIMIT,
+                       EC_LIB_RMAP_RECURSION_LIMIT,
                        "route-map recursion limit (%d) reached, discarding route",
                        RMAP_RECURSION_LIMIT);
                recursion = 0;
@@ -1457,8 +1531,10 @@ route_map_result_t route_map_apply(struct route_map *map,
        if (map == NULL)
                return RMAP_DENYMATCH;
 
+       map->applied++;
        for (index = map->head; index; index = index->next) {
                /* Apply this index. */
+               index->applied++;
                ret = route_map_apply_match(&index->match_list, prefix, type,
                                            object);
 
@@ -1547,12 +1623,12 @@ void route_map_event_hook(void (*func)(route_map_event_t, const char *))
 }
 
 /* Routines for route map dependency lists and dependency processing */
-static int route_map_rmap_hash_cmp(const void *p1, const void *p2)
+static bool route_map_rmap_hash_cmp(const void *p1, const void *p2)
 {
        return (strcmp((const char *)p1, (const char *)p2) == 0);
 }
 
-static int route_map_dep_hash_cmp(const void *p1, const void *p2)
+static bool route_map_dep_hash_cmp(const void *p1, const void *p2)
 {
 
        return (strcmp(((const struct route_map_dep *)p1)->dep_name,
@@ -1759,8 +1835,19 @@ void route_map_upd8_dependency(route_map_event_t type, const char *arg,
 {
        struct hash *upd8_hash = NULL;
 
-       if ((upd8_hash = route_map_get_dep_hash(type)))
+       if ((upd8_hash = route_map_get_dep_hash(type))) {
                route_map_dep_update(upd8_hash, arg, rmap_name, type);
+
+               if (type == RMAP_EVENT_CALL_ADDED) {
+                       /* Execute hook. */
+                       if (route_map_master.add_hook)
+                               (*route_map_master.add_hook)(rmap_name);
+               } else if (type == RMAP_EVENT_CALL_DELETED) {
+                       /* Execute hook. */
+                       if (route_map_master.delete_hook)
+                               (*route_map_master.delete_hook)(rmap_name);
+               }
+       }
 }
 
 void route_map_notify_dependencies(const char *affected_name,
@@ -2017,6 +2104,45 @@ DEFUN (no_match_ip_next_hop_prefix_list,
        return CMD_SUCCESS;
 }
 
+DEFUN(match_ip_next_hop_type, match_ip_next_hop_type_cmd,
+      "match ip next-hop type <blackhole>",
+      MATCH_STR IP_STR
+      "Match next-hop address of route\n"
+      "Match entries by type\n"
+      "Blackhole\n")
+{
+       int idx_word = 4;
+       VTY_DECLVAR_CONTEXT(route_map_index, index);
+
+       if (rmap_match_set_hook.match_ip_next_hop_type)
+               return rmap_match_set_hook.match_ip_next_hop_type(
+                       vty, index, "ip next-hop type", argv[idx_word]->arg,
+                       RMAP_EVENT_MATCH_ADDED);
+       return CMD_SUCCESS;
+}
+
+DEFUN(no_match_ip_next_hop_type, no_match_ip_next_hop_type_cmd,
+      "no match ip next-hop type [<blackhole>]",
+      NO_STR MATCH_STR IP_STR
+      "Match next-hop address of route\n"
+      "Match entries by type\n"
+      "Blackhole\n")
+{
+       int idx_word = 5;
+       VTY_DECLVAR_CONTEXT(route_map_index, index);
+
+       if (rmap_match_set_hook.no_match_ip_next_hop) {
+               if (argc <= idx_word)
+                       return rmap_match_set_hook.no_match_ip_next_hop(
+                               vty, index, "ip next-hop type", NULL,
+                               RMAP_EVENT_MATCH_DELETED);
+               return rmap_match_set_hook.no_match_ip_next_hop(
+                       vty, index, "ip next-hop type", argv[idx_word]->arg,
+                       RMAP_EVENT_MATCH_DELETED);
+       }
+       return CMD_SUCCESS;
+}
+
 
 DEFUN (match_ipv6_address,
        match_ipv6_address_cmd,
@@ -2095,6 +2221,40 @@ DEFUN (no_match_ipv6_address_prefix_list,
        return CMD_SUCCESS;
 }
 
+DEFUN(match_ipv6_next_hop_type, match_ipv6_next_hop_type_cmd,
+      "match ipv6 next-hop type <blackhole>",
+      MATCH_STR IPV6_STR
+      "Match address of route\n"
+      "Match entries by type\n"
+      "Blackhole\n")
+{
+       int idx_word = 4;
+       VTY_DECLVAR_CONTEXT(route_map_index, index);
+
+       if (rmap_match_set_hook.match_ipv6_next_hop_type)
+               return rmap_match_set_hook.match_ipv6_next_hop_type(
+                       vty, index, "ipv6 next-hop type", argv[idx_word]->arg,
+                       RMAP_EVENT_MATCH_ADDED);
+       return CMD_SUCCESS;
+}
+
+DEFUN(no_match_ipv6_next_hop_type, no_match_ipv6_next_hop_type_cmd,
+      "no match ipv6 next-hop type [<blackhole>]",
+      NO_STR MATCH_STR IPV6_STR
+      "Match address of route\n"
+      "Match entries by type\n"
+      "Blackhole\n")
+{
+       int idx_word = 5;
+       VTY_DECLVAR_CONTEXT(route_map_index, index);
+
+       if (rmap_match_set_hook.no_match_ipv6_next_hop_type)
+               return rmap_match_set_hook.no_match_ipv6_next_hop_type(
+                       vty, index, "ipv6 next-hop type",
+                       (argc <= idx_word) ? NULL : argv[idx_word]->arg,
+                       RMAP_EVENT_MATCH_DELETED);
+       return CMD_SUCCESS;
+}
 
 DEFUN (match_metric,
        match_metric_cmd,
@@ -2862,12 +3022,18 @@ void route_map_init(void)
        install_element(RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
        install_element(RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
 
+       install_element(RMAP_NODE, &match_ip_next_hop_type_cmd);
+       install_element(RMAP_NODE, &no_match_ip_next_hop_type_cmd);
+
        install_element(RMAP_NODE, &match_ipv6_address_cmd);
        install_element(RMAP_NODE, &no_match_ipv6_address_cmd);
 
        install_element(RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
        install_element(RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
 
+       install_element(RMAP_NODE, &match_ipv6_next_hop_type_cmd);
+       install_element(RMAP_NODE, &no_match_ipv6_next_hop_type_cmd);
+
        install_element(RMAP_NODE, &match_metric_cmd);
        install_element(RMAP_NODE, &no_match_metric_cmd);