diff options
-rw-r--r-- | include/tcpopt.h | 4 | ||||
-rw-r--r-- | src/exthdr.c | 46 | ||||
-rw-r--r-- | src/tcpopt.c | 7 |
3 files changed, 27 insertions, 30 deletions
diff --git a/include/tcpopt.h b/include/tcpopt.h index bb5c1329..3a0b8424 100644 --- a/include/tcpopt.h +++ b/include/tcpopt.h @@ -12,8 +12,8 @@ extern void tcpopt_init_raw(struct expr *expr, uint8_t type, unsigned int offset, unsigned int len, uint32_t flags); -extern bool tcpopt_find_template(struct expr *expr, const struct expr *mask, - unsigned int *shift); +extern bool tcpopt_find_template(struct expr *expr, unsigned int offset, + unsigned int len); /* TCP option numbers used on wire */ enum tcpopt_kind { diff --git a/src/exthdr.c b/src/exthdr.c index c02b17d3..2357ab60 100644 --- a/src/exthdr.c +++ b/src/exthdr.c @@ -348,16 +348,7 @@ static unsigned int mask_length(const struct expr *mask) bool exthdr_find_template(struct expr *expr, const struct expr *mask, unsigned int *shift) { unsigned int off, mask_offset, mask_len; - - if (expr->exthdr.op != NFT_EXTHDR_OP_IPV4 && - expr->exthdr.tmpl != &exthdr_unknown_template) - return false; - - /* In case we are handling tcp options instead of the default ipv6 - * extension headers. - */ - if (expr->exthdr.op == NFT_EXTHDR_OP_TCPOPT) - return tcpopt_find_template(expr, mask, shift); + bool found; mask_offset = mpz_scan1(mask->value, 0); mask_len = mask_length(mask); @@ -366,24 +357,31 @@ bool exthdr_find_template(struct expr *expr, const struct expr *mask, unsigned i off += round_up(mask->len, BITS_PER_BYTE) - mask_len; /* Handle ip options after the offset and mask have been calculated. */ - if (expr->exthdr.op == NFT_EXTHDR_OP_IPV4) { - if (ipopt_find_template(expr, off, mask_len - mask_offset)) { - *shift = mask_offset; - return true; - } else { + switch (expr->exthdr.op) { + case NFT_EXTHDR_OP_IPV4: + found = ipopt_find_template(expr, off, mask_len - mask_offset); + break; + case NFT_EXTHDR_OP_TCPOPT: + found = tcpopt_find_template(expr, off, mask_len - mask_offset); + break; + case NFT_EXTHDR_OP_IPV6: + exthdr_init_raw(expr, expr->exthdr.desc->type, + off, mask_len - mask_offset, expr->exthdr.op, 0); + + /* still failed to find a template... Bug. */ + if (expr->exthdr.tmpl == &exthdr_unknown_template) return false; - } + found = true; + break; + default: + found = false; + break; } - exthdr_init_raw(expr, expr->exthdr.desc->type, - off, mask_len - mask_offset, expr->exthdr.op, 0); - - /* still failed to find a template... Bug. */ - if (expr->exthdr.tmpl == &exthdr_unknown_template) - return false; + if (found) + *shift = mask_offset; - *shift = mask_offset; - return true; + return found; } #define HDR_TEMPLATE(__name, __dtype, __type, __member) \ diff --git a/src/tcpopt.c b/src/tcpopt.c index 641daa73..c3e07d78 100644 --- a/src/tcpopt.c +++ b/src/tcpopt.c @@ -225,6 +225,7 @@ void tcpopt_init_raw(struct expr *expr, uint8_t type, unsigned int off, expr->exthdr.flags = flags; expr->exthdr.offset = off; expr->exthdr.op = NFT_EXTHDR_OP_TCPOPT; + expr->exthdr.tmpl = &tcpopt_unknown_template; if (flags & NFT_EXTHDR_F_PRESENT) datatype_set(expr, &boolean_type); @@ -252,14 +253,12 @@ void tcpopt_init_raw(struct expr *expr, uint8_t type, unsigned int off, } } -bool tcpopt_find_template(struct expr *expr, const struct expr *mask, - unsigned int *shift) +bool tcpopt_find_template(struct expr *expr, unsigned int offset, unsigned int len) { if (expr->exthdr.tmpl != &tcpopt_unknown_template) return false; - tcpopt_init_raw(expr, expr->exthdr.desc->type, expr->exthdr.offset, - expr->len, 0); + tcpopt_init_raw(expr, expr->exthdr.desc->type, offset, len, 0); if (expr->exthdr.tmpl == &tcpopt_unknown_template) return false; |