Skip to content
This repository has been archived by the owner on Jun 20, 2024. It is now read-only.

Fast datapath #1438

Merged
merged 15 commits into from
Oct 13, 2015
120 changes: 91 additions & 29 deletions prog/weaver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/davecheney/profile"
"github.com/docker/docker/pkg/mflag"
"github.com/gorilla/mux"
"github.com/weaveworks/go-odp/odp"

. "github.com/weaveworks/weave/common"
"github.com/weaveworks/weave/common/docker"
Expand All @@ -35,8 +36,13 @@ func main() {
runtime.GOMAXPROCS(procs)

var (
// flags that cause immediate exit
justVersion bool
createDatapath bool
deleteDatapath bool
addDatapathInterface string

config weave.Config
justVersion bool
protocolMinVersion int
ifaceName string
routerName string
Expand All @@ -60,9 +66,14 @@ func main() {
dnsClientTimeout time.Duration
dnsEffectiveListenAddress string
iface *net.Interface
datapathName string
)

mflag.BoolVar(&justVersion, []string{"#version", "-version"}, false, "print version and exit")
mflag.BoolVar(&createDatapath, []string{"-create-datapath"}, false, "create ODP datapath and exit")
mflag.BoolVar(&deleteDatapath, []string{"-delete-datapath"}, false, "delete ODP datapath and exit")
mflag.StringVar(&addDatapathInterface, []string{"-add-datapath-iface"}, "", "add a network interface to the ODP datapath and exit")

mflag.IntVar(&config.Port, []string{"#port", "-port"}, weave.Port, "router port")
mflag.IntVar(&protocolMinVersion, []string{"-min-protocol-version"}, weave.ProtocolMinVersion, "minimum weave protocol version")
mflag.StringVar(&ifaceName, []string{"#iface", "-iface"}, "", "name of interface to capture/inject from (disabled if blank)")
Expand All @@ -86,6 +97,7 @@ func main() {
mflag.IntVar(&dnsTTL, []string{"-dns-ttl"}, nameserver.DefaultTTL, "TTL for DNS request from our domain")
mflag.DurationVar(&dnsClientTimeout, []string{"-dns-fallback-timeout"}, nameserver.DefaultClientTimeout, "timeout for fallback DNS requests")
mflag.StringVar(&dnsEffectiveListenAddress, []string{"-dns-effective-listen-address"}, "", "address DNS will actually be listening, after Docker port mapping")
mflag.StringVar(&datapathName, []string{"-datapath"}, "", "ODP datapath name")

// crude way of detecting that we probably have been started in a
// container, with `weave launch` --> suppress misleading paths in
Expand All @@ -94,14 +106,37 @@ func main() {
os.Args[0] = "weave"
mflag.CommandLine.Init("weave", mflag.ExitOnError)
}

mflag.Parse()

peers = mflag.Args()

SetLogLevel(logLevel)
if justVersion {

switch {
case justVersion:
fmt.Printf("weave router %s\n", version)
os.Exit(0)

case createDatapath:
err := weave.CreateDatapath(datapathName)
if odp.IsKernelLacksODPError(err) {
// When the kernel lacks ODP support, exit
// with a special status to distinguish it for
// the weave script.
os.Exit(17)
}

checkFatal(err)
os.Exit(0)

case deleteDatapath:
checkFatal(weave.DeleteDatapath(datapathName))
os.Exit(0)

case addDatapathInterface != "":
checkFatal(weave.AddDatapathInterface(datapathName, addDatapathInterface))
os.Exit(0)
}

Log.Println("Command line options:", options())
Expand All @@ -112,21 +147,58 @@ func main() {
}
config.ProtocolMinVersion = byte(protocolMinVersion)

var err error
var fastDPOverlay weave.Overlay
if datapathName != "" {
// A datapath name implies that "Bridge" and "Overlay"
// packet handling use fast datapath, although other
// options can override that below. Even if both
// things are overridden, we might need bridging on
// the datapath.
fastdp, err := weave.NewFastDatapath(weave.FastDatapathConfig{
DatapathName: datapathName,
Port: config.Port,
})

checkFatal(err)
config.Bridge = fastdp.Bridge()
fastDPOverlay = fastdp.Overlay()
}

if ifaceName != "" {
// -iface can coexist with -datapath, because
// pcap-based packet capture is a bit more efficient
// than capture via ODP misses, even when using an
// ODP-based bridge. So when using weave encyption,
// it's preferable to use -iface.
iface, err := weavenet.EnsureInterface(ifaceName)
if err != nil {
Log.Fatal(err)
}
checkFatal(err)

// bufsz flag is in MB
config.Bridge, err = weave.NewPcap(iface, bufSzMB*1024*1024)
if err != nil {
Log.Fatal(err)
}
checkFatal(err)
}

if password == "" {
password = os.Getenv("WEAVE_PASSWORD")
}

if password == "" {
Log.Println("Communication between peers is unencrypted.")
} else {
config.Password = []byte(password)
Log.Println("Communication between peers is encrypted.")

// fastdp doesn't support encryption
fastDPOverlay = nil
}

overlays := weave.NewOverlaySwitch()
if fastDPOverlay != nil {
overlays.Add("fastdp", fastDPOverlay)
}
overlays.Add("sleeve", weave.NewSleeveOverlay(config.Port))
config.Overlay = overlays

if routerName == "" {
if iface == nil {
Log.Fatal("Either an interface must be specified with --iface or a name with -name")
Expand All @@ -135,25 +207,11 @@ func main() {
}

name, err := weave.PeerNameFromUserInput(routerName)
if err != nil {
Log.Fatal(err)
}
checkFatal(err)

if nickName == "" {
nickName, err = os.Hostname()
if err != nil {
Log.Fatal(err)
}
}

if password == "" {
password = os.Getenv("WEAVE_PASSWORD")
}
if password == "" {
Log.Println("Communication between peers is unencrypted.")
} else {
config.Password = []byte(password)
Log.Println("Communication between peers is encrypted.")
checkFatal(err)
}

if prof != "" {
Expand All @@ -164,7 +222,6 @@ func main() {
}

config.PeerDiscovery = !noDiscovery
config.Overlay = weave.NewSleeveOverlay(config.Port)

if pktdebug {
config.PacketLogging = packetLogging{}
Expand Down Expand Up @@ -285,9 +342,8 @@ func (nopPacketLogging) LogForwardPacket(string, weave.ForwardPacketKey) {

func parseAndCheckCIDR(cidrStr string) address.CIDR {
_, cidr, err := address.ParseCIDR(cidrStr)
if err != nil {
Log.Fatal(err)
}
checkFatal(err)

if cidr.Size() < ipam.MinSubnetSize {
Log.Fatalf("Allocation range smaller than minimum size %d: %s", ipam.MinSubnetSize, cidrStr)
}
Expand Down Expand Up @@ -346,3 +402,9 @@ func listenAndServeHTTP(httpAddr string, muxRouter *mux.Router) {
Log.Fatal("Unable to create http server", err)
}
}

func checkFatal(e error) {
if e != nil {
Log.Fatal(e)
}
}
19 changes: 16 additions & 3 deletions proxy/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,28 @@ var (

func callWeave(args ...string) ([]byte, []byte, error) {
args = append([]string{"--local"}, args...)
Log.Debug("Calling weave", args)
cmd := exec.Command("./weave", args...)
cmd.Env = []string{
"PATH=/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"PROCFS=/hostproc",
}
if bridge := os.Getenv("DOCKER_BRIDGE"); bridge != "" {
cmd.Env = append(cmd.Env, fmt.Sprintf("DOCKER_BRIDGE=%s", bridge))

propagateEnv := func(key string) {
if val := os.Getenv(key); val != "" {
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", key, val))
}
}

propagateEnv("DOCKER_BRIDGE")

// Propogage WEAVE_DEBUG, to make debugging easier.
propagateEnv("WEAVE_DEBUG")

// This prevents the code coverage contortions in our
// integration test suite breaking things.
propagateEnv("COVERAGE")

Log.Debug("Calling weave args: ", args, "env: ", cmd.Env)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
Expand Down
12 changes: 7 additions & 5 deletions proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,13 +436,15 @@ func (proxy *Proxy) getDNSDomain() (domain string) {
}

weaveContainer, err := proxy.client.InspectContainer("weave")
if err != nil ||
weaveContainer.NetworkSettings == nil ||
weaveContainer.NetworkSettings.IPAddress == "" {
return
var weaveIP string
if err == nil && weaveContainer.NetworkSettings != nil {
weaveIP = weaveContainer.NetworkSettings.IPAddress
}
if weaveIP == "" {
weaveIP = "127.0.0.1"
}

url := fmt.Sprintf("http://%s:%d/domain", weaveContainer.NetworkSettings.IPAddress, router.HTTPPort)
url := fmt.Sprintf("http://%s:%d/domain", weaveIP, router.HTTPPort)
resp, err := http.Get(url)
if err != nil || resp.StatusCode != http.StatusOK {
return
Expand Down
Loading