Skip to content

Conversation

amitlevy21
Copy link

Hi,
Netlink package has evolved, but requires minimun version of go 1.18
Please consider this pr

Thank you

netlink package has evolved, but requires minimun version of go 1.18
@florianl
Copy link
Owner

Hi 👋
Thanks for the request. As development on mdlayer/netlink got stalled, I'm considering using a fork, like https://github.com/florianl/netlink/tree/flo-trunc, that includes improvements like mdlayher/netlink#215.

Is there a specific reason you are looking for the update of mdlayer/netlink?

@amitlevy21
Copy link
Author

amitlevy21 commented Jun 25, 2025

@florianl Thank you for the quick response!
I'm encountering this bug which I haven't being able to fix:
Error while processing nflog: netlink receive: use of closed file
I was wondering if bumping the version would help, since I took a look at go-nflog source code and I could not find any direct cause. I thought even if it doesn't relate, would be nice to update the version.

However, due to the reasons you mentioned, Its understandable and your fork idea sounds great.

This is my code just in case you might spot anything

package nflog

import (
	"context"
	"errors"
	"time"
	"log"

	florianl "github.com/florianl/go-nflog/v2"
)

const socketReadBufferSize = 4 * 1024 * 1024

// Config describes parameters for NFLOG
type Config struct {
	// CopySize says how many bytes of a packet to receive
	CopySize int
	// NFLOG group to listen
	Group int
	// Timeout in 1/100s of a second before packets will be flushed to userspace
	Timeout int
	// Queue size threshold, after reaching all queued packets will be flushed to userspace
	QueueThreshold int
	// Callback is a function that will be called for each packet
	Callback func(Attribute)
}

type Attribute struct {
	Prefix  string
	Payload []byte
	UID     uint32
	GID     uint32
}

type nflogListener struct {
	nf   *florianl.Nflog
	done <-chan struct{}
	cb   func(Attribute)
}

func New(c Config, done <-chan struct{}) (*nflogListener, error) {
	config := florianl.Config{
		Bufsize:     uint32(c.CopySize),
		Group:       uint16(c.Group),
		Copymode:    florianl.CopyPacket,
		ReadTimeout: 100 * time.Millisecond,
		Timeout:     uint32(c.Timeout),
		QThresh:     uint32(c.QueueThreshold),
	}
	nf, err := florianl.Open(&config)
	if err != nil {
		return nil, err
	}

	return &nflogListener{nf, done, c.Callback}, nil
}

func (n *nflogListener) Listen() error {
	ctx, cancel := context.WithCancel(context.Background())
	defer n.nf.Close()
	defer cancel()

	if err := n.nf.Con.SetReadBuffer(socketReadBufferSize); err != nil {
		return err
	}
	errFn := func(err error) int {
			log.Printf("Error while processing nflog: %s", err)
		return 0
	}
	hookFn := func(attributes florianl.Attribute) int {
		attrs := Attribute{}
		if attributes.Prefix != nil {
			attrs.Prefix = *attributes.Prefix
		}
		if attributes.UID != nil {
			attrs.UID = *attributes.UID
		}
		if attributes.GID != nil {
			attrs.GID = *attributes.GID
		}
		if attributes.Payload != nil {
			attrs.Payload = *attributes.Payload
			n.cb(attrs)
		}
		return 0
	}
	err := n.nf.RegisterWithErrorFunc(ctx, hookFn, errFn)
	if err != nil {
		log.Printf("Error while registering nflog: %v", err)
		return err
	}
	log.Printf("nflog listening")
	defer log.Printf("nflog listening stopped")

	// ideally, we should only wait for ctx
	// we have other parts in the code that wait for done channel to terminate
	// so we sync with others by waiting for both channels
	// maybe we will consider migrating to use only ctx in the future for all parts
	// would like to see how this behaves in production first.
	select {
	case <-n.done:
		return nil

	case <-ctx.Done():
		return nil
	}
}

@florianl
Copy link
Owner

Thanks for the feedback. I will likely close this PR and upgrade the dependency in the coming days.

From the provided code and information it is hard to tell the origin of the named error. Updating the netlink dependency will likely also not solve it, I think. To debug your issue, I would recommend to

  • look into nf.SetOption(netlink.ExtendedAcknowledge, true) and set it after opening the netlink socket
  • using strace to get more details on what is happening

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants