tetragon
236 строк · 4.5 Кб
1// SPDX-License-Identifier: Apache-2.0
2// Copyright Authors of Tetragon
3
4package vtuplefilter5
6import (7"fmt"8"net"9"strconv"10"strings"11
12"github.com/cilium/tetragon/pkg/vtuple"13)
14
15type Port = uint1616type Addr = net.IP17
18type ParseError struct {19msg string20}
21
22func (e *ParseError) Error() string {23return fmt.Sprintf("parsing error: %s", e.msg)24}
25
26func ParseErrorFmt(s string, args ...interface{}) *ParseError {27return &ParseError{28msg: fmt.Sprintf(s, args...),29}30}
31
32// FromLine
33func FromLine(s string) (Filter, error) {34var fs []Filter35
36for _, ss := range strings.Split(s, ",") {37var f Filter38opts := strings.Split(ss, "=")39if len(opts) != 2 {40return nil, ParseErrorFmt("expecting x=a format for %s", ss)41}42
43switch opts[0] {44case "sport", "dport", "port":45port64, err := strconv.ParseUint(opts[1], 10, 16)46if err != nil {47return nil, ParseErrorFmt("failed to parse %s as port: %s", opts[1], err)48}49port16 := uint16(port64)50switch opts[0] {51case "sport":52f = CreateSrcPortFilter(port16)53case "dport":54f = CreateDstPortFilter(port16)55case "port":56f = CreateAnyPortFilter(port16)57}58
59case "saddr":60case "daddr":61case "addr":62ip := net.ParseIP(opts[1])63if ip == nil {64return nil, ParseErrorFmt("failed to parse %s as ip", opts[1])65}66
67switch opts[0] {68case "saddr":69f = CreateSrcAddrFilter(ip)70case "daddr":71f = CreateDstAddrFilter(ip)72case "addr":73f = CreateAnyAddrFilter(ip)74}75
76case "prot":77switch strings.ToLower(opts[1]) {78case "tcp":79f = &ProtTcpFilter{}80case "udp":81f = &ProtUdpFilter{}82
83// NB: once needed, we can easily do {tcp,udp}{4,6}84}85
86default:87return nil, ParseErrorFmt("cannot parse %s: unknown %s", ss, opts[0])88}89
90if f == nil {91panic("Unexpected error: f should be set")92}93fs = append(fs, f)94}95
96return &And{fs: fs}, nil97}
98
99type Filter interface {100FilterFn(t vtuple.VTuple) bool101}
102
103// Logical operations
104type And struct {105fs []Filter106}
107
108func (op *And) FilterFn(t vtuple.VTuple) bool {109for _, f := range op.fs {110if !f.FilterFn(t) {111return false112}113} // NB: for 0 filters, AND returns true114return true115}
116
117func CreateAndFilter(fs ...Filter) Filter {118return &And{fs: fs}119}
120
121type Or struct {122fs []Filter123}
124
125func (op *Or) FilterFn(t vtuple.VTuple) bool {126for _, f := range op.fs {127if f.FilterFn(t) {128return true129}130}131// NB: for 0 filters, OR returns false132return false133}
134
135func CreateOrFilter(fs ...Filter) Filter {136return &Or{fs: fs}137}
138
139type Not struct {140f Filter
141}
142
143func (op *Not) FilterFn(t vtuple.VTuple) bool {144return !op.f.FilterFn(t)145}
146
147// getters/setters (or projections if you are into SQL)
148
149type PortFilter struct {150getPort (func(vtuple.VTuple) Port)151pred (func(Port) bool)152}
153
154// port filters
155
156func (pf *PortFilter) FilterFn(t vtuple.VTuple) bool {157addr := pf.getPort(t)158return pf.pred(addr)159}
160
161func CreateSrcPortFilter(port Port) Filter {162return &PortFilter{163getPort: func(t vtuple.VTuple) Port { return t.SrcPort() },164pred: func(p Port) bool { return p == port },165}166}
167func CreateDstPortFilter(port Port) Filter {168return &PortFilter{169getPort: func(t vtuple.VTuple) Port { return t.DstPort() },170pred: func(p Port) bool { return p == port },171}172}
173
174func CreateAnyPortFilter(port Port) Filter {175srcF := CreateSrcPortFilter(port)176dstF := CreateDstPortFilter(port)177return CreateOrFilter(srcF, dstF)178}
179
180// address filters
181
182type AddrFilter struct {183getAddr (func(vtuple.VTuple) Addr)184pred (func(Addr) bool)185}
186
187func (pf *AddrFilter) FilterFn(t vtuple.VTuple) bool {188addr := pf.getAddr(t)189return pf.pred(addr)190}
191
192func CreateSrcAddrFilter(addr Addr) Filter {193return &AddrFilter{194getAddr: func(t vtuple.VTuple) Addr { return t.SrcAddr() },195pred: func(a Addr) bool { return a.Equal(addr) },196}197}
198
199func CreateDstAddrFilter(addr Addr) Filter {200return &AddrFilter{201getAddr: func(t vtuple.VTuple) Addr { return t.DstAddr() },202pred: func(a Addr) bool { return a.Equal(addr) },203}204}
205
206func CreateAnyAddrFilter(addr Addr) Filter {207srcF := CreateSrcAddrFilter(addr)208dstF := CreateDstAddrFilter(addr)209return CreateOrFilter(srcF, dstF)210}
211
212// protocol filters
213
214type ProtTcpFilter struct{}215
216func (f *ProtTcpFilter) FilterFn(t vtuple.VTuple) bool {217return t.IsTCP()218}
219
220type ProtUdpFilter struct{}221
222func (f *ProtUdpFilter) FilterFn(t vtuple.VTuple) bool {223return t.IsUDP()224}
225
226type ProtIP4Filter struct{}227
228func (f *ProtIP4Filter) FilterFn(t vtuple.VTuple) bool {229return t.IsIP4()230}
231
232type ProtIP6Filter struct{}233
234func (f *ProtIP6Filter) FilterFn(t vtuple.VTuple) bool {235return t.IsIP6()236}
237