nftables icon indicating copy to clipboard operation
nftables copied to clipboard

AddSet silently fails (!) when adding IP addresses with too many bytes (without To4() call)

Open bensarifathi opened this issue 4 years ago • 5 comments

Hi am facing trouble when using this package i can't load my rule this is my code :

package main

import (
	"fmt"
	"log"
	"net"

	"github.com/google/nftables"
	"github.com/google/nftables/expr"
)

func main() {
	c := &nftables.Conn{}

	// Basic boilerplate; create a table & chain.
	table := &nftables.Table{
		Family: nftables.TableFamilyIPv4,
		Name:   "ip_filter",
	}
	table = c.AddTable(table)

	myChain := c.AddChain(&nftables.Chain{
		Name:     "filter_chain",
		Table:    table,
		Type:     nftables.ChainTypeFilter,
		Hooknum:  nftables.ChainHookInput,
		Priority: nftables.ChainPriorityFilter,
	})

	set := &nftables.Set{
		Name:    "whitelist",
		Table:   table,
		KeyType: nftables.TypeIPAddr, // our keys are IPv4 addresses
	}

	// Create the set with a bunch of initial values.
	if err := c.AddSet(set, []nftables.SetElement{
		{Key: net.ParseIP("8.8.8.8")},
	}); err != nil {
		log.Fatal(err.Error())
	}

	c.AddRule(&nftables.Rule{
		Table: table,
		Chain: myChain,
		Exprs: []expr.Any{
			// [ payload load 4b @ network header + 16 => reg 1 ]
			&expr.Payload{
				DestRegister: 1,
				Base:         expr.PayloadBaseNetworkHeader,
				Offset:       16,
				Len:          4,
			},
			// [ lookup reg 1 set whitelist ]
			&expr.Lookup{
				SourceRegister: 1,
				SetName:        set.Name,
				SetID:          set.ID,
			},
			//[ immediate reg 0 drop ]
			&expr.Verdict{
				Kind: expr.VerdictDrop,
			},
		},
	})
	if err := c.Flush(); err != nil {
		log.Fatal(err.Error())
	}
	rules, _ := c.GetRule(table, myChain)
	fmt.Println(rules)
}

after executing my code and run the following command : sudo nft list ruleset i expect to found my configured config but i found nothing. is this a compatibility problem ?

bensarifathi avatar Sep 07 '21 22:09 bensarifathi

I haven’t had a chance to look at your code yet, but I’m using this package on Linux 5.14.1 (latest kernel release) without any issues.

stapelberg avatar Sep 08 '21 06:09 stapelberg

my previous kernel version was 5.4.0-77-generic so i've decided to update my kernel to 5.14.2-051402-generic but the problem is still the same.

bensarifathi avatar Sep 08 '21 10:09 bensarifathi

This part of your code:

	// Create the set with a bunch of initial values.
	if err := c.AddSet(set, []nftables.SetElement{
		{Key: net.ParseIP("8.8.8.8")},
	}); err != nil {
		log.Fatal(err.Error())
	}

…is missing a To4() call:

	// Create the set with a bunch of initial values.
	if err := c.AddSet(set, []nftables.SetElement{
		{Key: net.ParseIP("8.8.8.8").To4()},
	}); err != nil {
		log.Fatal(err.Error())
	}

When I change that, it works.

I don’t know why no error message is generated with the wrong code, though :-/

stapelberg avatar Sep 09 '21 07:09 stapelberg

@stapelberg indeed now the program work just fine thank you so much.

bensarifathi avatar Sep 09 '21 08:09 bensarifathi

I don’t know why no error message is generated with the wrong code, though :-/

Probably because it doesn't check for the length of the []byte but just takes the first 4 (and the 8.8.8.8 are in the last 4).

pepa65 avatar Dec 30 '23 15:12 pepa65