From 031c75209e72182a0a39f91e896103c4586ba901 Mon Sep 17 00:00:00 2001 From: RandolphCYG Date: Wed, 17 Nov 2021 19:50:40 +0800 Subject: [PATCH] [FIX]fix GetRule method https://github.com/google/nftables/issues/114 && add GetTable and GetChain method to get specific data by name && add test files --- .github/workflows/push.yml | 0 .gitignore | 1 + CONTRIBUTING.md | 0 LICENSE | 0 README.md | 61 ++++++++++++++++++++++++++++++++++++-- binaryutil/binaryutil.go | 0 chain.go | 14 +++++++++ conn.go | 0 counter.go | 0 doc.go | 0 expr/bitwise.go | 0 expr/bitwise_test.go | 0 expr/byteorder.go | 0 expr/counter.go | 0 expr/ct.go | 0 expr/dup.go | 0 expr/dynset.go | 0 expr/expr.go | 0 expr/exthdr.go | 0 expr/fib.go | 0 expr/hash.go | 0 expr/immediate.go | 0 expr/limit.go | 0 expr/log.go | 0 expr/lookup.go | 0 expr/nat.go | 0 expr/notrack.go | 0 expr/numgen.go | 0 expr/objref.go | 0 expr/payload.go | 0 expr/queue.go | 0 expr/range.go | 0 expr/redirect.go | 0 expr/reject.go | 0 expr/rt.go | 0 expr/tproxy.go | 0 expr/verdict.go | 0 go.mod | 0 go.sum | 0 nftables_test.go | 0 obj.go | 0 rule.go | 6 +++- set.go | 0 set_test.go | 0 table.go | 17 +++++++++++ tests/get_data_test.go | 52 ++++++++++++++++++++++++++++++++ util.go | 0 47 files changed, 148 insertions(+), 3 deletions(-) mode change 100644 => 100755 .github/workflows/push.yml create mode 100644 .gitignore mode change 100644 => 100755 CONTRIBUTING.md mode change 100644 => 100755 LICENSE mode change 100644 => 100755 README.md mode change 100644 => 100755 binaryutil/binaryutil.go mode change 100644 => 100755 chain.go mode change 100644 => 100755 conn.go mode change 100644 => 100755 counter.go mode change 100644 => 100755 doc.go mode change 100644 => 100755 expr/bitwise.go mode change 100644 => 100755 expr/bitwise_test.go mode change 100644 => 100755 expr/byteorder.go mode change 100644 => 100755 expr/counter.go mode change 100644 => 100755 expr/ct.go mode change 100644 => 100755 expr/dup.go mode change 100644 => 100755 expr/dynset.go mode change 100644 => 100755 expr/expr.go mode change 100644 => 100755 expr/exthdr.go mode change 100644 => 100755 expr/fib.go mode change 100644 => 100755 expr/hash.go mode change 100644 => 100755 expr/immediate.go mode change 100644 => 100755 expr/limit.go mode change 100644 => 100755 expr/log.go mode change 100644 => 100755 expr/lookup.go mode change 100644 => 100755 expr/nat.go mode change 100644 => 100755 expr/notrack.go mode change 100644 => 100755 expr/numgen.go mode change 100644 => 100755 expr/objref.go mode change 100644 => 100755 expr/payload.go mode change 100644 => 100755 expr/queue.go mode change 100644 => 100755 expr/range.go mode change 100644 => 100755 expr/redirect.go mode change 100644 => 100755 expr/reject.go mode change 100644 => 100755 expr/rt.go mode change 100644 => 100755 expr/tproxy.go mode change 100644 => 100755 expr/verdict.go mode change 100644 => 100755 go.mod mode change 100644 => 100755 go.sum mode change 100644 => 100755 nftables_test.go mode change 100644 => 100755 obj.go mode change 100644 => 100755 rule.go mode change 100644 => 100755 set.go mode change 100644 => 100755 set_test.go mode change 100644 => 100755 table.go create mode 100644 tests/get_data_test.go mode change 100644 => 100755 util.go diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml old mode 100644 new mode 100755 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f11b75 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md old mode 100644 new mode 100755 diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 index cb633c7..5853f92 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ [![Build Status](https://github.com/google/nftables/actions/workflows/push.yml/badge.svg)](https://github.com/google/nftables/actions/workflows/push.yml) [![GoDoc](https://godoc.org/github.com/google/nftables?status.svg)](https://godoc.org/github.com/google/nftables) +## 1. Introduction **This is not the correct repository for issues with the Linux nftables project!** This repository contains a third-party Go package to programmatically interact with nftables. Find the official nftables website at @@ -11,14 +12,70 @@ implemented in pure Go, i.e. does not wrap libnftnl. This is not an official Google product. -## Breaking changes +## 2. Breaking changes This package is in very early stages, and only contains enough data types and functions to install very basic nftables rules. It is likely that mistakes with the data types/API will be identified as more functionality is added. -## Contributions +## 3. Contributions Contributions are very welcome! +## 4. Examples + +### 1. Get common data types of Nftables + +#### 1.1. Get table by net family and its name + +```go +conn := nftables.Conn{} // start up a conn + +table, _ := conn.GetTable("nat", nftables.TableFamilyIPv4) +fmt.Println(table.Name) +``` +#### 1.2. Get chain by chain's name + +```go +conn := nftables.Conn{} // start up a conn +chain, _ := conn.GetChain("POSTROUTING") // get chain +fmt.Println(chain.Name) +``` + +#### 1.3. Get set and set's elements by table and set's name + +```go +conn := nftables.Conn{} // start up a conn + +table, _ := conn.GetTable("nat", nftables.TableFamilyIPv4) // get table + + +set, _ := conn.GetSetByName(table, "dest_addrs") // get set +fmt.Println(set.Name) + +eles, _ := conn.GetSetElements(set) +fmt.Println(eles) +``` + +#### 1.4. Get rules by table and chain + +```go + conn := nftables.Conn{} // start up a conn + + table, _ := conn.GetTable("nat", nftables.TableFamilyIPv4) // get table + chain, _ := conn.GetChain("POSTROUTING") // get chain + + rules, _ := conn.GetRule(table, chain) // get rules + for _, rule := range rules { + fmt.Println(rule.Table.Name, rule.Table.Family, rule.Chain.Name, rule.Handle) + // unpack exprs + for _, expr := range rule.Exprs { + fmt.Println(expr) + } + } +``` + +### 2. Insert common data types of Nftables + +**wait for update** \ No newline at end of file diff --git a/binaryutil/binaryutil.go b/binaryutil/binaryutil.go old mode 100644 new mode 100755 diff --git a/chain.go b/chain.go old mode 100644 new mode 100755 index 74caca5..1a4a445 --- a/chain.go +++ b/chain.go @@ -205,6 +205,20 @@ func (cc *Conn) ListChains() ([]*Chain, error) { return chains, nil } +// GetChain gets a chain by name +func (cc *Conn) GetChain(name string) (*Chain, error) { + chains, err := cc.ListChains() + if err != nil { + return nil, err + } + for _, chain := range chains { + if chain.Name == name { + return chain, nil + } + } + return nil, nil +} + func chainFromMsg(msg netlink.Message) (*Chain, error) { chainHeaderType := netlink.HeaderType((unix.NFNL_SUBSYS_NFTABLES << 8) | unix.NFT_MSG_NEWCHAIN) if got, want := msg.Header.Type, chainHeaderType; got != want { diff --git a/conn.go b/conn.go old mode 100644 new mode 100755 diff --git a/counter.go b/counter.go old mode 100644 new mode 100755 diff --git a/doc.go b/doc.go old mode 100644 new mode 100755 diff --git a/expr/bitwise.go b/expr/bitwise.go old mode 100644 new mode 100755 diff --git a/expr/bitwise_test.go b/expr/bitwise_test.go old mode 100644 new mode 100755 diff --git a/expr/byteorder.go b/expr/byteorder.go old mode 100644 new mode 100755 diff --git a/expr/counter.go b/expr/counter.go old mode 100644 new mode 100755 diff --git a/expr/ct.go b/expr/ct.go old mode 100644 new mode 100755 diff --git a/expr/dup.go b/expr/dup.go old mode 100644 new mode 100755 diff --git a/expr/dynset.go b/expr/dynset.go old mode 100644 new mode 100755 diff --git a/expr/expr.go b/expr/expr.go old mode 100644 new mode 100755 diff --git a/expr/exthdr.go b/expr/exthdr.go old mode 100644 new mode 100755 diff --git a/expr/fib.go b/expr/fib.go old mode 100644 new mode 100755 diff --git a/expr/hash.go b/expr/hash.go old mode 100644 new mode 100755 diff --git a/expr/immediate.go b/expr/immediate.go old mode 100644 new mode 100755 diff --git a/expr/limit.go b/expr/limit.go old mode 100644 new mode 100755 diff --git a/expr/log.go b/expr/log.go old mode 100644 new mode 100755 diff --git a/expr/lookup.go b/expr/lookup.go old mode 100644 new mode 100755 diff --git a/expr/nat.go b/expr/nat.go old mode 100644 new mode 100755 diff --git a/expr/notrack.go b/expr/notrack.go old mode 100644 new mode 100755 diff --git a/expr/numgen.go b/expr/numgen.go old mode 100644 new mode 100755 diff --git a/expr/objref.go b/expr/objref.go old mode 100644 new mode 100755 diff --git a/expr/payload.go b/expr/payload.go old mode 100644 new mode 100755 diff --git a/expr/queue.go b/expr/queue.go old mode 100644 new mode 100755 diff --git a/expr/range.go b/expr/range.go old mode 100644 new mode 100755 diff --git a/expr/redirect.go b/expr/redirect.go old mode 100644 new mode 100755 diff --git a/expr/reject.go b/expr/reject.go old mode 100644 new mode 100755 diff --git a/expr/rt.go b/expr/rt.go old mode 100644 new mode 100755 diff --git a/expr/tproxy.go b/expr/tproxy.go old mode 100644 new mode 100755 diff --git a/expr/verdict.go b/expr/verdict.go old mode 100644 new mode 100755 diff --git a/go.mod b/go.mod old mode 100644 new mode 100755 diff --git a/go.sum b/go.sum old mode 100644 new mode 100755 diff --git a/nftables_test.go b/nftables_test.go old mode 100644 new mode 100755 diff --git a/obj.go b/obj.go old mode 100644 new mode 100755 diff --git a/rule.go b/rule.go old mode 100644 new mode 100755 index ec4ce1f..d55e2d0 --- a/rule.go +++ b/rule.go @@ -84,7 +84,10 @@ func (cc *Conn) GetRule(t *Table, c *Chain) ([]*Rule, error) { if err != nil { return nil, err } - rules = append(rules, r) + + if r.Table.Name == t.Name && r.Table.Family == t.Family && r.Chain.Name == c.Name { + rules = append(rules, r) + } } return rules, nil @@ -293,6 +296,7 @@ func ruleFromMsg(msg netlink.Message) (*Rule, error) { switch ad.Type() { case unix.NFTA_RULE_TABLE: r.Table = &Table{Name: ad.String()} + r.Table.Family = TableFamily(msg.Data[0]) case unix.NFTA_RULE_CHAIN: r.Chain = &Chain{Name: ad.String()} case unix.NFTA_RULE_EXPRESSIONS: diff --git a/set.go b/set.go old mode 100644 new mode 100755 diff --git a/set_test.go b/set_test.go old mode 100644 new mode 100755 diff --git a/table.go b/table.go old mode 100644 new mode 100755 index da0126a..9f8c99c --- a/table.go +++ b/table.go @@ -45,6 +45,23 @@ type Table struct { Family TableFamily } +// GetTable gets a table by name and family +func (cc *Conn) GetTable(name string, family TableFamily) (*Table, error) { + cc.Lock() + defer cc.Unlock() + + tables, err := cc.ListTables() + if err != nil { + return nil, err + } + for _, table := range tables { + if table.Name == name && table.Family == family { + return table, nil + } + } + return nil, nil +} + // DelTable deletes a specific table, along with all chains/rules it contains. func (cc *Conn) DelTable(t *Table) { cc.Lock() diff --git a/tests/get_data_test.go b/tests/get_data_test.go new file mode 100644 index 0000000..919088e --- /dev/null +++ b/tests/get_data_test.go @@ -0,0 +1,52 @@ +package tests + +import ( + "fmt" + "github.com/google/nftables" + "testing" +) + +// Get table by net family and its name +func TestGetTable(t *testing.T) { + conn := nftables.Conn{} // start up a conn + + table, _ := conn.GetTable("nat", nftables.TableFamilyIPv4) + fmt.Println(table.Name) +} + +// Get chain by chain's name +func TestGetChain(t *testing.T) { + conn := nftables.Conn{} // start up a conn + chain, _ := conn.GetChain("POSTROUTING") // get chain + fmt.Println(chain.Name) +} + +// Get set and set's elements by table and set's name +func TestGetSet(t *testing.T) { + conn := nftables.Conn{} // start up a conn + + table, _ := conn.GetTable("nat", nftables.TableFamilyIPv4) // get table + + set, _ := conn.GetSetByName(table, "dest_addrs") // get set + fmt.Println(set.Name) + + eles, _ := conn.GetSetElements(set) + fmt.Println(eles) +} + +// Get rules by table and chain +func TestGetRules(t *testing.T) { + conn := nftables.Conn{} // start up a conn + + table, _ := conn.GetTable("nat", nftables.TableFamilyIPv4) // get table + chain, _ := conn.GetChain("POSTROUTING") // get chain + + rules, _ := conn.GetRule(table, chain) // get rules + for _, rule := range rules { + fmt.Println(rule.Table.Name, rule.Table.Family, rule.Chain.Name, rule.Handle) + // unpack exprs + for _, expr := range rule.Exprs { + fmt.Println(expr) + } + } +} \ No newline at end of file diff --git a/util.go b/util.go old mode 100644 new mode 100755