diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 3b7c913..38bdaea 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,14 +1,22 @@ +--- name: Test on: - push: pull_request: jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@main - - uses: actions/setup-go@v1 - with: - go-version: '1.16' - - run: go test ./... + - uses: actions/checkout@main + - uses: actions/setup-go@v1 + with: + go-version: '1.16' + - run: go test ./... + fmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@main + - uses: actions/setup-go@v1 + with: + go-version: '1.16' + - run: '[ -z "$(gofmt -e -d ./)" ]' diff --git a/LICENSE b/LICENSE index e1c3e53..68b6515 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021 Leon Löchner +Copyright (c) 2022 Leon Löchner Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/match_modules.go b/match_modules.go index c7e4d52..07182c7 100644 --- a/match_modules.go +++ b/match_modules.go @@ -80,7 +80,7 @@ func (p *Parser) parseStatistic(f *map[string]Flag) (state, error) { // unscanIgnoreWhitespace twice (this can fail // because of a fixed sized buffer, that is full // of Whitespaces). - p.unscan(1) //IgnoreWhitespace(2) // unscan 2 + p.unscan(1) // IgnoreWhitespace(2) // unscan 2 return sNot, nil } case sIF: @@ -160,7 +160,7 @@ func (p *Parser) parseUdp(f *map[string]Flag) (state, error) { // unscanIgnoreWhitespace twice (this can fail // because of a fixed sized buffer, that is full // of Whitespaces). - p.unscan(1) //IgnoreWhitespace(2) // unscan 2 + p.unscan(1) // IgnoreWhitespace(2) // unscan 2 return sNot, nil } case sIF: @@ -188,10 +188,10 @@ func (p *Parser) parseUdp(f *map[string]Flag) (state, error) { } return sStart, nil } + func (p *Parser) parseAddrtype(f *map[string]Flag) (state, error) { s := sStart for tok, lit := p.scanIgnoreWhitespace(); tok != EOF; tok, lit = p.scanIgnoreWhitespace() { - for nextValue := false; !nextValue; { nextValue = true switch s { @@ -228,7 +228,7 @@ func (p *Parser) parseAddrtype(f *map[string]Flag) (state, error) { // unscanIgnoreWhitespace twice (this can fail // because of a fixed sized buffer, that is full // of Whitespaces). - p.unscan(1) //IgnoreWhitespace(2) // unscan 2 + p.unscan(1) // IgnoreWhitespace(2) // unscan 2 return sNot, nil } case sIF: @@ -334,7 +334,7 @@ func (p *Parser) parseTcp(f *map[string]Flag) (state, error) { // unscanIgnoreWhitespace twice (this can fail // because of a fixed sized buffer, that is full // of Whitespaces). - p.unscan(1) //IgnoreWhitespace(2) // unscan 2 + p.unscan(1) // IgnoreWhitespace(2) // unscan 2 return sNot, nil } case sIF: diff --git a/parser.go b/parser.go index 031e639..73a8d81 100644 --- a/parser.go +++ b/parser.go @@ -60,9 +60,8 @@ func (d Policy) String() string { } if d.Counter != nil { return fmt.Sprintf("%s%s %s %s", prefix, d.Chain, d.Action, d.Counter.String()) - } else { - return fmt.Sprintf("%s%s %s", prefix, d.Chain, d.Action) } + return fmt.Sprintf("%s%s %s", prefix, d.Chain, d.Action) } // Rule represents a rule in an iptables dump. Normally the start with -A. @@ -144,7 +143,6 @@ func (r Rule) Spec() (ret []string) { } else { ret = append(ret, "!", "-f") } - } if r.IPv4 { ret = append(ret, "-4") @@ -154,7 +152,6 @@ func (r Rule) Spec() (ret []string) { } if len(r.Matches) > 0 { for _, m := range r.Matches { - ret = append(ret, m.Spec()...) } } @@ -169,8 +166,8 @@ func (r Rule) Spec() (ret []string) { // EqualTo returns true, if the rules are // equal to each other. -func (r1 Rule) EqualTo(r2 Rule) bool { - return reflect.DeepEqual(r1, r2) +func (r Rule) EqualTo(r2 Rule) bool { + return reflect.DeepEqual(r, r2) } // DNSOrIPPair either holds an IP or DNS and a flag. @@ -187,6 +184,7 @@ func (d DNSOrIPPair) String(f string) string { return strings.Join(d.Spec(f), " ") } +// Spec returns a DNSOrIPPair how coreos' iptables package would expect it. func (d DNSOrIPPair) Spec(f string) []string { s := []string{"!", f, d.Value.String()} if !d.Not { @@ -256,6 +254,7 @@ func (sp StringPair) String(f string) string { return strings.Join(sp.Spec(f), " ") } +// Spec returns a StringPair how coreos' iptables package would expect it. func (sp StringPair) Spec(f string) []string { ret := []string{"!", f, sp.Value} if !sp.Not { @@ -285,6 +284,7 @@ func (m Match) String() string { return strings.Join(m.Spec(), " ") } +// Spec returns a Match how coreos' iptables package would expect it. func (m Match) Spec() []string { ret := make([]string, 2, 2+len(m.Flags)*2) ret[0], ret[1] = "-m", m.Type @@ -305,6 +305,7 @@ func (fl Flag) String(f string) string { return strings.Join(fl.Spec(f), " ") } +// Spec returns a Flag how coreos' iptables package would expect it. func (fl Flag) Spec(f string) []string { ret := []string{"!", f} ret = append(ret, fl.Values...) @@ -314,6 +315,7 @@ func (fl Flag) Spec(f string) []string { return ret } +// Target represents a Target Extension. See iptables-extensions(8). type Target struct { Name string Flags map[string]Flag @@ -323,6 +325,7 @@ func (t Target) String(name string) string { return strings.Join(t.Spec(name), " ") } +// Spec returns a Target how coreos' iptables package would expect it. func (t Target) Spec(f string) []string { ret := make([]string, 2, 2+len(t.Flags)*2) ret[0], ret[1] = f, t.Name @@ -332,17 +335,17 @@ func (t Target) Spec(f string) []string { return ret } -// Max buffer size of the ring buffer in the parser. -const BUF_SIZE = 10 +// BUFSIZE is the max buffer size of the ring buffer in the parser. +const BUFSIZE = 16 // Parser represents a parser. type Parser struct { s *scanner buf struct { - toks [BUF_SIZE]Token // token buffer - lits [BUF_SIZE]string // literal buffer - p int // current position in the buffer (max=BUF_SIZE) - n int // offset (max=BUF_SIZE) + toks [BUFSIZE]Token // token buffer + lits [BUFSIZE]string // literal buffer + p int // current position in the buffer (max=BUF_SIZE) + n int // offset (max=BUF_SIZE) } } @@ -371,7 +374,7 @@ func (p *Parser) Parse() (l Line, err error) { case COLON: return p.parseDefault(p.s.scanLine()) case EOF: - return nil, io.EOF //ErrEOF + return nil, io.EOF // ErrEOF case NEWLINE: return nil, errors.New("empty line") default: @@ -392,8 +395,10 @@ func (p *Parser) ParseRule() (*Rule, error) { } } -var matchModules map[string]struct{} -var targetExtensions map[string]struct{} +var ( + matchModules map[string]struct{} + targetExtensions map[string]struct{} +) func init() { matchModules = make(map[string]struct{}) @@ -430,17 +435,17 @@ func (p *Parser) parseDefault(lit string) (Line, error) { func parseCounter(bytes []byte) (Counter, error) { var c Counter pc := regCounter.ReplaceAll(bytes, []byte("$1")) - if i, err := strconv.ParseUint(string(pc), 10, 0); err != nil { + i, err := strconv.ParseUint(string(pc), 10, 0) + if err != nil { return c, fmt.Errorf("Could not parse counter: %w", err) - } else { - c.packets = i } + c.packets = i pc = regCounter.ReplaceAll(bytes, []byte("$2")) - if i, err := strconv.ParseUint(string(pc), 10, 0); err != nil { + i, err = strconv.ParseUint(string(pc), 10, 0) + if err != nil { return c, fmt.Errorf("Could not parse counter: %w", err) - } else { - c.bytes = i } + c.bytes = i return c, nil } @@ -579,7 +584,6 @@ func (p *Parser) parseRule() (Line, error) { // Avoid scanning the next token, if an error occured. nextValue = nextValue && err == nil } - } return r, nil } @@ -608,7 +612,7 @@ func (p *Parser) parsePolicy(d bool) (Line, error) { return ret, nil } if tok, lit := p.scanIgnoreWhitespace(); tok != EOF && tok != NEWLINE { - return nil, fmt.Errorf("found %q, expected EOF or newline.", lit) + return nil, fmt.Errorf("found %q, expected EOF or newline", lit) } return ret, nil } @@ -648,9 +652,8 @@ func (p *Parser) parseStringPair(sp *StringPair, not bool) (state, error) { *sp = StringPair{Value: "", Not: not} p.unscan(1) return sStart, errors.New("unexpected token, expected IDENT") - } else { - *sp = StringPair{Value: lit, Not: not} } + *sp = StringPair{Value: lit, Not: not} return sStart, nil } @@ -666,14 +669,14 @@ func (p *Parser) scan() (tok Token, lit string) { // If we have a token on the buffer, return it. if p.buf.n != 0 { p.buf.n-- - return p.buf.toks[mod(p.buf.p-p.buf.n-1, BUF_SIZE)], p.buf.lits[mod(p.buf.p-p.buf.n-1, BUF_SIZE)] + return p.buf.toks[mod(p.buf.p-p.buf.n-1, BUFSIZE)], p.buf.lits[mod(p.buf.p-p.buf.n-1, BUFSIZE)] } // Otherwise read the next token from the scanner. tok, lit = p.s.scan() // Save it to the buffer in case we unscan later. p.buf.toks[p.buf.p], p.buf.lits[p.buf.p] = tok, lit p.buf.p++ // increase the pointer of the ring buffer. - p.buf.p %= BUF_SIZE + p.buf.p %= BUFSIZE return } @@ -689,28 +692,12 @@ func (p *Parser) scanIgnoreWhitespace() (tok Token, lit string) { // unscan reverts the pointer on the buffer, callers should not unscan more then what was // previously read, or values larger then BUF_SIZE. func (p *Parser) unscan(n int) { - if p.buf.n+n >= BUF_SIZE { + if p.buf.n+n >= BUFSIZE { panic("size exceeds buffer") } p.buf.n += n } -func (p *Parser) unscanIgnoreWhitespace(n int) error { - for i := 0; i < BUF_SIZE; i++ { - if p.buf.toks[p.buf.n] == ILLEGAL { - break - } - if p.buf.toks[p.buf.n] == WS { - p.unscan(1) - } else { - if n--; n == 0 { - return nil - } - } - } - return errors.New("buffer has no none whitespace characters") -} - var hasWS *regexp.Regexp = regexp.MustCompile(`\s`) func enquoteIfWS(s []string) []string { diff --git a/parser_test.go b/parser_test.go index 80c8477..44b54e5 100644 --- a/parser_test.go +++ b/parser_test.go @@ -54,7 +54,6 @@ func TestDNSOrIPPair_Spec(t *testing.T) { } { if res := tc.d.Spec(tc.f); !reflect.DeepEqual(res, tc.r) { t.Errorf("test %d:\n\texp=%q\n\tgot=%q\n", i, tc.r, res) - } } } @@ -84,7 +83,6 @@ func TestStringPair_Spec(t *testing.T) { } { if res := tc.p.Spec(tc.f); !reflect.DeepEqual(res, tc.r) { t.Errorf("test %d:\n\texp=%q\n\tgot=%q\n", i, tc.r, res) - } } } @@ -114,7 +112,6 @@ func TestFlag_String(t *testing.T) { } { if res := tc.p.String(tc.f); !reflect.DeepEqual(res, tc.r) { t.Errorf("test %d:\n\texp=%q\n\tgot=%q\n", i, tc.r, res) - } } } @@ -128,7 +125,7 @@ func TestMatch_String(t *testing.T) { p: Match{ Type: "comment", Flags: map[string]Flag{ - "comment": Flag{ + "comment": { Values: []string{"hallo"}, }, }, @@ -139,7 +136,7 @@ func TestMatch_String(t *testing.T) { p: Match{ Type: "tcp", Flags: map[string]Flag{ - "tcp-options": Flag{ + "tcp-options": { Not: true, Values: []string{"bla", "blub"}, }, @@ -150,7 +147,6 @@ func TestMatch_String(t *testing.T) { } { if res := tc.p.String(); !reflect.DeepEqual(res, tc.r) { t.Errorf("test %d:\n\texp=%q\n\tgot=%q\n", i, tc.r, res) - } } } @@ -165,7 +161,7 @@ func TestTarget_String(t *testing.T) { p: Target{ Name: "foo", Flags: map[string]Flag{ - "bar": Flag{ + "bar": { Values: []string{"foo"}, }, }, @@ -177,7 +173,7 @@ func TestTarget_String(t *testing.T) { p: Target{ Name: "foo", Flags: map[string]Flag{ - "bar": Flag{ + "bar": { Not: true, Values: []string{"foo", "bar"}, }, @@ -189,7 +185,6 @@ func TestTarget_String(t *testing.T) { } { if res := tc.p.String(tc.f); !reflect.DeepEqual(res, tc.r) { t.Errorf("test %d:\n\texp=%q\n\tgot=%q\n", i, tc.r, res) - } } } @@ -202,10 +197,12 @@ func TestRule_Spec(t *testing.T) { { rule: Rule{ Chain: "foo", - Source: &DNSOrIPPair{Value: DNSOrIP{ - iP: parseCIDR("192.168.178.2"), + Source: &DNSOrIPPair{ + Value: DNSOrIP{ + iP: parseCIDR("192.168.178.2"), + }, + Not: true, }, - Not: true}, Destination: &DNSOrIPPair{Value: DNSOrIP{iP: parseCIDR("1.1.1.1")}, Not: true}, }, res: []string{"!", "-s", "192.168.178.2/32", "!", "-d", "1.1.1.1/32"}, @@ -213,7 +210,6 @@ func TestRule_Spec(t *testing.T) { } { if res := tc.rule.Spec(); !reflect.DeepEqual(res, tc.res) { t.Errorf("test %d:\n\texp=%q\n\tgot=%q\n", i, tc.res, res) - } } } @@ -226,10 +222,12 @@ func TestRule_String(t *testing.T) { { rule: Rule{ Chain: "foo", - Source: &DNSOrIPPair{Value: DNSOrIP{ - iP: parseCIDR("192.168.178.2"), + Source: &DNSOrIPPair{ + Value: DNSOrIP{ + iP: parseCIDR("192.168.178.2"), + }, + Not: true, }, - Not: true}, Destination: &DNSOrIPPair{Value: DNSOrIP{iP: parseCIDR("1.1.1.1")}, Not: true}, }, res: "-A foo ! -s 192.168.178.2/32 ! -d 1.1.1.1/32", @@ -241,14 +239,14 @@ func TestRule_String(t *testing.T) { { Type: "comment", Flags: map[string]Flag{ - "comment": Flag{Values: []string{`kubernetes service traffic requiring SNAT`}}, + "comment": {Values: []string{`kubernetes service traffic requiring SNAT`}}, }, }, }, Jump: &Target{ Name: "MASQUERADE", Flags: map[string]Flag{ - "to-ports": Flag{ + "to-ports": { Values: []string{"200-1000"}, }, }, @@ -259,7 +257,6 @@ func TestRule_String(t *testing.T) { } { if res := tc.rule.String(); !reflect.DeepEqual(res, tc.res) { t.Errorf("test %d:\n\texp=%q\n\tgot=%q\n", i, tc.res, res) - } } } @@ -333,7 +330,8 @@ func TestParser_Parse(t *testing.T) { Counter: &Counter{ packets: 10, bytes: 100, - }}, + }, + }, err: nil, }, { @@ -345,7 +343,8 @@ func TestParser_Parse(t *testing.T) { Counter: &Counter{ packets: 0, bytes: 100, - }}, + }, + }, err: nil, }, { @@ -372,10 +371,12 @@ func TestParser_Parse(t *testing.T) { s: "-A foo ! -s 192.168.178.2 ! --dst 1.1.1.1", r: Rule{ Chain: "foo", - Source: &DNSOrIPPair{Value: DNSOrIP{ - iP: parseCIDR("192.168.178.2"), + Source: &DNSOrIPPair{ + Value: DNSOrIP{ + iP: parseCIDR("192.168.178.2"), + }, + Not: true, }, - Not: true}, Destination: &DNSOrIPPair{Value: DNSOrIP{iP: parseCIDR("1.1.1.1")}, Not: true}, }, err: nil, @@ -418,7 +419,7 @@ func TestParser_Parse(t *testing.T) { { Type: "comment", Flags: map[string]Flag{ - "comment": Flag{ + "comment": { Values: []string{`this crazy\`}, }, }, @@ -448,7 +449,7 @@ func TestParser_Parse(t *testing.T) { { Type: "comment", Flags: map[string]Flag{ - "comment": Flag{ + "comment": { Values: []string{`this crazy`}, }, }, @@ -478,7 +479,7 @@ func TestParser_Parse(t *testing.T) { { Type: "comment", Flags: map[string]Flag{ - "comment": Flag{ + "comment": { Values: []string{`--this-crazy`}, }, }, @@ -506,7 +507,7 @@ func TestParser_Parse(t *testing.T) { { Type: "comment", Flags: map[string]Flag{ - "comment": Flag{ + "comment": { Values: []string{`this \"crazy\"`}, }, }, @@ -527,7 +528,7 @@ func TestParser_Parse(t *testing.T) { { Type: "comment", Flags: map[string]Flag{ - "comment": Flag{ + "comment": { Values: []string{`this \"crazy\"`}, }, }, @@ -560,9 +561,9 @@ func TestParser_Parse(t *testing.T) { { Type: "tcp", Flags: map[string]Flag{ - "destination-port": Flag{Values: []string{"8080:9000"}}, - "source-port": Flag{Values: []string{"1010"}}, - "tcp-flags": Flag{Values: []string{"SYN,FIN", "ACK"}}, + "destination-port": {Values: []string{"8080:9000"}}, + "source-port": {Values: []string{"1010"}}, + "tcp-flags": {Values: []string{"SYN,FIN", "ACK"}}, }, }, }, @@ -579,12 +580,12 @@ func TestParser_Parse(t *testing.T) { { Type: "tcp", Flags: map[string]Flag{ - "source-port": Flag{Values: []string{"1010"}}, - "destination-port": Flag{ + "source-port": {Values: []string{"1010"}}, + "destination-port": { Values: []string{"1000"}, Not: true, }, - "tcp-flags": Flag{Values: []string{"SYN,FIN", "ACK"}}, + "tcp-flags": {Values: []string{"SYN,FIN", "ACK"}}, }, }, }, @@ -601,17 +602,17 @@ func TestParser_Parse(t *testing.T) { { Type: "tcp", Flags: map[string]Flag{ - "source-port": Flag{Values: []string{"1010"}}, - "destination-port": Flag{ + "source-port": {Values: []string{"1010"}}, + "destination-port": { Values: []string{"1000:1010"}, Not: true, }, - "tcp-flags": Flag{Values: []string{"SYN,FIN", "ACK"}}, - "tcp-option": Flag{ + "tcp-flags": {Values: []string{"SYN,FIN", "ACK"}}, + "tcp-option": { Not: true, Values: []string{"1"}, }, - "syn": Flag{ + "syn": { Not: true, }, }, @@ -630,21 +631,21 @@ func TestParser_Parse(t *testing.T) { { Type: "tcp", Flags: map[string]Flag{ - "source-port": Flag{ + "source-port": { Not: true, Values: []string{"1010"}, }, - "destination-port": Flag{ + "destination-port": { Values: []string{"1000:1010"}, }, - "tcp-flags": Flag{ + "tcp-flags": { Not: true, Values: []string{"SYN,FIN", "ACK"}, }, - "tcp-option": Flag{ + "tcp-option": { Values: []string{"1"}, }, - "syn": Flag{}, + "syn": {}, }, }, }, @@ -676,29 +677,29 @@ func TestParser_Parse(t *testing.T) { { Type: "tcp", Flags: map[string]Flag{ - "source-port": Flag{ + "source-port": { Not: true, Values: []string{"1010"}, }, - "destination-port": Flag{ + "destination-port": { Values: []string{"1000:1010"}, }, - "tcp-flags": Flag{ + "tcp-flags": { Not: true, Values: []string{"SYN,FIN", "ACK"}, }, - "tcp-option": Flag{ + "tcp-option": { Values: []string{"1"}, }, - "syn": Flag{}, + "syn": {}, }, }, }, Jump: &Target{ Name: "DNAT", Flags: map[string]Flag{ - "random": Flag{}, - "to-destination": Flag{ + "random": {}, + "to-destination": { Values: []string{"192.168.1.1-192.168.1.2:80-81"}, }, }, @@ -718,7 +719,7 @@ func TestParser_Parse(t *testing.T) { Jump: &Target{ Name: "SNAT", Flags: map[string]Flag{ - "to-source": Flag{ + "to-source": { Values: []string{"192.168.1.1"}, }, }, @@ -738,10 +739,10 @@ func TestParser_Parse(t *testing.T) { Jump: &Target{ Name: "SNAT", Flags: map[string]Flag{ - "to-source": Flag{ + "to-source": { Values: []string{"192.168.1.1"}, }, - "random-fully": Flag{}, + "random-fully": {}, }, }, }, @@ -756,13 +757,13 @@ func TestParser_Parse(t *testing.T) { { Type: "comment", Flags: map[string]Flag{ - "comment": Flag{Values: []string{`kubernetes service nodeports; NOTE: this must be the last rule in this chain`}}, + "comment": {Values: []string{`kubernetes service nodeports; NOTE: this must be the last rule in this chain`}}, }, }, { Type: "addrtype", Flags: map[string]Flag{ - "dst-type": Flag{ + "dst-type": { Values: []string{"LOCAL"}, }, }, @@ -791,13 +792,13 @@ func TestParser_Parse(t *testing.T) { { Type: "comment", Flags: map[string]Flag{ - "comment": Flag{Values: []string{`kube-system/kube-dns:dns cluster IP`}}, + "comment": {Values: []string{`kube-system/kube-dns:dns cluster IP`}}, }, }, { Type: "udp", Flags: map[string]Flag{ - "destination-port": Flag{ + "destination-port": { Values: []string{"53"}, }, }, @@ -818,14 +819,14 @@ func TestParser_Parse(t *testing.T) { { Type: "comment", Flags: map[string]Flag{ - "comment": Flag{Values: []string{`kubernetes service traffic requiring SNAT`}}, + "comment": {Values: []string{`kubernetes service traffic requiring SNAT`}}, }, }, }, Jump: &Target{ Name: "MASQUERADE", Flags: map[string]Flag{ - "random-fully": Flag{}, + "random-fully": {}, }, }, }, @@ -840,16 +841,16 @@ func TestParser_Parse(t *testing.T) { { Type: "comment", Flags: map[string]Flag{ - "comment": Flag{Values: []string{`kubernetes service traffic requiring SNAT`}}, + "comment": {Values: []string{`kubernetes service traffic requiring SNAT`}}, }, }, }, Jump: &Target{ Name: "MASQUERADE", Flags: map[string]Flag{ - "random-fully": Flag{}, - "random": Flag{}, - "to-ports": Flag{ + "random-fully": {}, + "random": {}, + "to-ports": { Values: []string{"200-1000"}, }, }, @@ -862,12 +863,15 @@ func TestParser_Parse(t *testing.T) { s: "-A foo ! -s 192.168.178.2 ! --dst 1.1.1.1 -m statistic --mode random --probability 0.50000000000 --every 10 --packet 5", r: Rule{ Chain: "foo", - Source: &DNSOrIPPair{Value: DNSOrIP{ - iP: parseCIDR("192.168.178.2"), + Source: &DNSOrIPPair{ + Value: DNSOrIP{ + iP: parseCIDR("192.168.178.2"), + }, + Not: true, }, - Not: true}, Destination: &DNSOrIPPair{Value: DNSOrIP{iP: parseCIDR("1.1.1.1")}, Not: true}, - Matches: []Match{{Type: "statistic", + Matches: []Match{{ + Type: "statistic", Flags: map[string]Flag{ "mode": { Values: []string{`random`}, @@ -881,7 +885,8 @@ func TestParser_Parse(t *testing.T) { "every": { Values: []string{`10`}, }, - }}}, + }, + }}, }, err: nil, }, @@ -894,7 +899,8 @@ func TestParser_Parse(t *testing.T) { Counter: &Counter{ packets: 0, bytes: 100, - }}, + }, + }, err: nil, }, { @@ -910,7 +916,7 @@ func TestParser_Parse(t *testing.T) { { Type: "addrtype", Flags: map[string]Flag{ - "dst-type": Flag{Values: []string{"LOCAL"}}, + "dst-type": {Values: []string{"LOCAL"}}, }, }, }, @@ -974,7 +980,7 @@ func TestParser_Parse(t *testing.T) { { Type: "tcp", Flags: map[string]Flag{ - "destination-port": Flag{ + "destination-port": { Values: []string{"6443"}, }, }, @@ -1034,7 +1040,8 @@ func TestParser_ParseMore(t *testing.T) { Counter: &Counter{ packets: 10, bytes: 100, - }}, + }, + }, Rule{ Chain: "foo", Destination: &DNSOrIPPair{Value: DNSOrIP{iP: parseCIDR("192.168.178.2")}}, @@ -1052,7 +1059,7 @@ func TestParser_ParseMore(t *testing.T) { { Type: "comment", Flags: map[string]Flag{ - "comment": Flag{ + "comment": { Values: []string{`this crazy`}, }, }, @@ -1067,16 +1074,16 @@ func TestParser_ParseMore(t *testing.T) { { Type: "comment", Flags: map[string]Flag{ - "comment": Flag{Values: []string{"kubernetes service traffic requiring SNAT"}}, + "comment": {Values: []string{"kubernetes service traffic requiring SNAT"}}, }, }, }, Jump: &Target{ Name: "MASQUERADE", Flags: map[string]Flag{ - "random-fully": Flag{}, - "random": Flag{}, - "to-ports": Flag{ + "random-fully": {}, + "random": {}, + "to-ports": { Values: []string{"200-1000"}, }, }, @@ -1103,7 +1110,7 @@ func TestParser_ParseMore(t *testing.T) { { Type: "addrtype", Flags: map[string]Flag{ - "dst-type": Flag{Values: []string{"LOCAL"}}, + "dst-type": {Values: []string{"LOCAL"}}, }, }, }, @@ -1152,7 +1159,7 @@ func TestParser_ParseMore(t *testing.T) { { Type: "tcp", Flags: map[string]Flag{ - "destination-port": Flag{ + "destination-port": { Values: []string{"6443"}, }, },