func newConn(s *socket.Conn, config *Config) (*conn, uint32, error) {
	if config == nil {
		config = &Config{}
	}
	addr := &unix.SockaddrNetlink{
		Family: unix.AF_NETLINK,
		Groups: config.Groups,
	}
	if err := s.Bind(addr); err != nil {
		_ = s.Close()
		return nil, 0, err
	}
	sa, err := s.Getsockname()
	if err != nil {
		_ = s.Close()
		return nil, 0, err
	}
	return &conn{
		s: s,
	}, sa.(*unix.SockaddrNetlink).Pid, nil
}
newConn binds a connection to netlink using the input *socket.Conn.
package netlink
import (
	"os"
	"runtime"
	"syscall"
	"time"
	"unsafe"
	"github.com/mdlayher/socket"
	"golang.org/x/net/bpf"
	"golang.org/x/sys/unix"
)
var _ Socket = &conn{}
type conn struct {
	s *socket.Conn
}
func dial(family int, config *Config) (*conn, uint32, error) {
	if config == nil {
		config = &Config{}
	}
	if config.NetNS != 0 {
		runtime.LockOSThread()
		defer runtime.UnlockOSThread()
		threadNS, err := threadNetNS()
		if err != nil {
			return nil, 0, err
		}
		defer threadNS.Close()
		if err := threadNS.Set(config.NetNS); err != nil {
			return nil, 0, err
		}
		defer threadNS.Restore()
	}
	s, err := socket.Socket(unix.AF_NETLINK, unix.SOCK_RAW, family, "netlink")
	if err != nil {
		return nil, 0, err
	}
	return newConn(s, config)
}