Skip to content

Commit 6ad42ba

Browse files
committed
isisd: Fix the issue where redistributed routes do not change when the route-map is modified.
Signed-off-by: huachao01 <[email protected]>
1 parent b66145b commit 6ad42ba

File tree

4 files changed

+76
-16
lines changed

4 files changed

+76
-16
lines changed

isisd/isis_redist.c

+19-7
Original file line numberDiff line numberDiff line change
@@ -286,9 +286,9 @@ bool isis_redist_table_is_present(const struct vty *vty,
286286
}
287287

288288
/* Handle notification about route being added */
289-
void isis_redist_add(struct isis *isis, int type, struct prefix *p,
290-
struct prefix_ipv6 *src_p, uint8_t distance,
291-
uint32_t metric, const route_tag_t tag, uint16_t table)
289+
void isis_redist_add(struct isis *isis, int type, struct prefix *p, struct prefix_ipv6 *src_p,
290+
uint8_t distance, uint32_t metric, const route_tag_t tag, uint16_t table,
291+
struct zapi_nexthop *nexthops, uint16_t nexthop_num)
292292
{
293293
int family = p->family;
294294
struct route_table *ei_table = get_ext_info(isis, family);
@@ -298,6 +298,7 @@ void isis_redist_add(struct isis *isis, int type, struct prefix *p,
298298
struct isis_area *area;
299299
int level;
300300
struct isis_redist *redist;
301+
int i;
301302

302303
zlog_debug("%s: New route %pFX from %s: distance %d.", __func__, p,
303304
zebra_route_string(type), distance);
@@ -320,6 +321,11 @@ void isis_redist_add(struct isis *isis, int type, struct prefix *p,
320321
info->distance = distance;
321322
info->metric = metric;
322323
info->tag = tag;
324+
info->nexthop_num = nexthop_num;
325+
326+
for (i = 0; i < nexthop_num; i++) {
327+
info->nexthop[i] = nexthop_from_zapi_nexthop(&nexthops[i]);
328+
}
323329

324330
if (is_default_prefix(p)
325331
&& (!src_p || !src_p->prefixlen)) {
@@ -338,8 +344,8 @@ void isis_redist_add(struct isis *isis, int type, struct prefix *p,
338344
}
339345
}
340346

341-
void isis_redist_delete(struct isis *isis, int type, struct prefix *p,
342-
struct prefix_ipv6 *src_p, uint16_t table)
347+
void isis_redist_delete(struct isis *isis, int type, struct prefix *p, struct prefix_ipv6 *src_p,
348+
uint16_t table, struct zapi_nexthop *nexthops, uint16_t nexthop_num)
343349
{
344350
int family = p->family;
345351
struct route_table *ei_table = get_ext_info(isis, family);
@@ -348,6 +354,8 @@ void isis_redist_delete(struct isis *isis, int type, struct prefix *p,
348354
struct isis_area *area;
349355
int level;
350356
struct isis_redist *redist;
357+
int i;
358+
struct isis_ext_info *info;
351359

352360
zlog_debug("%s: Removing route %pFX from %s.", __func__, p,
353361
zebra_route_string(type));
@@ -358,8 +366,8 @@ void isis_redist_delete(struct isis *isis, int type, struct prefix *p,
358366
* by "default-information originate always". Areas without the
359367
* "always" setting will ignore routes with origin
360368
* DEFAULT_ROUTE. */
361-
isis_redist_add(isis, DEFAULT_ROUTE, p, NULL, 254,
362-
MAX_WIDE_PATH_METRIC, 0, table);
369+
isis_redist_add(isis, DEFAULT_ROUTE, p, NULL, 254, MAX_WIDE_PATH_METRIC, 0, table,
370+
nexthops, nexthop_num);
363371
return;
364372
}
365373

@@ -390,6 +398,10 @@ void isis_redist_delete(struct isis *isis, int type, struct prefix *p,
390398
isis_redist_uninstall(area, level, p, src_p);
391399
}
392400

401+
info = ei_node->info;
402+
for (i = 0; i < info->nexthop_num; i++) {
403+
nexthop_free(info->nexthop[i]);
404+
}
393405
XFREE(MTYPE_ISIS_EXT_INFO, ei_node->info);
394406
route_unlock_node(ei_node);
395407
}

isisd/isis_redist.h

+8-5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ struct isis_ext_info {
1919
uint32_t metric;
2020
uint8_t distance;
2121
route_tag_t tag;
22+
struct nexthop *nexthop[MULTIPATH_NUM];
23+
uint16_t nexthop_num;
2224
};
2325

2426
struct isis_redist {
@@ -42,16 +44,17 @@ struct isis_area;
4244
struct prefix;
4345
struct prefix_ipv6;
4446
struct vty;
47+
struct zapi_nexthop;
4548

4649
afi_t afi_for_redist_protocol(int protocol);
4750

4851
struct route_table *get_ext_reach(struct isis_area *area, int family,
4952
int level);
50-
void isis_redist_add(struct isis *isis, int type, struct prefix *p,
51-
struct prefix_ipv6 *src_p, uint8_t distance,
52-
uint32_t metric, route_tag_t tag, uint16_t instance);
53-
void isis_redist_delete(struct isis *isis, int type, struct prefix *p,
54-
struct prefix_ipv6 *src_p, uint16_t tableid);
53+
void isis_redist_add(struct isis *isis, int type, struct prefix *p, struct prefix_ipv6 *src_p,
54+
uint8_t distance, uint32_t metric, route_tag_t tag, uint16_t instance,
55+
struct zapi_nexthop *nexthops, uint16_t nexthop_num);
56+
void isis_redist_delete(struct isis *isis, int type, struct prefix *p, struct prefix_ipv6 *src_p,
57+
uint16_t tableid, struct zapi_nexthop *nexthops, uint16_t nexthop_num);
5558
int isis_redist_config_write(struct vty *vty, struct isis_area *area,
5659
int family);
5760
void isis_redist_init(void);

isisd/isis_routemap.c

+45
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,45 @@ static const struct route_map_rule_cmd route_match_ip_address_cmd = {
6666

6767
/* ------------------------------------------------------------*/
6868

69+
70+
static enum route_map_cmd_result_t route_match_interface(void *rule, const struct prefix *p,
71+
void *object)
72+
{
73+
struct interface *ifp;
74+
struct isis_ext_info *info;
75+
struct nexthop *nexthop;
76+
int i;
77+
78+
info = object;
79+
for (i = 0; i < info->nexthop_num; ++i) {
80+
nexthop = info->nexthop[i];
81+
ifp = if_lookup_by_name((char *)rule, nexthop->vrf_id);
82+
83+
if (ifp != NULL && ifp->ifindex == nexthop->ifindex)
84+
return RMAP_MATCH;
85+
}
86+
return RMAP_NOMATCH;
87+
}
88+
89+
static void *route_match_interface_compile(const char *arg)
90+
{
91+
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
92+
}
93+
94+
static void route_match_interface_free(void *rule)
95+
{
96+
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
97+
}
98+
99+
100+
static const struct route_map_rule_cmd route_match_interface_cmd = { "interface",
101+
route_match_interface,
102+
route_match_interface_compile,
103+
route_match_interface_free };
104+
105+
106+
/* ------------------------------------------------------------*/
107+
69108
static enum route_map_cmd_result_t
70109
route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
71110
void *object)
@@ -253,13 +292,19 @@ void isis_route_map_init(void)
253292
route_map_match_tag_hook(generic_match_add);
254293
route_map_no_match_tag_hook(generic_match_delete);
255294

295+
route_map_match_interface_hook(generic_match_add);
296+
route_map_no_match_interface_hook(generic_match_delete);
297+
298+
256299
route_map_set_metric_hook(generic_set_add);
257300
route_map_no_set_metric_hook(generic_set_delete);
258301

302+
259303
route_map_install_match(&route_match_ip_address_cmd);
260304
route_map_install_match(&route_match_ip_address_prefix_list_cmd);
261305
route_map_install_match(&route_match_ipv6_address_cmd);
262306
route_map_install_match(&route_match_ipv6_address_prefix_list_cmd);
263307
route_map_install_match(&route_match_tag_cmd);
308+
route_map_install_match(&route_match_interface_cmd);
264309
route_map_install_set(&route_set_metric_cmd);
265310
}

isisd/isis_zebra.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -504,11 +504,11 @@ static int isis_zebra_read(ZAPI_CALLBACK_ARGS)
504504
}
505505

506506
if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
507-
isis_redist_add(isis, api.type, &api.prefix, &api.src_prefix,
508-
api.distance, api.metric, api.tag, api.instance);
507+
isis_redist_add(isis, api.type, &api.prefix, &api.src_prefix, api.distance,
508+
api.metric, api.tag, api.instance, api.nexthops, api.nexthop_num);
509509
else
510-
isis_redist_delete(isis, api.type, &api.prefix, &api.src_prefix,
511-
api.instance);
510+
isis_redist_delete(isis, api.type, &api.prefix, &api.src_prefix, api.instance,
511+
api.nexthops, api.nexthop_num);
512512

513513
return 0;
514514
}

0 commit comments

Comments
 (0)