Skip to content

Commit

Permalink
cilium: add wildcarded capture map representation
Browse files Browse the repository at this point in the history
Add a basic v4/v6 map representation so that the user space bits can build
on top of it. This is needed for later map+mask management as well as a
Cilium CLI map dump for introspection. Default map size is currently fixed,
but we can add an agent knob at some point if needed.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
  • Loading branch information
borkmann committed Mar 30, 2021
1 parent 02e55a7 commit 9c47695
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 7 deletions.
8 changes: 4 additions & 4 deletions bpf/lib/pcap.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,12 @@ struct capture4_wcard {
__u8 flags; /* reserved: 0 */
};

struct bpf_elf_map __section_maps cilium_capture4_rules = {
struct bpf_elf_map __section_maps CAPTURE4_RULES = {
.type = BPF_MAP_TYPE_HASH,
.size_key = sizeof(struct capture4_wcard),
.size_value = sizeof(struct capture_rule),
.pinning = PIN_GLOBAL_NS,
.max_elem = 1024,
.max_elem = CAPTURE4_SIZE,
.flags = BPF_F_NO_PREALLOC,
};

Expand Down Expand Up @@ -254,12 +254,12 @@ struct capture6_wcard {
__u8 flags; /* reserved: 0 */
};

struct bpf_elf_map __section_maps cilium_capture6_rules = {
struct bpf_elf_map __section_maps CAPTURE6_RULES = {
.type = BPF_MAP_TYPE_HASH,
.size_key = sizeof(struct capture6_wcard),
.size_value = sizeof(struct capture_rule),
.pinning = PIN_GLOBAL_NS,
.max_elem = 1024,
.max_elem = CAPTURE6_SIZE,
.flags = BPF_F_NO_PREALLOC,
};

Expand Down
4 changes: 4 additions & 0 deletions bpf/node_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ DEFINE_IPV6(HOST_IP, 0xbe, 0xef, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0xa, 0x
#define SNAT_MAPPING_IPV4_SIZE 524288
#define NODEPORT_NEIGH4_SIZE 524288
#endif /* ENABLE_NODEPORT */
#define CAPTURE4_RULES cilium_capture4_rules
#define CAPTURE4_SIZE 16384
#endif /* ENABLE_IPV4 */

#ifdef ENABLE_IPV6
Expand All @@ -70,6 +72,8 @@ DEFINE_IPV6(HOST_IP, 0xbe, 0xef, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0xa, 0x
#define SNAT_MAPPING_IPV6_SIZE 524288
#define NODEPORT_NEIGH6_SIZE 524288
#endif /* ENABLE_NODEPORT */
#define CAPTURE6_RULES cilium_capture6_rules
#define CAPTURE6_SIZE 16384
#endif /* ENABLE_IPV6 */

#define ENCAP_GENEVE 1
Expand Down
9 changes: 9 additions & 0 deletions pkg/datapath/linux/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import (
"github.com/cilium/cilium/pkg/maps/nat"
"github.com/cilium/cilium/pkg/maps/neighborsmap"
"github.com/cilium/cilium/pkg/maps/policymap"
"github.com/cilium/cilium/pkg/maps/recorder"
"github.com/cilium/cilium/pkg/maps/signalmap"
"github.com/cilium/cilium/pkg/maps/sockmap"
"github.com/cilium/cilium/pkg/maps/tunnel"
Expand Down Expand Up @@ -260,6 +261,14 @@ func (h *HeaderfileWriter) WriteNodeConfig(w io.Writer, cfg *datapath.LocalNodeC
}
if option.Config.EnableRecorder {
cDefinesMap["ENABLE_CAPTURE"] = "1"
if option.Config.EnableIPv4 {
cDefinesMap["CAPTURE4_RULES"] = recorder.MapNameWcard4
cDefinesMap["CAPTURE4_SIZE"] = fmt.Sprintf("%d", recorder.MapSize)
}
if option.Config.EnableIPv6 {
cDefinesMap["CAPTURE6_RULES"] = recorder.MapNameWcard6
cDefinesMap["CAPTURE6_SIZE"] = fmt.Sprintf("%d", recorder.MapSize)
}
}
cDefinesMap["ENABLE_NODEPORT"] = "1"
cDefinesMap["ENABLE_LOADBALANCER"] = "1"
Expand Down
7 changes: 4 additions & 3 deletions pkg/datapath/maps/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/cilium/cilium/pkg/maps/ipmasq"
"github.com/cilium/cilium/pkg/maps/lbmap"
"github.com/cilium/cilium/pkg/maps/policymap"
"github.com/cilium/cilium/pkg/maps/recorder"
"github.com/cilium/cilium/pkg/option"
)

Expand Down Expand Up @@ -148,7 +149,7 @@ func (ms *MapSweeper) RemoveDisabledMaps() {
"cilium_lb6_reverse_sk",
"cilium_snat_v6_external",
"cilium_proxy6",
"cilium_capture6_rules",
recorder.MapNameWcard6,
lbmap.MaglevOuter6MapName,
lbmap.Affinity6MapName,
lbmap.SourceRange6MapName,
Expand All @@ -169,7 +170,7 @@ func (ms *MapSweeper) RemoveDisabledMaps() {
"cilium_lb4_reverse_sk",
"cilium_snat_v4_external",
"cilium_proxy4",
"cilium_capture4_rules",
recorder.MapNameWcard4,
lbmap.MaglevOuter4MapName,
lbmap.Affinity4MapName,
lbmap.SourceRange4MapName,
Expand All @@ -183,7 +184,7 @@ func (ms *MapSweeper) RemoveDisabledMaps() {
}

if !option.Config.EnableRecorder {
maps = append(maps, []string{"cilium_capture4_rules", "cilium_capture6_rules",
maps = append(maps, []string{recorder.MapNameWcard4, recorder.MapNameWcard6,
"cilium_capture_cache", "cilium_ktime_cache"}...)
}

Expand Down
18 changes: 18 additions & 0 deletions pkg/maps/recorder/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2021 Authors of Cilium
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package recorder represents the BPF map used to (wildcard-)filter
// traffic that is subject to the pcap recorder.
// +groupName=maps
package recorder
84 changes: 84 additions & 0 deletions pkg/maps/recorder/ipv4.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright 2021 Authors of Cilium
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package recorder

import (
"fmt"
"unsafe"

"github.com/cilium/cilium/pkg/bpf"
"github.com/cilium/cilium/pkg/byteorder"
"github.com/cilium/cilium/pkg/types"
)

type CaptureWcard4 struct {
DestAddr types.IPv4 `align:"daddr"`
SrcAddr types.IPv4 `align:"saddr"`
DestPort uint16 `align:"dport"`
SrcPort uint16 `align:"sport"`
NextHdr uint8 `align:"nexthdr"`
DestMask uint8 `align:"dmask"`
SrcMask uint8 `align:"smask"`
Flags uint8 `align:"flags"`
}

type CaptureRule4 CaptureRule

func (k *CaptureWcard4) GetKeyPtr() unsafe.Pointer { return unsafe.Pointer(k) }
func (k *CaptureWcard4) NewValue() bpf.MapValue { return &CaptureRule4{} }
func (k *CaptureWcard4) DeepCopyMapKey() bpf.MapKey {
return &CaptureWcard4{
DestAddr: k.DestAddr,
SrcAddr: k.SrcAddr,
DestPort: k.DestPort,
SrcPort: k.SrcPort,
NextHdr: k.NextHdr,
DestMask: k.DestMask,
SrcMask: k.SrcMask,
Flags: k.Flags,
}
}
func (k *CaptureWcard4) String() string {
return fmt.Sprintf("%s/%d %s/%d %d %d %d\n",
k.DestAddr,
int(k.DestMask),
k.SrcAddr,
int(k.SrcMask),
byteorder.NetworkToHost(k.DestPort),
byteorder.NetworkToHost(k.SrcPort),
int(k.NextHdr))
}

func (v *CaptureRule4) GetValuePtr() unsafe.Pointer { return unsafe.Pointer(v) }
func (v *CaptureRule4) DeepCopyMapValue() bpf.MapValue {
return &CaptureRule4{
RuleId: v.RuleId,
Reserved: v.Reserved,
CapLen: v.CapLen,
}
}
func (v *CaptureRule4) String() string {
return fmt.Sprintf("%d %d", int(v.RuleId), int(v.CapLen))
}

var CaptureMap4 = bpf.NewMap(
MapNameWcard4,
bpf.MapTypeHash,
&CaptureWcard4{}, int(unsafe.Sizeof(CaptureWcard4{})),
&CaptureRule4{}, int(unsafe.Sizeof(CaptureRule4{})),
MapSize,
bpf.BPF_F_NO_PREALLOC, 0,
bpf.ConvertKeyValue,
).WithCache()
84 changes: 84 additions & 0 deletions pkg/maps/recorder/ipv6.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright 2021 Authors of Cilium
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package recorder

import (
"fmt"
"unsafe"

"github.com/cilium/cilium/pkg/bpf"
"github.com/cilium/cilium/pkg/byteorder"
"github.com/cilium/cilium/pkg/types"
)

type CaptureWcard6 struct {
DestAddr types.IPv6 `align:"daddr"`
SrcAddr types.IPv6 `align:"saddr"`
DestPort uint16 `align:"dport"`
SrcPort uint16 `align:"sport"`
NextHdr uint8 `align:"nexthdr"`
DestMask uint8 `align:"dmask"`
SrcMask uint8 `align:"smask"`
Flags uint8 `align:"flags"`
}

type CaptureRule6 CaptureRule

func (k *CaptureWcard6) GetKeyPtr() unsafe.Pointer { return unsafe.Pointer(k) }
func (k *CaptureWcard6) NewValue() bpf.MapValue { return &CaptureRule6{} }
func (k *CaptureWcard6) DeepCopyMapKey() bpf.MapKey {
return &CaptureWcard6{
DestAddr: k.DestAddr,
SrcAddr: k.SrcAddr,
DestPort: k.DestPort,
SrcPort: k.SrcPort,
NextHdr: k.NextHdr,
DestMask: k.DestMask,
SrcMask: k.SrcMask,
Flags: k.Flags,
}
}
func (k *CaptureWcard6) String() string {
return fmt.Sprintf("%s/%d %s/%d %d %d %d\n",
k.DestAddr,
int(k.DestMask),
k.SrcAddr,
int(k.SrcMask),
byteorder.NetworkToHost(k.DestPort),
byteorder.NetworkToHost(k.SrcPort),
int(k.NextHdr))
}

func (v *CaptureRule6) GetValuePtr() unsafe.Pointer { return unsafe.Pointer(v) }
func (v *CaptureRule6) DeepCopyMapValue() bpf.MapValue {
return &CaptureRule6{
RuleId: v.RuleId,
Reserved: v.Reserved,
CapLen: v.CapLen,
}
}
func (v *CaptureRule6) String() string {
return fmt.Sprintf("%d %d", int(v.RuleId), int(v.CapLen))
}

var CaptureMap6 = bpf.NewMap(
MapNameWcard6,
bpf.MapTypeHash,
&CaptureWcard6{}, int(unsafe.Sizeof(CaptureWcard6{})),
&CaptureRule6{}, int(unsafe.Sizeof(CaptureRule6{})),
MapSize,
bpf.BPF_F_NO_PREALLOC, 0,
bpf.ConvertKeyValue,
).WithCache()
30 changes: 30 additions & 0 deletions pkg/maps/recorder/recorder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2021 Authors of Cilium
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package recorder

const (
// MapNameWcard4 represents IPv4 capture wildcard table.
MapNameWcard4 = "cilium_capture4_rules"
// MapNameWcard6 represents IPv6 capture wildcard table.
MapNameWcard6 = "cilium_capture6_rules"
// MapSize is the default size of the v4 and v6 maps
MapSize = 16384
)

type CaptureRule struct {
RuleId uint16 `align:"rule_id"`
Reserved uint16 `align:"reserved"`
CapLen uint32 `align:"cap_len"`
}

0 comments on commit 9c47695

Please sign in to comment.