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