File s390-tools-sles15-zdev-fix-qeth-BridgePort-and-VNICC-conflict-checking.patch of Package s390-tools.10760

Subject: zdev: qeth BridgePort and VNICC attribute conflict
From: Hans Wippel <hwippel@linux.ibm.com>

Description:  zdev: qeth BridgePort and VNICC attribute conflict
Symptom:      chzdev cannot set VNICC attributes due to a conflict with
              BridgePort attributes.
Problem:      Existing conflict checking always assumes a BridgePort and a
              VNICC attribute are active.
Solution:     Introduce a function that determines if BridgePort or VNICC
              attributes are active and use only active attributes for conflict
              checking.
Reproduction: Set VNICC attribute with chzdev w/o active BridgePort attributes.
Upstream-ID:  df01c470c2a680a924ccdba3b6657af4669002b2
Problem-ID:   172409


Signed-off-by: Hans Wippel <hwippel@linux.ibm.com>
---
 zdev/src/qeth.c |   33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

--- a/zdev/src/qeth.c
+++ b/zdev/src/qeth.c
@@ -1170,6 +1170,37 @@ static exit_code_t check_ineffective_set
 	return rc;
 }
 
+/* Check if a possibly conflicting setting is active in the configuration */
+static bool conflict_setting_active(struct setting *s)
+{
+	enum qeth_attr_group_type t;
+
+	t = get_attr_group_type(s);
+	if (t != group_bridge && t != group_vnicc) {
+		/* Check BridgePort and VNICC attributes only */
+		return false;
+	}
+	if (s->specified) {
+		/* Specified on the command line: We are strict here and do not
+		 * allow to specify VNICC and BridgePort attributes in the same
+		 * command to avoid issues when attributes are enabled/disabled
+		 * in the wrong order. Example: disable VNICC and enable
+		 * BridgePort in the same command would	result in an error
+		 * because BridgePort attributes are set first.
+		 */
+		return true;
+	}
+	if (attrib_match_default(s->attrib, s->value)) {
+		/* Not active if set to default value */
+		return false;
+	}
+	if (s->actual_value && strncmp(s->actual_value, "n/a", 3) == 0) {
+		/* Not active if in n/a state (conflicting attribute set) */
+		return false;
+	}
+	return true;
+}
+
 /* Check if there are conflicting attribute settings */
 static exit_code_t check_conflicting_settings(struct setting_list *list)
 {
@@ -1181,6 +1212,8 @@ static exit_code_t check_conflicting_set
 	util_list_iterate(&list->list, s) {
 		if (s->removed)
 			continue;
+		if (!conflict_setting_active(s))
+			continue;
 		t = get_attr_group_type(s);
 		if (t == group_bridge && (!bridge || !bridge->specified))
 			bridge = s;