Skip to content

Commit 278ce75

Browse files
committed
Added support for Linux l2tunnel mode
1 parent 0e0da7b commit 278ce75

File tree

11 files changed

+117
-31
lines changed

11 files changed

+117
-31
lines changed

cni/netconfig.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ type NetworkConfig struct {
1212
CniVersion string `json:"cniVersion"`
1313
Name string `json:"name"`
1414
Type string `json:"type"`
15+
Mode string `json:"mode"`
1516
Master string `json:"master"`
1617
Bridge string `json:"bridge,omitempty"`
1718
LogLevel string `json:"logLevel,omitempty"`

cni/network/network.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ func (plugin *netPlugin) Add(args *cniSkel.CmdArgs) error {
135135
// Create the network.
136136
nwInfo := network.NetworkInfo{
137137
Id: networkId,
138+
Mode: nwCfg.Mode,
138139
Subnets: []string{subnet.String()},
139140
BridgeName: nwCfg.Bridge,
140141
}

cnm/api.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,13 @@ const (
99

1010
// Libnetwork remote plugin paths
1111
activatePath = "/Plugin.Activate"
12+
13+
// Libnetwork labels
14+
genericData = "com.docker.network.generic"
1215
)
1316

17+
type OptionMap map[string]interface{}
18+
1419
//
1520
// Libnetwork remote plugin API
1621
//

cnm/network/api.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ const (
1616
joinPath = "/NetworkDriver.Join"
1717
leavePath = "/NetworkDriver.Leave"
1818
endpointOperInfoPath = "/NetworkDriver.EndpointOperInfo"
19+
20+
// Libnetwork network plugin options
21+
modeOption = "com.microsoft.azure.network.mode"
1922
)
2023

2124
// Request sent by libnetwork when querying plugin capabilities.

cnm/network/network.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@ func (plugin *netPlugin) createNetwork(w http.ResponseWriter, r *http.Request) {
132132
Options: req.Options,
133133
}
134134

135+
// Parse network options.
136+
options := plugin.ParseOptions(req.Options)
137+
if options != nil {
138+
nwInfo.Mode, _ = options[modeOption].(string)
139+
}
140+
135141
// Assume single pool per address family.
136142
if len(req.IPv4Data) > 0 {
137143
nwInfo.Subnets = append(nwInfo.Subnets, req.IPv4Data[0].Pool)

cnm/plugin.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ func (plugin *Plugin) Uninitialize() {
7878
plugin.Plugin.Uninitialize()
7979
}
8080

81+
// ParseOptions returns generic options from a libnetwork request.
82+
func (plugin *Plugin) ParseOptions(options OptionMap) OptionMap {
83+
opt, _ := options[genericData].(OptionMap)
84+
return opt
85+
}
86+
8187
//
8288
// Libnetwork remote plugin API
8389
//

ebtables/ebtables.go

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,26 +36,44 @@ func installEbtables() {
3636
// SetSnatForInterface sets a MAC SNAT rule for an interface.
3737
func SetSnatForInterface(interfaceName string, macAddress net.HardwareAddr, action string) error {
3838
command := fmt.Sprintf(
39-
"ebtables -t nat %s POSTROUTING -o %s -j snat --to-src %s --snat-arp",
39+
"ebtables -t nat %s POSTROUTING -s unicast -o %s -j snat --to-src %s --snat-arp --snat-target ACCEPT",
4040
action, interfaceName, macAddress.String())
4141

4242
return executeShellCommand(command)
4343
}
4444

45+
// SetArpReply sets an ARP reply rule for the given target IP address and MAC address.
46+
func SetArpReply(ipAddress net.IP, macAddress net.HardwareAddr, action string) error {
47+
command := fmt.Sprintf(
48+
"ebtables -t nat %s PREROUTING -p ARP --arp-ip-dst %s -j arpreply --arpreply-mac %s --arpreply-target DROP",
49+
action, ipAddress, macAddress.String())
50+
51+
return executeShellCommand(command)
52+
}
53+
4554
// SetDnatForArpReplies sets a MAC DNAT rule for ARP replies received on an interface.
4655
func SetDnatForArpReplies(interfaceName string, action string) error {
4756
command := fmt.Sprintf(
48-
"ebtables -t nat %s PREROUTING -p ARP -i %s -j dnat --to-dst ff:ff:ff:ff:ff:ff",
57+
"ebtables -t nat %s PREROUTING -p ARP -i %s -j dnat --to-dst ff:ff:ff:ff:ff:ff --dnat-target ACCEPT",
4958
action, interfaceName)
5059

5160
return executeShellCommand(command)
5261
}
5362

63+
// SetVepaMode sets the VEPA mode for an interface.
64+
func SetVepaMode(upstreamIfName string, upstreamMacAddress string, action string) error {
65+
command := fmt.Sprintf(
66+
"ebtables -t nat %s PREROUTING -i ! %s -j dnat --to-dst %s --dnat-target ACCEPT",
67+
action, upstreamIfName, upstreamMacAddress)
68+
69+
return executeShellCommand(command)
70+
}
71+
5472
// SetDnatForIPAddress sets a MAC DNAT rule for an IP address.
55-
func SetDnatForIPAddress(ipAddress net.IP, macAddress net.HardwareAddr, action string) error {
73+
func SetDnatForIPAddress(interfaceName string, ipAddress net.IP, macAddress net.HardwareAddr, action string) error {
5674
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())
75+
"ebtables -t nat %s PREROUTING -p IPv4 -i %s --ip-dst %s -j dnat --to-dst %s --dnat-target ACCEPT",
76+
action, interfaceName, ipAddress.String(), macAddress.String())
5977

6078
return executeShellCommand(command)
6179
}

network/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
var (
1111
// Error responses returned by NetworkManager.
1212
errSubnetNotFound = fmt.Errorf("Subnet not found")
13-
errNetworkTypeInvalid = fmt.Errorf("Network type is invalid")
13+
errNetworkModeInvalid = fmt.Errorf("Network mode is invalid")
1414
errNetworkExists = fmt.Errorf("Network already exists")
1515
errNetworkNotFound = fmt.Errorf("Network not found")
1616
errEndpointExists = fmt.Errorf("Endpoint already exists")

network/endpoint_linux.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func (nw *network) newEndpointImpl(epInfo *EndpointInfo) (*endpoint, error) {
8080
// Setup MAC address translation rules for container interface.
8181
log.Printf("[net] Setting up MAC address translation rules for endpoint %v.", contIfName)
8282
for _, ipAddr := range epInfo.IPAddresses {
83-
err = ebtables.SetDnatForIPAddress(ipAddr.IP, containerIf.HardwareAddr, ebtables.Append)
83+
err = ebtables.SetDnatForIPAddress(nw.extIf.Name, ipAddr.IP, containerIf.HardwareAddr, ebtables.Append)
8484
if err != nil {
8585
goto cleanup
8686
}
@@ -205,7 +205,7 @@ func (nw *network) deleteEndpointImpl(ep *endpoint) error {
205205
// Delete MAC address translation rule.
206206
log.Printf("[net] Deleting MAC address translation rules for endpoint %v.", ep.Id)
207207
for _, ipAddr := range ep.IPAddresses {
208-
err = ebtables.SetDnatForIPAddress(ipAddr.IP, ep.MacAddress, ebtables.Delete)
208+
err = ebtables.SetDnatForIPAddress(nw.extIf.Name, ipAddr.IP, ep.MacAddress, ebtables.Delete)
209209
if err != nil {
210210
goto cleanup
211211
}

network/network.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import (
1111

1212
const (
1313
// Operational modes.
14-
OpModeBridge = "bridge"
14+
opModeBridge = "bridge"
15+
opModeTunnel = "tunnel"
16+
opModeDefault = opModeTunnel
1517
)
1618

1719
// ExternalInterface is a host network interface that bridges containers to external networks.
@@ -104,6 +106,11 @@ func (nm *networkManager) newNetwork(nwInfo *NetworkInfo) (*network, error) {
104106

105107
log.Printf("[net] Creating network %+v.", nwInfo)
106108

109+
// Set defaults.
110+
if nwInfo.Mode == "" {
111+
nwInfo.Mode = opModeDefault
112+
}
113+
107114
// Find the external interface for this subnet.
108115
extIf := nm.findExternalInterfaceBySubnet(nwInfo.Subnets[0])
109116
if extIf == nil {

0 commit comments

Comments
 (0)