diff options
| author | Donatas Abraitis <donatas@opensourcerouting.org> | 2022-10-27 07:26:35 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-27 07:26:35 +0100 |
| commit | 2ab7bfffde9657d658afbd31f36161b9b453d84a (patch) | |
| tree | e107e1951b850d678ca045923f82d62fdad90547 | |
| parent | 7d92ea97e216141b28a9a15098929010666ef202 (diff) | |
| parent | 74fc2957ce09a7128dd036ecd19c38c5f4adf1b9 (diff) | |
Merge pull request #12206 from FRRouting/mergify/bp/dev/8.4/pr-12179
ospf: optimization for FRR's P2MP mode (backport #12179)
| -rw-r--r-- | ospfd/ospf_flood.c | 7 | ||||
| -rw-r--r-- | ospfd/ospf_packet.c | 3 | ||||
| -rw-r--r-- | tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py | 156 |
3 files changed, 164 insertions, 2 deletions
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index e686a93ba9..c2af09a679 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -648,6 +648,13 @@ int ospf_flood_through_interface(struct ospf_interface *oi, OSPF_SEND_PACKET_DIRECT); } } else + /* Optimization: for P2MP interfaces, + don't send back out the incoming interface immediately, + allow time to rx multicast ack to the rx'ed (multicast) + update */ + if (retx_flag != 1 || + oi->type != OSPF_IFTYPE_POINTOMULTIPOINT || inbr == NULL || + oi != inbr->oi) ospf_ls_upd_send_lsa(oi->nbr_self, lsa, OSPF_SEND_PACKET_INDIRECT); diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 57643f637e..466b5fa2a2 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -4220,7 +4220,8 @@ static void ospf_ls_ack_send_list(struct ospf_interface *oi, struct list *ack, op->length = length; /* Decide destination address. */ - if (oi->type == OSPF_IFTYPE_POINTOPOINT) + if (oi->type == OSPF_IFTYPE_POINTOPOINT || + oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) op->dst.s_addr = htonl(OSPF_ALLSPFROUTERS); else op->dst.s_addr = dst.s_addr; diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py b/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py index 3b84a99cdf..e131fba0c3 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py @@ -47,10 +47,12 @@ from lib.common_config import ( step, create_interfaces_cfg, topo_daemons, + retry, + run_frr_cmd, ) from lib.topolog import logger from lib.topojson import build_config_from_json -from lib.topotest import frr_unicode +from lib.topotest import frr_unicode, json_cmp from lib.ospf import ( verify_ospf_interface, @@ -378,6 +380,158 @@ def test_ospf_p2mp_tc1_p0(request): write_test_footer(tc_name) +@retry(retry_timeout=30) +def verify_ospf_json(tgen, dut, input_dict, cmd="show ip ospf database json"): + del tgen + show_ospf_json = run_frr_cmd(dut, cmd, isjson=True) + if not bool(show_ospf_json): + return "ospf is not running" + result = json_cmp(show_ospf_json, input_dict) + return str(result) if result else None + + +@pytest.mark.parametrize("tgen", [2], indirect=True) +def test_ospf_nbrs(tgen): + db_full = { + "areas": { + "0.0.0.0": { + "routerLinkStates": [ + { + "lsId": "100.1.1.0", + "advertisedRouter": "100.1.1.0", + "numOfRouterLinks": 6, + }, + { + "lsId": "100.1.1.1", + "advertisedRouter": "100.1.1.1", + "numOfRouterLinks": 6, + }, + { + "lsId": "100.1.1.2", + "advertisedRouter": "100.1.1.2", + "numOfRouterLinks": 6, + }, + { + "lsId": "100.1.1.3", + "advertisedRouter": "100.1.1.3", + "numOfRouterLinks": 7, + }, + ] + } + } + } + input = [ + [ + "r0", + "show ip ospf n json", + { + "neighbors": { + "100.1.1.1": [ + { + "state": "Full/DROther", + } + ], + "100.1.1.2": [ + { + "state": "Full/DROther", + } + ], + "100.1.1.3": [ + { + "state": "Full/DROther", + } + ], + } + }, + ], + [ + "r1", + "show ip ospf n json", + { + "neighbors": { + "100.1.1.0": [ + { + "state": "Full/DROther", + } + ], + "100.1.1.2": [ + { + "state": "Full/DROther", + } + ], + "100.1.1.3": [ + { + "state": "Full/DROther", + } + ], + } + }, + ], + [ + "r2", + "show ip ospf n json", + { + "neighbors": { + "100.1.1.0": [ + { + "state": "Full/DROther", + } + ], + "100.1.1.1": [ + { + "state": "Full/DROther", + } + ], + "100.1.1.3": [ + { + "state": "Full/DROther", + } + ], + } + }, + ], + [ + "r3", + "show ip ospf n json", + { + "neighbors": { + "100.1.1.0": [ + { + "state": "Full/DROther", + } + ], + "100.1.1.1": [ + { + "state": "Full/DROther", + } + ], + "100.1.1.2": [ + { + "state": "Full/DROther", + } + ], + } + }, + ], + ["r0", "show ip ospf database json", db_full], + ["r1", "show ip ospf database json", db_full], + ["r2", "show ip ospf database json", db_full], + ["r3", "show ip ospf database json", db_full], + ["r0", "show ip ospf database json", db_full], + ["r0", "show ip ospf database router json", {}], + ["r0", "show ip ospf interface traffic json", {}], + ["r1", "show ip ospf interface traffic json", {}], + ["r2", "show ip ospf interface traffic json", {}], + ["r3", "show ip ospf interface traffic json", {}], + ] + for cmd_set in input: + step("test_ospf: %s - %s" % (cmd_set[0], cmd_set[1])) + assert ( + verify_ospf_json(tgen, tgen.gears[cmd_set[0]], cmd_set[2], cmd_set[1]) + is None + ) + + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) |
