1
0
mirror of https://gitee.com/willfree/mlsr.git synced 2026-06-15 20:04:48 +08:00
Files
mlsr/mir/FibCodeCaller.go
2022-09-11 19:31:03 +08:00

372 lines
11 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package mir
// @Author: Wang Feng
// @Description: 其他模块可以调用本结构体,来完成对mir中fib的修改
// 最终形态应支持对mir中推式/拉式的fib表的修改。可暂时仅支持拉式。
// 注:基于wzq代码修改而来:https://gitea.qjm253.cn/PKUSZ-future-network-lab/ospf-min/src/branch/master/mir/fibcontroller.go
// @Version: 0.1.0
// @Date: 2022/7/21 15:13
// @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
//
package mir
import (
"encoding/json"
"errors"
"fmt"
common2 "minlib/common"
"minlib/component"
"minlib/logicface"
"minlib/mgmt"
"minlib/security"
)
// 一些关于MIR的默认信息。todo 后期应完善到配置文件中,从配置文件中进行读取。
const (
MirUnixPath = "/tmp/mir.sock"
MirIdentityDBPath = "/usr/local/.mir/identity/"
MirDefaultId = "/min/mlsrDeamon"
MirDefaultPasswd = "pkusz"
MirTopPrefix = "/min-mir/mgmt/localhost"
)
// MirNextHopInfo
// @Description: 下一跳信息【可用于ListFib函数返回值的反序列化】
//
type MirNextHopInfo struct {
LogicFaceId uint64
Cost uint64
}
// MirFibInfo
// @Description: 每个FIB条目中,一个前缀可对应多个下一跳【可用于ListFib函数返回值的反序列化】
//
type MirFibInfo struct {
Identifier string
NextHopsInfo []MirNextHopInfo
}
// MirFaceInfo
// @Description: 用于从MIR获取所有face信息时的反序列化
//
type MirFaceInfo struct {
LogicFaceId uint64
RemoteUri string
LocalUri string
Mtu uint64
RateLimit int64
}
// FibCodeCaller
// @Description: 实现MIR中fib表项信息更改的结构体
//
type FibCodeCaller struct {
mirController *mgmt.MIRController
keyChain *security.KeyChain
}
//
// NewDefaultKeychain
// @Description: 传入mir身份密码,获取路由器的KeyChain
// @param passwd
// @return *security.KeyChain
//
func (c *FibCodeCaller) newDefaultKeychain(passwd string) *security.KeyChain {
keyChain := new(security.KeyChain)
if err := keyChain.InitialKeyChainByPath(MirIdentityDBPath); err != nil {
common2.LogFatal(err)
}
if identity := keyChain.GetIdentityByName(MirDefaultId); identity == nil {
common2.LogFatal("Identity => "+MirDefaultId, " not exists")
} else {
if err := keyChain.SetCurrentIdentity(identity, passwd); err != nil {
common2.LogFatal(err)
}
}
return keyChain
}
//
// NewController
// @Description: 传入密钥链,构建MirController(内置于MIR做进程间通信的unix-logicface
// @param keyChain
// @return *mgmt.MIRController
//
func (c *FibCodeCaller) newController(keyChain *security.KeyChain) *mgmt.MIRController {
_controller := mgmt.CreateMIRController(func() (mgmt.IMgmtLogicFace, error) {
face := new(logicface.LogicFace)
/* unix connection */
if err := face.InitWithUnixSocket(MirUnixPath); err != nil {
return nil, err
}
return face, nil
}, true, keyChain)
return _controller
}
//
// Init
// @Description: 传入mir密钥
// @receiver c
// @param password
//
func (c *FibCodeCaller) Init(password string) {
c.keyChain = c.newDefaultKeychain(password)
c.mirController = c.newController(c.keyChain)
}
func (c *FibCodeCaller) Init2(password string, chain *security.KeyChain) {
c.keyChain = chain
c.mirController = c.newController(c.keyChain)
}
//
// newReadControlParameters
// @Description: 用于只读的参数,如ListFib
// @receiver c
// @return *component.ControlParameters
// @return error
//
func (c *FibCodeCaller) newReadControlParameters() (*component.ControlParameters, error) {
semantics := "pull"
parameters := &component.ControlParameters{}
parameters.SetSemantics(component.GetSemanticsEnumByString(semantics))
if !component.CheckSemanticsSupport(parameters.Semantics()) {
/* Not Support for this semantics */
return nil, errors.New("not support semantics: pull")
}
return parameters, nil
}
//
// newModifyControlParameters
// @Description: 用于修改的参数,如DelFib、AddFib
// @receiver c
// @param prefix 名称前缀
// @param nexthop 该名称前缀的网络出口,本函数将据此获取其对应的logicFaceId,并作为参数放入返回值中
// @param cost 本条目的开销
// @return *component.ControlParameters
// @return error
//
func (c *FibCodeCaller) newModifyControlParameters(prefix, nexthop string, cost uint64) (*component.ControlParameters, error) {
/* Attributes that fib needs */
semantics := "pull"
parameters := &component.ControlParameters{}
identifier, err := component.CreateIdentifierByString(prefix)
if err != nil {
return nil, err
}
logicFaceId, err := c.nexthop2LfId(nexthop)
if err != nil {
return nil, err
}
/* Control parameters setting */
parameters.SetPrefix(identifier)
parameters.SetLogicFaceId(logicFaceId)
parameters.SetCost(cost)
parameters.SetSemantics(component.GetSemanticsEnumByString(semantics)) /* push or pull semantic */
if !component.CheckSemanticsSupport(parameters.Semantics()) {
/* Not Support for this semantics */
return nil, errors.New("not support semantics: pull")
}
return parameters, nil
}
//
// newFibAddCommandExecutor
// @Description: 获取命令执行器,用于AddFib
// @receiver c
// @param parameters
// @return *mgmt.CommandExecutor
// @return error
//
func (c *FibCodeCaller) newFibAddCommandExecutor(parameters *component.ControlParameters) (*mgmt.CommandExecutor, error) {
/* Command executor factory method */
/* CreateFibxxxCommand needs more abstraction */
commandExecutor, err := c.mirController.PrepareCommandExecutor(mgmt.CreateFibAddCommand(MirTopPrefix, parameters))
if err != nil {
return nil, err
}
commandExecutor.SetAutoShutdown(true)
return commandExecutor, nil
}
//
// newFibDeleteCommandExecutor
// @Description: 获取命令执行器,用于DelFib
// @receiver c
// @param parameters
// @return *mgmt.CommandExecutor
// @return error
//
func (c *FibCodeCaller) newFibDeleteCommandExecutor(parameters *component.ControlParameters) (*mgmt.CommandExecutor, error) {
/* Command executor factory method */
/* CreateFibxxxCommand needs more abstraction */
commandExecutor, err := c.mirController.PrepareCommandExecutor(mgmt.CreateFibDeleteCommand(MirTopPrefix, parameters))
if err != nil {
return nil, err
}
commandExecutor.SetAutoShutdown(true)
return commandExecutor, nil
}
//
// newFibListCommandExecutor
// @Description: 获取命令执行器,用于ListFib
// @receiver c
// @param parameters
// @return *mgmt.CommandExecutor
// @return error
//
func (c *FibCodeCaller) newFibListCommandExecutor(parameters *component.ControlParameters) (*mgmt.CommandExecutor, error) {
/* Command executor factory method */
/* CreateFibxxxCommand needs more abstraction (return value should be interface) */
commandExecutor, err := c.mirController.PrepareCommandExecutor(mgmt.CreateFibListCommand(MirTopPrefix, parameters))
if err != nil {
return nil, err
}
commandExecutor.SetAutoShutdown(true)
return commandExecutor, nil
}
//
// addFib
// @Description: 增加某个fib表项
// @receiver c
// @param prefix
// @param nexthop
// @param cost
// @return error
//
func (c *FibCodeCaller) addFib(prefix string, nexthop string, cost uint64) error {
/* Create Control Parameters */
parameters, err := c.newModifyControlParameters(prefix, nexthop, cost)
if err != nil {
return err
}
/* Create Command Executor*/
commandExecutor, err := c.newFibAddCommandExecutor(parameters)
if err != nil {
return err
}
/* execute command */
response, err := commandExecutor.Start()
if err != nil {
return err
}
/* success */
if response.Code != mgmt.ControlResponseCodeSuccess {
/* failure */
return errors.New(fmt.Sprintf("Add next hop for %s => %s failed! errMsg: %s", prefix, nexthop, response.Msg))
}
return nil
}
//
// DelFib
// @Description: 删除某个fib表项
// @receiver c
// @param prefix
// @param nexthop
// @param cost
// @return error
//
func (c *FibCodeCaller) delFib(prefix string, nexthop string, cost uint64) error {
/* Create Control Parameters */
parameters, err := c.newModifyControlParameters(prefix, nexthop, cost)
if err != nil {
return err
}
/* Create Command Executor*/
commandExecutor, err := c.newFibDeleteCommandExecutor(parameters)
if err != nil {
return err
}
/* execute command */
response, err := commandExecutor.Start()
if err != nil {
return err
}
/* success */
if response.Code != mgmt.ControlResponseCodeSuccess {
/* failure */
return errors.New(fmt.Sprintf("Delete next hop for %s => %s failed! errMsg: %s", prefix, nexthop, response.Msg))
}
return nil
}
//
// ListFib
// @Description: 获取fib表项(默认拉式)
// @receiver c
// @return string
//
func (c *FibCodeCaller) listFib() (string, error) {
/* Create Control Parameters */
parameters, err := NewReadControlParameters()
if err != nil {
return err.Error(), err
}
/* Create Command Executor*/
commandExecutor, err := c.newFibListCommandExecutor(parameters)
if err != nil {
return err.Error(), err
}
/* execute command */
response, err := commandExecutor.Start()
if err != nil {
return err.Error(), err
}
/* success */
if response.Code != mgmt.ControlResponseCodeSuccess {
/* failure */
return errors.New(fmt.Sprintf("List fibs failed! errMsg: %s", response.Msg)).Error(), err
}
return response.GetString(), nil
}
//
// nexthop2LfId
// @Description: 根据NextHop获取其对应的logicfaceID,以填充到用于修改的参数中去。
// 获取过程:先通过与MIR进程通信,获取所有LogicFace信息;
// 再通过将face的远端uri与传入的nexthop进行对比,找到匹配的那个logicFace;
// 最后将该logicface的id进行返回。
// @receiver c
// @param nexthop 形式如”tcp://192.168.0.1:2333“的对端uri
// @return uint64 LogicFaceId
// @return error
//
func (c *FibCodeCaller) nexthop2LfId(nexthop string) (uint64, error) {
commandExecutor, err := c.mirController.PrepareCommandExecutor(mgmt.CreateLogicFaceListCommand(MirTopPrefix))
if err != nil {
return 0, err
}
commandExecutor.SetAutoShutdown(true)
/* execute command */
response, err := commandExecutor.Start()
if err != nil {
return 0, err
}
var faceInfoList []MirFaceInfo
/* unmarshal response */
err = json.Unmarshal(response.GetBytes(), &faceInfoList)
if err != nil {
return 0, err
}
/* function: get logic face id in logic face list */
getId := func(ifAddr string) int {
for _, v := range faceInfoList {
if v.RemoteUri == ifAddr {
return int(v.LogicFaceId)
}
}
return -1
}
res := -1
res = getId(nexthop)
if res != -1 {
return uint64(res), nil
}
return 0, errors.New(fmt.Sprintf("Cannot get logicface of : %s", nexthop))
}