// 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 { s, err := nl.Subscribe(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, Link: link} } } }() return nil }
// RouteSubscribe takes a chan down which notifications will be sent // when routes are added or deleted. Close the 'done' chan to stop subscription. func RouteSubscribe(ch chan<- RouteUpdate, done <-chan struct{}) error { s, err := nl.Subscribe(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 (dev *vxlanDevice) MonitorMisses(misses chan *netlink.Neigh) { nlsock, err := nl.Subscribe(syscall.NETLINK_ROUTE, syscall.RTNLGRP_NEIGH) if err != nil { log.Error("Failed to subscribe to netlink RTNLGRP_NEIGH messages") return } for { msgs, err := nlsock.Receive() if err != nil { log.Errorf("Failed to receive from netlink: %v ", err) time.Sleep(1 * time.Second) continue } for _, msg := range msgs { dev.processNeighMsg(msg, misses) } } }