From: Bogdan Pricope <bogdan.pric...@linaro.org>

Implement MAC address set function and set corresponding
capability flag.

Signed-off-by: Bogdan Pricope <bogdan.pric...@linaro.org>
---
/** Email created from pull request 232 (bogdanPricope:tap_set_mac_pr)
 ** https://github.com/Linaro/odp/pull/232
 ** Patch: https://github.com/Linaro/odp/pull/232.patch
 ** Base sha: edca8cd1e55898826f79383b689c2c4bd2c28b3a
 ** Merge commit sha: 89f18d929052add128b4252f5b17907b9a354ccb
 **/
 platform/linux-generic/pktio/tap.c | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/platform/linux-generic/pktio/tap.c 
b/platform/linux-generic/pktio/tap.c
index 2fda0b814..d8b78f3f8 100644
--- a/platform/linux-generic/pktio/tap.c
+++ b/platform/linux-generic/pktio/tap.c
@@ -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(&ethreq, 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, &ethreq);
+       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,

Reply via email to