This patch adds parsing of XML elements identifying NetEm parameters.
Along with parsing, basic syntax check is executed, checking if
mandatory attributes are correctly entered.
Signed-off-by: Jiri Prochazka <jprochaz(a)redhat.com>
---
lnst/Controller/RecipeParser.py | 63 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/lnst/Controller/RecipeParser.py b/lnst/Controller/RecipeParser.py
index 7269820..73422f1 100644
--- a/lnst/Controller/RecipeParser.py
+++ b/lnst/Controller/RecipeParser.py
@@ -111,6 +111,11 @@ class RecipeParser(XmlParser):
if self._has_attribute(iface_tag, "netns"):
iface["netns"] = self._get_attribute(iface_tag, "netns")
+ # netem
+ netem_tag = iface_tag.find("netem")
+ if netem_tag is not None:
+ iface["netem"] = self._process_netem(netem_tag)
+
# params
params_tag = iface_tag.find("params")
params = self._process_params(params_tag)
@@ -269,6 +274,64 @@ class RecipeParser(XmlParser):
return options
+ def _validate_netem(self, options, netem_op, netem_tag):
+ if netem_op == "delay":
+ valid = False
+ jitter = False
+ correlation = False
+ distribution = False
+ valid_distributions = ["normal", "uniform",
"pareto", "paretonormal"]
+ for opt in options:
+ if "time" in opt.values():
+ valid = True
+ elif "distribution" in opt.values():
+ if opt["value"] not in valid_distributions:
+ raise RecipeError("netem: invalid distribution type",
netem_tag)
+ else:
+ distribution = True
+ elif "jitter" in opt.values():
+ jitter = True
+ elif "correlation" in opt.values():
+ correlation = True
+ if not jitter:
+ if correlation or distribution:
+ raise RecipeError("netem: jitter option is mandatory when using
<correlation> or <distribution>", netem_tag)
+ if not valid:
+ raise RecipeError("netem: time option is mandatory for
<delay>", netem_tag)
+ elif netem_op == "loss":
+ for opt in options:
+ if "percent" in opt.values():
+ return
+ raise RecipeError("netem: percent option is mandatory for
<loss>", netem_tag)
+ elif netem_op == "duplication":
+ for opt in options:
+ if "percent" in opt.values():
+ return
+ raise RecipeError("netem: percent option is mandatory for
<duplication>", netem_tag)
+ elif netem_op == "corrupt":
+ for opt in options:
+ if "percent" in opt.values():
+ return
+ raise RecipeError("netem: percent option is mandatory for
<corrupt>", netem_tag)
+ elif netem_op == "reordering":
+ for opt in options:
+ if "percent" in opt.values():
+ return
+ raise RecipeError("netem: percent option is mandatory for
<reordering>", netem_tag)
+
+ def _process_netem(self, netem_tag):
+ interface = XmlData(netem_tag)
+ # params
+ for netem_op in ["delay", "loss", "duplication",
"corrupt", "reordering"]:
+ netem_op_tag = netem_tag.find(netem_op)
+ if netem_op_tag is not None:
+ options_tag = netem_op_tag.find("options")
+ options = self._process_options(options_tag)
+ if len(options) > 0:
+ self._validate_netem(options, netem_op, netem_tag)
+ interface[netem_op] = options
+ return interface
+
def _process_task(self, task_tag):
task = XmlData(task_tag)
--
2.1.0