[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

This commit is contained in:
RandolphCYG 2021-11-17 19:50:40 +08:00
parent 16a134723a
commit 031c75209e
47 changed files with 148 additions and 3 deletions

0
.github/workflows/push.yml vendored Normal file → Executable file
View File

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.idea/

0
CONTRIBUTING.md Normal file → Executable file
View File

0
LICENSE Normal file → Executable file
View File

61
README.md Normal file → Executable file
View File

@ -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**

0
binaryutil/binaryutil.go Normal file → Executable file
View File

14
chain.go Normal file → Executable file
View File

@ -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 {

0
conn.go Normal file → Executable file
View File

0
counter.go Normal file → Executable file
View File

0
doc.go Normal file → Executable file
View File

0
expr/bitwise.go Normal file → Executable file
View File

0
expr/bitwise_test.go Normal file → Executable file
View File

0
expr/byteorder.go Normal file → Executable file
View File

0
expr/counter.go Normal file → Executable file
View File

0
expr/ct.go Normal file → Executable file
View File

0
expr/dup.go Normal file → Executable file
View File

0
expr/dynset.go Normal file → Executable file
View File

0
expr/expr.go Normal file → Executable file
View File

0
expr/exthdr.go Normal file → Executable file
View File

0
expr/fib.go Normal file → Executable file
View File

0
expr/hash.go Normal file → Executable file
View File

0
expr/immediate.go Normal file → Executable file
View File

0
expr/limit.go Normal file → Executable file
View File

0
expr/log.go Normal file → Executable file
View File

0
expr/lookup.go Normal file → Executable file
View File

0
expr/nat.go Normal file → Executable file
View File

0
expr/notrack.go Normal file → Executable file
View File

0
expr/numgen.go Normal file → Executable file
View File

0
expr/objref.go Normal file → Executable file
View File

0
expr/payload.go Normal file → Executable file
View File

0
expr/queue.go Normal file → Executable file
View File

0
expr/range.go Normal file → Executable file
View File

0
expr/redirect.go Normal file → Executable file
View File

0
expr/reject.go Normal file → Executable file
View File

0
expr/rt.go Normal file → Executable file
View File

0
expr/tproxy.go Normal file → Executable file
View File

0
expr/verdict.go Normal file → Executable file
View File

0
go.mod Normal file → Executable file
View File

0
go.sum Normal file → Executable file
View File

0
nftables_test.go Normal file → Executable file
View File

0
obj.go Normal file → Executable file
View File

6
rule.go Normal file → Executable file
View File

@ -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:

0
set.go Normal file → Executable file
View File

0
set_test.go Normal file → Executable file
View File

17
table.go Normal file → Executable file
View File

@ -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()

52
tests/get_data_test.go Normal file
View File

@ -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)
}
}
}

0
util.go Normal file → Executable file
View File