Signed-off-by: YAMAMOTO Takashi <y...@mwd.biglobe.ne.jp> --- 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 dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev