act_ct.c (d93618da6b6d453c6a9684a3460ffd51b9b4ef2e) act_ct.c (1913894100ca53205f2d56091cb34b8eba1de217)
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2/* -
3 * net/sched/act_ct.c Connection Tracking action
4 *
5 * Authors: Paul Blakey <paulb@mellanox.com>
6 * Yossi Kuperman <yossiku@mellanox.com>
7 * Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
8 */

--- 331 unchanged lines hidden (view full) ---

340 flow_block_cb_free(block_cb);
341 }
342 up_write(&ct_ft->nf_ft.flow_block_lock);
343 kfree(ct_ft);
344
345 module_put(THIS_MODULE);
346}
347
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2/* -
3 * net/sched/act_ct.c Connection Tracking action
4 *
5 * Authors: Paul Blakey <paulb@mellanox.com>
6 * Yossi Kuperman <yossiku@mellanox.com>
7 * Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
8 */

--- 331 unchanged lines hidden (view full) ---

340 flow_block_cb_free(block_cb);
341 }
342 up_write(&ct_ft->nf_ft.flow_block_lock);
343 kfree(ct_ft);
344
345 module_put(THIS_MODULE);
346}
347
348static void tcf_ct_flow_table_put(struct tcf_ct_params *params)
348static void tcf_ct_flow_table_put(struct tcf_ct_flow_table *ct_ft)
349{
349{
350 struct tcf_ct_flow_table *ct_ft = params->ct_ft;
351
352 if (refcount_dec_and_test(&params->ct_ft->ref)) {
350 if (refcount_dec_and_test(&ct_ft->ref)) {
353 rhashtable_remove_fast(&zones_ht, &ct_ft->node, zones_params);
354 INIT_RCU_WORK(&ct_ft->rwork, tcf_ct_flow_table_cleanup_work);
355 queue_rcu_work(act_ct_wq, &ct_ft->rwork);
356 }
357}
358
359static void tcf_ct_flow_tc_ifidx(struct flow_offload *entry,
360 struct nf_conn_act_ct_ext *act_ct_ext, u8 dir)

--- 466 unchanged lines hidden (view full) ---

827 skb->ignore_df = 1;
828 return err;
829
830out_free:
831 kfree_skb(skb);
832 return err;
833}
834
351 rhashtable_remove_fast(&zones_ht, &ct_ft->node, zones_params);
352 INIT_RCU_WORK(&ct_ft->rwork, tcf_ct_flow_table_cleanup_work);
353 queue_rcu_work(act_ct_wq, &ct_ft->rwork);
354 }
355}
356
357static void tcf_ct_flow_tc_ifidx(struct flow_offload *entry,
358 struct nf_conn_act_ct_ext *act_ct_ext, u8 dir)

--- 466 unchanged lines hidden (view full) ---

825 skb->ignore_df = 1;
826 return err;
827
828out_free:
829 kfree_skb(skb);
830 return err;
831}
832
835static void tcf_ct_params_free(struct rcu_head *head)
833static void tcf_ct_params_free(struct tcf_ct_params *params)
836{
834{
837 struct tcf_ct_params *params = container_of(head,
838 struct tcf_ct_params, rcu);
839
840 tcf_ct_flow_table_put(params);
841
835 if (params->ct_ft)
836 tcf_ct_flow_table_put(params->ct_ft);
842 if (params->tmpl)
843 nf_ct_put(params->tmpl);
844 kfree(params);
845}
846
837 if (params->tmpl)
838 nf_ct_put(params->tmpl);
839 kfree(params);
840}
841
842static void tcf_ct_params_free_rcu(struct rcu_head *head)
843{
844 struct tcf_ct_params *params;
845
846 params = container_of(head, struct tcf_ct_params, rcu);
847 tcf_ct_params_free(params);
848}
849
847#if IS_ENABLED(CONFIG_NF_NAT)
848/* Modelled after nf_nat_ipv[46]_fn().
849 * range is only used for new, uninitialized NAT state.
850 * Returns either NF_ACCEPT or NF_DROP.
851 */
852static int ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
853 enum ip_conntrack_info ctinfo,
854 const struct nf_nat_range2 *range,

--- 530 unchanged lines hidden (view full) ---

1385 }
1386
1387 err = tcf_ct_fill_params(net, params, parm, tb, extack);
1388 if (err)
1389 goto cleanup;
1390
1391 err = tcf_ct_flow_table_get(net, params);
1392 if (err)
850#if IS_ENABLED(CONFIG_NF_NAT)
851/* Modelled after nf_nat_ipv[46]_fn().
852 * range is only used for new, uninitialized NAT state.
853 * Returns either NF_ACCEPT or NF_DROP.
854 */
855static int ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
856 enum ip_conntrack_info ctinfo,
857 const struct nf_nat_range2 *range,

--- 530 unchanged lines hidden (view full) ---

1388 }
1389
1390 err = tcf_ct_fill_params(net, params, parm, tb, extack);
1391 if (err)
1392 goto cleanup;
1393
1394 err = tcf_ct_flow_table_get(net, params);
1395 if (err)
1393 goto cleanup_params;
1396 goto cleanup;
1394
1395 spin_lock_bh(&c->tcf_lock);
1396 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
1397 params = rcu_replace_pointer(c->params, params,
1398 lockdep_is_held(&c->tcf_lock));
1399 spin_unlock_bh(&c->tcf_lock);
1400
1401 if (goto_ch)
1402 tcf_chain_put_by_act(goto_ch);
1403 if (params)
1397
1398 spin_lock_bh(&c->tcf_lock);
1399 goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
1400 params = rcu_replace_pointer(c->params, params,
1401 lockdep_is_held(&c->tcf_lock));
1402 spin_unlock_bh(&c->tcf_lock);
1403
1404 if (goto_ch)
1405 tcf_chain_put_by_act(goto_ch);
1406 if (params)
1404 call_rcu(&params->rcu, tcf_ct_params_free);
1407 call_rcu(&params->rcu, tcf_ct_params_free_rcu);
1405
1406 return res;
1407
1408
1409 return res;
1410
1408cleanup_params:
1409 if (params->tmpl)
1410 nf_ct_put(params->tmpl);
1411cleanup:
1412 if (goto_ch)
1413 tcf_chain_put_by_act(goto_ch);
1411cleanup:
1412 if (goto_ch)
1413 tcf_chain_put_by_act(goto_ch);
1414 kfree(params);
1414 if (params)
1415 tcf_ct_params_free(params);
1415 tcf_idr_release(*a, bind);
1416 return err;
1417}
1418
1419static void tcf_ct_cleanup(struct tc_action *a)
1420{
1421 struct tcf_ct_params *params;
1422 struct tcf_ct *c = to_ct(a);
1423
1424 params = rcu_dereference_protected(c->params, 1);
1425 if (params)
1416 tcf_idr_release(*a, bind);
1417 return err;
1418}
1419
1420static void tcf_ct_cleanup(struct tc_action *a)
1421{
1422 struct tcf_ct_params *params;
1423 struct tcf_ct *c = to_ct(a);
1424
1425 params = rcu_dereference_protected(c->params, 1);
1426 if (params)
1426 call_rcu(&params->rcu, tcf_ct_params_free);
1427 call_rcu(&params->rcu, tcf_ct_params_free_rcu);
1427}
1428
1429static int tcf_ct_dump_key_val(struct sk_buff *skb,
1430 void *val, int val_type,
1431 void *mask, int mask_type,
1432 int len)
1433{
1434 int err;

--- 248 unchanged lines hidden ---
1428}
1429
1430static int tcf_ct_dump_key_val(struct sk_buff *skb,
1431 void *val, int val_type,
1432 void *mask, int mask_type,
1433 int len)
1434{
1435 int err;

--- 248 unchanged lines hidden ---