diff --git a/internal/rule/rule.go b/internal/rule/rule.go new file mode 100644 index 0000000..3a90968 --- /dev/null +++ b/internal/rule/rule.go @@ -0,0 +1,68 @@ +package rule + +import ( + "strconv" + + "git.kor-elf.net/kor-elf-shield/go-nftables-client/family" + "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/command" +) + +type API interface { + // Add adds a new rule. + // + // This command is equivalent to: + // nft add rule (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ expr }' + Add(family family.Type, tableName string, chainName string, expr ...string) error + + // Insert inserts a new rule. + // Inserted rules are placed at the beginning of the chain, by default. + // + // This command is equivalent to: + // nft insert rule (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ expr }' + Insert(family family.Type, tableName string, chainName string, expr ...string) error + + // Replace replaces a rule. + // + // This command is equivalent to: + // nft replace rule (ip|ip6|inet|arp|bridge) {table_name} {chain_name} {handle} '{ expr }' + Replace(family family.Type, tableName string, chainName string, handle uint64, expr ...string) error + + // Delete deletes a rule. + // + // This command is equivalent to: + // nft delete rule (ip|ip6|inet|arp|bridge) {table_name} {chain_name} {handle} + Delete(family family.Type, tableName string, chainName string, handle uint64) error +} + +type rule struct { + command command.NFT +} + +func New(command command.NFT) API { + return &rule{ + command: command, + } +} + +func (r *rule) Add(family family.Type, tableName string, chainName string, expr ...string) error { + args := []string{"add", "rule", family.String(), tableName, chainName} + args = append(args, expr...) + return r.command.Run(args...) +} + +func (r *rule) Insert(family family.Type, tableName string, chainName string, expr ...string) error { + args := []string{"insert", "rule", family.String(), tableName, chainName} + args = append(args, expr...) + return r.command.Run(args...) +} + +func (r *rule) Replace(family family.Type, tableName string, chainName string, handle uint64, expr ...string) error { + args := []string{"replace", "rule", family.String(), tableName, chainName, "handle", strconv.Itoa(int(handle))} + args = append(args, expr...) + return r.command.Run(args...) +} + +func (r *rule) Delete(family family.Type, tableName string, chainName string, handle uint64) error { + args := []string{"delete", "rule", family.String(), tableName, chainName, "handle", strconv.Itoa(int(handle))} + return r.command.Run(args...) +} diff --git a/nft.go b/nft.go index 83a953a..ec28c78 100644 --- a/nft.go +++ b/nft.go @@ -7,6 +7,7 @@ import ( "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/chain" "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/command" + "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/rule" "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/table" ) @@ -33,12 +34,16 @@ type NFT interface { // Chain returns an API for working with chains. Chain() chain.API + + // Rule returns an API for working with rules. + Rule() rule.API } type nft struct { command command.NFT table table.API chain chain.API + rule rule.API } // New Returns a client for working with nftables. @@ -66,6 +71,7 @@ func NewWithPath(path string) (NFT, error) { command: nftCommand, table: table.New(nftCommand), chain: chain.New(nftCommand), + rule: rule.New(nftCommand), }, nil } @@ -116,6 +122,10 @@ func (n *nft) Chain() chain.API { return n.chain } +func (n *nft) Rule() rule.API { + return n.rule +} + func (n *nft) Command() command.NFT { return n.command }