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.
This commit is contained in:
Aurelien DARRAGON 2023-09-05 14:58:53 +02:00 committed by Christopher Faulet
parent 72514a4467
commit f80122db26

View File

@ -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;