Skip to content

Commit b7c3a17

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: ==================== Netfilter fixes for net The following patchset contains Netfilter fixes for net: 1) Fix suspicious RCU usage in ipset, from Jozsef Kadlecsik. 2) Use kvcalloc, from Joe Perches. 3) Flush flowtable hardware workqueue after garbage collection run, from Paul Blakey. 4) Missing flowtable hardware workqueue flush from nf_flow_table_free(), also from Paul. 5) Restore NF_FLOW_HW_DEAD in flow_offload_work_del(), from Paul. 6) Flowtable documentation fixes, from Matteo Croce. ==================== Signed-off-by: Jakub Kicinski <[email protected]>
2 parents cb3c0e6 + 78e06cf commit b7c3a17

File tree

6 files changed

+28
-26
lines changed

6 files changed

+28
-26
lines changed

Documentation/networking/nf_flowtable.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ flowtable and add one rule to your forward chain.
7676

7777
table inet x {
7878
flowtable f {
79-
hook ingress priority 0 devices = { eth0, eth1 };
79+
hook ingress priority 0; devices = { eth0, eth1 };
8080
}
8181
chain y {
8282
type filter hook forward priority 0; policy accept;

net/netfilter/ipset/ip_set_core.c

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,31 +1483,34 @@ ip_set_dump_policy[IPSET_ATTR_CMD_MAX + 1] = {
14831483
};
14841484

14851485
static int
1486-
dump_init(struct netlink_callback *cb, struct ip_set_net *inst)
1486+
ip_set_dump_start(struct netlink_callback *cb)
14871487
{
14881488
struct nlmsghdr *nlh = nlmsg_hdr(cb->skb);
14891489
int min_len = nlmsg_total_size(sizeof(struct nfgenmsg));
14901490
struct nlattr *cda[IPSET_ATTR_CMD_MAX + 1];
14911491
struct nlattr *attr = (void *)nlh + min_len;
1492+
struct sk_buff *skb = cb->skb;
1493+
struct ip_set_net *inst = ip_set_pernet(sock_net(skb->sk));
14921494
u32 dump_type;
1493-
ip_set_id_t index;
14941495
int ret;
14951496

14961497
ret = nla_parse(cda, IPSET_ATTR_CMD_MAX, attr,
14971498
nlh->nlmsg_len - min_len,
14981499
ip_set_dump_policy, NULL);
14991500
if (ret)
1500-
return ret;
1501+
goto error;
15011502

15021503
cb->args[IPSET_CB_PROTO] = nla_get_u8(cda[IPSET_ATTR_PROTOCOL]);
15031504
if (cda[IPSET_ATTR_SETNAME]) {
1505+
ip_set_id_t index;
15041506
struct ip_set *set;
15051507

15061508
set = find_set_and_id(inst, nla_data(cda[IPSET_ATTR_SETNAME]),
15071509
&index);
1508-
if (!set)
1509-
return -ENOENT;
1510-
1510+
if (!set) {
1511+
ret = -ENOENT;
1512+
goto error;
1513+
}
15111514
dump_type = DUMP_ONE;
15121515
cb->args[IPSET_CB_INDEX] = index;
15131516
} else {
@@ -1523,10 +1526,17 @@ dump_init(struct netlink_callback *cb, struct ip_set_net *inst)
15231526
cb->args[IPSET_CB_DUMP] = dump_type;
15241527

15251528
return 0;
1529+
1530+
error:
1531+
/* We have to create and send the error message manually :-( */
1532+
if (nlh->nlmsg_flags & NLM_F_ACK) {
1533+
netlink_ack(cb->skb, nlh, ret, NULL);
1534+
}
1535+
return ret;
15261536
}
15271537

15281538
static int
1529-
ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
1539+
ip_set_dump_do(struct sk_buff *skb, struct netlink_callback *cb)
15301540
{
15311541
ip_set_id_t index = IPSET_INVALID_ID, max;
15321542
struct ip_set *set = NULL;
@@ -1537,18 +1547,8 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
15371547
bool is_destroyed;
15381548
int ret = 0;
15391549

1540-
if (!cb->args[IPSET_CB_DUMP]) {
1541-
ret = dump_init(cb, inst);
1542-
if (ret < 0) {
1543-
nlh = nlmsg_hdr(cb->skb);
1544-
/* We have to create and send the error message
1545-
* manually :-(
1546-
*/
1547-
if (nlh->nlmsg_flags & NLM_F_ACK)
1548-
netlink_ack(cb->skb, nlh, ret, NULL);
1549-
return ret;
1550-
}
1551-
}
1550+
if (!cb->args[IPSET_CB_DUMP])
1551+
return -EINVAL;
15521552

15531553
if (cb->args[IPSET_CB_INDEX] >= inst->ip_set_max)
15541554
goto out;
@@ -1684,7 +1684,8 @@ static int ip_set_dump(struct net *net, struct sock *ctnl, struct sk_buff *skb,
16841684

16851685
{
16861686
struct netlink_dump_control c = {
1687-
.dump = ip_set_dump_start,
1687+
.start = ip_set_dump_start,
1688+
.dump = ip_set_dump_do,
16881689
.done = ip_set_dump_done,
16891690
};
16901691
return netlink_dump_start(ctnl, skb, nlh, &c);

net/netfilter/nf_conntrack_core.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2248,8 +2248,7 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
22482248
BUILD_BUG_ON(sizeof(struct hlist_nulls_head) != sizeof(struct hlist_head));
22492249
nr_slots = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_nulls_head));
22502250

2251-
hash = kvmalloc_array(nr_slots, sizeof(struct hlist_nulls_head),
2252-
GFP_KERNEL | __GFP_ZERO);
2251+
hash = kvcalloc(nr_slots, sizeof(struct hlist_nulls_head), GFP_KERNEL);
22532252

22542253
if (hash && nulls)
22552254
for (i = 0; i < nr_slots; i++)

net/netfilter/nf_flow_table_core.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,9 +529,9 @@ static void nf_flow_table_do_cleanup(struct flow_offload *flow, void *data)
529529
static void nf_flow_table_iterate_cleanup(struct nf_flowtable *flowtable,
530530
struct net_device *dev)
531531
{
532-
nf_flow_table_offload_flush(flowtable);
533532
nf_flow_table_iterate(flowtable, nf_flow_table_do_cleanup, dev);
534533
flush_delayed_work(&flowtable->gc_work);
534+
nf_flow_table_offload_flush(flowtable);
535535
}
536536

537537
void nf_flow_table_cleanup(struct net_device *dev)
@@ -553,6 +553,7 @@ void nf_flow_table_free(struct nf_flowtable *flow_table)
553553
cancel_delayed_work_sync(&flow_table->gc_work);
554554
nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL);
555555
nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, flow_table);
556+
nf_flow_table_offload_flush(flow_table);
556557
rhashtable_destroy(&flow_table->rhashtable);
557558
}
558559
EXPORT_SYMBOL_GPL(nf_flow_table_free);

net/netfilter/nf_flow_table_offload.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,7 @@ static void flow_offload_work_del(struct flow_offload_work *offload)
675675
{
676676
flow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_ORIGINAL);
677677
flow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_REPLY);
678+
set_bit(NF_FLOW_HW_DEAD, &offload->flow->flags);
678679
}
679680

680681
static void flow_offload_tuple_stats(struct flow_offload_work *offload,

net/netfilter/x_tables.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -939,14 +939,14 @@ EXPORT_SYMBOL(xt_check_entry_offsets);
939939
*
940940
* @size: number of entries
941941
*
942-
* Return: NULL or kmalloc'd or vmalloc'd array
942+
* Return: NULL or zeroed kmalloc'd or vmalloc'd array
943943
*/
944944
unsigned int *xt_alloc_entry_offsets(unsigned int size)
945945
{
946946
if (size > XT_MAX_TABLE_SIZE / sizeof(unsigned int))
947947
return NULL;
948948

949-
return kvmalloc_array(size, sizeof(unsigned int), GFP_KERNEL | __GFP_ZERO);
949+
return kvcalloc(size, sizeof(unsigned int), GFP_KERNEL);
950950

951951
}
952952
EXPORT_SYMBOL(xt_alloc_entry_offsets);

0 commit comments

Comments
 (0)