[dpdk-dev,6/6] net/tap: implement link up and down callbacks

Message ID 1485855778-15496-6-git-send-email-pascal.mazon@6wind.com
State Superseded, archived
Delegated to: Ferruh Yigit
Headers show

Checks

Context Check Description
ci/Intel compilation success Compilation OK
ci/checkpatch success coding style OK

Commit Message

Pascal Mazon Jan. 31, 2017, 9:42 a.m.
Signed-off-by: Pascal Mazon <pascal.mazon@6wind.com>
---
 drivers/net/tap/rte_eth_tap.c | 59 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

Comments

Ferruh Yigit Jan. 31, 2017, 1:21 p.m. | #1
On 1/31/2017 9:42 AM, Pascal Mazon wrote:
> Signed-off-by: Pascal Mazon <pascal.mazon@6wind.com>
> ---
>  drivers/net/tap/rte_eth_tap.c | 59 +++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 59 insertions(+)
> 
> diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
> index 734e3a579219..9b6bbff5fd81 100644
> --- a/drivers/net/tap/rte_eth_tap.c
> +++ b/drivers/net/tap/rte_eth_tap.c
> @@ -405,6 +405,63 @@ tap_link_update(struct rte_eth_dev *dev __rte_unused,
>  	return 0;
>  }
>  
> +static int tap_link_set(struct pmd_internals *pmd, int state)
> +{
> +	struct ifreq ifr;
> +	int err, s;
> +
> +	/*
> +	 * An AF_INET/DGRAM socket is needed for
> +	 * SIOCGIFFLAGS/SIOCSIFFLAGS, using fd won't work.
> +	 */
> +	s = socket(AF_INET, SOCK_DGRAM, 0);
> +	if (s < 0) {
> +		RTE_LOG(ERR, PMD,
> +			"Unable to get a socket to set flags: %s\n",
> +			strerror(errno));
> +		return -1;
> +	}
> +	memset(&ifr, 0, sizeof(ifr));
> +	strncpy(ifr.ifr_name, pmd->name, IFNAMSIZ);

Again how this will behave for multiple queue setup.

Rest looks good.

> +	err = ioctl(s, SIOCGIFFLAGS, &ifr);
> +	if (err < 0) {
> +		RTE_LOG(ERR, PMD, "Unable to get tap netdevice flags: %s\n",
> +			strerror(errno));
> +		close(s);
> +		return -1;
> +	}
<...>
Pascal Mazon Jan. 31, 2017, 2:31 p.m. | #2
On 01/31/2017 02:21 PM, Ferruh Yigit wrote:
> On 1/31/2017 9:42 AM, Pascal Mazon wrote:
>> Signed-off-by: Pascal Mazon <pascal.mazon@6wind.com>
>> ---
>>  drivers/net/tap/rte_eth_tap.c | 59 +++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 59 insertions(+)
>>
>> diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
>> index 734e3a579219..9b6bbff5fd81 100644
>> --- a/drivers/net/tap/rte_eth_tap.c
>> +++ b/drivers/net/tap/rte_eth_tap.c
>> @@ -405,6 +405,63 @@ tap_link_update(struct rte_eth_dev *dev __rte_unused,
>>  	return 0;
>>  }
>>
>> +static int tap_link_set(struct pmd_internals *pmd, int state)
>> +{
>> +	struct ifreq ifr;
>> +	int err, s;
>> +
>> +	/*
>> +	 * An AF_INET/DGRAM socket is needed for
>> +	 * SIOCGIFFLAGS/SIOCSIFFLAGS, using fd won't work.
>> +	 */
>> +	s = socket(AF_INET, SOCK_DGRAM, 0);
>> +	if (s < 0) {
>> +		RTE_LOG(ERR, PMD,
>> +			"Unable to get a socket to set flags: %s\n",
>> +			strerror(errno));
>> +		return -1;
>> +	}
>> +	memset(&ifr, 0, sizeof(ifr));
>> +	strncpy(ifr.ifr_name, pmd->name, IFNAMSIZ);
>
> Again how this will behave for multiple queue setup.

The link status is not related to the number of queues.
As long as there is at least one queue configured (if the last queue is
closed, then the netdevice is effectively deleted entirely), it is
possible to set the link up or down.
With the link down, no queues will be able to receive or send packets.

>
> Rest looks good.
>
>> +	err = ioctl(s, SIOCGIFFLAGS, &ifr);
>> +	if (err < 0) {
>> +		RTE_LOG(ERR, PMD, "Unable to get tap netdevice flags: %s\n",
>> +			strerror(errno));
>> +		close(s);
>> +		return -1;
>> +	}
> <...>
>

Patch

diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 734e3a579219..9b6bbff5fd81 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -405,6 +405,63 @@  tap_link_update(struct rte_eth_dev *dev __rte_unused,
 	return 0;
 }
 
+static int tap_link_set(struct pmd_internals *pmd, int state)
+{
+	struct ifreq ifr;
+	int err, s;
+
+	/*
+	 * An AF_INET/DGRAM socket is needed for
+	 * SIOCGIFFLAGS/SIOCSIFFLAGS, using fd won't work.
+	 */
+	s = socket(AF_INET, SOCK_DGRAM, 0);
+	if (s < 0) {
+		RTE_LOG(ERR, PMD,
+			"Unable to get a socket to set flags: %s\n",
+			strerror(errno));
+		return -1;
+	}
+	memset(&ifr, 0, sizeof(ifr));
+	strncpy(ifr.ifr_name, pmd->name, IFNAMSIZ);
+	err = ioctl(s, SIOCGIFFLAGS, &ifr);
+	if (err < 0) {
+		RTE_LOG(ERR, PMD, "Unable to get tap netdevice flags: %s\n",
+			strerror(errno));
+		close(s);
+		return -1;
+	}
+	if (state == ETH_LINK_UP)
+		ifr.ifr_flags |= IFF_UP | IFF_NOARP;
+	else
+		ifr.ifr_flags &= ~(IFF_UP | IFF_NOARP);
+	err = ioctl(s, SIOCSIFFLAGS, &ifr);
+	if (err < 0) {
+		RTE_LOG(ERR, PMD, "Unable to set flags %s: %s\n",
+			state == ETH_LINK_UP ? "UP" : "DOWN", strerror(errno));
+		close(s);
+		return -1;
+	}
+	close(s);
+
+	return 0;
+}
+
+static int
+tap_link_set_down(struct rte_eth_dev *dev)
+{
+	struct pmd_internals *pmd = dev->data->dev_private;
+
+	return tap_link_set(pmd, ETH_LINK_DOWN);
+}
+
+static int
+tap_link_set_up(struct rte_eth_dev *dev)
+{
+	struct pmd_internals *pmd = dev->data->dev_private;
+
+	return tap_link_set(pmd, ETH_LINK_UP);
+}
+
 static int
 tap_setup_queue(struct rte_eth_dev *dev,
 		struct pmd_internals *internals,
@@ -532,6 +589,8 @@  static const struct eth_dev_ops ops = {
 	.rx_queue_release       = tap_rx_queue_release,
 	.tx_queue_release       = tap_tx_queue_release,
 	.link_update            = tap_link_update,
+	.dev_set_link_up        = tap_link_set_up,
+	.dev_set_link_down      = tap_link_set_down,
 	.stats_get              = tap_stats_get,
 	.stats_reset            = tap_stats_reset,
 };