-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Takeru Hayasaka <hayatake396@gmail.com> Co-authored-by: Wataru Mishima <watal.i27e@gmail.com> Co-authored-by: Yuta Fukagawa <25516089+yfskyline@users.noreply.github.com>
- Loading branch information
1 parent
5af1beb
commit bf023bb
Showing
20 changed files
with
918 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Copyright (c) 2023 NTT Communications Corporation | ||
# Copyright (c) 2023 Takeru Hayasaka | ||
|
||
GOCMD=go | ||
BINARY_NAME=fluvia | ||
CLANG ?= clang | ||
CFLAGS := -O2 -g -Wall $(CFLAGS) | ||
DIFF_FROM_BRANCH_NAME ?= origin/main | ||
|
||
GREEN := $(shell tput -Txterm setaf 2) | ||
YELLOW := $(shell tput -Txterm setaf 3) | ||
WHITE := $(shell tput -Txterm setaf 7) | ||
CYAN := $(shell tput -Txterm setaf 6) | ||
RESET := $(shell tput -Txterm sgr0) | ||
|
||
.PHONY: all build clean | ||
|
||
all: go-gen build | ||
|
||
build: | ||
mkdir -p out/bin | ||
$(GOCMD) build -o out/bin/$(BINARY_NAME) ./cmd/$(BINARY_NAME)/main.go | ||
|
||
clean: | ||
rm -fr out | ||
|
||
go-gen: export BPF_CLANG := $(CLANG) | ||
go-gen: export BPF_CFLAGS := $(CFLAGS) | ||
go-gen: | ||
go generate ./... | ||
|
||
help: | ||
@echo '' | ||
@echo 'Usage:' | ||
@echo ' ${YELLOW}make${RESET} ${GREEN}<target>${RESET}' | ||
@echo '' | ||
@echo 'Targets:' | ||
@awk 'BEGIN {FS = ":.*?## "} { \ | ||
if (/^[a-zA-Z_-]+:.*?##.*$$/) {printf " ${YELLOW}%-20s${GREEN}%s${RESET}\n", $$1, $$2} \ | ||
else if (/^## .*$$/) {printf " ${CYAN}%s${RESET}\n", substr($$1,4)} \ | ||
}' $(MAKEFILE_LIST) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
--- | ||
ipfix: | ||
address: 127.0.0.1 | ||
port: 4739 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// Copyright (c) 2023 NTT Communications Corporation | ||
// Copyright (c) 2023 Takeru Hayasaka | ||
// | ||
// This software is released under the MIT License. | ||
// see https://github.com/nttcom/fluvia/blob/main/LICENSE | ||
|
||
package bpf | ||
|
||
import ( | ||
"fmt" | ||
"net" | ||
|
||
"github.com/cilium/ebpf" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -no-global-types -cc $BPF_CLANG -cflags $BPF_CFLAGS xdp ../../src/main.c -- -I../../src | ||
|
||
type XdpProbeData struct { | ||
H_dest [6]uint8 | ||
H_source [6]uint8 | ||
H_proto uint16 | ||
_ [2]byte | ||
V6Srcaddr struct{ In6U struct{ U6Addr8 [16]uint8 } } | ||
V6Dstaddr struct{ In6U struct{ U6Addr8 [16]uint8 } } | ||
NextHdr uint8 | ||
HdrExtLen uint8 | ||
RoutingType uint8 | ||
SegmentsLeft uint8 | ||
LastEntry uint8 | ||
Flags uint8 | ||
Tag uint16 | ||
Segments [10]struct{ In6U struct{ U6Addr8 [16]uint8 } } | ||
} | ||
|
||
func ReadXdpObjects(ops *ebpf.CollectionOptions) (*xdpObjects, error) { | ||
obj := &xdpObjects{} | ||
err := loadXdpObjects(obj, ops) | ||
if err != nil { | ||
return nil, errors.WithStack(err) | ||
} | ||
|
||
// TODO: BPF log level remove hardcoding. yaml in config | ||
if err != nil { | ||
return nil, errors.WithStack(err) | ||
} | ||
|
||
return obj, nil | ||
} | ||
|
||
const ( | ||
XDP_ABORTED uint32 = iota | ||
XDP_DROP | ||
XDP_PASS | ||
XDP_TX | ||
XDP_REDIRECT | ||
) | ||
|
||
func PrintEntrys(entry XdpProbeData, count uint64) { | ||
mac := func(mac [6]uint8) string { | ||
return fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) | ||
} | ||
saddr := net.IP(entry.V6Srcaddr.In6U.U6Addr8[:]).String() | ||
daddr := net.IP(entry.V6Dstaddr.In6U.U6Addr8[:]).String() | ||
|
||
fmt.Printf( | ||
"H_dest: %s, H_source: %v, H_proto: %v, V6Dstaddr: %v, V6Srcaddr: %v -> count: %v\n", | ||
mac(entry.H_dest), mac(entry.H_source), entry.H_proto, daddr, saddr, count) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
package bpf | ||
|
||
import ( | ||
"encoding/binary" | ||
"errors" | ||
"net" | ||
|
||
"github.com/google/gopacket" | ||
"github.com/google/gopacket/layers" | ||
) | ||
|
||
type Srv6Layer struct { | ||
layers.BaseLayer | ||
NextHeader uint8 | ||
HdrExtLen uint8 | ||
RoutingType uint8 | ||
SegmentsLeft uint8 | ||
LastEntry uint8 | ||
Flags uint8 | ||
Tag uint16 | ||
Segments []net.IP | ||
} | ||
|
||
var Srv6LayerType = gopacket.RegisterLayerType( | ||
2001, | ||
gopacket.LayerTypeMetadata{ | ||
Name: "Srv6LayerType", | ||
Decoder: gopacket.DecodeFunc(decodeSrv6Layer), | ||
}, | ||
) | ||
|
||
func (l *Srv6Layer) LayerType() gopacket.LayerType { | ||
return Srv6LayerType | ||
} | ||
|
||
func (i *Srv6Layer) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { | ||
if len(data) < 8 { | ||
df.SetTruncated() | ||
return errors.New("SRV6 layer less then 8 bytes for SRV6 packet") | ||
} | ||
i.NextHeader = data[0] | ||
i.HdrExtLen = data[1] | ||
i.RoutingType = data[2] | ||
i.SegmentsLeft = data[3] | ||
i.LastEntry = data[4] | ||
i.Flags = data[5] | ||
i.Tag = binary.BigEndian.Uint16(data[6:8]) | ||
|
||
for j := 0; j < int(i.HdrExtLen/2); j++ { | ||
startBit := 8 + 16*j | ||
endBit := 24 + 16*j | ||
var addr []byte | ||
for k := endBit; k >= startBit; k-- { | ||
addr = append(addr, data[k]) | ||
} | ||
i.Segments = append(i.Segments, addr) | ||
} | ||
i.BaseLayer = layers.BaseLayer{ | ||
Contents: data[:8], | ||
Payload: data[8:], | ||
} | ||
return nil | ||
} | ||
|
||
func (i *Srv6Layer) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { | ||
l := int(i.HdrExtLen)*8 + 8 | ||
bytes, err := b.PrependBytes(l) | ||
if err != nil { | ||
return err | ||
} | ||
bytes[0] = i.NextHeader | ||
bytes[1] = i.HdrExtLen | ||
bytes[2] = i.RoutingType | ||
bytes[3] = i.SegmentsLeft | ||
bytes[4] = i.LastEntry | ||
bytes[5] = i.Flags | ||
binary.BigEndian.PutUint16(bytes[6:], i.Tag) | ||
|
||
for i2, address := range i.Segments { | ||
lsb := binary.BigEndian.Uint64(address[:8]) | ||
msb := binary.BigEndian.Uint64(address[8:]) | ||
binary.BigEndian.PutUint64(bytes[8+16*i2:], lsb) | ||
binary.BigEndian.PutUint64(bytes[16+16*i2:], msb) | ||
} | ||
return nil | ||
} | ||
|
||
func (i *Srv6Layer) NextLayerType() gopacket.LayerType { | ||
return gopacket.LayerTypePayload | ||
} | ||
|
||
// Custom decode function. We can name it whatever we want | ||
// but it should have the same arguments and return value | ||
// When the layer is registered we tell it to use this decode function | ||
func decodeSrv6Layer(data []byte, p gopacket.PacketBuilder) error { | ||
i := &Srv6Layer{} | ||
err := i.DecodeFromBytes(data, p) | ||
if err != nil { | ||
return err | ||
} | ||
p.AddLayer(i) | ||
next := i.NextLayerType() | ||
if next == gopacket.LayerTypeZero { | ||
return nil | ||
} | ||
return p.NextDecoder(next) | ||
} |
Oops, something went wrong.