mirror of
https://gitee.com/willfree/mlsr.git
synced 2026-06-17 16:20:25 +08:00
229 lines
5.3 KiB
Go
229 lines
5.3 KiB
Go
// Package route
|
|
// @Author: Wang Feng
|
|
// @Description:
|
|
// @Version: 0.1.0
|
|
// @Date: 2022/5/5 20:44
|
|
// @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
|
|
//
|
|
|
|
package route
|
|
|
|
import (
|
|
"errors"
|
|
"minlib/encoding"
|
|
"mlsr/extensions"
|
|
"strconv"
|
|
)
|
|
|
|
type NextHopContainer []*NextHop
|
|
|
|
//
|
|
// NextHopList
|
|
// @Description: 下一跳列表
|
|
//
|
|
type NextHopList struct {
|
|
encoding.SelfEncodingBase
|
|
nextHops NextHopContainer
|
|
}
|
|
|
|
//
|
|
// ToString
|
|
// @Description: 转string。用于测试
|
|
// @receiver l
|
|
// @return string
|
|
//
|
|
func (l *NextHopList) ToString() string {
|
|
res := "----------------\n"
|
|
for i := 0; i < len(l.nextHops); i++ {
|
|
res += l.nextHops[i].LogicFaceUri() + " "
|
|
res += strconv.FormatUint(l.nextHops[i].RouteCost.RouteCost(), 10) + " "
|
|
res += strconv.FormatBool(l.nextHops[i].IsHyperbolic) + " \n"
|
|
}
|
|
res += "----------------\n"
|
|
return res
|
|
}
|
|
|
|
//
|
|
// GetNextHops
|
|
// @Description: 获取下一跳列表
|
|
// @receiver l
|
|
// @return []*NextHop
|
|
//
|
|
func (l *NextHopList) GetNextHops() []*NextHop {
|
|
return l.nextHops
|
|
}
|
|
|
|
//
|
|
// findSameUriNextHop
|
|
// @Description: 找到uri一致的下一跳表项
|
|
// @receiver l
|
|
// @param hop
|
|
// @return int 找不到时,返回-1
|
|
//
|
|
func (l *NextHopList) findSameUriNextHop(hop *NextHop) int {
|
|
for i := 0; i < len(l.nextHops); i++ {
|
|
if l.nextHops[i].LogicFaceUri() == hop.LogicFaceUri() {
|
|
return i
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
//
|
|
// findSameNextHop
|
|
// @Description: 找到uri和cost都一致的下一跳表项
|
|
// @receiver l
|
|
// @param hop
|
|
// @return int 找不到,返回-1
|
|
//
|
|
func (l *NextHopList) findSameNextHop(hop *NextHop) int {
|
|
for i := 0; i < len(l.nextHops); i++ {
|
|
if (l.nextHops[i].LogicFaceUri() == hop.LogicFaceUri()) &&
|
|
(l.nextHops[i].RouteCost.RouteCost() == hop.RouteCost.RouteCost()) {
|
|
return i
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
//
|
|
// AddNextHop
|
|
// @Description: 增加一个下一跳表项。1. 如果不存在同uri,则插入;2. 如果存在,但cost不同,则按照新的下一跳来更新它
|
|
// @receiver l
|
|
// @param hop
|
|
//
|
|
func (l *NextHopList) AddNextHop(hop *NextHop) {
|
|
index := l.findSameUriNextHop(hop)
|
|
if index < 0 {
|
|
l.nextHops = append(l.nextHops, hop)
|
|
} else if l.nextHops[index].RouteCost.RouteCost() != hop.RouteCost.RouteCost() {
|
|
// 注意,这里必须先删掉旧的,再加入新的;如果直接修改旧的nextHop,则可能导致该nextHop所属的另一个NextHopList属性被改变
|
|
l.RemoveNextHop(l.nextHops[index])
|
|
l.nextHops = append(l.nextHops, hop)
|
|
}
|
|
}
|
|
|
|
//
|
|
// AddNextHopBySmallerPriciple
|
|
// @Description: 在加入重合下一跳时,按照取较小开销的下一跳原则,进行更新
|
|
// @receiver l
|
|
// @param hop
|
|
//
|
|
func (l *NextHopList) AddNextHopBySmallerPriciple(hop *NextHop) {
|
|
index := l.findSameUriNextHop(hop)
|
|
if index < 0 {
|
|
l.nextHops = append(l.nextHops, hop)
|
|
} else if l.nextHops[index].RouteCost.RouteCost() > hop.RouteCost.RouteCost() {
|
|
// 注意,这里必须先删掉旧的,再加入新的;如果直接修改旧的nextHop,则可能导致该nextHop所属的另一个NextHopList属性被改变
|
|
l.RemoveNextHop(l.nextHops[index])
|
|
l.nextHops = append(l.nextHops, hop)
|
|
}
|
|
}
|
|
|
|
//
|
|
// RemoveNextHop
|
|
// @Description: 删除一个下一跳表项。
|
|
// @receiver l
|
|
// @param hop
|
|
//
|
|
func (l *NextHopList) RemoveNextHop(hop *NextHop) {
|
|
// 查找该条目索引
|
|
index := l.findSameUriNextHop(hop)
|
|
if index >= 0 {
|
|
l.nextHops = append(l.nextHops[:index], l.nextHops[index+1:]...)
|
|
}
|
|
}
|
|
|
|
//
|
|
// Size
|
|
// @Description: 返回表项数目
|
|
// @receiver l
|
|
// @return int
|
|
//
|
|
func (l *NextHopList) Size() int {
|
|
return len(l.nextHops)
|
|
}
|
|
|
|
//
|
|
// Clear
|
|
// @Description: 清空列表
|
|
// @receiver l
|
|
//
|
|
func (l *NextHopList) Clear() {
|
|
l.nextHops = []*NextHop{}
|
|
}
|
|
|
|
//
|
|
// WireEncode
|
|
// @Description: 线速编码
|
|
// @receiver l
|
|
// @param encoder
|
|
// @return int
|
|
// @return error
|
|
//
|
|
func (l *NextHopList) WireEncode(encoder *encoding.Encoder) (int, error) {
|
|
// 判断列表长度,为0则抛出错误
|
|
if len(l.nextHops) == 0 {
|
|
return 0, errors.New("Invalid NextHopList, expect at least one NextHop!")
|
|
}
|
|
totalLength := 0
|
|
// 编码 TLV-VALUE
|
|
// 反向遍历,可以保证解码的时候正向输出
|
|
for i := len(l.nextHops) - 1; i >= 0; i-- {
|
|
if l.nextHops[i] == nil {
|
|
continue
|
|
}
|
|
tmpLen, err := l.nextHops[i].WireEncode(encoder)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
totalLength += tmpLen
|
|
}
|
|
|
|
// 编码 TLV-LENGTH
|
|
tmpLen, err := encoder.PrependVarNumber(encoding.VlInt(totalLength))
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
totalLength += tmpLen
|
|
|
|
// 编码 TLV-TYPE
|
|
tmpLen, err = encoder.PrependVarNumber(extensions.TlvMlsrNextHopList)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
totalLength += tmpLen
|
|
|
|
return totalLength, nil
|
|
}
|
|
|
|
//
|
|
// WireDecode
|
|
// @Description: 线速解码
|
|
// @receiver l
|
|
// @param block
|
|
// @return error
|
|
//
|
|
func (l *NextHopList) WireDecode(block *encoding.Block) error {
|
|
// 检查 TLV-TYPE 是否正确
|
|
if err := encoding.ExpectType(block.GetType(), extensions.TlvMlsrNextHopList); err != nil {
|
|
return err
|
|
}
|
|
|
|
// 解析子 TLV
|
|
if err := block.ParseSubElements(); err != nil {
|
|
return err
|
|
}
|
|
hopContainer := make(NextHopContainer, len(block.GetSubElements()))
|
|
for index, element := range block.GetSubElements() {
|
|
var nextHop NextHop
|
|
err := nextHop.WireDecode(element)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
hopContainer[index] = &nextHop
|
|
}
|
|
l.nextHops = hopContainer
|
|
return nil
|
|
}
|