summaryrefslogtreecommitdiff
path: root/isisd
diff options
context:
space:
mode:
authorRuss White <russ@riw.us>2025-03-25 10:18:13 -0400
committerGitHub <noreply@github.com>2025-03-25 10:18:13 -0400
commit694f67c48a561730eb98568dc83bf029fb5cd99e (patch)
tree6b27ac4dfa5a9c2e4f59846240ac10989edf0a4b /isisd
parentccfdab3ddb56afa030360e57e532ced90fdd6308 (diff)
parent01d6daea2f5487cd7fd589569a0dbc6205ab8914 (diff)
Merge pull request #18369 from huchaogithup/master-dev-pr1
isisd: Fix the issue where redistributed routes do not change when th…
Diffstat (limited to 'isisd')
-rw-r--r--isisd/isis_redist.c46
-rw-r--r--isisd/isis_redist.h2
-rw-r--r--isisd/isis_routemap.c41
-rw-r--r--isisd/isisd.h1
4 files changed, 90 insertions, 0 deletions
diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c
index 2cb08db27b..76189edcdc 100644
--- a/isisd/isis_redist.c
+++ b/isisd/isis_redist.c
@@ -44,6 +44,17 @@ static int redist_protocol(int family)
return 0;
}
+int afi_skt_for_redist_protocol(int protocol)
+{
+ if (protocol == 0)
+ return AF_INET;
+ if (protocol == 1)
+ return AF_INET6;
+
+ assert(!"Unknown redist protocol!");
+ return AF_INET;
+}
+
afi_t afi_for_redist_protocol(int protocol)
{
if (protocol == 0)
@@ -430,6 +441,41 @@ void isis_redist_free(struct isis *isis)
}
}
+void isis_redist_update(struct isis_area *area, int level, int family, int type, uint16_t table)
+{
+ struct isis_redist *redist;
+ struct route_table *ei_table;
+ struct route_node *rn;
+ struct isis_ext_info *info;
+
+ redist = isis_redist_lookup(area, family, type, level, table);
+ if (!redist)
+ return;
+
+ ei_table = get_ext_info(area->isis, family);
+ for (rn = route_top(ei_table); rn; rn = srcdest_route_next(rn)) {
+ if (!rn->info)
+ continue;
+ info = rn->info;
+
+ const struct prefix *p, *src_p;
+
+ srcdest_rnode_prefixes(rn, &p, &src_p);
+
+ if (type == DEFAULT_ROUTE) {
+ if (!is_default_prefix(p) || (src_p && src_p->prefixlen)) {
+ continue;
+ }
+ } else {
+ if (info->origin != type)
+ continue;
+ }
+
+ isis_redist_update_ext_reach(area, level, redist, p,
+ (const struct prefix_ipv6 *)src_p, info);
+ }
+}
+
void isis_redist_set(struct isis_area *area, int level, int family, int type,
uint32_t metric, const char *routemap, int originate_type,
uint16_t table)
diff --git a/isisd/isis_redist.h b/isisd/isis_redist.h
index 688f27e62d..7ae3c0e52a 100644
--- a/isisd/isis_redist.h
+++ b/isisd/isis_redist.h
@@ -43,6 +43,7 @@ struct prefix;
struct prefix_ipv6;
struct vty;
+int afi_skt_for_redist_protocol(int protocol);
afi_t afi_for_redist_protocol(int protocol);
struct route_table *get_ext_reach(struct isis_area *area, int family,
@@ -60,6 +61,7 @@ void isis_redist_area_finish(struct isis_area *area);
void isis_redist_set(struct isis_area *area, int level, int family, int type,
uint32_t metric, const char *routemap, int originate_type,
uint16_t table);
+void isis_redist_update(struct isis_area *area, int level, int family, int type, uint16_t table);
void isis_redist_unset(struct isis_area *area, int level, int family, int type,
uint16_t table);
diff --git a/isisd/isis_routemap.c b/isisd/isis_routemap.c
index 9be133c788..7aaba08c44 100644
--- a/isisd/isis_routemap.c
+++ b/isisd/isis_routemap.c
@@ -234,10 +234,51 @@ static const struct route_map_rule_cmd route_set_metric_cmd = {
route_set_metric_free
};
+static void isis_route_map_update(const char *name)
+{
+ struct isis *isis;
+ struct listnode *node, *lnode;
+ struct isis_area *area;
+ int type;
+ int level;
+ int protocol;
+ struct isis_redist *redist;
+
+ for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
+ for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
+ for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++)
+ for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++)
+ for (level = 0; level < ISIS_LEVELS; level++) {
+ if (area->redist_settings[protocol][type][level] ==
+ NULL)
+ continue;
+ for (ALL_LIST_ELEMENTS_RO(area->redist_settings
+ [protocol][type]
+ [level],
+ lnode, redist)) {
+ if (redist->redist == 0)
+ continue;
+
+ if (redist->map_name &&
+ strcmp(redist->map_name, name) == 0) {
+ isis_redist_update(area, level + 1,
+ afi_skt_for_redist_protocol(
+ protocol),
+ type,
+ redist->table);
+ }
+ }
+ }
+}
+
void isis_route_map_init(void)
{
route_map_init();
+ route_map_add_hook(isis_route_map_update);
+ route_map_delete_hook(isis_route_map_update);
+ route_map_event_hook(isis_route_map_update);
+
route_map_match_ip_address_hook(generic_match_add);
route_map_no_match_ip_address_hook(generic_match_delete);
diff --git a/isisd/isisd.h b/isisd/isisd.h
index 48f6a5832d..cd50d43a18 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -56,6 +56,7 @@ static const bool fabricd = false;
extern void isis_cli_init(void);
#endif
+
#define ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf) \
if (argv_find(argv, argc, "vrf", &idx_vrf)) { \
vrf_name = argv[idx_vrf + 1]->arg; \