]> git.puffer.fish Git - mirror/frr.git/commitdiff
tests: adding ospfv3 base cases. 9262/head
authornguggarigoud <nguggarigoud@vmware.com>
Tue, 3 Aug 2021 01:18:29 +0000 (18:18 -0700)
committernguggarigoud <nguggarigoud@vmware.com>
Wed, 16 Mar 2022 02:58:51 +0000 (19:58 -0700)
Covers basic test case like route map, rte calc.

Signed-off-by: nguggarigoud <nguggarigoud@vmware.com>
17 files changed:
tests/topotests/lib/common_config.py
tests/topotests/lib/ospf.py
tests/topotests/lib/topotest.py
tests/topotests/ospfv3_basic_functionality/ospfv3_asbr_summary_type7_lsa.json [new file with mode: 0644]
tests/topotests/ospfv3_basic_functionality/ospfv3_dual_stack.json [new file with mode: 0644]
tests/topotests/ospfv3_basic_functionality/ospfv3_ecmp.json
tests/topotests/ospfv3_basic_functionality/ospfv3_ecmp_lan.json [new file with mode: 0644]
tests/topotests/ospfv3_basic_functionality/ospfv3_lan.json [new file with mode: 0644]
tests/topotests/ospfv3_basic_functionality/ospfv3_nssa2.json [new file with mode: 0644]
tests/topotests/ospfv3_basic_functionality/ospfv3_routemaps.json
tests/topotests/ospfv3_basic_functionality/ospfv3_rte_calc.json
tests/topotests/ospfv3_basic_functionality/test_ospfv3_asbr_summary_topo1.py
tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp_lan.py [new file with mode: 0644]
tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa2.py [new file with mode: 0644]
tests/topotests/ospfv3_basic_functionality/test_ospfv3_routemaps.py
tests/topotests/ospfv3_basic_functionality/test_ospfv3_rte_calc.py
tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py

index c0572fca4c1046f301bbc2e25bbef78ee2063c25..005896b01c0a3e0a9df0c43b349a4c95ae661331 100644 (file)
@@ -2536,6 +2536,7 @@ def create_route_maps(tgen, input_dict, build=False):
                         ipv6_data = set_data.setdefault("ipv6", {})
                         local_preference = set_data.setdefault("locPrf", None)
                         metric = set_data.setdefault("metric", None)
+                        metric_type = set_data.setdefault("metric-type", None)
                         as_path = set_data.setdefault("path", {})
                         weight = set_data.setdefault("weight", None)
                         community = set_data.setdefault("community", {})
@@ -2559,7 +2560,11 @@ def create_route_maps(tgen, input_dict, build=False):
 
                         # Metric
                         if metric:
-                            rmap_data.append("set metric {} \n".format(metric))
+                            del_comm = set_data.setdefault("delete", None)
+                            if del_comm:
+                                rmap_data.append("no set metric {}".format(metric))
+                            else:
+                                rmap_data.append("set metric {}".format(metric))
 
                         # Origin
                         if origin:
index 8d2bf12af296626733e762caa3420e841163108d..e7ea7d32ba79eac6bcade7c7b509e7ed8312dbe3 100644 (file)
@@ -1668,7 +1668,7 @@ def verify_ospf6_rib(
             logger.info("Checking router %s RIB:", router)
 
             # Verifying RIB routes
-            command = "show ipv6 ospf route"
+            command = "show ipv6 ospf route detail"
 
             found_routes = []
             missing_routes = []
@@ -1710,6 +1710,8 @@ def verify_ospf6_rib(
 
                     # Generating IPs for verification
                     ip_list = generate_ips(network, no_of_ip)
+                    if len(ip_list) == 1:
+                        ip_list = [network]
                     st_found = False
                     nh_found = False
                     for st_rt in ip_list:
@@ -1846,7 +1848,7 @@ def verify_ospf6_rib(
                                     return errormsg
 
                             if metric is not None:
-                                if "type2cost" not in ospf_rib_json[st_rt]:
+                                if "metricCostE2" not in ospf_rib_json[st_rt]:
                                     errormsg = (
                                         "[DUT: {}]: metric is"
                                         " not present for"
@@ -1854,7 +1856,7 @@ def verify_ospf6_rib(
                                     )
                                     return errormsg
 
-                                if metric != ospf_rib_json[st_rt]["type2cost"]:
+                                if metric != ospf_rib_json[st_rt]["metricCostE2"]:
                                     errormsg = (
                                         "[DUT: {}]: metric value "
                                         "{} is not matched for "
index 62b6a8a70e9dd183d42269a8ef8b3402cfc9943e..e786ae02cdf732a9e2d8571e31f3e07464d45965 100644 (file)
@@ -737,6 +737,7 @@ def proto_name_to_number(protocol):
         "sharp": "194",
         "pbr": "195",
         "static": "196",
+        "ospf6": "197",
     }.get(
         protocol, protocol
     )  # default return same as input
diff --git a/tests/topotests/ospfv3_basic_functionality/ospfv3_asbr_summary_type7_lsa.json b/tests/topotests/ospfv3_basic_functionality/ospfv3_asbr_summary_type7_lsa.json
new file mode 100644 (file)
index 0000000..27b36ae
--- /dev/null
@@ -0,0 +1,202 @@
+{
+    "address_types": [
+        "ipv6"
+    ],
+    "ipv6base": "fd00::",
+    "ipv6mask": 64,
+    "link_ip_start": {
+        "ipv6": "fd00::",
+        "v6mask": 64
+    },
+    "lo_prefix": {
+        "ipv6": "2001:db8:f::",
+        "v6mask": 128
+    },
+    "routers": {
+        "r0": {
+            "links": {
+                "lo": {
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r1": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.2",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r2": {
+                    "ipv6": "auto"
+                },
+                "r3": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "network": "point-to-point"
+                    }
+                }
+            },
+            "ospf6": {
+                "router_id": "100.1.1.0",
+                "area": [
+                    {
+                        "id": "0.0.0.2",
+                        "type": "nssa"
+                    }
+                ],
+                "neighbors": {
+                    "r1": {},
+                    "r3": {}
+                }
+            }
+        },
+        "r1": {
+            "links": {
+                "lo": {
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r0": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.2",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r2": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.2",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r3": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.2",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r3-link0": {
+                    "ipv6": "auto",
+                    "description": "DummyIntftoR3"
+                }
+            },
+            "ospf6": {
+                "router_id": "100.1.1.1",
+                "area": [
+                    {
+                        "id": "0.0.0.2",
+                        "type": "nssa"
+                    }
+                ],
+                "neighbors": {
+                    "r0": {},
+                    "r2": {},
+                    "r3": {}
+                }
+            }
+        },
+        "r2": {
+            "links": {
+                "lo": {
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r0": {
+                    "ipv6": "auto"
+                },
+                "r1": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.2",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r3": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.2",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                }
+            },
+            "ospf6": {
+                "router_id": "100.1.1.2",
+                "area": [
+                    {
+                        "id": "0.0.0.2",
+                        "type": "nssa"
+                    }
+                ],
+                "neighbors": {
+                    "r1": {},
+                    "r3": {}
+                }
+            }
+        },
+        "r3": {
+            "links": {
+                "lo": {
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r0": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "network": "point-to-point"
+                    }
+                },
+                "r1": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.2",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r2": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.2",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r1-link0": {
+                    "ipv6": "auto",
+                    "description": "DummyIntftoR1",
+                    "ospf6": {
+                        "area": "0.0.0.3"
+                    }
+                }
+            },
+            "ospf6": {
+                "router_id": "100.1.1.3",
+                "area": [
+                    {
+                        "id": "0.0.0.2",
+                        "type": "nssa"
+                    }
+                ],
+                "neighbors": {
+                    "r0": {},
+                    "r1": {},
+                    "r2": {}
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/topotests/ospfv3_basic_functionality/ospfv3_dual_stack.json b/tests/topotests/ospfv3_basic_functionality/ospfv3_dual_stack.json
new file mode 100644 (file)
index 0000000..5555d92
--- /dev/null
@@ -0,0 +1,312 @@
+{
+    "address_types": [
+        "ipv4",
+        "ipv6"
+    ],
+    "ipv4base": "10.0.0.0",
+    "ipv4mask": 30,
+    "ipv6base": "fd00::",
+    "ipv6mask": 64,
+    "link_ip_start": {
+        "ipv4": "10.0.0.0",
+        "v4mask": 30,
+        "ipv6": "fd00::",
+        "v6mask": 64
+    },
+    "lo_prefix": {
+        "ipv4": "1.0.",
+        "v4mask": 32,
+        "ipv6": "2001:db8:f::",
+        "v6mask": 128
+    },
+    "routers": {
+        "r0": {
+            "links": {
+                "lo": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r1": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    },
+                    "ospf": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r2": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    },
+                    "ospf": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r3": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "network": "point-to-point"
+                    },
+                    "ospf": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "network": "point-to-point"
+                    }
+                }
+            },
+            "ospf6": {
+                "router_id": "100.1.1.0",
+                "neighbors": {
+                    "r1": {},
+                    "r2": {},
+                    "r3": {}
+                }
+            },
+            "ospf": {
+                "router_id": "100.1.1.0",
+                "neighbors": {
+                    "r1": {},
+                    "r2": {},
+                    "r3": {}
+                }
+            }
+        },
+        "r1": {
+            "links": {
+                "lo": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r0": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    },
+                    "ospf": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r2": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    },
+                    "ospf": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r3": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    },
+                    "ospf": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r3-link0": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "description": "DummyIntftoR3"
+                }
+            },
+            "ospf6": {
+                "router_id": "100.1.1.1",
+                "neighbors": {
+                    "r0": {},
+                    "r2": {},
+                    "r3": {}
+                }
+            },
+            "ospf": {
+                "router_id": "100.1.1.1",
+                "neighbors": {
+                    "r0": {},
+                    "r2": {},
+                    "r3": {}
+                }
+            }
+        },
+        "r2": {
+            "links": {
+                "lo": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r0": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    },
+                    "ospf": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r1": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    },
+                    "ospf": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r3": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    },
+                    "ospf": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                }
+            },
+            "ospf6": {
+                "router_id": "100.1.1.2",
+                "neighbors": {
+                    "r1": {},
+                    "r0": {},
+                    "r3": {}
+                }
+            },
+            "ospf": {
+                "router_id": "100.1.1.2",
+                "neighbors": {
+                    "r1": {},
+                    "r0": {},
+                    "r3": {}
+                }
+            }
+        },
+        "r3": {
+            "links": {
+                "lo": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r0": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "network": "point-to-point"
+                    },
+                    "ospf": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "network": "point-to-point"
+                    }
+                },
+                "r1": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    },
+                    "ospf": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r2": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    },
+                    "ospf": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r1-link0": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "description": "DummyIntftoR1",
+                    "ospf6": {
+                        "area": "0.0.0.0"
+                    },
+                    "ospf": {
+                        "area": "0.0.0.0"
+                    }
+                }
+            },
+            "ospf6": {
+                "router_id": "1.0.4.17",
+                "neighbors": {
+                    "r0": {},
+                    "r1": {},
+                    "r2": {}
+                }
+            },
+            "ospf": {
+                "router_id": "100.1.1.3",
+                "neighbors": {
+                    "r0": {},
+                    "r1": {},
+                    "r2": {}
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
index c928093925f23a2f6423a5a9dd7a2526c33c89ed..22f46e2bf6893961c3d9b5ff8c04751ab08cf0d1 100644 (file)
@@ -2,6 +2,7 @@
     "address_types": [
         "ipv6"
     ],
+
     "ipv6base": "fd00::",
     "ipv6mask": 64,
     "link_ip_start": {
@@ -9,6 +10,7 @@
         "v6mask": 64
     },
     "lo_prefix": {
+
         "ipv6": "2001:db8:f::",
         "v6mask": 128
     },
@@ -21,6 +23,7 @@
                 },
                 "r1": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -29,6 +32,7 @@
                 },
                 "r1-link1": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -37,6 +41,7 @@
                 },
                 "r1-link2": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -45,6 +50,7 @@
                 },
                 "r1-link3": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -53,6 +59,7 @@
                 },
                 "r1-link4": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -61,6 +68,7 @@
                 },
                 "r1-link5": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -69,6 +77,7 @@
                 },
                 "r1-link6": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -77,6 +86,7 @@
                 },
                 "r1-link7": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -85,6 +95,7 @@
                 },
                 "r2": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r3": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                     }
                 }
             },
+
             "ospf6": {
                 "router_id": "100.1.1.0",
                 "neighbors": {
                 },
                 "r0": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r0-link1": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r0-link2": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r0-link3": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r0-link4": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r0-link5": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r0-link6": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r0-link7": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r2": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r3": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                     "description": "DummyIntftoR3"
                 }
             },
+
             "ospf6": {
                 "router_id": "100.1.1.1",
                 "neighbors": {
                 },
                 "r0": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r1": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r3": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                     }
                 }
             },
+
             "ospf6": {
                 "router_id": "100.1.1.2",
                 "neighbors": {
                 },
                 "r0": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r1": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r2": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 "r1-link0": {
                     "ipv6": "auto",
                     "description": "DummyIntftoR1",
-                    "ospf": {
-                        "area": "0.0.0.0"
-                    },
+
                     "ospf6": {
                         "area": "0.0.0.0"
                     }
                 }
             },
+
             "ospf6": {
                 "router_id": "100.1.1.3",
                 "neighbors": {
diff --git a/tests/topotests/ospfv3_basic_functionality/ospfv3_ecmp_lan.json b/tests/topotests/ospfv3_basic_functionality/ospfv3_ecmp_lan.json
new file mode 100644 (file)
index 0000000..53b3f49
--- /dev/null
@@ -0,0 +1,264 @@
+{
+    "address_types": [
+        "ipv6"
+    ],
+    "ipv6base": "fd00::",
+    "ipv6mask": 64,
+    "link_ip_start": {
+        "ipv6": "fd00::",
+        "v6mask": 64
+    },
+    "lo_prefix": {
+        "ipv6": "2001:db8:f::",
+        "v6mask": 128
+    },
+    "switches": {
+        "s1": {
+            "links": {
+                "r0": {
+
+                    "ipv6": "auto",
+
+                    "ospf6": {
+                        "area": "0.0.0.3",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "priority": 98
+                    }
+                },
+                "r1": {
+
+                    "ipv6": "auto",
+
+                    "ospf6": {
+                        "area": "0.0.0.3",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "priority": 99
+                    }
+                },
+                "r2": {
+
+                    "ipv6": "auto",
+
+                    "ospf6": {
+                        "area": "0.0.0.3",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "priority": 0
+                    }
+                },
+                "r3": {
+
+                    "ipv6": "auto",
+
+                    "ospf6": {
+                        "area": "0.0.0.3",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "priority": 0
+                    }
+                },
+                "r4": {
+
+                    "ipv6": "auto",
+
+                    "ospf6": {
+                        "area": "0.0.0.3",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "priority": 0
+                    }
+                },
+                "r5": {
+
+                    "ipv6": "auto",
+
+                    "ospf6": {
+                        "area": "0.0.0.3",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "priority": 0
+                    }
+                },
+                "r6": {
+
+                    "ipv6": "auto",
+
+                    "ospf6": {
+                        "area": "0.0.0.3",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "priority": 0
+                    }
+                },
+                "r7": {
+
+                    "ipv6": "auto",
+
+                    "ospf6": {
+                        "area": "0.0.0.3",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "priority": 0
+                    }
+                }
+            }
+        }
+    },
+    "routers": {
+        "r0": {
+            "links": {
+                "lo": {
+
+                    "ipv6": "auto",
+                    "type": "loopback"
+                }
+            },
+            "ospf6": {
+                "router_id": "100.1.1.0",
+                "neighbors": {
+                    "r1": {},
+                    "r2": {},
+                    "r3": {},
+                    "r4": {},
+                    "r5": {},
+                    "r6": {},
+                    "r7": {}
+                }
+            }
+        },
+        "r1": {
+            "links": {
+                "lo": {
+
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r3-link0": {
+
+                    "ipv6": "auto",
+                    "description": "DummyIntftoR3"
+                }
+            },
+            "ospf6": {
+                "router_id": "100.1.1.1",
+                "neighbors": {
+                    "r0": {},
+                    "r2": {},
+                    "r3": {},
+                    "r4": {},
+                    "r5": {},
+                    "r6": {},
+                    "r7": {}
+                }
+            }
+        },
+        "r2": {
+            "links": {
+                "lo": {
+
+                    "ipv6": "auto",
+                    "type": "loopback"
+                }
+            },
+            "ospf6": {
+                "router_id": "100.1.1.2",
+                "neighbors": {
+                    "r1": {},
+                    "r0": {}
+                }
+            }
+        },
+        "r3": {
+            "links": {
+                "lo": {
+
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r1-link0": {
+
+                    "ipv6": "auto",
+                    "description": "DummyIntftoR1"
+
+                }
+            },
+
+            "ospf6": {
+                "router_id": "100.1.1.3",
+                "neighbors": {
+                    "r0": {},
+                    "r1": {}
+                }
+            }
+        },
+        "r4": {
+            "links": {
+                "lo": {
+
+                    "ipv6": "auto",
+                    "type": "loopback"
+                }
+            },
+
+            "ospf6": {
+                "router_id": "100.1.1.4",
+                "neighbors": {
+                    "r0": {},
+                    "r1": {}
+                }
+            }
+        },
+        "r5": {
+            "links": {
+                "lo": {
+
+                    "ipv6": "auto",
+                    "type": "loopback"
+                }
+            },
+            "ospf6": {
+                "router_id": "100.1.1.5",
+                "neighbors": {
+                    "r0": {},
+                    "r1": {}
+                }
+            }
+        },
+        "r6": {
+            "links": {
+                "lo": {
+
+                    "ipv6": "auto",
+                    "type": "loopback"
+                }
+            },
+
+            "ospf6": {
+                "router_id": "100.1.1.6",
+                "neighbors": {
+                    "r0": {},
+                    "r1": {}
+                }
+            }
+        },
+        "r7": {
+            "links": {
+                "lo": {
+
+                    "ipv6": "auto",
+                    "type": "loopback"
+                }
+            },
+
+            "ospf6": {
+                "router_id": "100.1.1.7",
+                "neighbors": {
+                    "r0": {},
+                    "r1": {}
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/topotests/ospfv3_basic_functionality/ospfv3_lan.json b/tests/topotests/ospfv3_basic_functionality/ospfv3_lan.json
new file mode 100644 (file)
index 0000000..3a2fc02
--- /dev/null
@@ -0,0 +1,140 @@
+{
+    "address_types": [
+        "ipv6"
+    ],
+
+    "ipv6base": "fd00::",
+    "ipv6mask": 64,
+    "link_ip_start": {
+
+        "ipv6": "fd00::",
+        "v6mask": 64
+    },
+    "lo_prefix": {
+
+        "ipv6": "2001:db8:f::",
+        "v6mask": 128
+    },
+    "switches": {
+        "s1": {
+            "links": {
+                "r0": {
+                    "ipv6": "auto",
+
+                    "ospf6": {
+                        "area": "0.0.0.3",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "priority": 98
+                    }
+                },
+                "r1": {
+                    "ipv6": "auto",
+
+                    "ospf6": {
+                        "area": "0.0.0.3",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "priority": 99
+                    }
+                },
+                "r2": {
+                    "ipv6": "auto",
+
+                    "ospf6": {
+                        "area": "0.0.0.3",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "priority": 0
+                    }
+                },
+                "r3": {
+                    "ipv6": "auto",
+
+                    "ospf6": {
+                        "area": "0.0.0.3",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "priority": 0
+                    }
+                }
+            }
+        }
+    },
+    "routers": {
+        "r0": {
+            "links": {
+                "lo": {
+                    "ipv6": "auto",
+                    "type": "loopback"
+                }
+            },
+
+            "ospf6": {
+                "router_id": "100.1.1.0",
+                "neighbors": {
+                    "r1": {},
+                    "r2": {},
+                    "r3": {}
+                }
+            }
+        },
+        "r1": {
+            "links": {
+                "lo": {
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r3-link0": {
+                    "ipv6": "auto",
+                    "description": "DummyIntftoR3"
+                }
+            },
+
+            "ospf6": {
+                "router_id": "100.1.1.1",
+                "neighbors": {
+                    "r0": {},
+                    "r2": {},
+                    "r3": {}
+                }
+            }
+        },
+        "r2": {
+            "links": {
+                "lo": {
+                    "ipv6": "auto",
+                    "type": "loopback"
+                }
+            },
+
+            "ospf6": {
+                "router_id": "100.1.1.2",
+                "neighbors": {
+                    "r1": {},
+                    "r0": {}
+                }
+            }
+        },
+        "r3": {
+            "links": {
+                "lo": {
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r1-link0": {
+                    "ipv6": "auto",
+                    "description": "DummyIntftoR1"
+                }
+            },
+
+            "ospf6": {
+                "router_id": "100.1.1.3",
+                "neighbors": {
+                    "r0": {},
+                    "r1": {}
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/topotests/ospfv3_basic_functionality/ospfv3_nssa2.json b/tests/topotests/ospfv3_basic_functionality/ospfv3_nssa2.json
new file mode 100644 (file)
index 0000000..b1432b9
--- /dev/null
@@ -0,0 +1,197 @@
+
+{
+    "address_types": [
+        "ipv6"
+    ],
+    "ipv6base": "fd00::",
+    "ipv6mask": 64,
+    "link_ip_start": {
+        "ipv6": "fd00::",
+        "v6mask": 64
+    },
+    "lo_prefix": {
+        "ipv6": "2001:db8:f::",
+        "v6mask": 128
+    },
+    "routers": {
+        "r0": {
+            "links": {
+                "lo": {
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r1": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r2": {
+                    "ipv6": "auto"
+                },
+                "r3": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "network": "point-to-point"
+                    }
+                }
+            },
+            "ospf6": {
+                "router_id": "100.1.1.0",
+                "neighbors": {
+                    "r1": {},
+                    "r3": {}
+                }
+            }
+        },
+        "r1": {
+            "links": {
+                "lo": {
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r0": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r2": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.2",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r3": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.2",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r3-link0": {
+                    "ipv6": "auto",
+                    "description": "DummyIntftoR3"
+                }
+            },
+            "ospf6": {
+                "router_id": "100.1.1.1",
+                "area": [
+                    {
+                        "id": "0.0.0.2",
+                        "type": "nssa"
+                    }
+                ],
+                "neighbors": {
+                    "r0": {},
+                    "r2": {},
+                    "r3": {}
+                }
+            }
+        },
+        "r2": {
+            "links": {
+                "lo": {
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r0": {
+                    "ipv6": "auto"
+                },
+                "r1": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.2",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r3": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.2",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                }
+            },
+            "ospf6": {
+                "router_id": "100.1.1.2",
+                "area": [
+                    {
+                        "id": "0.0.0.2",
+                        "type": "nssa"
+                    }
+                ],
+                "neighbors": {
+                    "r1": {},
+                    "r3": {}
+                }
+            }
+        },
+        "r3": {
+            "links": {
+                "lo": {
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r0": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.0",
+                        "hello_interval": 1,
+                        "dead_interval": 4,
+                        "network": "point-to-point"
+                    }
+                },
+                "r1": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.2",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r2": {
+                    "ipv6": "auto",
+                    "ospf6": {
+                        "area": "0.0.0.2",
+                        "hello_interval": 1,
+                        "dead_interval": 4
+                    }
+                },
+                "r1-link0": {
+                    "ipv6": "auto",
+                    "description": "DummyIntftoR1",
+                    "ospf6": {
+                        "area": "0.0.0.3"
+                    }
+                }
+            },
+            "ospf6": {
+                "router_id": "100.1.1.3",
+                "area": [
+                    {
+                        "id": "0.0.0.2",
+                        "type": "nssa"
+                    }
+                ],
+                "neighbors": {
+                    "r0": {},
+                    "r1": {},
+                    "r2": {}
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
index 226f84f3206ee38db9a49d882dbec442d46fc351..a1c7bd72d4acbd36f69ab0d4cf4db5059550e3aa 100644 (file)
@@ -1,14 +1,26 @@
 {
-    "address_types": ["ipv6"],
+    "address_types": [
+        "ipv6"
+    ],
+
     "ipv6base": "fd00::",
     "ipv6mask": 64,
-    "link_ip_start": {"ipv6": "fd00::", "v6mask": 64},
-    "lo_prefix": {"ipv6": "2001:db8:f::", "v6mask": 128},
+    "link_ip_start": {
+
+        "ipv6": "fd00::",
+        "v6mask": 64
+    },
+    "lo_prefix": {
+
+        "ipv6": "2001:db8:f::",
+        "v6mask": 128
+    },
     "routers": {
         "r0": {
             "links": {
                 "r1": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -17,6 +29,7 @@
                 },
                 "r2": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -25,6 +38,7 @@
                 },
                 "r3": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                     }
                 }
             },
+
             "ospf6": {
                 "router_id": "100.1.1.0",
-                "neighbors": {"r1": {}, "r2": {}, "r3": {}}
+                "neighbors": {
+                    "r1": {},
+                    "r2": {},
+                    "r3": {}
+                }
             }
         },
         "r1": {
             "links": {
                 "r0": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -49,6 +69,7 @@
                 },
                 "r2": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -57,6 +78,7 @@
                 },
                 "r3": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                     }
                 }
             },
+
             "ospf6": {
                 "router_id": "100.1.1.1",
-                "neighbors": {"r0": {}, "r2": {}, "r3": {}}
+                "neighbors": {
+                    "r0": {},
+                    "r2": {},
+                    "r3": {}
+                }
             }
         },
         "r2": {
             "links": {
                 "r0": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r1": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r3": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                     }
                 }
             },
+
             "ospf6": {
                 "router_id": "100.1.1.2",
-                "neighbors": {"r1": {}, "r0": {}, "r3": {}}
+                "neighbors": {
+                    "r1": {},
+                    "r0": {},
+                    "r3": {}
+                }
             }
         },
         "r3": {
             "links": {
                 "r0": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r1": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r2": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                     }
                 }
             },
+
             "ospf6": {
                 "router_id": "100.1.1.3",
-                "neighbors": {"r0": {}, "r1": {}, "r2": {}}
+                "neighbors": {
+                    "r0": {},
+                    "r1": {},
+                    "r2": {}
+                }
             }
         }
     }
-}
+}
\ No newline at end of file
index 3669b3a554c9f5a831d45798e34049a30a82fee3..e70481ace9c47d1195e5168f1aaf73c1bc91f91a 100644 (file)
@@ -5,13 +5,16 @@
     "address_types": [
         "ipv6"
     ],
+
     "ipv6base": "fd00::",
     "ipv6mask": 64,
     "link_ip_start": {
+
         "ipv6": "fd00::",
         "v6mask": 64
     },
     "lo_prefix": {
+
         "ipv6": "2001:db8:f::",
         "v6mask": 128
     },
@@ -24,6 +27,7 @@
                 },
                 "r1": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -32,6 +36,7 @@
                 },
                 "r2": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -40,6 +45,7 @@
                 },
                 "r3": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -47,6 +53,7 @@
                     }
                 }
             },
+
             "ospf6": {
                 "router_id": "100.1.1.0",
                 "neighbors": {
@@ -63,6 +70,7 @@
                 },
                 "r0": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -71,6 +79,7 @@
                 },
                 "r2": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -79,6 +88,7 @@
                 },
                 "r3": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
@@ -86,6 +96,7 @@
                     }
                 }
             },
+
             "ospf6": {
                 "router_id": "100.1.1.1",
                 "neighbors": {
                 },
                 "r0": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r1": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r3": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                     }
                 }
             },
+
             "ospf6": {
                 "router_id": "100.1.1.2",
                 "neighbors": {
                 },
                 "r1": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
                 },
                 "r2": {
                     "ipv6": "auto",
+
                     "ospf6": {
                         "area": "0.0.0.0",
                         "hello_interval": 1,
index 47333fcb397ad6fc325ec2f2d8ea13cdea00137e..10c51a67847402cc9e884f25a444ce444857f599 100644 (file)
@@ -56,6 +56,7 @@ from lib.common_config import (
     create_prefix_lists,
     create_route_maps,
     topo_daemons,
+    create_interfaces_cfg,
 )
 from lib.topolog import logger
 from lib.topojson import build_config_from_json
@@ -747,6 +748,1084 @@ def test_ospfv3_type5_summary_tc42_p0(request):
     write_test_footer(tc_name)
 
 
+def test_ospfv3_type5_summary_tc43_p0(request):
+    """OSPF summarisation with metric type 2."""
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    global topo
+    step("Bring up the base config as per the topology")
+    reset_config_on_routers(tgen)
+
+    protocol = "ospf"
+
+    step(
+        "Configure 5 static routes from the same network on R0"
+        "5 static routes from different networks and redistribute in R0"
+    )
+    input_dict_static_rtes = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"], "next_hop": "blackhole"},
+                {"network": NETWORK2["ipv6"], "next_hop": "blackhole"},
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict_static_rtes)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    dut = "r0"
+    red_static(dut)
+
+    step("Verify that routes are learnt on R1.")
+    dut = "r1"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict_static_rtes)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+    result = verify_rib(tgen, "ipv6", dut, input_dict_static_rtes, protocol=protocol)
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+
+    step(
+        "Configure External Route summary in R0 to summarise 5" " routes to one route."
+    )
+    ospf_summ_r1 = {
+        "r0": {
+            "ospf6": {
+                "summary-address": [
+                    {"prefix": SUMMARY["ipv6"][0].split("/")[0], "mask": "32"}
+                ]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_summ_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+    step(
+        "Verify that external routes are summarised to configured summary "
+        "address on R0 after 5 secs of delay timer expiry and only one "
+        "route is sent to R1."
+    )
+    input_dict_summary = {"r0": {"static_routes": [{"network": SUMMARY["ipv6"][0]}]}}
+    dut = "r1"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict_summary)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+
+    step("Verify that show ip ospf summary should show the summaries.")
+    input_dict = {
+        SUMMARY["ipv6"][0]: {
+            "Summary address": SUMMARY["ipv6"][0],
+            "Metric-type": "E2",
+            "Metric": 20,
+            "Tag": 0,
+            "External route count": 5,
+        }
+    }
+    dut = "r0"
+    result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+
+    step("Change the summary address mask to lower match (ex - 16 to 8)")
+    ospf_summ_r1 = {
+        "r0": {
+            "ospf6": {
+                "summary-address": [
+                    {"prefix": SUMMARY["ipv6"][0].split("/")[0], "mask": "16"},
+                    {
+                        "prefix": SUMMARY["ipv6"][0].split("/")[0],
+                        "mask": "32",
+                        "delete": True,
+                    },
+                ]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_summ_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    sleep(5)
+
+    input_dict = {
+        "2011::/16": {
+            "Summary address": "2011::/16",
+            "Metric-type": "E2",
+            "Metric": 20,
+            "Tag": 0,
+            "External route count": 5,
+        }
+    }
+    dut = "r0"
+    result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+
+    step(
+        "Verify that external routes(static / connected) are summarised"
+        " to configured summary address with newly configured mask."
+    )
+
+    input_dict_summary = {"r0": {"static_routes": [{"network": "2011::0/16"}]}}
+    dut = "r1"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict_summary)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+
+    step("Change the summary address mask to higher match (ex - 8 to 24)")
+    ospf_summ_r1 = {
+        "r0": {
+            "ospf6": {
+                "summary-address": [
+                    {"prefix": SUMMARY["ipv6"][0].split("/")[0], "mask": "32"}
+                ]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_summ_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    input_dict = {
+        "2011::/32": {
+            "Summary address": "2011::/32",
+            "Metric-type": "E2",
+            "Metric": 20,
+            "Tag": 0,
+            "External route count": 0,
+        }
+    }
+    dut = "r0"
+    result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+
+    step(
+        "Verify that external routes(static / connected) are summarised"
+        " to configured summary address with newly configured mask."
+    )
+    step("Configure 2 summary address with different mask of same network.")
+    step(
+        "Verify that external routes(static / connected) are summarised "
+        "to configured summary address with highest match."
+    )
+
+    input_dict_summary = {"r0": {"static_routes": [{"network": "2011::0/32"}]}}
+    dut = "r1"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict_summary)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+
+    step(" Un configure one of the summary address.")
+    ospf_summ_r1 = {
+        "r0": {
+            "ospf6": {
+                "summary-address": [
+                    {
+                        "prefix": SUMMARY["ipv6"][0].split("/")[0],
+                        "mask": "32",
+                        "delete": True,
+                    }
+                ]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_summ_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    sleep(5)
+
+    step(
+        "Verify that external routes(static / connected) are summarised"
+        " to configured summary address with newly configured mask."
+    )
+
+    input_dict_summary = {"r0": {"static_routes": [{"network": "2011::0/16"}]}}
+    dut = "r1"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict_summary)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+
+    ospf_summ_r1 = {
+        "r0": {
+            "ospf6": {
+                "summary-address": [
+                    {"prefix": SUMMARY["ipv6"][0].split("/")[0], "mask": "16"}
+                ]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_summ_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "Verify that external routes(static / connected) are summarised "
+        "to configured summary address with highest match."
+    )
+    input_dict_summary = {"r0": {"static_routes": [{"network": "2011::0/16"}]}}
+    dut = "r1"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict_summary)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+
+    write_test_footer(tc_name)
+
+
+def ospfv3_type5_summary_tc45_p0(request):
+    """OSPF summarisation with Tag option"""
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    global topo
+    step("Bring up the base config as per the topology")
+    step("Configure OSPF on all the routers of the topology.")
+    reset_config_on_routers(tgen)
+
+    protocol = "ospf"
+
+    step(
+        "Configure 5 static routes from the same network on R0"
+        "5 static routes from different networks and redistribute in R0"
+    )
+    input_dict_static_rtes = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"], "next_hop": "blackhole"},
+                {"network": NETWORK2["ipv6"], "next_hop": "blackhole"},
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict_static_rtes)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    dut = "r0"
+    red_static(dut)
+
+    step("Verify that routes are learnt on R1.")
+    dut = "r1"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict_static_rtes)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+    result = verify_rib(tgen, "ipv6", dut, input_dict_static_rtes, protocol=protocol)
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+
+    step(
+        "Configure External Route summary in R0 to summarise 5" " routes to one route."
+    )
+    ospf_summ_r1 = {
+        "r0": {
+            "ospf6": {
+                "summary-address": [
+                    {
+                        "prefix": SUMMARY["ipv6"][0].split("/")[0],
+                        "mask": "32",
+                        "tag": "1234",
+                    }
+                ]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_summ_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "Verify that external routes are summarised to configured summary"
+        " address on R0 and only one route is sent to R1 with configured tag."
+    )
+    input_dict_summary = {
+        "r0": {"static_routes": [{"network": SUMMARY["ipv6"][0], "tag": "1234"}]}
+    }
+    dut = "r1"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict_summary)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+
+    step("Verify that show ip ospf summary should show the summaries with tag.")
+    input_dict = {
+        SUMMARY["ipv6"][0]: {
+            "Summary address": SUMMARY["ipv6"][0],
+            "Metric-type": "E2",
+            "Metric": 20,
+            "Tag": 1234,
+            "External route count": 5,
+        }
+    }
+    dut = "r0"
+    result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+
+    step("Delete the configured summary")
+    ospf_summ_r1 = {
+        "r0": {
+            "ospf6": {
+                "summary-address": [
+                    {
+                        "prefix": SUMMARY["ipv6"][0].split("/")[0],
+                        "mask": "32",
+                        "tag": "1234",
+                        "delete": True,
+                    }
+                ]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_summ_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Verify that summary lsa is withdrawn from R1 and deleted from R0.")
+    dut = "r1"
+    result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+        tc_name, result
+    )
+
+    result = verify_rib(
+        tgen, "ipv6", dut, input_dict_summary, protocol=protocol, expected=False
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed" "Error: Summary Route still present in RIB".format(
+        tc_name
+    )
+
+    step("show ip ospf summary should not have any summary address.")
+    input_dict = {
+        SUMMARY["ipv6"][0]: {
+            "Summary address": SUMMARY["ipv6"][0],
+            "Metric-type": "E2",
+            "Metric": 20,
+            "Tag": 1234,
+            "External route count": 5,
+        }
+    }
+    dut = "r0"
+    result = verify_ospf_summary(
+        tgen, topo, dut, input_dict, ospf="ospf6", expected=False
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed" "Error: Summary still present in DB".format(tc_name)
+
+    step("Configure Min tag value")
+    ospf_summ_r1 = {
+        "r0": {
+            "ospf6": {
+                "summary-address": [
+                    {"prefix": SUMMARY["ipv6"][0].split("/")[0], "mask": "32", "tag": 1}
+                ]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_summ_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+    input_dict_summary = {
+        "r0": {"static_routes": [{"network": SUMMARY["ipv6"][0], "tag": "1"}]}
+    }
+    dut = "r1"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict_summary)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+
+    step("Verify that show ip ospf summary should show the summaries with tag.")
+    input_dict = {
+        SUMMARY["ipv6"][0]: {
+            "Summary address": SUMMARY["ipv6"][0],
+            "Metric-type": "E2",
+            "Metric": 20,
+            "Tag": 1,
+            "External route count": 5,
+        }
+    }
+    dut = "r0"
+    result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+
+    step("Configure Max Tag Value")
+    ospf_summ_r1 = {
+        "r0": {
+            "ospf6": {
+                "summary-address": [
+                    {
+                        "prefix": SUMMARY["ipv6"][0].split("/")[0],
+                        "mask": "32",
+                        "tag": 4294967295,
+                    }
+                ]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_summ_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    input_dict_summary = {
+        "r0": {"static_routes": [{"network": SUMMARY["ipv6"][0], "tag": "4294967295"}]}
+    }
+    dut = "r1"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict_summary)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+
+    step(
+        "Verify that boundary values tags are used for summary route"
+        " using show ip ospf route command."
+    )
+    input_dict = {
+        SUMMARY["ipv6"][0]: {
+            "Summary address": SUMMARY["ipv6"][0],
+            "Metric-type": "E2",
+            "Metric": 20,
+            "Tag": 4294967295,
+            "External route count": 5,
+        }
+    }
+    dut = "r0"
+    result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+
+    step("configure new static route with different tag.")
+    input_dict_static_rtes_11 = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK_11["ipv6"], "next_hop": "blackhole", "tag": "88888"}
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict_static_rtes_11)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("New tag has not been used by summary address.")
+
+    input_dict_summary = {
+        "r0": {"static_routes": [{"network": SUMMARY["ipv6"][0], "tag": "88888"}]}
+    }
+    dut = "r1"
+
+    result = verify_ospf6_rib(
+        tgen, dut, input_dict_summary, tag="88888", expected=False
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+        tc_name, result
+    )
+
+    result = verify_rib(
+        tgen,
+        "ipv6",
+        dut,
+        input_dict_summary,
+        protocol=protocol,
+        tag="88888",
+        expected=False,
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+
+    step(
+        "Verify that boundary values tags are used for summary route"
+        " using show ip ospf route command."
+    )
+    input_dict = {
+        SUMMARY["ipv6"][0]: {
+            "Summary address": SUMMARY["ipv6"][0],
+            "Metric-type": "E2",
+            "Metric": 20,
+            "Tag": 88888,
+            "External route count": 5,
+        }
+    }
+    dut = "r0"
+    result = verify_ospf_summary(
+        tgen, topo, dut, input_dict, ospf="ospf6", expected=False
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+
+    step("Delete the configured summary address")
+    ospf_summ_r1 = {
+        "r0": {
+            "ospf6": {
+                "summary-address": [
+                    {
+                        "prefix": SUMMARY["ipv6"][0].split("/")[0],
+                        "mask": "32",
+                        "tag": 4294967295,
+                        "delete": True,
+                    }
+                ]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_summ_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "Verify that 6 routes are advertised to neighbour with 5 routes"
+        " without any tag, 1 route with tag."
+    )
+
+    dut = "r1"
+    result = verify_ospf6_rib(tgen, dut, input_dict_static_rtes)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+    result = verify_rib(tgen, "ipv6", dut, input_dict_static_rtes, protocol=protocol)
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+
+    step("Verify that summary address is flushed from neighbor.")
+
+    dut = "r1"
+    result = verify_ospf6_rib(tgen, dut, input_dict_summary, expected=False)
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+        tc_name, result
+    )
+
+    result = verify_rib(
+        tgen, "ipv6", dut, input_dict_summary, protocol=protocol, expected=False
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+
+    step("Configure summary first & then configure matching static route.")
+
+    input_dict_static_rtes = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"], "next_hop": "blackhole", "delete": True},
+                {"network": NETWORK2["ipv6"], "next_hop": "blackhole", "delete": True},
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict_static_rtes)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    ospf_summ_r1 = {
+        "r0": {
+            "ospf6": {
+                "summary-address": [
+                    {"prefix": SUMMARY["ipv6"][0].split("/")[0], "mask": "32"}
+                ]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_summ_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    input_dict_static_rtes = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"], "next_hop": "blackhole"},
+                {"network": NETWORK2["ipv6"], "next_hop": "blackhole"},
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict_static_rtes)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Repeat steps 1 to 10 of summarisation in non Back bone area.")
+    reset_config_on_routers(tgen)
+
+    step("Change the area id on the interface on R0")
+    input_dict = {
+        "r0": {
+            "links": {
+                "r1": {
+                    "interface": topo["routers"]["r0"]["links"]["r1"]["interface"],
+                    "ospf6": {"area": "0.0.0.0"},
+                    "delete": True,
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, input_dict)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+    input_dict = {
+        "r0": {
+            "links": {
+                "r1": {
+                    "interface": topo["routers"]["r0"]["links"]["r1"]["interface"],
+                    "ospf6": {"area": "0.0.0.1"},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, input_dict)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+    step("Change the area id on the interface  ")
+    input_dict = {
+        "r1": {
+            "links": {
+                "r0": {
+                    "interface": topo["routers"]["r1"]["links"]["r0"]["interface"],
+                    "ospf6": {"area": "0.0.0.0"},
+                    "delete": True,
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, input_dict)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+    input_dict = {
+        "r1": {
+            "links": {
+                "r0": {
+                    "interface": topo["routers"]["r1"]["links"]["r0"]["interface"],
+                    "ospf6": {"area": "0.0.0.1"},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, input_dict)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo)
+    assert ospf_covergence is True, "Testcase {} :Failed \n Error: {}".format(
+        tc_name, ospf_covergence
+    )
+
+    step(
+        "Configure 5 static routes from the same network on R0"
+        "5 static routes from different networks and redistribute in R0"
+    )
+    input_dict_static_rtes = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"], "next_hop": "blackhole"},
+                {"network": NETWORK2["ipv6"], "next_hop": "blackhole"},
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict_static_rtes)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    dut = "r0"
+    red_static(dut)
+
+    step("Verify that routes are learnt on R1.")
+    dut = "r1"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict_static_rtes)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+    result = verify_rib(tgen, "ipv6", dut, input_dict_static_rtes, protocol=protocol)
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+
+    step(
+        "Configure External Route summary in R0 to summarise 5" " routes to one route."
+    )
+    ospf_summ_r1 = {
+        "r0": {
+            "ospf6": {
+                "summary-address": [
+                    {
+                        "prefix": SUMMARY["ipv6"][0].split("/")[0],
+                        "mask": "32",
+                        "tag": "1234",
+                    }
+                ]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_summ_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "Verify that external routes are summarised to configured summary"
+        " address on R0 and only one route is sent to R1 with configured tag."
+    )
+    input_dict_summary = {
+        "r0": {"static_routes": [{"network": SUMMARY["ipv6"][0], "tag": "1234"}]}
+    }
+    dut = "r1"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict_summary)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+
+    step("Verify that show ip ospf summary should show the summaries with tag.")
+    input_dict = {
+        SUMMARY["ipv6"][0]: {
+            "Summary address": SUMMARY["ipv6"][0],
+            "Metric-type": "E2",
+            "Metric": 20,
+            "Tag": 1234,
+            "External route count": 5,
+        }
+    }
+    dut = "r0"
+    result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Delete the configured summary")
+    ospf_summ_r1 = {
+        "r0": {
+            "ospf6": {
+                "summary-address": [
+                    {
+                        "prefix": SUMMARY["ipv6"][0].split("/")[0],
+                        "mask": "32",
+                        "delete": True,
+                    }
+                ]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_summ_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Verify that summary lsa is withdrawn from R1 and deleted from R0.")
+    dut = "r1"
+    result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+        tc_name, result
+    )
+
+    result = verify_rib(
+        tgen, "ipv6", dut, input_dict_summary, protocol=protocol, expected=False
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed" "Error: Summary Route still present in RIB".format(
+        tc_name
+    )
+
+    step("show ip ospf summary should not have any summary address.")
+    input_dict = {
+        SUMMARY["ipv6"][0]: {
+            "Summary address": SUMMARY["ipv6"][0],
+            "Metric-type": "E2",
+            "Metric": 20,
+            "Tag": 1234,
+            "External route count": 5,
+        }
+    }
+    dut = "r0"
+    result = verify_ospf_summary(
+        tgen, topo, dut, input_dict, ospf="ospf6", expected=False
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed" "Error: Summary still present in DB".format(tc_name)
+
+    step("Configure Min tag value")
+    ospf_summ_r1 = {
+        "r0": {
+            "ospf6": {
+                "summary-address": [
+                    {"prefix": SUMMARY["ipv6"][0].split("/")[0], "mask": "32", "tag": 1}
+                ]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_summ_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+    input_dict_summary = {
+        "r0": {"static_routes": [{"network": SUMMARY["ipv6"][0], "tag": "1"}]}
+    }
+    dut = "r1"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict_summary)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+
+    step("Verify that show ip ospf summary should show the summaries with tag.")
+    input_dict = {
+        SUMMARY["ipv6"][0]: {
+            "Summary address": SUMMARY["ipv6"][0],
+            "Metric-type": "E2",
+            "Metric": 20,
+            "Tag": 1,
+            "External route count": 5,
+        }
+    }
+    dut = "r0"
+    result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+
+    step("Configure Max Tag Value")
+    ospf_summ_r1 = {
+        "r0": {
+            "ospf6": {
+                "summary-address": [
+                    {
+                        "prefix": SUMMARY["ipv6"][0].split("/")[0],
+                        "mask": "32",
+                        "tag": 4294967295,
+                    }
+                ]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_summ_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    input_dict_summary = {
+        "r0": {"static_routes": [{"network": SUMMARY["ipv6"][0], "tag": "4294967295"}]}
+    }
+    dut = "r1"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict_summary)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+
+    step(
+        "Verify that boundary values tags are used for summary route"
+        " using show ip ospf route command."
+    )
+    input_dict = {
+        SUMMARY["ipv6"][0]: {
+            "Summary address": SUMMARY["ipv6"][0],
+            "Metric-type": "E2",
+            "Metric": 20,
+            "Tag": 4294967295,
+            "External route count": 5,
+        }
+    }
+    dut = "r0"
+    result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+
+    step("configure new static route with different tag.")
+    input_dict_static_rtes_11 = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK_11["ipv6"], "next_hop": "blackhole", "tag": "88888"}
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict_static_rtes_11)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("New tag has not been used by summary address.")
+
+    input_dict_summary = {
+        "r0": {"static_routes": [{"network": SUMMARY["ipv6"][0], "tag": "88888"}]}
+    }
+    dut = "r1"
+
+    result = verify_ospf6_rib(
+        tgen, dut, input_dict_summary, tag="88888", expected=False
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+        tc_name, result
+    )
+
+    result = verify_rib(
+        tgen,
+        "ipv6",
+        dut,
+        input_dict_summary,
+        protocol=protocol,
+        tag="88888",
+        expected=False,
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+
+    step(
+        "Verify that boundary values tags are used for summary route"
+        " using show ip ospf route command."
+    )
+    input_dict = {
+        SUMMARY["ipv6"][0]: {
+            "Summary address": SUMMARY["ipv6"][0],
+            "Metric-type": "E2",
+            "Metric": 20,
+            "Tag": 88888,
+            "External route count": 5,
+        }
+    }
+    dut = "r0"
+    result = verify_ospf_summary(
+        tgen, topo, dut, input_dict, ospf="ospf6", expected=False
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
+
+    step("Delete the configured summary address")
+    ospf_summ_r1 = {
+        "r0": {
+            "ospf6": {
+                "summary-address": [
+                    {
+                        "prefix": SUMMARY["ipv6"][0].split("/")[0],
+                        "mask": "32",
+                        "tag": 4294967295,
+                        "delete": True,
+                    }
+                ]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_summ_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "Verify that 6 routes are advertised to neighbour with 5 routes"
+        " without any tag, 1 route with tag."
+    )
+
+    dut = "r1"
+    result = verify_ospf6_rib(tgen, dut, input_dict_static_rtes)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+    result = verify_rib(tgen, "ipv6", dut, input_dict_static_rtes, protocol=protocol)
+    assert (
+        result is True
+    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
+
+    step("Verify that summary address is flushed from neighbor.")
+
+    dut = "r1"
+    result = verify_ospf6_rib(tgen, dut, input_dict_summary, expected=False)
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
+        tc_name, result
+    )
+
+    result = verify_rib(
+        tgen, "ipv6", dut, input_dict_summary, protocol=protocol, expected=False
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
+
+    step("Configure summary first & then configure matching static route.")
+
+    input_dict_static_rtes = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"], "next_hop": "blackhole", "delete": True},
+                {"network": NETWORK2["ipv6"], "next_hop": "blackhole", "delete": True},
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict_static_rtes)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    ospf_summ_r1 = {
+        "r0": {
+            "ospf6": {
+                "summary-address": [
+                    {"prefix": SUMMARY["ipv6"][0].split("/")[0], "mask": "32"}
+                ]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_summ_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    input_dict_static_rtes = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"], "next_hop": "blackhole"},
+                {"network": NETWORK2["ipv6"], "next_hop": "blackhole"},
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict_static_rtes)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    write_test_footer(tc_name)
+
+
 def test_ospfv3_type5_summary_tc46_p0(request):
     """OSPF summarisation with advertise and no advertise option"""
     tc_name = request.node.name
@@ -1657,127 +2736,6 @@ def test_ospfv3_type5_summary_tc49_p2(request):
         result is not True
     ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
 
-    step("Kill OSPF6d daemon on R0.")
-    kill_router_daemons(tgen, "r0", ["ospf6d"])
-
-    step("Bring up OSPF6d daemon on R0.")
-    start_router_daemons(tgen, "r0", ["ospf6d"])
-
-    step("Verify OSPF neighbors are up after bringing back ospf6d in R0")
-    # Api call verify whether OSPF is converged
-    ospf_covergence = verify_ospf6_neighbor(tgen, topo)
-    assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
-        ospf_covergence
-    )
-
-    step(
-        "Verify that external routes are summarised to configured summary "
-        "address on R0 after 5 secs of delay timer expiry and only one "
-        "route is sent to R1."
-    )
-    input_dict_summary = {"r0": {"static_routes": [{"network": SUMMARY["ipv6"][0]}]}}
-    dut = "r1"
-
-    result = verify_ospf6_rib(tgen, dut, input_dict_summary)
-    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
-
-    result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
-    assert (
-        result is True
-    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
-
-    step("Verify that show ip ospf summary should show the summaries.")
-    input_dict = {
-        SUMMARY["ipv6"][0]: {
-            "Summary address": SUMMARY["ipv6"][0],
-            "Metric-type": "E2",
-            "Metric": 20,
-            "Tag": 0,
-            "External route count": 5,
-        }
-    }
-    dut = "r0"
-    result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
-    assert (
-        result is True
-    ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
-
-    step("Verify that originally advertised routes are withdraw from there" " peer.")
-    input_dict = {
-        "r0": {"static_routes": [{"network": NETWORK["ipv6"], "next_hop": "blackhole"}]}
-    }
-    dut = "r1"
-    result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
-    assert (
-        result is not True
-    ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
-        tc_name, result
-    )
-
-    result = verify_rib(
-        tgen, "ipv6", dut, input_dict, protocol=protocol, expected=False
-    )
-    assert (
-        result is not True
-    ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
-
-    step("restart zebrad")
-    kill_router_daemons(tgen, "r0", ["zebra"])
-
-    step("Bring up zebra daemon on R0.")
-    start_router_daemons(tgen, "r0", ["zebra"])
-
-    step(
-        "Verify that external routes are summarised to configured summary "
-        "address on R0 after 5 secs of delay timer expiry and only one "
-        "route is sent to R1."
-    )
-    input_dict_summary = {"r0": {"static_routes": [{"network": SUMMARY["ipv6"][0]}]}}
-    dut = "r1"
-
-    result = verify_ospf6_rib(tgen, dut, input_dict_summary)
-    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
-
-    result = verify_rib(tgen, "ipv6", dut, input_dict_summary, protocol=protocol)
-    assert (
-        result is True
-    ), "Testcase {} : Failed" "Error: Routes is missing in RIB".format(tc_name)
-
-    step("Verify that show ip ospf summary should show the summaries.")
-    input_dict = {
-        SUMMARY["ipv6"][0]: {
-            "Summary address": SUMMARY["ipv6"][0],
-            "Metric-type": "E2",
-            "Metric": 20,
-            "Tag": 0,
-            "External route count": 5,
-        }
-    }
-    dut = "r0"
-    result = verify_ospf_summary(tgen, topo, dut, input_dict, ospf="ospf6")
-    assert (
-        result is True
-    ), "Testcase {} : Failed" "Error: Summary missing in OSPF DB".format(tc_name)
-
-    step("Verify that originally advertised routes are withdraw from there" " peer.")
-    input_dict = {
-        "r0": {"static_routes": [{"network": NETWORK["ipv6"], "next_hop": "blackhole"}]}
-    }
-    dut = "r1"
-    result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
-    assert (
-        result is not True
-    ), "Testcase {} : Failed \n Error: " "Routes still present in OSPF RIB {}".format(
-        tc_name, result
-    )
-
-    result = verify_rib(
-        tgen, "ipv6", dut, input_dict, protocol=protocol, expected=False
-    )
-    assert (
-        result is not True
-    ), "Testcase {} : Failed" "Error: Routes still present in RIB".format(tc_name)
-
     write_test_footer(tc_name)
 
 
diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp_lan.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp_lan.py
new file mode 100644 (file)
index 0000000..fe8be0a
--- /dev/null
@@ -0,0 +1,400 @@
+#!/usr/bin/python
+
+#
+# Copyright (c) 2021 by VMware, Inc. ("VMware")
+# Used Copyright (c) 2018 by Network Device Education Foundation, Inc.
+# ("NetDEF") in this file.
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+
+"""OSPF Basic Functionality Automation."""
+import os
+import sys
+import time
+import pytest
+import json
+from copy import deepcopy
+from ipaddress import IPv4Address
+from lib.topotest import frr_unicode
+import ipaddress
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+sys.path.append(os.path.join(CWD, "../lib/"))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib.topogen import Topogen, get_topogen
+
+# Import topoJson from lib, to create topology and initial configuration
+from lib.common_config import (
+    start_topology,
+    write_test_header,
+    write_test_footer,
+    reset_config_on_routers,
+    verify_rib,
+    create_static_routes,
+    step,
+    create_route_maps,
+    shutdown_bringup_interface,
+    create_interfaces_cfg,
+    topo_daemons,
+    get_frr_ipv6_linklocal,
+)
+from lib.topolog import logger
+from lib.topojson import build_config_from_json
+
+from lib.ospf import (
+    verify_ospf6_neighbor,
+    config_ospf_interface,
+    clear_ospf,
+    verify_ospf6_rib,
+    create_router_ospf,
+    verify_ospf6_interface,
+    verify_ospf6_database,
+    config_ospf6_interface,
+)
+
+from ipaddress import IPv6Address
+
+pytestmark = [pytest.mark.ospfd, pytest.mark.staticd]
+
+
+# Global variables
+topo = None
+
+NETWORK = {
+    "ipv4": [
+        "11.0.20.1/32",
+        "11.0.20.2/32",
+        "11.0.20.3/32",
+        "11.0.20.4/32",
+        "11.0.20.5/32",
+    ],
+    "ipv6": ["2::1/128", "2::2/128", "2::3/128", "2::4/128", "2::5/128"],
+}
+MASK = {"ipv6": "32", "ipv6": "128"}
+
+"""
+TOPOOLOGY =
+      Please view in a fixed-width font such as Courier.
+      Topo : Broadcast Networks
+        +---+       +---+          +---+           +---+
+        |R0 +       +R1 +          +R2 +           +R3 |
+        +-+-+       +-+-+          +-+-+           +-+-+
+          |           |              |               |
+          |           |              |               |
+        --+-----------+--------------+---------------+-----
+                         Ethernet Segment
+
+TESTCASES =
+1.  Verify OSPF ECMP with max path configured as 8
+    (Edge having 1 uplink port as broadcast network,
+    connect to 8 TORs - LAN case)
+
+ """
+
+
+def setup_module(mod):
+    """
+    Sets up the pytest environment
+
+    * `mod`: module name
+    """
+    global topo, switch_name
+    testsuite_run_time = time.asctime(time.localtime(time.time()))
+    logger.info("Testsuite start time: {}".format(testsuite_run_time))
+    logger.info("=" * 40)
+
+    logger.info("Running setup_module to create topology")
+
+    # This function initiates the topology build with Topogen...
+    json_file = "{}/ospfv3_ecmp_lan.json".format(CWD)
+    tgen = Topogen(json_file, mod.__name__)
+    global topo
+    topo = tgen.json_topo
+    # ... and here it calls Mininet initialization functions.
+
+    # get list of daemons needs to be started for this suite.
+    daemons = topo_daemons(tgen, topo)
+
+    # Starting topology, create tmp files which are loaded to routers
+    #  to start deamons and then start routers
+    start_topology(tgen, daemons)
+
+    # Creating configuration from JSON
+    build_config_from_json(tgen, topo)
+
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+    # Api call verify whether OSPF is converged
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo, lan=True)
+    assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+        ospf_covergence
+    )
+
+    switch_name = [k for k in topo["switches"].keys()][0]
+
+    logger.info("Running setup_module() done")
+
+
+def teardown_module(mod):
+    """
+    Teardown the pytest environment.
+
+    * `mod`: module name
+    """
+
+    logger.info("Running teardown_module to delete topology")
+
+    tgen = get_topogen()
+
+    # Stop toplogy and Remove tmp files
+
+    try:
+        # Stop toplogy and Remove tmp files
+        tgen.stop_topology()
+
+    except OSError:
+        # OSError exception is raised when mininet tries to stop switch
+        # though switch is stopped once but mininet tries to stop same
+        # switch again, where it ended up with exception
+        pass
+    logger.info(
+        "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
+    )
+    logger.info("=" * 40)
+
+
+def red_static(dut, config=True):
+    """Local def for Redstribute static routes inside ospf."""
+    global topo
+    tgen = get_topogen()
+    if config:
+        ospf_red = {dut: {"ospf6": {"redistribute": [{"redist_type": "static"}]}}}
+    else:
+        ospf_red = {
+            dut: {
+                "ospf6": {"redistribute": [{"redist_type": "static", "delete": True}]}
+            }
+        }
+    result = create_router_ospf(tgen, topo, ospf_red)
+    assert result is True, "Testcase : Failed \n Error: {}".format(result)
+
+
+def red_connected(dut, config=True):
+    """Local def for Redstribute connected routes inside ospf."""
+    global topo
+    tgen = get_topogen()
+    if config:
+        ospf_red = {dut: {"ospf6": {"redistribute": [{"redist_type": "connected"}]}}}
+    else:
+        ospf_red = {
+            dut: {
+                "ospf6": {
+                    "redistribute": [{"redist_type": "connected", "del_action": True}]
+                }
+            }
+        }
+    result = create_router_ospf(tgen, topo, ospf_red)
+    assert result is True, "Testcase: Failed \n Error: {}".format(result)
+
+
+def get_llip(onrouter, intf):
+    """
+    API to get the link local ipv6 address of a perticular interface
+
+    Parameters
+    ----------
+    * `fromnode`: Source node
+    * `tonode` : interface for which link local ip needs to be returned.
+
+    Usage
+    -----
+    result = get_llip('r1', 'r2-link0')
+
+    Returns
+    -------
+    1) link local ipv6 address from the interface.
+    2) errormsg - when link local ip not found.
+    """
+    tgen = get_topogen()
+    intf = topo["routers"][onrouter]["links"][intf]["interface"]
+    llip = get_frr_ipv6_linklocal(tgen, onrouter, intf)
+    if llip:
+        logger.info("llip ipv6 address to be set as NH is %s", llip)
+        return llip
+    return None
+
+
+def get_glipv6(onrouter, intf):
+    """
+    API to get the global ipv6 address of a perticular interface
+
+    Parameters
+    ----------
+    * `onrouter`: Source node
+    * `intf` : interface for which link local ip needs to be returned.
+
+    Usage
+    -----
+    result = get_glipv6('r1', 'r2-link0')
+
+    Returns
+    -------
+    1) global ipv6 address from the interface.
+    2) errormsg - when link local ip not found.
+    """
+    glipv6 = (topo["routers"][onrouter]["links"][intf]["ipv6"]).split("/")[0]
+    if glipv6:
+        logger.info("Global ipv6 address to be set as NH is %s", glipv6)
+        return glipv6
+    return None
+
+
+# ##################################
+# Test cases start here.
+# ##################################
+
+
+def test_ospfv3_lan_ecmp_tc18_p0(request):
+    """
+    OSPF ECMP.
+
+    Verify OSPF ECMP with max path configured as 8
+    (Edge having 1 uplink port as broadcast network,
+    connect to 8 TORs - LAN case)
+
+    """
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    global topo
+    step("Bring up the base config as per the topology")
+    step(". Configure ospf in all the routers on LAN interface.")
+
+    reset_config_on_routers(tgen)
+
+    step("Verify that OSPF is up with 8 neighborship sessions.")
+
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo, lan=True)
+    assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+        ospf_covergence
+    )
+
+    step(
+        "Configure a static route in all the routes and "
+        "redistribute static/connected in OSPF."
+    )
+
+    for rtr in topo["routers"]:
+        input_dict = {
+            rtr: {
+                "static_routes": [
+                    {"network": NETWORK["ipv6"][0], "no_of_ip": 5, "next_hop": "Null0"}
+                ]
+            }
+        }
+        result = create_static_routes(tgen, input_dict)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
+
+        dut = rtr
+        red_static(dut)
+
+    step(
+        "Verify that route in R0 in stalled with 8 hops. "
+        "Verify ospf route table and ip route table."
+    )
+
+    nh = []
+    for rtr in topo["routers"]:
+        llip = get_llip(rtr, switch_name)
+        assert llip is not None, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
+        nh.append(llip)
+
+    llip = get_llip("r1", switch_name)
+    assert llip is not None, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    nh.remove(llip)
+    dut = "r1"
+    result = verify_ospf6_rib(tgen, dut, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    protocol = "ospf6"
+    result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(" clear ip ospf interface on DUT(r0)")
+    clear_ospf(tgen, "r0", ospf="ospf6")
+
+    step(
+        "Verify that after clearing the ospf interface all the "
+        "neighbours are up and routes are installed with 8 next hop "
+        "in ospf and ip route tables on R0"
+    )
+
+    dut = "r0"
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut, lan=True)
+    assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+        ospf_covergence
+    )
+
+    step(" clear ip ospf interface on R2")
+    clear_ospf(tgen, "r2")
+
+    dut = "r2"
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut, lan=True)
+    assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+        ospf_covergence
+    )
+
+    step("Delete static/connected cmd in ospf in all the routes one by one.")
+    for rtr in topo["routers"]:
+        input_dict = {
+            rtr: {
+                "static_routes": [
+                    {
+                        "network": NETWORK["ipv6"][0],
+                        "no_of_ip": 5,
+                        "next_hop": "Null0",
+                        "delete": True,
+                    }
+                ]
+            }
+        }
+        result = create_static_routes(tgen, input_dict)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
+
+    write_test_footer(tc_name)
+
+
+if __name__ == "__main__":
+    args = ["-s"] + sys.argv[1:]
+    sys.exit(pytest.main(args))
diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa2.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa2.py
new file mode 100644 (file)
index 0000000..dc3b915
--- /dev/null
@@ -0,0 +1,482 @@
+#!/usr/bin/python
+
+#
+# Copyright (c) 2021 by VMware, Inc. ("VMware")
+# Used Copyright (c) 2018 by Network Device Education Foundation, Inc.
+# ("NetDEF") in this file.
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+
+"""OSPF Basic Functionality Automation."""
+import os
+import sys
+import time
+import pytest
+from copy import deepcopy
+import ipaddress
+from lib.ospf import (
+    verify_ospf6_neighbor,
+    config_ospf6_interface,
+    clear_ospf,
+    verify_ospf6_rib,
+    verify_ospf6_interface,
+    verify_ospf6_database,
+    create_router_ospf,
+)
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib.topogen import Topogen, get_topogen
+
+from lib.bgp import (
+    verify_bgp_convergence,
+    create_router_bgp,
+    clear_bgp_and_verify,
+    verify_bgp_rib,
+)
+from lib.topolog import logger
+from lib.common_config import (
+    start_topology,
+    write_test_header,
+    write_test_footer,
+    reset_config_on_routers,
+    verify_rib,
+    create_static_routes,
+    step,
+    topo_daemons,
+    create_route_maps,
+    shutdown_bringup_interface,
+    create_interfaces_cfg,
+    check_router_status,
+)
+from ipaddress import IPv4Address
+from lib.topolog import logger
+from lib.topojson import build_config_from_json
+
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+pytestmark = [pytest.mark.ospfd, pytest.mark.staticd]
+
+# Global variables
+topo = None
+NETWORK = {
+    "ipv4": [
+        "11.0.20.1/32",
+        "11.0.20.2/32",
+        "11.0.20.3/32",
+        "11.0.20.4/32",
+        "11.0.20.5/32",
+    ],
+    "ipv6": [
+        "2011:0:20::1/128",
+        "2011:0:20::2/128",
+        "2011:0:20::3/128",
+        "2011:0:20::4/128",
+        "2011:0:20::5/128",
+    ],
+}
+"""
+TOPOOLOGY =
+      Please view in a fixed-width font such as Courier.
+      +---+  A1       +---+
+      +R1 +------------+R2 |
+      +-+-+-           +--++
+        |  --        --  |
+        |    -- A0 --    |
+      A0|      ----      |
+        |      ----      | A2
+        |    --    --    |
+        |  --        --  |
+      +-+-+-            +-+-+
+      +R0 +-------------+R3 |
+      +---+     A3     +---+
+
+
+
+TESTCASES =
+1. OSPF Learning - Verify OSPF can learn different types of LSA and
+   processes them.[Edge learning different types of LSAs]
+2. Verify that ospf non back bone area can be configured as NSSA area
+3. Verify that ospf NSSA area DUT is capable receiving & processing
+   Type7 N2 route.
+"""
+
+
+def setup_module(mod):
+    """
+    Sets up the pytest environment
+
+    * `mod`: module name
+    """
+    global topo
+    testsuite_run_time = time.asctime(time.localtime(time.time()))
+    logger.info("Testsuite start time: {}".format(testsuite_run_time))
+    logger.info("=" * 40)
+
+    logger.info("Running setup_module to create topology")
+
+    # This function initiates the topology build with Topogen...
+    json_file = "{}/ospfv3_nssa2.json".format(CWD)
+    tgen = Topogen(json_file, mod.__name__)
+    global topo
+    topo = tgen.json_topo
+    # ... and here it calls Mininet initialization functions.
+
+    # get list of daemons needs to be started for this suite.
+    daemons = topo_daemons(tgen, topo)
+
+    # Starting topology, create tmp files which are loaded to routers
+    #  to start deamons and then start routers
+    start_topology(tgen, daemons)
+
+    # Creating configuration from JSON
+    build_config_from_json(tgen, topo)
+
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    # Api call verify whether OSPF is converged
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo)
+    assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+        ospf_covergence
+    )
+
+    logger.info("Running setup_module() done")
+
+
+def teardown_module():
+    """Teardown the pytest environment."""
+    logger.info("Running teardown_module to delete topology")
+
+    tgen = get_topogen()
+
+    # Stop toplogy and Remove tmp files
+    tgen.stop_topology()
+
+
+def red_static(dut, config=True):
+    """Local def for Redstribute static routes inside ospf."""
+    global topo
+    tgen = get_topogen()
+    if config:
+        ospf_red = {dut: {"ospf6": {"redistribute": [{"redist_type": "static"}]}}}
+    else:
+        ospf_red = {
+            dut: {
+                "ospf6": {"redistribute": [{"redist_type": "static", "delete": True}]}
+            }
+        }
+    result = create_router_ospf(tgen, topo, ospf_red)
+    assert result is True, "Testcase : Failed \n Error: {}".format(result)
+
+
+def red_connected(dut, config=True):
+    """Local def for Redstribute connected routes inside ospf."""
+    global topo
+    tgen = get_topogen()
+    if config:
+        ospf_red = {dut: {"ospf6": {"redistribute": [{"redist_type": "connected"}]}}}
+    else:
+        ospf_red = {
+            dut: {
+                "ospf6": {
+                    "redistribute": [{"redist_type": "connected", "del_action": True}]
+                }
+            }
+        }
+    result = create_router_ospf(tgen, topo, ospf_red)
+    assert result is True, "Testcase: Failed \n Error: {}".format(result)
+
+
+# ##################################
+# Test cases start here.
+# ##################################
+
+
+def test_ospfv3_nssa_tc26_p0(request):
+    """Verify that ospf non back bone area can be configured as NSSA area"""
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        check_router_status(tgen)
+
+    global topo
+    step("Bring up the base config as per the topology")
+    step("Configure ospf area 2 on r0 , r1 & r4, make the area 2 as NSSA area")
+
+    reset_config_on_routers(tgen)
+
+    input_dict = {
+        "r2": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"][0], "no_of_ip": 5, "next_hop": "Null0"}
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Redistribute static route in R2 ospf.")
+    dut = "r2"
+    red_static(dut)
+
+    step("Verify that Type 5 LSA is originated by R2.")
+    dut = "r0"
+    protocol = "ospf6"
+    result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Un configure redistribute command in R4")
+    dut = "r2"
+    red_static(dut, config=False)
+
+    input_dict = {
+        "r1": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"][0], "no_of_ip": 1, "routeType": "Network"}
+            ]
+        }
+    }
+
+    step("Configure area 0 on interface of r2 connecting to r1")
+
+    input_dict = {
+        "r2": {
+            "links": {
+                "r1": {
+                    "interface": topo["routers"]["r2"]["links"]["r1"]["interface"],
+                    "ospf6": {"area": "0.0.0.2"},
+                    "delete": True,
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, input_dict)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+    input_dict = {
+        "r2": {
+            "links": {
+                "r1": {
+                    "interface": topo["routers"]["r2"]["links"]["r1"]["interface"],
+                    "ospf6": {"area": "0.0.0.0"},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, input_dict)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that ospf neighbor goes down between r2 and r1.")
+    result = verify_ospf6_neighbor(tgen, topo, dut="r2", expected=False)
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Nbrs are not down" "Error: {}".format(tc_name, result)
+
+    step("Now configure area 0 on interface of r1 connecting to r2.")
+
+    input_dict = {
+        "r1": {
+            "links": {
+                "r2": {
+                    "interface": topo["routers"]["r1"]["links"]["r2"]["interface"],
+                    "ospf6": {"area": "0.0.0.2"},
+                    "delete": True,
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, input_dict)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+    input_dict = {
+        "r1": {
+            "links": {
+                "r2": {
+                    "interface": topo["routers"]["r1"]["links"]["r2"]["interface"],
+                    "ospf6": {"area": "0.0.0.0"},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, input_dict)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+    step("Verify that ospf neighbour comes up between r2 and r1.")
+    result = verify_ospf6_neighbor(tgen, topo, dut="r2")
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Configure area 2 on interface of r2 connecting to r1.")
+
+    input_dict = {
+        "r2": {
+            "links": {
+                "r1": {
+                    "interface": topo["routers"]["r2"]["links"]["r1"]["interface"],
+                    "ospf6": {"area": "0.0.0.0"},
+                    "delete": True,
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, input_dict)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+    input_dict = {
+        "r2": {
+            "links": {
+                "r1": {
+                    "interface": topo["routers"]["r2"]["links"]["r1"]["interface"],
+                    "ospf6": {"area": "0.0.0.2"},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, input_dict)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that ospf neighbor goes down between r2 and r1.")
+    result = verify_ospf6_neighbor(tgen, topo, dut="r2", expected=False)
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Nbrs are not down" "Error: {}".format(tc_name, result)
+
+    step("Now configure area 2 on interface of r1 connecting to r2.")
+
+    input_dict = {
+        "r1": {
+            "links": {
+                "r2": {
+                    "interface": topo["routers"]["r1"]["links"]["r2"]["interface"],
+                    "ospf6": {"area": "0.0.0.0"},
+                    "delete": True,
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, input_dict)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+    input_dict = {
+        "r1": {
+            "links": {
+                "r2": {
+                    "interface": topo["routers"]["r1"]["links"]["r2"]["interface"],
+                    "ospf6": {"area": "0.0.0.2"},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, input_dict)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+    step("Verify that ospf neighbour comes up between r2 and r1.")
+    result = verify_ospf6_neighbor(tgen, topo, dut="r2")
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    write_test_footer(tc_name)
+
+
+# As per internal discussion, this script has to be removed as translator
+# function is not supported, for more details kindly check this PR 2565570
+def ospfv3_nssa_tc27_p0(request):
+    """
+    OSPF NSSA.
+
+    Verify that ospf NSSA area DUT is capable receiving & processing
+    Type7 N2 route.
+    """
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        check_router_status(tgen)
+
+    global topo
+    step("Bring up the base config as per the topology")
+    step("Configure ospf area 2 on r0 , r1 & r4, make the area 2 as NSSA area")
+
+    reset_config_on_routers(tgen)
+
+    input_dict = {
+        "r2": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"][0], "no_of_ip": 5, "next_hop": "Null0"}
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Redistribute static route in R2 ospf.")
+    dut = "r2"
+    red_static(dut)
+
+    step("Verify that Type 5 LSA is originated by R2.")
+    dut = "r0"
+    protocol = "ospf6"
+    result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Un configure redistribute command in R4")
+    dut = "r2"
+    red_static(dut, config=False)
+
+    input_dict = {
+        "r1": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"][0], "no_of_ip": 1, "routeType": "Network"}
+            ]
+        }
+    }
+
+    dut = "r0"
+    result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
+    assert result is not True, "Testcase {} : Failed \n Error: {}".format(
+        tc_name, result
+    )
+
+    result = verify_rib(
+        tgen, "ipv6", dut, input_dict, protocol=protocol, expected=False
+    )
+    assert result is not True, "Testcase {} : Failed \n Error: {}".format(
+        tc_name, result
+    )
+
+    write_test_footer(tc_name)
+
+
+if __name__ == "__main__":
+    args = ["-s"] + sys.argv[1:]
+    sys.exit(pytest.main(args))
index 461efbe9793cef5a4f5cb92ce6b9e92301c9a337..d7cf951c5f14acc1d825b213d6ab4fa7bfec2b09 100644 (file)
@@ -178,6 +178,312 @@ def teardown_module(mod):
 # ##################################
 
 
+def test_ospfv3_routemaps_functionality_tc19_p0(request):
+    """
+    OSPF Route map - Verify OSPF route map support functionality.
+
+    """
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+    global topo
+    step("Bring up the base config as per the topology")
+    reset_config_on_routers(tgen)
+
+    step("Create static routes(10.0.20.1/32 and 10.0.20.2/32) in R0")
+    # Create Static routes
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {
+                    "network": NETWORK["ipv6"][0],
+                    "no_of_ip": 5,
+                    "next_hop": "Null0",
+                }
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    ospf_red_r1 = {"r0": {"ospf6": {"redistribute": [{"redist_type": "static"}]}}}
+    result = create_router_ospf(tgen, topo, ospf_red_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    dut = "r1"
+    lsid = NETWORK["ipv6"][0].split("/")[0]
+    rid = routerids[0]
+
+    protocol = "ospf"
+    result = verify_ospf6_rib(tgen, dut, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    ospf_red_r1 = {
+        "r0": {
+            "ospf6": {"redistribute": [{"redist_type": "static", "del_action": True}]}
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_red_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "Create prefix-list in R0 to permit 10.0.20.1/32 prefix &" " deny 10.0.20.2/32"
+    )
+
+    # Create ip prefix list
+    pfx_list = {
+        "r0": {
+            "prefix_lists": {
+                "ipv6": {
+                    "pf_list_1_ipv6": [
+                        {
+                            "seqid": 10,
+                            "network": NETWORK["ipv6"][0],
+                            "action": "permit",
+                        },
+                        {"seqid": 11, "network": "any", "action": "deny"},
+                    ]
+                }
+            }
+        }
+    }
+    result = create_prefix_lists(tgen, pfx_list)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that prefix-list is created in R0.")
+    result = verify_prefix_lists(tgen, pfx_list)
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n, prefix list creation failed. Error: {}".format(
+        tc_name, result
+    )
+
+    # Create route map
+    routemaps = {
+        "r0": {
+            "route_maps": {
+                "rmap_ipv6": [
+                    {
+                        "action": "permit",
+                        "match": {"ipv6": {"prefix_lists": "pf_list_1_ipv6"}},
+                    }
+                ]
+            }
+        }
+    }
+    result = create_route_maps(tgen, routemaps)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "Configure route map rmap1 and redistribute static routes to"
+        " ospf using route map rmap1"
+    )
+
+    ospf_red_r1 = {
+        "r0": {
+            "ospf6": {
+                "redistribute": [{"redist_type": "static", "route_map": "rmap_ipv6"}]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_red_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+    step("Verify that route map is activated in OSPF.")
+
+    step("Verify that route 10.0.20.1 is allowed and 10.0.20.2 is denied.")
+    dut = "r1"
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"][0], "no_of_ip": 1, "next_hop": "Null0"}
+            ]
+        }
+    }
+    result = verify_ospf6_rib(tgen, dut, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    dut = "r1"
+    lsid = NETWORK["ipv6"][1].split("/")[0]
+    rid = routerids[0]
+
+    step("Change prefix rules to permit 10.0.20.2 and deny 10.0.20.1")
+    # Create ip prefix list
+    pfx_list = {
+        "r0": {
+            "prefix_lists": {
+                "ipv6": {
+                    "pf_list_1_ipv6": [
+                        {
+                            "seqid": 10,
+                            "network": NETWORK["ipv6"][1],
+                            "action": "permit",
+                        },
+                        {"seqid": 11, "network": "any", "action": "deny"},
+                    ]
+                }
+            }
+        }
+    }
+    result = create_prefix_lists(tgen, pfx_list)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Verify that route 10.0.20.2 is allowed and 10.0.20.1 is denied.")
+    dut = "r1"
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"][1], "no_of_ip": 1, "next_hop": "Null0"}
+            ]
+        }
+    }
+    result = verify_ospf6_rib(tgen, dut, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"][0], "no_of_ip": 1, "next_hop": "Null0"}
+            ]
+        }
+    }
+    result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Route found in the RIB,  Error: {}".format(
+        tc_name, result
+    )
+
+    result = verify_rib(
+        tgen, "ipv6", dut, input_dict, protocol=protocol, expected=False
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
+        tc_name, result
+    )
+
+    step("Delete and reconfigure prefix list.")
+    # Create ip prefix list
+    pfx_list = {
+        "r0": {
+            "prefix_lists": {
+                "ipv6": {
+                    "pf_list_1_ipv6": [
+                        {
+                            "seqid": 10,
+                            "network": NETWORK["ipv6"][1],
+                            "action": "permit",
+                            "delete": True,
+                        },
+                        {
+                            "seqid": 11,
+                            "network": "any",
+                            "action": "deny",
+                            "delete": True,
+                        },
+                    ]
+                }
+            }
+        }
+    }
+    result = create_prefix_lists(tgen, pfx_list)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_prefix_lists(tgen, pfx_list)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"][0], "no_of_ip": 5, "next_hop": "Null0"}
+            ]
+        }
+    }
+    result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
+        tc_name, result
+    )
+
+    result = verify_rib(
+        tgen, "ipv6", dut, input_dict, protocol=protocol, expected=False
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
+        tc_name, result
+    )
+
+    pfx_list = {
+        "r0": {
+            "prefix_lists": {
+                "ipv6": {
+                    "pf_list_1_ipv6": [
+                        {
+                            "seqid": 10,
+                            "network": NETWORK["ipv6"][1],
+                            "action": "permit",
+                        },
+                        {"seqid": 11, "network": "any", "action": "deny"},
+                    ]
+                }
+            }
+        }
+    }
+    result = create_prefix_lists(tgen, pfx_list)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Verify that route 10.0.20.2 is allowed and 10.0.20.1 is denied.")
+    dut = "r1"
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"][1], "no_of_ip": 1, "next_hop": "Null0"}
+            ]
+        }
+    }
+    result = verify_ospf6_rib(tgen, dut, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"][0], "no_of_ip": 1, "next_hop": "Null0"}
+            ]
+        }
+    }
+    result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
+        tc_name, result
+    )
+
+    result = verify_rib(
+        tgen, "ipv6", dut, input_dict, protocol=protocol, expected=False
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
+        tc_name, result
+    )
+
+    write_test_footer(tc_name)
+
+
 def test_ospfv3_routemaps_functionality_tc20_p0(request):
     """
     OSPF route map support functionality.
@@ -461,7 +767,7 @@ def test_ospfv3_routemaps_functionality_tc22_p0(request):
                     {
                         "action": "permit",
                         "seq_id": "20",
-                        "match": {"ipv6": {"prefix_lists": "pf_list_2_ipv4"}},
+                        "match": {"ipv6": {"prefix_lists": "pf_list_2_ipv6"}},
                     },
                 ]
             }
@@ -474,7 +780,7 @@ def test_ospfv3_routemaps_functionality_tc22_p0(request):
     input_dict_2 = {
         "r0": {
             "prefix_lists": {
-                "ipv4": {
+                "ipv6": {
                     "pf_list_1_ipv6": [
                         {"seqid": 10, "network": NETWORK["ipv6"][0], "action": "permit"}
                     ]
@@ -489,8 +795,8 @@ def test_ospfv3_routemaps_functionality_tc22_p0(request):
     input_dict_2 = {
         "r0": {
             "prefix_lists": {
-                "ipv4": {
-                    "pf_list_2_ipv4": [
+                "ipv6": {
+                    "pf_list_2_ipv6": [
                         {"seqid": 10, "network": NETWORK["ipv6"][1], "action": "permit"}
                     ]
                 }
@@ -567,7 +873,7 @@ def test_ospfv3_routemaps_functionality_tc22_p0(request):
                     {
                         "action": "deny",
                         "seq_id": "20",
-                        "match": {"ipv6": {"prefix_lists": "pf_list_2_ipv4"}},
+                        "match": {"ipv6": {"prefix_lists": "pf_list_2_ipv6"}},
                     }
                 ]
             }
@@ -624,6 +930,106 @@ def test_ospfv3_routemaps_functionality_tc22_p0(request):
     write_test_footer(tc_name)
 
 
+def test_ospfv3_routemaps_functionality_tc23_p0(request):
+    """
+    OSPF Route map - Multiple set clauses.
+
+    Verify OSPF route map support functionality when we add/remove route-maps
+    with multiple set clauses and without any match statement.(Set only)
+
+    """
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+    global topo
+    step("Bring up the base config as per the topology")
+
+    reset_config_on_routers(tgen)
+
+    step(
+        " Create static routes(10.0.20.1/32) in R1 and "
+        "redistribute to OSPF using route map."
+    )
+    # Create Static routes
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {
+                    "network": NETWORK["ipv6"][0],
+                    "no_of_ip": 5,
+                    "next_hop": "Null0",
+                }
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    ospf_red_r0 = {
+        "r0": {
+            "ospf6": {
+                "redistribute": [{"redist_type": "static", "route_map": "rmap_ipv6"}]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_red_r0)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Configure route map with set clause (set metric)")
+    # Create route map
+    routemaps = {
+        "r0": {
+            "route_maps": {
+                "rmap_ipv6": [
+                    {"action": "permit", "seq_id": 10, "set": {"metric": 123}}
+                ]
+            }
+        }
+    }
+    result = create_route_maps(tgen, routemaps)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Verify that configured metric is applied to ospf routes.")
+    dut = "r1"
+    protocol = "ospf"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict, metric=123)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol, metric=123)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("un configure the set clause")
+    # Create route map
+    routemaps = {
+        "r0": {
+            "route_maps": {
+                "rmap_ipv6": [
+                    {
+                        "action": "permit",
+                        "seq_id": 10,
+                        "set": {"metric": 123, "delete": True},
+                    }
+                ]
+            }
+        }
+    }
+    result = create_route_maps(tgen, routemaps)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Verify that metric falls back to original metric for ospf routes.")
+    dut = "r1"
+    protocol = "ospf"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict, metric=20)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol, metric=20)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    write_test_footer(tc_name)
+
+
 def test_ospfv3_routemaps_functionality_tc24_p0(request):
     """
     OSPF Route map - Multiple set clauses.
index d8f659e5a920d278b67fff84efce7af4956faef0..21d03fadfbebdebca54d2dd5e4ab427eda2ceaeb 100644 (file)
@@ -48,17 +48,21 @@ from lib.common_config import (
     create_interfaces_cfg,
     topo_daemons,
     get_frr_ipv6_linklocal,
+    check_router_status,
+    create_static_routes,
 )
 
 from lib.topolog import logger
 from lib.topojson import build_config_from_json
-
+from lib.bgp import create_router_bgp, verify_bgp_convergence
 from lib.ospf import (
     verify_ospf6_neighbor,
+    clear_ospf,
     verify_ospf6_rib,
+    verify_ospf_database,
     create_router_ospf,
-    verify_ospf6_interface,
     config_ospf6_interface,
+    verify_ospf6_interface,
 )
 
 
@@ -251,6 +255,8 @@ def red_connected(dut, config=True):
 # ##################################
 # Test cases start here.
 # ##################################
+
+
 def test_ospfv3_redistribution_tc5_p0(request):
     """Test OSPF intra area route calculations."""
     tc_name = request.node.name
@@ -259,7 +265,7 @@ def test_ospfv3_redistribution_tc5_p0(request):
 
     # Don't run this test if we have any failure.
     if tgen.routers_have_failure():
-        pytest.skip(tgen.errors)
+        check_router_status(tgen)
 
     global topo
     step("Bring up the base config.")
@@ -280,7 +286,11 @@ def test_ospfv3_redistribution_tc5_p0(request):
 
     nh = llip
     input_dict = {
-        "r1": {"static_routes": [{"network": ip_net, "no_of_ip": 1, "routeType": "N"}]}
+        "r1": {
+            "static_routes": [
+                {"network": ip_net, "no_of_ip": 1, "routeType": "Network"}
+            ]
+        }
     }
 
     dut = "r1"
@@ -372,7 +382,7 @@ def test_ospfv3_redistribution_tc6_p0(request):
 
     # Don't run this test if we have any failure.
     if tgen.routers_have_failure():
-        pytest.skip(tgen.errors)
+        check_router_status(tgen)
 
     global topo
     step("Bring up the base config.")
@@ -380,8 +390,8 @@ def test_ospfv3_redistribution_tc6_p0(request):
 
     step("Verify that OSPF neighbors are FULL.")
     ospf_covergence = verify_ospf6_neighbor(tgen, topo)
-    assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
-        ospf_covergence
+    assert ospf_covergence is True, "Testcase {} : Failed \n Error: {}".format(
+        tc_name, ospf_covergence
     )
 
     step("verify intra area route is calculated for r0-r3 interface ip in R1")
@@ -391,7 +401,11 @@ def test_ospfv3_redistribution_tc6_p0(request):
     assert llip is not None, "Testcase {} : Failed \n Error: {}".format(tc_name, llip)
     nh = llip
     input_dict = {
-        "r1": {"static_routes": [{"network": ip_net, "no_of_ip": 1, "routeType": "N"}]}
+        "r1": {
+            "static_routes": [
+                {"network": ip_net, "no_of_ip": 1, "routeType": "Network"}
+            ]
+        }
     }
 
     dut = "r1"
@@ -460,9 +474,6 @@ def test_ospfv3_redistribution_tc6_p0(request):
     intf = topo["routers"]["r0"]["links"]["r3"]["interface"]
     shutdown_bringup_interface(tgen, dut, intf, False)
 
-    step("Verify that intraroute calculated for R1 intf on R0 is deleted.")
-    dut = "r1"
-
     step("un shut the OSPF interface on R0")
     dut = "r0"
     shutdown_bringup_interface(tgen, dut, intf, True)
@@ -478,6 +489,168 @@ def test_ospfv3_redistribution_tc6_p0(request):
     write_test_footer(tc_name)
 
 
+def test_ospfv3_redistribution_tc8_p1(request):
+    """
+    Test OSPF redistribution of connected routes.
+
+    Verify OSPF redistribution of connected routes when bgp multi hop
+    neighbor is configured using ospf routes
+
+    """
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+    global topo
+    step("Bring up the base config.")
+    step(
+        "Configure loopback interface on all routers, and redistribut"
+        "e connected routes into ospf"
+    )
+    if tgen.routers_have_failure():
+        check_router_status(tgen)
+    reset_config_on_routers(tgen)
+
+    step(
+        "verify that connected routes -loopback is found in all routers"
+        "advertised/exchaged via ospf"
+    )
+    for rtr in topo["routers"]:
+        red_static(rtr)
+        red_connected(rtr)
+
+    for node in topo["routers"]:
+        input_dict = {
+            "r0": {
+                "static_routes": [
+                    {
+                        "network": topo["routers"][node]["links"]["lo"]["ipv6"],
+                        "no_of_ip": 1,
+                    }
+                ]
+            }
+        }
+        for rtr in topo["routers"]:
+            result = verify_rib(tgen, "ipv6", rtr, input_dict)
+            assert result is True, "Testcase {} : Failed \n Error: {}".format(
+                tc_name, result
+            )
+
+    step("Configure E BGP multi hop using the loopback addresses.")
+    as_num = 100
+    for node in topo["routers"]:
+        as_num += 1
+        topo["routers"][node].update(
+            {
+                "bgp": {
+                    "local_as": as_num,
+                    "address_family": {"ipv6": {"unicast": {"neighbor": {}}}},
+                }
+            }
+        )
+    for node in topo["routers"]:
+        for rtr in topo["routers"]:
+            if node is not rtr:
+                topo["routers"][node]["bgp"]["address_family"]["ipv6"]["unicast"][
+                    "neighbor"
+                ].update(
+                    {
+                        rtr: {
+                            "dest_link": {
+                                "lo": {"source_link": "lo", "ebgp_multihop": 2}
+                            }
+                        }
+                    }
+                )
+
+    result = create_router_bgp(tgen, topo, topo["routers"])
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    # Modify router id
+    input_dict = {
+        "r0": {"bgp": {"router_id": "11.11.11.11"}},
+        "r1": {"bgp": {"router_id": "22.22.22.22"}},
+        "r2": {"bgp": {"router_id": "33.33.33.33"}},
+        "r3": {"bgp": {"router_id": "44.44.44.44"}},
+    }
+    result = create_router_bgp(tgen, topo, input_dict)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+    step("Verify that BGP neighbor is ESTABLISHED")
+    result = verify_bgp_convergence(tgen, topo)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+    step(
+        "Configure couple of static routes in R0 and "
+        "Redistribute static routes in R1 bgp."
+    )
+
+    for rtr in topo["routers"]:
+        ospf_red = {
+            rtr: {
+                "ospf6": {"redistribute": [{"redist_type": "static", "delete": True}]}
+            }
+        }
+        result = create_router_ospf(tgen, topo, ospf_red)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
+
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {
+                    "network": NETWORK["ipv6"][0],
+                    "no_of_ip": 5,
+                    "next_hop": "Null0",
+                }
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    configure_bgp_on_r0 = {
+        "r0": {
+            "bgp": {
+                "address_family": {
+                    "ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}}
+                }
+            }
+        }
+    }
+    result = create_router_bgp(tgen, topo, configure_bgp_on_r0)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+    protocol = "bgp"
+    for rtr in ["r1", "r2", "r3"]:
+        result = verify_rib(tgen, "ipv6", rtr, input_dict, protocol=protocol)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
+
+    step("Clear ospf neighbours in R0")
+    for rtr in topo["routers"]:
+        clear_ospf(tgen, rtr)
+
+    step("Verify that OSPF neighbours are reset and forms new adjacencies.")
+    # Api call verify whether OSPF is converged
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo)
+    assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+        ospf_covergence
+    )
+
+    step("Verify that BGP neighbours are reset and forms new adjacencies.")
+    result = verify_bgp_convergence(tgen, topo)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+    protocol = "bgp"
+    for rtr in ["r1", "r2", "r3"]:
+        result = verify_rib(tgen, "ipv6", rtr, input_dict, protocol=protocol)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
+
+    write_test_footer(tc_name)
+
+
 def test_ospfv3_cost_tc52_p0(request):
     """OSPF Cost - verifying ospf interface cost functionality"""
     tc_name = request.node.name
@@ -485,6 +658,8 @@ def test_ospfv3_cost_tc52_p0(request):
     tgen = get_topogen()
     global topo
     step("Bring up the base config.")
+    if tgen.routers_have_failure():
+        check_router_status(tgen)
     reset_config_on_routers(tgen)
 
     step(
@@ -565,6 +740,184 @@ def test_ospfv3_cost_tc52_p0(request):
     write_test_footer(tc_name)
 
 
+def test_ospfv3_def_rte_tc9_p0(request):
+    """OSPF default route - Verify OSPF default route origination."""
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+    global topo
+    step("Bring up the base config.")
+    step("Configure OSPF on all the routers of the topology.")
+    if tgen.routers_have_failure():
+        check_router_status(tgen)
+    reset_config_on_routers(tgen)
+
+    step(" Configure default-information originate always on R0.")
+    input_dict = {"r0": {"ospf6": {"default-information": {"originate": True}}}}
+    result = create_router_ospf(tgen, topo, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    dut = "r0"
+    step(" Configure default-information originate always on R0.")
+    input_dict = {
+        "r0": {
+            "ospf6": {
+                "default-information": {
+                    "originate": True,
+                    "always": True,
+                }
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Verify that default route is originated in area always.")
+    dut = "r1"
+
+    step(" Configure default-information originate metric type 1 on R0.")
+    input_dict = {
+        "r0": {
+            "ospf6": {
+                "default-information": {
+                    "originate": True,
+                    "always": True,
+                    "metric-type": 1,
+                }
+            }
+        }
+    }
+
+    step(
+        "Verify that default route is originated in area when external "
+        "routes are present in R0 with metric type as 1."
+    )
+    dut = "r0"
+    step(
+        "Verify that on R1 default route with type 1 is installed"
+        " (R1 is DUT in this case)"
+    )
+    dut = "r1"
+    step("Configure default-information originate metric type 2 on R0.")
+    input_dict = {
+        "r0": {
+            "ospf6": {
+                "default-information": {
+                    "originate": True,
+                    "always": True,
+                    "metric-type": 2,
+                }
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "Verify that default route is originated in area when external"
+        " routes are present in R0 with metric type as 2."
+    )
+
+    dut = "r1"
+    step(" Configure default-information originate metric 100 on R0")
+    input_dict = {
+        "r0": {
+            "ospf6": {
+                "default-information": {
+                    "originate": True,
+                    "always": True,
+                    "metric-type": 2,
+                    "metric": 100,
+                }
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Verify that default route is originated with cost as 100 on R0.")
+
+    dut = "r1"
+
+    step("Delete the default-information command")
+    input_dict = {
+        "r0": {
+            "ospf6": {
+                "default-information": {
+                    "originate": True,
+                    "always": True,
+                    "delete": True,
+                }
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    dut = "r0"
+    step("Configure default-information originate always on R0.")
+    input_dict = {
+        "r0": {
+            "ospf6": {
+                "default-information": {
+                    "originate": True,
+                    "always": True,
+                }
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Configure default route originate with active def route in zebra")
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {
+                    "network": "0::0/0",
+                    "no_of_ip": 1,
+                    "next_hop": "Null0",
+                }
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    input_dict = {
+        "r0": {
+            "ospf6": {
+                "default-information": {
+                    "originate": True,
+                }
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Verify that default route is originated by R0.")
+    dut = "r1"
+
+    step("Delete static route")
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {
+                    "network": "0::0/0",
+                    "no_of_ip": 1,
+                    "next_hop": "Null0",
+                    "delete": True,
+                }
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    write_test_footer(tc_name)
+
+
 if __name__ == "__main__":
     args = ["-s"] + sys.argv[1:]
     sys.exit(pytest.main(args))
index ed70c09faef3e74536da75e3988a3c784f3e0685..9ec06ec36be7659fdcd95aad46c41769d228c847 100644 (file)
@@ -26,6 +26,8 @@ import os
 import sys
 import time
 import pytest
+import ipaddress
+
 from copy import deepcopy
 from lib.topotest import frr_unicode
 
@@ -47,6 +49,8 @@ from lib.common_config import (
     step,
     create_interfaces_cfg,
     topo_daemons,
+    create_debug_log_config,
+    apply_raw_config,
 )
 from lib.topolog import logger
 from lib.topojson import build_config_from_json
@@ -55,6 +59,9 @@ from lib.ospf import (
     verify_ospf6_neighbor,
     clear_ospf,
     verify_ospf6_interface,
+    create_router_ospf,
+    config_ospf6_interface,
+    verify_ospf6_rib,
 )
 
 from ipaddress import IPv6Address
@@ -381,6 +388,956 @@ def test_ospfv3_p2p_tc3_p0(request):
     write_test_footer(tc_name)
 
 
+def test_ospfv3_hello_tc10_p0(request):
+    """
+    OSPF timers.
+
+    Verify OSPF interface timer hello interval functionality
+    """
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    global topo
+    step("Bring up the base config as per the topology")
+    reset_config_on_routers(tgen)
+
+    step("modify hello timer from default value to some other value on r1")
+
+    topo1 = {
+        "r1": {
+            "links": {
+                "r0": {
+                    "interface": topo["routers"]["r1"]["links"]["r0"]["interface"],
+                    "ospf6": {"hello_interval": 11, "dead_interval": 12},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "verify that new timer value is configured and applied using "
+        "the show ip ospf interface command."
+    )
+    dut = "r1"
+    input_dict = {
+        "r1": {
+            "links": {
+                "r0": {
+                    "ospf6": {
+                        "timerIntervalsConfigHello": 11,
+                        "timerIntervalsConfigDead": 12,
+                    }
+                }
+            }
+        }
+    }
+    result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("modify hello timer from default value to r1 hello timer on r2")
+
+    topo1 = {
+        "r0": {
+            "links": {
+                "r1": {
+                    "interface": topo["routers"]["r0"]["links"]["r1"]["interface"],
+                    "ospf6": {"hello_interval": 11, "dead_interval": 12},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that new timer value is configured.")
+    input_dict = {
+        "r0": {
+            "links": {
+                "r1": {
+                    "ospf6": {
+                        "timerIntervalsConfigHello": 11,
+                        "timerIntervalsConfigDead": 12,
+                    }
+                }
+            }
+        }
+    }
+    dut = "r0"
+    result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that ospf neighbours are  full")
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
+    assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+        ospf_covergence
+    )
+
+    step("reconfigure the default hello timer value to default on r1 and r2")
+
+    topo1 = {
+        "r0": {
+            "links": {
+                "r1": {
+                    "interface": topo["routers"]["r0"]["links"]["r1"]["interface"],
+                    "ospf6": {"hello_interval": 10, "dead_interval": 40},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    topo1 = {
+        "r1": {
+            "links": {
+                "r0": {
+                    "interface": topo["routers"]["r1"]["links"]["r0"]["interface"],
+                    "ospf6": {"hello_interval": 10, "dead_interval": 40},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that new timer value is configured.")
+    input_dict = {
+        "r0": {
+            "links": {
+                "r1": {
+                    "ospf6": {
+                        "timerIntervalsConfigHello": 10,
+                        "timerIntervalsConfigDead": 40,
+                    }
+                }
+            }
+        }
+    }
+    dut = "r0"
+    result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that ospf neighbours are  full")
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
+    assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+        ospf_covergence
+    )
+
+    step("reconfigure the default hello timer value to default on r1 and r2")
+
+    topo1 = {
+        "r0": {
+            "links": {
+                "r1": {
+                    "interface": topo["routers"]["r0"]["links"]["r1"]["interface"],
+                    "ospf6": {"hello_interval": 10, "dead_interval": 40},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    topo1 = {
+        "r1": {
+            "links": {
+                "r0": {
+                    "interface": topo["routers"]["r1"]["links"]["r0"]["interface"],
+                    "ospf6": {"hello_interval": 10, "dead_interval": 40},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that new timer value is configured.")
+    input_dict = {
+        "r0": {
+            "links": {
+                "r1": {
+                    "ospf6": {
+                        "timerIntervalsConfigHello": 10,
+                        "timerIntervalsConfigDead": 40,
+                    }
+                }
+            }
+        }
+    }
+    dut = "r0"
+    result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that ospf neighbours are  full")
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
+    assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+        ospf_covergence
+    )
+
+    step("configure hello timer = 1 on r1 and r2")
+    topo1 = {
+        "r0": {
+            "links": {
+                "r1": {
+                    "interface": topo["routers"]["r0"]["links"]["r1"]["interface"],
+                    "ospf6": {"hello_interval": 1, "dead_interval": 4},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    topo1 = {
+        "r1": {
+            "links": {
+                "r0": {
+                    "interface": topo["routers"]["r1"]["links"]["r0"]["interface"],
+                    "ospf6": {"hello_interval": 1, "dead_interval": 4},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that new timer value is configured.")
+    input_dict = {
+        "r0": {
+            "links": {
+                "r1": {
+                    "ospf6": {
+                        "timerIntervalsConfigHello": 1,
+                        "timerIntervalsConfigDead": 4,
+                    }
+                }
+            }
+        }
+    }
+    dut = "r0"
+    result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that ospf neighbours are  full")
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
+    assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
+        ospf_covergence
+    )
+
+    step(" Configure hello timer = 65535")
+    topo1 = {
+        "r0": {
+            "links": {
+                "r1": {
+                    "interface": topo["routers"]["r0"]["links"]["r1"]["interface"],
+                    "ospf6": {"hello_interval": 65535, "dead_interval": 4},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    topo1 = {
+        "r1": {
+            "links": {
+                "r0": {
+                    "interface": topo["routers"]["r1"]["links"]["r0"]["interface"],
+                    "ospf6": {"hello_interval": 65535, "dead_interval": 4},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that new timer value is configured.")
+    input_dict = {
+        "r0": {
+            "links": {
+                "r1": {
+                    "ospf6": {
+                        "timerIntervalsConfigHello": 65535,
+                        "timerIntervalsConfigDead": 4,
+                    }
+                }
+            }
+        }
+    }
+    dut = "r0"
+    result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that ospf neighbours are  full")
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
+    assert ospf_covergence is True, "Testcase {} : Failed \n Error: {}".format(
+        tc_name, ospf_covergence
+    )
+    step(" Try configuring timer values outside range for example 65536")
+    topo1 = {
+        "r0": {
+            "links": {
+                "r1": {
+                    "interface": topo["routers"]["r0"]["links"]["r1"]["interface"],
+                    "ospf6": {"hello_interval": 65536, "dead_interval": 4},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Create interface failed. Error: {}".format(
+        tc_name, result
+    )
+
+    step("Unconfigure the hello timer from the interface from r1 and r2.")
+
+    topo1 = {
+        "r1": {
+            "links": {
+                "r0": {
+                    "interface": topo["routers"]["r1"]["links"]["r0"]["interface"],
+                    "ospf6": {"hello_interval": 65535},
+                    "delete": True,
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "Verify that timer value is deleted from intf & " "set to default value 40 sec."
+    )
+    input_dict = {"r1": {"links": {"r0": {"ospf6": {"timerIntervalsConfigHello": 10}}}}}
+    dut = "r1"
+    result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    write_test_footer(tc_name)
+
+
+def test_ospfv3_dead_tc11_p0(request):
+    """
+    OSPF timers.
+
+    Verify OSPF interface timer dead interval functionality
+    """
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    global topo
+    step("Bring up the base config as per the topology")
+    reset_config_on_routers(tgen)
+
+    step("modify dead interval from default value to some other value on r1")
+
+    topo1 = {
+        "r1": {
+            "links": {
+                "r0": {
+                    "interface": topo["routers"]["r1"]["links"]["r0"]["interface"],
+                    "ospf6": {"hello_interval": 12, "dead_interval": 48},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "verify that new timer value is configured and applied using "
+        "the show ip ospf interface command."
+    )
+    dut = "r1"
+    input_dict = {"r1": {"links": {"r0": {"ospf6": {"timerIntervalsConfigDead": 48}}}}}
+    result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("modify dead interval from default value to r1" "dead interval timer on r2")
+
+    topo1 = {
+        "r0": {
+            "links": {
+                "r1": {
+                    "interface": topo["routers"]["r0"]["links"]["r1"]["interface"],
+                    "ospf6": {"dead_interval": 48, "hello_interval": 12},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that new timer value is configured.")
+    input_dict = {"r0": {"links": {"r1": {"ospf6": {"timerIntervalsConfigDead": 48}}}}}
+    dut = "r0"
+    result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that ospf neighbours are  full")
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
+    assert ospf_covergence is True, "Testcase {} : Failed \n Error: {}".format(
+        tc_name, ospf_covergence
+    )
+
+    step("remove ospf on R0")
+    ospf_del = {"r0": {"ospf6": {"delete": True}}}
+    result = create_router_ospf(tgen, topo, ospf_del)
+    assert result is True, "Testcase : Failed \n Error: {}".format(result)
+
+    # reconfiguring deleted ospf process by resetting the configs.
+    reset_config_on_routers(tgen)
+
+    step("reconfigure the default dead interval timer value to " "default on r1 and r2")
+    topo1 = {
+        "r0": {
+            "links": {
+                "r1": {
+                    "interface": topo["routers"]["r0"]["links"]["r1"]["interface"],
+                    "ospf6": {"dead_interval": 40},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    topo1 = {
+        "r1": {
+            "links": {
+                "r0": {
+                    "interface": topo["routers"]["r1"]["links"]["r0"]["interface"],
+                    "ospf6": {"dead_interval": 40},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that new timer value is configured.")
+    input_dict = {"r0": {"links": {"r1": {"ospf6": {"timerIntervalsConfigDead": 40}}}}}
+    dut = "r0"
+    result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that ospf neighbours are  full")
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
+    assert ospf_covergence is True, "Testcase {} : Failed \n Error: {}".format(
+        tc_name, ospf_covergence
+    )
+
+    step(" Configure dead timer = 65535 on r1 and r2")
+
+    topo1 = {
+        "r0": {
+            "links": {
+                "r1": {
+                    "interface": topo["routers"]["r0"]["links"]["r1"]["interface"],
+                    "ospf6": {"dead_interval": 65535},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    topo1 = {
+        "r1": {
+            "links": {
+                "r0": {
+                    "interface": topo["routers"]["r1"]["links"]["r0"]["interface"],
+                    "ospf6": {"dead_interval": 65535},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that new timer value is configured.")
+    input_dict = {
+        "r0": {"links": {"r1": {"ospf6": {"timerIntervalsConfigDead": 65535}}}}
+    }
+    dut = "r0"
+    result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that ospf neighbours are  full")
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
+    assert ospf_covergence is True, "Testcase {} : Failed \n Error: {}".format(
+        tc_name, ospf_covergence
+    )
+
+    step(" Try configuring timer values outside range for example 65536")
+    topo1 = {
+        "r0": {
+            "links": {
+                "r1": {
+                    "interface": topo["routers"]["r0"]["links"]["r1"]["interface"],
+                    "ospf6": {"dead_interval": 65536},
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Create interface config failed. Error: {}".format(
+        tc_name, result
+    )
+
+    step("Unconfigure the dead timer from the interface from r1 and r2.")
+
+    topo1 = {
+        "r1": {
+            "links": {
+                "r0": {
+                    "interface": topo["routers"]["r1"]["links"]["r0"]["interface"],
+                    "ospf6": {"dead_interval": 65535},
+                    "delete": True,
+                }
+            }
+        }
+    }
+
+    result = create_interfaces_cfg(tgen, topo1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "Verify that timer value is deleted from intf & " "set to default value 40 sec."
+    )
+    input_dict = {"r1": {"links": {"r0": {"ospf6": {"timerIntervalsConfigDead": 40}}}}}
+    dut = "r1"
+    result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    write_test_footer(tc_name)
+
+
+def test_ospfv3_tc4_mtu_ignore_p0(request):
+    """
+    OSPF NFSM - MTU change
+
+    Verify NFSM events when ospf nbr changes with different MTU values
+    """
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    global topo
+    step(" Bring up the base config as per the topology")
+    step("Configure OSPF on all the routers of the topology.")
+    step("Verify that OSPF neighbors are FULL.")
+    reset_config_on_routers(tgen)
+
+    step(
+        "Modify the MTU to non default Value on R0 to R1 interface. "
+        "Reset ospf neighbors on R0."
+    )
+
+    rtr0 = tgen.routers()["r0"]
+    rtr1 = tgen.routers()["r1"]
+
+    r0_r1_intf = topo["routers"]["r0"]["links"]["r1"]["interface"]
+    r1_r0_intf = topo["routers"]["r1"]["links"]["r0"]["interface"]
+
+    rtr0.run("ifconfig {} mtu 1400".format(r0_r1_intf))
+
+    clear_ospf(tgen, "r0", ospf="ospf6")
+    clear_ospf(tgen, "r1", ospf="ospf6")
+
+    step(
+        "Verify that OSPF neighborship between R0 and R1 is stuck in Exstart" " State."
+    )
+    result = verify_ospf6_neighbor(tgen, topo, expected=False)
+    assert result is not True, (
+        "Testcase {} : Failed \n OSPF nbrs are Full "
+        "instead of Exstart. Error: {}".format(tc_name, result)
+    )
+
+    step(
+        "Verify that configured MTU value is updated in the show ip " "ospf interface."
+    )
+
+    dut = "r0"
+    input_dict = {"r0": {"links": {"r1": {"ospf6": {"interfaceMtu": 1400}}}}}
+    result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "Modify the MTU to non default Value on R0 to R1 interface. "
+        "Reset ospf neighbors on R0."
+    )
+    rtr0.run("ifconfig {} mtu 1500".format(r0_r1_intf))
+
+    clear_ospf(tgen, "r0", ospf="ospf6")
+
+    step("Verify that OSPF neighborship between R0 and R1 becomes full.")
+    result = verify_ospf6_neighbor(tgen, topo)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "Configure mtu ignore and change the value of the mtu to non default"
+        " on R0 to R1 interface. Reset ospf neighbors on R0."
+    )
+    r0_ospf_mtu = {"r0": {"links": {"r1": {"ospf6": {"mtu_ignore": True}}}}}
+    result = config_ospf6_interface(tgen, topo, r0_ospf_mtu)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+    dut = "r0"
+    input_dict = {"r0": {"links": {"r1": {"ospf6": {"mtuMismatchDetection": True}}}}}
+    result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    r1_ospf_mtu = {"r1": {"links": {"r0": {"ospf6": {"mtu_ignore": True}}}}}
+    result = config_ospf6_interface(tgen, topo, r1_ospf_mtu)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+    rtr0.run("ifconfig {} mtu 1400".format(r0_r1_intf))
+
+    clear_ospf(tgen, "r0", ospf="ospf6")
+
+    step("Verify that OSPF neighborship between R0 and R1 becomes full.")
+    result = verify_ospf6_neighbor(tgen, topo)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "Unconfigure mtu-ignore command from the interface. "
+        "Reset ospf neighbors on R0."
+    )
+
+    r1_ospf_mtu = {
+        "r1": {"links": {"r0": {"ospf6": {"mtu_ignore": True, "delete": True}}}}
+    }
+    result = config_ospf6_interface(tgen, topo, r1_ospf_mtu)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+    clear_ospf(tgen, "r0", ospf="ospf6")
+
+    step(
+        "Verify that OSPF neighborship between R0 and R1 is stuck in Exstart" " State."
+    )
+    result = verify_ospf6_neighbor(tgen, topo, expected=False)
+    assert result is not True, (
+        "Testcase {} : Failed \n OSPF nbrs are Full "
+        "instead of Exstart. Error: {}".format(tc_name, result)
+    )
+
+    step("Modify the MTU to again default valaue on R0 to R1 interface.")
+
+    rtr0.run("ifconfig {} mtu 1500".format(r0_r1_intf))
+
+    clear_ospf(tgen, "r0", ospf="ospf6")
+
+    step("Verify that OSPF neighborship between R0 and R1 becomes full.")
+    result = verify_ospf6_neighbor(tgen, topo)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "Configure ospf interface with jumbo MTU (9216)." "Reset ospf neighbors on R0."
+    )
+
+    rtr0.run("ifconfig {} mtu 9216".format(r0_r1_intf))
+    rtr1.run("ifconfig {} mtu 9216".format(r1_r0_intf))
+
+    clear_ospf(tgen, "r0", ospf="ospf6")
+    clear_ospf(tgen, "r1", ospf="ospf6")
+
+    step("Verify that OSPF neighborship between R0 and R1 becomes full.")
+    result = verify_ospf6_neighbor(tgen, topo)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Verify that jumbo MTU is updated in the show ip ospf interface.")
+    dut = "r0"
+    input_dict = {"r0": {"links": {"r1": {"ospf6": {"interfaceMtu": 9216}}}}}
+    result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    write_test_footer(tc_name)
+
+
+def test_ospfv3_show_p1(request):
+    """Verify ospf show commands with json output."""
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    input_dict = {"r2": {"debug": {"log_file": "debug.log", "enable": ["ospf6"]}}}
+
+    result = create_debug_log_config(tgen, input_dict)
+
+    # Code coverage steps #Do Not upstream
+    input_dict_config = {
+        "r1": {
+            "raw_config": [
+                "end",
+                "debug ospf6 event",
+                "debug ospf6 gr helper",
+                "debug ospf6 ism events",
+                "debug ospf6 ism status",
+                "debug ospf6 ism timers",
+                "debug ospf6 nsm events",
+                "debug ospf6 nsm status",
+                "debug ospf6 nsm timers ",
+                "debug ospf6 nssa",
+                "debug ospf6 lsa aggregate",
+                "debug ospf6 lsa flooding ",
+                "debug ospf6 lsa generate",
+                "debug ospf6 lsa install ",
+                "debug ospf6 lsa refresh",
+                "debug ospf6 packet all detail",
+                "debug ospf6 packet all recv",
+                "debug ospf6 packet all send",
+                "debug ospf6 packet dd detail",
+                "debug ospf6 packet dd recv",
+                "debug ospf6 packet dd send ",
+                "debug ospf6 packet hello detail",
+                "debug ospf6 packet hello recv",
+                "debug ospf6 packet hello send",
+                "debug ospf6 packet ls-ack detail",
+                "debug ospf6 packet ls-ack recv",
+                "debug ospf6 packet ls-ack send",
+                "debug ospf6 packet ls-request detail",
+                "debug ospf6 packet ls-request recv",
+                "debug ospf6 packet ls-request send",
+                "debug ospf6 packet ls-update detail",
+                "debug ospf6 packet ls-update recv",
+                "debug ospf6 packet ls-update send",
+                "debug ospf6 sr",
+                "debug ospf6 te ",
+                "debug ospf6 zebra interface",
+                "debug ospf6 zebra redistribute",
+            ]
+        }
+    }
+
+    apply_raw_config(tgen, input_dict_config)
+
+    for rtr in topo["routers"]:
+        clear_ospf(tgen, rtr, ospf="ospf6")
+
+    step(" Bring up the base config as per the topology")
+    reset_config_on_routers(tgen)
+
+    for rtr in topo["routers"]:
+        clear_ospf(tgen, rtr, ospf="ospf6")
+
+    dut = "r1"
+    input_dict = {
+        "r1": {
+            "links": {
+                "r0": {
+                    "ospf6": {
+                        "status": "up",
+                        "type": "BROADCAST",
+                        "ospf6Enabled": True,
+                        "attachedToArea": True,
+                        "instanceId": 0,
+                        "interfaceMtu": 1500,
+                        "autoDetect": 1500,
+                        "mtuMismatchDetection": "enabled",
+                        "areaId": "0.0.0.0",
+                        "cost": 10,
+                        "transmitDelaySec": 1,
+                        "priority": 1,
+                        "timerIntervalsConfigHello": 1,
+                        "timerIntervalsConfigDead": 4,
+                        "timerIntervalsConfigRetransmit": 5,
+                        "dr": "0.0.0.0",
+                        "bdr": "0.0.0.0",
+                        "numberOfInterfaceScopedLsa": 2,
+                        "pendingLsaLsUpdateCount": 0,
+                        "lsUpdateSendThread": "off",
+                        "pendingLsaLsAckCount": 0,
+                        "lsAckSendThread": "off",
+                    }
+                }
+            }
+        }
+    }
+    result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    ip = topo["routers"]["r0"]["links"]["r3"]["ipv6"]
+    ip_net = str(ipaddress.ip_interface(u"{}".format(ip)).network)
+    nh = topo["routers"]["r0"]["links"]["r1"]["ipv6"].split("/")[0]
+    input_dict = {
+        "r1": {
+            "static_routes": [
+                {"network": ip_net, "no_of_ip": 1, "routeType": "Network"}
+            ]
+        }
+    }
+
+    dut = "r1"
+    result = verify_ospf6_rib(tgen, dut, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    write_test_footer(tc_name)
+
+
+def ospfv3_router_id_tc14_p2(request):
+    """OSPF Router ID - Verify OSPF router id changes."""
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    global topo
+    step(" Bring up the base config as per the topology")
+    reset_config_on_routers(tgen)
+
+    step("Configure system router id as 1.1.1.1 on R1 , clear ospf router")
+    ospf_rid = {"r0": {"ospf6": {"router_id": "1.1.1.1"}}}
+    result = create_router_ospf(tgen, topo, ospf_rid)
+    assert result is True, "Testcase : Failed \n Error: {}".format(result)
+
+    step("configure ospf router id as 1.1.1.2 on R1, clear ospf router")
+    ospf_rid = {"r1": {"ospf6": {"router_id": "1.1.1.2"}}}
+    result = create_router_ospf(tgen, topo, ospf_rid)
+    assert result is True, "Testcase : Failed \n Error: {}".format(result)
+
+    topo1 = deepcopy(topo)
+    step("Verify that OSPF takes system router ID as ospf router id.")
+
+    topo1["routers"]["r0"]["ospf6"]["router_id"] = "1.1.1.1"
+    topo1["routers"]["r1"]["ospf6"]["router_id"] = "1.1.1.2"
+
+    for rtr in topo["routers"]:
+        clear_ospf(tgen, rtr, ospf="ospf6")
+
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo1)
+    assert ospf_covergence is True, "OSPF NBRs not up.Failed \n Error:" " {}".format(
+        ospf_covergence
+    )
+
+    step(" delete ospf router id and clear ospf process.")
+    ospf_rid = {"r0": {"ospf6": {"del_router_id": "1.1.1.1"}}}
+    result = create_router_ospf(tgen, topo, ospf_rid)
+    assert result is True, "Testcase : Failed \n Error: {}".format(result)
+
+    ospf_rid = {"r1": {"ospf6": {"del_router_id": "1.1.1.2"}}}
+    result = create_router_ospf(tgen, topo, ospf_rid)
+    assert result is True, "Testcase : Failed \n Error: {}".format(result)
+
+    reset_config_on_routers(tgen)
+
+    step(" Configure R0 R1 R2 with same router ids")
+    ospf_rid = {"r0": {"ospf6": {"router_id": "1.1.1.1"}}}
+    result = create_router_ospf(tgen, topo, ospf_rid)
+    assert result is True, "Testcase : Failed \n Error: {}".format(result)
+
+    step("configure ospf router id as 1.1.1.2 on R1, reboot router")
+    ospf_rid = {"r1": {"ospf6": {"router_id": "1.1.1.1"}}}
+    result = create_router_ospf(tgen, topo, ospf_rid)
+    assert result is True, "Testcase : Failed \n Error: {}".format(result)
+
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo, expected=False)
+    assert (
+        ospf_covergence is not True
+    ), "OSPF NBRs are up.Failed \n Error:" " {}".format(ospf_covergence)
+    topo1 = {}
+    topo1 = deepcopy(topo)
+
+    for rtr in ["r1", "r2", "r3", "r0"]:
+        topo1["routers"][rtr]["ospf6"].pop("router_id")
+
+    build_config_from_json(tgen, topo1, save_bkup=False)
+
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo)
+    assert ospf_covergence is not True, (
+        "Testcase {} :Failed \n Neighborship "
+        "should not up as no router id is configured. Error: {}".format(tc_name, result)
+    )
+
+    step("Clear ospf process and check nbrs should not be up.")
+    for rtr in topo["routers"]:
+        clear_ospf(tgen, rtr, ospf="ospf6")
+
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo)
+    assert ospf_covergence is not True, (
+        "Testcase {} :Failed \n Neighborship "
+        "should not up as no router id is configured. Error: {}".format(tc_name, result)
+    )
+
+    topo1 = deepcopy(topo)
+
+    step("Configure system router id on routers , clear ospf router")
+    ospf_rid = {
+        "r0": {"ospf6": {"router_id": "1.1.1.1"}},
+        "r1": {"ospf6": {"router_id": "1.1.1.2"}},
+        "r2": {"ospf6": {"router_id": "1.1.1.3"}},
+        "r3": {"ospf6": {"router_id": "1.1.1.4"}},
+    }
+    result = create_router_ospf(tgen, topo1, ospf_rid)
+    assert result is True, "Testcase : Failed \n Error: {}".format(result)
+
+    topo1["routers"]["r0"]["ospf6"]["router_id"] = "1.1.1.1"
+    topo1["routers"]["r1"]["ospf6"]["router_id"] = "1.1.1.2"
+    topo1["routers"]["r2"]["ospf6"]["router_id"] = "1.1.1.3"
+    topo1["routers"]["r3"]["ospf6"]["router_id"] = "1.1.1.4"
+
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo1)
+    assert ospf_covergence is True, "OSPF NBRs not up.Failed \n Error:" " {}".format(
+        ospf_covergence
+    )
+
+    step(" Bring up the base config as per the topology")
+    reset_config_on_routers(tgen)
+
+    ospf_covergence = verify_ospf6_neighbor(tgen, topo)
+    assert ospf_covergence is True, "OSPF NBRs not up.Failed \n Error:" " {}".format(
+        ospf_covergence
+    )
+
+    write_test_footer(tc_name)
+
+
 if __name__ == "__main__":
     args = ["-s"] + sys.argv[1:]
     sys.exit(pytest.main(args))