aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTibor Frank <tifrank@cisco.com>2023-04-18 12:04:49 +0200
committerTibor Frank <tifrank@cisco.com>2023-04-18 12:06:14 +0000
commit877928bd3cf147654209225dd4605db02eb562e4 (patch)
treef8361c1bcf96c8b9d2726229734333a5bbfbe2ec
parent90597a49191ada39edbf3490948df2229c743bef (diff)
C-Dash: Add VPP Device coverage data
Signed-off-by: Tibor Frank <tifrank@cisco.com> Change-Id: Ib083d287b8483c8b5b1be14ef3ce6b798eb04352
-rw-r--r--csit.infra.dash/app/cdash/coverage/layout.py2
-rw-r--r--csit.infra.dash/app/cdash/coverage/tables.py298
-rw-r--r--csit.infra.dash/app/cdash/data/data.py6
-rw-r--r--csit.infra.dash/app/cdash/data/data.yaml95
-rw-r--r--csit.infra.dash/app/cdash/report/layout.py4
-rw-r--r--csit.infra.dash/app/cdash/trending/layout.py2
-rw-r--r--csit.infra.dash/app/cdash/utils/constants.py23
7 files changed, 194 insertions, 236 deletions
diff --git a/csit.infra.dash/app/cdash/coverage/layout.py b/csit.infra.dash/app/cdash/coverage/layout.py
index 03d2da7fb7..f519f5a8ac 100644
--- a/csit.infra.dash/app/cdash/coverage/layout.py
+++ b/csit.infra.dash/app/cdash/coverage/layout.py
@@ -92,7 +92,7 @@ class Layout:
if dut == "dpdk":
area = "dpdk"
else:
- area = "-".join(lst_test_id[3:-2])
+ area = ".".join(lst_test_id[3:-2])
suite = lst_test_id[-2].replace("2n1l-", "").replace("1n1l-", "").\
replace("2n-", "")
test = lst_test_id[-1]
diff --git a/csit.infra.dash/app/cdash/coverage/tables.py b/csit.infra.dash/app/cdash/coverage/tables.py
index a773a2280c..31b227e9a8 100644
--- a/csit.infra.dash/app/cdash/coverage/tables.py
+++ b/csit.infra.dash/app/cdash/coverage/tables.py
@@ -75,8 +75,10 @@ def select_coverage_data(
inplace=True
)
+ ttype = df["test_type"].to_list()[0]
+
# Prepare the coverage data
- def _latency(hdrh_string: str, percentile: float) -> int:
+ def _laten(hdrh_string: str, percentile: float) -> int:
"""Get latency from HDRH string for given percentile.
:param hdrh_string: Encoded HDRH string.
@@ -105,109 +107,118 @@ def select_coverage_data(
return test_id.split(".")[-1].replace("-ndrpdr", "")
cov = pd.DataFrame()
- cov["suite"] = df.apply(lambda row: _get_suite(row["test_id"]), axis=1)
+ cov["Suite"] = df.apply(lambda row: _get_suite(row["test_id"]), axis=1)
cov["Test Name"] = df.apply(lambda row: _get_test(row["test_id"]), axis=1)
- cov["Throughput_Unit"] = df["result_pdr_lower_rate_unit"]
- cov["Throughput_NDR"] = df.apply(
- lambda row: row["result_ndr_lower_rate_value"] / 1e6, axis=1
- )
- cov["Throughput_NDR_Mbps"] = df.apply(
- lambda row: row["result_ndr_lower_bandwidth_value"] /1e9, axis=1
- )
- cov["Throughput_PDR"] = \
- df.apply(lambda row: row["result_pdr_lower_rate_value"] / 1e6, axis=1)
- cov["Throughput_PDR_Mbps"] = df.apply(
- lambda row: row["result_pdr_lower_bandwidth_value"] /1e9, axis=1
- )
- cov["Latency Forward [us]_10% PDR_P50"] = df.apply(
- lambda row: _latency(row["result_latency_forward_pdr_10_hdrh"], 50.0),
- axis=1
- )
- cov["Latency Forward [us]_10% PDR_P90"] = df.apply(
- lambda row: _latency(row["result_latency_forward_pdr_10_hdrh"], 90.0),
- axis=1
- )
- cov["Latency Forward [us]_10% PDR_P99"] = df.apply(
- lambda row: _latency(row["result_latency_forward_pdr_10_hdrh"], 99.0),
- axis=1
- )
- cov["Latency Forward [us]_50% PDR_P50"] = df.apply(
- lambda row: _latency(row["result_latency_forward_pdr_50_hdrh"], 50.0),
- axis=1
- )
- cov["Latency Forward [us]_50% PDR_P90"] = df.apply(
- lambda row: _latency(row["result_latency_forward_pdr_50_hdrh"], 90.0),
- axis=1
- )
- cov["Latency Forward [us]_50% PDR_P99"] = df.apply(
- lambda row: _latency(row["result_latency_forward_pdr_50_hdrh"], 99.0),
- axis=1
- )
- cov["Latency Forward [us]_90% PDR_P50"] = df.apply(
- lambda row: _latency(row["result_latency_forward_pdr_90_hdrh"], 50.0),
- axis=1
- )
- cov["Latency Forward [us]_90% PDR_P90"] = df.apply(
- lambda row: _latency(row["result_latency_forward_pdr_90_hdrh"], 90.0),
- axis=1
- )
- cov["Latency Forward [us]_90% PDR_P99"] = df.apply(
- lambda row: _latency(row["result_latency_forward_pdr_90_hdrh"], 99.0),
- axis=1
- )
- cov["Latency Reverse [us]_10% PDR_P50"] = df.apply(
- lambda row: _latency(row["result_latency_reverse_pdr_10_hdrh"], 50.0),
- axis=1
- )
- cov["Latency Reverse [us]_10% PDR_P90"] = df.apply(
- lambda row: _latency(row["result_latency_reverse_pdr_10_hdrh"], 90.0),
- axis=1
- )
- cov["Latency Reverse [us]_10% PDR_P99"] = df.apply(
- lambda row: _latency(row["result_latency_reverse_pdr_10_hdrh"], 99.0),
- axis=1
- )
- cov["Latency Reverse [us]_50% PDR_P50"] = df.apply(
- lambda row: _latency(row["result_latency_reverse_pdr_50_hdrh"], 50.0),
- axis=1
- )
- cov["Latency Reverse [us]_50% PDR_P90"] = df.apply(
- lambda row: _latency(row["result_latency_reverse_pdr_50_hdrh"], 90.0),
- axis=1
- )
- cov["Latency Reverse [us]_50% PDR_P99"] = df.apply(
- lambda row: _latency(row["result_latency_reverse_pdr_50_hdrh"], 99.0),
- axis=1
- )
- cov["Latency Reverse [us]_90% PDR_P50"] = df.apply(
- lambda row: _latency(row["result_latency_reverse_pdr_90_hdrh"], 50.0),
- axis=1
- )
- cov["Latency Reverse [us]_90% PDR_P90"] = df.apply(
- lambda row: _latency(row["result_latency_reverse_pdr_90_hdrh"], 90.0),
- axis=1
- )
- cov["Latency Reverse [us]_90% PDR_P99"] = df.apply(
- lambda row: _latency(row["result_latency_reverse_pdr_90_hdrh"], 99.0),
- axis=1
- )
+
+ if ttype == "device":
+ cov = cov.assign(Result="PASS")
+ else:
+ cov["Throughput_Unit"] = df["result_pdr_lower_rate_unit"]
+ cov["Throughput_NDR"] = df.apply(
+ lambda row: row["result_ndr_lower_rate_value"] / 1e6, axis=1
+ )
+ cov["Throughput_NDR_Mbps"] = df.apply(
+ lambda row: row["result_ndr_lower_bandwidth_value"] /1e9, axis=1
+ )
+ cov["Throughput_PDR"] = df.apply(
+ lambda row: row["result_pdr_lower_rate_value"] / 1e6, axis=1
+ )
+ cov["Throughput_PDR_Mbps"] = df.apply(
+ lambda row: row["result_pdr_lower_bandwidth_value"] /1e9, axis=1
+ )
+ cov["Latency Forward [us]_10% PDR_P50"] = df.apply(
+ lambda row: _laten(row["result_latency_forward_pdr_10_hdrh"], 50.0),
+ axis=1
+ )
+ cov["Latency Forward [us]_10% PDR_P90"] = df.apply(
+ lambda row: _laten(row["result_latency_forward_pdr_10_hdrh"], 90.0),
+ axis=1
+ )
+ cov["Latency Forward [us]_10% PDR_P99"] = df.apply(
+ lambda row: _laten(row["result_latency_forward_pdr_10_hdrh"], 99.0),
+ axis=1
+ )
+ cov["Latency Forward [us]_50% PDR_P50"] = df.apply(
+ lambda row: _laten(row["result_latency_forward_pdr_50_hdrh"], 50.0),
+ axis=1
+ )
+ cov["Latency Forward [us]_50% PDR_P90"] = df.apply(
+ lambda row: _laten(row["result_latency_forward_pdr_50_hdrh"], 90.0),
+ axis=1
+ )
+ cov["Latency Forward [us]_50% PDR_P99"] = df.apply(
+ lambda row: _laten(row["result_latency_forward_pdr_50_hdrh"], 99.0),
+ axis=1
+ )
+ cov["Latency Forward [us]_90% PDR_P50"] = df.apply(
+ lambda row: _laten(row["result_latency_forward_pdr_90_hdrh"], 50.0),
+ axis=1
+ )
+ cov["Latency Forward [us]_90% PDR_P90"] = df.apply(
+ lambda row: _laten(row["result_latency_forward_pdr_90_hdrh"], 90.0),
+ axis=1
+ )
+ cov["Latency Forward [us]_90% PDR_P99"] = df.apply(
+ lambda row: _laten(row["result_latency_forward_pdr_90_hdrh"], 99.0),
+ axis=1
+ )
+ cov["Latency Reverse [us]_10% PDR_P50"] = df.apply(
+ lambda row: _laten(row["result_latency_reverse_pdr_10_hdrh"], 50.0),
+ axis=1
+ )
+ cov["Latency Reverse [us]_10% PDR_P90"] = df.apply(
+ lambda row: _laten(row["result_latency_reverse_pdr_10_hdrh"], 90.0),
+ axis=1
+ )
+ cov["Latency Reverse [us]_10% PDR_P99"] = df.apply(
+ lambda row: _laten(row["result_latency_reverse_pdr_10_hdrh"], 99.0),
+ axis=1
+ )
+ cov["Latency Reverse [us]_50% PDR_P50"] = df.apply(
+ lambda row: _laten(row["result_latency_reverse_pdr_50_hdrh"], 50.0),
+ axis=1
+ )
+ cov["Latency Reverse [us]_50% PDR_P90"] = df.apply(
+ lambda row: _laten(row["result_latency_reverse_pdr_50_hdrh"], 90.0),
+ axis=1
+ )
+ cov["Latency Reverse [us]_50% PDR_P99"] = df.apply(
+ lambda row: _laten(row["result_latency_reverse_pdr_50_hdrh"], 99.0),
+ axis=1
+ )
+ cov["Latency Reverse [us]_90% PDR_P50"] = df.apply(
+ lambda row: _laten(row["result_latency_reverse_pdr_90_hdrh"], 50.0),
+ axis=1
+ )
+ cov["Latency Reverse [us]_90% PDR_P90"] = df.apply(
+ lambda row: _laten(row["result_latency_reverse_pdr_90_hdrh"], 90.0),
+ axis=1
+ )
+ cov["Latency Reverse [us]_90% PDR_P99"] = df.apply(
+ lambda row: _laten(row["result_latency_reverse_pdr_90_hdrh"], 99.0),
+ axis=1
+ )
if csv:
return cov
- # Split data into tabels depending on the test suite.
- for suite in cov["suite"].unique().tolist():
- df_suite = pd.DataFrame(cov.loc[(cov["suite"] == suite)])
- unit = df_suite["Throughput_Unit"].tolist()[0]
- df_suite.rename(
- columns={
- "Throughput_NDR": f"Throughput_NDR_M{unit}",
- "Throughput_PDR": f"Throughput_PDR_M{unit}"
- },
- inplace=True
- )
- df_suite.drop(["suite", "Throughput_Unit"], axis=1, inplace=True)
+ # Split data into tables depending on the test suite.
+ for suite in cov["Suite"].unique().tolist():
+ df_suite = pd.DataFrame(cov.loc[(cov["Suite"] == suite)])
+
+ if ttype !="device":
+ unit = df_suite["Throughput_Unit"].tolist()[0]
+ df_suite.rename(
+ columns={
+ "Throughput_NDR": f"Throughput_NDR_M{unit}",
+ "Throughput_PDR": f"Throughput_PDR_M{unit}"
+ },
+ inplace=True
+ )
+ df_suite.drop(["Suite", "Throughput_Unit"], axis=1, inplace=True)
+
l_data.append((suite, df_suite, ))
+
return l_data
@@ -224,34 +235,59 @@ def coverage_tables(data: pd.DataFrame, selected: dict) -> list:
accordion_items = list()
for suite, cov_data in select_coverage_data(data, selected):
- cols = list()
- for idx, col in enumerate(cov_data.columns):
- if idx == 0:
- cols.append({
- "name": ["", "", col],
+ if len(cov_data.columns) == 3: # VPP Device
+ cols = [
+ {
+ "name": col,
"id": col,
"deletable": False,
"selectable": False,
"type": "text"
- })
- elif idx < 5:
- cols.append({
- "name": col.split("_"),
- "id": col,
- "deletable": False,
- "selectable": False,
- "type": "numeric",
- "format": Format(precision=2, scheme=Scheme.fixed)
- })
- else:
- cols.append({
- "name": col.split("_"),
- "id": col,
- "deletable": False,
- "selectable": False,
- "type": "numeric",
- "format": Format(precision=0, scheme=Scheme.fixed)
- })
+ } for col in cov_data.columns
+ ]
+ style_cell={"textAlign": "left"}
+ style_cell_conditional=[
+ {
+ "if": {"column_id": "Result"},
+ "textAlign": "right"
+ }
+ ]
+ else: # Performance
+ cols = list()
+ for idx, col in enumerate(cov_data.columns):
+ if idx == 0:
+ cols.append({
+ "name": ["", "", col],
+ "id": col,
+ "deletable": False,
+ "selectable": False,
+ "type": "text"
+ })
+ elif idx < 5:
+ cols.append({
+ "name": col.split("_"),
+ "id": col,
+ "deletable": False,
+ "selectable": False,
+ "type": "numeric",
+ "format": Format(precision=2, scheme=Scheme.fixed)
+ })
+ else:
+ cols.append({
+ "name": col.split("_"),
+ "id": col,
+ "deletable": False,
+ "selectable": False,
+ "type": "numeric",
+ "format": Format(precision=0, scheme=Scheme.fixed)
+ })
+ style_cell={"textAlign": "right"}
+ style_cell_conditional=[
+ {
+ "if": {"column_id": "Test Name"},
+ "textAlign": "left"
+ }
+ ]
accordion_items.append(
dbc.AccordionItem(
@@ -267,18 +303,14 @@ def coverage_tables(data: pd.DataFrame, selected: dict) -> list:
selected_columns=[],
selected_rows=[],
page_action="none",
- style_cell={"textAlign": "right"},
- style_cell_conditional=[{
- "if": {"column_id": "Test Name"},
- "textAlign": "left"
- }]
+ style_cell=style_cell,
+ style_cell_conditional=style_cell_conditional
)
)
)
-
return dbc.Accordion(
- children=accordion_items,
- class_name="gy-2 p-0",
- start_collapsed=True,
- always_open=True
- )
+ children=accordion_items,
+ class_name="gy-1 p-0",
+ start_collapsed=True,
+ always_open=True
+ )
diff --git a/csit.infra.dash/app/cdash/data/data.py b/csit.infra.dash/app/cdash/data/data.py
index c8d5907200..a0d698e2b0 100644
--- a/csit.infra.dash/app/cdash/data/data.py
+++ b/csit.infra.dash/app/cdash/data/data.py
@@ -122,7 +122,6 @@ class Data:
def _create_dataframe_from_parquet(
path, partition_filter=None,
columns=None,
- categories=None,
validate_schema=False,
last_modified_begin=None,
last_modified_end=None,
@@ -141,8 +140,6 @@ class Data:
extracted from S3. This function MUST return a bool, True to read
the partition or False to ignore it. Ignored if dataset=False.
:param columns: Names of columns to read from the file(s).
- :param categories: List of columns names that should be returned as
- pandas.Categorical.
:param validate_schema: Check that individual file schemas are all the
same / compatible. Schemas within a folder prefix should all be the
same. Disable if you have schemas that are different and want to
@@ -156,7 +153,6 @@ class Data:
:type path: Union[str, List[str]]
:type partition_filter: Callable[[Dict[str, str]], bool], optional
:type columns: List[str], optional
- :type categories: List[str], optional
:type validate_schema: bool, optional
:type last_modified_begin: datetime, optional
:type last_modified_end: datetime, optional
@@ -177,7 +173,6 @@ class Data:
use_threads=True,
dataset=True,
columns=columns,
- categories=categories,
partition_filter=partition_filter,
last_modified_begin=last_modified_begin,
last_modified_end=last_modified_end
@@ -234,7 +229,6 @@ class Data:
path=data_set["path"],
partition_filter=partition_filter,
columns=data_set.get("columns", None),
- categories=data_set.get("categories", None),
days=time_period
)
diff --git a/csit.infra.dash/app/cdash/data/data.yaml b/csit.infra.dash/app/cdash/data/data.yaml
index 975241b84e..8beee0bacc 100644
--- a/csit.infra.dash/app/cdash/data/data.yaml
+++ b/csit.infra.dash/app/cdash/data/data.yaml
@@ -7,9 +7,6 @@
- build
- start_time
- duration
- categories:
- - job
- - build
- data_type: trending
partition: test_type
partition_name: mrr
@@ -28,12 +25,6 @@
- result_receive_rate_rate_stdev
- result_receive_rate_rate_unit
- telemetry
- categories:
- - job
- - build
- - dut_type
- - dut_version
- - version
- data_type: trending
partition: test_type
partition_name: ndrpdr
@@ -63,12 +54,6 @@
- result_latency_forward_pdr_10_hdrh
- result_latency_forward_pdr_0_hdrh
- telemetry
- categories:
- - job
- - build
- - dut_type
- - dut_version
- - version
- data_type: trending
partition: test_type
partition_name: hoststack
@@ -91,13 +76,6 @@
- telemetry
- test_id
- version
- categories:
- - job
- - build
- - dut_type
- - dut_version
- - tg_type
- - version
- data_type: iterative
partition: test_type
partition_name: mrr
@@ -117,12 +95,6 @@
- result_receive_rate_rate_stdev
- result_receive_rate_rate_unit
- result_receive_rate_rate_values
- categories:
- - job
- - build
- - dut_type
- - dut_version
- - version
- data_type: iterative
partition: test_type
partition_name: mrr
@@ -142,12 +114,6 @@
- result_receive_rate_rate_stdev
- result_receive_rate_rate_unit
- result_receive_rate_rate_values
- categories:
- - job
- - build
- - dut_type
- - dut_version
- - version
- data_type: iterative
partition: test_type
partition_name: mrr
@@ -167,12 +133,6 @@
- result_receive_rate_rate_stdev
- result_receive_rate_rate_unit
- result_receive_rate_rate_values
- categories:
- - job
- - build
- - dut_type
- - dut_version
- - version
- data_type: iterative
partition: test_type
partition_name: ndrpdr
@@ -202,12 +162,6 @@
- result_latency_forward_pdr_50_unit
- result_latency_forward_pdr_10_hdrh
- result_latency_forward_pdr_0_hdrh
- categories:
- - job
- - build
- - dut_type
- - dut_version
- - version
- data_type: iterative
partition: test_type
partition_name: ndrpdr
@@ -237,12 +191,6 @@
- result_latency_forward_pdr_50_unit
- result_latency_forward_pdr_10_hdrh
- result_latency_forward_pdr_0_hdrh
- categories:
- - job
- - build
- - dut_type
- - dut_version
- - version
- data_type: iterative
partition: test_type
partition_name: ndrpdr
@@ -272,12 +220,6 @@
- result_latency_forward_pdr_50_unit
- result_latency_forward_pdr_10_hdrh
- result_latency_forward_pdr_0_hdrh
- categories:
- - job
- - build
- - dut_type
- - dut_version
- - version
- data_type: iterative
partition: test_type
partition_name: hoststack
@@ -301,13 +243,6 @@
- telemetry
- test_id
- version
- categories:
- - job
- - build
- - dut_type
- - dut_version
- - tg_type
- - version
- data_type: coverage
partition: test_type
partition_name: ndrpdr
@@ -335,30 +270,16 @@
- result_latency_forward_pdr_90_hdrh
- result_latency_forward_pdr_50_hdrh
- result_latency_forward_pdr_10_hdrh
- categories:
+- data_type: coverage
+ partition: test_type
+ partition_name: device
+ release: rls2302
+ path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2302
+ columns:
- job
- build
- dut_type
- dut_version
- - tg_type
+ - passed
+ - test_id
- version
-# - data_type: coverage
-# partition: test_type
-# partition_name: device
-# release: rls2302
-# path: s3://fdio-docs-s3-cloudfront-index/csit/parquet/coverage_rls2302
-# columns:
-# - job
-# - build
-# - dut_type
-# - dut_version
-# - start_time
-# - passed
-# - test_id
-# - version
-# categories:
-# - job
-# - build
-# - dut_type
-# - dut_version
-# - version
diff --git a/csit.infra.dash/app/cdash/report/layout.py b/csit.infra.dash/app/cdash/report/layout.py
index 8dbaea3508..1e79b68b5e 100644
--- a/csit.infra.dash/app/cdash/report/layout.py
+++ b/csit.infra.dash/app/cdash/report/layout.py
@@ -125,7 +125,7 @@ class Layout:
if dut == "dpdk":
area = "dpdk"
else:
- area = "-".join(lst_test_id[3:-2])
+ area = ".".join(lst_test_id[3:-2])
suite = lst_test_id[-2].replace("2n1l-", "").replace("1n1l-", "").\
replace("2n-", "")
test = lst_test_id[-1]
@@ -1312,7 +1312,7 @@ class Layout:
Input("plot-btn-download", "n_clicks"),
prevent_initial_call=True
)
- def _download_trending_data(store_sel, _):
+ def _download_iterative_data(store_sel, _):
"""Download the data
:param store_sel: List of tests selected by user stored in the
diff --git a/csit.infra.dash/app/cdash/trending/layout.py b/csit.infra.dash/app/cdash/trending/layout.py
index 411061470e..005d1dc141 100644
--- a/csit.infra.dash/app/cdash/trending/layout.py
+++ b/csit.infra.dash/app/cdash/trending/layout.py
@@ -119,7 +119,7 @@ class Layout:
if dut == "dpdk":
area = "dpdk"
else:
- area = "-".join(lst_test[3:-2])
+ area = ".".join(lst_test[3:-2])
suite = lst_test[-2].replace("2n1l-", "").replace("1n1l-", "").\
replace("2n-", "")
test = lst_test[-1]
diff --git a/csit.infra.dash/app/cdash/utils/constants.py b/csit.infra.dash/app/cdash/utils/constants.py
index e9c08d36e3..6ab80d0b5c 100644
--- a/csit.infra.dash/app/cdash/utils/constants.py
+++ b/csit.infra.dash/app/cdash/utils/constants.py
@@ -124,12 +124,23 @@ class Constants:
"lb": "Load Balancer",
"srv6": "SRv6 Routing",
"vm_vhost": "VMs vhost-user",
- "nfv_density-dcr_memif-chain_ipsec": "CNF Service Chains Routing IPSec",
- "nfv_density-vm_vhost-chain_dot1qip4vxlan":"VNF Service Chains Tunnels",
- "nfv_density-vm_vhost-chain": "VNF Service Chains Routing",
- "nfv_density-dcr_memif-pipeline": "CNF Service Pipelines Routing",
- "nfv_density-dcr_memif-chain": "CNF Service Chains Routing",
- "hoststack": "Hoststack"
+ "nfv_density.dcr_memif.chain_ipsec": "CNF Service Chains Routing IPSec",
+ "nfv_density.vm_vhost.chain_dot1qip4vxlan":"VNF Service Chains Tunnels",
+ "nfv_density.vm_vhost.chain": "VNF Service Chains Routing",
+ "nfv_density.dcr_memif.pipeline": "CNF Service Pipelines Routing",
+ "nfv_density.dcr_memif.chain": "CNF Service Chains Routing",
+ "hoststack": "Hoststack",
+ "flow": "Flow",
+ "l2bd": "L2 Bridge Domain",
+ "crypto.ethip4": "IPSec IPv4 Routing",
+ "crypto.ethip6": "IPSec IPv6 Routing",
+ "interfaces": "Interfaces",
+ "ip4_tunnels.lisp": "IPv4 Tunnels LISP",
+ "ip6_tunnels.lisp": "IPv6 Tunnels LISP",
+ "l2patch": "L2 Patch",
+ "l2xc": "L2 Cross Connect",
+ "vm_vhost.ethip4": "VMs vhost-user IPv4 Routing",
+ "vm_vhost.ethip6": "VMs vhost-user IPv6 Routing"
}
# URL style.