Skip to content

Commit abe2fec

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next
Pablo Neira Ayuso says: ==================== Netfilter updates for net-next 1) Revert CHECKSUM_UNNECESSARY for UDP packet from conntrack. 2) Reject unsupported families when creating tables, from Phil Sutter. 3) GRE support for the flowtable, from Toshiaki Makita. 4) Add GRE offload support for act_ct, also from Toshiaki. 5) Update mlx5 driver to support for GRE flowtable offload, from Toshiaki Makita. 6) Oneliner to clean up incorrect indentation in nf_conntrack_bridge, from Jiapeng Chong. * git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next: netfilter: bridge: clean up some inconsistent indenting net/mlx5: Support GRE conntrack offload act_ct: Support GRE offload netfilter: flowtable: Support GRE netfilter: nf_tables: Reject tables of unsupported family Revert "netfilter: conntrack: mark UDP zero checksum as CHECKSUM_UNNECESSARY" ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 72f56fd + 334ff12 commit abe2fec

File tree

9 files changed

+223
-53
lines changed

9 files changed

+223
-53
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,8 @@ mlx5_tc_ct_rule_to_tuple(struct mlx5_ct_tuple *tuple, struct flow_rule *rule)
260260
return -EOPNOTSUPP;
261261
}
262262
} else {
263-
return -EOPNOTSUPP;
263+
if (tuple->ip_proto != IPPROTO_GRE)
264+
return -EOPNOTSUPP;
264265
}
265266

266267
return 0;
@@ -809,7 +810,11 @@ mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv,
809810
attr->dest_chain = 0;
810811
attr->dest_ft = mlx5e_tc_post_act_get_ft(ct_priv->post_act);
811812
attr->ft = nat ? ct_priv->ct_nat : ct_priv->ct;
812-
attr->outer_match_level = MLX5_MATCH_L4;
813+
if (entry->tuple.ip_proto == IPPROTO_TCP ||
814+
entry->tuple.ip_proto == IPPROTO_UDP)
815+
attr->outer_match_level = MLX5_MATCH_L4;
816+
else
817+
attr->outer_match_level = MLX5_MATCH_L3;
813818
attr->counter = entry->counter->counter;
814819
attr->flags |= MLX5_ATTR_FLAG_NO_IN_PORT;
815820
if (ct_priv->ns_type == MLX5_FLOW_NAMESPACE_FDB)
@@ -1226,16 +1231,20 @@ mlx5_tc_ct_skb_to_tuple(struct sk_buff *skb, struct mlx5_ct_tuple *tuple,
12261231
struct flow_keys flow_keys;
12271232

12281233
skb_reset_network_header(skb);
1229-
skb_flow_dissect_flow_keys(skb, &flow_keys, 0);
1234+
skb_flow_dissect_flow_keys(skb, &flow_keys, FLOW_DISSECTOR_F_STOP_BEFORE_ENCAP);
12301235

12311236
tuple->zone = zone;
12321237

12331238
if (flow_keys.basic.ip_proto != IPPROTO_TCP &&
1234-
flow_keys.basic.ip_proto != IPPROTO_UDP)
1239+
flow_keys.basic.ip_proto != IPPROTO_UDP &&
1240+
flow_keys.basic.ip_proto != IPPROTO_GRE)
12351241
return false;
12361242

1237-
tuple->port.src = flow_keys.ports.src;
1238-
tuple->port.dst = flow_keys.ports.dst;
1243+
if (flow_keys.basic.ip_proto == IPPROTO_TCP ||
1244+
flow_keys.basic.ip_proto == IPPROTO_UDP) {
1245+
tuple->port.src = flow_keys.ports.src;
1246+
tuple->port.dst = flow_keys.ports.dst;
1247+
}
12391248
tuple->n_proto = flow_keys.basic.n_proto;
12401249
tuple->ip_proto = flow_keys.basic.ip_proto;
12411250

net/bridge/netfilter/nf_conntrack_bridge.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ static unsigned int nf_ct_bridge_confirm(struct sk_buff *skb)
381381
protoff = skb_network_offset(skb) + ip_hdrlen(skb);
382382
break;
383383
case htons(ETH_P_IPV6): {
384-
unsigned char pnum = ipv6_hdr(skb)->nexthdr;
384+
unsigned char pnum = ipv6_hdr(skb)->nexthdr;
385385
__be16 frag_off;
386386

387387
protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &pnum,

net/netfilter/nf_conntrack_proto_udp.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,8 @@ static bool udp_error(struct sk_buff *skb,
6363
}
6464

6565
/* Packet with no checksum */
66-
if (!hdr->check) {
67-
skb->ip_summed = CHECKSUM_UNNECESSARY;
66+
if (!hdr->check)
6867
return false;
69-
}
7068

7169
/* Checksum invalid? Ignore.
7270
* We skip checking packets on the outgoing path

net/netfilter/nf_flow_table_core.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,14 @@ flow_offload_fill_dir(struct flow_offload *flow,
3939

4040
ft->l3proto = ctt->src.l3num;
4141
ft->l4proto = ctt->dst.protonum;
42-
ft->src_port = ctt->src.u.tcp.port;
43-
ft->dst_port = ctt->dst.u.tcp.port;
42+
43+
switch (ctt->dst.protonum) {
44+
case IPPROTO_TCP:
45+
case IPPROTO_UDP:
46+
ft->src_port = ctt->src.u.tcp.port;
47+
ft->dst_port = ctt->dst.u.tcp.port;
48+
break;
49+
}
4450
}
4551

4652
struct flow_offload *flow_offload_alloc(struct nf_conn *ct)

net/netfilter/nf_flow_table_ip.c

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ static int nf_flow_tuple_ip(struct sk_buff *skb, const struct net_device *dev,
172172
struct flow_ports *ports;
173173
unsigned int thoff;
174174
struct iphdr *iph;
175+
u8 ipproto;
175176

176177
if (!pskb_may_pull(skb, sizeof(*iph) + offset))
177178
return -1;
@@ -185,13 +186,19 @@ static int nf_flow_tuple_ip(struct sk_buff *skb, const struct net_device *dev,
185186

186187
thoff += offset;
187188

188-
switch (iph->protocol) {
189+
ipproto = iph->protocol;
190+
switch (ipproto) {
189191
case IPPROTO_TCP:
190192
*hdrsize = sizeof(struct tcphdr);
191193
break;
192194
case IPPROTO_UDP:
193195
*hdrsize = sizeof(struct udphdr);
194196
break;
197+
#ifdef CONFIG_NF_CT_PROTO_GRE
198+
case IPPROTO_GRE:
199+
*hdrsize = sizeof(struct gre_base_hdr);
200+
break;
201+
#endif
195202
default:
196203
return -1;
197204
}
@@ -202,15 +209,29 @@ static int nf_flow_tuple_ip(struct sk_buff *skb, const struct net_device *dev,
202209
if (!pskb_may_pull(skb, thoff + *hdrsize))
203210
return -1;
204211

212+
switch (ipproto) {
213+
case IPPROTO_TCP:
214+
case IPPROTO_UDP:
215+
ports = (struct flow_ports *)(skb_network_header(skb) + thoff);
216+
tuple->src_port = ports->source;
217+
tuple->dst_port = ports->dest;
218+
break;
219+
case IPPROTO_GRE: {
220+
struct gre_base_hdr *greh;
221+
222+
greh = (struct gre_base_hdr *)(skb_network_header(skb) + thoff);
223+
if ((greh->flags & GRE_VERSION) != GRE_VERSION_0)
224+
return -1;
225+
break;
226+
}
227+
}
228+
205229
iph = (struct iphdr *)(skb_network_header(skb) + offset);
206-
ports = (struct flow_ports *)(skb_network_header(skb) + thoff);
207230

208231
tuple->src_v4.s_addr = iph->saddr;
209232
tuple->dst_v4.s_addr = iph->daddr;
210-
tuple->src_port = ports->source;
211-
tuple->dst_port = ports->dest;
212233
tuple->l3proto = AF_INET;
213-
tuple->l4proto = iph->protocol;
234+
tuple->l4proto = ipproto;
214235
tuple->iifidx = dev->ifindex;
215236
nf_flow_tuple_encap(skb, tuple);
216237

@@ -521,20 +542,27 @@ static int nf_flow_tuple_ipv6(struct sk_buff *skb, const struct net_device *dev,
521542
struct flow_ports *ports;
522543
struct ipv6hdr *ip6h;
523544
unsigned int thoff;
545+
u8 nexthdr;
524546

525547
thoff = sizeof(*ip6h) + offset;
526548
if (!pskb_may_pull(skb, thoff))
527549
return -1;
528550

529551
ip6h = (struct ipv6hdr *)(skb_network_header(skb) + offset);
530552

531-
switch (ip6h->nexthdr) {
553+
nexthdr = ip6h->nexthdr;
554+
switch (nexthdr) {
532555
case IPPROTO_TCP:
533556
*hdrsize = sizeof(struct tcphdr);
534557
break;
535558
case IPPROTO_UDP:
536559
*hdrsize = sizeof(struct udphdr);
537560
break;
561+
#ifdef CONFIG_NF_CT_PROTO_GRE
562+
case IPPROTO_GRE:
563+
*hdrsize = sizeof(struct gre_base_hdr);
564+
break;
565+
#endif
538566
default:
539567
return -1;
540568
}
@@ -545,15 +573,29 @@ static int nf_flow_tuple_ipv6(struct sk_buff *skb, const struct net_device *dev,
545573
if (!pskb_may_pull(skb, thoff + *hdrsize))
546574
return -1;
547575

576+
switch (nexthdr) {
577+
case IPPROTO_TCP:
578+
case IPPROTO_UDP:
579+
ports = (struct flow_ports *)(skb_network_header(skb) + thoff);
580+
tuple->src_port = ports->source;
581+
tuple->dst_port = ports->dest;
582+
break;
583+
case IPPROTO_GRE: {
584+
struct gre_base_hdr *greh;
585+
586+
greh = (struct gre_base_hdr *)(skb_network_header(skb) + thoff);
587+
if ((greh->flags & GRE_VERSION) != GRE_VERSION_0)
588+
return -1;
589+
break;
590+
}
591+
}
592+
548593
ip6h = (struct ipv6hdr *)(skb_network_header(skb) + offset);
549-
ports = (struct flow_ports *)(skb_network_header(skb) + thoff);
550594

551595
tuple->src_v6 = ip6h->saddr;
552596
tuple->dst_v6 = ip6h->daddr;
553-
tuple->src_port = ports->source;
554-
tuple->dst_port = ports->dest;
555597
tuple->l3proto = AF_INET6;
556-
tuple->l4proto = ip6h->nexthdr;
598+
tuple->l4proto = nexthdr;
557599
tuple->iifidx = dev->ifindex;
558600
nf_flow_tuple_encap(skb, tuple);
559601

net/netfilter/nf_flow_table_offload.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ static int nf_flow_rule_match(struct nf_flow_match *match,
174174
match->dissector.used_keys |= BIT(FLOW_DISSECTOR_KEY_TCP);
175175
break;
176176
case IPPROTO_UDP:
177+
case IPPROTO_GRE:
177178
break;
178179
default:
179180
return -EOPNOTSUPP;
@@ -182,15 +183,22 @@ static int nf_flow_rule_match(struct nf_flow_match *match,
182183
key->basic.ip_proto = tuple->l4proto;
183184
mask->basic.ip_proto = 0xff;
184185

185-
key->tp.src = tuple->src_port;
186-
mask->tp.src = 0xffff;
187-
key->tp.dst = tuple->dst_port;
188-
mask->tp.dst = 0xffff;
189-
190186
match->dissector.used_keys |= BIT(FLOW_DISSECTOR_KEY_META) |
191187
BIT(FLOW_DISSECTOR_KEY_CONTROL) |
192-
BIT(FLOW_DISSECTOR_KEY_BASIC) |
193-
BIT(FLOW_DISSECTOR_KEY_PORTS);
188+
BIT(FLOW_DISSECTOR_KEY_BASIC);
189+
190+
switch (tuple->l4proto) {
191+
case IPPROTO_TCP:
192+
case IPPROTO_UDP:
193+
key->tp.src = tuple->src_port;
194+
mask->tp.src = 0xffff;
195+
key->tp.dst = tuple->dst_port;
196+
mask->tp.dst = 0xffff;
197+
198+
match->dissector.used_keys |= BIT(FLOW_DISSECTOR_KEY_PORTS);
199+
break;
200+
}
201+
194202
return 0;
195203
}
196204

net/netfilter/nf_tables_api.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,30 @@ static int nft_objname_hash_cmp(struct rhashtable_compare_arg *arg,
10721072
return strcmp(obj->key.name, k->name);
10731073
}
10741074

1075+
static bool nft_supported_family(u8 family)
1076+
{
1077+
return false
1078+
#ifdef CONFIG_NF_TABLES_INET
1079+
|| family == NFPROTO_INET
1080+
#endif
1081+
#ifdef CONFIG_NF_TABLES_IPV4
1082+
|| family == NFPROTO_IPV4
1083+
#endif
1084+
#ifdef CONFIG_NF_TABLES_ARP
1085+
|| family == NFPROTO_ARP
1086+
#endif
1087+
#ifdef CONFIG_NF_TABLES_NETDEV
1088+
|| family == NFPROTO_NETDEV
1089+
#endif
1090+
#if IS_ENABLED(CONFIG_NF_TABLES_BRIDGE)
1091+
|| family == NFPROTO_BRIDGE
1092+
#endif
1093+
#ifdef CONFIG_NF_TABLES_IPV6
1094+
|| family == NFPROTO_IPV6
1095+
#endif
1096+
;
1097+
}
1098+
10751099
static int nf_tables_newtable(struct sk_buff *skb, const struct nfnl_info *info,
10761100
const struct nlattr * const nla[])
10771101
{
@@ -1086,6 +1110,9 @@ static int nf_tables_newtable(struct sk_buff *skb, const struct nfnl_info *info,
10861110
u32 flags = 0;
10871111
int err;
10881112

1113+
if (!nft_supported_family(family))
1114+
return -EOPNOTSUPP;
1115+
10891116
lockdep_assert_held(&nft_net->commit_mutex);
10901117
attr = nla[NFTA_TABLE_NAME];
10911118
table = nft_table_lookup(net, attr, family, genmask,

net/netfilter/nft_flow_offload.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,19 @@ static void nft_flow_offload_eval(const struct nft_expr *expr,
298298
break;
299299
case IPPROTO_UDP:
300300
break;
301+
#ifdef CONFIG_NF_CT_PROTO_GRE
302+
case IPPROTO_GRE: {
303+
struct nf_conntrack_tuple *tuple;
304+
305+
if (ct->status & IPS_NAT_MASK)
306+
goto out;
307+
tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
308+
/* No support for GRE v1 */
309+
if (tuple->src.u.gre.key || tuple->dst.u.gre.key)
310+
goto out;
311+
break;
312+
}
313+
#endif
301314
default:
302315
goto out;
303316
}

0 commit comments

Comments
 (0)