Skip to content

Commit

Permalink
macvlan: remove tmp interface when name already used in netns
Browse files Browse the repository at this point in the history
If the interface name is already used in the netns the rename call will
fail and netavark error out. This is correct but before it returns it
should remove the tmp interface otherwise we end up leaking it.

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
  • Loading branch information
Luap99 committed Nov 3, 2022
1 parent 9cb258f commit e6d09ff
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 3 deletions.
16 changes: 13 additions & 3 deletions src/network/macvlan.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{collections::HashMap, net::IpAddr, os::unix::prelude::RawFd};

use log::debug;
use log::{debug, error};
use netlink_packet_route::nlas::link::{InfoData, InfoKind, InfoMacVlan, Nla};
use rand::distributions::{Alphanumeric, DistString};

Expand Down Expand Up @@ -198,12 +198,22 @@ fn setup(
// retry, error could EEXIST again because we pick a random name
continue;
}

let link = netns
.get_link(netlink::LinkID::Name(tmp_name))
.get_link(netlink::LinkID::Name(tmp_name.clone()))
.wrap("get tmp macvlan interface")?;
netns
.set_link_name(link.header.index, if_name.to_string())
.wrap("rename tmp macvlan interface")?;
.wrap("rename tmp macvlan interface")
.map_err(|err| {
// If there is an error here most likely the name in the netns is already used,
// make sure to delete the tmp interface.
if let Err(err) = netns.del_link(netlink::LinkID::ID(link.header.index))
{
error!("failed to delete tmp macvlan link {}: {}", tmp_name, err);
};
err
})?;

// successful run, break out of loop
break;
Expand Down
49 changes: 49 additions & 0 deletions test/300-macvlan.bats
Original file line number Diff line number Diff line change
Expand Up @@ -283,3 +283,52 @@ EOF

run_netavark teardown $(get_container_netns_path) <<<"$config"
}

@test "macvlan same interface name on container" {

read -r -d '\0' config <<EOF
{
"container_id": "someID",
"container_name": "someName",
"networks": {
"podman": {
"static_ips": [
"10.88.0.2"
],
"interface_name": "eth0"
}
},
"network_info": {
"podman": {
"name": "podman",
"id": "2f259bab93aaaaa2542ba43ef33eb990d0999ee1b9924b557b7be53c0b7a1bb9",
"driver": "macvlan",
"network_interface": "dummy0",
"subnets": [
{
"subnet": "10.88.0.0/16",
"gateway": "10.88.0.1"
}
],
"ipv6_enabled": false,
"internal": false,
"dns_enabled": false,
"ipam_options": {
"driver": "host-local"
}
}
}
}\0
EOF

run_in_container_netns ip link add eth0 type dummy

expected_rc=1 run_netavark setup $(get_container_netns_path) <<<"$config"

# make sure the tmp interface is not leaked on the host or netns
run_in_host_netns ip -o link show
assert "${#lines[@]}" == 2 "only two interfaces (lo, dummy0) on the host, the tmp macvlan interface should be gone"

run_in_container_netns ip -o link show
assert "${#lines[@]}" == 2 "only two interfaces (lo, eth0) in the netns, the tmp macvlan interface should be gone"
}

0 comments on commit e6d09ff

Please sign in to comment.