Skip to content

feat: add support for com.docker.network.bridge.enable_icc network option #4311

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

swagatbora90
Copy link
Contributor

This PR adds support for docker compatible com.docker.network.bridge.enable_icc or --icc network create option. This option is used to enable/disable intercontainer connectivity.

By default, any bridge network allows connectivity between containers attached to the same network, while containers in different networks are isolated. The enable_icc feature can be further used to enable/disable intra bridge container connectivity.

Requires firewall plugin >= v1.7.1

Testing

  1. Create a network with com.docker.network.bridge.enable_icc set to false, say test-net
  2. Run a container and attach it to test-net
  3. Run a second container and attach it to test-net
  4. Ping from container 1 to container 2 should not succeed.
sudo nerdctl network create  -o "com.docker.network.bridge.enable_icc=false" test-net          
254ddbe0ec1e5f3ed4b492876e2b6b9a051436b44c40d00ebd5e72bf7aa88435

sudo nerdctl run -d  --network test-net --name C1 ubuntu  sleep infinity  
6f22e651b9a4f3988e1ebce35f13806f65d0be942bfe9a2325c668a53cafcc9b

 sudo nerdctl run --network test-net alpine ping -c 1 -W 1 C1
PING C1 (10.4.4.4): 56 data bytes

--- C1 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

With icc=true, it will fallback to default behavior

sudo nerdctl network create  -o "com.docker.network.bridge.enable_icc=true" test-net1   
cf021853e2fd31f5ef29264e5fd834d45bf1ea364c3fef8ff60edec326899b77
 
sudo nerdctl run -d  --network test-net1 --name C2 ubuntu  sleep infinity  
2c95ae6ad9da8a07de97c609d9e65acdc95f3b343ea6e4c46ccd4c9b3df79b90

sudo nerdctl run --network test-net1 alpine ping -c 1 -W 1 C2
PING C2 (10.4.5.2): 56 data bytes
64 bytes from 10.4.5.2: seq=0 ttl=127 time=0.115 ms

--- C2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.115/0.115/0.115 ms

return helpers.Command("run", "--rm", "--net", data.Identifier(),
testutil.CommonImage, "ping", "-c", "1", "-W", "1", data.Identifier("c1"))
},
Expected: test.Expects(1, nil, nil), // Expect ping to fail with exit code 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if ping portably returns that same exit code.
Maybe use expect.ExitCodeGenericFail to check for failure without being specific on exit code?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eg: on macOS, it seems to exit 2

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will change this to just check for any non-zero exit code

}

// firewallPluginGEQ110 checks if the firewall plugin is greater than or equal to v1.1.0
func firewallPluginGEQ110(firewallPath string) (bool, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can just remove this helper and call directly firewallPluginGEQVersion(firewallPath, "v1.1.0") where needs be?

testutil.CommonImage, "ping", "-c", "1", "-W", "1", data.Identifier("c1"))
},
Expected: test.Expects(0, nil, nil), // Expect ping to succeed with exit code 0
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a third case where enable_icc is not specified, to verify the default behavior?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, will add

@@ -129,9 +135,24 @@ func (e *CNIEnv) generateCNIPlugins(driver string, name string, ipam map[string]
if ipv6 {
bridge.Capabilities["ips"] = true
}
plugins = []CNIPlugin{bridge, newPortMapPlugin(), newFirewallPlugin(), newTuningPlugin()}

// Determine the appropriate firewall ingress policy based on icc setting
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only matter for non-default network, right?

Maybe the entire section should be moved inside the if name != DefaultNetworkName { section?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, currently network options are only applied to non default network, which makes sense since the default network is created by nerdctl. That being said, there isn't a hard rule that these network options can never be applied to the default network. Docker actually allows you to configure the default network with these options on daemon startup. I think we can keep this as is, and let the callers decide how they want to invoke this.

@@ -111,6 +112,11 @@ func (e *CNIEnv) generateCNIPlugins(driver string, name string, ipam map[string]
if err != nil {
return nil, err
}
case "icc", "com.docker.network.bridge.enable_icc":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs documentation

@swagatbora90 swagatbora90 force-pushed the feat-icc-nerdctl branch 3 times, most recently from c85e72d to bea516f Compare June 12, 2025 00:32
@@ -439,3 +442,23 @@ func ContainerdVersion(v string) *test.Requirement {
},
}
}

// CNIFirewallVersionGE checks if the CNI firewall plugin version is greater than or equal to the specified version
func CNIFirewallVersionGE(requiredVersion string) *test.Requirement {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "GE" suffix isn't consistent with ContainerdVersion()


testCase.Require = require.All(
require.Linux,
nerdtest.Rootful,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Member

@AkihiroSuda AkihiroSuda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

@AkihiroSuda AkihiroSuda added this to the v2.1.3 milestone Jun 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants