little-dude / netlink

netlink libraries for rust
Other
332 stars 89 forks source link

veth: name and peer name swapped #289

Open Tuetuopay opened 1 year ago

Tuetuopay commented 1 year ago

When creating a veth pair, the name and the peer name are swapped.

The odd thing is the sources actually contain a comment about it being swapped: https://github.com/little-dude/netlink/blob/master/rtnetlink/src/link/add.rs#L568.

I don't know if it's supposed to counter something from the kernel or not, but on the latest library version, with the latest kenel, those are indeed swapped.

Reproduction

  1. Create a netns, e.g. test: ip netns add test
  2. Create a veth peer from the default ns to the test ns. The test NS should have the peer and the default one the regular one.
use std::{fs::File, os::unix::prelude::AsRawFd};

use rtnetlink::{
    new_connection,
    packet::nlas::link::{Info, InfoData, Nla, VethInfo},
};
use tokio::runtime::Builder;

fn main() {
    Builder::new_current_thread().enable_all().build().unwrap().block_on(async_main());
}

async fn async_main() {
    let (worker, rtnl, _) = new_connection().unwrap();
    tokio::spawn(worker);

    let ns = File::open("/var/run/netns/common").unwrap();

    let mut req = rtnl.link().add().veth("name".to_owned(), "peer".to_owned());
    for nla in &mut req.message_mut().nlas {
        if let Nla::Info(infos) = nla {
            for info in infos {
                if let Info::Data(InfoData::Veth(VethInfo::Peer(peer))) = info {
                    peer.nlas.push(Nla::NetNsFd(ns.as_raw_fd()));
                }
            }
        }
    }
    req.execute().await.unwrap();
}
  1. Observe that the default ns contains the link named peer, while the test ns contains the one named name