diff --git a/prog/weaver/main.go b/prog/weaver/main.go index 50bf68e2..53aa8d26 100644 --- a/prog/weaver/main.go +++ b/prog/weaver/main.go @@ -65,7 +65,6 @@ func main() { peers []string noDNS bool dnsConfig dnsConfig - iface *net.Interface datapathName string trustedSubnetStr string @@ -131,25 +130,23 @@ func main() { } config.ProtocolMinVersion = byte(protocolMinVersion) - overlays := weave.NewOverlaySwitch() - switch { - case datapathName != "" && ifaceName != "": - Log.Fatal("At most one of --datapath and --iface must be specified.") - case datapathName != "": - fastdp, err := weave.NewFastDatapath(datapathName, config.Port) - checkFatal(err) - networkConfig.Bridge = fastdp.Bridge() - overlays.Add("fastdp", fastdp.Overlay()) - case ifaceName != "": - var err error - iface, err = weavenet.EnsureInterface(ifaceName) - checkFatal(err) - networkConfig.Bridge, err = weave.NewPcap(iface, bufSzMB*1024*1024) // bufsz flag is in MB + overlay, bridge := createOverlay(datapathName, ifaceName, config.Port, bufSzMB) + networkConfig.Bridge = bridge + + if routerName == "" { + iface := bridge.Interface() + if iface == nil { + Log.Fatal("Either an interface must be specified with --datapath or --iface, or a name with --name") + } + routerName = iface.HardwareAddr.String() + } + name, err := mesh.PeerNameFromUserInput(routerName) + checkFatal(err) + + if nickName == "" { + nickName, err = os.Hostname() checkFatal(err) } - sleeve := weave.NewSleeveOverlay(config.Port) - overlays.Add("sleeve", sleeve) - overlays.SetCompatOverlay(sleeve) if password == "" { password = os.Getenv("WEAVE_PASSWORD") @@ -161,21 +158,6 @@ func main() { Log.Println("Communication between peers via untrusted networks is encrypted.") } - if routerName == "" { - if iface == nil { - Log.Fatal("Either an interface must be specified with --iface or a name with -name") - } - routerName = iface.HardwareAddr.String() - } - - name, err := mesh.PeerNameFromUserInput(routerName) - checkFatal(err) - - if nickName == "" { - nickName, err = os.Hostname() - checkFatal(err) - } - if prof != "" { p := *profile.CPUProfile p.ProfilePath = prof @@ -195,7 +177,7 @@ func main() { Log.Fatal("Unable to parse trusted subnets: ", err) } - router := weave.NewNetworkRouter(config, networkConfig, name, nickName, overlays) + router := weave.NewNetworkRouter(config, networkConfig, name, nickName, overlay) Log.Println("Our name is", router.Ourself) var dockerCli *docker.Client @@ -309,6 +291,31 @@ func (nopPacketLogging) LogPacket(string, weave.PacketKey) { func (nopPacketLogging) LogForwardPacket(string, weave.ForwardPacketKey) { } +func createOverlay(datapathName string, ifaceName string, port int, bufSzMB int) (weave.NetworkOverlay, weave.Bridge) { + overlay := weave.NewOverlaySwitch() + var bridge weave.Bridge + switch { + case datapathName != "" && ifaceName != "": + Log.Fatal("At most one of --datapath and --iface must be specified.") + case datapathName != "": + fastdp, err := weave.NewFastDatapath(datapathName, port) + checkFatal(err) + bridge = fastdp.Bridge() + overlay.Add("fastdp", fastdp.Overlay()) + case ifaceName != "": + iface, err := weavenet.EnsureInterface(ifaceName) + checkFatal(err) + bridge, err = weave.NewPcap(iface, bufSzMB*1024*1024) // bufsz flag is in MB + checkFatal(err) + default: + bridge = weave.NullBridge{} + } + sleeve := weave.NewSleeveOverlay(port) + overlay.Add("sleeve", sleeve) + overlay.SetCompatOverlay(sleeve) + return overlay, bridge +} + func parseAndCheckCIDR(cidrStr string) address.CIDR { _, cidr, err := address.ParseCIDR(cidrStr) checkFatal(err) diff --git a/router/bridge.go b/router/bridge.go index 00481a0a..434669bd 100644 --- a/router/bridge.go +++ b/router/bridge.go @@ -1,5 +1,9 @@ package router +import ( + "net" +) + // Interface to packet handling on the local virtual bridge type Bridge interface { // Inject a packet to be delivered locally @@ -9,6 +13,7 @@ type Bridge interface { // should not be included. StartConsumingPackets(BridgeConsumer) error + Interface() *net.Interface String() string Stats() map[string]int } @@ -26,6 +31,10 @@ func (NullBridge) StartConsumingPackets(BridgeConsumer) error { return nil } +func (NullBridge) Interface() *net.Interface { + return nil +} + func (NullBridge) String() string { return "" } diff --git a/router/fastdp.go b/router/fastdp.go index 6a867f9d..ad294bfd 100644 --- a/router/fastdp.go +++ b/router/fastdp.go @@ -32,7 +32,7 @@ type FastDatapath struct { lock sync.Mutex // guards state and synchronises use of dpif dpif *odp.Dpif dp odp.DatapathHandle - mtu int // [1] + iface *net.Interface deleteFlowsCount uint64 missCount uint64 missHandlers map[odp.VportID]missHandler @@ -59,10 +59,6 @@ type FastDatapath struct { // forwarders by remote peer forwarders map[mesh.PeerName]*fastDatapathForwarder - - // [1] The mtu from the datapath netdev (which should match the - // mtus on all the veths hooked up to the datapath). We validate - // that we are able to support that mtu. } func NewFastDatapath(dpName string, port int) (*FastDatapath, error) { @@ -92,7 +88,7 @@ func NewFastDatapath(dpName string, port int) (*FastDatapath, error) { dpname: dpName, dpif: dpif, dp: dp, - mtu: iface.MTU, + iface: iface, missHandlers: make(map[odp.VportID]missHandler), sendToPort: nil, sendToMAC: make(map[MAC]bridgeSender), @@ -208,6 +204,10 @@ func (fastdp *FastDatapath) Bridge() Bridge { return fastDatapathBridge{fastdp} } +func (fastdp fastDatapathBridge) Interface() *net.Interface { + return fastdp.iface +} + func (fastdp fastDatapathBridge) String() string { return fmt.Sprint(fastdp.dpname, " (via ODP)") } @@ -665,7 +665,7 @@ func (fwd *fastDatapathForwarder) sendHeartbeat() { // the heartbeat payload consists of the 64-bit connection uid // followed by the 16-bit packet size. - buf := make([]byte, EthernetOverhead+fwd.fastdp.mtu) + buf := make([]byte, EthernetOverhead+fwd.fastdp.iface.MTU) binary.BigEndian.PutUint64(buf[EthernetOverhead:], fwd.connUID) binary.BigEndian.PutUint16(buf[EthernetOverhead+8:], uint16(len(buf))) diff --git a/router/pcap.go b/router/pcap.go index 848870be..781bb816 100644 --- a/router/pcap.go +++ b/router/pcap.go @@ -104,6 +104,10 @@ func newPcapHandle(ifName string, promisc bool, snaplen int, bufSz int) (handle return } +func (p *Pcap) Interface() *net.Interface { + return p.iface +} + func (p *Pcap) String() string { return fmt.Sprint(p.iface.Name, " (via pcap)") }