* [PATCHv1 6/7] TAP: tap as an independent module
From: Sainath Grandhi @ 2017-01-06 22:33 UTC (permalink / raw)
To: netdev; +Cc: davem, mahesh, linux-kernel, Sainath Grandhi
In-Reply-To: <1483742009-19184-1-git-send-email-sainath.grandhi@intel.com>
This patch makes tap a separate module for other types of virtual interfaces, for example,
ipvlan to use.
Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
Tested-by: Sainath Grandhi <sainath.grandhi@intel.com>
---
drivers/net/Kconfig | 14 +++
drivers/net/Makefile | 3 +-
drivers/net/macvtap.c | 247 +++++++++++++++++++++++++++++++++++++++++++++
drivers/net/macvtap_main.c | 247 ---------------------------------------------
drivers/net/tap.c | 10 ++
5 files changed, 272 insertions(+), 249 deletions(-)
create mode 100644 drivers/net/macvtap.c
delete mode 100644 drivers/net/macvtap_main.c
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 95c32f2..280380d 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -284,6 +284,20 @@ config TUN
If you don't know what to use this for, you don't need it.
+config TAP
+ tristate "TAP module support for virtual interfaces"
+ ---help---
+ TAP module serves two purposes. This can be used as library of functions
+ for virtual interfaces to implement tap functionality.
+
+ This module also includes character device file and socket operations
+ that can be used by virtual interface implementing tap.
+
+ To compile this driver as a module, choose M here: the module
+ will be called tap.
+
+ If you don't know what to use this for, you don't need it.
+
config TUN_VNET_CROSS_LE
bool "Support for cross-endian vnet headers on little-endian kernels"
default n
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 19b03a9..7dd86ca 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_PHYLIB) += phy/
obj-$(CONFIG_RIONET) += rionet.o
obj-$(CONFIG_NET_TEAM) += team/
obj-$(CONFIG_TUN) += tun.o
+obj-$(CONFIG_TAP) += tap.o
obj-$(CONFIG_VETH) += veth.o
obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
obj-$(CONFIG_VXLAN) += vxlan.o
@@ -29,8 +30,6 @@ obj-$(CONFIG_GTP) += gtp.o
obj-$(CONFIG_NLMON) += nlmon.o
obj-$(CONFIG_NET_VRF) += vrf.o
-macvtap-objs := macvtap_main.o tap.o
-
#
# Networking Drivers
#
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
new file mode 100644
index 0000000..3f047b4
--- /dev/null
+++ b/drivers/net/macvtap.c
@@ -0,0 +1,247 @@
+#include <linux/etherdevice.h>
+#include <linux/if_macvlan.h>
+#include <linux/if_tap.h>
+#include <linux/if_vlan.h>
+#include <linux/interrupt.h>
+#include <linux/nsproxy.h>
+#include <linux/compat.h>
+#include <linux/if_tun.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/cache.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <linux/cdev.h>
+#include <linux/idr.h>
+#include <linux/fs.h>
+#include <linux/uio.h>
+
+#include <net/net_namespace.h>
+#include <net/rtnetlink.h>
+#include <net/sock.h>
+#include <linux/virtio_net.h>
+#include <linux/skb_array.h>
+
+struct macvtap_dev {
+ struct macvlan_dev vlan;
+ struct tap_dev tap;
+};
+
+/*
+ * Variables for dealing with macvtaps device numbers.
+ */
+static dev_t macvtap_major;
+
+static const void *macvtap_net_namespace(struct device *d)
+{
+ struct net_device *dev = to_net_dev(d->parent);
+ return dev_net(dev);
+}
+
+static struct class macvtap_class = {
+ .name = "macvtap",
+ .owner = THIS_MODULE,
+ .ns_type = &net_ns_type_operations,
+ .namespace = macvtap_net_namespace,
+};
+static struct cdev macvtap_cdev;
+
+#define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \
+ NETIF_F_TSO6 | NETIF_F_UFO)
+
+static void macvtap_count_tx_dropped(struct tap_dev *tap)
+{
+ struct macvlan_dev *vlan = (struct macvlan_dev *)container_of(tap, struct macvtap_dev, tap);
+
+ this_cpu_inc(vlan->pcpu_stats->tx_dropped);
+}
+
+static void macvtap_count_rx_dropped(struct tap_dev *tap)
+{
+ struct macvlan_dev *vlan = (struct macvlan_dev *)container_of(tap, struct macvtap_dev, tap);
+
+ macvlan_count_rx(vlan, 0, 0, 0);
+}
+
+static void macvtap_update_features(struct tap_dev *tap,
+ netdev_features_t features)
+{
+ struct macvlan_dev *vlan = (struct macvlan_dev *)container_of(tap, struct macvtap_dev, tap);
+
+ vlan->set_features = features;
+ netdev_update_features(vlan->dev);
+}
+
+static int macvtap_newlink(struct net *src_net,
+ struct net_device *dev,
+ struct nlattr *tb[],
+ struct nlattr *data[])
+{
+ struct macvtap_dev *vlantap = netdev_priv(dev);
+ int err;
+
+ INIT_LIST_HEAD(&vlantap->tap.queue_list);
+
+ /* Since macvlan supports all offloads by default, make
+ * tap support all offloads also.
+ */
+ vlantap->tap.tap_features = TUN_OFFLOADS;
+
+ /* Register callbacks for rx/tx drops accounting and updating
+ * net_device features
+ */
+ vlantap->tap.count_tx_dropped = macvtap_count_tx_dropped;
+ vlantap->tap.count_rx_dropped = macvtap_count_rx_dropped;
+ vlantap->tap.update_features = macvtap_update_features;
+
+ err = netdev_rx_handler_register(dev, tap_handle_frame, &vlantap->tap);
+ if (err)
+ return err;
+
+ /* Don't put anything that may fail after macvlan_common_newlink
+ * because we can't undo what it does.
+ */
+ err = macvlan_common_newlink(src_net, dev, tb, data);
+ if (err) {
+ netdev_rx_handler_unregister(dev);
+ return err;
+ }
+
+ vlantap->tap.dev = vlantap->vlan.dev;
+
+ return 0;
+}
+
+static void macvtap_dellink(struct net_device *dev,
+ struct list_head *head)
+{
+ struct macvtap_dev *vlantap = netdev_priv(dev);
+
+ netdev_rx_handler_unregister(dev);
+ tap_del_queues(&vlantap->tap);
+ macvlan_dellink(dev, head);
+}
+
+static void macvtap_setup(struct net_device *dev)
+{
+ macvlan_common_setup(dev);
+ dev->tx_queue_len = TUN_READQ_SIZE;
+}
+
+static struct rtnl_link_ops macvtap_link_ops __read_mostly = {
+ .kind = "macvtap",
+ .setup = macvtap_setup,
+ .newlink = macvtap_newlink,
+ .dellink = macvtap_dellink,
+ .priv_size = sizeof(struct macvtap_dev),
+};
+
+static int macvtap_device_event(struct notifier_block *unused,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+ struct macvtap_dev *vlantap;
+ struct device *classdev;
+ dev_t devt;
+ int err;
+ char tap_name[IFNAMSIZ];
+
+ if (dev->rtnl_link_ops != &macvtap_link_ops)
+ return NOTIFY_DONE;
+
+ snprintf(tap_name, IFNAMSIZ, "tap%d", dev->ifindex);
+ vlantap = netdev_priv(dev);
+
+ switch (event) {
+ case NETDEV_REGISTER:
+ /* Create the device node here after the network device has
+ * been registered but before register_netdevice has
+ * finished running.
+ */
+ err = tap_get_minor(macvtap_major, &vlantap->tap);
+ if (err)
+ return notifier_from_errno(err);
+
+ devt = MKDEV(MAJOR(macvtap_major), vlantap->tap.minor);
+ classdev = device_create(&macvtap_class, &dev->dev, devt,
+ dev, tap_name);
+ if (IS_ERR(classdev)) {
+ tap_free_minor(macvtap_major, &vlantap->tap);
+ return notifier_from_errno(PTR_ERR(classdev));
+ }
+ err = sysfs_create_link(&dev->dev.kobj, &classdev->kobj,
+ tap_name);
+ if (err)
+ return notifier_from_errno(err);
+ break;
+ case NETDEV_UNREGISTER:
+ /* vlan->minor == 0 if NETDEV_REGISTER above failed */
+ if (vlantap->tap.minor == 0)
+ break;
+ sysfs_remove_link(&dev->dev.kobj, tap_name);
+ devt = MKDEV(MAJOR(macvtap_major), vlantap->tap.minor);
+ device_destroy(&macvtap_class, devt);
+ tap_free_minor(macvtap_major, &vlantap->tap);
+ break;
+ case NETDEV_CHANGE_TX_QUEUE_LEN:
+ if (tap_queue_resize(&vlantap->tap))
+ return NOTIFY_BAD;
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block macvtap_notifier_block __read_mostly = {
+ .notifier_call = macvtap_device_event,
+};
+
+static int macvtap_init(void)
+{
+ int err;
+
+ err = tap_create_cdev(&macvtap_cdev, &macvtap_major, "macvtap");
+
+ if (err)
+ goto out1;
+
+ err = class_register(&macvtap_class);
+ if (err)
+ goto out2;
+
+ err = register_netdevice_notifier(&macvtap_notifier_block);
+ if (err)
+ goto out3;
+
+ err = macvlan_link_register(&macvtap_link_ops);
+ if (err)
+ goto out4;
+
+ return 0;
+
+out4:
+ unregister_netdevice_notifier(&macvtap_notifier_block);
+out3:
+ class_unregister(&macvtap_class);
+out2:
+ cdev_del(&macvtap_cdev);
+out1:
+ return err;
+}
+module_init(macvtap_init);
+
+extern struct idr minor_idr;
+static void macvtap_exit(void)
+{
+ rtnl_link_unregister(&macvtap_link_ops);
+ unregister_netdevice_notifier(&macvtap_notifier_block);
+ class_unregister(&macvtap_class);
+ tap_destroy_cdev(macvtap_major, &macvtap_cdev);
+}
+module_exit(macvtap_exit);
+
+MODULE_ALIAS_RTNL_LINK("macvtap");
+MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/macvtap_main.c b/drivers/net/macvtap_main.c
deleted file mode 100644
index 3f047b4..0000000
--- a/drivers/net/macvtap_main.c
+++ /dev/null
@@ -1,247 +0,0 @@
-#include <linux/etherdevice.h>
-#include <linux/if_macvlan.h>
-#include <linux/if_tap.h>
-#include <linux/if_vlan.h>
-#include <linux/interrupt.h>
-#include <linux/nsproxy.h>
-#include <linux/compat.h>
-#include <linux/if_tun.h>
-#include <linux/module.h>
-#include <linux/skbuff.h>
-#include <linux/cache.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/wait.h>
-#include <linux/cdev.h>
-#include <linux/idr.h>
-#include <linux/fs.h>
-#include <linux/uio.h>
-
-#include <net/net_namespace.h>
-#include <net/rtnetlink.h>
-#include <net/sock.h>
-#include <linux/virtio_net.h>
-#include <linux/skb_array.h>
-
-struct macvtap_dev {
- struct macvlan_dev vlan;
- struct tap_dev tap;
-};
-
-/*
- * Variables for dealing with macvtaps device numbers.
- */
-static dev_t macvtap_major;
-
-static const void *macvtap_net_namespace(struct device *d)
-{
- struct net_device *dev = to_net_dev(d->parent);
- return dev_net(dev);
-}
-
-static struct class macvtap_class = {
- .name = "macvtap",
- .owner = THIS_MODULE,
- .ns_type = &net_ns_type_operations,
- .namespace = macvtap_net_namespace,
-};
-static struct cdev macvtap_cdev;
-
-#define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \
- NETIF_F_TSO6 | NETIF_F_UFO)
-
-static void macvtap_count_tx_dropped(struct tap_dev *tap)
-{
- struct macvlan_dev *vlan = (struct macvlan_dev *)container_of(tap, struct macvtap_dev, tap);
-
- this_cpu_inc(vlan->pcpu_stats->tx_dropped);
-}
-
-static void macvtap_count_rx_dropped(struct tap_dev *tap)
-{
- struct macvlan_dev *vlan = (struct macvlan_dev *)container_of(tap, struct macvtap_dev, tap);
-
- macvlan_count_rx(vlan, 0, 0, 0);
-}
-
-static void macvtap_update_features(struct tap_dev *tap,
- netdev_features_t features)
-{
- struct macvlan_dev *vlan = (struct macvlan_dev *)container_of(tap, struct macvtap_dev, tap);
-
- vlan->set_features = features;
- netdev_update_features(vlan->dev);
-}
-
-static int macvtap_newlink(struct net *src_net,
- struct net_device *dev,
- struct nlattr *tb[],
- struct nlattr *data[])
-{
- struct macvtap_dev *vlantap = netdev_priv(dev);
- int err;
-
- INIT_LIST_HEAD(&vlantap->tap.queue_list);
-
- /* Since macvlan supports all offloads by default, make
- * tap support all offloads also.
- */
- vlantap->tap.tap_features = TUN_OFFLOADS;
-
- /* Register callbacks for rx/tx drops accounting and updating
- * net_device features
- */
- vlantap->tap.count_tx_dropped = macvtap_count_tx_dropped;
- vlantap->tap.count_rx_dropped = macvtap_count_rx_dropped;
- vlantap->tap.update_features = macvtap_update_features;
-
- err = netdev_rx_handler_register(dev, tap_handle_frame, &vlantap->tap);
- if (err)
- return err;
-
- /* Don't put anything that may fail after macvlan_common_newlink
- * because we can't undo what it does.
- */
- err = macvlan_common_newlink(src_net, dev, tb, data);
- if (err) {
- netdev_rx_handler_unregister(dev);
- return err;
- }
-
- vlantap->tap.dev = vlantap->vlan.dev;
-
- return 0;
-}
-
-static void macvtap_dellink(struct net_device *dev,
- struct list_head *head)
-{
- struct macvtap_dev *vlantap = netdev_priv(dev);
-
- netdev_rx_handler_unregister(dev);
- tap_del_queues(&vlantap->tap);
- macvlan_dellink(dev, head);
-}
-
-static void macvtap_setup(struct net_device *dev)
-{
- macvlan_common_setup(dev);
- dev->tx_queue_len = TUN_READQ_SIZE;
-}
-
-static struct rtnl_link_ops macvtap_link_ops __read_mostly = {
- .kind = "macvtap",
- .setup = macvtap_setup,
- .newlink = macvtap_newlink,
- .dellink = macvtap_dellink,
- .priv_size = sizeof(struct macvtap_dev),
-};
-
-static int macvtap_device_event(struct notifier_block *unused,
- unsigned long event, void *ptr)
-{
- struct net_device *dev = netdev_notifier_info_to_dev(ptr);
- struct macvtap_dev *vlantap;
- struct device *classdev;
- dev_t devt;
- int err;
- char tap_name[IFNAMSIZ];
-
- if (dev->rtnl_link_ops != &macvtap_link_ops)
- return NOTIFY_DONE;
-
- snprintf(tap_name, IFNAMSIZ, "tap%d", dev->ifindex);
- vlantap = netdev_priv(dev);
-
- switch (event) {
- case NETDEV_REGISTER:
- /* Create the device node here after the network device has
- * been registered but before register_netdevice has
- * finished running.
- */
- err = tap_get_minor(macvtap_major, &vlantap->tap);
- if (err)
- return notifier_from_errno(err);
-
- devt = MKDEV(MAJOR(macvtap_major), vlantap->tap.minor);
- classdev = device_create(&macvtap_class, &dev->dev, devt,
- dev, tap_name);
- if (IS_ERR(classdev)) {
- tap_free_minor(macvtap_major, &vlantap->tap);
- return notifier_from_errno(PTR_ERR(classdev));
- }
- err = sysfs_create_link(&dev->dev.kobj, &classdev->kobj,
- tap_name);
- if (err)
- return notifier_from_errno(err);
- break;
- case NETDEV_UNREGISTER:
- /* vlan->minor == 0 if NETDEV_REGISTER above failed */
- if (vlantap->tap.minor == 0)
- break;
- sysfs_remove_link(&dev->dev.kobj, tap_name);
- devt = MKDEV(MAJOR(macvtap_major), vlantap->tap.minor);
- device_destroy(&macvtap_class, devt);
- tap_free_minor(macvtap_major, &vlantap->tap);
- break;
- case NETDEV_CHANGE_TX_QUEUE_LEN:
- if (tap_queue_resize(&vlantap->tap))
- return NOTIFY_BAD;
- break;
- }
-
- return NOTIFY_DONE;
-}
-
-static struct notifier_block macvtap_notifier_block __read_mostly = {
- .notifier_call = macvtap_device_event,
-};
-
-static int macvtap_init(void)
-{
- int err;
-
- err = tap_create_cdev(&macvtap_cdev, &macvtap_major, "macvtap");
-
- if (err)
- goto out1;
-
- err = class_register(&macvtap_class);
- if (err)
- goto out2;
-
- err = register_netdevice_notifier(&macvtap_notifier_block);
- if (err)
- goto out3;
-
- err = macvlan_link_register(&macvtap_link_ops);
- if (err)
- goto out4;
-
- return 0;
-
-out4:
- unregister_netdevice_notifier(&macvtap_notifier_block);
-out3:
- class_unregister(&macvtap_class);
-out2:
- cdev_del(&macvtap_cdev);
-out1:
- return err;
-}
-module_init(macvtap_init);
-
-extern struct idr minor_idr;
-static void macvtap_exit(void)
-{
- rtnl_link_unregister(&macvtap_link_ops);
- unregister_netdevice_notifier(&macvtap_notifier_block);
- class_unregister(&macvtap_class);
- tap_destroy_cdev(macvtap_major, &macvtap_cdev);
-}
-module_exit(macvtap_exit);
-
-MODULE_ALIAS_RTNL_LINK("macvtap");
-MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/tap.c b/drivers/net/tap.c
index 1d5bcf3..ee0d49a 100644
--- a/drivers/net/tap.c
+++ b/drivers/net/tap.c
@@ -311,6 +311,7 @@ void tap_del_queues(struct tap_dev *tap)
/* guarantee that any future tap_set_queue will fail */
tap->numvtaps = MAX_TAP_QUEUES;
}
+EXPORT_SYMBOL_GPL(tap_del_queues);
rx_handler_result_t tap_handle_frame(struct sk_buff **pskb)
{
@@ -388,6 +389,7 @@ rx_handler_result_t tap_handle_frame(struct sk_buff **pskb)
kfree_skb(skb);
return RX_HANDLER_CONSUMED;
}
+EXPORT_SYMBOL_GPL(tap_handle_frame);
int tap_get_minor(dev_t major, struct tap_dev *tap)
{
@@ -416,6 +418,7 @@ int tap_get_minor(dev_t major, struct tap_dev *tap)
mutex_unlock(&tap_major->minor_lock);
return retval < 0 ? retval : 0;
}
+EXPORT_SYMBOL_GPL(tap_get_minor);
void tap_free_minor(dev_t major, struct tap_dev *tap)
{
@@ -439,6 +442,7 @@ void tap_free_minor(dev_t major, struct tap_dev *tap)
}
mutex_unlock(&tap_major->minor_lock);
}
+EXPORT_SYMBOL_GPL(tap_free_minor);
static struct tap_dev *dev_get_by_tap_file(int major, int minor)
{
@@ -1201,6 +1205,7 @@ int tap_queue_resize(struct tap_dev *tap)
kfree(arrays);
return ret;
}
+EXPORT_SYMBOL_GPL(tap_queue_resize);
static int tap_list_add(dev_t major, const char *device_name)
{
@@ -1244,6 +1249,7 @@ int tap_create_cdev(struct cdev *tap_cdev,
out1:
return err;
}
+EXPORT_SYMBOL_GPL(tap_create_cdev);
void tap_destroy_cdev(dev_t major, struct cdev *tap_cdev)
{
@@ -1264,3 +1270,7 @@ void tap_destroy_cdev(dev_t major, struct cdev *tap_cdev)
unregister_chrdev_region(major, TAP_NUM_DEVS);
idr_destroy(&tap_major->minor_idr);
}
+EXPORT_SYMBOL_GPL(tap_destroy_cdev);
+
+MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>");
+MODULE_LICENSE("GPL");
--
2.7.4
^ permalink raw reply related
* [PATCHv1 7/7] IPVTAP: IP-VLAN based tap driver
From: Sainath Grandhi @ 2017-01-06 22:33 UTC (permalink / raw)
To: netdev; +Cc: davem, mahesh, linux-kernel, Sainath Grandhi
In-Reply-To: <1483742009-19184-1-git-send-email-sainath.grandhi@intel.com>
This patch adds a tap character device driver that is based on the
IP-VLAN network interface, called ipvtap. An ipvtap device can be created
in the same way as an ipvlan device, using 'type ipvtap', and then accessed
using the tap user space interface.
Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
Tested-by: Sainath Grandhi <sainath.grandhi@intel.com>
---
drivers/net/Kconfig | 12 ++
drivers/net/Makefile | 1 +
drivers/net/ipvlan/Makefile | 1 +
drivers/net/ipvlan/ipvlan.h | 7 ++
drivers/net/ipvlan/ipvlan_core.c | 5 +-
drivers/net/ipvlan/ipvlan_main.c | 37 +++---
drivers/net/ipvlan/ipvtap.c | 238 +++++++++++++++++++++++++++++++++++++++
7 files changed, 282 insertions(+), 19 deletions(-)
create mode 100644 drivers/net/ipvlan/ipvtap.c
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 280380d..ddfb30a 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -165,6 +165,18 @@ config IPVLAN
To compile this driver as a module, choose M here: the module
will be called ipvlan.
+config IPVTAP
+ tristate "IP-VLAN based tap driver"
+ depends on IPVLAN
+ depends on INET
+ help
+ This adds a specialized tap character device driver that is based
+ on the IP-VLAN network interface, called ipvtap. An ipvtap device
+ can be added in the same way as a ipvlan device, using 'type
+ ipvtap', and then be accessed through the tap user space interface.
+
+ To compile this driver as a module, choose M here: the module
+ will be called macvtap.
config VXLAN
tristate "Virtual eXtensible Local Area Network (VXLAN)"
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 7dd86ca..98ed4d9 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -7,6 +7,7 @@
#
obj-$(CONFIG_BONDING) += bonding/
obj-$(CONFIG_IPVLAN) += ipvlan/
+obj-$(CONFIG_IPVTAP) += ipvlan/
obj-$(CONFIG_DUMMY) += dummy.o
obj-$(CONFIG_EQUALIZER) += eql.o
obj-$(CONFIG_IFB) += ifb.o
diff --git a/drivers/net/ipvlan/Makefile b/drivers/net/ipvlan/Makefile
index df79910..8a2c64d 100644
--- a/drivers/net/ipvlan/Makefile
+++ b/drivers/net/ipvlan/Makefile
@@ -3,5 +3,6 @@
#
obj-$(CONFIG_IPVLAN) += ipvlan.o
+obj-$(CONFIG_IPVTAP) += ipvtap.o
ipvlan-objs := ipvlan_core.o ipvlan_main.o
diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h
index dbfbb33..4362d88 100644
--- a/drivers/net/ipvlan/ipvlan.h
+++ b/drivers/net/ipvlan/ipvlan.h
@@ -133,4 +133,11 @@ struct sk_buff *ipvlan_l3_rcv(struct net_device *dev, struct sk_buff *skb,
u16 proto);
unsigned int ipvlan_nf_input(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state);
+void ipvlan_count_rx(const struct ipvl_dev *ipvlan,
+ unsigned int len, bool success, bool mcast);
+int ipvlan_link_new(struct net *src_net, struct net_device *dev,
+ struct nlattr *tb[], struct nlattr *data[]);
+void ipvlan_link_delete(struct net_device *dev, struct list_head *head);
+void ipvlan_link_setup(struct net_device *dev);
+int ipvlan_link_register(struct rtnl_link_ops *ops);
#endif /* __IPVLAN_H */
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
index 83ce74a..9af16ab 100644
--- a/drivers/net/ipvlan/ipvlan_core.c
+++ b/drivers/net/ipvlan/ipvlan_core.c
@@ -16,8 +16,8 @@ void ipvlan_init_secret(void)
net_get_random_once(&ipvlan_jhash_secret, sizeof(ipvlan_jhash_secret));
}
-static void ipvlan_count_rx(const struct ipvl_dev *ipvlan,
- unsigned int len, bool success, bool mcast)
+void ipvlan_count_rx(const struct ipvl_dev *ipvlan,
+ unsigned int len, bool success, bool mcast)
{
if (!ipvlan)
return;
@@ -36,6 +36,7 @@ static void ipvlan_count_rx(const struct ipvl_dev *ipvlan,
this_cpu_inc(ipvlan->pcpu_stats->rx_errs);
}
}
+EXPORT_SYMBOL_GPL(ipvlan_count_rx);
static u8 ipvlan_get_v6_hash(const void *iaddr)
{
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index 8b0f993..666a05d 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -13,14 +13,14 @@ static u32 ipvl_nf_hook_refcnt = 0;
static struct nf_hook_ops ipvl_nfops[] __read_mostly = {
{
- .hook = ipvlan_nf_input,
- .pf = NFPROTO_IPV4,
+ .hook = ipvlan_nf_input,
+ .pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_IN,
.priority = INT_MAX,
},
{
- .hook = ipvlan_nf_input,
- .pf = NFPROTO_IPV6,
+ .hook = ipvlan_nf_input,
+ .pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN,
.priority = INT_MAX,
},
@@ -398,7 +398,7 @@ static int ipvlan_hard_header(struct sk_buff *skb, struct net_device *dev,
}
static const struct header_ops ipvlan_header_ops = {
- .create = ipvlan_hard_header,
+ .create = ipvlan_hard_header,
.parse = eth_header_parse,
.cache = eth_header_cache,
.cache_update = eth_header_cache_update,
@@ -494,8 +494,8 @@ static int ipvlan_nl_fillinfo(struct sk_buff *skb,
return ret;
}
-static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
- struct nlattr *tb[], struct nlattr *data[])
+int ipvlan_link_new(struct net *src_net, struct net_device *dev,
+ struct nlattr *tb[], struct nlattr *data[])
{
struct ipvl_dev *ipvlan = netdev_priv(dev);
struct ipvl_port *port;
@@ -567,8 +567,9 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
ipvlan_port_destroy(phy_dev);
return err;
}
+EXPORT_SYMBOL_GPL(ipvlan_link_new);
-static void ipvlan_link_delete(struct net_device *dev, struct list_head *head)
+void ipvlan_link_delete(struct net_device *dev, struct list_head *head)
{
struct ipvl_dev *ipvlan = netdev_priv(dev);
struct ipvl_addr *addr, *next;
@@ -583,8 +584,9 @@ static void ipvlan_link_delete(struct net_device *dev, struct list_head *head)
unregister_netdevice_queue(dev, head);
netdev_upper_dev_unlink(ipvlan->phy_dev, dev);
}
+EXPORT_SYMBOL_GPL(ipvlan_link_delete);
-static void ipvlan_link_setup(struct net_device *dev)
+void ipvlan_link_setup(struct net_device *dev)
{
ether_setup(dev);
@@ -595,6 +597,7 @@ static void ipvlan_link_setup(struct net_device *dev)
dev->header_ops = &ipvlan_header_ops;
dev->ethtool_ops = &ipvlan_ethtool_ops;
}
+EXPORT_SYMBOL_GPL(ipvlan_link_setup);
static const struct nla_policy ipvlan_nl_policy[IFLA_IPVLAN_MAX + 1] =
{
@@ -605,22 +608,22 @@ static struct rtnl_link_ops ipvlan_link_ops = {
.kind = "ipvlan",
.priv_size = sizeof(struct ipvl_dev),
- .get_size = ipvlan_nl_getsize,
- .policy = ipvlan_nl_policy,
- .validate = ipvlan_nl_validate,
- .fill_info = ipvlan_nl_fillinfo,
- .changelink = ipvlan_nl_changelink,
- .maxtype = IFLA_IPVLAN_MAX,
-
.setup = ipvlan_link_setup,
.newlink = ipvlan_link_new,
.dellink = ipvlan_link_delete,
};
-static int ipvlan_link_register(struct rtnl_link_ops *ops)
+int ipvlan_link_register(struct rtnl_link_ops *ops)
{
+ ops->get_size = ipvlan_nl_getsize;
+ ops->policy = ipvlan_nl_policy;
+ ops->validate = ipvlan_nl_validate;
+ ops->fill_info = ipvlan_nl_fillinfo;
+ ops->changelink = ipvlan_nl_changelink;
+ ops->maxtype = IFLA_IPVLAN_MAX;
return rtnl_link_register(ops);
}
+EXPORT_SYMBOL_GPL(ipvlan_link_register);
static int ipvlan_device_event(struct notifier_block *unused,
unsigned long event, void *ptr)
diff --git a/drivers/net/ipvlan/ipvtap.c b/drivers/net/ipvlan/ipvtap.c
new file mode 100644
index 0000000..0422cdf
--- /dev/null
+++ b/drivers/net/ipvlan/ipvtap.c
@@ -0,0 +1,238 @@
+#include <linux/etherdevice.h>
+#include "ipvlan.h"
+#include <linux/if_vlan.h>
+#include <linux/if_tap.h>
+#include <linux/interrupt.h>
+#include <linux/nsproxy.h>
+#include <linux/compat.h>
+#include <linux/if_tun.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/cache.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <linux/cdev.h>
+#include <linux/idr.h>
+#include <linux/fs.h>
+#include <linux/uio.h>
+
+#include <net/net_namespace.h>
+#include <net/rtnetlink.h>
+#include <net/sock.h>
+#include <linux/virtio_net.h>
+
+#define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \
+ NETIF_F_TSO6 | NETIF_F_UFO)
+
+static dev_t ipvtap_major;
+static struct cdev ipvtap_cdev;
+
+static const void *ipvtap_net_namespace(struct device *d)
+{
+ struct net_device *dev = to_net_dev(d->parent);
+ return dev_net(dev);
+}
+
+static struct class ipvtap_class = {
+ .name = "ipvtap",
+ .owner = THIS_MODULE,
+ .ns_type = &net_ns_type_operations,
+ .namespace = ipvtap_net_namespace,
+};
+
+struct ipvtap_dev {
+ struct ipvl_dev vlan;
+ struct tap_dev tap;
+};
+
+static void ipvtap_count_tx_dropped(struct tap_dev *tap)
+{
+ struct ipvl_dev *vlan = (struct ipvl_dev *)container_of(tap, struct ipvtap_dev, tap);
+
+ this_cpu_inc(vlan->pcpu_stats->tx_drps);
+}
+
+static void ipvtap_count_rx_dropped(struct tap_dev *tap)
+{
+ struct ipvl_dev *vlan = (struct ipvl_dev *)container_of(tap, struct ipvtap_dev, tap);
+
+ ipvlan_count_rx(vlan, 0, 0, 0);
+}
+
+static void ipvtap_update_features(struct tap_dev *tap,
+ netdev_features_t features)
+{
+ struct ipvl_dev *vlan = (struct ipvl_dev *)container_of(tap, struct ipvtap_dev, tap);
+
+ vlan->sfeatures = features;
+ netdev_update_features(vlan->dev);
+}
+
+static int ipvtap_newlink(struct net *src_net,
+ struct net_device *dev,
+ struct nlattr *tb[],
+ struct nlattr *data[])
+{
+ struct ipvtap_dev *vlantap = netdev_priv(dev);
+ int err;
+
+ INIT_LIST_HEAD(&vlantap->tap.queue_list);
+
+ /* Since macvlan supports all offloads by default, make
+ * tap support all offloads also.
+ */
+ vlantap->tap.tap_features = TUN_OFFLOADS;
+ vlantap->tap.count_tx_dropped = ipvtap_count_tx_dropped;
+ vlantap->tap.update_features = ipvtap_update_features;
+ vlantap->tap.count_rx_dropped = ipvtap_count_rx_dropped;
+
+ err = netdev_rx_handler_register(dev, tap_handle_frame, &vlantap->tap);
+ if (err)
+ return err;
+
+ /* Don't put anything that may fail after macvlan_common_newlink
+ * because we can't undo what it does.
+ */
+ err = ipvlan_link_new(src_net, dev, tb, data);
+ if (err) {
+ netdev_rx_handler_unregister(dev);
+ return err;
+ }
+
+ vlantap->tap.dev = vlantap->vlan.dev;
+
+ return err;
+}
+
+static void ipvtap_dellink(struct net_device *dev,
+ struct list_head *head)
+{
+ struct ipvtap_dev *vlan = netdev_priv(dev);
+
+ netdev_rx_handler_unregister(dev);
+ tap_del_queues(&vlan->tap);
+ ipvlan_link_delete(dev, head);
+}
+
+static void ipvtap_setup(struct net_device *dev)
+{
+ ipvlan_link_setup(dev);
+ dev->tx_queue_len = TUN_READQ_SIZE;
+ dev->priv_flags &= ~IFF_NO_QUEUE;
+}
+
+static struct rtnl_link_ops ipvtap_link_ops __read_mostly = {
+ .kind = "ipvtap",
+ .setup = ipvtap_setup,
+ .newlink = ipvtap_newlink,
+ .dellink = ipvtap_dellink,
+ .priv_size = sizeof(struct ipvtap_dev),
+};
+
+static int ipvtap_device_event(struct notifier_block *unused,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+ struct ipvtap_dev *vlantap;
+ struct device *classdev;
+ dev_t devt;
+ int err;
+ char tap_name[IFNAMSIZ];
+
+ if (dev->rtnl_link_ops != &ipvtap_link_ops)
+ return NOTIFY_DONE;
+
+ snprintf(tap_name, IFNAMSIZ, "tap%d", dev->ifindex);
+ vlantap = netdev_priv(dev);
+
+ switch (event) {
+ case NETDEV_REGISTER:
+ /* Create the device node here after the network device has
+ * been registered but before register_netdevice has
+ * finished running.
+ */
+ err = tap_get_minor(ipvtap_major, &vlantap->tap);
+ if (err)
+ return notifier_from_errno(err);
+
+ devt = MKDEV(MAJOR(ipvtap_major), vlantap->tap.minor);
+ classdev = device_create(&ipvtap_class, &dev->dev, devt,
+ dev, tap_name);
+ if (IS_ERR(classdev)) {
+ tap_free_minor(ipvtap_major, &vlantap->tap);
+ return notifier_from_errno(PTR_ERR(classdev));
+ }
+ err = sysfs_create_link(&dev->dev.kobj, &classdev->kobj,
+ tap_name);
+ if (err)
+ return notifier_from_errno(err);
+ break;
+ case NETDEV_UNREGISTER:
+ /* vlan->minor == 0 if NETDEV_REGISTER above failed */
+ if (vlantap->tap.minor == 0)
+ break;
+ sysfs_remove_link(&dev->dev.kobj, tap_name);
+ devt = MKDEV(MAJOR(ipvtap_major), vlantap->tap.minor);
+ device_destroy(&ipvtap_class, devt);
+ tap_free_minor(ipvtap_major, &vlantap->tap);
+ break;
+ case NETDEV_CHANGE_TX_QUEUE_LEN:
+ if (tap_queue_resize(&vlantap->tap))
+ return NOTIFY_BAD;
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block ipvtap_notifier_block __read_mostly = {
+ .notifier_call = ipvtap_device_event,
+};
+
+static int ipvtap_init(void)
+{
+ int err;
+
+ err = tap_create_cdev(&ipvtap_cdev, &ipvtap_major, "ipvtap");
+
+ if (err)
+ goto out1;
+
+ err = class_register(&ipvtap_class);
+ if (err)
+ goto out2;
+
+ err = register_netdevice_notifier(&ipvtap_notifier_block);
+ if (err)
+ goto out3;
+
+ err = ipvlan_link_register(&ipvtap_link_ops);
+ if (err)
+ goto out4;
+
+ return 0;
+
+out4:
+ unregister_netdevice_notifier(&ipvtap_notifier_block);
+out3:
+ class_unregister(&ipvtap_class);
+out2:
+ cdev_del(&ipvtap_cdev);
+out1:
+ return err;
+}
+module_init(ipvtap_init);
+
+static void ipvtap_exit(void)
+{
+ rtnl_link_unregister(&ipvtap_link_ops);
+ unregister_netdevice_notifier(&ipvtap_notifier_block);
+ class_unregister(&ipvtap_class);
+ tap_destroy_cdev(ipvtap_major, &ipvtap_cdev);
+}
+module_exit(ipvtap_exit);
+MODULE_ALIAS_RTNL_LINK("ipvtap");
+MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>");
+MODULE_LICENSE("GPL");
--
2.7.4
^ permalink raw reply related
* [PATCHv1 2/7] TAP: Renaming tap related APIs, data structures, macros
From: Sainath Grandhi @ 2017-01-06 22:33 UTC (permalink / raw)
To: netdev; +Cc: davem, mahesh, linux-kernel, Sainath Grandhi
In-Reply-To: <1483742009-19184-1-git-send-email-sainath.grandhi@intel.com>
Renaming tap related APIs, data structures and macros in tap.c from macvtap_.* to tap_.*
Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
Tested-by: Sainath Grandhi <sainath.grandhi@intel.com>
---
drivers/net/macvtap_main.c | 18 +--
drivers/net/tap.c | 332 ++++++++++++++++++++++-----------------------
drivers/vhost/net.c | 3 +-
include/linux/if_macvlan.h | 4 +-
include/linux/if_macvtap.h | 10 --
include/linux/if_tap.h | 11 ++
6 files changed, 190 insertions(+), 188 deletions(-)
delete mode 100644 include/linux/if_macvtap.h
create mode 100644 include/linux/if_tap.h
diff --git a/drivers/net/macvtap_main.c b/drivers/net/macvtap_main.c
index 96ffa60..548f339 100644
--- a/drivers/net/macvtap_main.c
+++ b/drivers/net/macvtap_main.c
@@ -1,6 +1,6 @@
#include <linux/etherdevice.h>
#include <linux/if_macvlan.h>
-#include <linux/if_macvtap.h>
+#include <linux/if_tap.h>
#include <linux/if_vlan.h>
#include <linux/interrupt.h>
#include <linux/nsproxy.h>
@@ -62,7 +62,7 @@ static int macvtap_newlink(struct net *src_net,
*/
vlan->tap_features = TUN_OFFLOADS;
- err = netdev_rx_handler_register(dev, macvtap_handle_frame, vlan);
+ err = netdev_rx_handler_register(dev, tap_handle_frame, vlan);
if (err)
return err;
@@ -82,7 +82,7 @@ static void macvtap_dellink(struct net_device *dev,
struct list_head *head)
{
netdev_rx_handler_unregister(dev);
- macvtap_del_queues(dev);
+ tap_del_queues(dev);
macvlan_dellink(dev, head);
}
@@ -121,7 +121,7 @@ static int macvtap_device_event(struct notifier_block *unused,
* been registered but before register_netdevice has
* finished running.
*/
- err = macvtap_get_minor(vlan);
+ err = tap_get_minor(vlan);
if (err)
return notifier_from_errno(err);
@@ -129,7 +129,7 @@ static int macvtap_device_event(struct notifier_block *unused,
classdev = device_create(&macvtap_class, &dev->dev, devt,
dev, tap_name);
if (IS_ERR(classdev)) {
- macvtap_free_minor(vlan);
+ tap_free_minor(vlan);
return notifier_from_errno(PTR_ERR(classdev));
}
err = sysfs_create_link(&dev->dev.kobj, &classdev->kobj,
@@ -144,10 +144,10 @@ static int macvtap_device_event(struct notifier_block *unused,
sysfs_remove_link(&dev->dev.kobj, tap_name);
devt = MKDEV(MAJOR(macvtap_major), vlan->minor);
device_destroy(&macvtap_class, devt);
- macvtap_free_minor(vlan);
+ tap_free_minor(vlan);
break;
case NETDEV_CHANGE_TX_QUEUE_LEN:
- if (macvtap_queue_resize(vlan))
+ if (tap_queue_resize(vlan))
return NOTIFY_BAD;
break;
}
@@ -159,7 +159,7 @@ static struct notifier_block macvtap_notifier_block __read_mostly = {
.notifier_call = macvtap_device_event,
};
-extern struct file_operations macvtap_fops;
+extern struct file_operations tap_fops;
static int macvtap_init(void)
{
int err;
@@ -169,7 +169,7 @@ static int macvtap_init(void)
if (err)
goto out1;
- cdev_init(&macvtap_cdev, &macvtap_fops);
+ cdev_init(&macvtap_cdev, &tap_fops);
err = cdev_add(&macvtap_cdev, macvtap_major, MACVTAP_NUM_DEVS);
if (err)
goto out2;
diff --git a/drivers/net/tap.c b/drivers/net/tap.c
index 8f12a39..d0807c2 100644
--- a/drivers/net/tap.c
+++ b/drivers/net/tap.c
@@ -24,16 +24,16 @@
#include <linux/skb_array.h>
/*
- * A macvtap queue is the central object of this driver, it connects
+ * A tap queue is the central object of this driver, it connects
* an open character device to a macvlan interface. There can be
* multiple queues on one interface, which map back to queues
* implemented in hardware on the underlying device.
*
- * macvtap_proto is used to allocate queues through the sock allocation
+ * tap_proto is used to allocate queues through the sock allocation
* mechanism.
*
*/
-struct macvtap_queue {
+struct tap_queue {
struct sock sk;
struct socket sock;
struct socket_wq wq;
@@ -47,21 +47,21 @@ struct macvtap_queue {
struct skb_array skb_array;
};
-#define MACVTAP_FEATURES (IFF_VNET_HDR | IFF_MULTI_QUEUE)
+#define TAP_IFFEATURES (IFF_VNET_HDR | IFF_MULTI_QUEUE)
-#define MACVTAP_VNET_LE 0x80000000
-#define MACVTAP_VNET_BE 0x40000000
+#define TAP_VNET_LE 0x80000000
+#define TAP_VNET_BE 0x40000000
#ifdef CONFIG_TUN_VNET_CROSS_LE
-static inline bool macvtap_legacy_is_little_endian(struct macvtap_queue *q)
+static inline bool tap_legacy_is_little_endian(struct tap_queue *q)
{
- return q->flags & MACVTAP_VNET_BE ? false :
+ return q->flags & TAP_VNET_BE ? false :
virtio_legacy_is_little_endian();
}
-static long macvtap_get_vnet_be(struct macvtap_queue *q, int __user *sp)
+static long tap_get_vnet_be(struct tap_queue *q, int __user *sp)
{
- int s = !!(q->flags & MACVTAP_VNET_BE);
+ int s = !!(q->flags & TAP_VNET_BE);
if (put_user(s, sp))
return -EFAULT;
@@ -69,7 +69,7 @@ static long macvtap_get_vnet_be(struct macvtap_queue *q, int __user *sp)
return 0;
}
-static long macvtap_set_vnet_be(struct macvtap_queue *q, int __user *sp)
+static long tap_set_vnet_be(struct tap_queue *q, int __user *sp)
{
int s;
@@ -77,77 +77,77 @@ static long macvtap_set_vnet_be(struct macvtap_queue *q, int __user *sp)
return -EFAULT;
if (s)
- q->flags |= MACVTAP_VNET_BE;
+ q->flags |= TAP_VNET_BE;
else
- q->flags &= ~MACVTAP_VNET_BE;
+ q->flags &= ~TAP_VNET_BE;
return 0;
}
#else
-static inline bool macvtap_legacy_is_little_endian(struct macvtap_queue *q)
+static inline bool tap_legacy_is_little_endian(struct tap_queue *q)
{
return virtio_legacy_is_little_endian();
}
-static long macvtap_get_vnet_be(struct macvtap_queue *q, int __user *argp)
+static long tap_get_vnet_be(struct tap_queue *q, int __user *argp)
{
return -EINVAL;
}
-static long macvtap_set_vnet_be(struct macvtap_queue *q, int __user *argp)
+static long tap_set_vnet_be(struct tap_queue *q, int __user *argp)
{
return -EINVAL;
}
#endif /* CONFIG_TUN_VNET_CROSS_LE */
-static inline bool macvtap_is_little_endian(struct macvtap_queue *q)
+static inline bool tap_is_little_endian(struct tap_queue *q)
{
- return q->flags & MACVTAP_VNET_LE ||
- macvtap_legacy_is_little_endian(q);
+ return q->flags & TAP_VNET_LE ||
+ tap_legacy_is_little_endian(q);
}
-static inline u16 macvtap16_to_cpu(struct macvtap_queue *q, __virtio16 val)
+static inline u16 tap16_to_cpu(struct tap_queue *q, __virtio16 val)
{
- return __virtio16_to_cpu(macvtap_is_little_endian(q), val);
+ return __virtio16_to_cpu(tap_is_little_endian(q), val);
}
-static inline __virtio16 cpu_to_macvtap16(struct macvtap_queue *q, u16 val)
+static inline __virtio16 cpu_to_tap16(struct tap_queue *q, u16 val)
{
- return __cpu_to_virtio16(macvtap_is_little_endian(q), val);
+ return __cpu_to_virtio16(tap_is_little_endian(q), val);
}
-static struct proto macvtap_proto = {
- .name = "macvtap",
+static struct proto tap_proto = {
+ .name = "tap",
.owner = THIS_MODULE,
- .obj_size = sizeof (struct macvtap_queue),
+ .obj_size = sizeof(struct tap_queue),
};
-#define MACVTAP_NUM_DEVS (1U << MINORBITS)
+#define TAP_NUM_DEVS (1U << MINORBITS)
static DEFINE_MUTEX(minor_lock);
DEFINE_IDR(minor_idr);
#define GOODCOPY_LEN 128
-static const struct proto_ops macvtap_socket_ops;
+static const struct proto_ops tap_socket_ops;
#define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO)
#define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG | NETIF_F_FRAGLIST)
-static struct macvlan_dev *macvtap_get_vlan_rcu(const struct net_device *dev)
+static struct macvlan_dev *tap_get_vlan_rcu(const struct net_device *dev)
{
return rcu_dereference(dev->rx_handler_data);
}
/*
* RCU usage:
- * The macvtap_queue and the macvlan_dev are loosely coupled, the
+ * The tap_queue and the macvlan_dev are loosely coupled, the
* pointers from one to the other can only be read while rcu_read_lock
* or rtnl is held.
*
- * Both the file and the macvlan_dev hold a reference on the macvtap_queue
+ * Both the file and the macvlan_dev hold a reference on the tap_queue
* through sock_hold(&q->sk). When the macvlan_dev goes away first,
* q->vlan becomes inaccessible. When the files gets closed,
- * macvtap_get_queue() fails.
+ * tap_get_queue() fails.
*
* There may still be references to the struct sock inside of the
* queue from outbound SKBs, but these never reference back to the
@@ -155,8 +155,8 @@ static struct macvlan_dev *macvtap_get_vlan_rcu(const struct net_device *dev)
* when both our references and any pending SKBs are gone.
*/
-static int macvtap_enable_queue(struct net_device *dev, struct file *file,
- struct macvtap_queue *q)
+static int tap_enable_queue(struct net_device *dev, struct file *file,
+ struct tap_queue *q)
{
struct macvlan_dev *vlan = netdev_priv(dev);
int err = -EINVAL;
@@ -177,12 +177,12 @@ static int macvtap_enable_queue(struct net_device *dev, struct file *file,
}
/* Requires RTNL */
-static int macvtap_set_queue(struct net_device *dev, struct file *file,
- struct macvtap_queue *q)
+static int tap_set_queue(struct net_device *dev, struct file *file,
+ struct tap_queue *q)
{
struct macvlan_dev *vlan = netdev_priv(dev);
- if (vlan->numqueues == MAX_MACVTAP_QUEUES)
+ if (vlan->numqueues == MAX_TAP_QUEUES)
return -EBUSY;
rcu_assign_pointer(q->vlan, vlan);
@@ -201,10 +201,10 @@ static int macvtap_set_queue(struct net_device *dev, struct file *file,
return 0;
}
-static int macvtap_disable_queue(struct macvtap_queue *q)
+static int tap_disable_queue(struct tap_queue *q)
{
struct macvlan_dev *vlan;
- struct macvtap_queue *nq;
+ struct tap_queue *nq;
ASSERT_RTNL();
if (!q->enabled)
@@ -236,7 +236,7 @@ static int macvtap_disable_queue(struct macvtap_queue *q)
* Using the spinlock makes sure that we don't get
* to the queue again after destroying it.
*/
-static void macvtap_put_queue(struct macvtap_queue *q)
+static void tap_put_queue(struct tap_queue *q)
{
struct macvlan_dev *vlan;
@@ -245,7 +245,7 @@ static void macvtap_put_queue(struct macvtap_queue *q)
if (vlan) {
if (q->enabled)
- BUG_ON(macvtap_disable_queue(q));
+ BUG_ON(tap_disable_queue(q));
vlan->numqueues--;
RCU_INIT_POINTER(q->vlan, NULL);
@@ -266,11 +266,11 @@ static void macvtap_put_queue(struct macvtap_queue *q)
* Cache vlan->numvtaps since it can become zero during the execution
* of this function.
*/
-static struct macvtap_queue *macvtap_get_queue(struct net_device *dev,
- struct sk_buff *skb)
+static struct tap_queue *tap_get_queue(struct net_device *dev,
+ struct sk_buff *skb)
{
struct macvlan_dev *vlan = netdev_priv(dev);
- struct macvtap_queue *tap = NULL;
+ struct tap_queue *tap = NULL;
/* Access to taps array is protected by rcu, but access to numvtaps
* isn't. Below we use it to lookup a queue, but treat it as a hint
* and validate that the result isn't NULL - in case we are
@@ -313,10 +313,10 @@ static struct macvtap_queue *macvtap_get_queue(struct net_device *dev,
* that it holds on all queues and safely set the pointer
* from the queues to NULL.
*/
-void macvtap_del_queues(struct net_device *dev)
+void tap_del_queues(struct net_device *dev)
{
struct macvlan_dev *vlan = netdev_priv(dev);
- struct macvtap_queue *q, *tmp;
+ struct tap_queue *q, *tmp;
ASSERT_RTNL();
list_for_each_entry_safe(q, tmp, &vlan->queue_list, next) {
@@ -329,23 +329,23 @@ void macvtap_del_queues(struct net_device *dev)
}
BUG_ON(vlan->numvtaps);
BUG_ON(vlan->numqueues);
- /* guarantee that any future macvtap_set_queue will fail */
- vlan->numvtaps = MAX_MACVTAP_QUEUES;
+ /* guarantee that any future tap_set_queue will fail */
+ vlan->numvtaps = MAX_TAP_QUEUES;
}
-rx_handler_result_t macvtap_handle_frame(struct sk_buff **pskb)
+rx_handler_result_t tap_handle_frame(struct sk_buff **pskb)
{
struct sk_buff *skb = *pskb;
struct net_device *dev = skb->dev;
struct macvlan_dev *vlan;
- struct macvtap_queue *q;
+ struct tap_queue *q;
netdev_features_t features = TAP_FEATURES;
- vlan = macvtap_get_vlan_rcu(dev);
+ vlan = tap_get_vlan_rcu(dev);
if (!vlan)
return RX_HANDLER_PASS;
- q = macvtap_get_queue(dev, skb);
+ q = tap_get_queue(dev, skb);
if (!q)
return RX_HANDLER_PASS;
@@ -409,23 +409,23 @@ rx_handler_result_t macvtap_handle_frame(struct sk_buff **pskb)
return RX_HANDLER_CONSUMED;
}
-int macvtap_get_minor(struct macvlan_dev *vlan)
+int tap_get_minor(struct macvlan_dev *vlan)
{
int retval = -ENOMEM;
mutex_lock(&minor_lock);
- retval = idr_alloc(&minor_idr, vlan, 1, MACVTAP_NUM_DEVS, GFP_KERNEL);
+ retval = idr_alloc(&minor_idr, vlan, 1, TAP_NUM_DEVS, GFP_KERNEL);
if (retval >= 0) {
vlan->minor = retval;
} else if (retval == -ENOSPC) {
- netdev_err(vlan->dev, "Too many macvtap devices\n");
+ netdev_err(vlan->dev, "Too many tap devices\n");
retval = -EINVAL;
}
mutex_unlock(&minor_lock);
return retval < 0 ? retval : 0;
}
-void macvtap_free_minor(struct macvlan_dev *vlan)
+void tap_free_minor(struct macvlan_dev *vlan)
{
mutex_lock(&minor_lock);
if (vlan->minor) {
@@ -435,7 +435,7 @@ void macvtap_free_minor(struct macvlan_dev *vlan)
mutex_unlock(&minor_lock);
}
-static struct net_device *dev_get_by_macvtap_minor(int minor)
+static struct net_device *dev_get_by_tap_minor(int minor)
{
struct net_device *dev = NULL;
struct macvlan_dev *vlan;
@@ -450,7 +450,7 @@ static struct net_device *dev_get_by_macvtap_minor(int minor)
return dev;
}
-static void macvtap_sock_write_space(struct sock *sk)
+static void tap_sock_write_space(struct sock *sk)
{
wait_queue_head_t *wqueue;
@@ -463,28 +463,28 @@ static void macvtap_sock_write_space(struct sock *sk)
wake_up_interruptible_poll(wqueue, POLLOUT | POLLWRNORM | POLLWRBAND);
}
-static void macvtap_sock_destruct(struct sock *sk)
+static void tap_sock_destruct(struct sock *sk)
{
- struct macvtap_queue *q = container_of(sk, struct macvtap_queue, sk);
+ struct tap_queue *q = container_of(sk, struct tap_queue, sk);
skb_array_cleanup(&q->skb_array);
}
-static int macvtap_open(struct inode *inode, struct file *file)
+static int tap_open(struct inode *inode, struct file *file)
{
struct net *net = current->nsproxy->net_ns;
struct net_device *dev;
- struct macvtap_queue *q;
+ struct tap_queue *q;
int err = -ENODEV;
rtnl_lock();
- dev = dev_get_by_macvtap_minor(iminor(inode));
+ dev = dev_get_by_tap_minor(iminor(inode));
if (!dev)
goto err;
err = -ENOMEM;
- q = (struct macvtap_queue *)sk_alloc(net, AF_UNSPEC, GFP_KERNEL,
- &macvtap_proto, 0);
+ q = (struct tap_queue *)sk_alloc(net, AF_UNSPEC, GFP_KERNEL,
+ &tap_proto, 0);
if (!q)
goto err;
@@ -493,15 +493,15 @@ static int macvtap_open(struct inode *inode, struct file *file)
q->sock.type = SOCK_RAW;
q->sock.state = SS_CONNECTED;
q->sock.file = file;
- q->sock.ops = &macvtap_socket_ops;
+ q->sock.ops = &tap_socket_ops;
sock_init_data(&q->sock, &q->sk);
- q->sk.sk_write_space = macvtap_sock_write_space;
- q->sk.sk_destruct = macvtap_sock_destruct;
+ q->sk.sk_write_space = tap_sock_write_space;
+ q->sk.sk_destruct = tap_sock_destruct;
q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP;
q->vnet_hdr_sz = sizeof(struct virtio_net_hdr);
/*
- * so far only KVM virtio_net uses macvtap, enable zero copy between
+ * so far only KVM virtio_net uses tap, enable zero copy between
* guest kernel and host kernel when lower device supports zerocopy
*
* The macvlan supports zerocopy iff the lower device supports zero
@@ -514,7 +514,7 @@ static int macvtap_open(struct inode *inode, struct file *file)
if (skb_array_init(&q->skb_array, dev->tx_queue_len, GFP_KERNEL))
goto err_array;
- err = macvtap_set_queue(dev, file, q);
+ err = tap_set_queue(dev, file, q);
if (err)
goto err_queue;
@@ -535,16 +535,16 @@ static int macvtap_open(struct inode *inode, struct file *file)
return err;
}
-static int macvtap_release(struct inode *inode, struct file *file)
+static int tap_release(struct inode *inode, struct file *file)
{
- struct macvtap_queue *q = file->private_data;
- macvtap_put_queue(q);
+ struct tap_queue *q = file->private_data;
+ tap_put_queue(q);
return 0;
}
-static unsigned int macvtap_poll(struct file *file, poll_table * wait)
+static unsigned int tap_poll(struct file *file, poll_table *wait)
{
- struct macvtap_queue *q = file->private_data;
+ struct tap_queue *q = file->private_data;
unsigned int mask = POLLERR;
if (!q)
@@ -565,8 +565,8 @@ static unsigned int macvtap_poll(struct file *file, poll_table * wait)
return mask;
}
-static inline struct sk_buff *macvtap_alloc_skb(struct sock *sk, size_t prepad,
- size_t len, size_t linear,
+static inline struct sk_buff *tap_alloc_skb(struct sock *sk, size_t prepad,
+ size_t len, size_t linear,
int noblock, int *err)
{
struct sk_buff *skb;
@@ -589,13 +589,13 @@ static inline struct sk_buff *macvtap_alloc_skb(struct sock *sk, size_t prepad,
}
/* Neighbour code has some assumptions on HH_DATA_MOD alignment */
-#define MACVTAP_RESERVE HH_DATA_OFF(ETH_HLEN)
+#define TAP_RESERVE HH_DATA_OFF(ETH_HLEN)
/* Get packet from user space buffer */
-static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
- struct iov_iter *from, int noblock)
+static ssize_t tap_get_user(struct tap_queue *q, struct msghdr *m,
+ struct iov_iter *from, int noblock)
{
- int good_linear = SKB_MAX_HEAD(MACVTAP_RESERVE);
+ int good_linear = SKB_MAX_HEAD(TAP_RESERVE);
struct sk_buff *skb;
struct macvlan_dev *vlan;
unsigned long total_len = iov_iter_count(from);
@@ -621,14 +621,14 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
goto err;
iov_iter_advance(from, vnet_hdr_len - sizeof(vnet_hdr));
if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
- macvtap16_to_cpu(q, vnet_hdr.csum_start) +
- macvtap16_to_cpu(q, vnet_hdr.csum_offset) + 2 >
- macvtap16_to_cpu(q, vnet_hdr.hdr_len))
- vnet_hdr.hdr_len = cpu_to_macvtap16(q,
- macvtap16_to_cpu(q, vnet_hdr.csum_start) +
- macvtap16_to_cpu(q, vnet_hdr.csum_offset) + 2);
+ tap16_to_cpu(q, vnet_hdr.csum_start) +
+ tap16_to_cpu(q, vnet_hdr.csum_offset) + 2 >
+ tap16_to_cpu(q, vnet_hdr.hdr_len))
+ vnet_hdr.hdr_len = cpu_to_tap16(q,
+ tap16_to_cpu(q, vnet_hdr.csum_start) +
+ tap16_to_cpu(q, vnet_hdr.csum_offset) + 2);
err = -EINVAL;
- if (macvtap16_to_cpu(q, vnet_hdr.hdr_len) > len)
+ if (tap16_to_cpu(q, vnet_hdr.hdr_len) > len)
goto err;
}
@@ -640,7 +640,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
struct iov_iter i;
copylen = vnet_hdr.hdr_len ?
- macvtap16_to_cpu(q, vnet_hdr.hdr_len) : GOODCOPY_LEN;
+ tap16_to_cpu(q, vnet_hdr.hdr_len) : GOODCOPY_LEN;
if (copylen > good_linear)
copylen = good_linear;
else if (copylen < ETH_HLEN)
@@ -654,15 +654,15 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
if (!zerocopy) {
copylen = len;
- linear = macvtap16_to_cpu(q, vnet_hdr.hdr_len);
+ linear = tap16_to_cpu(q, vnet_hdr.hdr_len);
if (linear > good_linear)
linear = good_linear;
else if (linear < ETH_HLEN)
linear = ETH_HLEN;
}
- skb = macvtap_alloc_skb(&q->sk, MACVTAP_RESERVE, copylen,
- linear, noblock, &err);
+ skb = tap_alloc_skb(&q->sk, TAP_RESERVE, copylen,
+ linear, noblock, &err);
if (!skb)
goto err;
@@ -680,7 +680,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
if (vnet_hdr_len) {
err = virtio_net_hdr_to_skb(skb, &vnet_hdr,
- macvtap_is_little_endian(q));
+ tap_is_little_endian(q));
if (err)
goto err_kfree;
}
@@ -728,18 +728,18 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
return err;
}
-static ssize_t macvtap_write_iter(struct kiocb *iocb, struct iov_iter *from)
+static ssize_t tap_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
struct file *file = iocb->ki_filp;
- struct macvtap_queue *q = file->private_data;
+ struct tap_queue *q = file->private_data;
- return macvtap_get_user(q, NULL, from, file->f_flags & O_NONBLOCK);
+ return tap_get_user(q, NULL, from, file->f_flags & O_NONBLOCK);
}
/* Put packet to the user space buffer */
-static ssize_t macvtap_put_user(struct macvtap_queue *q,
- const struct sk_buff *skb,
- struct iov_iter *iter)
+static ssize_t tap_put_user(struct tap_queue *q,
+ const struct sk_buff *skb,
+ struct iov_iter *iter)
{
int ret;
int vnet_hdr_len = 0;
@@ -753,7 +753,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
return -EINVAL;
if (virtio_net_hdr_from_skb(skb, &vnet_hdr,
- macvtap_is_little_endian(q)))
+ tap_is_little_endian(q)))
BUG();
if (copy_to_iter(&vnet_hdr, sizeof(vnet_hdr), iter) !=
@@ -792,9 +792,9 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
return ret ? ret : total;
}
-static ssize_t macvtap_do_read(struct macvtap_queue *q,
- struct iov_iter *to,
- int noblock)
+static ssize_t tap_do_read(struct tap_queue *q,
+ struct iov_iter *to,
+ int noblock)
{
DEFINE_WAIT(wait);
struct sk_buff *skb;
@@ -827,7 +827,7 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q,
finish_wait(sk_sleep(&q->sk), &wait);
if (skb) {
- ret = macvtap_put_user(q, skb, to);
+ ret = tap_put_user(q, skb, to);
if (unlikely(ret < 0))
kfree_skb(skb);
else
@@ -836,20 +836,20 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q,
return ret;
}
-static ssize_t macvtap_read_iter(struct kiocb *iocb, struct iov_iter *to)
+static ssize_t tap_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
struct file *file = iocb->ki_filp;
- struct macvtap_queue *q = file->private_data;
+ struct tap_queue *q = file->private_data;
ssize_t len = iov_iter_count(to), ret;
- ret = macvtap_do_read(q, to, file->f_flags & O_NONBLOCK);
+ ret = tap_do_read(q, to, file->f_flags & O_NONBLOCK);
ret = min_t(ssize_t, ret, len);
if (ret > 0)
iocb->ki_pos = ret;
return ret;
}
-static struct macvlan_dev *macvtap_get_vlan(struct macvtap_queue *q)
+static struct macvlan_dev *tap_get_vlan(struct tap_queue *q)
{
struct macvlan_dev *vlan;
@@ -861,33 +861,33 @@ static struct macvlan_dev *macvtap_get_vlan(struct macvtap_queue *q)
return vlan;
}
-static void macvtap_put_vlan(struct macvlan_dev *vlan)
+static void tap_put_vlan(struct macvlan_dev *vlan)
{
dev_put(vlan->dev);
}
-static int macvtap_ioctl_set_queue(struct file *file, unsigned int flags)
+static int tap_ioctl_set_queue(struct file *file, unsigned int flags)
{
- struct macvtap_queue *q = file->private_data;
+ struct tap_queue *q = file->private_data;
struct macvlan_dev *vlan;
int ret;
- vlan = macvtap_get_vlan(q);
+ vlan = tap_get_vlan(q);
if (!vlan)
return -EINVAL;
if (flags & IFF_ATTACH_QUEUE)
- ret = macvtap_enable_queue(vlan->dev, file, q);
+ ret = tap_enable_queue(vlan->dev, file, q);
else if (flags & IFF_DETACH_QUEUE)
- ret = macvtap_disable_queue(q);
+ ret = tap_disable_queue(q);
else
ret = -EINVAL;
- macvtap_put_vlan(vlan);
+ tap_put_vlan(vlan);
return ret;
}
-static int set_offload(struct macvtap_queue *q, unsigned long arg)
+static int set_offload(struct tap_queue *q, unsigned long arg)
{
struct macvlan_dev *vlan;
netdev_features_t features;
@@ -919,7 +919,7 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg)
* setting the TSO bit means that the userspace wants to
* accept TSO frames and turning it off means that user space
* does not support TSO.
- * For macvtap, we have to invert it to mean the same thing.
+ * For tap, we have to invert it to mean the same thing.
* When user space turns off TSO, we turn off GSO/LRO so that
* user-space will not receive TSO frames.
*/
@@ -941,10 +941,10 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg)
/*
* provide compatibility with generic tun/tap interface
*/
-static long macvtap_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
+static long tap_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
- struct macvtap_queue *q = file->private_data;
+ struct tap_queue *q = file->private_data;
struct macvlan_dev *vlan;
void __user *argp = (void __user *)arg;
struct ifreq __user *ifr = argp;
@@ -962,16 +962,16 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
return -EFAULT;
ret = 0;
- if ((u & ~MACVTAP_FEATURES) != (IFF_NO_PI | IFF_TAP))
+ if ((u & ~TAP_IFFEATURES) != (IFF_NO_PI | IFF_TAP))
ret = -EINVAL;
else
- q->flags = (q->flags & ~MACVTAP_FEATURES) | u;
+ q->flags = (q->flags & ~TAP_IFFEATURES) | u;
return ret;
case TUNGETIFF:
rtnl_lock();
- vlan = macvtap_get_vlan(q);
+ vlan = tap_get_vlan(q);
if (!vlan) {
rtnl_unlock();
return -ENOLINK;
@@ -982,7 +982,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
if (copy_to_user(&ifr->ifr_name, vlan->dev->name, IFNAMSIZ) ||
put_user(u, &ifr->ifr_flags))
ret = -EFAULT;
- macvtap_put_vlan(vlan);
+ tap_put_vlan(vlan);
rtnl_unlock();
return ret;
@@ -990,12 +990,12 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
if (get_user(u, &ifr->ifr_flags))
return -EFAULT;
rtnl_lock();
- ret = macvtap_ioctl_set_queue(file, u);
+ ret = tap_ioctl_set_queue(file, u);
rtnl_unlock();
return ret;
case TUNGETFEATURES:
- if (put_user(IFF_TAP | IFF_NO_PI | MACVTAP_FEATURES, up))
+ if (put_user(IFF_TAP | IFF_NO_PI | TAP_IFFEATURES, up))
return -EFAULT;
return 0;
@@ -1022,7 +1022,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
return 0;
case TUNGETVNETLE:
- s = !!(q->flags & MACVTAP_VNET_LE);
+ s = !!(q->flags & TAP_VNET_LE);
if (put_user(s, sp))
return -EFAULT;
return 0;
@@ -1031,16 +1031,16 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
if (get_user(s, sp))
return -EFAULT;
if (s)
- q->flags |= MACVTAP_VNET_LE;
+ q->flags |= TAP_VNET_LE;
else
- q->flags &= ~MACVTAP_VNET_LE;
+ q->flags &= ~TAP_VNET_LE;
return 0;
case TUNGETVNETBE:
- return macvtap_get_vnet_be(q, sp);
+ return tap_get_vnet_be(q, sp);
case TUNSETVNETBE:
- return macvtap_set_vnet_be(q, sp);
+ return tap_set_vnet_be(q, sp);
case TUNSETOFFLOAD:
/* let the user check for future flags */
@@ -1055,7 +1055,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
case SIOCGIFHWADDR:
rtnl_lock();
- vlan = macvtap_get_vlan(q);
+ vlan = tap_get_vlan(q);
if (!vlan) {
rtnl_unlock();
return -ENOLINK;
@@ -1066,7 +1066,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
copy_to_user(&ifr->ifr_hwaddr.sa_data, vlan->dev->dev_addr, ETH_ALEN) ||
put_user(u, &ifr->ifr_hwaddr.sa_family))
ret = -EFAULT;
- macvtap_put_vlan(vlan);
+ tap_put_vlan(vlan);
rtnl_unlock();
return ret;
@@ -1074,13 +1074,13 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
if (copy_from_user(&sa, &ifr->ifr_hwaddr, sizeof(sa)))
return -EFAULT;
rtnl_lock();
- vlan = macvtap_get_vlan(q);
+ vlan = tap_get_vlan(q);
if (!vlan) {
rtnl_unlock();
return -ENOLINK;
}
ret = dev_set_mac_address(vlan->dev, &sa);
- macvtap_put_vlan(vlan);
+ tap_put_vlan(vlan);
rtnl_unlock();
return ret;
@@ -1090,42 +1090,42 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
}
#ifdef CONFIG_COMPAT
-static long macvtap_compat_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
+static long tap_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
- return macvtap_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
+ return tap_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
}
#endif
-const struct file_operations macvtap_fops = {
+const struct file_operations tap_fops = {
.owner = THIS_MODULE,
- .open = macvtap_open,
- .release = macvtap_release,
- .read_iter = macvtap_read_iter,
- .write_iter = macvtap_write_iter,
- .poll = macvtap_poll,
+ .open = tap_open,
+ .release = tap_release,
+ .read_iter = tap_read_iter,
+ .write_iter = tap_write_iter,
+ .poll = tap_poll,
.llseek = no_llseek,
- .unlocked_ioctl = macvtap_ioctl,
+ .unlocked_ioctl = tap_ioctl,
#ifdef CONFIG_COMPAT
- .compat_ioctl = macvtap_compat_ioctl,
+ .compat_ioctl = tap_compat_ioctl,
#endif
};
-static int macvtap_sendmsg(struct socket *sock, struct msghdr *m,
- size_t total_len)
+static int tap_sendmsg(struct socket *sock, struct msghdr *m,
+ size_t total_len)
{
- struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock);
- return macvtap_get_user(q, m, &m->msg_iter, m->msg_flags & MSG_DONTWAIT);
+ struct tap_queue *q = container_of(sock, struct tap_queue, sock);
+ return tap_get_user(q, m, &m->msg_iter, m->msg_flags & MSG_DONTWAIT);
}
-static int macvtap_recvmsg(struct socket *sock, struct msghdr *m,
- size_t total_len, int flags)
+static int tap_recvmsg(struct socket *sock, struct msghdr *m,
+ size_t total_len, int flags)
{
- struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock);
+ struct tap_queue *q = container_of(sock, struct tap_queue, sock);
int ret;
if (flags & ~(MSG_DONTWAIT|MSG_TRUNC))
return -EINVAL;
- ret = macvtap_do_read(q, &m->msg_iter, flags & MSG_DONTWAIT);
+ ret = tap_do_read(q, &m->msg_iter, flags & MSG_DONTWAIT);
if (ret > total_len) {
m->msg_flags |= MSG_TRUNC;
ret = flags & MSG_TRUNC ? ret : total_len;
@@ -1133,40 +1133,40 @@ static int macvtap_recvmsg(struct socket *sock, struct msghdr *m,
return ret;
}
-static int macvtap_peek_len(struct socket *sock)
+static int tap_peek_len(struct socket *sock)
{
- struct macvtap_queue *q = container_of(sock, struct macvtap_queue,
+ struct tap_queue *q = container_of(sock, struct tap_queue,
sock);
return skb_array_peek_len(&q->skb_array);
}
/* Ops structure to mimic raw sockets with tun */
-static const struct proto_ops macvtap_socket_ops = {
- .sendmsg = macvtap_sendmsg,
- .recvmsg = macvtap_recvmsg,
- .peek_len = macvtap_peek_len,
+static const struct proto_ops tap_socket_ops = {
+ .sendmsg = tap_sendmsg,
+ .recvmsg = tap_recvmsg,
+ .peek_len = tap_peek_len,
};
/* Get an underlying socket object from tun file. Returns error unless file is
* attached to a device. The returned object works like a packet socket, it
* can be used for sock_sendmsg/sock_recvmsg. The caller is responsible for
* holding a reference to the file for as long as the socket is in use. */
-struct socket *macvtap_get_socket(struct file *file)
+struct socket *tap_get_socket(struct file *file)
{
- struct macvtap_queue *q;
- if (file->f_op != &macvtap_fops)
+ struct tap_queue *q;
+ if (file->f_op != &tap_fops)
return ERR_PTR(-EINVAL);
q = file->private_data;
if (!q)
return ERR_PTR(-EBADFD);
return &q->sock;
}
-EXPORT_SYMBOL_GPL(macvtap_get_socket);
+EXPORT_SYMBOL_GPL(tap_get_socket);
-int macvtap_queue_resize(struct macvlan_dev *vlan)
+int tap_queue_resize(struct macvlan_dev *vlan)
{
struct net_device *dev = vlan->dev;
- struct macvtap_queue *q;
+ struct tap_queue *q;
struct skb_array **arrays;
int n = vlan->numqueues;
int ret, i = 0;
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 5dc3465..4875efd 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -24,6 +24,7 @@
#include <linux/if_arp.h>
#include <linux/if_tun.h>
#include <linux/if_macvlan.h>
+#include <linux/if_tap.h>
#include <linux/if_vlan.h>
#include <net/sock.h>
@@ -943,7 +944,7 @@ static struct socket *get_tap_socket(int fd)
sock = tun_get_socket(file);
if (!IS_ERR(sock))
return sock;
- sock = macvtap_get_socket(file);
+ sock = tap_get_socket(file);
if (IS_ERR(sock))
fput(file);
return sock;
diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h
index a4ccc31..5233898 100644
--- a/include/linux/if_macvlan.h
+++ b/include/linux/if_macvlan.h
@@ -29,7 +29,7 @@ struct macvtap_queue;
* Maximum times a macvtap device can be opened. This can be used to
* configure the number of receive queue, e.g. for multiqueue virtio.
*/
-#define MAX_MACVTAP_QUEUES 256
+#define MAX_TAP_QUEUES 256
#define MACVLAN_MC_FILTER_BITS 8
#define MACVLAN_MC_FILTER_SZ (1 << MACVLAN_MC_FILTER_BITS)
@@ -49,7 +49,7 @@ struct macvlan_dev {
enum macvlan_mode mode;
u16 flags;
/* This array tracks active taps. */
- struct macvtap_queue __rcu *taps[MAX_MACVTAP_QUEUES];
+ struct tap_queue __rcu *taps[MAX_TAP_QUEUES];
/* This list tracks all taps (both enabled and disabled) */
struct list_head queue_list;
int numvtaps;
diff --git a/include/linux/if_macvtap.h b/include/linux/if_macvtap.h
deleted file mode 100644
index c9bf84b..0000000
--- a/include/linux/if_macvtap.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _LINUX_IF_MACVTAP_H_
-#define _LINUX_IF_MACVTAP_H_
-
-rx_handler_result_t macvtap_handle_frame(struct sk_buff **pskb);
-void macvtap_del_queues(struct net_device *dev);
-int macvtap_get_minor(struct macvlan_dev *vlan);
-void macvtap_free_minor(struct macvlan_dev *vlan);
-int macvtap_queue_resize(struct macvlan_dev *vlan);
-
-#endif /*_LINUX_IF_MACVTAP_H_*/
diff --git a/include/linux/if_tap.h b/include/linux/if_tap.h
new file mode 100644
index 0000000..d9ecc15
--- /dev/null
+++ b/include/linux/if_tap.h
@@ -0,0 +1,11 @@
+#ifndef _LINUX_IF_TAP_H_
+#define _LINUX_IF_TAP_H_
+
+rx_handler_result_t tap_handle_frame(struct sk_buff **pskb);
+void tap_del_queues(struct net_device *dev);
+int tap_get_minor(struct macvlan_dev *vlan);
+void tap_free_minor(struct macvlan_dev *vlan);
+int tap_queue_resize(struct macvlan_dev *vlan);
+struct socket *tap_get_socket(struct file *file);
+
+#endif /*_LINUX_IF_TAP_H_*/
--
2.7.4
^ permalink raw reply related
* Re: [PATCH net-next 2/2] arm: dts: vf610-zii-dev-rev-b: remove ports label
From: Andrew Lunn @ 2017-01-06 22:41 UTC (permalink / raw)
To: Vivien Didelot
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli,
Uwe Kleine-König
In-Reply-To: <20170106220043.21280-3-vivien.didelot@savoirfairelinux.com>
On Fri, Jan 06, 2017 at 05:00:43PM -0500, Vivien Didelot wrote:
> Now that the "label" property is optional for Ethernet switch ports,
> remove them in the ZII Dev Rev B board DTS.
>
> On a Rev B board, once eth1 is up, this DTS now exposes to userspace:
>
> # ip link | grep ': ' | cut -d: -f2
> lo
> eth0
> eth1
> eth2@eth1
> eth3@eth1
> eth4@eth1
> eth5@eth1
> eth6@eth1
> eth7@eth1
> eth8@eth1
> eth9@eth1
> eth10@eth1
> eth11@eth1
> eth12@eth1
It exposes this, this time. Next time, it could be:
eth0
eth1@eth0
eth2@eth0
eth3@eth0
eth4@eth0
eth5@eth0
eth6@eth0
eth7@eth0
eth8@eth0
eth9@eth0
eth10@eth0
eth11@eth0
eth12
depending on how the base interfaces enumerate.
We have gone from deterministic names to non-deterministic names for
the switch ports. We now must have udev rules, if we want
deterministic names.
If the names where not deterministic before, i would of agreed to
this. But they are deterministic, set by device tree, and set to match
some physical property of the hardware, generally the label on the
case/PCB.
If somebody were to produce a switch on a PCIe card, or a USB bus,
things then are non-deterministic, and leaving the kernel to assign a
name is O.K. So i think the first patch is O.K, but i don't like this
patch.
Andrew
^ permalink raw reply
* Re: [PATCH net-next 1/2] net: dsa: make "label" property optional for dsa2
From: Florian Fainelli @ 2017-01-06 22:47 UTC (permalink / raw)
To: Andrew Lunn, Vivien Didelot
Cc: netdev, linux-kernel, kernel, David S. Miller,
Uwe Kleine-König
In-Reply-To: <20170106222008.GC10626@lunn.ch>
On 01/06/2017 02:20 PM, Andrew Lunn wrote:
>> If one wants to rename an interface, udev rules can be used as usual.
>
> Hi Vivien
>
> Do you have some examples?
>
> A quick look at udevadm info suggests we can use
>
> ATTR{phys_port_id} and ATTR{phys_switch_id}
>
> Humm, it would be nice to know why the second switch has a
> phys_switch_id of 01000000.
Well, that's a combination of being on a little endian system and using
%*phN as a printk formatter, and the type being 32-bit long (int). I
agree this does not feel natural, but since this is sysfs (so ABI in a
way), it's going to be though to change now.
--
Florian
^ permalink raw reply
* Re: [PATCHv1 1/7] TAP: Refactoring macvtap.c
From: Andy Shevchenko @ 2017-01-06 23:12 UTC (permalink / raw)
To: Sainath Grandhi
Cc: netdev, David S. Miller, mahesh, linux-kernel@vger.kernel.org
In-Reply-To: <1483742009-19184-2-git-send-email-sainath.grandhi@intel.com>
On Sat, Jan 7, 2017 at 12:33 AM, Sainath Grandhi
<sainath.grandhi@intel.com> wrote:
> macvtap module has code for tap/queue management and link management. This patch splits
> the code into macvtap_main.c for link management and tap.c for tap/queue management.
> Functionality in tap.c can be re-used for implementing tap on other virtual interfaces.
>
> Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
> Tested-by: Sainath Grandhi <sainath.grandhi@intel.com>
> ---
> drivers/net/Makefile | 2 +
> drivers/net/macvtap.c | 1374 --------------------------------------------
> drivers/net/macvtap_main.c | 218 +++++++
> drivers/net/tap.c | 1186 ++++++++++++++++++++++++++++++++++++++
> include/linux/if_macvtap.h | 10 +
> 5 files changed, 1416 insertions(+), 1374 deletions(-)
> delete mode 100644 drivers/net/macvtap.c
> create mode 100644 drivers/net/macvtap_main.c
> create mode 100644 drivers/net/tap.c
> create mode 100644 include/linux/if_macvtap.h
Can you use -M -C for better view of this change? It's really hard to review.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCHv1 7/7] IPVTAP: IP-VLAN based tap driver
From: Eric Dumazet @ 2017-01-06 23:14 UTC (permalink / raw)
To: Sainath Grandhi; +Cc: netdev, davem, mahesh, linux-kernel
In-Reply-To: <1483742009-19184-8-git-send-email-sainath.grandhi@intel.com>
On Fri, 2017-01-06 at 14:33 -0800, Sainath Grandhi wrote:
> This patch adds a tap character device driver that is based on the
> IP-VLAN network interface, called ipvtap. An ipvtap device can be created
> in the same way as an ipvlan device, using 'type ipvtap', and then accessed
> using the tap user space interface.
>
> Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
> Tested-by: Sainath Grandhi <sainath.grandhi@intel.com>
> ---
> +module_exit(ipvtap_exit);
> +MODULE_ALIAS_RTNL_LINK("ipvtap");
> +MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>");
> +MODULE_LICENSE("GPL");
Who wrote this driver exactly ???
^ permalink raw reply
* Re: [PATCHv1 5/7] TAP: Extending tap device create/destroy APIs
From: Eric Dumazet @ 2017-01-06 23:15 UTC (permalink / raw)
To: Sainath Grandhi; +Cc: netdev, davem, mahesh, linux-kernel
In-Reply-To: <1483742009-19184-6-git-send-email-sainath.grandhi@intel.com>
On Fri, 2017-01-06 at 14:33 -0800, Sainath Grandhi wrote:
> +static int tap_list_add(dev_t major, const char *device_name)
> +{
> + int err = 0;
> + struct major_info *tap_major;
> +
> + tap_major = kzalloc(sizeof(*tap_major), GFP_ATOMIC);
> +
> + tap_major->major = MAJOR(major);
> +
kzalloc() can perfectly return NULL.
You do not want to crash it that happens.
^ permalink raw reply
* Re: [PATCH v2] PCI: lock each enable/disable num_vfs operation in sysfs
From: Greg @ 2017-01-06 23:17 UTC (permalink / raw)
To: Emil Tantilov
Cc: linux-pci, intel-wired-lan, alexander.h.duyck, netdev,
linux-kernel
In-Reply-To: <20170106215908.20736.34632.stgit@localhost6.localdomain6>
On Fri, 2017-01-06 at 13:59 -0800, Emil Tantilov wrote:
> Enabling/disabling SRIOV via sysfs by echo-ing multiple values
> simultaneously:
>
> echo 63 > /sys/class/net/ethX/device/sriov_numvfs&
> echo 63 > /sys/class/net/ethX/device/sriov_numvfs
>
> sleep 5
>
> echo 0 > /sys/class/net/ethX/device/sriov_numvfs&
> echo 0 > /sys/class/net/ethX/device/sriov_numvfs
>
> Results in the following bug:
>
> kernel BUG at drivers/pci/iov.c:495!
> invalid opcode: 0000 [#1] SMP
> CPU: 1 PID: 8050 Comm: bash Tainted: G W 4.9.0-rc7-net-next #2092
> RIP: 0010:[<ffffffff813b1647>]
> [<ffffffff813b1647>] pci_iov_release+0x57/0x60
>
> Call Trace:
> [<ffffffff81391726>] pci_release_dev+0x26/0x70
> [<ffffffff8155be6e>] device_release+0x3e/0xb0
> [<ffffffff81365ee7>] kobject_cleanup+0x67/0x180
> [<ffffffff81365d9d>] kobject_put+0x2d/0x60
> [<ffffffff8155bc27>] put_device+0x17/0x20
> [<ffffffff8139c08a>] pci_dev_put+0x1a/0x20
> [<ffffffff8139cb6b>] pci_get_dev_by_id+0x5b/0x90
> [<ffffffff8139cca5>] pci_get_subsys+0x35/0x40
> [<ffffffff8139ccc8>] pci_get_device+0x18/0x20
> [<ffffffff8139ccfb>] pci_get_domain_bus_and_slot+0x2b/0x60
> [<ffffffff813b09e7>] pci_iov_remove_virtfn+0x57/0x180
> [<ffffffff813b0b95>] pci_disable_sriov+0x65/0x140
> [<ffffffffa00a1af7>] ixgbe_disable_sriov+0xc7/0x1d0 [ixgbe]
> [<ffffffffa00a1e9d>] ixgbe_pci_sriov_configure+0x3d/0x170 [ixgbe]
> [<ffffffff8139d28c>] sriov_numvfs_store+0xdc/0x130
> ...
> RIP [<ffffffff813b1647>] pci_iov_release+0x57/0x60
>
> Use the existing mutex lock to protect each enable/disable operation.
>
> -v2: move the existing lock from protecting the config of the IOV bus
> to protecting the writes to sriov_numvfs in sysfs without maintaining
> a "locked" version of pci_iov_add/remove_virtfn().
> As suggested by Gavin Shan <gwshan@linux.vnet.ibm.com>
>
> CC: Alexander Duyck <alexander.h.duyck@intel.com>
> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> ---
> drivers/pci/iov.c | 7 -------
> drivers/pci/pci-sysfs.c | 23 ++++++++++++++++-------
> drivers/pci/pci.h | 2 +-
> 3 files changed, 17 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
> index 4722782..2479ae8 100644
> --- a/drivers/pci/iov.c
> +++ b/drivers/pci/iov.c
> @@ -124,7 +124,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset)
> struct pci_sriov *iov = dev->sriov;
> struct pci_bus *bus;
>
> - mutex_lock(&iov->dev->sriov->lock);
> bus = virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id));
> if (!bus)
> goto failed;
> @@ -162,7 +161,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset)
> __pci_reset_function(virtfn);
>
> pci_device_add(virtfn, virtfn->bus);
> - mutex_unlock(&iov->dev->sriov->lock);
>
> pci_bus_add_device(virtfn);
> sprintf(buf, "virtfn%u", id);
> @@ -181,12 +179,10 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset)
> sysfs_remove_link(&dev->dev.kobj, buf);
> failed1:
> pci_dev_put(dev);
> - mutex_lock(&iov->dev->sriov->lock);
> pci_stop_and_remove_bus_device(virtfn);
> failed0:
> virtfn_remove_bus(dev->bus, bus);
> failed:
> - mutex_unlock(&iov->dev->sriov->lock);
>
> return rc;
> }
> @@ -195,7 +191,6 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset)
> {
> char buf[VIRTFN_ID_LEN];
> struct pci_dev *virtfn;
> - struct pci_sriov *iov = dev->sriov;
>
> virtfn = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus),
> pci_iov_virtfn_bus(dev, id),
> @@ -218,10 +213,8 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset)
> if (virtfn->dev.kobj.sd)
> sysfs_remove_link(&virtfn->dev.kobj, "physfn");
>
> - mutex_lock(&iov->dev->sriov->lock);
> pci_stop_and_remove_bus_device(virtfn);
> virtfn_remove_bus(dev->bus, virtfn->bus);
> - mutex_unlock(&iov->dev->sriov->lock);
>
> /* balance pci_get_domain_bus_and_slot() */
> pci_dev_put(virtfn);
> diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
> index 0666287..25d010d 100644
> --- a/drivers/pci/pci-sysfs.c
> +++ b/drivers/pci/pci-sysfs.c
> @@ -472,6 +472,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
> const char *buf, size_t count)
> {
> struct pci_dev *pdev = to_pci_dev(dev);
> + struct pci_sriov *iov = pdev->sriov;
> int ret;
> u16 num_vfs;
>
> @@ -482,38 +483,46 @@ static ssize_t sriov_numvfs_store(struct device *dev,
> if (num_vfs > pci_sriov_get_totalvfs(pdev))
> return -ERANGE;
>
> + mutex_lock(&iov->dev->sriov->lock);
> +
> if (num_vfs == pdev->sriov->num_VFs)
> - return count; /* no change */
> + goto exit;
>
> /* is PF driver loaded w/callback */
> if (!pdev->driver || !pdev->driver->sriov_configure) {
> dev_info(&pdev->dev, "Driver doesn't support SRIOV configuration via sysfs\n");
> - return -ENOSYS;
> + ret = -ENOENT;
> + goto exit;
Hi Emil,
Generally the patch looks fine to me - but I am wondering why the change
from -ENOSYS TO -ENOENT?
Thanks,
- Greg
> }
>
> if (num_vfs == 0) {
> /* disable VFs */
> ret = pdev->driver->sriov_configure(pdev, 0);
> - if (ret < 0)
> - return ret;
> - return count;
> + goto exit;
> }
>
> /* enable VFs */
> if (pdev->sriov->num_VFs) {
> dev_warn(&pdev->dev, "%d VFs already enabled. Disable before enabling %d VFs\n",
> pdev->sriov->num_VFs, num_vfs);
> - return -EBUSY;
> + ret = -EBUSY;
> + goto exit;
> }
>
> ret = pdev->driver->sriov_configure(pdev, num_vfs);
> if (ret < 0)
> - return ret;
> + goto exit;
>
> if (ret != num_vfs)
> dev_warn(&pdev->dev, "%d VFs requested; only %d enabled\n",
> num_vfs, ret);
>
> +exit:
> + mutex_unlock(&iov->dev->sriov->lock);
> +
> + if (ret < 0)
> + return ret;
> +
> return count;
> }
>
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index cb17db2..8dd38e6 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -270,7 +270,7 @@ struct pci_sriov {
> u16 driver_max_VFs; /* max num VFs driver supports */
> struct pci_dev *dev; /* lowest numbered PF */
> struct pci_dev *self; /* this PF */
> - struct mutex lock; /* lock for VF bus */
> + struct mutex lock; /* lock for setting sriov_numvfs in sysfs */
> resource_size_t barsz[PCI_SRIOV_NUM_BARS]; /* VF BAR size */
> };
>
>
^ permalink raw reply
* Re: [PATCHv1 5/7] TAP: Extending tap device create/destroy APIs
From: Andy Shevchenko @ 2017-01-06 23:20 UTC (permalink / raw)
To: Sainath Grandhi
Cc: netdev, David S. Miller, mahesh, linux-kernel@vger.kernel.org
In-Reply-To: <1483742009-19184-6-git-send-email-sainath.grandhi@intel.com>
On Sat, Jan 7, 2017 at 12:33 AM, Sainath Grandhi
<sainath.grandhi@intel.com> wrote:
> Extending tap APIs get/free_minor and create/destroy_cdev to handle more than one
> type of virtual interface.
>
> Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
> Tested-by: Sainath Grandhi <sainath.grandhi@intel.com>
Usually it implies that commiter has tested the stuff.
> --- a/drivers/net/tap.c
> +++ b/drivers/net/tap.c
> @@ -99,12 +99,16 @@ static struct proto tap_proto = {
> };
>
> #define TAP_NUM_DEVS (1U << MINORBITS)
> +
> +LIST_HEAD(major_list);
> +
static ?
> -int tap_get_minor(struct tap_dev *tap)
> +int tap_get_minor(dev_t major, struct tap_dev *tap)
> {
> int retval = -ENOMEM;
> + struct major_info *tap_major, *tmp;
> + bool found = false;
>
> - mutex_lock(&macvtap_major.minor_lock);
> - retval = idr_alloc(&macvtap_major.minor_idr, tap, 1, TAP_NUM_DEVS, GFP_KERNEL);
> + list_for_each_entry_safe(tap_major, tmp, &major_list, next) {
> + if (tap_major->major == MAJOR(major)) {
> + found = true;
> + break;
> + }
> + }
> +
> + if (!found)
> + return -EINVAL;
This is candidate to be a separate helper function. See also below.
> -void tap_free_minor(struct tap_dev *tap)
> +void tap_free_minor(dev_t major, struct tap_dev *tap)
> {
> - mutex_lock(&macvtap_major.minor_lock);
> + struct major_info *tap_major, *tmp;
> + bool found = false;
> +
> + list_for_each_entry_safe(tap_major, tmp, &major_list, next) {
> + if (tap_major->major == MAJOR(major)) {
> + found = true;
> + break;
> + }
> + }
> +
> + if (!found)
> + return;
Here is quite the same code (as above).
> -static struct tap_dev *dev_get_by_tap_minor(int minor)
> +static struct tap_dev *dev_get_by_tap_file(int major, int minor)
> {
> struct net_device *dev = NULL;
> struct tap_dev *tap;
> + struct major_info *tap_major, *tmp;
> + bool found = false;
>
> - mutex_lock(&macvtap_major.minor_lock);
> - tap = idr_find(&macvtap_major.minor_idr, minor);
> + list_for_each_entry_safe(tap_major, tmp, &major_list, next) {
> + if (tap_major->major == major) {
> + found = true;
> + break;
> + }
> + }
> +
> + if (!found)
> + return NULL;
And here.
> +static int tap_list_add(dev_t major, const char *device_name)
> +{
> + int err = 0;
> + struct major_info *tap_major;
Perhaps
+ struct major_info *tap_major;
+ int err = 0;
> +
> + tap_major = kzalloc(sizeof(*tap_major), GFP_ATOMIC);
> +
> + tap_major->major = MAJOR(major);
> +
> + idr_init(&tap_major->minor_idr);
> + mutex_init(&tap_major->minor_lock);
> +
> + tap_major->device_name = device_name;
> +
> + list_add_tail(&tap_major->next, &major_list);
> + return err;
> + err = tap_list_add(*tap_major, device_name);
>
> return err;
return tap_list_add();
> void tap_destroy_cdev(dev_t major, struct cdev *tap_cdev)
> {
> + struct major_info *tap_major, *tmp;
> + bool found = false;
> +
> + list_for_each_entry_safe(tap_major, tmp, &major_list, next) {
> + if (tap_major->major == MAJOR(major)) {
> + found = true;
> + break;
> + }
> + }
> +
> + if (!found)
> + return;
And here.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* [PATCH net] bpf: change back to orig prog on too many passes
From: Daniel Borkmann @ 2017-01-06 23:26 UTC (permalink / raw)
To: davem; +Cc: alexei.starovoitov, netdev, Daniel Borkmann
If after too many passes still no image could be emitted, then
swap back to the original program as we do in all other cases
and don't use the one with blinding.
Fixes: 959a75791603 ("bpf, x86: add support for constant blinding")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
---
arch/x86/net/bpf_jit_comp.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index e76d1af..bb660e5 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -1172,6 +1172,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
set_memory_ro((unsigned long)header, header->pages);
prog->bpf_func = (void *)image;
prog->jited = 1;
+ } else {
+ prog = orig_prog;
}
out_addrs:
--
1.9.3
^ permalink raw reply related
* RE: [Intel-wired-lan] [PATCH v2] PCI: lock each enable/disable num_vfs operation in sysfs
From: Tantilov, Emil S @ 2017-01-06 23:28 UTC (permalink / raw)
To: Greg
Cc: linux-pci@vger.kernel.org, intel-wired-lan@lists.osuosl.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Gavin Shan
In-Reply-To: <1483744662.3868.1.camel@gmail.com>
>-----Original Message-----
>From: Intel-wired-lan [mailto:intel-wired-lan-bounces@lists.osuosl.org] On
>Behalf Of Greg
>Sent: Friday, January 06, 2017 3:18 PM
>To: Tantilov, Emil S <emil.s.tantilov@intel.com>
>Cc: linux-pci@vger.kernel.org; intel-wired-lan@lists.osuosl.org; linux-
>kernel@vger.kernel.org; netdev@vger.kernel.org
>Subject: Re: [Intel-wired-lan] [PATCH v2] PCI: lock each enable/disable
>num_vfs operation in sysfs
>
>On Fri, 2017-01-06 at 13:59 -0800, Emil Tantilov wrote:
>> Enabling/disabling SRIOV via sysfs by echo-ing multiple values
>> simultaneously:
>>
>> echo 63 > /sys/class/net/ethX/device/sriov_numvfs&
>> echo 63 > /sys/class/net/ethX/device/sriov_numvfs
>>
>> sleep 5
>>
>> echo 0 > /sys/class/net/ethX/device/sriov_numvfs&
>> echo 0 > /sys/class/net/ethX/device/sriov_numvfs
>>
>> Results in the following bug:
>>
>> kernel BUG at drivers/pci/iov.c:495!
>> invalid opcode: 0000 [#1] SMP
>> CPU: 1 PID: 8050 Comm: bash Tainted: G W 4.9.0-rc7-net-next #2092
>> RIP: 0010:[<ffffffff813b1647>]
>> [<ffffffff813b1647>] pci_iov_release+0x57/0x60
>>
>> Call Trace:
>> [<ffffffff81391726>] pci_release_dev+0x26/0x70
>> [<ffffffff8155be6e>] device_release+0x3e/0xb0
>> [<ffffffff81365ee7>] kobject_cleanup+0x67/0x180
>> [<ffffffff81365d9d>] kobject_put+0x2d/0x60
>> [<ffffffff8155bc27>] put_device+0x17/0x20
>> [<ffffffff8139c08a>] pci_dev_put+0x1a/0x20
>> [<ffffffff8139cb6b>] pci_get_dev_by_id+0x5b/0x90
>> [<ffffffff8139cca5>] pci_get_subsys+0x35/0x40
>> [<ffffffff8139ccc8>] pci_get_device+0x18/0x20
>> [<ffffffff8139ccfb>] pci_get_domain_bus_and_slot+0x2b/0x60
>> [<ffffffff813b09e7>] pci_iov_remove_virtfn+0x57/0x180
>> [<ffffffff813b0b95>] pci_disable_sriov+0x65/0x140
>> [<ffffffffa00a1af7>] ixgbe_disable_sriov+0xc7/0x1d0 [ixgbe]
>> [<ffffffffa00a1e9d>] ixgbe_pci_sriov_configure+0x3d/0x170 [ixgbe]
>> [<ffffffff8139d28c>] sriov_numvfs_store+0xdc/0x130
>> ...
>> RIP [<ffffffff813b1647>] pci_iov_release+0x57/0x60
>>
>> Use the existing mutex lock to protect each enable/disable operation.
>>
>> -v2: move the existing lock from protecting the config of the IOV bus
>> to protecting the writes to sriov_numvfs in sysfs without maintaining
>> a "locked" version of pci_iov_add/remove_virtfn().
>> As suggested by Gavin Shan <gwshan@linux.vnet.ibm.com>
>>
>> CC: Alexander Duyck <alexander.h.duyck@intel.com>
>> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
>> ---
>> drivers/pci/iov.c | 7 -------
>> drivers/pci/pci-sysfs.c | 23 ++++++++++++++++-------
>> drivers/pci/pci.h | 2 +-
>> 3 files changed, 17 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
>> index 4722782..2479ae8 100644
>> --- a/drivers/pci/iov.c
>> +++ b/drivers/pci/iov.c
>> @@ -124,7 +124,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id,
>int reset)
>> struct pci_sriov *iov = dev->sriov;
>> struct pci_bus *bus;
>>
>> - mutex_lock(&iov->dev->sriov->lock);
>> bus = virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id));
>> if (!bus)
>> goto failed;
>> @@ -162,7 +161,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id,
>int reset)
>> __pci_reset_function(virtfn);
>>
>> pci_device_add(virtfn, virtfn->bus);
>> - mutex_unlock(&iov->dev->sriov->lock);
>>
>> pci_bus_add_device(virtfn);
>> sprintf(buf, "virtfn%u", id);
>> @@ -181,12 +179,10 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id,
>int reset)
>> sysfs_remove_link(&dev->dev.kobj, buf);
>> failed1:
>> pci_dev_put(dev);
>> - mutex_lock(&iov->dev->sriov->lock);
>> pci_stop_and_remove_bus_device(virtfn);
>> failed0:
>> virtfn_remove_bus(dev->bus, bus);
>> failed:
>> - mutex_unlock(&iov->dev->sriov->lock);
>>
>> return rc;
>> }
>> @@ -195,7 +191,6 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int
>id, int reset)
>> {
>> char buf[VIRTFN_ID_LEN];
>> struct pci_dev *virtfn;
>> - struct pci_sriov *iov = dev->sriov;
>>
>> virtfn = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus),
>> pci_iov_virtfn_bus(dev, id),
>> @@ -218,10 +213,8 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int
>id, int reset)
>> if (virtfn->dev.kobj.sd)
>> sysfs_remove_link(&virtfn->dev.kobj, "physfn");
>>
>> - mutex_lock(&iov->dev->sriov->lock);
>> pci_stop_and_remove_bus_device(virtfn);
>> virtfn_remove_bus(dev->bus, virtfn->bus);
>> - mutex_unlock(&iov->dev->sriov->lock);
>>
>> /* balance pci_get_domain_bus_and_slot() */
>> pci_dev_put(virtfn);
>> diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
>> index 0666287..25d010d 100644
>> --- a/drivers/pci/pci-sysfs.c
>> +++ b/drivers/pci/pci-sysfs.c
>> @@ -472,6 +472,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
>> const char *buf, size_t count)
>> {
>> struct pci_dev *pdev = to_pci_dev(dev);
>> + struct pci_sriov *iov = pdev->sriov;
>> int ret;
>> u16 num_vfs;
>>
>> @@ -482,38 +483,46 @@ static ssize_t sriov_numvfs_store(struct device
>*dev,
>> if (num_vfs > pci_sriov_get_totalvfs(pdev))
>> return -ERANGE;
>>
>> + mutex_lock(&iov->dev->sriov->lock);
>> +
>> if (num_vfs == pdev->sriov->num_VFs)
>> - return count; /* no change */
>> + goto exit;
>>
>> /* is PF driver loaded w/callback */
>> if (!pdev->driver || !pdev->driver->sriov_configure) {
>> dev_info(&pdev->dev, "Driver doesn't support SRIOV
>configuration via sysfs\n");
>> - return -ENOSYS;
>> + ret = -ENOENT;
>> + goto exit;
>
>Hi Emil,
>
>Generally the patch looks fine to me - but I am wondering why the change
>from -ENOSYS TO -ENOENT?
Because checkpatch was complaining that ENOSYS should only be used for
"invalid syscall nr".
If you look at the discussion of the previous version of the patch you can
see the details there. Basically Gavin preferred ENOENT and I don't really
care so much (I kind of ran into this by accident as this patch does not need
to change the error code).
Thanks,
Emil
^ permalink raw reply
* Re: [Intel-wired-lan] [PATCH v2] PCI: lock each enable/disable num_vfs operation in sysfs
From: Greg @ 2017-01-06 23:35 UTC (permalink / raw)
To: Tantilov, Emil S
Cc: linux-pci@vger.kernel.org, intel-wired-lan@lists.osuosl.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Gavin Shan
In-Reply-To: <87618083B2453E4A8714035B62D6799250744DCD@FMSMSX105.amr.corp.intel.com>
On Fri, 2017-01-06 at 23:28 +0000, Tantilov, Emil S wrote:
> >-----Original Message-----
> >From: Intel-wired-lan [mailto:intel-wired-lan-bounces@lists.osuosl.org] On
> >Behalf Of Greg
> >Sent: Friday, January 06, 2017 3:18 PM
> >To: Tantilov, Emil S <emil.s.tantilov@intel.com>
> >Cc: linux-pci@vger.kernel.org; intel-wired-lan@lists.osuosl.org; linux-
> >kernel@vger.kernel.org; netdev@vger.kernel.org
> >Subject: Re: [Intel-wired-lan] [PATCH v2] PCI: lock each enable/disable
> >num_vfs operation in sysfs
> >
> >On Fri, 2017-01-06 at 13:59 -0800, Emil Tantilov wrote:
> >> Enabling/disabling SRIOV via sysfs by echo-ing multiple values
> >> simultaneously:
> >>
> >> echo 63 > /sys/class/net/ethX/device/sriov_numvfs&
> >> echo 63 > /sys/class/net/ethX/device/sriov_numvfs
> >>
> >> sleep 5
> >>
> >> echo 0 > /sys/class/net/ethX/device/sriov_numvfs&
> >> echo 0 > /sys/class/net/ethX/device/sriov_numvfs
> >>
> >> Results in the following bug:
> >>
> >> kernel BUG at drivers/pci/iov.c:495!
> >> invalid opcode: 0000 [#1] SMP
> >> CPU: 1 PID: 8050 Comm: bash Tainted: G W 4.9.0-rc7-net-next #2092
> >> RIP: 0010:[<ffffffff813b1647>]
> >> [<ffffffff813b1647>] pci_iov_release+0x57/0x60
> >>
> >> Call Trace:
> >> [<ffffffff81391726>] pci_release_dev+0x26/0x70
> >> [<ffffffff8155be6e>] device_release+0x3e/0xb0
> >> [<ffffffff81365ee7>] kobject_cleanup+0x67/0x180
> >> [<ffffffff81365d9d>] kobject_put+0x2d/0x60
> >> [<ffffffff8155bc27>] put_device+0x17/0x20
> >> [<ffffffff8139c08a>] pci_dev_put+0x1a/0x20
> >> [<ffffffff8139cb6b>] pci_get_dev_by_id+0x5b/0x90
> >> [<ffffffff8139cca5>] pci_get_subsys+0x35/0x40
> >> [<ffffffff8139ccc8>] pci_get_device+0x18/0x20
> >> [<ffffffff8139ccfb>] pci_get_domain_bus_and_slot+0x2b/0x60
> >> [<ffffffff813b09e7>] pci_iov_remove_virtfn+0x57/0x180
> >> [<ffffffff813b0b95>] pci_disable_sriov+0x65/0x140
> >> [<ffffffffa00a1af7>] ixgbe_disable_sriov+0xc7/0x1d0 [ixgbe]
> >> [<ffffffffa00a1e9d>] ixgbe_pci_sriov_configure+0x3d/0x170 [ixgbe]
> >> [<ffffffff8139d28c>] sriov_numvfs_store+0xdc/0x130
> >> ...
> >> RIP [<ffffffff813b1647>] pci_iov_release+0x57/0x60
> >>
> >> Use the existing mutex lock to protect each enable/disable operation.
> >>
> >> -v2: move the existing lock from protecting the config of the IOV bus
> >> to protecting the writes to sriov_numvfs in sysfs without maintaining
> >> a "locked" version of pci_iov_add/remove_virtfn().
> >> As suggested by Gavin Shan <gwshan@linux.vnet.ibm.com>
> >>
> >> CC: Alexander Duyck <alexander.h.duyck@intel.com>
> >> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> >> ---
> >> drivers/pci/iov.c | 7 -------
> >> drivers/pci/pci-sysfs.c | 23 ++++++++++++++++-------
> >> drivers/pci/pci.h | 2 +-
> >> 3 files changed, 17 insertions(+), 15 deletions(-)
> >>
> >> diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
> >> index 4722782..2479ae8 100644
> >> --- a/drivers/pci/iov.c
> >> +++ b/drivers/pci/iov.c
> >> @@ -124,7 +124,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id,
> >int reset)
> >> struct pci_sriov *iov = dev->sriov;
> >> struct pci_bus *bus;
> >>
> >> - mutex_lock(&iov->dev->sriov->lock);
> >> bus = virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id));
> >> if (!bus)
> >> goto failed;
> >> @@ -162,7 +161,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id,
> >int reset)
> >> __pci_reset_function(virtfn);
> >>
> >> pci_device_add(virtfn, virtfn->bus);
> >> - mutex_unlock(&iov->dev->sriov->lock);
> >>
> >> pci_bus_add_device(virtfn);
> >> sprintf(buf, "virtfn%u", id);
> >> @@ -181,12 +179,10 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id,
> >int reset)
> >> sysfs_remove_link(&dev->dev.kobj, buf);
> >> failed1:
> >> pci_dev_put(dev);
> >> - mutex_lock(&iov->dev->sriov->lock);
> >> pci_stop_and_remove_bus_device(virtfn);
> >> failed0:
> >> virtfn_remove_bus(dev->bus, bus);
> >> failed:
> >> - mutex_unlock(&iov->dev->sriov->lock);
> >>
> >> return rc;
> >> }
> >> @@ -195,7 +191,6 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int
> >id, int reset)
> >> {
> >> char buf[VIRTFN_ID_LEN];
> >> struct pci_dev *virtfn;
> >> - struct pci_sriov *iov = dev->sriov;
> >>
> >> virtfn = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus),
> >> pci_iov_virtfn_bus(dev, id),
> >> @@ -218,10 +213,8 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int
> >id, int reset)
> >> if (virtfn->dev.kobj.sd)
> >> sysfs_remove_link(&virtfn->dev.kobj, "physfn");
> >>
> >> - mutex_lock(&iov->dev->sriov->lock);
> >> pci_stop_and_remove_bus_device(virtfn);
> >> virtfn_remove_bus(dev->bus, virtfn->bus);
> >> - mutex_unlock(&iov->dev->sriov->lock);
> >>
> >> /* balance pci_get_domain_bus_and_slot() */
> >> pci_dev_put(virtfn);
> >> diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
> >> index 0666287..25d010d 100644
> >> --- a/drivers/pci/pci-sysfs.c
> >> +++ b/drivers/pci/pci-sysfs.c
> >> @@ -472,6 +472,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
> >> const char *buf, size_t count)
> >> {
> >> struct pci_dev *pdev = to_pci_dev(dev);
> >> + struct pci_sriov *iov = pdev->sriov;
> >> int ret;
> >> u16 num_vfs;
> >>
> >> @@ -482,38 +483,46 @@ static ssize_t sriov_numvfs_store(struct device
> >*dev,
> >> if (num_vfs > pci_sriov_get_totalvfs(pdev))
> >> return -ERANGE;
> >>
> >> + mutex_lock(&iov->dev->sriov->lock);
> >> +
> >> if (num_vfs == pdev->sriov->num_VFs)
> >> - return count; /* no change */
> >> + goto exit;
> >>
> >> /* is PF driver loaded w/callback */
> >> if (!pdev->driver || !pdev->driver->sriov_configure) {
> >> dev_info(&pdev->dev, "Driver doesn't support SRIOV
> >configuration via sysfs\n");
> >> - return -ENOSYS;
> >> + ret = -ENOENT;
> >> + goto exit;
> >
> >Hi Emil,
> >
> >Generally the patch looks fine to me - but I am wondering why the change
> >from -ENOSYS TO -ENOENT?
>
> Because checkpatch was complaining that ENOSYS should only be used for
> "invalid syscall nr".
>
> If you look at the discussion of the previous version of the patch you can
> see the details there. Basically Gavin preferred ENOENT and I don't really
> care so much (I kind of ran into this by accident as this patch does not need
> to change the error code).
Ah, OK. Thanks for the explanation! Tell all my old buddies there at
Intel I said hi.
Regards,
- Greg
>
> Thanks,
> Emil
^ permalink raw reply
* RE: [PATCH v3] net: stmmac: fix maxmtu assignment to be within valid range
From: Kweh, Hock Leong @ 2017-01-06 23:38 UTC (permalink / raw)
To: Joao Pinto, David S. Miller, Giuseppe CAVALLARO,
seraphin.bonnaffe@st.com, Jarod Wilson, Andy Shevchenko
Cc: Alexandre TORGUE, Joachim Eastwood, Niklas Cassel, Johan Hovold,
pavel@ucw.cz, lars.persson@axis.com, netdev, LKML
In-Reply-To: <a7c3212f-1772-8e07-b9a3-3ebbb4150fc7@synopsys.com>
> -----Original Message-----
> From: Joao Pinto [mailto:Joao.Pinto@synopsys.com]
> Sent: Saturday, January 07, 2017 12:58 AM
> To: Kweh, Hock Leong <hock.leong.kweh@intel.com>; David S. Miller
> <davem@davemloft.net>; Joao Pinto <Joao.Pinto@synopsys.com>; Giuseppe
> CAVALLARO <peppe.cavallaro@st.com>; seraphin.bonnaffe@st.com; Jarod
> Wilson <jarod@redhat.com>; Andy Shevchenko <andy.shevchenko@gmail.com>
> Cc: Alexandre TORGUE <alexandre.torgue@gmail.com>; Joachim Eastwood
> <manabian@gmail.com>; Niklas Cassel <niklas.cassel@axis.com>; Johan Hovold
> <johan@kernel.org>; pavel@ucw.cz; lars.persson@axis.com; netdev
> <netdev@vger.kernel.org>; LKML <linux-kernel@vger.kernel.org>
> Subject: Re: [PATCH v3] net: stmmac: fix maxmtu assignment to be within valid
> range
>
>
> Hi Wilson,
>
> Às 12:49 AM de 1/7/2017, Kweh, Hock Leong escreveu:
> > From: "Kweh, Hock Leong" <hock.leong.kweh@intel.com>
> >
> > There is no checking valid value of maxmtu when getting it from device tree.
> > This resolution added the checking condition to ensure the assignment is
> > made within a valid range.
> >
> > Signed-off-by: Kweh, Hock Leong <hock.leong.kweh@intel.com>
> > ---
> > changelog v3:
> > * print the warning message only if maxmtu < min_mtu
> > * add maxmtu = JUMBO_LEN at stmmac_pci.c to follow stmmac_platform.c
> >
> > changelog v2:
> > * correction of "devicetree" to "device tree" reported by Andy
> > * print warning message while maxmtu is not in valid range
> >
> > drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 +++++++-
> > drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 4 ++++
> > 2 files changed, 11 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > index 92ac006..ce74ae6 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > @@ -3345,8 +3345,14 @@ int stmmac_dvr_probe(struct device *device,
> > ndev->max_mtu = JUMBO_LEN;
> > else
> > ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD +
> NET_IP_ALIGN);
> > - if (priv->plat->maxmtu < ndev->max_mtu)
> > +
> > + if ((priv->plat->maxmtu < ndev->max_mtu) &&
> > + (priv->plat->maxmtu >= ndev->min_mtu))
> > ndev->max_mtu = priv->plat->maxmtu;
> > + else if (priv->plat->maxmtu < ndev->min_mtu)
> > + netdev_warn(priv->dev,
> > + "%s: warning: maxmtu having invalid value (%d)\n",
> > + __func__, priv->plat->maxmtu);
> >
> > if (flow_ctrl)
> > priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
> b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
> > index a283177..e539afe 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
> > @@ -204,6 +204,10 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
> >
> > pci_set_master(pdev);
> >
> > + /* Set the maxmtu to a default of JUMBO_LEN in case the
> > + * parameter is not defined for the device.
> > + */
> > + plat->maxmtu = JUMBO_LEN;
>
> I suggest to put this configuration in one of the default config functions.
>
> Tahnks.
>
My original thought is to have one line for all *_default_data() instead of having
multiple same line inside each *_default_data(). If this is not a big concern of
future expand, I can do that. Thanks.
> > if (info) {
> > info->pdev = pdev;
> > if (info->setup) {
> >
^ permalink raw reply
* Re: [PATCHv1 7/7] IPVTAP: IP-VLAN based tap driver
From: Mahesh Bandewar (महेश बंडेवार) @ 2017-01-06 23:46 UTC (permalink / raw)
To: Sainath Grandhi; +Cc: linux-netdev, David Miller, mahesh, linux-kernel
In-Reply-To: <1483742009-19184-8-git-send-email-sainath.grandhi@intel.com>
few superficial comments inline.
On Fri, Jan 6, 2017 at 2:33 PM, Sainath Grandhi
<sainath.grandhi@intel.com> wrote:
> This patch adds a tap character device driver that is based on the
> IP-VLAN network interface, called ipvtap. An ipvtap device can be created
> in the same way as an ipvlan device, using 'type ipvtap', and then accessed
> using the tap user space interface.
>
> Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
> Tested-by: Sainath Grandhi <sainath.grandhi@intel.com>
> ---
> drivers/net/Kconfig | 12 ++
> drivers/net/Makefile | 1 +
> drivers/net/ipvlan/Makefile | 1 +
> drivers/net/ipvlan/ipvlan.h | 7 ++
> drivers/net/ipvlan/ipvlan_core.c | 5 +-
> drivers/net/ipvlan/ipvlan_main.c | 37 +++---
> drivers/net/ipvlan/ipvtap.c | 238 +++++++++++++++++++++++++++++++++++++++
> 7 files changed, 282 insertions(+), 19 deletions(-)
> create mode 100644 drivers/net/ipvlan/ipvtap.c
>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 280380d..ddfb30a 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -165,6 +165,18 @@ config IPVLAN
> To compile this driver as a module, choose M here: the module
> will be called ipvlan.
>
> +config IPVTAP
> + tristate "IP-VLAN based tap driver"
> + depends on IPVLAN
> + depends on INET
> + help
> + This adds a specialized tap character device driver that is based
> + on the IP-VLAN network interface, called ipvtap. An ipvtap device
> + can be added in the same way as a ipvlan device, using 'type
> + ipvtap', and then be accessed through the tap user space interface.
> +
> + To compile this driver as a module, choose M here: the module
> + will be called macvtap.
>
> config VXLAN
> tristate "Virtual eXtensible Local Area Network (VXLAN)"
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index 7dd86ca..98ed4d9 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -7,6 +7,7 @@
> #
> obj-$(CONFIG_BONDING) += bonding/
> obj-$(CONFIG_IPVLAN) += ipvlan/
> +obj-$(CONFIG_IPVTAP) += ipvlan/
> obj-$(CONFIG_DUMMY) += dummy.o
> obj-$(CONFIG_EQUALIZER) += eql.o
> obj-$(CONFIG_IFB) += ifb.o
> diff --git a/drivers/net/ipvlan/Makefile b/drivers/net/ipvlan/Makefile
> index df79910..8a2c64d 100644
> --- a/drivers/net/ipvlan/Makefile
> +++ b/drivers/net/ipvlan/Makefile
> @@ -3,5 +3,6 @@
> #
>
> obj-$(CONFIG_IPVLAN) += ipvlan.o
> +obj-$(CONFIG_IPVTAP) += ipvtap.o
>
> ipvlan-objs := ipvlan_core.o ipvlan_main.o
> diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h
> index dbfbb33..4362d88 100644
> --- a/drivers/net/ipvlan/ipvlan.h
> +++ b/drivers/net/ipvlan/ipvlan.h
> @@ -133,4 +133,11 @@ struct sk_buff *ipvlan_l3_rcv(struct net_device *dev, struct sk_buff *skb,
> u16 proto);
> unsigned int ipvlan_nf_input(void *priv, struct sk_buff *skb,
> const struct nf_hook_state *state);
> +void ipvlan_count_rx(const struct ipvl_dev *ipvlan,
> + unsigned int len, bool success, bool mcast);
> +int ipvlan_link_new(struct net *src_net, struct net_device *dev,
> + struct nlattr *tb[], struct nlattr *data[]);
> +void ipvlan_link_delete(struct net_device *dev, struct list_head *head);
> +void ipvlan_link_setup(struct net_device *dev);
> +int ipvlan_link_register(struct rtnl_link_ops *ops);
> #endif /* __IPVLAN_H */
> diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
> index 83ce74a..9af16ab 100644
> --- a/drivers/net/ipvlan/ipvlan_core.c
> +++ b/drivers/net/ipvlan/ipvlan_core.c
> @@ -16,8 +16,8 @@ void ipvlan_init_secret(void)
> net_get_random_once(&ipvlan_jhash_secret, sizeof(ipvlan_jhash_secret));
> }
>
> -static void ipvlan_count_rx(const struct ipvl_dev *ipvlan,
> - unsigned int len, bool success, bool mcast)
> +void ipvlan_count_rx(const struct ipvl_dev *ipvlan,
> + unsigned int len, bool success, bool mcast)
> {
> if (!ipvlan)
> return;
> @@ -36,6 +36,7 @@ static void ipvlan_count_rx(const struct ipvl_dev *ipvlan,
> this_cpu_inc(ipvlan->pcpu_stats->rx_errs);
> }
> }
> +EXPORT_SYMBOL_GPL(ipvlan_count_rx);
Why export, isn't just removing 'static' enough?
>
> static u8 ipvlan_get_v6_hash(const void *iaddr)
> {
> diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
> index 8b0f993..666a05d 100644
> --- a/drivers/net/ipvlan/ipvlan_main.c
> +++ b/drivers/net/ipvlan/ipvlan_main.c
> @@ -13,14 +13,14 @@ static u32 ipvl_nf_hook_refcnt = 0;
>
> static struct nf_hook_ops ipvl_nfops[] __read_mostly = {
> {
> - .hook = ipvlan_nf_input,
> - .pf = NFPROTO_IPV4,
> + .hook = ipvlan_nf_input,
> + .pf = NFPROTO_IPV4,
spurious?
> .hooknum = NF_INET_LOCAL_IN,
> .priority = INT_MAX,
> },
> {
> - .hook = ipvlan_nf_input,
> - .pf = NFPROTO_IPV6,
> + .hook = ipvlan_nf_input,
> + .pf = NFPROTO_IPV6,
spurious??
> .hooknum = NF_INET_LOCAL_IN,
> .priority = INT_MAX,
> },
> @@ -398,7 +398,7 @@ static int ipvlan_hard_header(struct sk_buff *skb, struct net_device *dev,
> }
>
> static const struct header_ops ipvlan_header_ops = {
> - .create = ipvlan_hard_header,
> + .create = ipvlan_hard_header,
spurious???
> .parse = eth_header_parse,
> .cache = eth_header_cache,
> .cache_update = eth_header_cache_update,
> @@ -494,8 +494,8 @@ static int ipvlan_nl_fillinfo(struct sk_buff *skb,
> return ret;
> }
>
> -static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
> - struct nlattr *tb[], struct nlattr *data[])
> +int ipvlan_link_new(struct net *src_net, struct net_device *dev,
> + struct nlattr *tb[], struct nlattr *data[])
> {
> struct ipvl_dev *ipvlan = netdev_priv(dev);
> struct ipvl_port *port;
> @@ -567,8 +567,9 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
> ipvlan_port_destroy(phy_dev);
> return err;
> }
> +EXPORT_SYMBOL_GPL(ipvlan_link_new);
>
> -static void ipvlan_link_delete(struct net_device *dev, struct list_head *head)
> +void ipvlan_link_delete(struct net_device *dev, struct list_head *head)
> {
> struct ipvl_dev *ipvlan = netdev_priv(dev);
> struct ipvl_addr *addr, *next;
> @@ -583,8 +584,9 @@ static void ipvlan_link_delete(struct net_device *dev, struct list_head *head)
> unregister_netdevice_queue(dev, head);
> netdev_upper_dev_unlink(ipvlan->phy_dev, dev);
> }
> +EXPORT_SYMBOL_GPL(ipvlan_link_delete);
>
> -static void ipvlan_link_setup(struct net_device *dev)
> +void ipvlan_link_setup(struct net_device *dev)
> {
> ether_setup(dev);
>
> @@ -595,6 +597,7 @@ static void ipvlan_link_setup(struct net_device *dev)
> dev->header_ops = &ipvlan_header_ops;
> dev->ethtool_ops = &ipvlan_ethtool_ops;
> }
> +EXPORT_SYMBOL_GPL(ipvlan_link_setup);
>
> static const struct nla_policy ipvlan_nl_policy[IFLA_IPVLAN_MAX + 1] =
> {
> @@ -605,22 +608,22 @@ static struct rtnl_link_ops ipvlan_link_ops = {
> .kind = "ipvlan",
> .priv_size = sizeof(struct ipvl_dev),
>
> - .get_size = ipvlan_nl_getsize,
> - .policy = ipvlan_nl_policy,
> - .validate = ipvlan_nl_validate,
> - .fill_info = ipvlan_nl_fillinfo,
> - .changelink = ipvlan_nl_changelink,
> - .maxtype = IFLA_IPVLAN_MAX,
> -
> .setup = ipvlan_link_setup,
> .newlink = ipvlan_link_new,
> .dellink = ipvlan_link_delete,
> };
>
> -static int ipvlan_link_register(struct rtnl_link_ops *ops)
> +int ipvlan_link_register(struct rtnl_link_ops *ops)
> {
> + ops->get_size = ipvlan_nl_getsize;
> + ops->policy = ipvlan_nl_policy;
> + ops->validate = ipvlan_nl_validate;
> + ops->fill_info = ipvlan_nl_fillinfo;
> + ops->changelink = ipvlan_nl_changelink;
> + ops->maxtype = IFLA_IPVLAN_MAX;
> return rtnl_link_register(ops);
> }
> +EXPORT_SYMBOL_GPL(ipvlan_link_register);
>
> static int ipvlan_device_event(struct notifier_block *unused,
> unsigned long event, void *ptr)
> diff --git a/drivers/net/ipvlan/ipvtap.c b/drivers/net/ipvlan/ipvtap.c
> new file mode 100644
> index 0000000..0422cdf
> --- /dev/null
> +++ b/drivers/net/ipvlan/ipvtap.c
> @@ -0,0 +1,238 @@
> +#include <linux/etherdevice.h>
> +#include "ipvlan.h"
> +#include <linux/if_vlan.h>
> +#include <linux/if_tap.h>
> +#include <linux/interrupt.h>
> +#include <linux/nsproxy.h>
> +#include <linux/compat.h>
> +#include <linux/if_tun.h>
> +#include <linux/module.h>
> +#include <linux/skbuff.h>
> +#include <linux/cache.h>
> +#include <linux/sched.h>
> +#include <linux/types.h>
> +#include <linux/slab.h>
> +#include <linux/wait.h>
> +#include <linux/cdev.h>
> +#include <linux/idr.h>
> +#include <linux/fs.h>
> +#include <linux/uio.h>
> +
> +#include <net/net_namespace.h>
> +#include <net/rtnetlink.h>
> +#include <net/sock.h>
> +#include <linux/virtio_net.h>
> +
> +#define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \
> + NETIF_F_TSO6 | NETIF_F_UFO)
> +
> +static dev_t ipvtap_major;
> +static struct cdev ipvtap_cdev;
> +
> +static const void *ipvtap_net_namespace(struct device *d)
> +{
> + struct net_device *dev = to_net_dev(d->parent);
> + return dev_net(dev);
> +}
> +
> +static struct class ipvtap_class = {
> + .name = "ipvtap",
> + .owner = THIS_MODULE,
> + .ns_type = &net_ns_type_operations,
> + .namespace = ipvtap_net_namespace,
> +};
> +
> +struct ipvtap_dev {
> + struct ipvl_dev vlan;
> + struct tap_dev tap;
> +};
> +
> +static void ipvtap_count_tx_dropped(struct tap_dev *tap)
> +{
> + struct ipvl_dev *vlan = (struct ipvl_dev *)container_of(tap, struct ipvtap_dev, tap);
> +
> + this_cpu_inc(vlan->pcpu_stats->tx_drps);
> +}
> +
> +static void ipvtap_count_rx_dropped(struct tap_dev *tap)
> +{
> + struct ipvl_dev *vlan = (struct ipvl_dev *)container_of(tap, struct ipvtap_dev, tap);
> +
> + ipvlan_count_rx(vlan, 0, 0, 0);
> +}
> +
> +static void ipvtap_update_features(struct tap_dev *tap,
> + netdev_features_t features)
> +{
> + struct ipvl_dev *vlan = (struct ipvl_dev *)container_of(tap, struct ipvtap_dev, tap);
> +
> + vlan->sfeatures = features;
> + netdev_update_features(vlan->dev);
> +}
> +
> +static int ipvtap_newlink(struct net *src_net,
> + struct net_device *dev,
> + struct nlattr *tb[],
> + struct nlattr *data[])
> +{
> + struct ipvtap_dev *vlantap = netdev_priv(dev);
> + int err;
> +
> + INIT_LIST_HEAD(&vlantap->tap.queue_list);
> +
> + /* Since macvlan supports all offloads by default, make
> + * tap support all offloads also.
> + */
> + vlantap->tap.tap_features = TUN_OFFLOADS;
> + vlantap->tap.count_tx_dropped = ipvtap_count_tx_dropped;
> + vlantap->tap.update_features = ipvtap_update_features;
> + vlantap->tap.count_rx_dropped = ipvtap_count_rx_dropped;
> +
> + err = netdev_rx_handler_register(dev, tap_handle_frame, &vlantap->tap);
> + if (err)
> + return err;
> +
> + /* Don't put anything that may fail after macvlan_common_newlink
> + * because we can't undo what it does.
> + */
> + err = ipvlan_link_new(src_net, dev, tb, data);
> + if (err) {
> + netdev_rx_handler_unregister(dev);
> + return err;
> + }
> +
> + vlantap->tap.dev = vlantap->vlan.dev;
> +
> + return err;
> +}
> +
> +static void ipvtap_dellink(struct net_device *dev,
> + struct list_head *head)
> +{
> + struct ipvtap_dev *vlan = netdev_priv(dev);
> +
> + netdev_rx_handler_unregister(dev);
> + tap_del_queues(&vlan->tap);
> + ipvlan_link_delete(dev, head);
> +}
> +
> +static void ipvtap_setup(struct net_device *dev)
> +{
> + ipvlan_link_setup(dev);
> + dev->tx_queue_len = TUN_READQ_SIZE;
> + dev->priv_flags &= ~IFF_NO_QUEUE;
> +}
> +
> +static struct rtnl_link_ops ipvtap_link_ops __read_mostly = {
> + .kind = "ipvtap",
> + .setup = ipvtap_setup,
> + .newlink = ipvtap_newlink,
> + .dellink = ipvtap_dellink,
> + .priv_size = sizeof(struct ipvtap_dev),
> +};
> +
> +static int ipvtap_device_event(struct notifier_block *unused,
> + unsigned long event, void *ptr)
> +{
> + struct net_device *dev = netdev_notifier_info_to_dev(ptr);
> + struct ipvtap_dev *vlantap;
> + struct device *classdev;
> + dev_t devt;
> + int err;
> + char tap_name[IFNAMSIZ];
> +
> + if (dev->rtnl_link_ops != &ipvtap_link_ops)
> + return NOTIFY_DONE;
> +
> + snprintf(tap_name, IFNAMSIZ, "tap%d", dev->ifindex);
> + vlantap = netdev_priv(dev);
> +
> + switch (event) {
> + case NETDEV_REGISTER:
> + /* Create the device node here after the network device has
> + * been registered but before register_netdevice has
> + * finished running.
> + */
> + err = tap_get_minor(ipvtap_major, &vlantap->tap);
> + if (err)
> + return notifier_from_errno(err);
> +
> + devt = MKDEV(MAJOR(ipvtap_major), vlantap->tap.minor);
> + classdev = device_create(&ipvtap_class, &dev->dev, devt,
> + dev, tap_name);
> + if (IS_ERR(classdev)) {
> + tap_free_minor(ipvtap_major, &vlantap->tap);
> + return notifier_from_errno(PTR_ERR(classdev));
> + }
> + err = sysfs_create_link(&dev->dev.kobj, &classdev->kobj,
> + tap_name);
> + if (err)
> + return notifier_from_errno(err);
> + break;
> + case NETDEV_UNREGISTER:
> + /* vlan->minor == 0 if NETDEV_REGISTER above failed */
> + if (vlantap->tap.minor == 0)
> + break;
> + sysfs_remove_link(&dev->dev.kobj, tap_name);
> + devt = MKDEV(MAJOR(ipvtap_major), vlantap->tap.minor);
> + device_destroy(&ipvtap_class, devt);
> + tap_free_minor(ipvtap_major, &vlantap->tap);
> + break;
> + case NETDEV_CHANGE_TX_QUEUE_LEN:
> + if (tap_queue_resize(&vlantap->tap))
> + return NOTIFY_BAD;
> + break;
> + }
> +
> + return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block ipvtap_notifier_block __read_mostly = {
> + .notifier_call = ipvtap_device_event,
> +};
> +
> +static int ipvtap_init(void)
> +{
> + int err;
> +
> + err = tap_create_cdev(&ipvtap_cdev, &ipvtap_major, "ipvtap");
> +
> + if (err)
> + goto out1;
> +
> + err = class_register(&ipvtap_class);
> + if (err)
> + goto out2;
> +
> + err = register_netdevice_notifier(&ipvtap_notifier_block);
> + if (err)
> + goto out3;
> +
> + err = ipvlan_link_register(&ipvtap_link_ops);
> + if (err)
> + goto out4;
> +
> + return 0;
> +
> +out4:
> + unregister_netdevice_notifier(&ipvtap_notifier_block);
> +out3:
> + class_unregister(&ipvtap_class);
> +out2:
> + cdev_del(&ipvtap_cdev);
> +out1:
> + return err;
> +}
> +module_init(ipvtap_init);
> +
> +static void ipvtap_exit(void)
> +{
> + rtnl_link_unregister(&ipvtap_link_ops);
> + unregister_netdevice_notifier(&ipvtap_notifier_block);
> + class_unregister(&ipvtap_class);
> + tap_destroy_cdev(ipvtap_major, &ipvtap_cdev);
> +}
> +module_exit(ipvtap_exit);
> +MODULE_ALIAS_RTNL_LINK("ipvtap");
> +MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>");
> +MODULE_LICENSE("GPL");
> --
> 2.7.4
>
^ permalink raw reply
* RE: [PATCH v3] net: stmmac: fix maxmtu assignment to be within valid range
From: Kweh, Hock Leong @ 2017-01-06 23:47 UTC (permalink / raw)
To: Andy Shevchenko
Cc: David S. Miller, Joao Pinto, Giuseppe CAVALLARO,
seraphin.bonnaffe@st.com, Jarod Wilson, Alexandre TORGUE,
Joachim Eastwood, Niklas Cassel, Johan Hovold, Pavel Machek,
lars.persson@axis.com, netdev, LKML
In-Reply-To: <CAHp75VdkGcQM_fW6LLuQ1JC67p4vGNWKcyxPs5Sc-4tFi2MGLg@mail.gmail.com>
> -----Original Message-----
> From: Andy Shevchenko [mailto:andy.shevchenko@gmail.com]
> Sent: Saturday, January 07, 2017 1:07 AM
> To: Kweh, Hock Leong <hock.leong.kweh@intel.com>
> Cc: David S. Miller <davem@davemloft.net>; Joao Pinto
> <Joao.Pinto@synopsys.com>; Giuseppe CAVALLARO <peppe.cavallaro@st.com>;
> seraphin.bonnaffe@st.com; Jarod Wilson <jarod@redhat.com>; Alexandre
> TORGUE <alexandre.torgue@gmail.com>; Joachim Eastwood
> <manabian@gmail.com>; Niklas Cassel <niklas.cassel@axis.com>; Johan Hovold
> <johan@kernel.org>; Pavel Machek <pavel@ucw.cz>; lars.persson@axis.com;
> netdev <netdev@vger.kernel.org>; LKML <linux-kernel@vger.kernel.org>
> Subject: Re: [PATCH v3] net: stmmac: fix maxmtu assignment to be within valid
> range
>
> On Sat, Jan 7, 2017 at 2:49 AM, Kweh, Hock Leong
> <hock.leong.kweh@intel.com> wrote:
> > From: "Kweh, Hock Leong" <hock.leong.kweh@intel.com>
> >
> > There is no checking valid value of maxmtu when getting it from device tree.
> > This resolution added the checking condition to ensure the assignment is
> > made within a valid range.
>
> > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > @@ -3345,8 +3345,14 @@ int stmmac_dvr_probe(struct device *device,
> > ndev->max_mtu = JUMBO_LEN;
> > else
> > ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN);
> > - if (priv->plat->maxmtu < ndev->max_mtu)
>
> > +
>
> The lines are logically grouped here. No need to split it. Thus,
> remove this extra line.
>
Ok noted.
> > + if ((priv->plat->maxmtu < ndev->max_mtu) &&
> > + (priv->plat->maxmtu >= ndev->min_mtu))
>
> > ndev->max_mtu = priv->plat->maxmtu;
>
> > + else if (priv->plat->maxmtu < ndev->min_mtu)
>
> And if it > ndev->max_mtu?..
>
Base on my understanding to the original code, the "maxmtu >= ndev->max_mtu"
is meant for products that would want to use the value from logic which is just above
this statement where you just ask me not to add new line. That the reason the
stmmac_platform.c put in "plat->maxmtu = JUMBO_LEN;" as generic and I also
follow it in stmmac_pci.c.
Or do you mean only take maxmtu = JUMBO_LEN for the option to use driver itself
assignment statement above and all the > max_mtu consider invalid?
> > + netdev_warn(priv->dev,
> > + "%s: warning: maxmtu having invalid value (%d)\n",
> > + __func__, priv->plat->maxmtu);
>
>
> > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
> > @@ -204,6 +204,10 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
> >
> > pci_set_master(pdev);
> >
> > + /* Set the maxmtu to a default of JUMBO_LEN in case the
> > + * parameter is not defined for the device.
> > + */
> > + plat->maxmtu = JUMBO_LEN;
>
> Please, use *_default_data() hooks for that.
>
> At some point it might make sense to extract
> static int common_default_data() {...}
> and call it at the beginning of the rest of *_defautl_data() hooks.
>
Just try to understand, are you referring changing the code something
like this:
stmmac_default_data(plat);
if (info) {
info->pdev = pdev;
if (info->setup) {
ret = info->setup(plat, info);
if (ret)
return ret;
}
}
Where all the common code is inside the stmmac_default_data()?
Anyway, this patch is focus for fixing the maxmtu assignment in valid range.
I will submit V4 to put "plat->maxmtu = JUMBO_LEN;" into each *_default_data().
Regarding the common_default_data() would be a new patch for better code
structuring. Thanks.
> --
> With Best Regards,
> Andy Shevchenko
^ permalink raw reply
* [PATCH v4] net: stmmac: fix maxmtu assignment to be within valid range
From: Kweh, Hock Leong @ 2017-01-07 8:10 UTC (permalink / raw)
To: David S. Miller, Joao Pinto, Giuseppe CAVALLARO,
seraphin.bonnaffe, Jarod Wilson, Andy Shevchenko
Cc: Alexandre TORGUE, Joachim Eastwood, Niklas Cassel, Johan Hovold,
pavel, Kweh, Hock Leong, lars.persson, netdev, LKML
From: "Kweh, Hock Leong" <hock.leong.kweh@intel.com>
There is no checking valid value of maxmtu when getting it from device tree.
This resolution added the checking condition to ensure the assignment is
made within a valid range.
Signed-off-by: Kweh, Hock Leong <hock.leong.kweh@intel.com>
---
changelog v4:
* add print warning message when maxmtu > max_mtu as well
* add maxmtu = JUMBO_LEN into each *_default_data() at stmmac_pci.c
changelog v3:
* print the warning message only if maxmtu < min_mtu
* add maxmtu = JUMBO_LEN at stmmac_pci.c to follow stmmac_platform.c
changelog v2:
* correction of "devicetree" to "device tree" reported by Andy
* print warning message while maxmtu is not in valid range
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 +++++++-
drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 6 ++++++
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 92ac006..f2a352f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3345,8 +3345,14 @@ int stmmac_dvr_probe(struct device *device,
ndev->max_mtu = JUMBO_LEN;
else
ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN);
- if (priv->plat->maxmtu < ndev->max_mtu)
+ if ((priv->plat->maxmtu < ndev->max_mtu) &&
+ (priv->plat->maxmtu >= ndev->min_mtu))
ndev->max_mtu = priv->plat->maxmtu;
+ else if ((priv->plat->maxmtu < ndev->min_mtu) ||
+ (priv->plat->maxmtu > ndev->max_mtu))
+ netdev_warn(priv->dev,
+ "%s: warning: maxmtu having invalid value (%d)\n",
+ __func__, priv->plat->maxmtu);
if (flow_ctrl)
priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
index a283177..3da4737 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
@@ -89,6 +89,9 @@ static void stmmac_default_data(struct plat_stmmacenet_data *plat)
/* Set default value for unicast filter entries */
plat->unicast_filter_entries = 1;
+
+ /* Set the maxmtu to a default of JUMBO_LEN */
+ plat->maxmtu = JUMBO_LEN;
}
static int quark_default_data(struct plat_stmmacenet_data *plat,
@@ -126,6 +129,9 @@ static int quark_default_data(struct plat_stmmacenet_data *plat,
/* Set default value for unicast filter entries */
plat->unicast_filter_entries = 1;
+ /* Set the maxmtu to a default of JUMBO_LEN */
+ plat->maxmtu = JUMBO_LEN;
+
return 0;
}
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH v3] net: stmmac: fix maxmtu assignment to be within valid range
From: Andy Shevchenko @ 2017-01-07 0:07 UTC (permalink / raw)
To: Kweh, Hock Leong
Cc: David S. Miller, Joao Pinto, Giuseppe CAVALLARO,
seraphin.bonnaffe@st.com, Jarod Wilson, Alexandre TORGUE,
Joachim Eastwood, Niklas Cassel, Johan Hovold, Pavel Machek,
lars.persson@axis.com, netdev, LKML
In-Reply-To: <F54AEECA5E2B9541821D670476DAE19C5A918C87@PGSMSX102.gar.corp.intel.com>
On Sat, Jan 7, 2017 at 1:47 AM, Kweh, Hock Leong
<hock.leong.kweh@intel.com> wrote:
>> > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> > @@ -3345,8 +3345,14 @@ int stmmac_dvr_probe(struct device *device,
>> > ndev->max_mtu = JUMBO_LEN;
>> > else
>> > ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN);
>> > - if (priv->plat->maxmtu < ndev->max_mtu)
>>
>> > + if ((priv->plat->maxmtu < ndev->max_mtu) &&
>> > + (priv->plat->maxmtu >= ndev->min_mtu))
>>
>> > ndev->max_mtu = priv->plat->maxmtu;
>>
>> > + else if (priv->plat->maxmtu < ndev->min_mtu)
>>
>> And if it > ndev->max_mtu?..
>>
>
> Base on my understanding to the original code, the "maxmtu >= ndev->max_mtu"
> is meant for products that would want to use the value from logic which is just above
> this statement where you just ask me not to add new line. That the reason the
> stmmac_platform.c put in "plat->maxmtu = JUMBO_LEN;" as generic and I also
> follow it in stmmac_pci.c.
>
> Or do you mean only take maxmtu = JUMBO_LEN for the option to use driver itself
> assignment statement above and all the > max_mtu consider invalid?
So, just answer to the simple question: is it a valid case to have
plat->maxmtu > ndev->max_mtu? If it so, how is it used?
Otherwise we need a warning in such case. What did I miss?
>
>> > + netdev_warn(priv->dev,
>> > + "%s: warning: maxmtu having invalid value (%d)\n",
>> > + __func__, priv->plat->maxmtu);
>> > + /* Set the maxmtu to a default of JUMBO_LEN in case the
>> > + * parameter is not defined for the device.
>> > + */
>> > + plat->maxmtu = JUMBO_LEN;
>>
>> Please, use *_default_data() hooks for that.
>>
>> At some point it might make sense to extract
>> static int common_default_data() {...}
>> and call it at the beginning of the rest of *_defautl_data() hooks.
>>
>
> Just try to understand, are you referring changing the code something
> like this:
>
> stmmac_default_data(plat);
> if (info) {
> info->pdev = pdev;
> if (info->setup) {
> ret = info->setup(plat, info);
> if (ret)
> return ret;
> }
> }
>
> Where all the common code is inside the stmmac_default_data()?
No.
common_default_data()
{
... common defaults among *_default_data() ...
}
*_default_data()
{
...
common_default_data();
...
}
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH v4] net: stmmac: fix maxmtu assignment to be within valid range
From: Andy Shevchenko @ 2017-01-07 0:12 UTC (permalink / raw)
To: Kweh, Hock Leong
Cc: David S. Miller, Joao Pinto, Giuseppe CAVALLARO,
seraphin.bonnaffe, Jarod Wilson, Alexandre TORGUE,
Joachim Eastwood, Niklas Cassel, Johan Hovold, Pavel Machek,
lars.persson, netdev, LKML
In-Reply-To: <1483776634-13095-1-git-send-email-hock.leong.kweh@intel.com>
On Sat, Jan 7, 2017 at 10:10 AM, Kweh, Hock Leong
<hock.leong.kweh@intel.com> wrote:
> From: "Kweh, Hock Leong" <hock.leong.kweh@intel.com>
>
> There is no checking valid value of maxmtu when getting it from device tree.
> This resolution added the checking condition to ensure the assignment is
> made within a valid range.
> changelog v4:
> * add print warning message when maxmtu > max_mtu as well
Yep.
> * add maxmtu = JUMBO_LEN into each *_default_data() at stmmac_pci.c
Yep.
But see comment below.
P.S. And perhaps next time send into our internal mailing list first for review.
> @@ -3345,8 +3345,14 @@ int stmmac_dvr_probe(struct device *device,
> ndev->max_mtu = JUMBO_LEN;
> else
> ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN);
> - if (priv->plat->maxmtu < ndev->max_mtu)
> + if ((priv->plat->maxmtu < ndev->max_mtu) &&
> + (priv->plat->maxmtu >= ndev->min_mtu))
> ndev->max_mtu = priv->plat->maxmtu;
> + else if ((priv->plat->maxmtu < ndev->min_mtu) ||
> + (priv->plat->maxmtu > ndev->max_mtu))
> + netdev_warn(priv->dev,
What is the difference to just 'else'? (Returning back to my initial
proposal, I don't remember telling anything about 'else if' concept)
> + "%s: warning: maxmtu having invalid value (%d)\n",
> + __func__, priv->plat->maxmtu);
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH v2 02/12] net: ethernet: aquantia: Common functions and definitions
From: Lino Sanfilippo @ 2017-01-07 0:29 UTC (permalink / raw)
To: Alexander Loktionov, netdev, David VomLehn
Cc: Simon Edelhaus, Dmitrii Tarakanov, Pavel Belous
In-Reply-To: <41e24066f2a87cad644a902658846e109a6b406f.1483689029.git.vomlehn@texas.net>
Hi,
On 06.01.2017 09:06, Alexander Loktionov wrote:
> +
> +#define TXT(_T_) #_T_
> +#define TXTTXT(_T_) TXT(_T_)
do you really need these (IMHO ugly) macros? AFAICS you only use them to
build the driver
version string.
> +
> +#define AQ_CFG_DRV_AUTHOR "aQuantia"
> +#define AQ_CFG_DRV_DESC "aQuantia Corporation(R) Network Driver"
> +#define AQ_CFG_DRV_NAME "aquantia"
> +#define AQ_CFG_DRV_VERSION TXTTXT(NIC_MAJOR_DRIVER_VERSION)"."\
> + TXTTXT(NIC_MINOR_DRIVER_VERSION)"."\
> + TXTTXT(NIC_BUILD_DRIVER_VERSION)"."\
> + TXTTXT(NIC_REVISION_DRIVER_VERSION)
Regards,
Lino
^ permalink raw reply
* [PATCH next v1] ipvlan: don't use IDR for generating dev_id
From: Mahesh Bandewar @ 2017-01-07 0:33 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Mahesh Bandewar, Mahesh Bandewar, Eric Dumazet
From: Mahesh Bandewar <maheshb@google.com>
The patch 009146d117b ("ipvlan: assign unique dev-id for each slave
device.") used ida_simple_get() to generate dev_ids assigned to the
slave devices. However (Eric has pointed out that) there is a shortcoming
with that approach as it always uses the first available ID. This
becomes a problem when a slave gets deleted and a new slave gets added.
The ID gets reassigned causing the new slave to get the same link-local
address. This side-effect is undesirable.
This patch replaces IDR logic with a simple per-port variable that keeps
incrementing and wraps around when the MAX (0xFFFE) is reached. The
only downside is that this is an inefficient (n^2) search if there are
64k (or close to 64k) slaves in the system, the dev-id search takes time.
However having these many devices in the system has it's own challenges.
Fixes: 009146d117b ("ipvlan: assign unique dev-id for each slave device.")
Signed-off-by: Mahesh Bandewar <maheshb@google.com>
CC: Eric Dumazet <edumazet@google.com>
---
drivers/net/ipvlan/ipvlan.h | 2 +-
drivers/net/ipvlan/ipvlan_main.c | 69 ++++++++++++++++++++++++++++++++++------
2 files changed, 61 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h
index 0a9068fdee0f..535f254324ba 100644
--- a/drivers/net/ipvlan/ipvlan.h
+++ b/drivers/net/ipvlan/ipvlan.h
@@ -94,10 +94,10 @@ struct ipvl_port {
struct hlist_head hlhead[IPVLAN_HASH_SIZE];
struct list_head ipvlans;
u16 mode;
+ u16 dev_id_base;
struct work_struct wq;
struct sk_buff_head backlog;
int count;
- struct ida ida;
};
struct ipvl_skb_cb {
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index ce7ca6a5aa8a..691662e02abb 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -119,7 +119,7 @@ static int ipvlan_port_create(struct net_device *dev)
skb_queue_head_init(&port->backlog);
INIT_WORK(&port->wq, ipvlan_process_multicast);
- ida_init(&port->ida);
+ port->dev_id_base = 1;
err = netdev_rx_handler_register(dev, ipvlan_handle_frame, port);
if (err)
@@ -151,7 +151,6 @@ static void ipvlan_port_destroy(struct net_device *dev)
dev_put(skb->dev);
kfree_skb(skb);
}
- ida_destroy(&port->ida);
kfree(port);
}
@@ -496,6 +495,60 @@ static int ipvlan_nl_fillinfo(struct sk_buff *skb,
return ret;
}
+static u16 ipvlan_get_dev_id(struct ipvl_port *port)
+{
+ struct ipvl_dev *ipvlan;
+ u16 tid, dev_id = 0;
+ bool found, exhausted = false, second_round = false;
+
+ /* Idea here is to get the next available ID while avoiding
+ * reuse of already used IDs. Per port variable (dev_id_base)
+ * is used to get the next available ID.
+ *
+ * Possibilities are from 0x1 to 0xfffe so finding next available
+ * ID is not be that difficult. However if the system is up for a
+ * long time and these slave devices are getting added / deleted
+ * routinely and it reaches the MAX, then only the assignment will
+ * attempt to recycle previously used IDs starting from 0x1 (Provided
+ * these are not currently in use).
+ *
+ * In case of a failure, dev-id search will return 0. All IDs in-use
+ * case is very inefficient (n^2 search) but having close to 64k
+ * slaves has it's own system limitations.
+ */
+ while (!exhausted) {
+ tid = port->dev_id_base++;
+
+ if (tid == 0xFFFE) {
+ /* Reached MAX; restart from 1 */
+ port->dev_id_base = 1;
+ if (second_round)
+ exhausted = true;
+ else
+ second_round = true;
+ continue;
+ }
+ /* Should not be same as the masters' (if present) */
+ if (tid == port->dev->dev_id)
+ continue;
+ /* Make sure that it's already not assigned to any of the
+ * existing slaves.
+ */
+ found = false;
+ list_for_each_entry(ipvlan, &port->ipvlans, pnode) {
+ if (ipvlan->dev->dev_id == tid) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ dev_id = tid;
+ break;
+ }
+ }
+ return dev_id;
+}
+
static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[])
{
@@ -540,10 +593,11 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
* Assign IDs between 0x1 and 0xFFFE (used by the master) to each
* slave link [see addrconf_ifid_eui48()].
*/
- err = ida_simple_get(&port->ida, 1, 0xFFFE, GFP_KERNEL);
- if (err < 0)
+ dev->dev_id = ipvlan_get_dev_id(port);
+ if (dev->dev_id == 0) {
+ err = -ENOSPC;
goto destroy_ipvlan_port;
- dev->dev_id = err;
+ }
/* TODO Probably put random address here to be presented to the
* world but keep using the physical-dev address for the outgoing
@@ -555,7 +609,7 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
err = register_netdevice(dev);
if (err < 0)
- goto remove_ida;
+ goto destroy_ipvlan_port;
err = netdev_upper_dev_link(phy_dev, dev);
if (err) {
@@ -574,8 +628,6 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
netdev_upper_dev_unlink(phy_dev, dev);
unregister_netdev:
unregister_netdevice(dev);
-remove_ida:
- ida_simple_remove(&port->ida, dev->dev_id);
destroy_ipvlan_port:
if (create)
ipvlan_port_destroy(phy_dev);
@@ -593,7 +645,6 @@ static void ipvlan_link_delete(struct net_device *dev, struct list_head *head)
kfree_rcu(addr, rcu);
}
- ida_simple_remove(&ipvlan->port->ida, dev->dev_id);
list_del_rcu(&ipvlan->pnode);
unregister_netdevice_queue(dev, head);
netdev_upper_dev_unlink(ipvlan->phy_dev, dev);
--
2.11.0.390.gc69c2f50cf-goog
^ permalink raw reply related
* RE: [PATCH v4] net: stmmac: fix maxmtu assignment to be within valid range
From: Kweh, Hock Leong @ 2017-01-07 0:43 UTC (permalink / raw)
To: Andy Shevchenko
Cc: David S. Miller, Joao Pinto, Giuseppe CAVALLARO,
seraphin.bonnaffe@st.com, Jarod Wilson, Alexandre TORGUE,
Joachim Eastwood, Niklas Cassel, Johan Hovold, Pavel Machek,
lars.persson@axis.com, netdev, LKML
In-Reply-To: <CAHp75VeBJsTR9OrdYQqs7fCb40KzyByehX97VdKm8CerDUwVqg@mail.gmail.com>
> -----Original Message-----
> From: Andy Shevchenko [mailto:andy.shevchenko@gmail.com]
> Sent: Saturday, January 07, 2017 8:12 AM
> To: Kweh, Hock Leong <hock.leong.kweh@intel.com>
> Cc: David S. Miller <davem@davemloft.net>; Joao Pinto
> <Joao.Pinto@synopsys.com>; Giuseppe CAVALLARO <peppe.cavallaro@st.com>;
> seraphin.bonnaffe@st.com; Jarod Wilson <jarod@redhat.com>; Alexandre
> TORGUE <alexandre.torgue@gmail.com>; Joachim Eastwood
> <manabian@gmail.com>; Niklas Cassel <niklas.cassel@axis.com>; Johan Hovold
> <johan@kernel.org>; Pavel Machek <pavel@ucw.cz>; lars.persson@axis.com;
> netdev <netdev@vger.kernel.org>; LKML <linux-kernel@vger.kernel.org>
> Subject: Re: [PATCH v4] net: stmmac: fix maxmtu assignment to be within valid
> range
>
> On Sat, Jan 7, 2017 at 10:10 AM, Kweh, Hock Leong
> <hock.leong.kweh@intel.com> wrote:
> > From: "Kweh, Hock Leong" <hock.leong.kweh@intel.com>
> >
> > There is no checking valid value of maxmtu when getting it from device tree.
> > This resolution added the checking condition to ensure the assignment is
> > made within a valid range.
>
> > changelog v4:
> > * add print warning message when maxmtu > max_mtu as well
>
> Yep.
>
> > * add maxmtu = JUMBO_LEN into each *_default_data() at stmmac_pci.c
>
> Yep.
>
> But see comment below.
>
> P.S. And perhaps next time send into our internal mailing list first for review.
>
> > @@ -3345,8 +3345,14 @@ int stmmac_dvr_probe(struct device *device,
> > ndev->max_mtu = JUMBO_LEN;
> > else
> > ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN);
> > - if (priv->plat->maxmtu < ndev->max_mtu)
> > + if ((priv->plat->maxmtu < ndev->max_mtu) &&
> > + (priv->plat->maxmtu >= ndev->min_mtu))
> > ndev->max_mtu = priv->plat->maxmtu;
>
> > + else if ((priv->plat->maxmtu < ndev->min_mtu) ||
> > + (priv->plat->maxmtu > ndev->max_mtu))
> > + netdev_warn(priv->dev,
>
> What is the difference to just 'else'? (Returning back to my initial
> proposal, I don't remember telling anything about 'else if' concept)
>
When priv->plat->maxmtu == ndev->max_mtu will not be a warning message.
Oh NO ... it is a valid case for priv->plat->maxmtu > ndev->max_mtu if the
assignment of ndev->max_mtu is using SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN),
which is < JUMBO_LEN, then priv->plat->maxmtu > ndev->max_mtu is valid.
Revert back and submit V5. Thanks.
> > + "%s: warning: maxmtu having invalid value (%d)\n",
> > + __func__, priv->plat->maxmtu);
>
> --
> With Best Regards,
> Andy Shevchenko
^ permalink raw reply
* RE: [PATCH v3] net: stmmac: fix maxmtu assignment to be within valid range
From: Kweh, Hock Leong @ 2017-01-07 0:54 UTC (permalink / raw)
To: Andy Shevchenko
Cc: David S. Miller, Joao Pinto, Giuseppe CAVALLARO,
seraphin.bonnaffe@st.com, Jarod Wilson, Alexandre TORGUE,
Joachim Eastwood, Niklas Cassel, Johan Hovold, Pavel Machek,
lars.persson@axis.com, netdev, LKML
In-Reply-To: <CAHp75VeWs8LXS+zaCht8reLMLRtz+583K91QvoPquuUxC-rwWg@mail.gmail.com>
> -----Original Message-----
> From: Andy Shevchenko [mailto:andy.shevchenko@gmail.com]
> Sent: Saturday, January 07, 2017 8:07 AM
> To: Kweh, Hock Leong <hock.leong.kweh@intel.com>
> Cc: David S. Miller <davem@davemloft.net>; Joao Pinto
> <Joao.Pinto@synopsys.com>; Giuseppe CAVALLARO <peppe.cavallaro@st.com>;
> seraphin.bonnaffe@st.com; Jarod Wilson <jarod@redhat.com>; Alexandre
> TORGUE <alexandre.torgue@gmail.com>; Joachim Eastwood
> <manabian@gmail.com>; Niklas Cassel <niklas.cassel@axis.com>; Johan Hovold
> <johan@kernel.org>; Pavel Machek <pavel@ucw.cz>; lars.persson@axis.com;
> netdev <netdev@vger.kernel.org>; LKML <linux-kernel@vger.kernel.org>
> Subject: Re: [PATCH v3] net: stmmac: fix maxmtu assignment to be within valid
> range
>
> On Sat, Jan 7, 2017 at 1:47 AM, Kweh, Hock Leong
> <hock.leong.kweh@intel.com> wrote:
>
> >> > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> >> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> >> > @@ -3345,8 +3345,14 @@ int stmmac_dvr_probe(struct device *device,
> >> > ndev->max_mtu = JUMBO_LEN;
> >> > else
> >> > ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD +
> NET_IP_ALIGN);
> >> > - if (priv->plat->maxmtu < ndev->max_mtu)
> >>
> >> > + if ((priv->plat->maxmtu < ndev->max_mtu) &&
> >> > + (priv->plat->maxmtu >= ndev->min_mtu))
> >>
> >> > ndev->max_mtu = priv->plat->maxmtu;
> >>
> >> > + else if (priv->plat->maxmtu < ndev->min_mtu)
> >>
> >> And if it > ndev->max_mtu?..
> >>
> >
> > Base on my understanding to the original code, the "maxmtu >= ndev-
> >max_mtu"
> > is meant for products that would want to use the value from logic which is just
> above
> > this statement where you just ask me not to add new line. That the reason the
> > stmmac_platform.c put in "plat->maxmtu = JUMBO_LEN;" as generic and I
> also
> > follow it in stmmac_pci.c.
> >
> > Or do you mean only take maxmtu = JUMBO_LEN for the option to use driver
> itself
> > assignment statement above and all the > max_mtu consider invalid?
>
> So, just answer to the simple question: is it a valid case to have
> plat->maxmtu > ndev->max_mtu? If it so, how is it used?
> Otherwise we need a warning in such case. What did I miss?
>
it is a valid case for priv->plat->maxmtu > ndev->max_mtu if referring
to the statement above it:
/* MTU range: 46 - hw-specific max */
ndev->min_mtu = ETH_ZLEN - ETH_HLEN;
if ((priv->plat->enh_desc) || (priv->synopsys_id >= DWMAC_CORE_4_00))
ndev->max_mtu = JUMBO_LEN;
else
ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN);
When the ndev->max_mtu go into the else statement, then the assignment in
stmmac_platform.c & stammac_pci.c plat->maxmtu = JUMBO_LEN is actually
greater than ndev->max_mtu. That is what I understanding that maxmtu > max_mtu
is an option trick to allow driver assign value through the logic above instead of getting
it from of_property_read_u32(np, "max-frame-size", &plat->maxmtu); or *_default_data().
I need to revert back the V4 and submit V5.
> >
> >> > + netdev_warn(priv->dev,
> >> > + "%s: warning: maxmtu having invalid value (%d)\n",
> >> > + __func__, priv->plat->maxmtu);
>
>
> >> > + /* Set the maxmtu to a default of JUMBO_LEN in case the
> >> > + * parameter is not defined for the device.
> >> > + */
> >> > + plat->maxmtu = JUMBO_LEN;
> >>
> >> Please, use *_default_data() hooks for that.
> >>
> >> At some point it might make sense to extract
> >> static int common_default_data() {...}
> >> and call it at the beginning of the rest of *_defautl_data() hooks.
> >>
> >
> > Just try to understand, are you referring changing the code something
> > like this:
> >
> > stmmac_default_data(plat);
> > if (info) {
> > info->pdev = pdev;
> > if (info->setup) {
> > ret = info->setup(plat, info);
> > if (ret)
> > return ret;
> > }
> > }
> >
> > Where all the common code is inside the stmmac_default_data()?
>
> No.
>
> common_default_data()
> {
> ... common defaults among *_default_data() ...
> }
>
> *_default_data()
> {
> ...
> common_default_data();
> ...
> }
>
Ok noted. Will be a separate patch. Thanks.
Regards,
Wilson
> --
> With Best Regards,
> Andy Shevchenko
^ permalink raw reply
* [PATCH net-next] liquidio: store the L4 hash of rx packets in skb
From: Felix Manlunas @ 2017-01-07 0:55 UTC (permalink / raw)
To: davem; +Cc: netdev, raghu.vatsavayi, derek.chickles, satananda.burla
From: Prasad Kanneganti <prasad.kanneganti@cavium.com>
Store the L4 hash of received packets in the skb; the hash is computed in
the NIC firmware.
Signed-off-by: Prasad Kanneganti <prasad.kanneganti@cavium.com>
Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com>
Signed-off-by: Derek Chickles <derek.chickles@cavium.com>
Signed-off-by: Satanand Burla <satananda.burla@cavium.com>
---
drivers/net/ethernet/cavium/liquidio/lio_main.c | 17 +++++++++++++++--
drivers/net/ethernet/cavium/liquidio/lio_vf_main.c | 15 ++++++++++++++-
drivers/net/ethernet/cavium/liquidio/liquidio_common.h | 2 ++
3 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index 39a9665..adae858 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -2263,6 +2263,7 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)),
struct skb_shared_hwtstamps *shhwtstamps;
u64 ns;
u16 vtag = 0;
+ u32 r_dh_off;
struct net_device *netdev = (struct net_device *)arg;
struct octeon_droq *droq = container_of(param, struct octeon_droq,
napi);
@@ -2308,6 +2309,8 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)),
put_page(pg_info->page);
}
+ r_dh_off = (rh->r_dh.len - 1) * BYTES_PER_DHLEN_UNIT;
+
if (((oct->chip_id == OCTEON_CN66XX) ||
(oct->chip_id == OCTEON_CN68XX)) &&
ptp_enable) {
@@ -2320,16 +2323,26 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)),
/* Nanoseconds are in the first 64-bits
* of the packet.
*/
- memcpy(&ns, (skb->data), sizeof(ns));
+ memcpy(&ns, (skb->data + r_dh_off),
+ sizeof(ns));
+ r_dh_off -= BYTES_PER_DHLEN_UNIT;
shhwtstamps = skb_hwtstamps(skb);
shhwtstamps->hwtstamp =
ns_to_ktime(ns +
lio->ptp_adjust);
}
- skb_pull(skb, sizeof(ns));
}
}
+ if (rh->r_dh.has_hash) {
+ u32 hash = be32_to_cpu(*(u32 *)(skb->data + r_dh_off));
+
+ skb_set_hash(skb, hash, PKT_HASH_TYPE_L4);
+ r_dh_off -= BYTES_PER_DHLEN_UNIT;
+ }
+
+ skb_pull(skb, rh->r_dh.len * BYTES_PER_DHLEN_UNIT);
+
skb->protocol = eth_type_trans(skb, skb->dev);
if ((netdev->features & NETIF_F_RXCSUM) &&
(((rh->r_dh.encap_on) &&
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
index 70d96c1..c0ee746 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
@@ -1497,6 +1497,7 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)),
struct net_device *netdev = (struct net_device *)arg;
struct sk_buff *skb = (struct sk_buff *)skbuff;
u16 vtag = 0;
+ u32 r_dh_off;
if (netdev) {
struct lio *lio = GET_LIO(netdev);
@@ -1540,7 +1541,19 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)),
put_page(pg_info->page);
}
- skb_pull(skb, rh->r_dh.len * 8);
+ r_dh_off = (rh->r_dh.len - 1) * BYTES_PER_DHLEN_UNIT;
+
+ if (rh->r_dh.has_hwtstamp)
+ r_dh_off -= BYTES_PER_DHLEN_UNIT;
+
+ if (rh->r_dh.has_hash) {
+ u32 hash = be32_to_cpu(*(u32 *)(skb->data + r_dh_off));
+
+ skb_set_hash(skb, hash, PKT_HASH_TYPE_L4);
+ r_dh_off -= BYTES_PER_DHLEN_UNIT;
+ }
+
+ skb_pull(skb, rh->r_dh.len * BYTES_PER_DHLEN_UNIT);
skb->protocol = eth_type_trans(skb, skb->dev);
if ((netdev->features & NETIF_F_RXCSUM) &&
diff --git a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h
index ba329f6..bc0af8a 100644
--- a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h
+++ b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h
@@ -98,6 +98,8 @@ enum octeon_tag_type {
#define CVM_DRV_INVALID_APP (CVM_DRV_APP_START + 0x2)
#define CVM_DRV_APP_END (CVM_DRV_INVALID_APP - 1)
+#define BYTES_PER_DHLEN_UNIT 8
+
static inline u32 incr_index(u32 index, u32 count, u32 max)
{
if ((index + count) >= max)
^ permalink raw reply related
* Re: [PATCH v2 03/12] net: ethernet: aquantia: Add ring support code
From: Lino Sanfilippo @ 2017-01-07 1:05 UTC (permalink / raw)
To: Alexander Loktionov, netdev, David VomLehn
Cc: Simon Edelhaus, Dmitrii Tarakanov, Pavel Belous
In-Reply-To: <7d0b8bdb9c3ec1d2cbfb136796dbfc66e0ab535d.1483689029.git.vomlehn@texas.net>
On 06.01.2017 09:06, Alexander Loktionov wrote:
> From: David VomLehn <vomlehn@texas.net>
>
> Add code to support the transmit and receive ring buffers.
>
> Signed-off-by: Alexander Loktionov <Alexander.Loktionov@aquantia.com>
> Signed-off-by: Dmitrii Tarakanov <Dmitrii.Tarakanov@aquantia.com>
> Signed-off-by: Pavel Belous <Pavel.Belous@aquantia.com>
> Signed-off-by: David M. VomLehn <vomlehn@texas.net>
> ---
> drivers/net/ethernet/aquantia/aq_ring.c | 380 ++++++++++++++++++++++++++++++++
> drivers/net/ethernet/aquantia/aq_ring.h | 147 ++++++++++++
> 2 files changed, 527 insertions(+)
> create mode 100644 drivers/net/ethernet/aquantia/aq_ring.c
> create mode 100644 drivers/net/ethernet/aquantia/aq_ring.h
>
> diff --git a/drivers/net/ethernet/aquantia/aq_ring.c b/drivers/net/ethernet/aquantia/aq_ring.c
> new file mode 100644
> index 0000000..a7ef6aa
> --- /dev/null
> +++ b/drivers/net/ethernet/aquantia/aq_ring.c
> @@ -0,0 +1,380 @@
> +/*
> + * aQuantia Corporation Network Driver
> + * Copyright (C) 2014-2016 aQuantia Corporation. All rights reserved
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + */
> +
> +/* File aq_pci_ring.c: Definition of functions for Rx/Tx rings. */
> +
> +#include "aq_ring.h"
> +#include "aq_nic.h"
> +#include "aq_hw.h"
> +
> +#include <linux/netdevice.h>
> +#include <linux/etherdevice.h>
> +
> +static struct aq_ring_s *aq_ring_alloc(struct aq_ring_s *self,
> + struct aq_nic_s *aq_nic,
> + struct aq_nic_cfg_s *aq_nic_cfg)
> +{
> + int err = 0;
> +
> + if (!self) {
> + err = -ENOMEM;
> + goto err_exit;
> + }
Why do you check this parameter but not the others?
Beside this since the function is static the only caller is your own
code, so why is a check
needed at all? Can self ever be NULL? Same pattern occurs in several
other functions.
> +
> +struct aq_ring_s *aq_ring_tx_alloc(struct aq_ring_s *self,
> + struct aq_nic_s *aq_nic,
> + unsigned int idx,
> + struct aq_nic_cfg_s *aq_nic_cfg)
>
> +
> +struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self,
> + struct aq_nic_s *aq_nic,
> + unsigned int idx,
> + struct aq_nic_cfg_s *aq_nic_cfg)
> +{
> + int err = 0;
> +
> + if (!self) {
> + err = -ENOMEM;
> + goto err_exit;
>
> +
> +void aq_ring_free(struct aq_ring_s *self)
> +{
> + if (!self)
> + goto err_exit;
> +
> + kfree(self->buff_ring);
> +
> + if (self->dx_ring)
> + dma_free_coherent(aq_nic_get_dev(self->aq_nic),
> + self->size * self->dx_size, self->dx_ring,
> + self->dx_ring_pa);
> +
> +err_exit:;
> +}
This does not make sense. Just return immediately if "self" is NULL (and
if you really have to make
this check).
> +
> +int aq_ring_rx_clean(struct aq_ring_s *self, int *work_done, int budget)
> +{
> + struct net_device *ndev = aq_nic_get_ndev(self->aq_nic);
> + int err = 0;
> + bool is_rsc_completed = true;
> +
> + for (; (self->sw_head != self->hw_head) && budget;
> + self->sw_head = aq_ring_next_dx(self, self->sw_head),
> + --budget, ++(*work_done)) {
> + struct aq_ring_buff_s *buff = &self->buff_ring[self->sw_head];
> + struct sk_buff *skb = NULL;
> + unsigned int next_ = 0U;
> + unsigned int i = 0U;
> + struct aq_ring_buff_s *buff_ = NULL;
> +
> + if (buff->is_error) {
> + __free_pages(buff->page, 0);
> + continue;
> + }
> +
> + if (buff->is_cleaned)
> + continue;
> +
> + ++self->stats.rx_packets;
> + ++ndev->stats.rx_packets;
> + ndev->stats.rx_bytes += buff->len;
> +
> + if (!buff->is_eop) {
> + for (next_ = buff->next,
> + buff_ = &self->buff_ring[next_]; true;
> + next_ = buff_->next,
> + buff_ = &self->buff_ring[next_]) {
> + is_rsc_completed =
> + aq_ring_dx_in_range(self->sw_head,
> + next_,
> + self->hw_head);
> +
> + if (unlikely(!is_rsc_completed)) {
> + is_rsc_completed = false;
> + break;
> + }
> +
> + if (buff_->is_eop)
> + break;
> + }
> +
> + if (!is_rsc_completed) {
> + err = 0;
> + goto err_exit;
> + }
> + }
> +
> + skb = netdev_alloc_skb(ndev, ETH_HLEN + AQ_CFG_IP_ALIGN);
> +
> + skb_reserve(skb, AQ_CFG_IP_ALIGN);
netdev_alloc_skb_ip_align() will do the proper alignment for you (BTW.
AQ_CFG_IP_ALIGN is defined as 0 in aq_cfg.h.
Is this on purpose?)
> + skb_put(skb, ETH_HLEN);
> + memcpy(skb->data, page_address(buff->page), ETH_HLEN);
> +
> + skb_add_rx_frag(skb, 0, buff->page, ETH_HLEN,
> + buff->len - ETH_HLEN,
> + SKB_TRUESIZE(buff->len - ETH_HLEN));
> + if (!buff->is_eop) {
> + for (i = 1U, next_ = buff->next,
> + buff_ = &self->buff_ring[next_]; true;
> + next_ = buff_->next,
> + buff_ = &self->buff_ring[next_], ++i) {
> + skb_add_rx_frag(skb, i, buff_->page, 0,
> + buff_->len,
> + SKB_TRUESIZE(buff->len -
> + ETH_HLEN));
> + buff_->is_cleaned = 1;
> +
> + if (buff_->is_eop)
> + break;
> + }
> + }
> +
> + skb->dev = ndev;
This is unnecessary. The following call of eth_type_trans() will do
this already.
Regards,
Lino
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox