You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: neigh_linux.go
    path of file: ./repos/buildkit/vendor/github.com/vishvananda/netlink
    
    the code of the file until where you have to start completion: package netlink

import (
	"fmt"
	"net"
	"syscall"
	"unsafe"

	"github.com/vishvananda/netlink/nl"
	"github.com/vishvananda/netns"
	"golang.org/x/sys/unix"
)

const (
	NDA_UNSPEC = iota
	NDA_DST
	NDA_LLADDR
	NDA_CACHEINFO
	NDA_PROBES
	NDA_VLAN
	NDA_PORT
	NDA_VNI
	NDA_IFINDEX
	NDA_MASTER
	NDA_LINK_NETNSID
	NDA_SRC_VNI
	NDA_PROTOCOL
	NDA_NH_ID
	NDA_FDB_EXT_ATTRS
	NDA_FLAGS_EXT
	NDA_MAX = NDA_FLAGS_EXT
)

// Neighbor Cache Entry States.
const (
	NUD_NONE       = 0x00
	NUD_INCOMPLETE = 0x01
	NUD_REACHABLE  = 0x02
	NUD_
    
func neighSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- NeighUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error {
	s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_NEIGH)
	makeRequest := func(family int) error {
		req := pkgHandle.newNetlinkRequest(unix.RTM_GETNEIGH,
			unix.NLM_F_DUMP)
		infmsg := nl.NewIfInfomsg(family)
		req.AddData(infmsg)
		if err := s.Send(req); err != nil {
			return err
		}
		return nil
	}
	if err != nil {
		return err
	}
	if done != nil {
		go func() {
			<-done
			s.Close()
		}()
	}
	if listExisting {
		if err := makeRequest(unix.AF_UNSPEC); err != nil {
			return err
		}
		// We have to wait for NLMSG_DONE before making AF_BRIDGE request
	}
	go func() {
		defer close(ch)
		for {
			msgs, from, err := s.Receive()
			if err != nil {
				if cberr != nil {
					cberr(err)
				}
				return
			}
			if from.Pid != nl.PidKernel {
				if cberr != nil {
					cberr(fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel))
				}
				continue
			}
			for _, m := range msgs {
				if m.Header.Type == unix.NLMSG_DONE {
					if listExisting {
						// This will be called after handling AF_UNSPEC
						// list request, we have to wait for NLMSG_DONE
						// before making another request
						if err := makeRequest(unix.AF_BRIDGE); err != nil {
							if cberr != nil {
								cberr(err)
							}
							return
						}
						listExisting = false
					}
					continue
				}
				if m.Header.Type == unix.NLMSG_ERROR {
					error := int32(native.Uint32(m.Data[0:4]))
					if error == 0 {
						continue
					}
					if cberr != nil {
						cberr(syscall.Errno(-error))
					}
					return
				}
				neigh, err := NeighDeserialize(m.Data)
				if err != nil {
					if cberr != nil {
						cberr(err)
					}
					return
				}
				ch <- NeighUpdate{Type: m.Header.Type, Neigh: *neigh}
			}
		}
	}()

	return nil
}