diff --git a/net/if.go b/net/if.go index f107433e..d4972cad 100644 --- a/net/if.go +++ b/net/if.go @@ -19,9 +19,10 @@ func EnsureInterface(ifaceName string) (*net.Interface, error) { func ensureInterface(ifaceName string) (*net.Interface, error) { ch := make(chan netlink.LinkUpdate) - done := make(chan struct{}) - defer close(done) - if err := netlink.LinkSubscribe(ch, done); err != nil { + // NB: We do not supply (and eventually close) a 'done' channel + // here since that can cause incorrect file descriptor + // re-usage. See https://github.com/weaveworks/weave/issues/2120 + if err := netlink.LinkSubscribe(ch, nil); err != nil { return nil, err } // check for currently-existing interface after subscribing, to avoid race @@ -46,9 +47,7 @@ func EnsureInterfaceAndMcastRoute(ifaceName string) (*net.Interface, error) { return nil, err } ch := make(chan netlink.RouteUpdate) - done := make(chan struct{}) - defer close(done) - if err := netlink.RouteSubscribe(ch, done); err != nil { + if err := netlink.RouteSubscribe(ch, nil); err != nil { return nil, err } dest := net.IPv4(224, 0, 0, 0) diff --git a/prog/weaver/main.go b/prog/weaver/main.go index 77ead51e..cb297117 100644 --- a/prog/weaver/main.go +++ b/prog/weaver/main.go @@ -348,7 +348,9 @@ func createOverlay(datapathName string, ifaceName string, host string, port int, case datapathName != "" && ifaceName != "": Log.Fatal("At most one of --datapath and --iface must be specified.") case datapathName != "": - fastdp, err := weave.NewFastDatapath(datapathName, port) + iface, err := weavenet.EnsureInterface(datapathName) + checkFatal(err) + fastdp, err := weave.NewFastDatapath(iface, port) checkFatal(err) bridge = fastdp.Bridge() overlay.Add("fastdp", fastdp.Overlay()) diff --git a/router/fastdp.go b/router/fastdp.go index 3c1efa7d..1b50b03d 100644 --- a/router/fastdp.go +++ b/router/fastdp.go @@ -28,11 +28,10 @@ type bridgeSender func(key PacketKey, lock *fastDatapathLock) FlowOp type missHandler func(fks odp.FlowKeys, lock *fastDatapathLock) FlowOp type FastDatapath struct { - dpname string lock sync.Mutex // guards state and synchronises use of dpif + iface *net.Interface dpif *odp.Dpif dp odp.DatapathHandle - iface *net.Interface deleteFlowsCount uint64 missCount uint64 missHandlers map[odp.VportID]missHandler @@ -61,7 +60,7 @@ type FastDatapath struct { forwarders map[mesh.PeerName]*fastDatapathForwarder } -func NewFastDatapath(dpName string, port int) (*FastDatapath, error) { +func NewFastDatapath(iface *net.Interface, port int) (*FastDatapath, error) { dpif, err := odp.NewDpif() if err != nil { return nil, err @@ -74,21 +73,15 @@ func NewFastDatapath(dpName string, port int) (*FastDatapath, error) { } }() - dp, err := dpif.LookupDatapath(dpName) - if err != nil { - return nil, err - } - - iface, err := net.InterfaceByName(dpName) + dp, err := dpif.LookupDatapath(iface.Name) if err != nil { return nil, err } fastdp := &FastDatapath{ - dpname: dpName, + iface: iface, dpif: dpif, dp: dp, - iface: iface, missHandlers: make(map[odp.VportID]missHandler), sendToPort: nil, sendToMAC: make(map[MAC]bridgeSender), @@ -209,7 +202,7 @@ func (fastdp fastDatapathBridge) Interface() *net.Interface { } func (fastdp fastDatapathBridge) String() string { - return fmt.Sprint(fastdp.dpname, " (via ODP)") + return fmt.Sprint(fastdp.iface.Name, " (via ODP)") } func (fastdp fastDatapathBridge) Stats() map[string]int {