96 lines
1.9 KiB
Go
96 lines
1.9 KiB
Go
package nftables
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/google/nftables"
|
|
)
|
|
|
|
type ForeignRule struct {
|
|
Table string
|
|
Chain string
|
|
Handle uint64
|
|
Family nftables.TableFamily
|
|
|
|
table *nftables.Table
|
|
chain *nftables.Chain
|
|
}
|
|
|
|
func (f ForeignRule) String() string {
|
|
return fmt.Sprintf("table=%s chain=%s handle=%d", f.Table, f.Chain, f.Handle)
|
|
}
|
|
|
|
func (e *Engine) FindForeignRules() ([]ForeignRule, error) {
|
|
tables, err := e.conn.ListTables()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("listing tables: %w", err)
|
|
}
|
|
|
|
var ourTable *nftables.Table
|
|
for _, t := range tables {
|
|
if t.Name == e.cfg.Settings.TableName && t.Family == e.family() {
|
|
ourTable = t
|
|
break
|
|
}
|
|
}
|
|
if ourTable == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
compiler := NewCompiler(e.cfg)
|
|
desired, err := compiler.Compile()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("compiling config: %w", err)
|
|
}
|
|
|
|
desiredTags := make(map[string]bool)
|
|
for _, rules := range desired.Rules {
|
|
for _, r := range rules {
|
|
desiredTags[r.Tag] = true
|
|
}
|
|
}
|
|
|
|
var foreign []ForeignRule
|
|
|
|
chains, err := e.conn.ListChainsOfTableFamily(e.family())
|
|
if err != nil {
|
|
return nil, fmt.Errorf("listing chains: %w", err)
|
|
}
|
|
|
|
for _, chain := range chains {
|
|
if chain.Table.Name != e.cfg.Settings.TableName {
|
|
continue
|
|
}
|
|
rules, err := e.conn.GetRules(ourTable, chain)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
for _, rule := range rules {
|
|
tag := string(rule.UserData)
|
|
if tag == "" || !desiredTags[tag] {
|
|
foreign = append(foreign, ForeignRule{
|
|
Table: ourTable.Name,
|
|
Chain: chain.Name,
|
|
Handle: rule.Handle,
|
|
Family: ourTable.Family,
|
|
table: ourTable,
|
|
chain: chain,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
return foreign, nil
|
|
}
|
|
|
|
func (e *Engine) PurgeForeignRules(foreign []ForeignRule) error {
|
|
for _, f := range foreign {
|
|
e.conn.DelRule(&nftables.Rule{
|
|
Table: f.table,
|
|
Chain: f.chain,
|
|
Handle: f.Handle,
|
|
})
|
|
}
|
|
return e.conn.Flush()
|
|
}
|