Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions plugin/driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"os/exec"
"runtime"
"strings"
"time"

Log "github.com/Sirupsen/logrus"
"github.com/docker/libnetwork/drivers/remote/api"
Expand Down Expand Up @@ -352,20 +353,22 @@ func (driver *driver) joinEndpoint(w http.ResponseWriter, r *http.Request) {
}

objectResponse(w, res)
Log.Infof("Join endpoint %s:%s to %s", j.NetworkID, j.EndpointID, j.SandboxKey)
Log.Infof("Join endpoint %s: %s to %s", j.NetworkID, j.EndpointID, j.SandboxKey)

if auto_arp {
go func(net_ns_path string, pg_ifc_prefix string) {

// Disallow this goroutine to work on any other thread than this one
// since namespace ops (unshare, setns) are done for a single thread, we
// must ensure that the goroutine does not jump from OS thread to thread
runtime.LockOSThread()
defer runtime.UnlockOSThread()

err := RunContainerArping(net_ns_path, pg_ifc_prefix)
if err != nil {
Log.Printf("Error while running arping : %v", err)
for i := 0; i <= 4; i++ {
runtime.LockOSThread()
err := RunContainerArping(net_ns_path, pg_ifc_prefix)
if err != nil {
Log.Printf("Arping failed : %v", err)
}
runtime.UnlockOSThread()
time.Sleep(1 * time.Second)
}

}(j.SandboxKey, ifname.DstPrefix)
Expand Down
39 changes: 8 additions & 31 deletions plugin/driver/network_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"fmt"
"net"
"strings"
"time"

"github.com/google/gopacket"
"github.com/google/gopacket/layers"
Expand All @@ -32,27 +31,12 @@ import (
// that match with the prefix given to libnetwork
func RunContainerArping(net_ns_path string, pg_ifc_prefix string) error {

Log.Printf("Attempting to acces the container %s NetNS", net_ns_path)
var netns ns.NetNS
var err error
success := false

for attempts := 0; attempts <= 5; attempts++ {

netns, err = ns.GetNS(net_ns_path)

if err != nil {
Log.Printf("Attempt %d: failed to open netns %s: %v", attempts, net_ns_path, err)
time.Sleep(1 * time.Second)
} else {
success = true
break
}
attempts += 1
}

if !success {
return fmt.Errorf("Attempts exhaused, could not access %s, exiting", net_ns_path)
netns, err = ns.GetNS(net_ns_path)
if err != nil {
return fmt.Errorf("Failed to open netns %s: %v", net_ns_path, err)
}
defer netns.Close()

Expand All @@ -70,8 +54,6 @@ func RunContainerArping(net_ns_path string, pg_ifc_prefix string) error {
if strings.HasPrefix(ifc.Name, pg_ifc_prefix) {
// Valid PG-created ifc

// TODO we might want to add a retry here to make sure,
// in case the IFC is up but still has no IP, we retry
address_slice, err := ifc.Addrs()
if err != nil {
Log.Errorf("Failed to get Address slice for ifc %s: %v", ifc.Name, err)
Expand All @@ -83,7 +65,6 @@ func RunContainerArping(net_ns_path string, pg_ifc_prefix string) error {
continue
}

Log.Printf("Attempting raw socket open on %s", ifc.Name)
handle, err := pcap.OpenLive(ifc.Name, 65536, true, pcap.BlockForever)
if err != nil {
return fmt.Errorf("Failed to open raw socket %s : %v", ifc.Name, err)
Expand All @@ -105,18 +86,14 @@ func RunContainerArping(net_ns_path string, pg_ifc_prefix string) error {
// Get ARP packet
arp_pkt := getGratuitousArp(ifc.HardwareAddr, ip)

for i := 0; i <= 3; i++ {
Log.Printf("Sending %d GARP on %s : %s - %s",
i, ifc.Name, ifc.HardwareAddr.String(), ip.String())
Log.Printf("Sending %s GARP on %s : %s",
ifc.Name, ifc.HardwareAddr.String(), ip.String())

if err := handle.WritePacketData(arp_pkt); err != nil {
handle.Close()
return fmt.Errorf("Failed to write ARP packet data on %s : %v", ifc.Name, err)
}
time.Sleep(750 * time.Millisecond)
if err := handle.WritePacketData(arp_pkt); err != nil {
Log.Printf("Failed to write ARP packet data on %s : %v", ifc.Name, err)
continue
}
}

// Close the socket
handle.Close()
}
Expand Down