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: afeda4d14bb6f449cb269680cdbd56b26726eedf
 ** Merge commit sha: 8726d6c7a814c3380aacd18250194eae85ababb3
 **/
 platform/linux-generic/include/odp_packet_socket.h |  5 +++++
 platform/linux-generic/pktio/socket.c              | 25 ++++++++++++++++++++++
 platform/linux-generic/pktio/tap.c                 | 13 ++++++++++-
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/platform/linux-generic/include/odp_packet_socket.h 
b/platform/linux-generic/include/odp_packet_socket.h
index 0e61f6f0c..a05629ba5 100644
--- a/platform/linux-generic/include/odp_packet_socket.h
+++ b/platform/linux-generic/include/odp_packet_socket.h
@@ -99,6 +99,11 @@ ethaddrs_equal(unsigned char mac_a[], unsigned char mac_b[])
 int mac_addr_get_fd(int fd, const char *name, unsigned char mac_dst[]);
 
 /**
+ * Write the MAC address for a packet socket
+ */
+int mac_addr_set_fd(int fd, const char *name, const unsigned char mac_dst[]);
+
+/**
  * Read the MTU from a packet socket
  */
 uint32_t mtu_get_fd(int fd, const char *name);
diff --git a/platform/linux-generic/pktio/socket.c 
b/platform/linux-generic/pktio/socket.c
index 0a80035f5..447b02b20 100644
--- a/platform/linux-generic/pktio/socket.c
+++ b/platform/linux-generic/pktio/socket.c
@@ -125,6 +125,31 @@ int mac_addr_get_fd(int fd, const char *name, unsigned 
char mac_dst[])
        return 0;
 }
 
+/**
+ * ODP_PACKET_TAP:
+ */
+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;
+}
+
 /*
  * ODP_PACKET_SOCKET_MMSG:
  * ODP_PACKET_SOCKET_MMAP:
diff --git a/platform/linux-generic/pktio/tap.c 
b/platform/linux-generic/pktio/tap.c
index 2fda0b814..841631d9b 100644
--- a/platform/linux-generic/pktio/tap.c
+++ b/platform/linux-generic/pktio/tap.c
@@ -412,6 +412,16 @@ static int tap_link_status(pktio_entry_t *pktio_entry)
                              pktio_entry->s.name + 4);
 }
 
+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_capability(pktio_entry_t *pktio_entry ODP_UNUSED,
                          odp_pktio_capability_t *capa)
 {
@@ -420,6 +430,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 +454,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