aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/vxlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/vxlan.c')
-rw-r--r--drivers/net/vxlan.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 656230e0d18c..f10e58ac9c1b 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -29,9 +29,11 @@
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <linux/hash.h>
+#include <linux/ethtool.h>
#include <net/arp.h>
#include <net/ndisc.h>
#include <net/ip.h>
+#include <net/ipip.h>
#include <net/icmp.h>
#include <net/udp.h>
#include <net/rtnetlink.h>
@@ -143,9 +145,8 @@ static inline struct hlist_head *vni_head(struct net *net, u32 id)
static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id)
{
struct vxlan_dev *vxlan;
- struct hlist_node *node;
- hlist_for_each_entry_rcu(vxlan, node, vni_head(net, id), hlist) {
+ hlist_for_each_entry_rcu(vxlan, vni_head(net, id), hlist) {
if (vxlan->vni == id)
return vxlan;
}
@@ -290,9 +291,8 @@ static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
{
struct hlist_head *head = vxlan_fdb_head(vxlan, mac);
struct vxlan_fdb *f;
- struct hlist_node *node;
- hlist_for_each_entry_rcu(f, node, head, hlist) {
+ hlist_for_each_entry_rcu(f, head, hlist) {
if (compare_ether_addr(mac, f->eth_addr) == 0)
return f;
}
@@ -392,7 +392,8 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
}
/* Delete entry (via netlink) */
-static int vxlan_fdb_delete(struct ndmsg *ndm, struct net_device *dev,
+static int vxlan_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
+ struct net_device *dev,
const unsigned char *addr)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
@@ -419,10 +420,9 @@ static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
for (h = 0; h < FDB_HASH_SIZE; ++h) {
struct vxlan_fdb *f;
- struct hlist_node *n;
int err;
- hlist_for_each_entry_rcu(f, n, &vxlan->fdb_head[h], hlist) {
+ hlist_for_each_entry_rcu(f, &vxlan->fdb_head[h], hlist) {
if (idx < cb->args[0])
goto skip;
@@ -480,11 +480,10 @@ static bool vxlan_group_used(struct vxlan_net *vn,
const struct vxlan_dev *this)
{
const struct vxlan_dev *vxlan;
- struct hlist_node *node;
unsigned h;
for (h = 0; h < VNI_HASH_SIZE; ++h)
- hlist_for_each_entry(vxlan, node, &vn->vni_list[h], hlist) {
+ hlist_for_each_entry(vxlan, &vn->vni_list[h], hlist) {
if (vxlan == this)
continue;
@@ -960,13 +959,13 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
iph->daddr = dst;
iph->saddr = fl4.saddr;
iph->ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
+ tunnel_ip_select_ident(skb, old_iph, &rt->dst);
vxlan_set_owner(dev, skb);
/* See iptunnel_xmit() */
if (skb->ip_summed != CHECKSUM_PARTIAL)
skb->ip_summed = CHECKSUM_NONE;
- ip_select_ident(iph, &rt->dst, NULL);
err = ip_local_out(skb);
if (likely(net_xmit_eval(err) == 0)) {
@@ -1271,6 +1270,18 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
return 0;
}
+static void vxlan_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ strlcpy(drvinfo->version, VXLAN_VERSION, sizeof(drvinfo->version));
+ strlcpy(drvinfo->driver, "vxlan", sizeof(drvinfo->driver));
+}
+
+static const struct ethtool_ops vxlan_ethtool_ops = {
+ .get_drvinfo = vxlan_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+};
+
static int vxlan_newlink(struct net *net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[])
{
@@ -1348,6 +1359,8 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
vxlan->port_max = ntohs(p->high);
}
+ SET_ETHTOOL_OPS(dev, &vxlan_ethtool_ops);
+
err = register_netdevice(dev);
if (!err)
hlist_add_head_rcu(&vxlan->hlist, vni_head(net, vxlan->vni));