diff mbox

[PATCHv3,03/10] API: pktio: mac addr functions

Message ID 1417442928-20680-4-git-send-email-maxim.uvarov@linaro.org
State New
Headers show

Commit Message

Maxim Uvarov Dec. 1, 2014, 2:08 p.m. UTC
Define API for mac address change and implement linux-generic version.

Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
---
 platform/linux-generic/include/api/odp_packet_io.h | 25 ++++++++
 platform/linux-generic/include/api/odp_std_types.h |  2 +
 platform/linux-generic/odp_packet_io.c             | 74 ++++++++++++++++++++++
 3 files changed, 101 insertions(+)
diff mbox

Patch

diff --git a/platform/linux-generic/include/api/odp_packet_io.h b/platform/linux-generic/include/api/odp_packet_io.h
index c7d1e40..65adbe5 100644
--- a/platform/linux-generic/include/api/odp_packet_io.h
+++ b/platform/linux-generic/include/api/odp_packet_io.h
@@ -173,6 +173,31 @@  int odp_pktio_promisc_set(odp_pktio_t id, odp_bool_t enable);
 int odp_pktio_promisc_enabled(odp_pktio_t id);
 
 /**
+ * Set the default MAC address of a packet IO interface.
+ *
+ * @param[in] id         ODP packet IO handle.
+ * @param[in] mac_addr   MAC address to be assigned to the interface.
+ * @param[in] addr_size  Size of the address in bytes.
+ *
+ * @return 0 on success, -ERROR on error.
+ */
+int odp_pktio_mac_addr_set(odp_pktio_t id, const unsigned char *mac_addr,
+			   size_t addr_size);
+
+/**
+ * Get the default MAC address of a packet IO interface.
+ *
+ * @param[in]  id         ODP packet IO handle.
+ * @param[out] mac_addr   Storage for MAC address of the packet IO interface.
+ * @param[in]  addr_size  Storage size for the address
+ *
+ * @retval Address size written.
+ * @retval -ERROR on error.
+ */
+ssize_t odp_pktio_mac_addr(odp_pktio_t id, unsigned char *mac_addr,
+			  size_t addr_size);
+
+/**
  * @}
  */
 
diff --git a/platform/linux-generic/include/api/odp_std_types.h b/platform/linux-generic/include/api/odp_std_types.h
index 61255a6..01c0377 100644
--- a/platform/linux-generic/include/api/odp_std_types.h
+++ b/platform/linux-generic/include/api/odp_std_types.h
@@ -26,6 +26,8 @@  extern "C" {
 #include <stdint.h>
 #include <inttypes.h>
 #include <limits.h>
+#include <unistd.h>
+#include <errno.h>
 
 /** Use odp boolean type to have it well-defined and known size,
   * regardless which compiler is used as this facilities interoperability
diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
index ce02965..66be5f5 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -21,6 +21,7 @@ 
 
 #include <string.h>
 #include <sys/ioctl.h>
+#include <linux/if_arp.h>
 
 typedef struct {
 	pktio_entry_t entries[ODP_CONFIG_PKTIO_ENTRIES];
@@ -619,3 +620,76 @@  int odp_pktio_promisc_enabled(odp_pktio_t id)
 	else
 		return 0;
 }
+
+int odp_pktio_mac_addr_set(odp_pktio_t id, const unsigned char *mac_addr,
+		size_t addr_size)
+{
+	pktio_entry_t *entry;
+	int sockfd;
+	struct ifreq ifr;
+	int ret;
+
+	if (addr_size != ETH_ALEN)
+		return -ENOMEM;
+
+	entry = get_entry(id);
+	if (entry == NULL) {
+		ODP_DBG("pktio entry %d does not exist\n", id);
+		return -ENOENT;
+	}
+
+	if (entry->s.pkt_sock_mmap.sockfd > -1)
+		sockfd = entry->s.pkt_sock_mmap.sockfd;
+	else
+		sockfd = entry->s.pkt_sock.sockfd;
+
+	strncpy(ifr.ifr_name, entry->s.name, IFNAMSIZ - 1);
+	ifr.ifr_name[IFNAMSIZ] = 0;
+	memcpy(ifr.ifr_hwaddr.sa_data, mac_addr, addr_size);
+	ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
+
+	ret = ioctl(sockfd, SIOCSIFHWADDR, &ifr);
+	if (ret < 0) {
+		ODP_DBG("ioctl SIOCSIFHWADDR error\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+ssize_t odp_pktio_mac_addr(odp_pktio_t id, unsigned char *mac_addr,
+		       size_t addr_size)
+{
+	pktio_entry_t *entry;
+	int sockfd;
+	struct ifreq ifr;
+	int ret;
+
+	if (addr_size < ETH_ALEN)
+		return -ENOMEM;
+
+	entry = get_entry(id);
+	if (entry == NULL) {
+		ODP_DBG("pktio entry %d does not exist\n", id);
+		return -ENOENT;
+	}
+
+	if (entry->s.pkt_sock_mmap.sockfd > -1)
+		sockfd = entry->s.pkt_sock_mmap.sockfd;
+	else
+		sockfd = entry->s.pkt_sock.sockfd;
+
+	strncpy(ifr.ifr_name, entry->s.name, IFNAMSIZ - 1);
+	ifr.ifr_name[IFNAMSIZ] = 0;
+
+	ret = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
+	if (ret < 0) {
+		ODP_DBG("ioctl SIOCGIFHWADDR error\n");
+		return ret;
+	}
+
+	memcpy(mac_addr, (unsigned char *)ifr.ifr_ifru.ifru_hwaddr.sa_data,
+	       ETH_ALEN);
+
+	return ETH_ALEN;
+}