Skip to content

Commit

Permalink
loxilb-iogh-877 Initial support for egress
Browse files Browse the repository at this point in the history
  • Loading branch information
TrekkieCoder committed Dec 7, 2024
1 parent 426daa4 commit 03cf4b0
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 16 deletions.
179 changes: 168 additions & 11 deletions pkg/loxinet/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@ package loxinet

import (
"errors"
"fmt"
"net"
"os"
"time"

nlp "github.com/loxilb-io/loxilb/api/loxinlp"
cmn "github.com/loxilb-io/loxilb/common"
bfd "github.com/loxilb-io/loxilb/pkg/proto"
utils "github.com/loxilb-io/loxilb/pkg/utils"
tk "github.com/loxilb-io/loxilib"
"net"
"os"
"time"
)

// error codes for cluster module
Expand All @@ -34,6 +37,12 @@ const (
CIStateErr
)

const (
defaultClusterSubnet = "10.252.0.0/16"
defaultCluster6Subnet = "fd55:e81c:146f:66b5::/64"
ClusterNetID = 999
)

// ClusterInstance - Struct for Cluster Instance information
type ClusterInstance struct {
State int
Expand All @@ -53,18 +62,24 @@ type CIKAArgs struct {
RemoteIP net.IP
SourceIP net.IP
Interval int64
CSubnet string
CSubnet6 string
CDev string
}

// CIStateH - Cluster context handler
type CIStateH struct {
SpawnKa bool
RemoteIP net.IP
SourceIP net.IP
Interval int64
ClusterMap map[string]*ClusterInstance
StateMap map[string]int
NodeMap map[string]*ClusterNode
Bs *bfd.Struct
SpawnKa bool
RemoteIP net.IP
SourceIP net.IP
Interval int64
ClusterMap map[string]*ClusterInstance
StateMap map[string]int
NodeMap map[string]*ClusterNode
Bs *bfd.Struct
ClusterNet string
ClusterNet6 string
ClusterIf string
}

func (ci *CIStateH) BFDSessionNotify(instance string, remote string, ciState string) {
Expand Down Expand Up @@ -151,9 +166,151 @@ func CIInit(args CIKAArgs) *CIStateH {
}

nCIh.NodeMap = make(map[string]*ClusterNode)

args.CDev = "eth0"
if args.CDev != "" {
tk.LogIt(tk.LogError, "cluster-dev name\n")
_, err := net.InterfaceByName(args.CDev)
if err != nil {
tk.LogIt(tk.LogError, "cluster-dev name error\n")
os.Exit(1)
return nil
}
clusterCIDR := defaultClusterSubnet
if args.CSubnet != "" {
clusterCIDR = args.CSubnet
}

clusterCIDR6 := defaultCluster6Subnet
if args.CSubnet6 != "" {
clusterCIDR6 = args.CSubnet6
}

ip, _, err := net.ParseCIDR(clusterCIDR)
if err != nil {
tk.LogIt(tk.LogError, "ClusterIP address invalid %s\n", clusterCIDR)
return nil
}

ip6, _, err := net.ParseCIDR(clusterCIDR6)
if err != nil {
tk.LogIt(tk.LogError, "ClusterIP6 address invalid %s\n", clusterCIDR6)
return nil
}

ifIP, err := utils.GetIfaceIPAddr(args.CDev)
if err != nil || ifIP == nil {
tk.LogIt(tk.LogError, "No IP address found in cluster-dev\n")
return nil
}

ifIP6, _ := utils.GetIfaceIP6Addr(args.CDev)
if ifIP6 == nil {
tk.LogIt(tk.LogError, "No IP6 address found in cluster-dev\n")
ifIP6 = ip6
ifIP6[len(ifIP6)-1]++
}

ip[len(ip)-2] = ifIP[len(ifIP)-2]
ip[len(ip)-1] = ifIP[len(ifIP)-1]

ip6[len(ip)-2] = ifIP6[len(ifIP6)-2]
ip6[len(ip)-1] = ifIP6[len(ifIP6)-1]

clusterIfName := fmt.Sprintf("vxlan%d", ClusterNetID)

if nlp.AddVxLANBridgeNoHook(ClusterNetID, args.CDev) < 0 {
tk.LogIt(tk.LogError, "Failed to created Cluster Network\n")
return nil
}

if nlp.AddAddrNoHook(ip.String()+"/16", clusterIfName) < 0 {
tk.LogIt(tk.LogError, "Failed to add Cluster Addr %s:%s\n", ip.String(), clusterIfName)
return nil
}

if nlp.AddAddrNoHook(ip6.String()+"/64", clusterIfName) < 0 {
tk.LogIt(tk.LogError, "Failed to add Cluster Addr %s:%s\n", ip6.String(), clusterIfName)
nCIh.ClusterNet6 = ""
} else {
nCIh.ClusterNet6 = clusterCIDR6
}

tk.LogIt(tk.LogInfo, "Cluster IP address %s\n", ip.String())
tk.LogIt(tk.LogInfo, "Cluster IP6 address %s\n", ip6.String())

nCIh.ClusterIf = args.CDev
nCIh.ClusterNet = clusterCIDR
nCIh.ClusterNet6 = clusterCIDR6
}

return nCIh
}

// CIDestroy - routine to destroy Cluster context
func (ci *CIStateH) CIDestroy() {

if ci.ClusterIf != "" {
tk.LogIt(tk.LogError, "cluster-dev name\n")
_, err := net.InterfaceByName(ci.ClusterIf)
if err != nil {
tk.LogIt(tk.LogError, "cluster-dev name error\n")
return
}

clusterCIDR := ci.ClusterNet
clusterCIDR6 := ci.ClusterNet6

ip, _, err := net.ParseCIDR(clusterCIDR)
if err != nil {
tk.LogIt(tk.LogError, "ClusterIP address invalid %s\n", clusterCIDR)
return
}

ip6, _, err := net.ParseCIDR(clusterCIDR6)
if err != nil {
tk.LogIt(tk.LogError, "ClusterIP6 address invalid %s\n", clusterCIDR6)
return
}

ifIP, err := utils.GetIfaceIPAddr(ci.ClusterIf)
if err != nil || ifIP == nil {
tk.LogIt(tk.LogError, "No IP address found in cluster-dev\n")
return
}

ifIP6, _ := utils.GetIfaceIP6Addr(ci.ClusterIf)
if ifIP6 == nil {
tk.LogIt(tk.LogError, "No IP6 address found in cluster-dev\n")
ifIP6 = ip6
ifIP6[len(ifIP6)-1]++
}

ip[len(ip)-2] = ifIP[len(ifIP)-2]
ip[len(ip)-1] = ifIP[len(ifIP)-1]

ip6[len(ip)-2] = ifIP6[len(ifIP6)-2]
ip6[len(ip)-1] = ifIP6[len(ifIP6)-1]

tk.LogIt(tk.LogInfo, "Cluster IP address %s deleted\n", ip.String())
tk.LogIt(tk.LogInfo, "Cluster IP6 address %s deleted\n", ip6.String())

clusterIfName := fmt.Sprintf("vxlan%d", ClusterNetID)

if nlp.DelAddrNoHook(ip.String()+"/16", clusterIfName) < 0 {
tk.LogIt(tk.LogError, "Failed to delete Cluster Addr %s:%s\n", ip.String(), clusterIfName)
}

if nlp.DelAddrNoHook(ip6.String()+"/64", clusterIfName) < 0 {
tk.LogIt(tk.LogError, "Failed to delete Cluster Addr %s:%s\n", ip6.String(), clusterIfName)
}

if nlp.DelVxLANNoHook(ClusterNetID) < 0 {
tk.LogIt(tk.LogError, "Failed to delete Cluster Network\n")
}
}
}

// CIStateGetInst - routine to get HA state
func (h *CIStateH) CIStateGetInst(inst string) (string, error) {

Expand Down
6 changes: 5 additions & 1 deletion pkg/loxinet/loxinet.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ func loxiNetTicker(bgpPeerMode bool) {
if !bgpPeerMode {
mh.dpEbpf.DpEbpfUnInit()
}
mh.has.CIDestroy()
apiserver.ApiServerShutOk()
}
case t := <-mh.ticker.C:
Expand Down Expand Up @@ -300,7 +301,10 @@ func loxiNetInit() {
}

// Initialize the clustering subsystem
mh.has = CIInit(kaArgs)
if mh.has = CIInit(kaArgs); mh.has == nil {
tk.LogIt(tk.LogError, "cluster init failed\n")
os.Exit(1)
}
if clusterMode {
if opts.Opts.Bgp {
tk.LogIt(tk.LogInfo, "init-wait cluster mode\n")
Expand Down
33 changes: 29 additions & 4 deletions pkg/utils/net.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,32 @@ func Ntohll(i uint64) uint64 {
return binary.BigEndian.Uint64((*(*[8]byte)(unsafe.Pointer(&i)))[:])
}

// GetIfaceIpAddr - Get interface IP address
func GetIfaceIpAddr(ifName string) (addr net.IP, err error) {
// GetIfaceIPAddr - Get interface IP address
func GetIfaceIPAddr(ifName string) (addr net.IP, err error) {
var (
ief *net.Interface
addrs []net.Addr
ipAddr net.IP
)
if ief, err = net.InterfaceByName(ifName); err != nil {
return nil, errors.New("not such ifname")
}
if addrs, err = ief.Addrs(); err != nil {
return nil, errors.New("not such addrs")
}
for _, addr := range addrs {
if ipAddr = addr.(*net.IPNet).IP.To4(); ipAddr != nil {
break
}
}
if ipAddr == nil {
return nil, errors.New("not ipv4 address")
}
return ipAddr, nil
}

// GetIfaceIP6Addr - Get interface IP address
func GetIfaceIP6Addr(ifName string) (addr net.IP, err error) {
var (
ief *net.Interface
addrs []net.Addr
Expand All @@ -360,7 +384,8 @@ func GetIfaceIpAddr(ifName string) (addr net.IP, err error) {
return
}
for _, addr := range addrs {
if ipAddr = addr.(*net.IPNet).IP.To4(); ipAddr != nil {
if tk.IsNetIPv6(addr.(*net.IPNet).IP.String()) {
ipAddr = addr.(*net.IPNet).IP
break
}
}
Expand All @@ -374,7 +399,7 @@ func GetIfaceIpAddr(ifName string) (addr net.IP, err error) {
func SendArpReq(AdvIP net.IP, ifName string) (int, error) {
zeroAddr := []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

srcIP, err := GetIfaceIpAddr(ifName)
srcIP, err := GetIfaceIPAddr(ifName)
if err != nil {
return -1, err
}
Expand Down

0 comments on commit 03cf4b0

Please sign in to comment.