func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}) error { s, err := nl.SubscribeAt(newNs, curNs, syscall.NETLINK_ROUTE, syscall.RTNLGRP_IPV4_ROUTE, syscall.RTNLGRP_IPV6_ROUTE) if err != nil { return err } if done != nil { go func() { <-done s.Close() }() } go func() { defer close(ch) for { msgs, err := s.Receive() if err != nil { return } for _, m := range msgs { route, err := deserializeRoute(m.Data) if err != nil { return } ch <- RouteUpdate{Type: m.Header.Type, Route: route} } } }() return nil }
func linkSubscribe(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}) error { s, err := nl.SubscribeAt(newNs, curNs, syscall.NETLINK_ROUTE, syscall.RTNLGRP_LINK) if err != nil { return err } if done != nil { go func() { <-done s.Close() }() } go func() { defer close(ch) for { msgs, err := s.Receive() if err != nil { return } for _, m := range msgs { ifmsg := nl.DeserializeIfInfomsg(m.Data) link, err := LinkDeserialize(m.Data) if err != nil { return } ch <- LinkUpdate{IfInfomsg: *ifmsg, Header: m.Header, Link: link} } } }() return nil }
func addrSubscribe(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}) error { s, err := nl.SubscribeAt(newNs, curNs, syscall.NETLINK_ROUTE, syscall.RTNLGRP_IPV4_IFADDR, syscall.RTNLGRP_IPV6_IFADDR) if err != nil { return err } if done != nil { go func() { <-done s.Close() }() } go func() { defer close(ch) for { msgs, err := s.Receive() if err != nil { log.Printf("netlink.AddrSubscribe: Receive() error: %v", err) return } for _, m := range msgs { msgType := m.Header.Type if msgType != syscall.RTM_NEWADDR && msgType != syscall.RTM_DELADDR { log.Printf("netlink.AddrSubscribe: bad message type: %d", msgType) continue } addr, _, ifindex, err := parseAddr(m.Data) if err != nil { log.Printf("netlink.AddrSubscribe: could not parse address: %v", err) continue } ch <- AddrUpdate{LinkAddress: *addr.IPNet, LinkIndex: ifindex, NewAddr: msgType == syscall.RTM_NEWADDR} } } }() return nil }