Set mac addr for tap interface.
(&self, addr: MacAddr)
| 364 | |
| 365 | /// Set mac addr for tap interface. |
| 366 | pub fn set_mac_addr(&self, addr: MacAddr) -> Result<()> { |
| 367 | // Checking if the mac address already matches the desired one |
| 368 | // is useful to avoid making the "set ioctl" in the case where |
| 369 | // the VMM is running without the privilege to do that. |
| 370 | // In practice this comes from a reboot after the configuration |
| 371 | // has been update with the kernel generated address. |
| 372 | if self.get_mac_addr()? == addr { |
| 373 | return Ok(()); |
| 374 | } |
| 375 | |
| 376 | let sock = create_unix_socket().map_err(Error::NetUtil)?; |
| 377 | |
| 378 | let mut ifreq = self.get_ifreq(); |
| 379 | |
| 380 | // SAFETY: ioctl is safe. Called with a valid sock fd, and we check the return. |
| 381 | unsafe { Self::ioctl_with_ref(&sock, libc::SIOCGIFHWADDR as c_ulong, &ifreq)? }; |
| 382 | |
| 383 | // SAFETY: We only access one field of the ifru union |
| 384 | unsafe { |
| 385 | let ifru_hwaddr = &mut ifreq.ifr_ifru.ifru_hwaddr; |
| 386 | for (i, v) in addr.get_bytes().iter().enumerate() { |
| 387 | ifru_hwaddr.sa_data[i] = *v as c_char; |
| 388 | } |
| 389 | } |
| 390 | |
| 391 | // SAFETY: ioctl is safe. Called with a valid sock fd, and we check the return. |
| 392 | unsafe { Self::ioctl_with_ref(&sock, libc::SIOCSIFHWADDR as c_ulong, &ifreq) } |
| 393 | } |
| 394 | |
| 395 | /// Get mac addr for tap interface. |
| 396 | pub fn get_mac_addr(&self) -> Result<MacAddr> { |
no test coverage detected