[ovs-dev] [PATCH 15/18] implement set_etheraddr for NetBSD
YAMAMOTO Takashi
yamamoto at valinux.co.jp
Thu Jan 31 10:49:49 UTC 2013
From: YAMAMOTO Takashi <yamt at mwd.biglobe.ne.jp>
Signed-off-by: YAMAMOTO Takashi <yamamoto at valinux.co.jp>
---
lib/netdev-bsd.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 69 insertions(+), 7 deletions(-)
diff --git a/lib/netdev-bsd.c b/lib/netdev-bsd.c
index 76782ec..615a26f 100644
--- a/lib/netdev-bsd.c
+++ b/lib/netdev-bsd.c
@@ -1494,13 +1494,7 @@ static int
set_etheraddr(const char *netdev_name, int hwaddr_family,
int hwaddr_len, const uint8_t mac[ETH_ADDR_LEN])
{
-#if defined(__NetBSD__)
- (void)netdev_name;
- (void)hwaddr_family;
- (void)hwaddr_len;
- (void)mac;
- return ENOTSUP; /* XXX */
-#else
+#if defined(__FreeBSD__)
struct ifreq ifr;
memset(&ifr, 0, sizeof ifr);
@@ -1514,6 +1508,74 @@ set_etheraddr(const char *netdev_name, int hwaddr_family,
return errno;
}
return 0;
+#elif defined(__NetBSD__)
+ struct if_laddrreq req;
+ struct sockaddr_dl *sdl;
+ struct sockaddr_storage oldaddr;
+ int ret;
+ int s;
+
+ /*
+ * get the old address, add new one, and then remove old one.
+ */
+
+ if (hwaddr_len != ETH_ADDR_LEN) {
+ /* just to be safe about sockaddr storage size */
+ return ENOTSUP;
+ }
+ s = socket(AF_LINK, SOCK_DGRAM, 0);
+ if (s == -1) {
+ return errno;
+ }
+ memset(&req, 0, sizeof(req));
+ strncpy(req.iflr_name, netdev_name, sizeof(req.iflr_name));
+ req.addr.ss_len = sizeof(req.addr);
+ req.addr.ss_family = hwaddr_family;
+ sdl = (struct sockaddr_dl *)&req.addr;
+ sdl->sdl_alen = hwaddr_len;
+ ret = ioctl(s, SIOCGLIFADDR, &req);
+ if (ret == -1) {
+ int saved_errno = errno;
+
+ close(s);
+ return saved_errno;
+ }
+ if (!memcmp(&sdl->sdl_data[sdl->sdl_nlen], mac, hwaddr_len)) {
+ close(s);
+ return 0;
+ }
+ oldaddr = req.addr;
+
+ memset(&req, 0, sizeof(req));
+ strncpy(req.iflr_name, netdev_name, sizeof(req.iflr_name));
+ req.flags = IFLR_ACTIVE;
+ sdl = (struct sockaddr_dl *)&req.addr;
+ sdl->sdl_len = offsetof(struct sockaddr_dl, sdl_data) + hwaddr_len;
+ sdl->sdl_alen = hwaddr_len;
+ sdl->sdl_family = hwaddr_family;
+ memcpy(sdl->sdl_data, mac, hwaddr_len);
+ ret = ioctl(s, SIOCALIFADDR, &req);
+ if (ret == -1) {
+ int saved_errno = errno;
+
+ close(s);
+ return saved_errno;
+ }
+
+ memset(&req, 0, sizeof(req));
+ strncpy(req.iflr_name, netdev_name, sizeof(req.iflr_name));
+ req.addr = oldaddr;
+ ret = ioctl(s, SIOCDLIFADDR, &req);
+ if (ret == -1) {
+ int saved_errno = errno;
+
+ close(s);
+ return saved_errno;
+ }
+ close(s);
+ return 0;
+#else
+#error not implemented
#endif
}
--
1.7.12
More information about the dev
mailing list