From b4518e78a0f62921723b44c7f63137839f08ef6c Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 29 Oct 2008 13:46:54 -0700 Subject: [PATCH] New function netdev_set_etheraddr(). --- include/netdev.h | 1 + lib/netdev.c | 29 ++++++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/include/netdev.h b/include/netdev.h index 7c841715a..28a96e44f 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -75,6 +75,7 @@ int netdev_recv(struct netdev *, struct ofpbuf *); void netdev_recv_wait(struct netdev *); int netdev_drain(struct netdev *); int netdev_send(struct netdev *, const struct ofpbuf *); +int netdev_set_etheraddr(struct netdev *, const uint8_t mac[6]); const uint8_t *netdev_get_etheraddr(const struct netdev *); const char *netdev_get_name(const struct netdev *); int netdev_get_mtu(const struct netdev *); diff --git a/lib/netdev.c b/lib/netdev.c index 9bedb694b..746a3e2c0 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -86,6 +86,7 @@ struct netdev { int speed; int mtu; int txqlen; + int hwaddr_family; /* Bitmaps of OFPPF_* that describe features. All bits disabled if * unsupported or unavailable. */ @@ -354,6 +355,7 @@ do_open_netdev(const char *name, int ethertype, int tap_fd, struct in6_addr in6; int mtu; int txqlen; + int hwaddr_family; int error; struct netdev *netdev; @@ -411,10 +413,10 @@ do_open_netdev(const char *name, int ethertype, int tap_fd, name, strerror(errno)); goto error; } - if (ifr.ifr_hwaddr.sa_family != AF_UNSPEC - && ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { + hwaddr_family = ifr.ifr_hwaddr.sa_family; + if (hwaddr_family != AF_UNSPEC && hwaddr_family != ARPHRD_ETHER) { VLOG_WARN("%s device has unknown hardware address family %d", - name, (int) ifr.ifr_hwaddr.sa_family); + name, hwaddr_family); } memcpy(etheraddr, ifr.ifr_hwaddr.sa_data, sizeof etheraddr); @@ -441,6 +443,7 @@ do_open_netdev(const char *name, int ethertype, int tap_fd, netdev->name = xstrdup(name); netdev->ifindex = ifindex; netdev->txqlen = txqlen; + netdev->hwaddr_family = hwaddr_family; netdev->netdev_fd = netdev_fd; netdev->tap_fd = tap_fd < 0 ? netdev_fd : tap_fd; memcpy(netdev->etheraddr, etheraddr, sizeof etheraddr); @@ -630,6 +633,26 @@ netdev_send_wait(struct netdev *netdev) } } +/* Attempts to set 'netdev''s MAC address to 'mac'. Returns 0 if successful, + * otherwise a positive errno value. */ +int +netdev_set_etheraddr(struct netdev *netdev, const uint8_t mac[ETH_ADDR_LEN]) +{ + struct ifreq ifr; + + memset(&ifr, 0, sizeof ifr); + strncpy(ifr.ifr_name, netdev->name, sizeof ifr.ifr_name); + ifr.ifr_hwaddr.sa_family = netdev->hwaddr_family; + memcpy(ifr.ifr_hwaddr.sa_data, mac, ETH_ADDR_LEN); + if (ioctl(netdev->netdev_fd, SIOCSIFHWADDR, &ifr) < 0) { + VLOG_ERR("ioctl(SIOCSIFHWADDR) on %s device failed: %s", + netdev->name, strerror(errno)); + return errno; + } + memcpy(netdev->etheraddr, mac, ETH_ADDR_LEN); + return 0; +} + /* Returns a pointer to 'netdev''s MAC address. The caller must not modify or * free the returned buffer. */ const uint8_t * -- 2.43.0