Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add: netlink socket options #277

Merged
merged 2 commits into from
Sep 23, 2024
Merged

Add: netlink socket options #277

merged 2 commits into from
Sep 23, 2024

Conversation

Ignatella
Copy link
Contributor

@Ignatella Ignatella commented Sep 13, 2024

Hi!

While using nftables we understood that it would be great to be able to set some options on the socket, i.e. setting r/w buffer size or pid retrieval to track what process issues rule changes.

This PR attemps to add such api to the New method through options (callbacks) executed every time dialNetlink called.

conn.go Outdated Show resolved Hide resolved
conn.go Outdated Show resolved Hide resolved
@stapelberg
Copy link
Collaborator

While using nftables we understood that it would be great to be able to set some options on the socket, i.e. setting r/w buffer size or pid retrieval to track what process issues rule changes.

Out of curiosity: Under which conditions do you need to adjust the r/w buffer size?

Is the code which sets the options open source? If so, can you share a link please?

@Ignatella
Copy link
Contributor Author

Ignatella commented Sep 23, 2024

@stapelberg

Out of curiosity: Under which conditions do you need to adjust the r/w buffer size?

One of the flows and assumptions we must consider is the ability to set up to 5,000 rules in a single transaction. However, using the default buffer sizes causes the process to get stuck indefinitely.

conn, err: = nftables.New(nftables.WithSockOptions(func(conn * netlink.Conn) error {
    // 20 mb for read and write buffer
    if err: = conn.SetReadBuffer(20971520);
    err != nil {
        return err
    }

    if err: = conn.SetWriteBuffer(20971520);
    err != nil {
        return err
    }

    pid, err: = getPortID(conn)

    if err != nil {
        return err
    }

    nftportid.SetNftablesPortID(pid)

    return nil
}))

func getPortID(conn * netlink.Conn)(uint32, error) {
    var (
        sa unix.Sockaddr err error
    )
    rawConn, err: = conn.SyscallConn()
    if err != nil {
        return 0, err
    }
    doErr: = rawConn.Control(func(fd uintptr) {
        for {
            sa, err = unix.Getsockname(int(fd))
            if ready(err) {
                return
            }
        }
    })
    if doErr != nil {
        return 0, doErr
    }
    if err != nil {
        return 0, err
    }
    saCast, ok: = sa.( * unix.SockaddrNetlink)
    if !ok {
        return 0, errors.New("SockaddrNetlink missing? should not happen")
    }
    return saCast.Pid, nil
}

The code is not open source, but we can share how we use the proposed functionality. 😊 Also, please note the 'port ID' part, which we use to track who issues the changes.

@stapelberg stapelberg merged commit ed578af into google:main Sep 23, 2024
2 checks passed
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