Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR - bfd: Added bind option to select source #532

Merged
merged 2 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading