func getIPVSFamily() (int, error) { sock, err := nl.GetNetlinkSocketAt(netns.None(), netns.None(), syscall.NETLINK_GENERIC) if err != nil { return 0, err } req := newGenlRequest(genlCtrlID, genlCtrlCmdGetFamily) req.AddData(nl.NewRtAttr(genlCtrlAttrFamilyName, nl.ZeroTerminated("IPVS"))) msgs, err := execute(sock, req, 0) if err != nil { return 0, err } for _, m := range msgs { hdr := deserializeGenlMsg(m) attrs, err := nl.ParseRouteAttr(m[hdr.Len():]) if err != nil { return 0, err } for _, attr := range attrs { switch int(attr.Attr.Type) { case genlCtrlAttrFamilyID: return int(native.Uint16(attr.Value[0:2])), nil } } } return 0, fmt.Errorf("no family id in the netlink response") }
// NextEndpoint is an implementation of the loadbalancer interface for proxy. func (s *Segment) NextEndpoint(service string, srcAddr net.Addr) (netns.NsHandle, string, error) { err := s.Trigger() if err != nil { return netns.None(), "", err } host := net.JoinHostPort(s.Tail.Hostname, strconv.Itoa(s.Tail.Port)) return s.Tail.Ns, host, nil }
// NewProxier returns a new Proxier given a LoadBalancer and an // address on which to listen func NewProxier(loadBalancer LoadBalancer, address string) *Proxier { return &Proxier{ loadBalancer: loadBalancer, serviceMap: make(map[string]*serviceInfo), address: address, // NOTE(vish): this ns probably should be part of the Service struct ns: netns.None(), } }
// New provides a new ipvs handle in the namespace pointed to by the // passed path. It will return a valid handle or an error in case an // error occured while creating the handle. func New(path string) (*Handle, error) { setup() n := netns.None() if path != "" { var err error n, err = netns.GetFromPath(path) if err != nil { return nil, err } } defer n.Close() sock, err := nl.GetNetlinkSocketAt(n, netns.None(), syscall.NETLINK_GENERIC) if err != nil { return nil, err } return &Handle{sock: sock}, nil }
// NextEndpoint returns a service endpoint. // The service endpoint is chosen using the round-robin algorithm. func (lb *LoadBalancerRR) NextEndpoint(service string, srcAddr net.Addr) (netns.NsHandle, string, error) { ns := netns.None() lb.lock.RLock() endpoints, exists := lb.endpointsMap[service] index := lb.rrIndex[service] lb.lock.RUnlock() if !exists { return ns, "", ErrMissingServiceEntry } if len(endpoints) == 0 { return ns, "", ErrMissingEndpoints } endpoint := endpoints[index] lb.lock.Lock() lb.rrIndex[service] = (index + 1) % len(endpoints) lb.lock.Unlock() return ns, endpoint, nil }
t.Fatal(err) } return } defer func() { if err := n.Delete(); err != nil { t.Fatal(err) } }() } var ( once sync.Once start = make(chan struct{}) done = make(chan chan struct{}, numThreads-1) origns = netns.None() testns = netns.None() sboxes = make([]libnetwork.Sandbox, numThreads) ) const ( iterCnt = 25 numThreads = 3 first = 1 last = numThreads debug = false ) func createGlobalInstance(t *testing.T) { var err error defer close(start)
// LinkSubscribeAt works like LinkSubscribe plus it allows the caller // to choose the network namespace in which to subscribe (ns). func LinkSubscribeAt(ns netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}) error { return linkSubscribe(ns, netns.None(), ch, done) }
// LinkSubscribe takes a chan down which notifications will be sent // when links change. Close the 'done' chan to stop subscription. func LinkSubscribe(ch chan<- LinkUpdate, done <-chan struct{}) error { return linkSubscribe(netns.None(), netns.None(), ch, done) }
// NewHandle returns a netlink handle on the network namespace // specified by ns. If ns=netns.None(), current network namespace // will be assumed func NewHandleAt(ns netns.NsHandle, nlFamilies ...int) (*Handle, error) { return newHandle(ns, netns.None(), nlFamilies...) }
// RouteSubscribeAt works like RouteSubscribe plus it allows the caller // to choose the network namespace in which to subscribe (ns). func RouteSubscribeAt(ns netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}) error { return routeSubscribeAt(ns, netns.None(), ch, done) }
// AddrSubscribeAt works like AddrSubscribe plus it allows the caller // to choose the network namespace in which to subscribe (ns). func AddrSubscribeAt(ns netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}) error { return addrSubscribe(ns, netns.None(), ch, done) }
// AddrSubscribe takes a chan down which notifications will be sent // when addresses change. Close the 'done' chan to stop subscription. func AddrSubscribe(ch chan<- AddrUpdate, done <-chan struct{}) error { return addrSubscribe(netns.None(), netns.None(), ch, done) }
func NewSegment() *Segment { return &Segment{Head: ConnectionInfo{Ns: netns.None()}, Tail: ConnectionInfo{Ns: netns.None()}} }
// NewHandle returns a netlink handle on the network namespace // specified by ns. If ns=netns.None(), current network namespace // will be assumed func NewHandleAt(ns netns.NsHandle) (*Handle, error) { return newHandle(ns, netns.None()) }
// NewHandle returns a netlink handle on the current network namespace. func NewHandle() (*Handle, error) { return newHandle(netns.None(), netns.None()) }