Skip to content

Commit

Permalink
Merge pull request #1086 from Luap99/libnetwork-isolate
Browse files Browse the repository at this point in the history
libnetwork: add isolate network option
  • Loading branch information
openshift-ci[bot] authored Jul 7, 2022
2 parents 38a4077 + f4312dc commit 6a69ac6
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 41 deletions.
52 changes: 38 additions & 14 deletions libnetwork/cni/cni_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package cni

import (
"encoding/json"
"fmt"
"io/ioutil"
"net"
"os"
Expand Down Expand Up @@ -70,10 +71,10 @@ func createNetworkFromCNIConfigList(conf *libcni.NetworkConfigList, confPath str

// set network options
if bridge.MTU != 0 {
network.Options["mtu"] = strconv.Itoa(bridge.MTU)
network.Options[types.MTUOption] = strconv.Itoa(bridge.MTU)
}
if bridge.Vlan != 0 {
network.Options["vlan"] = strconv.Itoa(bridge.Vlan)
network.Options[types.VLANOption] = strconv.Itoa(bridge.Vlan)
}

err = convertIPAMConfToNetwork(&network, &bridge.IPAM, confPath)
Expand All @@ -91,11 +92,11 @@ func createNetworkFromCNIConfigList(conf *libcni.NetworkConfigList, confPath str

// set network options
if vlan.MTU != 0 {
network.Options["mtu"] = strconv.Itoa(vlan.MTU)
network.Options[types.MTUOption] = strconv.Itoa(vlan.MTU)
}

if vlan.Mode != "" {
network.Options["mode"] = vlan.Mode
network.Options[types.ModeOption] = vlan.Mode
}

err = convertIPAMConfToNetwork(&network, &vlan.IPAM, confPath)
Expand All @@ -110,18 +111,31 @@ func createNetworkFromCNIConfigList(conf *libcni.NetworkConfigList, confPath str
}

// check if the dnsname plugin is configured
network.DNSEnabled = findPluginByName(conf.Plugins, "dnsname")
network.DNSEnabled = findPluginByName(conf.Plugins, "dnsname") != nil

// now get isolation mode from firewall plugin
firewall := findPluginByName(conf.Plugins, "firewall")
if firewall != nil {
var firewallConf firewallConfig
err := json.Unmarshal(firewall.Bytes, &firewallConf)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal the firewall plugin config in %s: %w", confPath, err)
}
if firewallConf.IngressPolicy == ingressPolicySameBridge {
network.Options[types.IsolateOption] = "true"
}
}

return &network, nil
}

func findPluginByName(plugins []*libcni.NetworkConfig, name string) bool {
for _, plugin := range plugins {
if plugin.Network.Type == name {
return true
func findPluginByName(plugins []*libcni.NetworkConfig, name string) *libcni.NetworkConfig {
for i := range plugins {
if plugins[i].Network.Type == name {
return plugins[i]
}
}
return false
return nil
}

// convertIPAMConfToNetwork converts A cni IPAMConfig to libpod network subnets.
Expand Down Expand Up @@ -291,7 +305,7 @@ func (n *cniNetwork) createCNIConfigListFromNetwork(network *types.Network, writ
switch network.Driver {
case types.BridgeNetworkDriver:
bridge := newHostLocalBridge(network.NetworkInterface, isGateway, ipMasq, opts.mtu, opts.vlan, ipamConf)
plugins = append(plugins, bridge, newPortMapPlugin(), newFirewallPlugin(), newTuningPlugin())
plugins = append(plugins, bridge, newPortMapPlugin(), newFirewallPlugin(opts.isolate), newTuningPlugin())
// if we find the dnsname plugin we add configuration for it
if hasDNSNamePlugin(n.cniPluginDirs) && network.DNSEnabled {
// Note: in the future we might like to allow for dynamic domain names
Expand Down Expand Up @@ -382,26 +396,27 @@ type options struct {
vlan int
mtu int
vlanPluginMode string
isolate bool
}

func parseOptions(networkOptions map[string]string, networkDriver string) (*options, error) {
opt := &options{}
var err error
for k, v := range networkOptions {
switch k {
case "mtu":
case types.MTUOption:
opt.mtu, err = internalutil.ParseMTU(v)
if err != nil {
return nil, err
}

case "vlan":
case types.VLANOption:
opt.vlan, err = internalutil.ParseVlan(v)
if err != nil {
return nil, err
}

case "mode":
case types.ModeOption:
switch networkDriver {
case types.MacVLANNetworkDriver:
if !pkgutil.StringInSlice(v, types.ValidMacVLANModes) {
Expand All @@ -416,6 +431,15 @@ func parseOptions(networkOptions map[string]string, networkDriver string) (*opti
}
opt.vlanPluginMode = v

case types.IsolateOption:
if networkDriver != types.BridgeNetworkDriver {
return nil, errors.New("isolate option is only supported with the bridge driver")
}
opt.isolate, err = strconv.ParseBool(v)
if err != nil {
return nil, fmt.Errorf("failed to parse isolate option: %w", err)
}

default:
return nil, errors.Errorf("unsupported network option %s", k)
}
Expand Down
16 changes: 12 additions & 4 deletions libnetwork/cni/cni_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ const (

// podmanOptionsKey key used to store the podman network options in a cni config
podmanOptionsKey = "podman_options"

// ingressPolicySameBridge is used to only allow connection on the same bridge network
ingressPolicySameBridge = "same-bridge"
)

// cniPortMapEntry struct is used by the portmap plugin
Expand Down Expand Up @@ -95,8 +98,9 @@ type VLANConfig struct {

// firewallConfig describes the firewall plugin
type firewallConfig struct {
PluginType string `json:"type"`
Backend string `json:"backend"`
PluginType string `json:"type"`
Backend string `json:"backend"`
IngressPolicy string `json:"ingressPolicy,omitempty"`
}

// tuningConfig describes the tuning plugin
Expand Down Expand Up @@ -222,10 +226,14 @@ func newPortMapPlugin() portMapConfig {
}

// newFirewallPlugin creates a generic firewall plugin
func newFirewallPlugin() firewallConfig {
return firewallConfig{
func newFirewallPlugin(isolate bool) firewallConfig {
fw := firewallConfig{
PluginType: "firewall",
}
if isolate {
fw.IngressPolicy = ingressPolicySameBridge
}
return fw
}

// newTuningPlugin creates a generic tuning section
Expand Down
66 changes: 54 additions & 12 deletions libnetwork/cni/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ var _ = Describe("Config", func() {
network := types.Network{
Driver: "macvlan",
Options: map[string]string{
"mode": mode,
types.ModeOption: mode,
},
}
network1, err := libpodNet.NetworkCreate(network)
Expand All @@ -409,7 +409,7 @@ var _ = Describe("Config", func() {
network := types.Network{
Driver: "macvlan",
Options: map[string]string{
"mode": "test",
types.ModeOption: "test",
},
}
_, err := libpodNet.NetworkCreate(network)
Expand Down Expand Up @@ -460,7 +460,7 @@ var _ = Describe("Config", func() {
network := types.Network{
Driver: "ipvlan",
Options: map[string]string{
"mode": mode,
types.ModeOption: mode,
},
}
network1, err := libpodNet.NetworkCreate(network)
Expand Down Expand Up @@ -488,7 +488,7 @@ var _ = Describe("Config", func() {
network := types.Network{
Driver: "ipvlan",
Options: map[string]string{
"mode": "test",
types.ModeOption: "test",
},
}
_, err := libpodNet.NetworkCreate(network)
Expand Down Expand Up @@ -969,7 +969,7 @@ var _ = Describe("Config", func() {
It("create network with mtu option", func() {
network := types.Network{
Options: map[string]string{
"mtu": "1500",
types.MTUOption: "1500",
},
}
network1, err := libpodNet.NetworkCreate(network)
Expand All @@ -985,7 +985,7 @@ var _ = Describe("Config", func() {
It("create network with invalid mtu option", func() {
network := types.Network{
Options: map[string]string{
"mtu": "abc",
types.MTUOption: "abc",
},
}
_, err := libpodNet.NetworkCreate(network)
Expand All @@ -994,7 +994,7 @@ var _ = Describe("Config", func() {

network = types.Network{
Options: map[string]string{
"mtu": "-1",
types.MTUOption: "-1",
},
}
_, err = libpodNet.NetworkCreate(network)
Expand All @@ -1006,7 +1006,7 @@ var _ = Describe("Config", func() {
network := types.Network{
Driver: "macvlan",
Options: map[string]string{
"mtu": "1500",
types.MTUOption: "1500",
},
}
network1, err := libpodNet.NetworkCreate(network)
Expand All @@ -1022,7 +1022,7 @@ var _ = Describe("Config", func() {
It("create network with vlan option", func() {
network := types.Network{
Options: map[string]string{
"vlan": "5",
types.VLANOption: "5",
},
}
network1, err := libpodNet.NetworkCreate(network)
Expand All @@ -1038,7 +1038,7 @@ var _ = Describe("Config", func() {
It("create network with invalid vlan option", func() {
network := types.Network{
Options: map[string]string{
"vlan": "abc",
types.VLANOption: "abc",
},
}
_, err := libpodNet.NetworkCreate(network)
Expand All @@ -1047,7 +1047,7 @@ var _ = Describe("Config", func() {

network = types.Network{
Options: map[string]string{
"vlan": "-1",
types.VLANOption: "-1",
},
}
_, err = libpodNet.NetworkCreate(network)
Expand Down Expand Up @@ -1162,6 +1162,39 @@ var _ = Describe("Config", func() {
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(Equal("unsupported ipam driver \"blah\""))
})

It("create network with isolate option", func() {
network := types.Network{
Options: map[string]string{
types.IsolateOption: "true",
},
}
network1, err := libpodNet.NetworkCreate(network)
Expect(err).ToNot(HaveOccurred())
Expect(network1.Driver).To(Equal("bridge"))
Expect(network1.Options).ToNot(BeNil())
path := filepath.Join(cniConfDir, network1.Name+".conflist")
Expect(path).To(BeARegularFile())
grepInFile(path, `"ingressPolicy": "same-bridge"`)
Expect(network1.Options).To(HaveKeyWithValue("isolate", "true"))
// reload configs from disk
libpodNet, err = getNetworkInterface(cniConfDir)
Expect(err).ToNot(HaveOccurred())

network1, err = libpodNet.NetworkInspect(network1.Name)
Expect(err).ToNot(HaveOccurred())
Expect(network1.Options).To(HaveKeyWithValue("isolate", "true"))
})

It("create network with invalid isolate option", func() {
network := types.Network{
Options: map[string]string{
types.IsolateOption: "123",
},
}
_, err := libpodNet.NetworkCreate(network)
Expect(err).To(HaveOccurred())
})
})

Context("network load valid existing ones", func() {
Expand Down Expand Up @@ -1370,6 +1403,15 @@ var _ = Describe("Config", func() {
Expect(network.IPAMOptions).To(HaveKeyWithValue("driver", "none"))
})

It("bridge with isolate option", func() {
network, err := libpodNet.NetworkInspect("isolate")
Expect(err).To(BeNil())
Expect(network.Name).To(Equal("isolate"))
Expect(network.ID).To(HaveLen(64))
Expect(network.Driver).To(Equal("bridge"))
Expect(network.Options).To(HaveKeyWithValue("isolate", "true"))
})

It("network list with filters (name)", func() {
filters := map[string][]string{
"name": {"internal", "bridge"},
Expand Down Expand Up @@ -1449,7 +1491,7 @@ var _ = Describe("Config", func() {
HaveNetworkName("mtu"), HaveNetworkName("vlan"), HaveNetworkName("podman"),
HaveNetworkName("label"), HaveNetworkName("macvlan"), HaveNetworkName("macvlan_mtu"),
HaveNetworkName("dualstack"), HaveNetworkName("ipam-none"), HaveNetworkName("ipam-empty"),
HaveNetworkName("ipam-static")))
HaveNetworkName("ipam-static"), HaveNetworkName("isolate")))
})

It("network list with filters (label)", func() {
Expand Down
46 changes: 46 additions & 0 deletions libnetwork/cni/testfiles/valid/isolate.conflist
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"cniVersion": "0.4.0",
"name": "isolate",
"plugins": [
{
"type": "bridge",
"bridge": "cni-podman123",
"isGateway": true,
"ipMasq": true,
"hairpinMode": true,
"ipam": {
"type": "host-local",
"routes": [
{
"dst": "0.0.0.0/0"
}
],
"ranges": [
[
{
"subnet": "10.0.0.0/24",
"gateway": "10.0.0.1"
}
]
]
},
"capabilities": {
"ips": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
},
{
"type": "firewall",
"backend": "",
"ingressPolicy": "same-bridge"
},
{
"type": "tuning"
}
]
}
Loading

0 comments on commit 6a69ac6

Please sign in to comment.