@@ -137,6 +137,7 @@ typedef struct pktio_if_ops {
int (*promisc_mode_set)(pktio_entry_t *pktio_entry, int enable);
int (*promisc_mode_get)(pktio_entry_t *pktio_entry);
int (*mac_get)(pktio_entry_t *pktio_entry, void *mac_addr);
+ int (*link_status)(pktio_entry_t *pktio_entry);
int (*capability)(pktio_entry_t *pktio_entry,
odp_pktio_capability_t *capa);
int (*input_queues_config)(pktio_entry_t *pktio_entry,
@@ -118,6 +118,11 @@ int promisc_mode_set_fd(int fd, const char *name, int enable);
int promisc_mode_get_fd(int fd, const char *name);
/**
+ * Return link status of a packet socket (up/down)
+ */
+int link_status_fd(int fd, const char *name);
+
+/**
* Get enabled RSS hash protocols of a packet socket
*
* @param fd Socket file descriptor
@@ -821,6 +821,32 @@ int odp_pktio_mac_addr(odp_pktio_t id, void *mac_addr, int addr_size)
return ret;
}
+int odp_pktio_link_status(odp_pktio_t id)
+{
+ pktio_entry_t *entry;
+ int ret = -1;
+
+ entry = get_pktio_entry(id);
+ if (entry == NULL) {
+ ODP_DBG("pktio entry %d does not exist\n", id);
+ return -1;
+ }
+
+ lock_entry(entry);
+
+ if (odp_unlikely(is_free(entry))) {
+ unlock_entry(entry);
+ ODP_DBG("already freed pktio\n");
+ return -1;
+ }
+
+ if (entry->s.ops->link_status)
+ ret = entry->s.ops->link_status(entry);
+ unlock_entry(entry);
+
+ return ret;
+}
+
void odp_pktio_param_init(odp_pktio_param_t *params)
{
memset(params, 0, sizeof(odp_pktio_param_t));
@@ -195,6 +195,23 @@ int promisc_mode_get_fd(int fd, const char *name)
return !!(ifr.ifr_flags & IFF_PROMISC);
}
+int link_status_fd(int fd, const char *name)
+{
+ struct ifreq ifr;
+ int ret;
+
+ snprintf(ifr.ifr_name, IF_NAMESIZE, "%s", name);
+ ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
+ if (ret < 0) {
+ __odp_errno = errno;
+ ODP_DBG("ioctl(SIOCGIFFLAGS): %s: \"%s\".\n", strerror(errno),
+ ifr.ifr_name);
+ return -1;
+ }
+
+ return !!(ifr.ifr_flags & IFF_RUNNING);
+}
+
/**
* Get enabled hash options of a packet socket
*
@@ -767,6 +784,12 @@ static int sock_promisc_mode_get(pktio_entry_t *pktio_entry)
pktio_entry->s.name);
}
+static int sock_link_status(pktio_entry_t *pktio_entry)
+{
+ return link_status_fd(pktio_entry->s.pkt_sock.sockfd,
+ pktio_entry->s.name);
+}
+
const pktio_if_ops_t sock_mmsg_pktio_ops = {
.name = "socket",
.init = NULL,
@@ -781,6 +804,7 @@ const pktio_if_ops_t sock_mmsg_pktio_ops = {
.promisc_mode_set = sock_promisc_mode_set,
.promisc_mode_get = sock_promisc_mode_get,
.mac_get = sock_mac_addr_get,
+ .link_status = sock_link_status,
.capability = NULL,
.input_queues_config = NULL,
.output_queues_config = NULL,
@@ -554,6 +554,12 @@ static int sock_mmap_promisc_mode_get(pktio_entry_t *pktio_entry)
pktio_entry->s.name);
}
+static int sock_mmap_link_status(pktio_entry_t *pktio_entry)
+{
+ return link_status_fd(pktio_entry->s.pkt_sock_mmap.sockfd,
+ pktio_entry->s.name);
+}
+
const pktio_if_ops_t sock_mmap_pktio_ops = {
.name = "socket_mmap",
.init = NULL,
@@ -568,6 +574,7 @@ const pktio_if_ops_t sock_mmap_pktio_ops = {
.promisc_mode_set = sock_mmap_promisc_mode_set,
.promisc_mode_get = sock_mmap_promisc_mode_get,
.mac_get = sock_mmap_mac_addr_get,
+ .link_status = sock_mmap_link_status,
.capability = NULL,
.input_queues_config = NULL,
.output_queues_config = NULL,
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> --- .../linux-generic/include/odp_packet_io_internal.h | 1 + platform/linux-generic/include/odp_packet_socket.h | 5 +++++ platform/linux-generic/odp_packet_io.c | 26 ++++++++++++++++++++++ platform/linux-generic/pktio/socket.c | 24 ++++++++++++++++++++ platform/linux-generic/pktio/socket_mmap.c | 7 ++++++ 5 files changed, 63 insertions(+)