Skip to content

Commit

Permalink
Merge pull request #602 from TrekkieCoder/sock-addr
Browse files Browse the repository at this point in the history
PR - LocalVIP access support via sock-addr eBPF
  • Loading branch information
UltraInstinct14 authored Mar 26, 2024
2 parents 9f3ba4a + 3500b78 commit abcae2e
Show file tree
Hide file tree
Showing 12 changed files with 177 additions and 36 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ docker-cp: build
docker cp /opt/loxilb/llb_ebpf_main.o $(loxilbid):/opt/loxilb/llb_ebpf_main.o
docker cp /opt/loxilb/llb_ebpf_emain.o $(loxilbid):/opt/loxilb/llb_ebpf_emain.o
docker cp /opt/loxilb/llb_xdp_main.o $(loxilbid):/opt/loxilb/llb_xdp_main.o
docker cp /opt/loxilb/llb_kern_sock.o $(loxilbid):/opt/loxilb/llb_kern_sock.o
docker cp loxilb-ebpf/kernel/loxilb_dp_debug $(loxilbid):/usr/local/sbin/
docker cp loxilb-ebpf/libbpf/src/libbpf.so.0.8.1 $(loxilbid):/usr/lib64/
docker cp loxilb-ebpf/utils/loxilb_dp_tool $(loxilbid):/usr/local/sbin/
Expand All @@ -38,6 +39,7 @@ docker-cp-ebpf: build
docker cp /opt/loxilb/llb_ebpf_main.o $(loxilbid):/opt/loxilb/llb_ebpf_main.o
docker cp /opt/loxilb/llb_ebpf_emain.o $(loxilbid):/opt/loxilb/llb_ebpf_emain.o
docker cp /opt/loxilb/llb_xdp_main.o $(loxilbid):/opt/loxilb/llb_xdp_main.o
docker cp /opt/loxilb/llb_kern_sock.o $(loxilbid):/opt/loxilb/llb_kern_sock.o
docker cp loxilb-ebpf/kernel/loxilb_dp_debug $(loxilbid):/usr/local/sbin/
docker cp loxilb-ebpf/libbpf/src/libbpf.so.0.8.1 $(loxilbid):/usr/lib64/

Expand Down
2 changes: 1 addition & 1 deletion loxilb-ebpf
2 changes: 1 addition & 1 deletion loxinet/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func (h *CIStateH) ClusterNodeAdd(node cmn.ClusterNodeMod) (int, error) {
cNode := h.NodeMap[node.Addr.String()]

if cNode != nil {
return -1, errors.New("exisitng cnode")
return -1, errors.New("existing cnode")
}

cNode = new(ClusterNode)
Expand Down
30 changes: 27 additions & 3 deletions loxinet/dpbroker.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,15 @@ type UlClDpWorkQ struct {
Type DpTunT
}

// SockVIPDpWorkQ - work queue entry for local VIP-port rewrite
type SockVIPDpWorkQ struct {
Work DpWorkT
VIP net.IP
Port uint16
RwPort uint16
Status *DpStatusT
}

// DpSyncOpT - Sync Operation type
type DpSyncOpT uint8

Expand Down Expand Up @@ -417,6 +426,8 @@ type DpHookInterface interface {
DpTableGet(w *TableDpWorkQ) (DpRetT, error)
DpCtAdd(w *DpCtInfo) int
DpCtDel(w *DpCtInfo) int
DpSockVIPAdd(w *SockVIPDpWorkQ) int
DpSockVIPDel(w *SockVIPDpWorkQ) int
DpTableGC()
DpCtGetAsync()
DpGetLock()
Expand Down Expand Up @@ -479,7 +490,7 @@ func (dp *DpH) WaitXsyncReady(who string) {

// DpXsyncRPC - Routine for syncing connection information with peers
func (dp *DpH) DpXsyncRPC(op DpSyncOpT, arg interface{}) int {
var reply, ret int
var ret int
var err error

dp.SyncMtx.Lock()
Expand All @@ -491,7 +502,7 @@ func (dp *DpH) DpXsyncRPC(op DpSyncOpT, arg interface{}) int {

rpcRetries := 0
rpcErr := false
var cti *DpCtInfo = nil
var cti *DpCtInfo
var blkCti []DpCtInfo

switch na := arg.(type) {
Expand All @@ -512,7 +523,7 @@ func (dp *DpH) DpXsyncRPC(op DpSyncOpT, arg interface{}) int {
}
}

reply = 0
reply := 0
rpcCallStr := ""
if op == DpSyncAdd || op == DpSyncBcast {
if len(blkCti) > 0 {
Expand Down Expand Up @@ -723,6 +734,17 @@ func (dp *DpH) DpWorkOnFw(fWq *FwDpWorkQ) DpRetT {
return DpWqUnkErr
}

// DpWorkOnSockVIP - routine to work on local VIP-port rewrite
func (dp *DpH) DpWorkOnSockVIP(vsWq *SockVIPDpWorkQ) DpRetT {
if vsWq.Work == DpCreate {
return dp.DpHooks.DpSockVIPAdd(vsWq)
} else if vsWq.Work == DpRemove {
return dp.DpHooks.DpSockVIPDel(vsWq)
}

return DpWqUnkErr
}

// DpWorkOnPeerOp - routine to work on a peer request for clustering
func (dp *DpH) DpWorkOnPeerOp(pWq *PeerDpWorkQ) DpRetT {
if pWq.Work == DpCreate {
Expand Down Expand Up @@ -783,6 +805,8 @@ func DpWorkSingle(dp *DpH, m interface{}) DpRetT {
ret = dp.DpWorkOnFw(mq)
case *PeerDpWorkQ:
ret = dp.DpWorkOnPeerOp(mq)
case *SockVIPDpWorkQ:
ret = dp.DpWorkOnSockVIP(mq)
default:
tk.LogIt(tk.LogError, "unexpected type %T\n", mq)
ret = DpWqUnkErr
Expand Down
77 changes: 76 additions & 1 deletion loxinet/dpebpf_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ const (
EbpfErrFwDel
EbpfErrCtAdd
EbpfErrCtDel
EbpfErrSockVIPMod
EbpfErrSockVIPAdd
EbpfErrSockVIPDel
EbpfErrWqUnk
)

Expand Down Expand Up @@ -135,6 +138,8 @@ type (
fw4Ent C.struct_dp_fwv4_ent
portAct C.struct_dp_rdr_act
mapNoti C.struct_ll_dp_map_notif
vipKey C.struct_sock_rwr_key
vipAct C.struct_sock_rwr_action
)

// DpEbpfH - context container
Expand Down Expand Up @@ -256,7 +261,7 @@ func DpEbpfSetLogLevel(logLevel tk.LogLevelT) {
}

// DpEbpfInit - initialize the ebpf dp subsystem
func DpEbpfInit(clusterEn bool, nodeNum int, rssEn bool, egrHooks bool, logLevel tk.LogLevelT) *DpEbpfH {
func DpEbpfInit(clusterEn, rssEn, egrHooks, localVIP bool, nodeNum int, logLevel tk.LogLevelT) *DpEbpfH {
var cfg C.struct_ebpfcfg

if clusterEn {
Expand All @@ -269,6 +274,11 @@ func DpEbpfInit(clusterEn bool, nodeNum int, rssEn bool, egrHooks bool, logLevel
} else {
cfg.egr_hooks = 0
}
if localVIP {
cfg.have_sockrwr = 1
} else {
cfg.have_sockrwr = 0
}

cfg.nodenum = C.int(nodeNum)
cfg.loglevel = 1
Expand Down Expand Up @@ -356,6 +366,10 @@ func (e *DpEbpfH) DpEbpfUnInit() {
C.free(unsafe.Pointer(ifStr))
C.free(unsafe.Pointer(section))
}

if mh.locVIP {
C.llb_unload_kern_sock()
}
}

func convNetIP2DPv6Addr(addr unsafe.Pointer, goIP net.IP) {
Expand Down Expand Up @@ -1666,6 +1680,67 @@ func (e *DpEbpfH) DpFwRuleDel(w *FwDpWorkQ) int {
return e.DpFwRuleMod(w)
}

// DpSockVIPMod - routine to work on a ebpf local VIP-port rewrite modification
func (e *DpEbpfH) DpSockVIPMod(w *SockVIPDpWorkQ) int {
key := new(vipKey)

if tk.IsNetIPv6(w.VIP.String()) {
return EbpfErrSockVIPMod
}

C.memset(unsafe.Pointer(key), 0, C.sizeof_struct_sock_rwr_key)
key.vip[0] = C.uint(tk.IPtonl(w.VIP))
key.port = C.ushort(tk.Htons(w.Port))

if w.Work == DpCreate {
dat := new(vipAct)
C.memset(unsafe.Pointer(dat), 0, C.sizeof_struct_sock_rwr_action)
dat.rw_port = C.ushort(tk.Htons(w.RwPort))

ret := C.llb_add_map_elem(C.LL_DP_SOCK_RWR_MAP,
unsafe.Pointer(key),
unsafe.Pointer(dat))

if ret != 0 {
*w.Status = 1
tk.LogIt(tk.LogError, "sock-vip rwr add failed\n")
return EbpfErrSockVIPAdd
}

tk.LogIt(tk.LogDebug, "sock-vip (%s:%v) rwr (%v) added\n",
w.VIP.String(), w.Port, w.RwPort)

*w.Status = 0

} else if w.Work == DpRemove {
C.llb_del_map_elem(C.LL_DP_SOCK_RWR_MAP, unsafe.Pointer(key))
return 0
}
return 0
}

// DpSockVIPAdd - routine to work on a ebpf local VIP-port rewrite addition
func (e *DpEbpfH) DpSockVIPAdd(w *SockVIPDpWorkQ) int {
ec := e.DpSockVIPMod(w)
if ec != 0 {
*w.Status = DpCreateErr
} else {
*w.Status = 0
}
return ec
}

// DpSockVIPDel - routine to work on a ebpf local VIP-port rewrite delete
func (e *DpEbpfH) DpSockVIPDel(w *SockVIPDpWorkQ) int {
ec := e.DpSockVIPMod(w)
if ec != 0 {
*w.Status = DpRemoveErr
} else {
*w.Status = 0
}
return ec
}

//export goMapNotiHandler
func goMapNotiHandler(m *mapNoti) {

Expand Down
2 changes: 1 addition & 1 deletion loxinet/layer3.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func (l3 *L3H) IfaAdd(Obj string, Cidr string) (int, error) {
// IfaDelete - Deletes an interface IP address (primary or secondary) and de-associate from Obj
// Obj can be anything but usually it is the name of a valid interface
func (l3 *L3H) IfaDelete(Obj string, Cidr string) (int, error) {
var found bool = false
found := false
addr, network, err := net.ParseCIDR(Cidr)
if err != nil {
tk.LogIt(tk.LogError, "ifa delete - malformed %s:%s\n", Cidr, Obj)
Expand Down
32 changes: 20 additions & 12 deletions loxinet/loxinet.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,7 @@ package loxinet
import (
"errors"
"fmt"
apiserver "github.com/loxilb-io/loxilb/api"
k8s "github.com/loxilb-io/loxilb/api/k8s"
nlp "github.com/loxilb-io/loxilb/api/loxinlp"
prometheus "github.com/loxilb-io/loxilb/api/prometheus"
cmn "github.com/loxilb-io/loxilb/common"
opts "github.com/loxilb-io/loxilb/options"
tk "github.com/loxilb-io/loxilib"
"net"
_ "net/http/pprof"
"os"
"os/signal"
"runtime/debug"
Expand All @@ -36,6 +28,14 @@ import (
"sync"
"syscall"
"time"

apiserver "github.com/loxilb-io/loxilb/api"
k8s "github.com/loxilb-io/loxilb/api/k8s"
nlp "github.com/loxilb-io/loxilb/api/loxinlp"
prometheus "github.com/loxilb-io/loxilb/api/prometheus"
cmn "github.com/loxilb-io/loxilb/common"
opts "github.com/loxilb-io/loxilb/options"
tk "github.com/loxilb-io/loxilib"
)

// string constant representing root security zone
Expand All @@ -56,6 +56,8 @@ const (
BpfFsCheckFile = "/opt/loxilb/dp/bpf/intf_map"
ARPAcceptAll = "sysctl net.ipv4.conf.all.arp_accept=1"
ARPAcceptDfl = "sysctl net.ipv4.conf.default.arp_accept=1"
UnMountCG2 = "umount /sys/fs/cgroup/unified || mkdir -p /sys/fs/cgroup/unified"
MountCG2 = "mount -t cgroup2 -o rw,relatime,nsdelegate,memory_recursiveprot cgroup2 /sys/fs/cgroup/unified"
)

type loxiNetH struct {
Expand All @@ -77,6 +79,7 @@ type loxiNetH struct {
self int
rssEn bool
eHooks bool
locVIP bool
pFile *os.File
}

Expand Down Expand Up @@ -209,6 +212,7 @@ func loxiNetInit() {
mh.eHooks = opts.Opts.EgrHooks
mh.sumDis = opts.Opts.CSumDisable
mh.pProbe = opts.Opts.PassiveEPProbe
mh.locVIP = opts.Opts.LocalVIP
mh.sigCh = make(chan os.Signal, 5)
signal.Notify(mh.sigCh, os.Interrupt, syscall.SIGCHLD, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)

Expand All @@ -226,15 +230,19 @@ func loxiNetInit() {
return
}
}
if opts.Opts.Rpc == "netrpc" {
if opts.Opts.RPC == "netrpc" {
rpcMode = RPCTypeNetRPC
} else {
rpcMode = RPCTypeGRPC
}

if !opts.Opts.BgpPeerMode {
if mh.locVIP {
RunCommand(UnMountCG2, false)
RunCommand(MountCG2, false)
}
// Initialize the ebpf datapath subsystem
mh.dpEbpf = DpEbpfInit(clusterMode, mh.self, mh.rssEn, mh.eHooks, -1)
mh.dpEbpf = DpEbpfInit(clusterMode, mh.rssEn, mh.eHooks, mh.locVIP, mh.self, -1)
mh.dp = DpBrokerInit(mh.dpEbpf, rpcMode)

// Initialize the security zone subsystem
Expand Down Expand Up @@ -291,8 +299,8 @@ func loxiNetInit() {
}

// Initialize the k8s subsystem
if opts.Opts.K8sApi != "none" {
k8s.K8sApiInit(opts.Opts.K8sApi, NetAPIInit(opts.Opts.BgpPeerMode))
if opts.Opts.K8sAPI != "none" {
k8s.K8sApiInit(opts.Opts.K8sAPI, NetAPIInit(opts.Opts.BgpPeerMode))
}

// Initialize the Prometheus subsystem
Expand Down
7 changes: 4 additions & 3 deletions loxinet/loxinettest.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ package loxinet

import (
"fmt"
cmn "github.com/loxilb-io/loxilb/common"
opts "github.com/loxilb-io/loxilb/options"
"net"
"testing"

cmn "github.com/loxilb-io/loxilb/common"
opts "github.com/loxilb-io/loxilb/options"
)

// TestLoxinet - Go unit test entry point
Expand All @@ -31,7 +32,7 @@ func TestLoxinet(t *testing.T) {
opts.Opts.NoAPI = true
opts.Opts.CPUProfile = "none"
opts.Opts.Prometheus = false
opts.Opts.K8sApi = "none"
opts.Opts.K8sAPI = "none"
opts.Opts.ClusterNodes = "none"

fmt.Printf("LoxiLB Net Unit-Test \n")
Expand Down
Loading

0 comments on commit abcae2e

Please sign in to comment.