From 28a8065ec432fdb25e2070e625e1415b67dc9c6d Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 11 Aug 2023 10:12:06 -0400 Subject: [PATCH 1/7] zebra: Rename `struct nh_rmap_obj` to `struct zebra_rmap_obj` This structure is really the generic route map object for handling routemaps in zebra. Let's name it appropriately. Future commits will consolidate the data to using the struct route_entry as part of this data instead of copying bits and bobs of it. This will allow future work to set/control the route_entry more directly. Signed-off-by: Donald Sharp --- zebra/zebra_routemap.c | 134 ++++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index eb94e26c30..91c8af9c6c 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -31,7 +31,7 @@ static uint32_t zebra_rmap_update_timer = ZEBRA_RMAP_DEFAULT_UPDATE_TIMER; static struct event *zebra_t_rmap_update = NULL; char *zebra_import_table_routemap[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; -struct nh_rmap_obj { +struct zebra_rmap_obj { struct nexthop *nexthop; vrf_id_t vrf_id; uint32_t source_protocol; @@ -49,12 +49,12 @@ static enum route_map_cmd_result_t route_match_tag(void *rule, const struct prefix *prefix, void *object) { route_tag_t *tag; - struct nh_rmap_obj *nh_data; + struct zebra_rmap_obj *rm_data; tag = rule; - nh_data = object; + rm_data = object; - if (nh_data->tag == *tag) + if (rm_data->tag == *tag) return RMAP_MATCH; return RMAP_NOMATCH; @@ -74,19 +74,19 @@ static const struct route_map_rule_cmd route_match_tag_cmd = { static enum route_map_cmd_result_t route_match_interface(void *rule, const struct prefix *prefix, void *object) { - struct nh_rmap_obj *nh_data; + struct zebra_rmap_obj *rm_data; char *ifname = rule; ifindex_t ifindex; if (strcasecmp(ifname, "any") == 0) return RMAP_MATCH; - nh_data = object; - if (!nh_data || !nh_data->nexthop) + rm_data = object; + if (!rm_data || !rm_data->nexthop) return RMAP_NOMATCH; - ifindex = ifname2ifindex(ifname, nh_data->vrf_id); + ifindex = ifname2ifindex(ifname, rm_data->vrf_id); if (ifindex == 0) return RMAP_NOMATCH; - if (nh_data->nexthop->ifindex == ifindex) + if (rm_data->nexthop->ifindex == ifindex) return RMAP_MATCH; return RMAP_NOMATCH; @@ -1017,21 +1017,21 @@ static enum route_map_cmd_result_t route_match_ip_next_hop(void *rule, const struct prefix *prefix, void *object) { struct access_list *alist; - struct nh_rmap_obj *nh_data; + struct zebra_rmap_obj *rm_data; struct prefix_ipv4 p; - nh_data = object; - if (!nh_data) + rm_data = object; + if (!rm_data) return RMAP_NOMATCH; - switch (nh_data->nexthop->type) { + switch (rm_data->nexthop->type) { case NEXTHOP_TYPE_IFINDEX: /* Interface routes can't match ip next-hop */ return RMAP_NOMATCH; case NEXTHOP_TYPE_IPV4_IFINDEX: case NEXTHOP_TYPE_IPV4: p.family = AF_INET; - p.prefix = nh_data->nexthop->gate.ipv4; + p.prefix = rm_data->nexthop->gate.ipv4; p.prefixlen = IPV4_MAX_BITLEN; break; case NEXTHOP_TYPE_IPV6: @@ -1080,21 +1080,21 @@ route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix, void *object) { struct prefix_list *plist; - struct nh_rmap_obj *nh_data; + struct zebra_rmap_obj *rm_data; struct prefix_ipv4 p; - nh_data = (struct nh_rmap_obj *)object; - if (!nh_data) + rm_data = (struct zebra_rmap_obj *)object; + if (!rm_data) return RMAP_NOMATCH; - switch (nh_data->nexthop->type) { + switch (rm_data->nexthop->type) { case NEXTHOP_TYPE_IFINDEX: /* Interface routes can't match ip next-hop */ return RMAP_NOMATCH; case NEXTHOP_TYPE_IPV4_IFINDEX: case NEXTHOP_TYPE_IPV4: p.family = AF_INET; - p.prefix = nh_data->nexthop->gate.ipv4; + p.prefix = rm_data->nexthop->gate.ipv4; p.prefixlen = IPV4_MAX_BITLEN; break; case NEXTHOP_TYPE_IPV6: @@ -1264,14 +1264,14 @@ static enum route_map_cmd_result_t route_match_ipv6_next_hop_type(void *rule, const struct prefix *prefix, void *object) { - struct nh_rmap_obj *nh_data; + struct zebra_rmap_obj *rm_data; if (prefix->family == AF_INET6) { - nh_data = (struct nh_rmap_obj *)object; - if (!nh_data) + rm_data = (struct zebra_rmap_obj *)object; + if (!rm_data) return RMAP_NOMATCH; - if (nh_data->nexthop->type == NEXTHOP_TYPE_BLACKHOLE) + if (rm_data->nexthop->type == NEXTHOP_TYPE_BLACKHOLE) return RMAP_MATCH; } @@ -1356,21 +1356,21 @@ route_match_ip_nexthop_prefix_len(void *rule, const struct prefix *prefix, void *object) { uint32_t *prefixlen = (uint32_t *)rule; - struct nh_rmap_obj *nh_data; + struct zebra_rmap_obj *rm_data; struct prefix_ipv4 p; - nh_data = (struct nh_rmap_obj *)object; - if (!nh_data || !nh_data->nexthop) + rm_data = (struct zebra_rmap_obj *)object; + if (!rm_data || !rm_data->nexthop) return RMAP_NOMATCH; - switch (nh_data->nexthop->type) { + switch (rm_data->nexthop->type) { case NEXTHOP_TYPE_IFINDEX: /* Interface routes can't match ip next-hop */ return RMAP_NOMATCH; case NEXTHOP_TYPE_IPV4_IFINDEX: case NEXTHOP_TYPE_IPV4: p.family = AF_INET; - p.prefix = nh_data->nexthop->gate.ipv4; + p.prefix = rm_data->nexthop->gate.ipv4; p.prefixlen = IPV4_MAX_BITLEN; break; case NEXTHOP_TYPE_IPV6: @@ -1395,14 +1395,14 @@ static enum route_map_cmd_result_t route_match_ip_next_hop_type(void *rule, const struct prefix *prefix, void *object) { - struct nh_rmap_obj *nh_data; + struct zebra_rmap_obj *rm_data; if (prefix->family == AF_INET) { - nh_data = (struct nh_rmap_obj *)object; - if (!nh_data) + rm_data = (struct zebra_rmap_obj *)object; + if (!rm_data) return RMAP_NOMATCH; - if (nh_data->nexthop->type == NEXTHOP_TYPE_BLACKHOLE) + if (rm_data->nexthop->type == NEXTHOP_TYPE_BLACKHOLE) return RMAP_MATCH; } @@ -1433,13 +1433,13 @@ static enum route_map_cmd_result_t route_match_source_protocol(void *rule, const struct prefix *p, void *object) { uint32_t *rib_type = (uint32_t *)rule; - struct nh_rmap_obj *nh_data; + struct zebra_rmap_obj *rm_data; - nh_data = (struct nh_rmap_obj *)object; - if (!nh_data) + rm_data = (struct zebra_rmap_obj *)object; + if (!rm_data) return RMAP_NOMATCH; - return ((nh_data->source_protocol == *rib_type) ? RMAP_MATCH + return ((rm_data->source_protocol == *rib_type) ? RMAP_MATCH : RMAP_NOMATCH); } @@ -1473,13 +1473,13 @@ static enum route_map_cmd_result_t route_match_source_instance(void *rule, const struct prefix *p, void *object) { uint8_t *instance = (uint8_t *)rule; - struct nh_rmap_obj *nh_data; + struct zebra_rmap_obj *rm_data; - nh_data = (struct nh_rmap_obj *)object; - if (!nh_data) + rm_data = (struct zebra_rmap_obj *)object; + if (!rm_data) return RMAP_NOMATCH; - return (nh_data->instance == *instance) ? RMAP_MATCH : RMAP_NOMATCH; + return (rm_data->instance == *instance) ? RMAP_MATCH : RMAP_NOMATCH; } static void *route_match_source_instance_compile(const char *arg) @@ -1513,10 +1513,10 @@ static const struct route_map_rule_cmd route_match_source_instance_cmd = { static enum route_map_cmd_result_t route_set_src(void *rule, const struct prefix *prefix, void *object) { - struct nh_rmap_obj *nh_data; + struct zebra_rmap_obj *rm_data; - nh_data = (struct nh_rmap_obj *)object; - nh_data->nexthop->rmap_src = *(union g_addr *)rule; + rm_data = (struct zebra_rmap_obj *)object; + rm_data->nexthop->rmap_src = *(union g_addr *)rule; return RMAP_OKAY; } @@ -1769,14 +1769,14 @@ zebra_route_map_check(afi_t family, int rib_type, uint8_t instance, struct route_map *rmap = NULL; char *rm_name; route_map_result_t ret = RMAP_PERMITMATCH; - struct nh_rmap_obj nh_obj; + struct zebra_rmap_obj rm_obj; - nh_obj.nexthop = nexthop; - nh_obj.vrf_id = nexthop->vrf_id; - nh_obj.source_protocol = rib_type; - nh_obj.instance = instance; - nh_obj.metric = 0; - nh_obj.tag = tag; + rm_obj.nexthop = nexthop; + rm_obj.vrf_id = nexthop->vrf_id; + rm_obj.source_protocol = rib_type; + rm_obj.instance = instance; + rm_obj.metric = 0; + rm_obj.tag = tag; if (rib_type >= 0 && rib_type < ZEBRA_ROUTE_MAX) { rm_name = PROTO_RM_NAME(zvrf, family, rib_type); @@ -1793,7 +1793,7 @@ zebra_route_map_check(afi_t family, int rib_type, uint8_t instance, return RMAP_DENYMATCH; } if (rmap) { - ret = route_map_apply(rmap, p, &nh_obj); + ret = route_map_apply(rmap, p, &rm_obj); } return (ret); @@ -1825,19 +1825,19 @@ zebra_import_table_route_map_check(int family, int re_type, uint8_t instance, { struct route_map *rmap = NULL; route_map_result_t ret = RMAP_DENYMATCH; - struct nh_rmap_obj nh_obj; + struct zebra_rmap_obj rm_obj; - 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; + rm_obj.nexthop = nexthop; + rm_obj.vrf_id = vrf_id; + rm_obj.source_protocol = re_type; + rm_obj.instance = instance; + rm_obj.metric = 0; + rm_obj.tag = tag; if (re_type >= 0 && re_type < ZEBRA_ROUTE_MAX) rmap = route_map_lookup_by_name(rmap_name); if (rmap) { - ret = route_map_apply(rmap, p, &nh_obj); + ret = route_map_apply(rmap, p, &rm_obj); } return (ret); @@ -1851,21 +1851,21 @@ route_map_result_t zebra_nht_route_map_check(afi_t afi, int client_proto, { struct route_map *rmap = NULL; route_map_result_t ret = RMAP_PERMITMATCH; - struct nh_rmap_obj nh_obj; + struct zebra_rmap_obj rm_obj; - 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; + rm_obj.nexthop = nexthop; + rm_obj.vrf_id = nexthop->vrf_id; + rm_obj.source_protocol = re->type; + rm_obj.instance = re->instance; + rm_obj.metric = re->metric; + rm_obj.tag = re->tag; if (client_proto >= 0 && client_proto < ZEBRA_ROUTE_MAX) rmap = NHT_RM_MAP(zvrf, afi, client_proto); if (!rmap && NHT_RM_MAP(zvrf, afi, ZEBRA_ROUTE_MAX)) rmap = NHT_RM_MAP(zvrf, afi, ZEBRA_ROUTE_MAX); if (rmap) - ret = route_map_apply(rmap, p, &nh_obj); + ret = route_map_apply(rmap, p, &rm_obj); return ret; } From 112bb33db504a14381754a8691af85ef22f826a3 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 11 Aug 2023 10:18:41 -0400 Subject: [PATCH 2/7] zebra: import table match against interface name could fail If an import table route-map is trying to match against a particular interface, The code is matching against the actual vrf the route entry is in -vs- the vrf the nexthop entry is in. Let's modify the code to actually allow the import table entry to match against the nexthops vrf. Not working: ip import-table 91 ip import-table 93 route-map FOO no service integrated-vtysh-config ! debug zebra events ! interface green ip address 192.168.4.3/24 exit ! route-map FOO permit 10 match interface green exit eva# show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP, F - PBR, f - OpenFabric, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp13s0, 1d10h07m T[91]>* 1.2.3.5/32 [15/0] via 192.168.119.1, enp13s0, 00:00:05 K>* 169.254.0.0/16 [0/1000] is directly connected, virbr0 linkdown, 1d16h34m C>* 192.168.44.0/24 is directly connected, virbr1, 01:30:51 C>* 192.168.45.0/24 is directly connected, virbr2, 01:30:51 C>* 192.168.119.0/24 is directly connected, enp13s0, 1d16h34m C>* 192.168.122.0/24 is directly connected, virbr0 linkdown, 01:30:51 eva# show ip route table 91 Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP, F - PBR, f - OpenFabric, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure VRF default table 91: K>* 1.2.3.5/32 [0/0] via 192.168.119.1, enp13s0, 00:00:15 eva# show ip route table 93 Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP, F - PBR, f - OpenFabric, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure VRF default table 93: K * 1.2.3.4/32 [0/0] via 192.168.4.5, green (vrf green), 00:03:05 Working: eva# show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP, F - PBR, f - OpenFabric, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp13s0, 00:03:09 T[93]>* 1.2.3.4/32 [15/0] via 192.168.4.5, green (vrf green), 00:02:21 T[91]>* 1.2.3.5/32 [15/0] via 192.168.119.1, enp13s0, 00:02:26 K>* 169.254.0.0/16 [0/1000] is directly connected, virbr0, 00:03:09 C>* 192.168.44.0/24 is directly connected, virbr1, 00:03:09 C>* 192.168.45.0/24 is directly connected, virbr2, 00:03:09 C>* 192.168.119.0/24 is directly connected, enp13s0, 00:03:09 C>* 192.168.122.0/24 is directly connected, virbr0, 00:03:09 eva# show ip route table 91 Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP, F - PBR, f - OpenFabric, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure VRF default table 91: K * 1.2.3.5/32 [0/0] via 192.168.119.1, enp13s0, 00:03:12 eva# show ip route table 93 Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP, F - PBR, f - OpenFabric, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure VRF default table 93: K * 1.2.3.4/32 [0/0] via 192.168.4.5, green (vrf green), 00:03:14 Signed-off-by: Donald Sharp --- zebra/redistribute.c | 8 ++++---- zebra/zebra_routemap.c | 11 ++++------- zebra/zebra_routemap.h | 8 +++----- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 9ca9c7a55a..89394d5b22 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -647,10 +647,10 @@ int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, afi = family2afi(rn->p.family); if (rmap_name) - ret = zebra_import_table_route_map_check( - afi, re->type, re->instance, &rn->p, - re->nhe->nhg.nexthop, - zvrf->vrf->vrf_id, re->tag, rmap_name); + ret = zebra_import_table_route_map_check(afi, re->type, + re->instance, &rn->p, + re->nhe->nhg.nexthop, + re->tag, rmap_name); if (ret != RMAP_PERMITMATCH) { UNSET_FLAG(re->flags, ZEBRA_FLAG_SELECTED); diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 91c8af9c6c..e0aff191fd 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -1816,19 +1816,16 @@ 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 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) +route_map_result_t zebra_import_table_route_map_check( + int family, int re_type, uint8_t instance, const struct prefix *p, + struct nexthop *nexthop, route_tag_t tag, const char *rmap_name) { struct route_map *rmap = NULL; route_map_result_t ret = RMAP_DENYMATCH; struct zebra_rmap_obj rm_obj; rm_obj.nexthop = nexthop; - rm_obj.vrf_id = vrf_id; + rm_obj.vrf_id = nexthop->vrf_id; rm_obj.source_protocol = re_type; rm_obj.instance = instance; rm_obj.metric = 0; diff --git a/zebra/zebra_routemap.h b/zebra/zebra_routemap.h index f77735edc2..0921933ef7 100644 --- a/zebra/zebra_routemap.h +++ b/zebra/zebra_routemap.h @@ -21,11 +21,9 @@ 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 route_map_result_t -zebra_import_table_route_map_check(int family, int rib_type, uint8_t instance, - const struct prefix *p, - struct nexthop *nexthop, vrf_id_t vrf_id, - route_tag_t tag, const char *rmap_name); +extern route_map_result_t zebra_import_table_route_map_check( + int family, int rib_type, uint8_t instance, const struct prefix *p, + struct nexthop *nexthop, route_tag_t tag, const char *rmap_name); extern route_map_result_t zebra_route_map_check(afi_t family, int rib_type, uint8_t instance, const struct prefix *p, struct nexthop *nexthop, From 8d56ba855b21882c9f9195e27b324d6af4741938 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 11 Aug 2023 11:06:04 -0400 Subject: [PATCH 3/7] zebra: Remove vrf_id from passed around object The nexthop that is stored already knows it's nexthop and in all cases the vrf id is derived from the nexthop->vrf_id let's just cut to the chase and not do this. Signed-off-by: Donald Sharp --- zebra/zebra_routemap.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index e0aff191fd..ec76222b3e 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -33,7 +33,6 @@ char *zebra_import_table_routemap[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; struct zebra_rmap_obj { struct nexthop *nexthop; - vrf_id_t vrf_id; uint32_t source_protocol; uint8_t instance; int metric; @@ -83,7 +82,7 @@ route_match_interface(void *rule, const struct prefix *prefix, void *object) rm_data = object; if (!rm_data || !rm_data->nexthop) return RMAP_NOMATCH; - ifindex = ifname2ifindex(ifname, rm_data->vrf_id); + ifindex = ifname2ifindex(ifname, rm_data->nexthop->vrf_id); if (ifindex == 0) return RMAP_NOMATCH; if (rm_data->nexthop->ifindex == ifindex) @@ -1772,7 +1771,6 @@ zebra_route_map_check(afi_t family, int rib_type, uint8_t instance, struct zebra_rmap_obj rm_obj; rm_obj.nexthop = nexthop; - rm_obj.vrf_id = nexthop->vrf_id; rm_obj.source_protocol = rib_type; rm_obj.instance = instance; rm_obj.metric = 0; @@ -1825,7 +1823,6 @@ route_map_result_t zebra_import_table_route_map_check( struct zebra_rmap_obj rm_obj; rm_obj.nexthop = nexthop; - rm_obj.vrf_id = nexthop->vrf_id; rm_obj.source_protocol = re_type; rm_obj.instance = instance; rm_obj.metric = 0; @@ -1851,7 +1848,6 @@ route_map_result_t zebra_nht_route_map_check(afi_t afi, int client_proto, struct zebra_rmap_obj rm_obj; rm_obj.nexthop = nexthop; - rm_obj.vrf_id = nexthop->vrf_id; rm_obj.source_protocol = re->type; rm_obj.instance = re->instance; rm_obj.metric = re->metric; From cad4d0c3327d6985446c949bc087a277ce9bb930 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 11 Aug 2023 11:11:40 -0400 Subject: [PATCH 4/7] zebra: Replace source_protocol with just using re in route map object Replace the source_protocol with just saving a pointer to the re in the `struct zebra_rmap_obj` data structure. Signed-off-by: Donald Sharp --- zebra/redistribute.c | 4 ++-- zebra/zebra_nhg.c | 4 ++-- zebra/zebra_routemap.c | 31 ++++++++++++++++--------------- zebra/zebra_routemap.h | 19 +++++++++++-------- 4 files changed, 31 insertions(+), 27 deletions(-) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 89394d5b22..c87da5ed6c 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -647,8 +647,8 @@ int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, afi = family2afi(rn->p.family); if (rmap_name) - ret = zebra_import_table_route_map_check(afi, re->type, - re->instance, &rn->p, + ret = zebra_import_table_route_map_check(afi, re, re->instance, + &rn->p, re->nhe->nhg.nexthop, re->tag, rmap_name); diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index a701b582ce..8c640f4e32 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -2703,8 +2703,8 @@ skip_check: } /* It'll get set if required inside */ - ret = zebra_route_map_check(family, re->type, re->instance, p, nexthop, - zvrf, re->tag); + ret = zebra_route_map_check(family, re, re->instance, p, nexthop, zvrf, + re->tag); if (ret == RMAP_DENYMATCH) { if (IS_ZEBRA_DEBUG_RIB) { zlog_debug( diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index ec76222b3e..e0069912f9 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -33,7 +33,7 @@ char *zebra_import_table_routemap[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; struct zebra_rmap_obj { struct nexthop *nexthop; - uint32_t source_protocol; + struct route_entry *re; uint8_t instance; int metric; route_tag_t tag; @@ -1431,15 +1431,14 @@ static const struct route_map_rule_cmd static enum route_map_cmd_result_t route_match_source_protocol(void *rule, const struct prefix *p, void *object) { - uint32_t *rib_type = (uint32_t *)rule; + int32_t *rib_type = (int32_t *)rule; struct zebra_rmap_obj *rm_data; rm_data = (struct zebra_rmap_obj *)object; if (!rm_data) return RMAP_NOMATCH; - return ((rm_data->source_protocol == *rib_type) ? RMAP_MATCH - : RMAP_NOMATCH); + return ((rm_data->re->type == *rib_type) ? RMAP_MATCH : RMAP_NOMATCH); } static void *route_match_source_protocol_compile(const char *arg) @@ -1761,7 +1760,7 @@ void zebra_routemap_finish(void) } route_map_result_t -zebra_route_map_check(afi_t family, int rib_type, uint8_t instance, +zebra_route_map_check(afi_t family, struct route_entry *re, uint8_t instance, const struct prefix *p, struct nexthop *nexthop, struct zebra_vrf *zvrf, route_tag_t tag) { @@ -1771,14 +1770,14 @@ zebra_route_map_check(afi_t family, int rib_type, uint8_t instance, struct zebra_rmap_obj rm_obj; rm_obj.nexthop = nexthop; - rm_obj.source_protocol = rib_type; + rm_obj.re = re; rm_obj.instance = instance; rm_obj.metric = 0; rm_obj.tag = tag; - if (rib_type >= 0 && rib_type < ZEBRA_ROUTE_MAX) { - rm_name = PROTO_RM_NAME(zvrf, family, rib_type); - rmap = PROTO_RM_MAP(zvrf, family, rib_type); + if (re->type >= 0 && re->type < ZEBRA_ROUTE_MAX) { + rm_name = PROTO_RM_NAME(zvrf, family, re->type); + rmap = PROTO_RM_MAP(zvrf, family, re->type); if (rm_name && !rmap) return RMAP_DENYMATCH; @@ -1814,21 +1813,23 @@ 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 re_type, uint8_t instance, const struct prefix *p, - struct nexthop *nexthop, route_tag_t tag, const char *rmap_name) +route_map_result_t +zebra_import_table_route_map_check(int family, struct route_entry *re, + uint8_t instance, const struct prefix *p, + struct nexthop *nexthop, route_tag_t tag, + const char *rmap_name) { struct route_map *rmap = NULL; route_map_result_t ret = RMAP_DENYMATCH; struct zebra_rmap_obj rm_obj; rm_obj.nexthop = nexthop; - rm_obj.source_protocol = re_type; + rm_obj.re = re; rm_obj.instance = instance; rm_obj.metric = 0; rm_obj.tag = tag; - if (re_type >= 0 && re_type < ZEBRA_ROUTE_MAX) + if (re->type >= 0 && re->type < ZEBRA_ROUTE_MAX) rmap = route_map_lookup_by_name(rmap_name); if (rmap) { ret = route_map_apply(rmap, p, &rm_obj); @@ -1848,7 +1849,7 @@ route_map_result_t zebra_nht_route_map_check(afi_t afi, int client_proto, struct zebra_rmap_obj rm_obj; rm_obj.nexthop = nexthop; - rm_obj.source_protocol = re->type; + rm_obj.re = re; rm_obj.instance = re->instance; rm_obj.metric = re->metric; rm_obj.tag = re->tag; diff --git a/zebra/zebra_routemap.h b/zebra/zebra_routemap.h index 0921933ef7..81a34ef28c 100644 --- a/zebra/zebra_routemap.h +++ b/zebra/zebra_routemap.h @@ -21,17 +21,20 @@ 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 route_map_result_t zebra_import_table_route_map_check( - int family, int rib_type, uint8_t instance, const struct prefix *p, - struct nexthop *nexthop, route_tag_t tag, const char *rmap_name); extern route_map_result_t -zebra_route_map_check(afi_t family, int rib_type, uint8_t instance, +zebra_import_table_route_map_check(int family, struct route_entry *re, + uint8_t instance, const struct prefix *p, + struct nexthop *nexthop, route_tag_t tag, + const char *rmap_name); +extern route_map_result_t +zebra_route_map_check(afi_t family, struct route_entry *re, uint8_t instance, const struct prefix *p, struct nexthop *nexthop, struct zebra_vrf *zvrf, route_tag_t tag); -extern route_map_result_t -zebra_nht_route_map_check(afi_t afi, int client_proto, const struct prefix *p, - struct zebra_vrf *zvrf, struct route_entry *, - struct nexthop *nexthop); +extern route_map_result_t zebra_nht_route_map_check(afi_t afi, int client_proto, + const struct prefix *p, + struct zebra_vrf *zvrf, + struct route_entry *re, + struct nexthop *nexthop); extern void zebra_routemap_vrf_delete(struct zebra_vrf *zvrf); From b7542d5af889e039ef19e1fd00d0116396659688 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 11 Aug 2023 11:15:06 -0400 Subject: [PATCH 5/7] zebra: Remove instance from zebra_rmap_obj data structure In all cases the instance is derived from the re pointer and since the re pointer is already stored, let's just remove it from the game and cut to the chase. Signed-off-by: Donald Sharp --- zebra/redistribute.c | 3 +-- zebra/zebra_nhg.c | 3 +-- zebra/zebra_routemap.c | 22 ++++++++-------------- zebra/zebra_routemap.h | 10 ++++------ 4 files changed, 14 insertions(+), 24 deletions(-) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index c87da5ed6c..9e73e6a2fd 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -647,8 +647,7 @@ int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, afi = family2afi(rn->p.family); if (rmap_name) - ret = zebra_import_table_route_map_check(afi, re, re->instance, - &rn->p, + ret = zebra_import_table_route_map_check(afi, re, &rn->p, re->nhe->nhg.nexthop, re->tag, rmap_name); diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 8c640f4e32..b94475fc08 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -2703,8 +2703,7 @@ skip_check: } /* It'll get set if required inside */ - ret = zebra_route_map_check(family, re, re->instance, p, nexthop, zvrf, - re->tag); + ret = zebra_route_map_check(family, re, p, nexthop, zvrf, re->tag); if (ret == RMAP_DENYMATCH) { if (IS_ZEBRA_DEBUG_RIB) { zlog_debug( diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index e0069912f9..f5c194fe3f 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -34,7 +34,6 @@ char *zebra_import_table_routemap[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; struct zebra_rmap_obj { struct nexthop *nexthop; struct route_entry *re; - uint8_t instance; int metric; route_tag_t tag; }; @@ -1477,7 +1476,7 @@ route_match_source_instance(void *rule, const struct prefix *p, void *object) if (!rm_data) return RMAP_NOMATCH; - return (rm_data->instance == *instance) ? RMAP_MATCH : RMAP_NOMATCH; + return (rm_data->re->instance == *instance) ? RMAP_MATCH : RMAP_NOMATCH; } static void *route_match_source_instance_compile(const char *arg) @@ -1759,10 +1758,10 @@ void zebra_routemap_finish(void) route_map_finish(); } -route_map_result_t -zebra_route_map_check(afi_t family, struct route_entry *re, uint8_t instance, - const struct prefix *p, struct nexthop *nexthop, - struct zebra_vrf *zvrf, route_tag_t tag) +route_map_result_t zebra_route_map_check(afi_t family, struct route_entry *re, + const struct prefix *p, + struct nexthop *nexthop, + struct zebra_vrf *zvrf, route_tag_t tag) { struct route_map *rmap = NULL; char *rm_name; @@ -1771,7 +1770,6 @@ zebra_route_map_check(afi_t family, struct route_entry *re, uint8_t instance, rm_obj.nexthop = nexthop; rm_obj.re = re; - rm_obj.instance = instance; rm_obj.metric = 0; rm_obj.tag = tag; @@ -1813,11 +1811,9 @@ 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, struct route_entry *re, - uint8_t instance, const struct prefix *p, - struct nexthop *nexthop, route_tag_t tag, - const char *rmap_name) +route_map_result_t zebra_import_table_route_map_check( + int family, struct route_entry *re, const struct prefix *p, + struct nexthop *nexthop, route_tag_t tag, const char *rmap_name) { struct route_map *rmap = NULL; route_map_result_t ret = RMAP_DENYMATCH; @@ -1825,7 +1821,6 @@ zebra_import_table_route_map_check(int family, struct route_entry *re, rm_obj.nexthop = nexthop; rm_obj.re = re; - rm_obj.instance = instance; rm_obj.metric = 0; rm_obj.tag = tag; @@ -1850,7 +1845,6 @@ route_map_result_t zebra_nht_route_map_check(afi_t afi, int client_proto, rm_obj.nexthop = nexthop; rm_obj.re = re; - rm_obj.instance = re->instance; rm_obj.metric = re->metric; rm_obj.tag = re->tag; diff --git a/zebra/zebra_routemap.h b/zebra/zebra_routemap.h index 81a34ef28c..3fa1476896 100644 --- a/zebra/zebra_routemap.h +++ b/zebra/zebra_routemap.h @@ -21,13 +21,11 @@ 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 route_map_result_t zebra_import_table_route_map_check( + int family, struct route_entry *re, const struct prefix *p, + struct nexthop *nexthop, route_tag_t tag, const char *rmap_name); extern route_map_result_t -zebra_import_table_route_map_check(int family, struct route_entry *re, - uint8_t instance, const struct prefix *p, - struct nexthop *nexthop, route_tag_t tag, - const char *rmap_name); -extern route_map_result_t -zebra_route_map_check(afi_t family, struct route_entry *re, uint8_t instance, +zebra_route_map_check(afi_t family, struct route_entry *re, const struct prefix *p, struct nexthop *nexthop, struct zebra_vrf *zvrf, route_tag_t tag); extern route_map_result_t zebra_nht_route_map_check(afi_t afi, int client_proto, From 17bcaad841f4f420ce441cfd2a471e0a385afb0b Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 11 Aug 2023 11:17:29 -0400 Subject: [PATCH 6/7] zebra: Use the re->metric instead of 0 for zebra_rmap_obj The zebra_rmap_obj was storing the re->metric and allowing matches against it, but in most cases it was just using 0. Use the Route entries metric instead. This should fix some bugs where a match metric never worked. Signed-off-by: Donald Sharp --- zebra/zebra_routemap.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index f5c194fe3f..7e17cff2d5 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -34,7 +34,6 @@ char *zebra_import_table_routemap[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; struct zebra_rmap_obj { struct nexthop *nexthop; struct route_entry *re; - int metric; route_tag_t tag; }; @@ -1770,7 +1769,6 @@ route_map_result_t zebra_route_map_check(afi_t family, struct route_entry *re, rm_obj.nexthop = nexthop; rm_obj.re = re; - rm_obj.metric = 0; rm_obj.tag = tag; if (re->type >= 0 && re->type < ZEBRA_ROUTE_MAX) { @@ -1821,7 +1819,6 @@ route_map_result_t zebra_import_table_route_map_check( rm_obj.nexthop = nexthop; rm_obj.re = re; - rm_obj.metric = 0; rm_obj.tag = tag; if (re->type >= 0 && re->type < ZEBRA_ROUTE_MAX) @@ -1845,7 +1842,6 @@ route_map_result_t zebra_nht_route_map_check(afi_t afi, int client_proto, rm_obj.nexthop = nexthop; rm_obj.re = re; - rm_obj.metric = re->metric; rm_obj.tag = re->tag; if (client_proto >= 0 && client_proto < ZEBRA_ROUTE_MAX) From d381190a5549163ac97945fcb4d716da5c04c46d Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 11 Aug 2023 11:21:03 -0400 Subject: [PATCH 7/7] zebra: Remove tag from zebra_rmap_obj The tag value in all cases was being set to the re->tag. re is already stored, so let's just use that. Signed-off-by: Donald Sharp --- zebra/redistribute.c | 2 +- zebra/zebra_nhg.c | 2 +- zebra/zebra_routemap.c | 16 +++++++--------- zebra/zebra_routemap.h | 11 ++++++----- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 9e73e6a2fd..8c8cbfc8d1 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -649,7 +649,7 @@ int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, if (rmap_name) ret = zebra_import_table_route_map_check(afi, re, &rn->p, re->nhe->nhg.nexthop, - re->tag, rmap_name); + rmap_name); if (ret != RMAP_PERMITMATCH) { UNSET_FLAG(re->flags, ZEBRA_FLAG_SELECTED); diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index b94475fc08..d3c86e2a37 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -2703,7 +2703,7 @@ skip_check: } /* It'll get set if required inside */ - ret = zebra_route_map_check(family, re, p, nexthop, zvrf, re->tag); + ret = zebra_route_map_check(family, re, p, nexthop, zvrf); if (ret == RMAP_DENYMATCH) { if (IS_ZEBRA_DEBUG_RIB) { zlog_debug( diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 7e17cff2d5..21aaf1d066 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -34,7 +34,6 @@ char *zebra_import_table_routemap[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; struct zebra_rmap_obj { struct nexthop *nexthop; struct route_entry *re; - route_tag_t tag; }; static void zebra_route_map_set_delay_timer(uint32_t value); @@ -51,7 +50,7 @@ route_match_tag(void *rule, const struct prefix *prefix, void *object) tag = rule; rm_data = object; - if (rm_data->tag == *tag) + if (rm_data->re->tag == *tag) return RMAP_MATCH; return RMAP_NOMATCH; @@ -1760,7 +1759,7 @@ void zebra_routemap_finish(void) route_map_result_t zebra_route_map_check(afi_t family, struct route_entry *re, const struct prefix *p, struct nexthop *nexthop, - struct zebra_vrf *zvrf, route_tag_t tag) + struct zebra_vrf *zvrf) { struct route_map *rmap = NULL; char *rm_name; @@ -1769,7 +1768,6 @@ route_map_result_t zebra_route_map_check(afi_t family, struct route_entry *re, rm_obj.nexthop = nexthop; rm_obj.re = re; - rm_obj.tag = tag; if (re->type >= 0 && re->type < ZEBRA_ROUTE_MAX) { rm_name = PROTO_RM_NAME(zvrf, family, re->type); @@ -1809,9 +1807,11 @@ 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, struct route_entry *re, const struct prefix *p, - struct nexthop *nexthop, route_tag_t tag, const char *rmap_name) +route_map_result_t zebra_import_table_route_map_check(int family, + struct route_entry *re, + const struct prefix *p, + struct nexthop *nexthop, + const char *rmap_name) { struct route_map *rmap = NULL; route_map_result_t ret = RMAP_DENYMATCH; @@ -1819,7 +1819,6 @@ route_map_result_t zebra_import_table_route_map_check( rm_obj.nexthop = nexthop; rm_obj.re = re; - rm_obj.tag = tag; if (re->type >= 0 && re->type < ZEBRA_ROUTE_MAX) rmap = route_map_lookup_by_name(rmap_name); @@ -1842,7 +1841,6 @@ route_map_result_t zebra_nht_route_map_check(afi_t afi, int client_proto, rm_obj.nexthop = nexthop; rm_obj.re = re; - rm_obj.tag = re->tag; if (client_proto >= 0 && client_proto < ZEBRA_ROUTE_MAX) rmap = NHT_RM_MAP(zvrf, afi, client_proto); diff --git a/zebra/zebra_routemap.h b/zebra/zebra_routemap.h index 3fa1476896..fceb53c841 100644 --- a/zebra/zebra_routemap.h +++ b/zebra/zebra_routemap.h @@ -23,11 +23,12 @@ extern void zebra_del_import_table_route_map(afi_t afi, uint32_t table); extern route_map_result_t zebra_import_table_route_map_check( int family, struct route_entry *re, const struct prefix *p, - struct nexthop *nexthop, route_tag_t tag, const char *rmap_name); -extern route_map_result_t -zebra_route_map_check(afi_t family, struct route_entry *re, - const struct prefix *p, struct nexthop *nexthop, - struct zebra_vrf *zvrf, route_tag_t tag); + struct nexthop *nexthop, const char *rmap_name); +extern route_map_result_t zebra_route_map_check(afi_t family, + struct route_entry *re, + const struct prefix *p, + struct nexthop *nexthop, + struct zebra_vrf *zvrf); extern route_map_result_t zebra_nht_route_map_check(afi_t afi, int client_proto, const struct prefix *p, struct zebra_vrf *zvrf,