blob: 00076d7cef998ed90aed94f49abee943aa2a9e55 [file] [log] [blame]
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001From f21a7a4849b50c30341ec571813bd7fe37040ad3 Mon Sep 17 00:00:00 2001
2From: Florian Westphal <fw@strlen.de>
3Date: Thu, 18 May 2017 13:30:54 +0200
4Subject: [PATCH 4/4] payload: enforce ip/ip6 protocol depending on icmp or
5 icmpv6
6
7After some discussion with Pablo we agreed to treat icmp/icmpv6 specially.
8
9in the case of a rule like 'tcp dport 22' the inet, bridge and netdev
10families only care about the lower layer protocol.
11
12In the icmpv6 case however we'd like to also enforce an ipv6 protocol check
13(and ipv4 check in icmp case).
14
15This extends payload_gen_special_dependency() to consider this.
16With this patch:
17
18add rule $pf filter input meta l4proto icmpv6
19add rule $pf filter input meta l4proto icmpv6 icmpv6 type echo-request
20add rule $pf filter input icmpv6 type echo-request
21
22will work in all tables and all families.
23For inet/bridge/netdev, an ipv6 protocol dependency is added; this will
24not match ipv4 packets with ip->protocol == icmpv6, EXCEPT in the case
25of the ip family.
26
27Its still possible to match icmpv6-in-ipv4 in inet/bridge/netdev with an
28explicit dependency:
29
30add rule inet f i ip protocol ipv6-icmp meta l4proto ipv6-icmp icmpv6 type ...
31
32Implicit dependencies won't get removed at the moment, so
33 bridge ... icmp type echo-request
34will be shown as
35 ether type ip meta l4proto 1 icmp type echo-request
36
37Signed-off-by: Florian Westphal <fw@strlen.de>
38---
39Upstream-Status: Backport
40Signed-off-by: André Draszik <adraszik@tycoint.com>
41 src/payload.c | 27 +++++++++++++++++++++++----
42 1 file changed, 23 insertions(+), 4 deletions(-)
43
44diff --git a/src/payload.c b/src/payload.c
45index 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--
832.11.0
84