Skip to content
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

bridge: Add mac field to specify container iface mac #636

Merged
merged 1 commit into from
Jun 30, 2021

Conversation

EdDev
Copy link
Contributor

@EdDev EdDev commented Jun 10, 2021

Controlling the mac address of the interface (veth peer) in the
container is useful for functionalities that depend on the mac address.
Examples range from dynamic IP allocations based on an identifier (the
mac) and up to firewall rules (e.g. no-mac-spoofing).

Enforcing a mac address at an early stage and not through a chained
plugin assures the configuration does not have wrong intermediate
configuration. This is especially critical when a dynamic IP may be
provided already in this period.
But it also has implications for future abilities that may land on the
bridge plugin, e.g. supporting no-mac-spoofing.

The field name used (mac) fits with other plugins which control the
mac address of the container interface.

The mac address may be specified through the following methods:

  • CNI_ARGS
  • Args
  • RuntimeConfig [1]

The list is ordered by priority, from lowest to higher. The higher
priority method overrides any previous settings.
(e.g. if the mac is specified in RuntimeConfig, it will override any
specifications of the mac mentioned in CNI_ARGS or Args)

[1] To use RuntimeConfig, the network configuration should include the
capabilities field with mac specified ("capabilities": {"mac": true}).

@EdDev
Copy link
Contributor Author

EdDev commented Jun 16, 2021

@squeed I have added the support for CNI_ARGS, Args and RunningConfig parameters.

Can you please approve the CI run?

@mccv1r0
Copy link
Member

mccv1r0 commented Jun 16, 2021

I believe that this would fix #450 as well.

@squeed
Copy link
Member

squeed commented Jun 16, 2021

This looks pretty good. @s1061123 would you mind giving this a quick review?

@squeed
Copy link
Member

squeed commented Jun 16, 2021

Personal nit pick - can this be a single commit?

@mccv1r0
Copy link
Member

mccv1r0 commented Jun 16, 2021

/lgtm

@EdDev
Copy link
Contributor Author

EdDev commented Jun 17, 2021

Personal nit pick - can this be a single commit?

The idea was to make it easy for reviewers to go over it in stages. The changes are independent, stand by themselves and give a nicer "story" in the history (the details in the tests may look messy when looked as one change).
But I do not have any strong feelings over this, if you still prefer to squash it all, just let me know.

@@ -233,6 +233,37 @@ var _ = Describe("Link", func() {
})
})

It("successfully creates a veth pair with an explicit mac", func() {
const mac = "02:00:00:00:01:23"
Copy link
Member

Choose a reason for hiding this comment

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

why this test case is separated into three steps? and I don't see the necessity of the third step

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 followed the format of the previous test.
I agree that the first two steps can be merged, they execute on the same netns so there is no reason to split them.
Perhaps the original reason for the split was to emphasize that the first step is the setup while the second is the assertion.
Anyway, I merged them.

The 3rd step is validating that the mac address specified is not assigned to the host side of the veth peer. It seemed a reasonable check to me.

} `json:"args,omitempty"`
RuntimeConfig struct {
Mac string `json:"mac,omitempty"`
} `json:"runtimeConfig,omit"`
Copy link
Member

Choose a reason for hiding this comment

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

nit: omit --> omitempty

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks! Done.

@@ -55,6 +55,24 @@ type NetConf struct {
HairpinMode bool `json:"hairpinMode"`
PromiscMode bool `json:"promiscMode"`
Vlan int `json:"vlan"`
Mac string `json:"mac,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

Mac field here is internal, it should be ignored when marshalling

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why do you think it is internal?
All existing plugins here (macvlan, tuning) allow setting the mac through the network configuration and not only though the runtime parameters.
At the moment, this looks like a consistent behavior to have the parameters as a subset of the configuration.

Are you suggesting not to expose this parameter at the network configuration level?

Copy link
Member

@dcbw dcbw Jun 23, 2021

Choose a reason for hiding this comment

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

@EdDev this is the netconf for the overall Bridge, not the container interface. A 'mac' field here would be the MAC of the bridge itself, not the container veth. It shouldn't be here because per-container options are not specified int he top-level plugin config struct. That's what the runtime args and CNI_ARGS are for.

The difference with macvlan and tuning is they do not have a "parent" interface like the bridge plugin does, so the MAC specified in the config there can only apply to the container interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@dcbw for the purpose of original requirement, I can take it out of the netconf. However, it seems to me that by doing so will break an existing convention where the runtime parameters are (always?) a subset of the netconf.

But again, I have no need for it and it is indeed odd to have this mac field defined at the network level.
If there no other opinions on this, I will take it out.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@EdDev
Copy link
Contributor Author

EdDev commented Jun 20, 2021

change: Responding to review.

@s1061123
Copy link
Contributor

As far as I looked the diff, the 'mac' field could be provided through following ways:

  • CNI config
  • RuntimeConfig
  • 'args'

So if user fills different MAC address in those fields, which MAC will wins?
You may need to add some comments (and document as well).

@EdDev
Copy link
Contributor Author

EdDev commented Jun 22, 2021

As far as I looked the diff, the 'mac' field could be provided through following ways:

* CNI config

* RuntimeConfig

* 'args'

So if user fills different MAC address in those fields, which MAC will wins?
You may need to add some comments (and document as well).

I think the order is suppose to be part of the convention.
RuntimeConfig overrides args which overrides CNI_ARGS which overrides CNI config.
The plugins which support all, use this convention.

There is an explicit statement where args override CNI_ARGS here.

@squeed , am I correct here? Is there another specification where this is defined? Do you think it is worth updating the convention document to clarify this?

@s1061123
Copy link
Contributor

In convention.md, it seems not to be mentioned clearly (explicitly) yet, I guess.

@squeed Do you have any plan to mention the priority among Args/CNI_ARGS/RuntimeConfig in spec?

Controlling the mac address of the interface (veth peer) in the
container is useful for functionalities that depend on the mac address.
Examples range from dynamic IP allocations based on an identifier (the
mac) and up to firewall rules (e.g. no-mac-spoofing).

Enforcing a mac address at an early stage and not through a chained
plugin assures the configuration does not have wrong intermediate
configuration. This is especially critical when a dynamic IP may be
provided already in this period.
But it also has implications for future abilities that may land on the
bridge plugin, e.g. supporting no-mac-spoofing.

The field name used (`mac`) fits with other plugins which control the
mac address of the container interface.

The mac address may be specified through the following methods:
- CNI_ARGS
- Args
- RuntimeConfig [1]

The list is ordered by priority, from lowest to higher. The higher
priority method overrides any previous settings.
(e.g. if the mac is specified in RuntimeConfig, it will override any
specifications of the mac mentioned in CNI_ARGS or Args)

[1] To use RuntimeConfig, the network configuration should include the
`capabilities` field with `mac` specified (`"capabilities": {"mac": true}`).

Signed-off-by: Edward Haas <[email protected]>
@EdDev
Copy link
Contributor Author

EdDev commented Jun 29, 2021

Change: Answered review requests

  • Squashed all commits into one.
  • Removed the ability to set the mac address from the plugin network config (netconf).

Copy link

@alonSadan alonSadan left a comment

Choose a reason for hiding this comment

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

thank you Eddi. Really Nice!

I am not so familiar with this subject, but (as I asked also in the inline comments) are all macs acceptable for a veth at this stage, or there are limitations ? what happens if the mac being set breaks the limitation?

For example I think that the bridges mac should be the smallest of all macs of the veths that are connected to this bridge. Do we care about this kind of limitation at this stage, and is there something should be done to enforce it ?

}

// MacEnvArgs represents CNI_ARGS
type MacEnvArgs struct {

Choose a reason for hiding this comment

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

Shouldn't the name be something more abstract, because it might contain more kinds of args in the future?
I mean, maybe it is better to drop Mac from the name?

Copy link
Member

Choose a reason for hiding this comment

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

No, this is the type boilerplate to automatically parse CNI_ARGS "MAC=FOO" strings.

plugins/main/bridge/bridge.go Show resolved Hide resolved
plugins/main/bridge/bridge_test.go Show resolved Hide resolved
@@ -1967,6 +2010,66 @@ var _ = Describe("bridge Operations", func() {
})
}

It(fmt.Sprintf("[%s] uses an explicit MAC addresses for the container iface (from CNI_ARGS)", ver), func() {

Choose a reason for hiding this comment

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

are all macs acceptable for a veth? if no perhaps it is also worth to add a test that shows what suppose to happen if someone sets a "wrong" mac?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, they are all "valid" here. The kernel will validate and fail the request if the MAC is wrong in some way (all zeros or 1s) and we shouldn't bother trying to reproduce the validation the kernel does I think.

@squeed
Copy link
Member

squeed commented Jun 30, 2021

This looks really good, thanks! I think this is ready to go.

A second set of eyes would help, but the testcases are nice.

By the way, I don't care about argument preference. If you try and specify mac two different ways, then you deserve what happens to you :-)

@dcbw
Copy link
Member

dcbw commented Jun 30, 2021

/lgtm

@dcbw dcbw merged commit f14ff66 into containernetworking:master Jun 30, 2021
@squeed
Copy link
Member

squeed commented Jun 30, 2021

@EdDev EdDev deleted the bridge-mac-specification branch June 30, 2021 16:27
@EdDev
Copy link
Contributor Author

EdDev commented Jun 30, 2021

@EdDev now that this has merged, can you file a PR on https://github.com/containernetworking/cni.dev/ that updates the bridge documentation (https://github.com/containernetworking/cni.dev/blob/main/content/plugins/current/main/bridge.md)

On it first thing tomorrow morning.
Thank you!

@EdDev
Copy link
Contributor Author

EdDev commented Jul 1, 2021

@EdDev now that this has merged, can you file a PR on https://github.com/containernetworking/cni.dev/ that updates the bridge documentation (https://github.com/containernetworking/cni.dev/blob/main/content/plugins/current/main/bridge.md)

On it first thing tomorrow morning.
Thank you!

Done

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.

7 participants