Signed-off-by: YAMAMOTO Takashi <[email protected]>
---
lib/netdev-bsd.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 53 insertions(+), 7 deletions(-)
diff --git a/lib/netdev-bsd.c b/lib/netdev-bsd.c
index e63ac3f..44fccd7 100644
--- a/lib/netdev-bsd.c
+++ b/lib/netdev-bsd.c
@@ -1507,13 +1507,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);
@@ -1527,6 +1521,58 @@ 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;
+
+ /*
+ * 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 EOPNOTSUPP;
+ }
+ 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(af_link_sock, SIOCGLIFADDR, &req);
+ if (ret == -1) {
+ return errno;
+ }
+ if (!memcmp(&sdl->sdl_data[sdl->sdl_nlen], mac, hwaddr_len)) {
+ 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(af_link_sock, SIOCALIFADDR, &req);
+ if (ret == -1) {
+ return errno;
+ }
+
+ memset(&req, 0, sizeof(req));
+ strncpy(req.iflr_name, netdev_name, sizeof(req.iflr_name));
+ req.addr = oldaddr;
+ ret = ioctl(af_link_sock, SIOCDLIFADDR, &req);
+ if (ret == -1) {
+ return errno;
+ }
+ return 0;
+#else
+#error not implemented
#endif
}
--
1.8.0.1
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev