mirror of
https://gitee.com/willfree/mlsr.git
synced 2026-06-03 15:56:13 +08:00
294 lines
9.1 KiB
Go
294 lines
9.1 KiB
Go
// Package route
|
|
// @Author: Wang Feng
|
|
// @Description:
|
|
// @Version: 0.1.0
|
|
// @Date: 2022/5/30 10:57
|
|
// @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
|
|
//
|
|
|
|
package route
|
|
|
|
import (
|
|
"fmt"
|
|
common2 "minlib/common"
|
|
"minlib/component"
|
|
"minlib/logicface"
|
|
"mlsr/common"
|
|
"mlsr/lsa"
|
|
"mlsr/lsdb"
|
|
"strconv"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
//
|
|
// testCreateAdjLsa
|
|
// @Description: 构造邻接lsa
|
|
// @param uri
|
|
// @return *lsa.AdjLsa
|
|
//
|
|
func testCreateAdjLsa(uri string) *lsa.AdjLsa {
|
|
base := new(lsa.AdjLsa)
|
|
timeExpire := time.Now()
|
|
timeExpire = timeExpire.Add(30 * time.Minute)
|
|
base.SetLsaExpirationTime(uint64(timeExpire.UnixMilli()))
|
|
base.SetLsaSequenceNumber(1234)
|
|
base.LsaOriginRouterIdentifier, _ = component.CreateIdentifierByString(uri)
|
|
return base
|
|
}
|
|
|
|
//
|
|
// testCreateAdjInfo
|
|
// @Description: 构造邻接信息
|
|
// @param cost
|
|
// @param uri
|
|
// @return *lsa.AdjLsaAdjacencyInfo
|
|
//
|
|
func testCreateAdjInfo(cost uint64, uri string) *lsa.AdjLsaAdjacencyInfo {
|
|
linkCost := lsa.AdjLsaLinkCost{}
|
|
linkCost.SetLinkCost(cost)
|
|
faceUri := lsa.AdjLsaLogicFaceUri{}
|
|
faceUri.SetLogicFaceUri("uri")
|
|
faceId := lsa.AdjLsaLogicFaceId{}
|
|
faceId.SetLogicFaceId(77)
|
|
iden, _ := component.CreateIdentifierByString(uri)
|
|
adjInfo := lsa.NewAdjLsaAdjacencyInfo(linkCost, faceUri, faceId, iden, 123, 1)
|
|
return adjInfo
|
|
}
|
|
|
|
//
|
|
// TestLinkStateRoutingTableCalculator_CalculateOnePath
|
|
// @Description: 测试普通的最短路径计算。测试已通过。
|
|
// @param t
|
|
//
|
|
func TestLinkStateRoutingTableCalculator_CalculateOnePath(t *testing.T) {
|
|
// 1. 构造邻接状态路由表计算器
|
|
rtc := new(LinkStateRoutingTableCalculator)
|
|
|
|
// 1.1 构造LSDB
|
|
// 配置文件初始化
|
|
mlsrConfig, err := common.ParseConfig(testConfigPath)
|
|
if err != nil {
|
|
fmt.Println("配置文件解析错误")
|
|
}
|
|
// 调度器初始化
|
|
sche := new(lsdb.MlsrScheduler)
|
|
sche.Init()
|
|
// LogicFace初始化(假设初始化,暂时用不到)
|
|
face := new(logicface.LogicFace)
|
|
// LSDB初始化
|
|
mlsdb := new(lsdb.Lsdb)
|
|
mlsdb.Init(mlsrConfig, sche, face)
|
|
// 安装本机adjlsa
|
|
mlsdb.BuildAndInstallOwnAdjLsa()
|
|
// 传入一些其它虚拟lsa,这些lsa与本机lsa共同形成一个小型路由拓扑
|
|
// 路由器B
|
|
adjLsaB := testCreateAdjLsa("/routerB")
|
|
adjInfoBA := testCreateAdjInfo(10, "/min/pkusz/routerA")
|
|
adjInfoBE := testCreateAdjInfo(50, "/routerE")
|
|
adjLsaB.Insert(adjInfoBA)
|
|
adjLsaB.Insert(adjInfoBE)
|
|
// 路由器C
|
|
adjLsaC := testCreateAdjLsa("/routerC")
|
|
adjInfoCA := testCreateAdjInfo(100, "/min/pkusz/routerA")
|
|
adjInfoCE := testCreateAdjInfo(10, "/routerE")
|
|
adjInfoCD := testCreateAdjInfo(60, "/routerD")
|
|
adjLsaC.Insert(adjInfoCA)
|
|
adjLsaC.Insert(adjInfoCD)
|
|
adjLsaC.Insert(adjInfoCE)
|
|
// 路由器E
|
|
adjLsaE := testCreateAdjLsa("/routerE")
|
|
adjInfoEB := testCreateAdjInfo(50, "/routerB")
|
|
adjInfoEC := testCreateAdjInfo(10, "/routerC")
|
|
adjInfoED := testCreateAdjInfo(20, "/routerD")
|
|
adjLsaE.Insert(adjInfoEB)
|
|
adjLsaE.Insert(adjInfoEC)
|
|
adjLsaE.Insert(adjInfoED)
|
|
// 路由器D
|
|
adjLsaD := testCreateAdjLsa("/routerD")
|
|
adjInfoDA := testCreateAdjInfo(30, "/min/pkusz/routerA")
|
|
adjInfoDC := testCreateAdjInfo(60, "/routerC")
|
|
adjInfoDE := testCreateAdjInfo(20, "/routerE")
|
|
adjLsaD.Insert(adjInfoDA)
|
|
adjLsaD.Insert(adjInfoDC)
|
|
adjLsaD.Insert(adjInfoDE)
|
|
mlsdb.InstallLsa(adjLsaB)
|
|
mlsdb.InstallLsa(adjLsaC)
|
|
mlsdb.InstallLsa(adjLsaD)
|
|
mlsdb.InstallLsa(adjLsaE)
|
|
// 1.2 构造RouterMap
|
|
lsas, err := mlsdb.GetLSAsByType(lsa.LsaADJACENCYType)
|
|
if err != nil {
|
|
common2.LogError("Get Lsa in calculateLsRoutingTable error, ", err)
|
|
}
|
|
common2.LogInfo("邻接lsa数目: ", len(lsas))
|
|
rMap := new(RouterMap)
|
|
rMap.Init()
|
|
err = rMap.CreateFromAdjLsdb(lsas)
|
|
// 打印rm
|
|
common2.LogInfo(rMap.ToString())
|
|
|
|
// 1.3 根据RouterMap,和lsdb中的adjlsa,构造邻接矩阵
|
|
// 设置路由器数目
|
|
rtc.SetRouterNum(rMap.GetMapSize())
|
|
// 分配矩阵空间
|
|
rtc.allocateAdjMatrix()
|
|
// 初始化矩阵值
|
|
rtc.initMatrix()
|
|
// 构造矩阵
|
|
err = rtc.makeAdjMatrix(mlsdb, rMap)
|
|
if err != nil {
|
|
common2.LogError("邻接矩阵构造失败")
|
|
}
|
|
|
|
// 1.4 打印输出路由表计算器
|
|
fmt.Println(rMap.ToString())
|
|
fmt.Println(rtc.ToString())
|
|
fmt.Println("源路由器的邻接数目:", rtc.getNumOfLinkfromAdjMatrix(0))
|
|
fmt.Println("另一个路由器的邻接数目:", rtc.getNumOfLinkfromAdjMatrix(1))
|
|
|
|
// 2. 执行单源最短路径算法
|
|
rtc.allocateParent()
|
|
rtc.allocateDistance()
|
|
rtc.doDijkstraPathCalculation(0)
|
|
// 查看执行结果
|
|
// 计算器中的上一跳路径,以及开销
|
|
fmt.Println(rtc.ToString())
|
|
// 计算器获取的针对每个目的路由器的下一跳,及开销。
|
|
names, nexthops := rtc.addAllLsNextHopsToRoutingTable(mlsrConfig.GetAdjacencys(), rMap, 0)
|
|
for i := 0; i < len(names); i++ {
|
|
fmt.Println(names[i].ToUri() + " ")
|
|
}
|
|
fmt.Println("")
|
|
for i := 0; i < len(nexthops); i++ {
|
|
fmt.Println(nexthops[i].LogicFaceUri() + "-" +
|
|
strconv.FormatUint(nexthops[i].RouteCost.RouteCost(), 10) + " ")
|
|
}
|
|
}
|
|
|
|
//
|
|
// TestLinkStateRoutingTableCalculator_CalculateMutilPath
|
|
// @Description: 测试多路径计算
|
|
// @param t
|
|
//
|
|
func TestLinkStateRoutingTableCalculator_CalculateMutilPath(t *testing.T) {
|
|
// 1. 构造邻接状态路由表计算器
|
|
rtc := new(LinkStateRoutingTableCalculator)
|
|
|
|
// 1.1 构造LSDB
|
|
// 配置文件初始化
|
|
mlsrConfig, err := common.ParseConfig(testConfigPath)
|
|
if err != nil {
|
|
fmt.Println("配置文件解析错误")
|
|
}
|
|
// 调度器初始化
|
|
sche := new(lsdb.MlsrScheduler)
|
|
sche.Init()
|
|
// LogicFace初始化(假设初始化,暂时用不到)
|
|
face := new(logicface.LogicFace)
|
|
// LSDB初始化
|
|
mlsdb := new(lsdb.Lsdb)
|
|
mlsdb.Init(mlsrConfig, sche, face)
|
|
// 安装本机adjlsa
|
|
mlsdb.BuildAndInstallOwnAdjLsa()
|
|
// 传入一些其它虚拟lsa,这些lsa与本机lsa共同形成一个小型路由拓扑
|
|
// 路由器B
|
|
adjLsaB := testCreateAdjLsa("/routerB")
|
|
adjInfoBA := testCreateAdjInfo(10, "/min/pkusz/routerA")
|
|
adjInfoBE := testCreateAdjInfo(50, "/routerE")
|
|
adjLsaB.Insert(adjInfoBA)
|
|
adjLsaB.Insert(adjInfoBE)
|
|
// 路由器C
|
|
adjLsaC := testCreateAdjLsa("/routerC")
|
|
adjInfoCA := testCreateAdjInfo(100, "/min/pkusz/routerA")
|
|
adjInfoCE := testCreateAdjInfo(10, "/routerE")
|
|
adjInfoCD := testCreateAdjInfo(60, "/routerD")
|
|
adjLsaC.Insert(adjInfoCA)
|
|
adjLsaC.Insert(adjInfoCD)
|
|
adjLsaC.Insert(adjInfoCE)
|
|
// 路由器E
|
|
adjLsaE := testCreateAdjLsa("/routerE")
|
|
adjInfoEB := testCreateAdjInfo(50, "/routerB")
|
|
adjInfoEC := testCreateAdjInfo(10, "/routerC")
|
|
adjInfoED := testCreateAdjInfo(20, "/routerD")
|
|
adjLsaE.Insert(adjInfoEB)
|
|
adjLsaE.Insert(adjInfoEC)
|
|
adjLsaE.Insert(adjInfoED)
|
|
// 路由器D
|
|
adjLsaD := testCreateAdjLsa("/routerD")
|
|
adjInfoDA := testCreateAdjInfo(30, "/min/pkusz/routerA")
|
|
adjInfoDC := testCreateAdjInfo(60, "/routerC")
|
|
adjInfoDE := testCreateAdjInfo(20, "/routerE")
|
|
adjLsaD.Insert(adjInfoDA)
|
|
adjLsaD.Insert(adjInfoDC)
|
|
adjLsaD.Insert(adjInfoDE)
|
|
mlsdb.InstallLsa(adjLsaB)
|
|
mlsdb.InstallLsa(adjLsaC)
|
|
mlsdb.InstallLsa(adjLsaD)
|
|
mlsdb.InstallLsa(adjLsaE)
|
|
// 1.2 构造RouterMap
|
|
lsas, err := mlsdb.GetLSAsByType(lsa.LsaADJACENCYType)
|
|
if err != nil {
|
|
common2.LogError("Get Lsa in calculateLsRoutingTable error, ", err)
|
|
}
|
|
common2.LogInfo("邻接lsa数目: ", len(lsas))
|
|
rMap := new(RouterMap)
|
|
rMap.Init()
|
|
err = rMap.CreateFromAdjLsdb(lsas)
|
|
// 打印rm
|
|
common2.LogInfo(rMap.ToString())
|
|
|
|
// 1.3 根据RouterMap,和lsdb中的adjlsa,构造邻接矩阵
|
|
// 设置路由器数目
|
|
rtc.SetRouterNum(rMap.GetMapSize())
|
|
// 分配矩阵空间
|
|
rtc.allocateAdjMatrix()
|
|
// 初始化矩阵值
|
|
rtc.initMatrix()
|
|
// 构造矩阵
|
|
err = rtc.makeAdjMatrix(mlsdb, rMap)
|
|
if err != nil {
|
|
common2.LogError("邻接矩阵构造失败")
|
|
}
|
|
|
|
// 1.4 打印输出路由表计算器
|
|
fmt.Println(rMap.ToString())
|
|
fmt.Println(rtc.ToString())
|
|
fmt.Println("源路由器的邻接数目:", rtc.getNumOfLinkfromAdjMatrix(0))
|
|
fmt.Println("另一个路由器的邻接数目:", rtc.getNumOfLinkfromAdjMatrix(1))
|
|
|
|
// 2. 执行多路径算法
|
|
rtc.allocateParent()
|
|
rtc.allocateDistance()
|
|
// 2.1. 先确定源路由器的邻居路由器数目
|
|
rtc.setNoLink(rtc.getNumOfLinkfromAdjMatrix(0))
|
|
rtc.allocateLinks()
|
|
rtc.allocateLinkCosts()
|
|
// 2.2. 获取用于路径计算的稀疏邻接列表。具体操作是填充:c.links,c.linkCosts
|
|
rtc.getLinksFromAdjMatrix(0)
|
|
//
|
|
routers := []*component.Identifier{} // 路由器标识
|
|
nexthops := []*NextHop{} // 下一跳
|
|
for i := 0; i < rtc.vNoLink; i++ {
|
|
// 模拟只有当前邻居i可以访问的情形。即:砍掉除当前邻居路由器外的其他邻接链路
|
|
rtc.adjustAdMatrix(0, rtc.links[i], rtc.linkCosts[i])
|
|
// 以当前邻居为起点,执行Dijkstra算法。
|
|
rtc.doDijkstraPathCalculation(0)
|
|
// 用计算结果更新路由表。
|
|
rs, ns := rtc.addAllLsNextHopsToRoutingTable(mlsrConfig.GetAdjacencys(), rMap, 0)
|
|
routers = append(routers, rs...)
|
|
nexthops = append(nexthops, ns...)
|
|
}
|
|
// 查看执行结果
|
|
// 计算器中的上一跳路径,以及开销
|
|
fmt.Println(rtc.ToString())
|
|
for i := 0; i < len(routers); i++ {
|
|
fmt.Println(routers[i].ToUri() + " ")
|
|
}
|
|
fmt.Println("")
|
|
for i := 0; i < len(nexthops); i++ {
|
|
fmt.Println(nexthops[i].LogicFaceUri() + "-" +
|
|
strconv.FormatUint(nexthops[i].RouteCost.RouteCost(), 10) + " ")
|
|
}
|
|
}
|