Skip to content

Commit

Permalink
Add the datapath filtering for policy verdict logs.
Browse files Browse the repository at this point in the history
Generate policy verdict logs only if the endpoint does have a network policy
enforced on the direction of the traffic.

Signed-off-by: Zang Li <zangli@google.com>
  • Loading branch information
lzang committed Mar 27, 2020
1 parent 5ff7c51 commit 300236c
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 22 deletions.
18 changes: 18 additions & 0 deletions bpf/lib/policy_log.h
Expand Up @@ -15,6 +15,12 @@
#include "common.h"

#ifdef POLICY_VERDICT_NOTIFY

#ifndef POLICY_VERDICT_LOG_FILTER
DEFINE_U32(POLICY_VERDICT_LOG_FILTER, 0xffff);
#define POLICY_VERDICT_LOG_FILTER fetch_u32(POLICY_VERDICT_LOG_FILTER)
#endif

struct policy_verdict_notify {
NOTIFY_CAPTURE_HDR
__u32 remote_label;
Expand All @@ -28,11 +34,23 @@ struct policy_verdict_notify {
__u32 pad1; // align with 64 bits
};

static __always_inline bool policy_verdict_filter_allow(__u32 filter, __u8 dir)
{
// Make dir being volatile to avoid compiler optimizing out filter (thinking
// it to be zero).
volatile __u8 d = dir;
return ((filter & d) > 0);
}

static __always_inline void
send_policy_verdict_notify(struct __ctx_buff *ctx, __u32 remote_label, __u16 dst_port,
__u8 proto, __u8 dir, __u8 is_ipv6, int verdict,
__u8 match_type)
{
if (!policy_verdict_filter_allow(POLICY_VERDICT_LOG_FILTER, dir)) {
return;
}

__u64 ctx_len = (__u64)ctx_full_len(ctx);
__u64 cap_len = min((__u64)TRACE_PAYLOAD_LEN, (__u64)ctx_len);
__u32 hash = get_hash_recalc(ctx);
Expand Down
3 changes: 3 additions & 0 deletions bpf/lxc_config.h
Expand Up @@ -17,6 +17,9 @@ DEFINE_U32(SECLABEL, 0xfffff);
DEFINE_U32(SECLABEL_NB, 0xfffff);
#define SECLABEL_NB fetch_u32(SECLABEL_NB)

DEFINE_U32(POLICY_VERDICT_LOG_FILTER, 0xffff);
#define POLICY_VERDICT_LOG_FILTER fetch_u32(POLICY_VERDICT_LOG_FILTER)

#define POLICY_MAP test_cilium_policy_65535

#ifndef SKIP_DEBUG
Expand Down
3 changes: 3 additions & 0 deletions pkg/datapath/config.go
Expand Up @@ -74,6 +74,9 @@ type EndpointConfiguration interface {
// per endpoint route installed in the host's routing table to point to
// the endpoint's interface
RequireEndpointRoute() bool

// GetPolicyVerdictLogFilter returns the PolicyVerdictLogFilter for the endpoint
GetPolicyVerdictLogFilter() uint32
}

// ConfigWriter is anything which writes the configuration for various datapath
Expand Down
1 change: 1 addition & 0 deletions pkg/datapath/linux/config/config.go
Expand Up @@ -366,6 +366,7 @@ func (h *HeaderfileWriter) writeStaticData(fw io.Writer, e datapath.EndpointConf
secID := e.GetIdentity().Uint32()
fmt.Fprintf(fw, defineUint32("SECLABEL", secID))
fmt.Fprintf(fw, defineUint32("SECLABEL_NB", byteorder.HostToNetwork(secID).(uint32)))
fmt.Fprintf(fw, defineUint32("POLICY_VERDICT_LOG_FILTER", e.GetPolicyVerdictLogFilter()))

epID := uint16(e.GetID())
fmt.Fprintf(fw, "#define POLICY_MAP %s\n", bpf.LocalMapName(policymap.MapName, epID))
Expand Down
14 changes: 11 additions & 3 deletions pkg/datapath/loader/template.go
Expand Up @@ -32,8 +32,9 @@ import (
const (
CallsMapName = "cilium_calls_"

templateSecurityID = identity.ReservedIdentityWorld
templateLxcID = uint16(65535)
templateSecurityID = identity.ReservedIdentityWorld
templateLxcID = uint16(65535)
templatePolicyVerdictFilter = uint32(0xffff)
)

var (
Expand Down Expand Up @@ -117,6 +118,13 @@ func (t *templateCfg) IPv6Address() addressing.CiliumIPv6 {
return addressing.CiliumIPv6(templateIPv6)
}

// GetPolicyVerdictLogFilter returns an uint32 filter to ensure
// that the filter is non-zero as per the requirements
// described in the structure definition.
func (t *templateCfg) GetPolicyVerdictLogFilter() uint32 {
return templatePolicyVerdictFilter
}

// wrap takes an endpoint configuration and optional stats tracker and wraps
// it inside a templateCfg which hides static data from callers that wish to
// generate header files based on the configuration, substituting it for
Expand Down Expand Up @@ -205,7 +213,7 @@ func elfVariableSubstitutions(ep datapath.Endpoint) map[string]uint32 {
identity := ep.GetIdentity().Uint32()
result["SECLABEL"] = identity
result["SECLABEL_NB"] = byteorder.HostToNetwork(identity).(uint32)

result["POLICY_VERDICT_LOG_FILTER"] = ep.GetPolicyVerdictLogFilter()
return result

}
Expand Down
14 changes: 14 additions & 0 deletions pkg/endpoint/bpf.go
Expand Up @@ -1303,6 +1303,20 @@ func (e *Endpoint) RequireEndpointRoute() bool {
return e.DatapathConfiguration.InstallEndpointRoute
}

// GetPolicyVerdictLogFilter returns the PolicyVerdictLogFilter that would control
// the creation of policy verdict logs. Value of VerdictLogFilter needs to be
// consistent with how it is used in policy_verdict_filter_allow() in bpf/lib/policy_log.h
func (e *Endpoint) GetPolicyVerdictLogFilter() uint32 {
var filter uint32 = 0
if e.desiredPolicy.IngressPolicyEnabled {
filter = (filter | 0x1)
}
if e.desiredPolicy.EgressPolicyEnabled {
filter = (filter | 0x2)
}
return filter
}

type linkCheckerFunc func(string) error

// ValidateConnectorPlumbing checks whether the endpoint is correctly plumbed
Expand Down
42 changes: 24 additions & 18 deletions pkg/endpoint/cache.go
Expand Up @@ -50,6 +50,7 @@ type epInfoCache struct {
requireEgressProg bool
requireRouting bool
requireEndpointRoute bool
policyVerdictLogFilter uint32
cidr4PrefixLengths, cidr6PrefixLengths []int
options *option.IntOptions
lxcMAC mac.MAC
Expand All @@ -71,24 +72,25 @@ func (e *Endpoint) createEpInfoCache(epdir string) *epInfoCache {
ep := &epInfoCache{
revision: e.nextPolicyRevision,

epdir: epdir,
id: e.GetID(),
ifName: e.ifName,
ipvlan: e.HasIpvlanDataPath(),
identity: e.GetIdentity(),
mac: e.GetNodeMAC(),
ipv4: e.IPv4Address(),
ipv6: e.IPv6Address(),
conntrackLocal: e.ConntrackLocalLocked(),
requireARPPassthrough: e.RequireARPPassthrough(),
requireEgressProg: e.RequireEgressProg(),
requireRouting: e.RequireRouting(),
requireEndpointRoute: e.RequireEndpointRoute(),
cidr4PrefixLengths: cidr4,
cidr6PrefixLengths: cidr6,
options: e.Options.DeepCopy(),
lxcMAC: e.mac,
ifIndex: e.ifIndex,
epdir: epdir,
id: e.GetID(),
ifName: e.ifName,
ipvlan: e.HasIpvlanDataPath(),
identity: e.GetIdentity(),
mac: e.GetNodeMAC(),
ipv4: e.IPv4Address(),
ipv6: e.IPv6Address(),
conntrackLocal: e.ConntrackLocalLocked(),
requireARPPassthrough: e.RequireARPPassthrough(),
requireEgressProg: e.RequireEgressProg(),
requireRouting: e.RequireRouting(),
requireEndpointRoute: e.RequireEndpointRoute(),
policyVerdictLogFilter: e.GetPolicyVerdictLogFilter(),
cidr4PrefixLengths: cidr4,
cidr6PrefixLengths: cidr6,
options: e.Options.DeepCopy(),
lxcMAC: e.mac,
ifIndex: e.ifIndex,

endpoint: e,
}
Expand Down Expand Up @@ -187,3 +189,7 @@ func (ep *epInfoCache) RequireRouting() bool {
func (ep *epInfoCache) RequireEndpointRoute() bool {
return ep.requireEndpointRoute
}

func (ep *epInfoCache) GetPolicyVerdictLogFilter() uint32 {
return ep.policyVerdictLogFilter
}
2 changes: 1 addition & 1 deletion pkg/monitor/datapath_policy.go
Expand Up @@ -96,7 +96,7 @@ type PolicyVerdictNotify struct {
DstPort uint16
Proto uint8
Flags uint8
Pad2 uint32
Pad1 uint32
// data
}

Expand Down
1 change: 1 addition & 0 deletions pkg/testutils/endpoint.go
Expand Up @@ -55,6 +55,7 @@ func (e *TestEndpoint) RequireARPPassthrough() bool { return false }
func (e *TestEndpoint) RequireEgressProg() bool { return false }
func (e *TestEndpoint) RequireRouting() bool { return false }
func (e *TestEndpoint) RequireEndpointRoute() bool { return false }
func (e *TestEndpoint) GetPolicyVerdictLogFilter() uint32 { return 0xffff }
func (e *TestEndpoint) GetCIDRPrefixLengths() ([]int, []int) { return nil, nil }
func (e *TestEndpoint) GetID() uint64 { return e.Id }
func (e *TestEndpoint) StringID() string { return "42" }
Expand Down

0 comments on commit 300236c

Please sign in to comment.