Skip to content

Commit

Permalink
Merge pull request #532 from TrekkieCoder/main
Browse files Browse the repository at this point in the history
PR - bfd: Added bind option to select source
  • Loading branch information
UltraInstinct14 authored Feb 19, 2024
2 parents 1ecd03c + 786a6e6 commit f0d8cf1
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 38 deletions.
36 changes: 20 additions & 16 deletions loxinet/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,6 @@ const (
CIStateErr
)

// Config related constants
const (
KAConfigFile = "/etc/keepalived/keepalived.conf"
KAPidFile1 = "/var/run/keepalived.pid"
KAPidFile2 = "/var/run/vrrp.pid"
)

// ClusterInstance - Struct for Cluster Instance information
type ClusterInstance struct {
State int
Expand All @@ -56,11 +49,20 @@ type ClusterNode struct {
Status DpStatusT
}

// CIKAArgs - Struct for cluster BFD args
type CIKAArgs struct {
SpawnKa bool
RemoteIP net.IP
SourceIP net.IP
Interval int64
}

// CIStateH - Cluster context handler
type CIStateH struct {
SpawnKa bool
RemoteIP net.IP
KaArgsVal int64
SourceIP net.IP
Interval int64
ClusterMap map[string]*ClusterInstance
StateMap map[string]int
NodeMap map[string]*ClusterNode
Expand Down Expand Up @@ -93,17 +95,18 @@ func (ci *CIStateH) startBFDProto() {
time.Sleep(KAInitTiVal * time.Second)

txInterval := uint32(bfd.BFDDflSysTXIntervalUs)
if ci.KaArgsVal != 0 && ci.KaArgsVal >= bfd.BFDMinSysTXIntervalUs {
txInterval = uint32(ci.KaArgsVal)
if ci.Interval != 0 && ci.Interval >= bfd.BFDMinSysTXIntervalUs {
txInterval = uint32(ci.Interval)
}

bs := bfd.StructNew(3784)
err := bs.BFDAddRemote(ci.RemoteIP.String(), 3784, txInterval, 3, cmn.CIDefault, ci)
bfdSessConfigArgs := bfd.ConfigArgs{RemoteIP: ci.RemoteIP.String(), SourceIP: ci.SourceIP.String(), Port: 3784, Interval: txInterval, Multi: 3, Instance: cmn.CIDefault}
err := bs.BFDAddRemote(bfdSessConfigArgs, ci)
if err != nil {
tk.LogIt(tk.LogCritical, "KA - Cant add BFD remote\n")
os.Exit(1)
}
tk.LogIt(tk.LogInfo, "KA - Added BFD remote %s:%vus\n", ci.RemoteIP.String(), txInterval)
tk.LogIt(tk.LogInfo, "KA - Added BFD remote %s:%s:%vus\n", ci.RemoteIP.String(), ci.SourceIP.String(), txInterval)
}

// CITicker - Periodic ticker for Cluster module
Expand All @@ -119,17 +122,18 @@ func (ci *CIStateH) CISpawn() {
}

// CIInit - routine to initialize Cluster context
func CIInit(spawnKa bool, remoteIP net.IP, extArgs int64) *CIStateH {
func CIInit(args CIKAArgs) *CIStateH {
var nCIh = new(CIStateH)
nCIh.StateMap = make(map[string]int)
nCIh.StateMap["MASTER"] = cmn.CIStateMaster
nCIh.StateMap["BACKUP"] = cmn.CIStateBackup
nCIh.StateMap["FAULT"] = cmn.CIStateConflict
nCIh.StateMap["STOP"] = cmn.CIStateNotDefined
nCIh.StateMap["NOT_DEFINED"] = cmn.CIStateNotDefined
nCIh.SpawnKa = spawnKa
nCIh.RemoteIP = remoteIP
nCIh.KaArgsVal = extArgs
nCIh.SpawnKa = args.SpawnKa
nCIh.RemoteIP = args.RemoteIP
nCIh.SourceIP = args.SourceIP
nCIh.Interval = args.Interval
nCIh.ClusterMap = make(map[string]*ClusterInstance)

if _, ok := nCIh.ClusterMap[cmn.CIDefault]; !ok {
Expand Down
4 changes: 2 additions & 2 deletions loxinet/loxinet.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ var mh loxiNetH
func loxiNetInit() {
var rpcMode int

spawnKa, kaMode, kaExtArgs := KAString2Mode(opts.Opts.Ka)
kaArgs := KAString2Mode(opts.Opts.Ka)
clusterMode := false
if opts.Opts.ClusterNodes != "none" {
clusterMode = true
Expand Down Expand Up @@ -249,7 +249,7 @@ func loxiNetInit() {
}

// Initialize the clustering subsystem
mh.has = CIInit(spawnKa, kaMode, kaExtArgs)
mh.has = CIInit(kaArgs)
if clusterMode {
if opts.Opts.Bgp {
tk.LogIt(tk.LogInfo, "init-wait cluster mode\n")
Expand Down
18 changes: 12 additions & 6 deletions loxinet/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,26 +139,32 @@ func LogString2Level(logStr string) tk.LogLevelT {
}

// KAString2Mode - Convert ka mode in string opts to spawn/KAMode
func KAString2Mode(kaStr string) (bool, net.IP, int64) {
func KAString2Mode(kaStr string) CIKAArgs {
spawnKa := false
kaExtraArgs := int64(0)
interval := int64(0)
sourceIP := net.ParseIP("0.0.0.0")

if kaStr == "none" {
return spawnKa, nil, kaExtraArgs
return CIKAArgs{SpawnKa: spawnKa, RemoteIP: nil, Interval: interval}
}

kaArgs := strings.Split(kaStr, ":")

remote := net.ParseIP(kaArgs[0])
if remote == nil {
return spawnKa, remote, kaExtraArgs
return CIKAArgs{SpawnKa: spawnKa, RemoteIP: nil, SourceIP: nil, Interval: interval}
}

if len(kaArgs) > 1 {
kaExtraArgs, _ = strconv.ParseInt(kaArgs[1], 10, 32)
sourceIP = net.ParseIP(kaArgs[1])
}

if len(kaArgs) > 2 {
interval, _ = strconv.ParseInt(kaArgs[2], 10, 32)
}
spawnKa = true
return spawnKa, remote, kaExtraArgs
return CIKAArgs{SpawnKa: spawnKa, RemoteIP: remote, SourceIP: sourceIP, Interval: interval}

}

// HTTPSProber - Do a https probe for given url
Expand Down
2 changes: 1 addition & 1 deletion options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

var Opts struct {
Bgp bool `short:"b" long:"bgp" description:"Connect and Sync with GoBGP server"`
Ka string `short:"k" long:"ka" description:"KeepAlive/BFD RemoteIP" default:"none"`
Ka string `short:"k" long:"ka" description:"KeepAlive/BFD RemoteIP:SourceIP:Interval" default:"none"`
Version bool `short:"v" long:"version" description:"Show loxilb version"`
NoAPI bool `short:"a" long:"api" description:"Run Rest API server"`
NoNlp bool `short:"n" long:"nonlp" description:"Do not register with nlp"`
Expand Down
45 changes: 32 additions & 13 deletions proto/bfd.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ const (
BFDMinSysRXIntervalUs = 200000
)

type ConfigArgs struct {
RemoteIP string
SourceIP string
Port uint16
Interval uint32
Multi uint8
Instance string
}

type WireRaw struct {
Version uint8
Length uint8
Expand Down Expand Up @@ -94,46 +103,44 @@ func StructNew(port uint16) *Struct {
return bfdStruct
}

func (bs *Struct) BFDAddRemote(remoteIP string, port uint16, interval uint32, multi uint8, instance string, cbs Notifer) error {
func (bs *Struct) BFDAddRemote(args ConfigArgs, cbs Notifer) error {
bs.BFDMtx.Lock()
defer bs.BFDMtx.Unlock()

sess := bs.BFDSessMap[remoteIP]
sess := bs.BFDSessMap[args.RemoteIP]
if sess != nil {
return errors.New("bfd existing session")
}

if interval < BFDMinSysTXIntervalUs || multi == 0 {
if args.Interval < BFDMinSysTXIntervalUs || args.Multi == 0 {
return errors.New("bfd malformed args")
}

sess = new(bfdSession)
sess.Instance = instance
sess.Instance = args.Instance
sess.Notify = cbs
err := sess.initialize(remoteIP, port, interval, multi)
err := sess.initialize(args.RemoteIP, args.SourceIP, args.Port, args.Interval, args.Multi)
if err != nil {
return errors.New("bfd failed to init session")
}

bs.BFDSessMap[remoteIP] = sess
bs.BFDSessMap[args.RemoteIP] = sess

return nil
}

func (bs *Struct) BFDDeleteRemote(remoteIP string, port uint16) error {
func (bs *Struct) BFDDeleteRemote(args ConfigArgs) error {
bs.BFDMtx.Lock()
defer bs.BFDMtx.Unlock()

sess := bs.BFDSessMap[remoteIP]
sess := bs.BFDSessMap[args.RemoteIP]
if sess == nil {
return errors.New("no bfd session")
}

sess.destruct()
delete(bs.BFDSessMap, sess.RemoteName)

bs.BFDSessMap[remoteIP] = sess

return nil
}

Expand Down Expand Up @@ -318,6 +325,7 @@ func getMyDisc(ip net.IP) net.IP {
// check if IPv4 or IPv6 is not nil
if ipnet.IP.To4() != nil || ipnet.IP.To16() != nil {
if ipnet.Contains(ip) {
tk.LogIt(tk.LogDebug, "bfd mydisc : %s\n", ipnet.IP.String())
return ipnet.IP
}
if first == nil {
Expand All @@ -327,10 +335,12 @@ func getMyDisc(ip net.IP) net.IP {
}
}

tk.LogIt(tk.LogDebug, "bfd mydisc : %s\n", first.String())

return first
}

func (b *bfdSession) initialize(remoteIP string, port uint16, interval uint32, multi uint8) error {
func (b *bfdSession) initialize(remoteIP string, sourceIP string, port uint16, interval uint32, multi uint8) error {
var err error
b.RemoteName = fmt.Sprintf("%s:%d", remoteIP, port)

Expand All @@ -339,9 +349,18 @@ func (b *bfdSession) initialize(remoteIP string, port uint16, interval uint32, m
return errors.New("address malformed")
}

myIP := getMyDisc(ip)
myIP := net.ParseIP(sourceIP)
if myIP == nil {
return errors.New("my discriminator not found")
return errors.New("source address malformed")
}

if myIP.IsUnspecified() {
myIP = getMyDisc(ip)
if myIP == nil {
return errors.New("my discriminator not found")
}
} else {
tk.LogIt(tk.LogDebug, "using bfd bind mydisc : %s\n", myIP.String())
}
b.MyDisc = tk.IPtonl(myIP)
b.RemDisc = 0 //tk.IPtonl(ip)
Expand Down

0 comments on commit f0d8cf1

Please sign in to comment.