@@ -59,6 +59,29 @@ static int gen_random_mac(unsigned char *mac)
return 0;
}
+static int mac_addr_set_fd(int fd, const char *name,
+ const unsigned char mac_dst[])
+{
+ struct ifreq ethreq;
+ int ret;
+
+ memset(ðreq, 0, sizeof(ethreq));
+ snprintf(ethreq.ifr_name, IF_NAMESIZE, "%s", name);
+
+ ethreq.ifr_hwaddr.sa_family = AF_UNIX;
+ memcpy(ethreq.ifr_hwaddr.sa_data, mac_dst, ETH_ALEN);
+
+ ret = ioctl(fd, SIOCSIFHWADDR, ðreq);
+ if (ret != 0) {
+ __odp_errno = errno;
+ ODP_ERR("ioctl(SIOCSIFHWADDR): %s: \"%s\".\n", strerror(errno),
+ ethreq.ifr_name);
+ return -1;
+ }
+
+ return 0;
+}
+
static int tap_pktio_open(odp_pktio_t id ODP_UNUSED,
pktio_entry_t *pktio_entry,
const char *devname, odp_pool_t pool)
@@ -406,6 +429,16 @@ static int tap_mac_addr_get(pktio_entry_t *pktio_entry, void *mac_addr)
return ETH_ALEN;
}
+static int tap_mac_addr_set(pktio_entry_t *pktio_entry, const void *mac_addr)
+{
+ pkt_tap_t *tap = &pktio_entry->s.pkt_tap;
+
+ memcpy(tap->if_mac, mac_addr, ETH_ALEN);
+
+ return mac_addr_set_fd(tap->fd, (char *)pktio_entry->s.name + 4,
+ tap->if_mac);
+}
+
static int tap_link_status(pktio_entry_t *pktio_entry)
{
return link_status_fd(pktio_entry->s.pkt_tap.skfd,
@@ -420,6 +453,7 @@ static int tap_capability(pktio_entry_t *pktio_entry ODP_UNUSED,
capa->max_input_queues = 1;
capa->max_output_queues = 1;
capa->set_op.op.promisc_mode = 1;
+ capa->set_op.op.mac_addr = 1;
odp_pktio_config_init(&capa->config);
capa->config.pktin.bit.ts_all = 1;
@@ -443,7 +477,7 @@ const pktio_if_ops_t tap_pktio_ops = {
.promisc_mode_set = tap_promisc_mode_set,
.promisc_mode_get = tap_promisc_mode_get,
.mac_get = tap_mac_addr_get,
- .mac_set = NULL,
+ .mac_set = tap_mac_addr_set,
.link_status = tap_link_status,
.capability = tap_capability,
.pktin_ts_res = NULL,