Skip to content

Commit

Permalink
Use struct for passing data to libbpf (projectcalico#7005)
Browse files Browse the repository at this point in the history
Pass data to libbpf using a struct
  • Loading branch information
sridhartigera authored Nov 17, 2022
1 parent b72d123 commit e3d99a3
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 47 deletions.
14 changes: 13 additions & 1 deletion felix/bpf-gpl/routes.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Project Calico BPF dataplane programs.
// Copyright (c) 2020-2021 Tigera, Inc. All rights reserved.
// Copyright (c) 2020-2022 Tigera, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later

#ifndef __CALI_ROUTES_H__
Expand Down Expand Up @@ -68,10 +68,13 @@ static CALI_BPF_INLINE enum cali_rt_flags cali_rt_lookup_flags(__be32 addr)
#define cali_rt_is_workload(rt) ((rt)->flags & CALI_RT_WORKLOAD)
#define cali_rt_is_tunneled(rt) ((rt)->flags & CALI_RT_TUNNELED)

#define cali_rt_flags_host(t) (((t) & CALI_RT_HOST) == CALI_RT_HOST)
#define cali_rt_flags_local_host(t) (((t) & (CALI_RT_LOCAL | CALI_RT_HOST)) == (CALI_RT_LOCAL | CALI_RT_HOST))
#define cali_rt_flags_local_workload(t) (((t) & CALI_RT_LOCAL) && ((t) & CALI_RT_WORKLOAD))
#define cali_rt_flags_remote_workload(t) (!((t) & CALI_RT_LOCAL) && ((t) & CALI_RT_WORKLOAD))
#define cali_rt_flags_remote_host(t) (((t) & (CALI_RT_LOCAL | CALI_RT_HOST)) == CALI_RT_HOST)
#define cali_rt_flags_remote_tunneled_host(t) (((t) & (CALI_RT_LOCAL | CALI_RT_HOST | CALI_RT_TUNNELED)) == (CALI_RT_HOST | CALI_RT_TUNNELED))
#define cali_rt_flags_local_tunneled_host(t) (((t) & (CALI_RT_LOCAL | CALI_RT_HOST | CALI_RT_TUNNELED)) == (CALI_RT_LOCAL | CALI_RT_HOST | CALI_RT_TUNNELED))

static CALI_BPF_INLINE bool rt_addr_is_local_host(__be32 addr)
{
Expand All @@ -83,4 +86,13 @@ static CALI_BPF_INLINE bool rt_addr_is_remote_host(__be32 addr)
return cali_rt_flags_remote_host(cali_rt_lookup_flags(addr));
}

static CALI_BPF_INLINE bool rt_addr_is_remote_tunneled_host(__be32 addr)
{
return cali_rt_flags_remote_tunneled_host(cali_rt_lookup_flags(addr));
}

static CALI_BPF_INLINE bool rt_addr_is_local_tunneled_host(__be32 addr)
{
return cali_rt_flags_local_tunneled_host(cali_rt_lookup_flags(addr));
}
#endif /* __CALI_ROUTES_H__ */
51 changes: 28 additions & 23 deletions felix/bpf/libbpf/libbpf.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,33 +295,38 @@ const (
GlobalsRPFStrictEnabled uint32 = C.CALI_GLOBALS_RPF_STRICT_ENABLED
)

type TcGlobalData struct {
HostIP uint32
IntfIP uint32
ExtToSvcMark uint32
Tmtu uint16
VxlanPort uint16
PSNatStart uint16
PSNatLen uint16
HostTunnelIP uint32
Flags uint32
WgPort uint16
NatIn uint32
NatOut uint32
}

func TcSetGlobals(
m *Map,
hostIP uint32,
intfIP uint32,
extToSvcMark uint32,
tmtu uint16,
vxlanPort uint16,
psNatStart uint16,
psNatLen uint16,
hostTunnelIP uint32,
flags uint32,
wgPort uint16,
natin, natout uint32,
globalData *TcGlobalData,
) error {
_, err := C.bpf_tc_set_globals(m.bpfMap,
C.uint(hostIP),
C.uint(intfIP),
C.uint(extToSvcMark),
C.ushort(tmtu),
C.ushort(vxlanPort),
C.ushort(psNatStart),
C.ushort(psNatLen),
C.uint(hostTunnelIP),
C.uint(flags),
C.ushort(wgPort),
C.uint(natin),
C.uint(natout),
C.uint(globalData.HostIP),
C.uint(globalData.IntfIP),
C.uint(globalData.ExtToSvcMark),
C.ushort(globalData.Tmtu),
C.ushort(globalData.VxlanPort),
C.ushort(globalData.PSNatStart),
C.ushort(globalData.PSNatLen),
C.uint(globalData.HostTunnelIP),
C.uint(globalData.Flags),
C.ushort(globalData.WgPort),
C.uint(globalData.NatIn),
C.uint(globalData.NatOut),
)

return err
Expand Down
17 changes: 16 additions & 1 deletion felix/bpf/libbpf/libbpf_stub.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,22 @@ const (
GlobalsRPFStrictEnabled uint32 = 16
)

func TcSetGlobals(_ *Map, _, _, _ uint32, _, _, _, _ uint16, _, _ uint32, _ uint16, _, _ uint32) error {
type TcGlobalData struct {
HostIP uint32
IntfIP uint32
ExtToSvcMark uint32
Tmtu uint16
VxlanPort uint16
PSNatStart uint16
PSNatLen uint16
HostTunnelIP uint32
Flags uint32
WgPort uint16
NatIn uint32
NatOut uint32
}

func TcSetGlobals(_ *Map, globalData *TcGlobalData) error {
panic("LIBBPF syscall stub")
}

Expand Down
12 changes: 7 additions & 5 deletions felix/bpf/routes/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,13 @@ const (
FlagSameSubnet Flags = 0x20
FlagTunneled Flags = 0x40

FlagsUnknown Flags = 0
FlagsRemoteWorkload = FlagWorkload
FlagsRemoteHost = FlagHost
FlagsLocalHost = FlagLocal | FlagHost
FlagsLocalWorkload = FlagLocal | FlagWorkload
FlagsUnknown Flags = 0
FlagsRemoteWorkload = FlagWorkload
FlagsRemoteHost = FlagHost
FlagsLocalHost = FlagLocal | FlagHost
FlagsLocalWorkload = FlagLocal | FlagWorkload
FlagsRemoteTunneledHost = FlagsRemoteHost | FlagTunneled
FlagsLocalTunneledHost = FlagsLocalHost | FlagTunneled

_ = FlagsUnknown
)
Expand Down
33 changes: 19 additions & 14 deletions felix/bpf/tc/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -605,41 +605,46 @@ func (ap *AttachPoint) Config() string {
}

func (ap *AttachPoint) ConfigureProgram(m *libbpf.Map) error {
hostIP, err := convertIPToUint32(ap.HostIP)
globalData := libbpf.TcGlobalData{ExtToSvcMark: ap.ExtToServiceConnmark,
VxlanPort: ap.VXLANPort,
Tmtu: ap.TunnelMTU,
PSNatStart: ap.PSNATStart,
PSNatLen: ap.PSNATEnd,
WgPort: ap.WgPort,
NatIn: ap.NATin,
NatOut: ap.NATout,
}
var err error
globalData.HostIP, err = convertIPToUint32(ap.HostIP)
if err != nil {
return err
}
vxlanPort := ap.VXLANPort
if vxlanPort == 0 {
vxlanPort = 4789
if globalData.VxlanPort == 0 {
globalData.VxlanPort = 4789
}

intfIP, err := convertIPToUint32(ap.IntfIP)
globalData.IntfIP, err = convertIPToUint32(ap.IntfIP)
if err != nil {
return err
}

var flags uint32
if ap.IPv6Enabled {
flags |= libbpf.GlobalsIPv6Enabled
globalData.Flags |= libbpf.GlobalsIPv6Enabled
}
if ap.RPFStrictEnabled {
flags |= libbpf.GlobalsRPFStrictEnabled
globalData.Flags |= libbpf.GlobalsRPFStrictEnabled
}

hostTunnelIP := hostIP
globalData.HostTunnelIP = globalData.HostIP

if ap.HostTunnelIP != nil {
hostTunnelIP, err = convertIPToUint32(ap.HostTunnelIP)
globalData.HostTunnelIP, err = convertIPToUint32(ap.HostTunnelIP)
if err != nil {
return err
}
}

return libbpf.TcSetGlobals(m, hostIP, intfIP,
ap.ExtToServiceConnmark, ap.TunnelMTU, vxlanPort, ap.PSNATStart, ap.PSNATEnd, hostTunnelIP,
flags, ap.WgPort, ap.NATin, ap.NATout,
)
return libbpf.TcSetGlobals(m, &globalData)
}

func (ap *AttachPoint) setMapSize(m *libbpf.Map) error {
Expand Down
8 changes: 6 additions & 2 deletions felix/dataplane/linux/bpf_route_mgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,10 @@ func (m *bpfRouteManager) calculateRoute(cidr ip.V4CIDR) *routes.Value {
nodeIP := net.ParseIP(cgRoute.DstNodeIp)
routeVal := routes.NewValueWithNextHop(flags, ip.FromNetIP(nodeIP).(ip.V4Addr))
route = &routeVal
case proto.RouteType_REMOTE_TUNNEL:
flags |= routes.FlagsRemoteTunneledHost
routeVal := routes.NewValueWithNextHop(flags, cidr.Addr().(ip.V4Addr))
route = &routeVal
case proto.RouteType_LOCAL_HOST:
// It may be a localhost IP that is not assigned to a device like an
// k8s ExternalIP. Route resolver knew that it was assigned to our
Expand Down Expand Up @@ -515,8 +519,8 @@ func (m *bpfRouteManager) onRouteUpdate(update *proto.RouteUpdate) {
return
}

// For now don't handle the tunnel addresses, which were previously not being included in the route updates.
if update.Type == proto.RouteType_REMOTE_TUNNEL || update.Type == proto.RouteType_LOCAL_TUNNEL {
// For now don't handle the local tunnel addresses, which were previously not being included in the route updates.
if update.Type == proto.RouteType_LOCAL_TUNNEL {
m.onRouteRemove(&proto.RouteRemove{Dst: update.Dst})
return
}
Expand Down
18 changes: 17 additions & 1 deletion felix/fv/bpf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,9 @@ const expectedRouteDumpWithTunnelAddr = `10.65.0.0/16: remote in-pool nat-out
FELIX_0/32: local host
FELIX_0_TNL/32: local host
FELIX_1/32: remote host
FELIX_2/32: remote host`
FELIX_1_TNL/32: remote host in-pool nat-out tunneled
FELIX_2/32: remote host
FELIX_2_TNL/32: remote host in-pool nat-out tunneled`

const extIP = "10.1.2.3"

Expand Down Expand Up @@ -950,14 +952,22 @@ func describeBPFTests(opts ...bpfTestOpt) bool {

It("should have correct routes", func() {
tunnelAddr := ""
tunnelAddrFelix1 := ""
tunnelAddrFelix2 := ""
expectedRoutes := expectedRouteDump
switch {
case felixes[0].ExpectedIPIPTunnelAddr != "":
tunnelAddr = felixes[0].ExpectedIPIPTunnelAddr
tunnelAddrFelix1 = felixes[1].ExpectedIPIPTunnelAddr
tunnelAddrFelix2 = felixes[2].ExpectedIPIPTunnelAddr
case felixes[0].ExpectedVXLANTunnelAddr != "":
tunnelAddr = felixes[0].ExpectedVXLANTunnelAddr
tunnelAddrFelix1 = felixes[1].ExpectedVXLANTunnelAddr
tunnelAddrFelix2 = felixes[2].ExpectedVXLANTunnelAddr
case felixes[0].ExpectedWireguardTunnelAddr != "":
tunnelAddr = felixes[0].ExpectedWireguardTunnelAddr
tunnelAddrFelix1 = felixes[1].ExpectedWireguardTunnelAddr
tunnelAddrFelix2 = felixes[2].ExpectedWireguardTunnelAddr
}

if tunnelAddr != "" {
Expand Down Expand Up @@ -985,6 +995,12 @@ func describeBPFTests(opts ...bpfTestOpt) bool {
if tunnelAddr != "" {
l = strings.ReplaceAll(l, tunnelAddr+"/32", "FELIX_0_TNL/32")
}
if tunnelAddrFelix1 != "" {
l = strings.ReplaceAll(l, tunnelAddrFelix1+"/32", "FELIX_1_TNL/32")
}
if tunnelAddrFelix2 != "" {
l = strings.ReplaceAll(l, tunnelAddrFelix2+"/32", "FELIX_2_TNL/32")
}
filteredLines = append(filteredLines, l)
}
sort.Strings(filteredLines)
Expand Down

0 comments on commit e3d99a3

Please sign in to comment.