aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-08-03 15:28:02 -0400
committerDavid S. Miller <davem@davemloft.net>2018-08-03 15:28:02 -0400
commit60a01828f33051feec8bf74f74e980a163d5a208 (patch)
treeefe603173134e9aa9dda6043038d0d22edf6b454
parentafb41bb039656f0cecb54eeb8b2e2088201295f5 (diff)
parentcaebd1b389708bf3d0465be829480fc706a68720 (diff)
Merge branch 'mlxsw-Fix-ACL-actions-error-condition-handling'
Ido Schimmel says: ==================== mlxsw: Fix ACL actions error condition handling Nir says: Two issues were lately noticed within mlxsw ACL actions error condition handling. The first patch deals with conflicting actions such as: # tc filter add dev swp49 parent ffff: \ protocol ip pref 10 flower skip_sw dst_ip 192.168.101.1 \ action goto chain 100 \ action mirred egress redirect dev swp4 The second action will never execute, however SW model allows this configuration, while the mlxsw driver cannot allow for it as it implements actions in sets of up to three actions per set with a single termination marking. Conflicting actions create a contradiction over this single marking and thus cannot be configured. The fix replaces a misplaced warning with an error code to be returned. Patches 2-4 fix a condition of duplicate destruction of resources. Some actions require allocation of specific resource prior to setting the action itself. On error condition this resource was destroyed twice, leading to a crash when using mirror action, and to a redundant destruction in other cases, since for error condition rule destruction also takes care of resource destruction. In order to fix this state a symmetry in behavior is added and resource destruction also takes care of removing the resource from rule's resource list. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c51
1 files changed, 29 insertions, 22 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
index 3c0d882ba183..f6f6a568d66a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
@@ -327,12 +327,16 @@ static void mlxsw_afa_resource_add(struct mlxsw_afa_block *block,
327 list_add(&resource->list, &block->resource_list); 327 list_add(&resource->list, &block->resource_list);
328} 328}
329 329
330static void mlxsw_afa_resource_del(struct mlxsw_afa_resource *resource)
331{
332 list_del(&resource->list);
333}
334
330static void mlxsw_afa_resources_destroy(struct mlxsw_afa_block *block) 335static void mlxsw_afa_resources_destroy(struct mlxsw_afa_block *block)
331{ 336{
332 struct mlxsw_afa_resource *resource, *tmp; 337 struct mlxsw_afa_resource *resource, *tmp;
333 338
334 list_for_each_entry_safe(resource, tmp, &block->resource_list, list) { 339 list_for_each_entry_safe(resource, tmp, &block->resource_list, list) {
335 list_del(&resource->list);
336 resource->destructor(block, resource); 340 resource->destructor(block, resource);
337 } 341 }
338} 342}
@@ -530,6 +534,7 @@ static void
530mlxsw_afa_fwd_entry_ref_destroy(struct mlxsw_afa_block *block, 534mlxsw_afa_fwd_entry_ref_destroy(struct mlxsw_afa_block *block,
531 struct mlxsw_afa_fwd_entry_ref *fwd_entry_ref) 535 struct mlxsw_afa_fwd_entry_ref *fwd_entry_ref)
532{ 536{
537 mlxsw_afa_resource_del(&fwd_entry_ref->resource);
533 mlxsw_afa_fwd_entry_put(block->afa, fwd_entry_ref->fwd_entry); 538 mlxsw_afa_fwd_entry_put(block->afa, fwd_entry_ref->fwd_entry);
534 kfree(fwd_entry_ref); 539 kfree(fwd_entry_ref);
535} 540}
@@ -579,6 +584,7 @@ static void
579mlxsw_afa_counter_destroy(struct mlxsw_afa_block *block, 584mlxsw_afa_counter_destroy(struct mlxsw_afa_block *block,
580 struct mlxsw_afa_counter *counter) 585 struct mlxsw_afa_counter *counter)
581{ 586{
587 mlxsw_afa_resource_del(&counter->resource);
582 block->afa->ops->counter_index_put(block->afa->ops_priv, 588 block->afa->ops->counter_index_put(block->afa->ops_priv,
583 counter->counter_index); 589 counter->counter_index);
584 kfree(counter); 590 kfree(counter);
@@ -626,8 +632,8 @@ static char *mlxsw_afa_block_append_action(struct mlxsw_afa_block *block,
626 char *oneact; 632 char *oneact;
627 char *actions; 633 char *actions;
628 634
629 if (WARN_ON(block->finished)) 635 if (block->finished)
630 return NULL; 636 return ERR_PTR(-EINVAL);
631 if (block->cur_act_index + action_size > 637 if (block->cur_act_index + action_size >
632 block->afa->max_acts_per_set) { 638 block->afa->max_acts_per_set) {
633 struct mlxsw_afa_set *set; 639 struct mlxsw_afa_set *set;
@@ -637,7 +643,7 @@ static char *mlxsw_afa_block_append_action(struct mlxsw_afa_block *block,
637 */ 643 */
638 set = mlxsw_afa_set_create(false); 644 set = mlxsw_afa_set_create(false);
639 if (!set) 645 if (!set)
640 return NULL; 646 return ERR_PTR(-ENOBUFS);
641 set->prev = block->cur_set; 647 set->prev = block->cur_set;
642 block->cur_act_index = 0; 648 block->cur_act_index = 0;
643 block->cur_set->next = set; 649 block->cur_set->next = set;
@@ -724,8 +730,8 @@ int mlxsw_afa_block_append_vlan_modify(struct mlxsw_afa_block *block,
724 MLXSW_AFA_VLAN_CODE, 730 MLXSW_AFA_VLAN_CODE,
725 MLXSW_AFA_VLAN_SIZE); 731 MLXSW_AFA_VLAN_SIZE);
726 732
727 if (!act) 733 if (IS_ERR(act))
728 return -ENOBUFS; 734 return PTR_ERR(act);
729 mlxsw_afa_vlan_pack(act, MLXSW_AFA_VLAN_VLAN_TAG_CMD_NOP, 735 mlxsw_afa_vlan_pack(act, MLXSW_AFA_VLAN_VLAN_TAG_CMD_NOP,
730 MLXSW_AFA_VLAN_CMD_SET_OUTER, vid, 736 MLXSW_AFA_VLAN_CMD_SET_OUTER, vid,
731 MLXSW_AFA_VLAN_CMD_SET_OUTER, pcp, 737 MLXSW_AFA_VLAN_CMD_SET_OUTER, pcp,
@@ -806,8 +812,8 @@ int mlxsw_afa_block_append_drop(struct mlxsw_afa_block *block)
806 MLXSW_AFA_TRAPDISC_CODE, 812 MLXSW_AFA_TRAPDISC_CODE,
807 MLXSW_AFA_TRAPDISC_SIZE); 813 MLXSW_AFA_TRAPDISC_SIZE);
808 814
809 if (!act) 815 if (IS_ERR(act))
810 return -ENOBUFS; 816 return PTR_ERR(act);
811 mlxsw_afa_trapdisc_pack(act, MLXSW_AFA_TRAPDISC_TRAP_ACTION_NOP, 817 mlxsw_afa_trapdisc_pack(act, MLXSW_AFA_TRAPDISC_TRAP_ACTION_NOP,
812 MLXSW_AFA_TRAPDISC_FORWARD_ACTION_DISCARD, 0); 818 MLXSW_AFA_TRAPDISC_FORWARD_ACTION_DISCARD, 0);
813 return 0; 819 return 0;
@@ -820,8 +826,8 @@ int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block, u16 trap_id)
820 MLXSW_AFA_TRAPDISC_CODE, 826 MLXSW_AFA_TRAPDISC_CODE,
821 MLXSW_AFA_TRAPDISC_SIZE); 827 MLXSW_AFA_TRAPDISC_SIZE);
822 828
823 if (!act) 829 if (IS_ERR(act))
824 return -ENOBUFS; 830 return PTR_ERR(act);
825 mlxsw_afa_trapdisc_pack(act, MLXSW_AFA_TRAPDISC_TRAP_ACTION_TRAP, 831 mlxsw_afa_trapdisc_pack(act, MLXSW_AFA_TRAPDISC_TRAP_ACTION_TRAP,
826 MLXSW_AFA_TRAPDISC_FORWARD_ACTION_DISCARD, 832 MLXSW_AFA_TRAPDISC_FORWARD_ACTION_DISCARD,
827 trap_id); 833 trap_id);
@@ -836,8 +842,8 @@ int mlxsw_afa_block_append_trap_and_forward(struct mlxsw_afa_block *block,
836 MLXSW_AFA_TRAPDISC_CODE, 842 MLXSW_AFA_TRAPDISC_CODE,
837 MLXSW_AFA_TRAPDISC_SIZE); 843 MLXSW_AFA_TRAPDISC_SIZE);
838 844
839 if (!act) 845 if (IS_ERR(act))
840 return -ENOBUFS; 846 return PTR_ERR(act);
841 mlxsw_afa_trapdisc_pack(act, MLXSW_AFA_TRAPDISC_TRAP_ACTION_TRAP, 847 mlxsw_afa_trapdisc_pack(act, MLXSW_AFA_TRAPDISC_TRAP_ACTION_TRAP,
842 MLXSW_AFA_TRAPDISC_FORWARD_ACTION_FORWARD, 848 MLXSW_AFA_TRAPDISC_FORWARD_ACTION_FORWARD,
843 trap_id); 849 trap_id);
@@ -856,6 +862,7 @@ static void
856mlxsw_afa_mirror_destroy(struct mlxsw_afa_block *block, 862mlxsw_afa_mirror_destroy(struct mlxsw_afa_block *block,
857 struct mlxsw_afa_mirror *mirror) 863 struct mlxsw_afa_mirror *mirror)
858{ 864{
865 mlxsw_afa_resource_del(&mirror->resource);
859 block->afa->ops->mirror_del(block->afa->ops_priv, 866 block->afa->ops->mirror_del(block->afa->ops_priv,
860 mirror->local_in_port, 867 mirror->local_in_port,
861 mirror->span_id, 868 mirror->span_id,
@@ -908,8 +915,8 @@ mlxsw_afa_block_append_allocated_mirror(struct mlxsw_afa_block *block,
908 char *act = mlxsw_afa_block_append_action(block, 915 char *act = mlxsw_afa_block_append_action(block,
909 MLXSW_AFA_TRAPDISC_CODE, 916 MLXSW_AFA_TRAPDISC_CODE,
910 MLXSW_AFA_TRAPDISC_SIZE); 917 MLXSW_AFA_TRAPDISC_SIZE);
911 if (!act) 918 if (IS_ERR(act))
912 return -ENOBUFS; 919 return PTR_ERR(act);
913 mlxsw_afa_trapdisc_pack(act, MLXSW_AFA_TRAPDISC_TRAP_ACTION_NOP, 920 mlxsw_afa_trapdisc_pack(act, MLXSW_AFA_TRAPDISC_TRAP_ACTION_NOP,
914 MLXSW_AFA_TRAPDISC_FORWARD_ACTION_FORWARD, 0); 921 MLXSW_AFA_TRAPDISC_FORWARD_ACTION_FORWARD, 0);
915 mlxsw_afa_trapdisc_mirror_pack(act, true, mirror_agent); 922 mlxsw_afa_trapdisc_mirror_pack(act, true, mirror_agent);
@@ -996,8 +1003,8 @@ int mlxsw_afa_block_append_fwd(struct mlxsw_afa_block *block,
996 1003
997 act = mlxsw_afa_block_append_action(block, MLXSW_AFA_FORWARD_CODE, 1004 act = mlxsw_afa_block_append_action(block, MLXSW_AFA_FORWARD_CODE,
998 MLXSW_AFA_FORWARD_SIZE); 1005 MLXSW_AFA_FORWARD_SIZE);
999 if (!act) { 1006 if (IS_ERR(act)) {
1000 err = -ENOBUFS; 1007 err = PTR_ERR(act);
1001 goto err_append_action; 1008 goto err_append_action;
1002 } 1009 }
1003 mlxsw_afa_forward_pack(act, MLXSW_AFA_FORWARD_TYPE_PBS, 1010 mlxsw_afa_forward_pack(act, MLXSW_AFA_FORWARD_TYPE_PBS,
@@ -1052,8 +1059,8 @@ int mlxsw_afa_block_append_allocated_counter(struct mlxsw_afa_block *block,
1052{ 1059{
1053 char *act = mlxsw_afa_block_append_action(block, MLXSW_AFA_POLCNT_CODE, 1060 char *act = mlxsw_afa_block_append_action(block, MLXSW_AFA_POLCNT_CODE,
1054 MLXSW_AFA_POLCNT_SIZE); 1061 MLXSW_AFA_POLCNT_SIZE);
1055 if (!act) 1062 if (IS_ERR(act))
1056 return -ENOBUFS; 1063 return PTR_ERR(act);
1057 mlxsw_afa_polcnt_pack(act, MLXSW_AFA_POLCNT_COUNTER_SET_TYPE_PACKETS_BYTES, 1064 mlxsw_afa_polcnt_pack(act, MLXSW_AFA_POLCNT_COUNTER_SET_TYPE_PACKETS_BYTES,
1058 counter_index); 1065 counter_index);
1059 return 0; 1066 return 0;
@@ -1123,8 +1130,8 @@ int mlxsw_afa_block_append_fid_set(struct mlxsw_afa_block *block, u16 fid)
1123 char *act = mlxsw_afa_block_append_action(block, 1130 char *act = mlxsw_afa_block_append_action(block,
1124 MLXSW_AFA_VIRFWD_CODE, 1131 MLXSW_AFA_VIRFWD_CODE,
1125 MLXSW_AFA_VIRFWD_SIZE); 1132 MLXSW_AFA_VIRFWD_SIZE);
1126 if (!act) 1133 if (IS_ERR(act))
1127 return -ENOBUFS; 1134 return PTR_ERR(act);
1128 mlxsw_afa_virfwd_pack(act, MLXSW_AFA_VIRFWD_FID_CMD_SET, fid); 1135 mlxsw_afa_virfwd_pack(act, MLXSW_AFA_VIRFWD_FID_CMD_SET, fid);
1129 return 0; 1136 return 0;
1130} 1137}
@@ -1193,8 +1200,8 @@ int mlxsw_afa_block_append_mcrouter(struct mlxsw_afa_block *block,
1193 char *act = mlxsw_afa_block_append_action(block, 1200 char *act = mlxsw_afa_block_append_action(block,
1194 MLXSW_AFA_MCROUTER_CODE, 1201 MLXSW_AFA_MCROUTER_CODE,
1195 MLXSW_AFA_MCROUTER_SIZE); 1202 MLXSW_AFA_MCROUTER_SIZE);
1196 if (!act) 1203 if (IS_ERR(act))
1197 return -ENOBUFS; 1204 return PTR_ERR(act);
1198 mlxsw_afa_mcrouter_pack(act, MLXSW_AFA_MCROUTER_RPF_ACTION_TRAP, 1205 mlxsw_afa_mcrouter_pack(act, MLXSW_AFA_MCROUTER_RPF_ACTION_TRAP,
1199 expected_irif, min_mtu, rmid_valid, kvdl_index); 1206 expected_irif, min_mtu, rmid_valid, kvdl_index);
1200 return 0; 1207 return 0;