From: Aurelien DARRAGON Date: Tue, 5 Sep 2023 12:58:53 +0000 (+0200) Subject: MINOR: pattern/ip: offload ip conversion logic to helper functions X-Git-Tag: v2.9-dev6~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f80122db266700259daa448b92a763e1b7a26dab;p=thirdparty%2Fhaproxy.git MINOR: pattern/ip: offload ip conversion logic to helper functions Now that v4tov6() and v6tov4() were reworked to match behavior from pat_match_ip() function in ("MINOR: tools/ip: v4tov6() and v6tov4() rework"), we can remove code duplication in pat_match_ip() by directly using those dedicated functions where relevant. --- diff --git a/src/pattern.c b/src/pattern.c index b393112d30..0a71237f3b 100644 --- a/src/pattern.c +++ b/src/pattern.c @@ -966,7 +966,7 @@ struct pattern *pat_match_len(struct sample *smp, struct pattern_expr *expr, int struct pattern *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int fill) { - unsigned int v4; /* in network byte order */ + struct in_addr v4; /* in network byte order */ struct in6_addr tmp6; struct in_addr *s; struct ebmb_node *node; @@ -1000,12 +1000,9 @@ struct pattern *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int } /* The IPv4 sample don't match the IPv4 tree. Convert the IPv4 - * sample address to IPv6 with the mapping method using the ::ffff: - * prefix, and try to lookup in the IPv6 tree. + * sample address to IPv6 and try to lookup in the IPv6 tree. */ - memset(&tmp6, 0, 10); - write_u16(&tmp6.s6_addr[10], htons(0xffff)); - write_u32(&tmp6.s6_addr[12], smp->data.u.ipv4.s_addr); + v4tov6(&tmp6, &smp->data.u.ipv4); node = ebmb_lookup_longest(&expr->pattern_tree_2, &tmp6); while (node) { elt = ebmb_entry(node, struct pattern_tree, node); @@ -1048,22 +1045,8 @@ struct pattern *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int return &static_pattern; } - /* Try to convert 6 to 4 when the start of the ipv6 address match the - * following forms : - * - ::ffff:ip:v4 (ipv4 mapped) - * - ::0000:ip:v4 (old ipv4 mapped) - * - 2002:ip:v4:: (6to4) - */ - if ((read_u64(&smp->data.u.ipv6.s6_addr[0]) == 0 && - (read_u32(&smp->data.u.ipv6.s6_addr[8]) == 0 || - read_u32(&smp->data.u.ipv6.s6_addr[8]) == htonl(0xFFFF))) || - read_u16(&smp->data.u.ipv6.s6_addr[0]) == htons(0x2002)) { - if (read_u32(&smp->data.u.ipv6.s6_addr[0]) == 0) - v4 = read_u32(&smp->data.u.ipv6.s6_addr[12]); - else - v4 = htonl((ntohs(read_u16(&smp->data.u.ipv6.s6_addr[2])) << 16) + - ntohs(read_u16(&smp->data.u.ipv6.s6_addr[4]))); - + /* Try to convert 6 to 4 */ + if (v6tov4(&v4, &smp->data.u.ipv6)) { /* Lookup an IPv4 address in the expression's pattern tree using the longest * match method. */ @@ -1097,25 +1080,11 @@ struct pattern *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int /* The input sample is IPv4, use it as is. */ if (smp->data.type == SMP_T_IPV4) { - v4 = smp->data.u.ipv4.s_addr; + v4.s_addr = smp->data.u.ipv4.s_addr; } else if (smp->data.type == SMP_T_IPV6) { - /* v4 match on a V6 sample. We want to check at least for - * the following forms : - * - ::ffff:ip:v4 (ipv4 mapped) - * - ::0000:ip:v4 (old ipv4 mapped) - * - 2002:ip:v4:: (6to4) - */ - if (read_u64(&smp->data.u.ipv6.s6_addr[0]) == 0 && - (read_u32(&smp->data.u.ipv6.s6_addr[8]) == 0 || - read_u32(&smp->data.u.ipv6.s6_addr[8]) == htonl(0xFFFF))) { - v4 = read_u32(&smp->data.u.ipv6.s6_addr[12]); - } - else if (read_u16(&smp->data.u.ipv6.s6_addr[0]) == htons(0x2002)) { - v4 = htonl((ntohs(read_u16(&smp->data.u.ipv6.s6_addr[2])) << 16) + - ntohs(read_u16(&smp->data.u.ipv6.s6_addr[4]))); - } - else + /* v4 match on a V6 sample. Try to convert v6 form to v4 address */ + if (!v6tov4(&v4, &smp->data.u.ipv6)) continue; } else { /* impossible */ @@ -1123,7 +1092,7 @@ struct pattern *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int } /* Check if the input sample match the current pattern. */ - if (((v4 ^ pattern->val.ipv4.addr.s_addr) & pattern->val.ipv4.mask.s_addr) == 0) + if (((v4.s_addr ^ pattern->val.ipv4.addr.s_addr) & pattern->val.ipv4.mask.s_addr) == 0) return pattern; } return NULL;