Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 1 | From f21a7a4849b50c30341ec571813bd7fe37040ad3 Mon Sep 17 00:00:00 2001 |
| 2 | From: Florian Westphal <fw@strlen.de> |
| 3 | Date: Thu, 18 May 2017 13:30:54 +0200 |
| 4 | Subject: [PATCH 4/4] payload: enforce ip/ip6 protocol depending on icmp or |
| 5 | icmpv6 |
| 6 | |
| 7 | After some discussion with Pablo we agreed to treat icmp/icmpv6 specially. |
| 8 | |
| 9 | in the case of a rule like 'tcp dport 22' the inet, bridge and netdev |
| 10 | families only care about the lower layer protocol. |
| 11 | |
| 12 | In the icmpv6 case however we'd like to also enforce an ipv6 protocol check |
| 13 | (and ipv4 check in icmp case). |
| 14 | |
| 15 | This extends payload_gen_special_dependency() to consider this. |
| 16 | With this patch: |
| 17 | |
| 18 | add rule $pf filter input meta l4proto icmpv6 |
| 19 | add rule $pf filter input meta l4proto icmpv6 icmpv6 type echo-request |
| 20 | add rule $pf filter input icmpv6 type echo-request |
| 21 | |
| 22 | will work in all tables and all families. |
| 23 | For inet/bridge/netdev, an ipv6 protocol dependency is added; this will |
| 24 | not match ipv4 packets with ip->protocol == icmpv6, EXCEPT in the case |
| 25 | of the ip family. |
| 26 | |
| 27 | Its still possible to match icmpv6-in-ipv4 in inet/bridge/netdev with an |
| 28 | explicit dependency: |
| 29 | |
| 30 | add rule inet f i ip protocol ipv6-icmp meta l4proto ipv6-icmp icmpv6 type ... |
| 31 | |
| 32 | Implicit dependencies won't get removed at the moment, so |
| 33 | bridge ... icmp type echo-request |
| 34 | will be shown as |
| 35 | ether type ip meta l4proto 1 icmp type echo-request |
| 36 | |
| 37 | Signed-off-by: Florian Westphal <fw@strlen.de> |
| 38 | --- |
| 39 | Upstream-Status: Backport |
| 40 | Signed-off-by: André Draszik <adraszik@tycoint.com> |
| 41 | src/payload.c | 27 +++++++++++++++++++++++---- |
| 42 | 1 file changed, 23 insertions(+), 4 deletions(-) |
| 43 | |
| 44 | diff --git a/src/payload.c b/src/payload.c |
| 45 | index 38db15e..8796ee5 100644 |
| 46 | --- a/src/payload.c |
| 47 | +++ b/src/payload.c |
| 48 | @@ -264,10 +264,29 @@ payload_gen_special_dependency(struct eval_ctx *ctx, const struct expr *expr) |
| 49 | case PROTO_BASE_LL_HDR: |
| 50 | return payload_get_get_ll_hdr(ctx); |
| 51 | case PROTO_BASE_TRANSPORT_HDR: |
| 52 | - if (expr->payload.desc == &proto_icmp) |
| 53 | - return &proto_ip; |
| 54 | - if (expr->payload.desc == &proto_icmp6) |
| 55 | - return &proto_ip6; |
| 56 | + if (expr->payload.desc == &proto_icmp || |
| 57 | + expr->payload.desc == &proto_icmp6) { |
| 58 | + const struct proto_desc *desc, *desc_upper; |
| 59 | + struct stmt *nstmt; |
| 60 | + |
| 61 | + desc = ctx->pctx.protocol[PROTO_BASE_LL_HDR].desc; |
| 62 | + if (!desc) { |
| 63 | + desc = payload_get_get_ll_hdr(ctx); |
| 64 | + if (!desc) |
| 65 | + break; |
| 66 | + } |
| 67 | + |
| 68 | + desc_upper = &proto_ip6; |
| 69 | + if (expr->payload.desc == &proto_icmp) |
| 70 | + desc_upper = &proto_ip; |
| 71 | + |
| 72 | + if (payload_add_dependency(ctx, desc, desc_upper, |
| 73 | + expr, &nstmt) < 0) |
| 74 | + return NULL; |
| 75 | + |
| 76 | + list_add_tail(&nstmt->list, &ctx->stmt->list); |
| 77 | + return desc_upper; |
| 78 | + } |
| 79 | return &proto_inet_service; |
| 80 | default: |
| 81 | break; |
| 82 | -- |
| 83 | 2.11.0 |
| 84 | |