Skip to content

Commit 78ddd44

Browse files
authored
Merge pull request #43 from Azure/development
Development
2 parents eb634ae + 83617be commit 78ddd44

File tree

9 files changed

+111
-72
lines changed

9 files changed

+111
-72
lines changed

Dockerfile

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
FROM golang:1.6
1+
FROM golang:latest
22

33
# Install dependencies.
44
RUN apt-get update && apt-get install -y ebtables
55

66
RUN go get -d -v golang.org/x/sys/unix
77

8-
COPY . /go/src/github.com/Azure/Aqua
9-
WORKDIR /go/src/github.com/Azure/Aqua
8+
COPY . /go/src/github.com/Azure/azure-container-networking
9+
WORKDIR /go/src/github.com/Azure/azure-container-networking
1010

11-
RUN go install
12-
13-
CMD ["/go/bin/Aqua"]
11+
RUN make azure-cnm-plugin
12+
RUN make azure-cni-plugin

common/utils.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"io/ioutil"
88
"net"
99
"os/exec"
10+
"time"
1011

1112
"github.com/Azure/azure-container-networking/log"
1213
)
@@ -35,6 +36,26 @@ func LogNetworkInterfaces() {
3536
}
3637
}
3738

39+
// GetLastRebootTime returns the last time the system rebooted.
40+
func GetLastRebootTime() (time.Time, error) {
41+
// Query last reboot time.
42+
out, err := exec.Command("uptime", "-s").Output()
43+
if err != nil {
44+
log.Printf("Failed to query uptime, err:%v", err)
45+
return time.Time{}, err
46+
}
47+
48+
// Parse the output.
49+
layout := "2006-01-02 15:04:05"
50+
rebootTime, err := time.Parse(layout, string(out[:len(out)-1]))
51+
if err != nil {
52+
log.Printf("Failed to parse uptime, err:%v", err)
53+
return time.Time{}, err
54+
}
55+
56+
return rebootTime, nil
57+
}
58+
3859
// ExecuteShellCommand executes a shell command.
3960
func ExecuteShellCommand(command string) error {
4061
log.Debugf("[shell] %s", command)

ebtables/ebtables.go

Lines changed: 24 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,18 @@ package ebtables
66
import (
77
"fmt"
88
"io/ioutil"
9+
"net"
910
"os/exec"
1011
"strings"
1112

1213
"github.com/Azure/azure-container-networking/log"
1314
)
1415

15-
// Init initializes the ebtables module.
16-
func init() {
17-
installEbtables()
18-
}
16+
const (
17+
// Ebtables actions.
18+
Append = "-A"
19+
Delete = "-D"
20+
)
1921

2022
// InstallEbtables installs the ebtables package.
2123
func installEbtables() {
@@ -31,64 +33,31 @@ func installEbtables() {
3133
}
3234
}
3335

34-
// SetupSnatForOutgoingPackets sets up snat
35-
func SetupSnatForOutgoingPackets(interfaceName string, snatAddress string) error {
36-
command := fmt.Sprintf("ebtables -t nat -A POSTROUTING -o %s -j snat --to-source %s --snat-arp", interfaceName, snatAddress)
37-
err := executeShellCommand(command)
38-
if err != nil {
39-
return err
40-
}
41-
return nil
42-
}
36+
// SetSnatForInterface sets a MAC SNAT rule for an interface.
37+
func SetSnatForInterface(interfaceName string, macAddress net.HardwareAddr, action string) error {
38+
command := fmt.Sprintf(
39+
"ebtables -t nat %s POSTROUTING -o %s -j snat --to-src %s --snat-arp",
40+
action, interfaceName, macAddress.String())
4341

44-
// CleanupSnatForOutgoingPackets cleans up snat
45-
func CleanupSnatForOutgoingPackets(interfaceName string, snatAddress string) error {
46-
command := fmt.Sprintf("ebtables -t nat -D POSTROUTING -o %s -j snat --to-source %s --snat-arp", interfaceName, snatAddress)
47-
err := executeShellCommand(command)
48-
if err != nil {
49-
return err
50-
}
51-
return nil
42+
return executeShellCommand(command)
5243
}
5344

54-
// SetupDnatForArpReplies sets up dnat
55-
func SetupDnatForArpReplies(interfaceName string) error {
56-
command := fmt.Sprintf("ebtables -t nat -A PREROUTING -i %s -p arp -j dnat --to-destination ff:ff:ff:ff:ff:ff", interfaceName)
57-
err := executeShellCommand(command)
58-
if err != nil {
59-
return err
60-
}
61-
return nil
62-
}
45+
// SetDnatForArpReplies sets a MAC DNAT rule for ARP replies received on an interface.
46+
func SetDnatForArpReplies(interfaceName string, action string) error {
47+
command := fmt.Sprintf(
48+
"ebtables -t nat %s PREROUTING -p ARP -i %s -j dnat --to-dst ff:ff:ff:ff:ff:ff",
49+
action, interfaceName)
6350

64-
// CleanupDnatForArpReplies cleans up dnat
65-
func CleanupDnatForArpReplies(interfaceName string) error {
66-
command := fmt.Sprintf("ebtables -t nat -D PREROUTING -i %s -p arp -j dnat --to-destination ff:ff:ff:ff:ff:ff", interfaceName)
67-
err := executeShellCommand(command)
68-
if err != nil {
69-
return err
70-
}
71-
return nil
51+
return executeShellCommand(command)
7252
}
7353

74-
// SetupDnatBasedOnIPV4Address sets up dnat
75-
func SetupDnatBasedOnIPV4Address(ipv4Address string, macAddress string) error {
76-
command := fmt.Sprintf("ebtables -t nat -A PREROUTING -p IPv4 --ip-dst %s -j dnat --to-dst %s --dnat-target ACCEPT", ipv4Address, macAddress)
77-
err := executeShellCommand(command)
78-
if err != nil {
79-
return err
80-
}
81-
return nil
82-
}
54+
// SetDnatForIPAddress sets a MAC DNAT rule for an IP address.
55+
func SetDnatForIPAddress(ipAddress net.IP, macAddress net.HardwareAddr, action string) error {
56+
command := fmt.Sprintf(
57+
"ebtables -t nat %s PREROUTING -p IPv4 --ip-dst %s -j dnat --to-dst %s",
58+
action, ipAddress.String(), macAddress.String())
8359

84-
// RemoveDnatBasedOnIPV4Address cleans up dnat
85-
func RemoveDnatBasedOnIPV4Address(ipv4Address string, macAddress string) error {
86-
command := fmt.Sprintf("ebtables -t nat -D PREROUTING -p IPv4 --ip-dst %s -j dnat --to-dst %s --dnat-target ACCEPT", ipv4Address, macAddress)
87-
err := executeShellCommand(command)
88-
if err != nil {
89-
return err
90-
}
91-
return nil
60+
return executeShellCommand(command)
9261
}
9362

9463
func executeShellCommand(command string) error {

ipam/manager.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package ipam
55

66
import (
77
"sync"
8+
"time"
89

910
"github.com/Azure/azure-container-networking/common"
1011
"github.com/Azure/azure-container-networking/log"
@@ -19,6 +20,8 @@ const (
1920

2021
// AddressManager manages the set of address spaces and pools allocated to containers.
2122
type addressManager struct {
23+
Version string
24+
TimeStamp time.Time
2225
AddrSpaces map[string]*addressSpace `json:"AddressSpaces"`
2326
store store.KeyValueStore
2427
source addressConfigSource
@@ -64,6 +67,7 @@ func NewAddressManager() (AddressManager, error) {
6467

6568
// Initialize configures address manager.
6669
func (am *addressManager) Initialize(config *common.PluginConfig, options map[string]interface{}) error {
70+
am.Version = config.Version
6771
am.store = config.Store
6872
am.netApi, _ = config.NetApi.(network.NetworkManager)
6973

@@ -91,8 +95,20 @@ func (am *addressManager) restore() error {
9195
return nil
9296
}
9397

98+
// After a reboot, all address resources are implicitly released.
99+
// Ignore the persisted state if it is older than the last reboot time.
100+
modTime, err := am.store.GetModificationTime()
101+
if err == nil {
102+
rebootTime, err := common.GetLastRebootTime()
103+
if err == nil && rebootTime.After(modTime) {
104+
log.Printf("[ipam] Ignoring stale state from store.")
105+
log.Printf("[ipam] Store timestamp %v is older than boot timestamp %v.", modTime, rebootTime)
106+
return nil
107+
}
108+
}
109+
94110
// Read any persisted state.
95-
err := am.store.Read(storeKey, am)
111+
err = am.store.Read(storeKey, am)
96112
if err != nil {
97113
if err == store.ErrKeyNotFound {
98114
return nil
@@ -121,6 +137,9 @@ func (am *addressManager) save() error {
121137
return nil
122138
}
123139

140+
// Update time stamp.
141+
am.TimeStamp = time.Now()
142+
124143
err := am.store.Write(storeKey, am)
125144
if err == nil {
126145
log.Printf("[ipam] Save succeeded.\n")

network/endpoint.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ func (nw *network) newEndpoint(epInfo *EndpointInfo) (*endpoint, error) {
101101
// Setup MAC address translation rules for container interface.
102102
log.Printf("[net] Setting up MAC address translation rules for endpoint %v.", contIfName)
103103
for _, ipAddr := range epInfo.IPAddresses {
104-
err = ebtables.SetupDnatBasedOnIPV4Address(ipAddr.IP.String(), containerIf.HardwareAddr.String())
104+
err = ebtables.SetDnatForIPAddress(ipAddr.IP, containerIf.HardwareAddr, ebtables.Append)
105105
if err != nil {
106106
goto cleanup
107107
}
@@ -240,7 +240,7 @@ func (nw *network) deleteEndpoint(endpointId string) error {
240240
// Delete MAC address translation rule.
241241
log.Printf("[net] Deleting MAC address translation rules for endpoint %v.", endpointId)
242242
for _, ipAddr := range ep.IPAddresses {
243-
err = ebtables.RemoveDnatBasedOnIPV4Address(ipAddr.IP.String(), ep.MacAddress.String())
243+
err = ebtables.SetDnatForIPAddress(ipAddr.IP, ep.MacAddress, ebtables.Delete)
244244
if err != nil {
245245
goto cleanup
246246
}

network/manager.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package network
55

66
import (
77
"sync"
8+
"time"
89

910
"github.com/Azure/azure-container-networking/common"
1011
"github.com/Azure/azure-container-networking/log"
@@ -18,6 +19,8 @@ const (
1819

1920
// NetworkManager manages the set of container networking resources.
2021
type networkManager struct {
22+
Version string
23+
TimeStamp time.Time
2124
ExternalInterfaces map[string]*externalInterface
2225
store store.KeyValueStore
2326
sync.Mutex
@@ -52,6 +55,7 @@ func NewNetworkManager() (NetworkManager, error) {
5255

5356
// Initialize configures network manager.
5457
func (nm *networkManager) Initialize(config *common.PluginConfig) error {
58+
nm.Version = config.Version
5559
nm.store = config.Store
5660

5761
// Restore persisted state.
@@ -70,8 +74,20 @@ func (nm *networkManager) restore() error {
7074
return nil
7175
}
7276

77+
// After a reboot, all address resources are implicitly released.
78+
// Ignore the persisted state if it is older than the last reboot time.
79+
modTime, err := nm.store.GetModificationTime()
80+
if err == nil {
81+
rebootTime, err := common.GetLastRebootTime()
82+
if err == nil && rebootTime.After(modTime) {
83+
log.Printf("[net] Ignoring stale state from store.")
84+
log.Printf("[net] Store timestamp %v is older than boot timestamp %v.", modTime, rebootTime)
85+
return nil
86+
}
87+
}
88+
7389
// Read any persisted state.
74-
err := nm.store.Read(storeKey, nm)
90+
err = nm.store.Read(storeKey, nm)
7591
if err != nil {
7692
if err == store.ErrKeyNotFound {
7793
// Considered successful.
@@ -101,6 +117,9 @@ func (nm *networkManager) save() error {
101117
return nil
102118
}
103119

120+
// Update time stamp.
121+
nm.TimeStamp = time.Now()
122+
104123
err := nm.store.Write(storeKey, nm)
105124
if err == nil {
106125
log.Printf("[net] Save succeeded.\n")

network/network.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,12 @@ func (nm *networkManager) connectExternalInterface(extIf *externalInterface, bri
172172

173173
// Setup MAC address translation rules for external interface.
174174
log.Printf("[net] Setting up MAC address translation rules for %v.", hostIf.Name)
175-
err = ebtables.SetupSnatForOutgoingPackets(hostIf.Name, hostIf.HardwareAddr.String())
175+
err = ebtables.SetSnatForInterface(hostIf.Name, hostIf.HardwareAddr, ebtables.Append)
176176
if err != nil {
177177
goto cleanup
178178
}
179179

180-
err = ebtables.SetupDnatForArpReplies(hostIf.Name)
180+
err = ebtables.SetDnatForArpReplies(hostIf.Name, ebtables.Append)
181181
if err != nil {
182182
goto cleanup
183183
}
@@ -240,8 +240,8 @@ cleanup:
240240
log.Printf("[net] Connecting interface %v failed, err:%v.", extIf.Name, err)
241241

242242
// Roll back the changes for the network.
243-
ebtables.CleanupDnatForArpReplies(extIf.Name)
244-
ebtables.CleanupSnatForOutgoingPackets(extIf.Name, extIf.MacAddress.String())
243+
ebtables.SetDnatForArpReplies(extIf.Name, ebtables.Delete)
244+
ebtables.SetSnatForInterface(extIf.Name, extIf.MacAddress, ebtables.Delete)
245245

246246
netlink.DeleteLink(bridgeName)
247247

@@ -253,8 +253,8 @@ func (nm *networkManager) disconnectExternalInterface(extIf *externalInterface)
253253
log.Printf("[net] Disconnecting interface %v.", extIf.Name)
254254

255255
// Cleanup MAC address translation rules.
256-
ebtables.CleanupDnatForArpReplies(extIf.Name)
257-
ebtables.CleanupSnatForOutgoingPackets(extIf.Name, extIf.MacAddress.String())
256+
ebtables.SetDnatForArpReplies(extIf.Name, ebtables.Delete)
257+
ebtables.SetSnatForInterface(extIf.Name, extIf.MacAddress, ebtables.Delete)
258258

259259
// Disconnect external interface from its bridge.
260260
err := netlink.SetLinkMaster(extIf.Name, "")

store/json.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func (kvs *jsonFileStore) Write(key string, value interface{}) error {
102102
return kvs.flush()
103103
}
104104

105-
// Flush commits in-memory state to backing store.
105+
// Flush commits in-memory state to persistent store.
106106
func (kvs *jsonFileStore) Flush() error {
107107
kvs.Mutex.Lock()
108108
defer kvs.Mutex.Unlock()
@@ -193,3 +193,13 @@ func (kvs *jsonFileStore) Unlock() error {
193193

194194
return nil
195195
}
196+
197+
// GetModificationTime returns the modification time of the persistent store.
198+
func (kvs *jsonFileStore) GetModificationTime() (time.Time, error) {
199+
info, err := os.Stat(kvs.fileName)
200+
if err != nil {
201+
return time.Time{}, err
202+
}
203+
204+
return info.ModTime(), nil
205+
}

store/store.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package store
55

66
import (
77
"fmt"
8+
"time"
89
)
910

1011
// KeyValueStore represents a persistent store of (key,value) pairs.
@@ -14,6 +15,7 @@ type KeyValueStore interface {
1415
Flush() error
1516
Lock(block bool) error
1617
Unlock() error
18+
GetModificationTime() (time.Time, error)
1719
}
1820

1921
var (

0 commit comments

Comments
 (0)