diff options
8 files changed, 874 insertions, 0 deletions
diff --git a/meta-networking/recipes-filter/nftables/files/0001-payload-explicit-network-ctx-assignment-for-icmp-icm.patch b/meta-networking/recipes-filter/nftables/files/0001-payload-explicit-network-ctx-assignment-for-icmp-icm.patch new file mode 100644 index 0000000000..86a3d53dfd --- /dev/null +++ b/meta-networking/recipes-filter/nftables/files/0001-payload-explicit-network-ctx-assignment-for-icmp-icm.patch | |||
| @@ -0,0 +1,323 @@ | |||
| 1 | From 0011985554e269e1cc8f8e5b41eb9dcd795ebe8c Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Arturo Borrero Gonzalez <arturo@debian.org> | ||
| 3 | Date: Wed, 25 Jan 2017 12:51:08 +0100 | ||
| 4 | Subject: [PATCH] payload: explicit network ctx assignment for icmp/icmp6 in | ||
| 5 | special families | ||
| 6 | |||
| 7 | In the inet, bridge and netdev families, we can add rules like these: | ||
| 8 | |||
| 9 | % nft add rule inet t c ip protocol icmp icmp type echo-request | ||
| 10 | % nft add rule inet t c ip6 nexthdr icmpv6 icmpv6 type echo-request | ||
| 11 | |||
| 12 | However, when we print the ruleset: | ||
| 13 | |||
| 14 | % nft list ruleset | ||
| 15 | table inet t { | ||
| 16 | chain c { | ||
| 17 | icmpv6 type echo-request | ||
| 18 | icmp type echo-request | ||
| 19 | } | ||
| 20 | } | ||
| 21 | |||
| 22 | These rules we obtain can't be added again: | ||
| 23 | |||
| 24 | % nft add rule inet t c icmp type echo-request | ||
| 25 | <cmdline>:1:19-27: Error: conflicting protocols specified: inet-service vs. icmp | ||
| 26 | add rule inet t c icmp type echo-request | ||
| 27 | ^^^^^^^^^ | ||
| 28 | |||
| 29 | % nft add rule inet t c icmpv6 type echo-request | ||
| 30 | <cmdline>:1:19-29: Error: conflicting protocols specified: inet-service vs. icmpv6 | ||
| 31 | add rule inet t c icmpv6 type echo-request | ||
| 32 | ^^^^^^^^^^^ | ||
| 33 | |||
| 34 | Since I wouldn't expect an IP packet carrying ICMPv6, or IPv6 packet | ||
| 35 | carrying ICMP, if the link layer is inet, the network layer protocol context | ||
| 36 | can be safely update to 'ip' or 'ip6'. | ||
| 37 | |||
| 38 | Moreover, nft currently generates a 'meta nfproto ipvX' depedency when | ||
| 39 | using icmp or icmp6 in the inet family, and similar in netdev and bridge | ||
| 40 | families. | ||
| 41 | |||
| 42 | While at it, a bit of code factorization is introduced. | ||
| 43 | |||
| 44 | Fixes: https://bugzilla.netfilter.org/show_bug.cgi?id=1073 | ||
| 45 | Signed-off-by: Arturo Borrero Gonzalez <arturo@debian.org> | ||
| 46 | Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | ||
| 47 | --- | ||
| 48 | Upstream-Status: Backport | ||
| 49 | Signed-off-by: André Draszik <adraszik@tycoint.com> | ||
| 50 | src/payload.c | 70 ++++++++++++++++--------------------- | ||
| 51 | tests/py/any/icmpX.t.netdev | 8 +++++ | ||
| 52 | tests/py/any/icmpX.t.netdev.payload | 36 +++++++++++++++++++ | ||
| 53 | tests/py/bridge/icmpX.t | 8 +++++ | ||
| 54 | tests/py/bridge/icmpX.t.payload | 36 +++++++++++++++++++ | ||
| 55 | tests/py/inet/icmpX.t | 8 +++++ | ||
| 56 | tests/py/inet/icmpX.t.payload | 36 +++++++++++++++++++ | ||
| 57 | 7 files changed, 162 insertions(+), 40 deletions(-) | ||
| 58 | create mode 100644 tests/py/any/icmpX.t.netdev | ||
| 59 | create mode 100644 tests/py/any/icmpX.t.netdev.payload | ||
| 60 | create mode 100644 tests/py/bridge/icmpX.t | ||
| 61 | create mode 100644 tests/py/bridge/icmpX.t.payload | ||
| 62 | create mode 100644 tests/py/inet/icmpX.t | ||
| 63 | create mode 100644 tests/py/inet/icmpX.t.payload | ||
| 64 | |||
| 65 | diff --git a/src/payload.c b/src/payload.c | ||
| 66 | index af533b2..74f8254 100644 | ||
| 67 | --- a/src/payload.c | ||
| 68 | +++ b/src/payload.c | ||
| 69 | @@ -223,6 +223,34 @@ static int payload_add_dependency(struct eval_ctx *ctx, | ||
| 70 | return 0; | ||
| 71 | } | ||
| 72 | |||
| 73 | +static const struct proto_desc * | ||
| 74 | +payload_gen_special_dependency(struct eval_ctx *ctx, const struct expr *expr) | ||
| 75 | +{ | ||
| 76 | + switch (expr->payload.base) { | ||
| 77 | + case PROTO_BASE_LL_HDR: | ||
| 78 | + switch (ctx->pctx.family) { | ||
| 79 | + case NFPROTO_INET: | ||
| 80 | + return &proto_inet; | ||
| 81 | + case NFPROTO_BRIDGE: | ||
| 82 | + return &proto_eth; | ||
| 83 | + case NFPROTO_NETDEV: | ||
| 84 | + return &proto_netdev; | ||
| 85 | + default: | ||
| 86 | + break; | ||
| 87 | + } | ||
| 88 | + break; | ||
| 89 | + case PROTO_BASE_TRANSPORT_HDR: | ||
| 90 | + if (expr->payload.desc == &proto_icmp) | ||
| 91 | + return &proto_ip; | ||
| 92 | + if (expr->payload.desc == &proto_icmp6) | ||
| 93 | + return &proto_ip6; | ||
| 94 | + return &proto_inet_service; | ||
| 95 | + default: | ||
| 96 | + break; | ||
| 97 | + } | ||
| 98 | + return NULL; | ||
| 99 | +} | ||
| 100 | + | ||
| 101 | /** | ||
| 102 | * payload_gen_dependency - generate match expression on payload dependency | ||
| 103 | * | ||
| 104 | @@ -276,46 +304,8 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr, | ||
| 105 | |||
| 106 | desc = ctx->pctx.protocol[expr->payload.base - 1].desc; | ||
| 107 | /* Special case for mixed IPv4/IPv6 and bridge tables */ | ||
| 108 | - if (desc == NULL) { | ||
| 109 | - switch (ctx->pctx.family) { | ||
| 110 | - case NFPROTO_INET: | ||
| 111 | - switch (expr->payload.base) { | ||
| 112 | - case PROTO_BASE_LL_HDR: | ||
| 113 | - desc = &proto_inet; | ||
| 114 | - break; | ||
| 115 | - case PROTO_BASE_TRANSPORT_HDR: | ||
| 116 | - desc = &proto_inet_service; | ||
| 117 | - break; | ||
| 118 | - default: | ||
| 119 | - break; | ||
| 120 | - } | ||
| 121 | - break; | ||
| 122 | - case NFPROTO_BRIDGE: | ||
| 123 | - switch (expr->payload.base) { | ||
| 124 | - case PROTO_BASE_LL_HDR: | ||
| 125 | - desc = &proto_eth; | ||
| 126 | - break; | ||
| 127 | - case PROTO_BASE_TRANSPORT_HDR: | ||
| 128 | - desc = &proto_inet_service; | ||
| 129 | - break; | ||
| 130 | - default: | ||
| 131 | - break; | ||
| 132 | - } | ||
| 133 | - break; | ||
| 134 | - case NFPROTO_NETDEV: | ||
| 135 | - switch (expr->payload.base) { | ||
| 136 | - case PROTO_BASE_LL_HDR: | ||
| 137 | - desc = &proto_netdev; | ||
| 138 | - break; | ||
| 139 | - case PROTO_BASE_TRANSPORT_HDR: | ||
| 140 | - desc = &proto_inet_service; | ||
| 141 | - break; | ||
| 142 | - default: | ||
| 143 | - break; | ||
| 144 | - } | ||
| 145 | - break; | ||
| 146 | - } | ||
| 147 | - } | ||
| 148 | + if (desc == NULL) | ||
| 149 | + desc = payload_gen_special_dependency(ctx, expr); | ||
| 150 | |||
| 151 | if (desc == NULL) | ||
| 152 | return expr_error(ctx->msgs, expr, | ||
| 153 | diff --git a/tests/py/any/icmpX.t.netdev b/tests/py/any/icmpX.t.netdev | ||
| 154 | new file mode 100644 | ||
| 155 | index 0000000..a327ce6 | ||
| 156 | --- /dev/null | ||
| 157 | +++ b/tests/py/any/icmpX.t.netdev | ||
| 158 | @@ -0,0 +1,8 @@ | ||
| 159 | +:ingress;type filter hook ingress device lo priority 0 | ||
| 160 | + | ||
| 161 | +*netdev;test-netdev;ingress | ||
| 162 | + | ||
| 163 | +ip protocol icmp icmp type echo-request;ok;icmp type echo-request | ||
| 164 | +icmp type echo-request;ok | ||
| 165 | +ip6 nexthdr icmpv6 icmpv6 type echo-request;ok;icmpv6 type echo-request | ||
| 166 | +icmpv6 type echo-request;ok | ||
| 167 | diff --git a/tests/py/any/icmpX.t.netdev.payload b/tests/py/any/icmpX.t.netdev.payload | ||
| 168 | new file mode 100644 | ||
| 169 | index 0000000..8b8107c | ||
| 170 | --- /dev/null | ||
| 171 | +++ b/tests/py/any/icmpX.t.netdev.payload | ||
| 172 | @@ -0,0 +1,36 @@ | ||
| 173 | +# ip protocol icmp icmp type echo-request | ||
| 174 | +netdev test-netdev ingress | ||
| 175 | + [ meta load protocol => reg 1 ] | ||
| 176 | + [ cmp eq reg 1 0x00000008 ] | ||
| 177 | + [ payload load 1b @ network header + 9 => reg 1 ] | ||
| 178 | + [ cmp eq reg 1 0x00000001 ] | ||
| 179 | + [ payload load 1b @ transport header + 0 => reg 1 ] | ||
| 180 | + [ cmp eq reg 1 0x00000008 ] | ||
| 181 | + | ||
| 182 | +# icmp type echo-request | ||
| 183 | +netdev test-netdev ingress | ||
| 184 | + [ meta load protocol => reg 1 ] | ||
| 185 | + [ cmp eq reg 1 0x00000008 ] | ||
| 186 | + [ payload load 1b @ network header + 9 => reg 1 ] | ||
| 187 | + [ cmp eq reg 1 0x00000001 ] | ||
| 188 | + [ payload load 1b @ transport header + 0 => reg 1 ] | ||
| 189 | + [ cmp eq reg 1 0x00000008 ] | ||
| 190 | + | ||
| 191 | +# ip6 nexthdr icmpv6 icmpv6 type echo-request | ||
| 192 | +netdev test-netdev ingress | ||
| 193 | + [ meta load protocol => reg 1 ] | ||
| 194 | + [ cmp eq reg 1 0x0000dd86 ] | ||
| 195 | + [ payload load 1b @ network header + 6 => reg 1 ] | ||
| 196 | + [ cmp eq reg 1 0x0000003a ] | ||
| 197 | + [ payload load 1b @ transport header + 0 => reg 1 ] | ||
| 198 | + [ cmp eq reg 1 0x00000080 ] | ||
| 199 | + | ||
| 200 | +# icmpv6 type echo-request | ||
| 201 | +netdev test-netdev ingress | ||
| 202 | + [ meta load protocol => reg 1 ] | ||
| 203 | + [ cmp eq reg 1 0x0000dd86 ] | ||
| 204 | + [ payload load 1b @ network header + 6 => reg 1 ] | ||
| 205 | + [ cmp eq reg 1 0x0000003a ] | ||
| 206 | + [ payload load 1b @ transport header + 0 => reg 1 ] | ||
| 207 | + [ cmp eq reg 1 0x00000080 ] | ||
| 208 | + | ||
| 209 | diff --git a/tests/py/bridge/icmpX.t b/tests/py/bridge/icmpX.t | ||
| 210 | new file mode 100644 | ||
| 211 | index 0000000..8c0a597 | ||
| 212 | --- /dev/null | ||
| 213 | +++ b/tests/py/bridge/icmpX.t | ||
| 214 | @@ -0,0 +1,8 @@ | ||
| 215 | +:input;type filter hook input priority 0 | ||
| 216 | + | ||
| 217 | +*bridge;test-bridge;input | ||
| 218 | + | ||
| 219 | +ip protocol icmp icmp type echo-request;ok;icmp type echo-request | ||
| 220 | +icmp type echo-request;ok | ||
| 221 | +ip6 nexthdr icmpv6 icmpv6 type echo-request;ok;icmpv6 type echo-request | ||
| 222 | +icmpv6 type echo-request;ok | ||
| 223 | diff --git a/tests/py/bridge/icmpX.t.payload b/tests/py/bridge/icmpX.t.payload | ||
| 224 | new file mode 100644 | ||
| 225 | index 0000000..19efdd8 | ||
| 226 | --- /dev/null | ||
| 227 | +++ b/tests/py/bridge/icmpX.t.payload | ||
| 228 | @@ -0,0 +1,36 @@ | ||
| 229 | +# ip protocol icmp icmp type echo-request | ||
| 230 | +bridge test-bridge input | ||
| 231 | + [ payload load 2b @ link header + 12 => reg 1 ] | ||
| 232 | + [ cmp eq reg 1 0x00000008 ] | ||
| 233 | + [ payload load 1b @ network header + 9 => reg 1 ] | ||
| 234 | + [ cmp eq reg 1 0x00000001 ] | ||
| 235 | + [ payload load 1b @ transport header + 0 => reg 1 ] | ||
| 236 | + [ cmp eq reg 1 0x00000008 ] | ||
| 237 | + | ||
| 238 | +# icmp type echo-request | ||
| 239 | +bridge test-bridge input | ||
| 240 | + [ payload load 2b @ link header + 12 => reg 1 ] | ||
| 241 | + [ cmp eq reg 1 0x00000008 ] | ||
| 242 | + [ payload load 1b @ network header + 9 => reg 1 ] | ||
| 243 | + [ cmp eq reg 1 0x00000001 ] | ||
| 244 | + [ payload load 1b @ transport header + 0 => reg 1 ] | ||
| 245 | + [ cmp eq reg 1 0x00000008 ] | ||
| 246 | + | ||
| 247 | +# ip6 nexthdr icmpv6 icmpv6 type echo-request | ||
| 248 | +bridge test-bridge input | ||
| 249 | + [ payload load 2b @ link header + 12 => reg 1 ] | ||
| 250 | + [ cmp eq reg 1 0x0000dd86 ] | ||
| 251 | + [ payload load 1b @ network header + 6 => reg 1 ] | ||
| 252 | + [ cmp eq reg 1 0x0000003a ] | ||
| 253 | + [ payload load 1b @ transport header + 0 => reg 1 ] | ||
| 254 | + [ cmp eq reg 1 0x00000080 ] | ||
| 255 | + | ||
| 256 | +# icmpv6 type echo-request | ||
| 257 | +bridge test-bridge input | ||
| 258 | + [ payload load 2b @ link header + 12 => reg 1 ] | ||
| 259 | + [ cmp eq reg 1 0x0000dd86 ] | ||
| 260 | + [ payload load 1b @ network header + 6 => reg 1 ] | ||
| 261 | + [ cmp eq reg 1 0x0000003a ] | ||
| 262 | + [ payload load 1b @ transport header + 0 => reg 1 ] | ||
| 263 | + [ cmp eq reg 1 0x00000080 ] | ||
| 264 | + | ||
| 265 | diff --git a/tests/py/inet/icmpX.t b/tests/py/inet/icmpX.t | ||
| 266 | new file mode 100644 | ||
| 267 | index 0000000..1b467a1 | ||
| 268 | --- /dev/null | ||
| 269 | +++ b/tests/py/inet/icmpX.t | ||
| 270 | @@ -0,0 +1,8 @@ | ||
| 271 | +:input;type filter hook input priority 0 | ||
| 272 | + | ||
| 273 | +*inet;test-inet;input | ||
| 274 | + | ||
| 275 | +ip protocol icmp icmp type echo-request;ok;icmp type echo-request | ||
| 276 | +icmp type echo-request;ok | ||
| 277 | +ip6 nexthdr icmpv6 icmpv6 type echo-request;ok;icmpv6 type echo-request | ||
| 278 | +icmpv6 type echo-request;ok | ||
| 279 | diff --git a/tests/py/inet/icmpX.t.payload b/tests/py/inet/icmpX.t.payload | ||
| 280 | new file mode 100644 | ||
| 281 | index 0000000..81ca774 | ||
| 282 | --- /dev/null | ||
| 283 | +++ b/tests/py/inet/icmpX.t.payload | ||
| 284 | @@ -0,0 +1,36 @@ | ||
| 285 | +# ip protocol icmp icmp type echo-request | ||
| 286 | +inet test-inet input | ||
| 287 | + [ meta load nfproto => reg 1 ] | ||
| 288 | + [ cmp eq reg 1 0x00000002 ] | ||
| 289 | + [ payload load 1b @ network header + 9 => reg 1 ] | ||
| 290 | + [ cmp eq reg 1 0x00000001 ] | ||
| 291 | + [ payload load 1b @ transport header + 0 => reg 1 ] | ||
| 292 | + [ cmp eq reg 1 0x00000008 ] | ||
| 293 | + | ||
| 294 | +# icmp type echo-request | ||
| 295 | +inet test-inet input | ||
| 296 | + [ meta load nfproto => reg 1 ] | ||
| 297 | + [ cmp eq reg 1 0x00000002 ] | ||
| 298 | + [ payload load 1b @ network header + 9 => reg 1 ] | ||
| 299 | + [ cmp eq reg 1 0x00000001 ] | ||
| 300 | + [ payload load 1b @ transport header + 0 => reg 1 ] | ||
| 301 | + [ cmp eq reg 1 0x00000008 ] | ||
| 302 | + | ||
| 303 | +# ip6 nexthdr icmpv6 icmpv6 type echo-request | ||
| 304 | +inet test-inet input | ||
| 305 | + [ meta load nfproto => reg 1 ] | ||
| 306 | + [ cmp eq reg 1 0x0000000a ] | ||
| 307 | + [ payload load 1b @ network header + 6 => reg 1 ] | ||
| 308 | + [ cmp eq reg 1 0x0000003a ] | ||
| 309 | + [ payload load 1b @ transport header + 0 => reg 1 ] | ||
| 310 | + [ cmp eq reg 1 0x00000080 ] | ||
| 311 | + | ||
| 312 | +# icmpv6 type echo-request | ||
| 313 | +inet test-inet input | ||
| 314 | + [ meta load nfproto => reg 1 ] | ||
| 315 | + [ cmp eq reg 1 0x0000000a ] | ||
| 316 | + [ payload load 1b @ network header + 6 => reg 1 ] | ||
| 317 | + [ cmp eq reg 1 0x0000003a ] | ||
| 318 | + [ payload load 1b @ transport header + 0 => reg 1 ] | ||
| 319 | + [ cmp eq reg 1 0x00000080 ] | ||
| 320 | + | ||
| 321 | -- | ||
| 322 | 2.11.0 | ||
| 323 | |||
diff --git a/meta-networking/recipes-filter/nftables/files/0002-proto-Add-some-exotic-ICMPv6-types.patch b/meta-networking/recipes-filter/nftables/files/0002-proto-Add-some-exotic-ICMPv6-types.patch new file mode 100644 index 0000000000..4d9e9d11a4 --- /dev/null +++ b/meta-networking/recipes-filter/nftables/files/0002-proto-Add-some-exotic-ICMPv6-types.patch | |||
| @@ -0,0 +1,147 @@ | |||
| 1 | From 9ade8fb75f8963375b45b3f2973b8bb7aa66ad76 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Phil Sutter <phil@nwl.cc> | ||
| 3 | Date: Thu, 16 Mar 2017 13:43:20 +0100 | ||
| 4 | Subject: [PATCH] proto: Add some exotic ICMPv6 types | ||
| 5 | |||
| 6 | This adds support for matching on inverse ND messages as defined by | ||
| 7 | RFC3122 (not implemented in Linux) and MLDv2 as defined by RFC3810. | ||
| 8 | |||
| 9 | Note that ICMPV6_MLD2_REPORT macro is defined in linux/icmpv6.h but | ||
| 10 | including that header leads to conflicts with symbols defined in | ||
| 11 | netinet/icmp6.h. | ||
| 12 | |||
| 13 | In addition to the above, "mld-listener-done" is introduced as an alias | ||
| 14 | for "mld-listener-reduction". | ||
| 15 | |||
| 16 | Signed-off-by: Phil Sutter <phil@nwl.cc> | ||
| 17 | Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | ||
| 18 | --- | ||
| 19 | Upstream-Status: Backport | ||
| 20 | Signed-off-by: André Draszik <adraszik@tycoint.com> | ||
| 21 | src/proto.c | 8 ++++++++ | ||
| 22 | tests/py/ip6/icmpv6.t | 8 ++++++-- | ||
| 23 | tests/py/ip6/icmpv6.t.payload.ip6 | 34 +++++++++++++++++++++++++++++++++- | ||
| 24 | 3 files changed, 47 insertions(+), 3 deletions(-) | ||
| 25 | |||
| 26 | diff --git a/src/proto.c b/src/proto.c | ||
| 27 | index fb96530..79e9dbf 100644 | ||
| 28 | --- a/src/proto.c | ||
| 29 | +++ b/src/proto.c | ||
| 30 | @@ -632,6 +632,10 @@ const struct proto_desc proto_ip = { | ||
| 31 | |||
| 32 | #include <netinet/icmp6.h> | ||
| 33 | |||
| 34 | +#define IND_NEIGHBOR_SOLICIT 141 | ||
| 35 | +#define IND_NEIGHBOR_ADVERT 142 | ||
| 36 | +#define ICMPV6_MLD2_REPORT 143 | ||
| 37 | + | ||
| 38 | static const struct symbol_table icmp6_type_tbl = { | ||
| 39 | .base = BASE_DECIMAL, | ||
| 40 | .symbols = { | ||
| 41 | @@ -643,6 +647,7 @@ static const struct symbol_table icmp6_type_tbl = { | ||
| 42 | SYMBOL("echo-reply", ICMP6_ECHO_REPLY), | ||
| 43 | SYMBOL("mld-listener-query", MLD_LISTENER_QUERY), | ||
| 44 | SYMBOL("mld-listener-report", MLD_LISTENER_REPORT), | ||
| 45 | + SYMBOL("mld-listener-done", MLD_LISTENER_REDUCTION), | ||
| 46 | SYMBOL("mld-listener-reduction", MLD_LISTENER_REDUCTION), | ||
| 47 | SYMBOL("nd-router-solicit", ND_ROUTER_SOLICIT), | ||
| 48 | SYMBOL("nd-router-advert", ND_ROUTER_ADVERT), | ||
| 49 | @@ -650,6 +655,9 @@ static const struct symbol_table icmp6_type_tbl = { | ||
| 50 | SYMBOL("nd-neighbor-advert", ND_NEIGHBOR_ADVERT), | ||
| 51 | SYMBOL("nd-redirect", ND_REDIRECT), | ||
| 52 | SYMBOL("router-renumbering", ICMP6_ROUTER_RENUMBERING), | ||
| 53 | + SYMBOL("ind-neighbor-solicit", IND_NEIGHBOR_SOLICIT), | ||
| 54 | + SYMBOL("ind-neighbor-advert", IND_NEIGHBOR_ADVERT), | ||
| 55 | + SYMBOL("mld2-listener-report", ICMPV6_MLD2_REPORT), | ||
| 56 | SYMBOL_LIST_END | ||
| 57 | }, | ||
| 58 | }; | ||
| 59 | diff --git a/tests/py/ip6/icmpv6.t b/tests/py/ip6/icmpv6.t | ||
| 60 | index afbd451..a898fe3 100644 | ||
| 61 | --- a/tests/py/ip6/icmpv6.t | ||
| 62 | +++ b/tests/py/ip6/icmpv6.t | ||
| 63 | @@ -11,7 +11,8 @@ icmpv6 type echo-request accept;ok | ||
| 64 | icmpv6 type echo-reply accept;ok | ||
| 65 | icmpv6 type mld-listener-query accept;ok | ||
| 66 | icmpv6 type mld-listener-report accept;ok | ||
| 67 | -icmpv6 type mld-listener-reduction accept;ok | ||
| 68 | +icmpv6 type mld-listener-done accept;ok | ||
| 69 | +icmpv6 type mld-listener-reduction accept;ok;icmpv6 type mld-listener-done accept | ||
| 70 | icmpv6 type nd-router-solicit accept;ok | ||
| 71 | icmpv6 type nd-router-advert accept;ok | ||
| 72 | icmpv6 type nd-neighbor-solicit accept;ok | ||
| 73 | @@ -19,8 +20,11 @@ icmpv6 type nd-neighbor-advert accept;ok | ||
| 74 | icmpv6 type nd-redirect accept;ok | ||
| 75 | icmpv6 type parameter-problem accept;ok | ||
| 76 | icmpv6 type router-renumbering accept;ok | ||
| 77 | +icmpv6 type ind-neighbor-solicit accept;ok | ||
| 78 | +icmpv6 type ind-neighbor-advert accept;ok | ||
| 79 | +icmpv6 type mld2-listener-report accept;ok | ||
| 80 | icmpv6 type {destination-unreachable, time-exceeded, nd-router-solicit} accept;ok | ||
| 81 | -icmpv6 type {router-renumbering, mld-listener-reduction, time-exceeded, nd-router-solicit} accept;ok | ||
| 82 | +icmpv6 type {router-renumbering, mld-listener-done, time-exceeded, nd-router-solicit} accept;ok | ||
| 83 | icmpv6 type {mld-listener-query, time-exceeded, nd-router-advert} accept;ok | ||
| 84 | icmpv6 type != {mld-listener-query, time-exceeded, nd-router-advert} accept;ok | ||
| 85 | |||
| 86 | diff --git a/tests/py/ip6/icmpv6.t.payload.ip6 b/tests/py/ip6/icmpv6.t.payload.ip6 | ||
| 87 | index 9fe2496..30f58ca 100644 | ||
| 88 | --- a/tests/py/ip6/icmpv6.t.payload.ip6 | ||
| 89 | +++ b/tests/py/ip6/icmpv6.t.payload.ip6 | ||
| 90 | @@ -54,6 +54,14 @@ ip6 test-ip6 input | ||
| 91 | [ cmp eq reg 1 0x00000083 ] | ||
| 92 | [ immediate reg 0 accept ] | ||
| 93 | |||
| 94 | +# icmpv6 type mld-listener-done accept | ||
| 95 | +ip6 test-ip6 input | ||
| 96 | + [ payload load 1b @ network header + 6 => reg 1 ] | ||
| 97 | + [ cmp eq reg 1 0x0000003a ] | ||
| 98 | + [ payload load 1b @ transport header + 0 => reg 1 ] | ||
| 99 | + [ cmp eq reg 1 0x00000084 ] | ||
| 100 | + [ immediate reg 0 accept ] | ||
| 101 | + | ||
| 102 | # icmpv6 type mld-listener-reduction accept | ||
| 103 | ip6 test-ip6 input | ||
| 104 | [ payload load 1b @ network header + 6 => reg 1 ] | ||
| 105 | @@ -118,6 +126,30 @@ ip6 test-ip6 input | ||
| 106 | [ cmp eq reg 1 0x0000008a ] | ||
| 107 | [ immediate reg 0 accept ] | ||
| 108 | |||
| 109 | +# icmpv6 type ind-neighbor-solicit accept | ||
| 110 | +ip6 test-ip6 input | ||
| 111 | + [ payload load 1b @ network header + 6 => reg 1 ] | ||
| 112 | + [ cmp eq reg 1 0x0000003a ] | ||
| 113 | + [ payload load 1b @ transport header + 0 => reg 1 ] | ||
| 114 | + [ cmp eq reg 1 0x0000008d ] | ||
| 115 | + [ immediate reg 0 accept ] | ||
| 116 | + | ||
| 117 | +# icmpv6 type ind-neighbor-advert accept | ||
| 118 | +ip6 test-ip6 input | ||
| 119 | + [ payload load 1b @ network header + 6 => reg 1 ] | ||
| 120 | + [ cmp eq reg 1 0x0000003a ] | ||
| 121 | + [ payload load 1b @ transport header + 0 => reg 1 ] | ||
| 122 | + [ cmp eq reg 1 0x0000008e ] | ||
| 123 | + [ immediate reg 0 accept ] | ||
| 124 | + | ||
| 125 | +# icmpv6 type mld2-listener-report accept | ||
| 126 | +ip6 test-ip6 input | ||
| 127 | + [ payload load 1b @ network header + 6 => reg 1 ] | ||
| 128 | + [ cmp eq reg 1 0x0000003a ] | ||
| 129 | + [ payload load 1b @ transport header + 0 => reg 1 ] | ||
| 130 | + [ cmp eq reg 1 0x0000008f ] | ||
| 131 | + [ immediate reg 0 accept ] | ||
| 132 | + | ||
| 133 | # icmpv6 type {destination-unreachable, time-exceeded, nd-router-solicit} accept | ||
| 134 | __set%d test-ip6 3 | ||
| 135 | __set%d test-ip6 0 | ||
| 136 | @@ -129,7 +161,7 @@ ip6 test-ip6 input | ||
| 137 | [ lookup reg 1 set __set%d ] | ||
| 138 | [ immediate reg 0 accept ] | ||
| 139 | |||
| 140 | -# icmpv6 type {router-renumbering, mld-listener-reduction, time-exceeded, nd-router-solicit} accept | ||
| 141 | +# icmpv6 type {router-renumbering, mld-listener-done, time-exceeded, nd-router-solicit} accept | ||
| 142 | __set%d test-ip6 3 | ||
| 143 | __set%d test-ip6 0 | ||
| 144 | element 0000008a : 0 [end] element 00000084 : 0 [end] element 00000003 : 0 [end] element 00000085 : 0 [end] | ||
| 145 | -- | ||
| 146 | 2.11.0 | ||
| 147 | |||
diff --git a/meta-networking/recipes-filter/nftables/files/0003-payload-split-ll-proto-dependency-into-helper.patch b/meta-networking/recipes-filter/nftables/files/0003-payload-split-ll-proto-dependency-into-helper.patch new file mode 100644 index 0000000000..50cac300e8 --- /dev/null +++ b/meta-networking/recipes-filter/nftables/files/0003-payload-split-ll-proto-dependency-into-helper.patch | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | From 8d8cfe5ad6ca460a5262fb15fdbef3601058c784 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 1/4] payload: split ll proto dependency into helper | ||
| 5 | |||
| 6 | will be re-used in folloup patch for icmp/icmpv6 depenency | ||
| 7 | handling. | ||
| 8 | |||
| 9 | Signed-off-by: Florian Westphal <fw@strlen.de> | ||
| 10 | --- | ||
| 11 | Upstream-Status: Backport | ||
| 12 | Signed-off-by: André Draszik <adraszik@tycoint.com> | ||
| 13 | src/payload.c | 29 ++++++++++++++++++----------- | ||
| 14 | 1 file changed, 18 insertions(+), 11 deletions(-) | ||
| 15 | |||
| 16 | diff --git a/src/payload.c b/src/payload.c | ||
| 17 | index 55128fe..31e5a02 100644 | ||
| 18 | --- a/src/payload.c | ||
| 19 | +++ b/src/payload.c | ||
| 20 | @@ -224,21 +224,28 @@ static int payload_add_dependency(struct eval_ctx *ctx, | ||
| 21 | } | ||
| 22 | |||
| 23 | static const struct proto_desc * | ||
| 24 | +payload_get_get_ll_hdr(const struct eval_ctx *ctx) | ||
| 25 | +{ | ||
| 26 | + switch (ctx->pctx.family) { | ||
| 27 | + case NFPROTO_INET: | ||
| 28 | + return &proto_inet; | ||
| 29 | + case NFPROTO_BRIDGE: | ||
| 30 | + return &proto_eth; | ||
| 31 | + case NFPROTO_NETDEV: | ||
| 32 | + return &proto_netdev; | ||
| 33 | + default: | ||
| 34 | + break; | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + return NULL; | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +static const struct proto_desc * | ||
| 41 | payload_gen_special_dependency(struct eval_ctx *ctx, const struct expr *expr) | ||
| 42 | { | ||
| 43 | switch (expr->payload.base) { | ||
| 44 | case PROTO_BASE_LL_HDR: | ||
| 45 | - switch (ctx->pctx.family) { | ||
| 46 | - case NFPROTO_INET: | ||
| 47 | - return &proto_inet; | ||
| 48 | - case NFPROTO_BRIDGE: | ||
| 49 | - return &proto_eth; | ||
| 50 | - case NFPROTO_NETDEV: | ||
| 51 | - return &proto_netdev; | ||
| 52 | - default: | ||
| 53 | - break; | ||
| 54 | - } | ||
| 55 | - break; | ||
| 56 | + return payload_get_get_ll_hdr(ctx); | ||
| 57 | case PROTO_BASE_TRANSPORT_HDR: | ||
| 58 | if (expr->payload.desc == &proto_icmp) | ||
| 59 | return &proto_ip; | ||
| 60 | -- | ||
| 61 | 2.11.0 | ||
| 62 | |||
diff --git a/meta-networking/recipes-filter/nftables/files/0004-src-allow-update-of-net-base-w.-meta-l4proto-icmpv6.patch b/meta-networking/recipes-filter/nftables/files/0004-src-allow-update-of-net-base-w.-meta-l4proto-icmpv6.patch new file mode 100644 index 0000000000..180edb3504 --- /dev/null +++ b/meta-networking/recipes-filter/nftables/files/0004-src-allow-update-of-net-base-w.-meta-l4proto-icmpv6.patch | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | From 9a1f2bbf3cd2417e0c10d18578e224abe2071d68 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Florian Westphal <fw@strlen.de> | ||
| 3 | Date: Tue, 21 Mar 2017 19:47:22 +0100 | ||
| 4 | Subject: [PATCH 2/4] src: allow update of net base w. meta l4proto icmpv6 | ||
| 5 | |||
| 6 | nft add rule ip6 f i meta l4proto ipv6-icmp icmpv6 type nd-router-advert | ||
| 7 | <cmdline>:1:50-60: Error: conflicting protocols specified: unknown vs. icmpv6 | ||
| 8 | |||
| 9 | add icmpv6 to nexthdr list so base gets updated correctly. | ||
| 10 | |||
| 11 | Reported-by: Thomas Woerner <twoerner@redhat.com> | ||
| 12 | Signed-off-by: Florian Westphal <fw@strlen.de> | ||
| 13 | --- | ||
| 14 | Upstream-Status: Backport | ||
| 15 | Signed-off-by: André Draszik <adraszik@tycoint.com> | ||
| 16 | src/proto.c | 1 + | ||
| 17 | tests/py/any/meta.t | 1 + | ||
| 18 | tests/py/any/meta.t.payload | 7 +++++++ | ||
| 19 | 3 files changed, 9 insertions(+) | ||
| 20 | |||
| 21 | diff --git a/src/proto.c b/src/proto.c | ||
| 22 | index 79e9dbf..fcdfbe7 100644 | ||
| 23 | --- a/src/proto.c | ||
| 24 | +++ b/src/proto.c | ||
| 25 | @@ -779,6 +779,7 @@ const struct proto_desc proto_inet_service = { | ||
| 26 | PROTO_LINK(IPPROTO_TCP, &proto_tcp), | ||
| 27 | PROTO_LINK(IPPROTO_DCCP, &proto_dccp), | ||
| 28 | PROTO_LINK(IPPROTO_SCTP, &proto_sctp), | ||
| 29 | + PROTO_LINK(IPPROTO_ICMPV6, &proto_icmp6), | ||
| 30 | }, | ||
| 31 | .templates = { | ||
| 32 | [0] = PROTO_META_TEMPLATE("l4proto", &inet_protocol_type, NFT_META_L4PROTO, 8), | ||
| 33 | diff --git a/tests/py/any/meta.t b/tests/py/any/meta.t | ||
| 34 | index c3ac0a4..2ff942f 100644 | ||
| 35 | --- a/tests/py/any/meta.t | ||
| 36 | +++ b/tests/py/any/meta.t | ||
| 37 | @@ -38,6 +38,7 @@ meta l4proto { 33, 55, 67, 88};ok;meta l4proto { 33, 55, 67, 88} | ||
| 38 | meta l4proto != { 33, 55, 67, 88};ok | ||
| 39 | meta l4proto { 33-55};ok | ||
| 40 | meta l4proto != { 33-55};ok | ||
| 41 | +meta l4proto ipv6-icmp icmpv6 type nd-router-advert;ok;icmpv6 type nd-router-advert | ||
| 42 | |||
| 43 | meta priority root;ok | ||
| 44 | meta priority none;ok | ||
| 45 | diff --git a/tests/py/any/meta.t.payload b/tests/py/any/meta.t.payload | ||
| 46 | index e432656..871f1ad 100644 | ||
| 47 | --- a/tests/py/any/meta.t.payload | ||
| 48 | +++ b/tests/py/any/meta.t.payload | ||
| 49 | @@ -187,6 +187,13 @@ ip test-ip4 input | ||
| 50 | [ byteorder reg 1 = hton(reg 1, 2, 1) ] | ||
| 51 | [ lookup reg 1 set __set%d 0x1 ] | ||
| 52 | |||
| 53 | +# meta l4proto ipv6-icmp icmpv6 type nd-router-advert | ||
| 54 | +ip test-ip4 input | ||
| 55 | + [ meta load l4proto => reg 1 ] | ||
| 56 | + [ cmp eq reg 1 0x0000003a ] | ||
| 57 | + [ payload load 1b @ transport header + 0 => reg 1 ] | ||
| 58 | + [ cmp eq reg 1 0x00000086 ] | ||
| 59 | + | ||
| 60 | # meta mark 0x4 | ||
| 61 | ip test-ip4 input | ||
| 62 | [ meta load mark => reg 1 ] | ||
| 63 | -- | ||
| 64 | 2.11.0 | ||
| 65 | |||
diff --git a/meta-networking/recipes-filter/nftables/files/0005-src-ipv6-switch-implicit-dependencies-to-meta-l4prot.patch b/meta-networking/recipes-filter/nftables/files/0005-src-ipv6-switch-implicit-dependencies-to-meta-l4prot.patch new file mode 100644 index 0000000000..f600ae05c0 --- /dev/null +++ b/meta-networking/recipes-filter/nftables/files/0005-src-ipv6-switch-implicit-dependencies-to-meta-l4prot.patch | |||
| @@ -0,0 +1,98 @@ | |||
| 1 | From 2366ed9ffcb4f5f5341f10f0a1d1a4688d37ad87 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Florian Westphal <fw@strlen.de> | ||
| 3 | Date: Wed, 22 Mar 2017 15:08:48 +0100 | ||
| 4 | Subject: [PATCH 3/4] src: ipv6: switch implicit dependencies to meta l4proto | ||
| 5 | |||
| 6 | when using rule like | ||
| 7 | |||
| 8 | ip6 filter input tcp dport 22 | ||
| 9 | nft generates: | ||
| 10 | [ payload load 1b @ network header + 6 => reg 1 ] | ||
| 11 | [ cmp eq reg 1 0x00000006 ] | ||
| 12 | [ payload load 2b @ transport header + 2 => reg 1 ] | ||
| 13 | [ cmp eq reg 1 0x00001600 ] | ||
| 14 | |||
| 15 | which is: ip6 filter input ip6 nexthdr tcp dport 22 | ||
| 16 | IOW, such a rule won't match if e.g. a fragment header is in place. | ||
| 17 | |||
| 18 | This changes ip6_proto to use 'meta l4proto' which is the protocol header | ||
| 19 | found by exthdr walk. | ||
| 20 | |||
| 21 | A side effect is that for bridge we get a shorter dependency chain as it | ||
| 22 | no longer needs to prepend 'ether proto ipv6' for old 'ip6 nexthdr' dep. | ||
| 23 | |||
| 24 | Only problem: | ||
| 25 | |||
| 26 | ip6 nexthdr tcp tcp dport 22 | ||
| 27 | will now inject a (useless) meta l4 dependency as ip6 nexthdr is no | ||
| 28 | longer flagged as EXPR_F_PROTOCOL, to avoid this add a small helper | ||
| 29 | that skips the unneded meta dependency in that case. | ||
| 30 | |||
| 31 | Signed-off-by: Florian Westphal <fw@strlen.de> | ||
| 32 | --- | ||
| 33 | Upstream-Status: Backport | ||
| 34 | Signed-off-by: André Draszik <adraszik@tycoint.com> | ||
| 35 | src/payload.c | 19 ++++++++++++++++++- | ||
| 36 | src/proto.c | 2 +- | ||
| 37 | 2 files changed, 19 insertions(+), 2 deletions(-) | ||
| 38 | |||
| 39 | diff --git a/src/payload.c b/src/payload.c | ||
| 40 | index 31e5a02..38db15e 100644 | ||
| 41 | --- a/src/payload.c | ||
| 42 | +++ b/src/payload.c | ||
| 43 | @@ -117,6 +117,23 @@ static const struct expr_ops payload_expr_ops = { | ||
| 44 | .pctx_update = payload_expr_pctx_update, | ||
| 45 | }; | ||
| 46 | |||
| 47 | +/* | ||
| 48 | + * ipv6 is special case, we normally use 'meta l4proto' to fetch the last | ||
| 49 | + * l4 header of the ipv6 extension header chain so we will also match | ||
| 50 | + * tcp after a fragmentation header, for instance. | ||
| 51 | + * | ||
| 52 | + * If user specifically asks for nexthdr x, treat is as a full | ||
| 53 | + * dependency rather than injecting another (useless) meta l4 one. | ||
| 54 | + */ | ||
| 55 | +static bool proto_key_is_protocol(const struct proto_desc *desc, unsigned int type) | ||
| 56 | +{ | ||
| 57 | + if (type == desc->protocol_key || | ||
| 58 | + (desc == &proto_ip6 && type == IP6HDR_NEXTHDR)) | ||
| 59 | + return true; | ||
| 60 | + | ||
| 61 | + return false; | ||
| 62 | +} | ||
| 63 | + | ||
| 64 | struct expr *payload_expr_alloc(const struct location *loc, | ||
| 65 | const struct proto_desc *desc, | ||
| 66 | unsigned int type) | ||
| 67 | @@ -129,7 +146,7 @@ struct expr *payload_expr_alloc(const struct location *loc, | ||
| 68 | if (desc != NULL) { | ||
| 69 | tmpl = &desc->templates[type]; | ||
| 70 | base = desc->base; | ||
| 71 | - if (type == desc->protocol_key) | ||
| 72 | + if (proto_key_is_protocol(desc, type)) | ||
| 73 | flags = EXPR_F_PROTOCOL; | ||
| 74 | } else { | ||
| 75 | tmpl = &proto_unknown_template; | ||
| 76 | diff --git a/src/proto.c b/src/proto.c | ||
| 77 | index fcdfbe7..3b20a5f 100644 | ||
| 78 | --- a/src/proto.c | ||
| 79 | +++ b/src/proto.c | ||
| 80 | @@ -707,7 +707,6 @@ const struct proto_desc proto_icmp6 = { | ||
| 81 | const struct proto_desc proto_ip6 = { | ||
| 82 | .name = "ip6", | ||
| 83 | .base = PROTO_BASE_NETWORK_HDR, | ||
| 84 | - .protocol_key = IP6HDR_NEXTHDR, | ||
| 85 | .protocols = { | ||
| 86 | PROTO_LINK(IPPROTO_ESP, &proto_esp), | ||
| 87 | PROTO_LINK(IPPROTO_AH, &proto_ah), | ||
| 88 | @@ -720,6 +719,7 @@ const struct proto_desc proto_ip6 = { | ||
| 89 | PROTO_LINK(IPPROTO_ICMPV6, &proto_icmp6), | ||
| 90 | }, | ||
| 91 | .templates = { | ||
| 92 | + [0] = PROTO_META_TEMPLATE("l4proto", &inet_protocol_type, NFT_META_L4PROTO, 8), | ||
| 93 | [IP6HDR_VERSION] = HDR_BITFIELD("version", &integer_type, 0, 4), | ||
| 94 | [IP6HDR_DSCP] = HDR_BITFIELD("dscp", &dscp_type, 4, 6), | ||
| 95 | [IP6HDR_ECN] = HDR_BITFIELD("ecn", &ecn_type, 10, 2), | ||
| 96 | -- | ||
| 97 | 2.11.0 | ||
| 98 | |||
diff --git a/meta-networking/recipes-filter/nftables/files/0006-payload-enforce-ip-ip6-protocol-depending-on-icmp-or.patch b/meta-networking/recipes-filter/nftables/files/0006-payload-enforce-ip-ip6-protocol-depending-on-icmp-or.patch new file mode 100644 index 0000000000..00076d7cef --- /dev/null +++ b/meta-networking/recipes-filter/nftables/files/0006-payload-enforce-ip-ip6-protocol-depending-on-icmp-or.patch | |||
| @@ -0,0 +1,84 @@ | |||
| 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 | |||
diff --git a/meta-networking/recipes-filter/nftables/files/0007-src-ip-switch-implicit-dependencies-to-meta-l4proto-.patch b/meta-networking/recipes-filter/nftables/files/0007-src-ip-switch-implicit-dependencies-to-meta-l4proto-.patch new file mode 100644 index 0000000000..5b72437d27 --- /dev/null +++ b/meta-networking/recipes-filter/nftables/files/0007-src-ip-switch-implicit-dependencies-to-meta-l4proto-.patch | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | From 0825c57d571bb7121e7048e198b9b023f7e7f358 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Florian Westphal <fw@strlen.de> | ||
| 3 | Date: Sun, 7 May 2017 03:53:30 +0200 | ||
| 4 | Subject: [PATCH] src: ip: switch implicit dependencies to meta l4proto too | ||
| 5 | |||
| 6 | after ip6 nexthdr also switch ip to meta l4proto instead of ip protocol. | ||
| 7 | |||
| 8 | While its needed for ipv6 (due to extension headers) this isn't needed | ||
| 9 | for ip but it has the advantage that | ||
| 10 | |||
| 11 | tcp dport 22 | ||
| 12 | |||
| 13 | produces same expressions for ip/ip6/inet families. | ||
| 14 | |||
| 15 | Signed-off-by: Florian Westphal <fw@strlen.de> | ||
| 16 | --- | ||
| 17 | Upstream-Status: Backport | ||
| 18 | Signed-off-by: André Draszik <adraszik@tycoint.com> | ||
| 19 | src/payload.c | 17 +++++++++++------ | ||
| 20 | src/proto.c | 3 ++- | ||
| 21 | 2 files changed, 13 insertions(+), 7 deletions(-) | ||
| 22 | |||
| 23 | diff --git a/src/payload.c b/src/payload.c | ||
| 24 | index 8796ee5..11b6df3 100644 | ||
| 25 | --- a/src/payload.c | ||
| 26 | +++ b/src/payload.c | ||
| 27 | @@ -118,17 +118,22 @@ static const struct expr_ops payload_expr_ops = { | ||
| 28 | }; | ||
| 29 | |||
| 30 | /* | ||
| 31 | - * ipv6 is special case, we normally use 'meta l4proto' to fetch the last | ||
| 32 | - * l4 header of the ipv6 extension header chain so we will also match | ||
| 33 | + * We normally use 'meta l4proto' to fetch the last l4 header of the | ||
| 34 | + * ipv6 extension header chain so we will also match | ||
| 35 | * tcp after a fragmentation header, for instance. | ||
| 36 | + * For consistency we also use meta l4proto for ipv4. | ||
| 37 | * | ||
| 38 | - * If user specifically asks for nexthdr x, treat is as a full | ||
| 39 | - * dependency rather than injecting another (useless) meta l4 one. | ||
| 40 | + * If user specifically asks for nexthdr x, don't add another (useless) | ||
| 41 | + * meta dependency. | ||
| 42 | */ | ||
| 43 | static bool proto_key_is_protocol(const struct proto_desc *desc, unsigned int type) | ||
| 44 | { | ||
| 45 | - if (type == desc->protocol_key || | ||
| 46 | - (desc == &proto_ip6 && type == IP6HDR_NEXTHDR)) | ||
| 47 | + if (type == desc->protocol_key) | ||
| 48 | + return true; | ||
| 49 | + | ||
| 50 | + if (desc == &proto_ip6 && type == IP6HDR_NEXTHDR) | ||
| 51 | + return true; | ||
| 52 | + if (desc == &proto_ip && type == IPHDR_PROTOCOL) | ||
| 53 | return true; | ||
| 54 | |||
| 55 | return false; | ||
| 56 | diff --git a/src/proto.c b/src/proto.c | ||
| 57 | index 3b20a5f..2afedf7 100644 | ||
| 58 | --- a/src/proto.c | ||
| 59 | +++ b/src/proto.c | ||
| 60 | @@ -587,7 +587,6 @@ const struct proto_desc proto_ip = { | ||
| 61 | .name = "ip", | ||
| 62 | .base = PROTO_BASE_NETWORK_HDR, | ||
| 63 | .checksum_key = IPHDR_CHECKSUM, | ||
| 64 | - .protocol_key = IPHDR_PROTOCOL, | ||
| 65 | .protocols = { | ||
| 66 | PROTO_LINK(IPPROTO_ICMP, &proto_icmp), | ||
| 67 | PROTO_LINK(IPPROTO_ESP, &proto_esp), | ||
| 68 | @@ -600,6 +599,7 @@ const struct proto_desc proto_ip = { | ||
| 69 | PROTO_LINK(IPPROTO_SCTP, &proto_sctp), | ||
| 70 | }, | ||
| 71 | .templates = { | ||
| 72 | + [0] = PROTO_META_TEMPLATE("l4proto", &inet_protocol_type, NFT_META_L4PROTO, 8), | ||
| 73 | [IPHDR_VERSION] = HDR_BITFIELD("version", &integer_type, 0, 4), | ||
| 74 | [IPHDR_HDRLENGTH] = HDR_BITFIELD("hdrlength", &integer_type, 4, 4), | ||
| 75 | [IPHDR_DSCP] = HDR_BITFIELD("dscp", &dscp_type, 8, 6), | ||
| 76 | @@ -779,6 +779,7 @@ const struct proto_desc proto_inet_service = { | ||
| 77 | PROTO_LINK(IPPROTO_TCP, &proto_tcp), | ||
| 78 | PROTO_LINK(IPPROTO_DCCP, &proto_dccp), | ||
| 79 | PROTO_LINK(IPPROTO_SCTP, &proto_sctp), | ||
| 80 | + PROTO_LINK(IPPROTO_ICMP, &proto_icmp), | ||
| 81 | PROTO_LINK(IPPROTO_ICMPV6, &proto_icmp6), | ||
| 82 | }, | ||
| 83 | .templates = { | ||
| 84 | -- | ||
| 85 | 2.11.0 | ||
| 86 | |||
diff --git a/meta-networking/recipes-filter/nftables/nftables_0.7.bb b/meta-networking/recipes-filter/nftables/nftables_0.7.bb index 3a3a946653..0ea79953be 100644 --- a/meta-networking/recipes-filter/nftables/nftables_0.7.bb +++ b/meta-networking/recipes-filter/nftables/nftables_0.7.bb | |||
| @@ -9,6 +9,15 @@ RRECOMMENDS_${PN} += "kernel-module-nf-tables \ | |||
| 9 | 9 | ||
| 10 | SRC_URI = "http://www.netfilter.org/projects/nftables/files/${BP}.tar.bz2 \ | 10 | SRC_URI = "http://www.netfilter.org/projects/nftables/files/${BP}.tar.bz2 \ |
| 11 | file://fix-to-generate-ntf.8.patch \ | 11 | file://fix-to-generate-ntf.8.patch \ |
| 12 | \ | ||
| 13 | file://0001-payload-explicit-network-ctx-assignment-for-icmp-icm.patch \ | ||
| 14 | file://0002-proto-Add-some-exotic-ICMPv6-types.patch \ | ||
| 15 | \ | ||
| 16 | file://0003-payload-split-ll-proto-dependency-into-helper.patch \ | ||
| 17 | file://0004-src-allow-update-of-net-base-w.-meta-l4proto-icmpv6.patch \ | ||
| 18 | file://0005-src-ipv6-switch-implicit-dependencies-to-meta-l4prot.patch \ | ||
| 19 | file://0006-payload-enforce-ip-ip6-protocol-depending-on-icmp-or.patch \ | ||
| 20 | file://0007-src-ip-switch-implicit-dependencies-to-meta-l4proto-.patch \ | ||
| 12 | " | 21 | " |
| 13 | SRC_URI[md5sum] = "4c005e76a15a029afaba71d7db21d065" | 22 | SRC_URI[md5sum] = "4c005e76a15a029afaba71d7db21d065" |
| 14 | SRC_URI[sha256sum] = "fe639239d801ce5890397f6f4391c58a934bfc27d8b7d5ef922692de5ec4ed43" | 23 | SRC_URI[sha256sum] = "fe639239d801ce5890397f6f4391c58a934bfc27d8b7d5ef922692de5ec4ed43" |
