-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Fix error 400 when updating the mac address of a network interface #370
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
Conversation
vmm/src/device_config/net.rs
Outdated
} | ||
|
||
fn push(&mut self, body: NetworkInterfaceBody) -> Result<(), SyncError> { | ||
self.validate_unique_mac(&body.guest_mac)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check is valid for all scenarios (create, update). Why not use this only once right after pub fn put
function before any add/update logic starts happening?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a corner case:
- update scenario (ID stays the same)
- tap device name changes (new device)
- mac address stays the same
This can be addressed either by taking the ID into account in validate_unique_mac
or by calling validate_unique_mac
before every push
/ update
where it's needed. I chose the latter because I didn't want to bring in the ID in a validation function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get it now.
vmm/src/device_config/net.rs
Outdated
} | ||
} | ||
self.if_list.push_back(cfg); | ||
fn add(&mut self, body: NetworkInterfaceBody) -> result::Result<SyncOkStatus, SyncError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rename the add
function to create
given that the outcomes when calling put
are two: Ok(SyncOkStatus::Updated)
and Ok(SyncOkStatus::Created)
respectively. It is confusing when you read the code to see: add, create and push altogether. I would move in this function all the code from the push
function (i.e. try_from_body and adding it to the vector of configs) and delete the push
function alltogether. Inside the update
you would remove the old config, create a new one calling create
and the function would still return Ok(SyncOkStatus::Updated)
. i think this would make the code easier to read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vmm/src/device_config/net.rs
Outdated
assert!(netif_configs.put(netif_body).is_ok()); | ||
assert_eq!(netif_configs.if_list.len(), 1); | ||
|
||
// Try to add another interface with the same MAC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: full stop for cosmetic purposes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vmm/src/device_config/net.rs
Outdated
assert!(netif_configs.put(other_netif_body.clone()).is_err()); | ||
assert_eq!(netif_configs.if_list.len(), 1); | ||
|
||
// Add another interface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: full stop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vmm/src/device_config/net.rs
Outdated
.push(make_netif_cfg(other_netif_body.clone(), "foo")); | ||
assert_eq!(netif_configs.if_list.len(), 2); | ||
|
||
// Try to update with an unavailable name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: full stop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vmm/src/device_config/net.rs
Outdated
assert!(netif_configs.put(other_netif_body.clone()).is_err()); | ||
assert_eq!(netif_configs.if_list.len(), 2); | ||
|
||
// Try to update with an unavailable MAC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: full stop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
FYI this doesn fix the problem that appears when issuing |
Changing the MAC address resulted in error 400 because the inner tap object was already taken. Added support to leave the tap in place and update the other fields, unless the interface's name changes. Fixes #354 Signed-off-by: Alexandra Iordache <[email protected]>
The network interfaces update test case only covered interface name update, which worked because a new tap device was created. See #354 Signed-off-by: Alexandra Iordache <[email protected]>
Updating a network interface via PUT with a new MAC resulted in error 400 because the implementation attempted a second
take()
on the inner (unchanged) tap device.Changes
Vec
instead of aLinkedList
because, when updating the name of an interface, the tap device changes, meaning that the oldNetworkInterfaceConfig
needs to be removed and the new one added in its steadTesting done
Build & unit tests
Integration tests
sudo env PATH=$PATH python3 -m pytest
Manual tests