From: "John W. Linville" <linville@tuxdriver.com>
To: Jiri Pirko <jiri@resnulli.us>
Cc: netdev@vger.kernel.org, "David S. Miller" <davem@davemloft.net>,
Jesse Gross <jesse@nicira.com>, Andy Zhou <azhou@nicira.com>,
Stephen Hemminger <stephen@networkplumber.org>,
Alexander Duyck <alexander.h.duyck@redhat.com>
Subject: Re: [RFC PATCH 5/5] geneve: add initial netdev driver for GENEVE tunnels
Date: Fri, 3 Apr 2015 10:57:12 -0400 [thread overview]
Message-ID: <20150403145711.GD31348@tuxdriver.com> (raw)
In-Reply-To: <20150402202002.GG2613@nanopsycho.orion>
On Thu, Apr 02, 2015 at 10:20:02PM +0200, Jiri Pirko wrote:
> Thu, Apr 02, 2015 at 09:17:06PM CEST, linville@tuxdriver.com wrote:
> >This is an initial implementation of a netdev driver for GENEVE
> >tunnels. This implementation uses a fixed UDP port, and only supports
> >a single tunnel (and therefore only a single VNI) per net namespace.
> >Only IPv4 links are supported at this time.
>
>
> Thanks for doing this John!
>
>
> >
> >Signed-off-by: John W. Linville <linville@tuxdriver.com>
> >---
> > drivers/net/Kconfig | 14 ++
> > drivers/net/Makefile | 1 +
> > drivers/net/geneve.c | 451 +++++++++++++++++++++++++++++++++++++++++++
> > include/uapi/linux/if_link.h | 9 +
> > 4 files changed, 475 insertions(+)
> > create mode 100644 drivers/net/geneve.c
> >
>
> ...
>
> >+/* Initialize the device structure. */
> >+static void geneve_setup(struct net_device *dev)
> >+{
> >+ struct geneve_dev *geneve = netdev_priv(dev);
> >+
> >+ ether_setup(dev);
> >+
> >+ dev->netdev_ops = &geneve_netdev_ops;
> >+ dev->destructor = free_netdev;
> >+ SET_NETDEV_DEVTYPE(dev, &geneve_type);
> >+
> >+ INIT_WORK(&geneve->sock_work, geneve_sock_work);
>
> I would push work initialization into geneve_newlink. Seems odd to have
> it here in setup.
Yes, that will probably work a lot better for multiple tunnels on a
host... :-)
> >+
> >+ dev->tx_queue_len = 0;
> >+ dev->features = 0;
> >+
> >+ dev->vlan_features = dev->features;
> >+ dev->hw_features = 0;
> >+
> >+ geneve->dev = dev;
> >+}
> >+
> >+static const struct nla_policy geneve_policy[IFLA_GENEVE_MAX + 1] = {
> >+ [IFLA_GENEVE_ID] = { .type = NLA_U32 },
> >+ [IFLA_GENEVE_REMOTE] = { .len = FIELD_SIZEOF(struct iphdr, daddr) },
> >+};
> >+
> >+static int geneve_validate(struct nlattr *tb[], struct nlattr *data[])
> >+{
> >+ if (tb[IFLA_ADDRESS]) {
> >+ if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
> >+ return -EINVAL;
> >+
> >+ if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
> >+ return -EADDRNOTAVAIL;
> >+ }
> >+
> >+ if (!data)
> >+ return -EINVAL;
> >+
> >+ if (data[IFLA_GENEVE_ID]) {
> >+ __u32 vni = nla_get_u32(data[IFLA_GENEVE_ID]);
>
> missing newline
Sure.
> >+ if (vni >= GENEVE_VID_MASK)
> >+ return -ERANGE;
> >+ }
> >+
> >+ return 0;
> >+}
> >+
> >+static void geneve_get_drvinfo(struct net_device *dev,
> >+ struct ethtool_drvinfo *drvinfo)
> >+{
> >+ strlcpy(drvinfo->version, GENEVE_NETDEV_VER, sizeof(drvinfo->version));
> >+ strlcpy(drvinfo->driver, "geneve", sizeof(drvinfo->driver));
> >+}
> >+
> >+static const struct ethtool_ops geneve_ethtool_ops = {
> >+ .get_drvinfo = geneve_get_drvinfo,
> >+ .get_link = ethtool_op_get_link,
> >+};
> >+
> >+static int geneve_newlink(struct net *net, struct net_device *dev,
> >+ struct nlattr *tb[], struct nlattr *data[])
> >+{
> >+ struct geneve_net *gn = net_generic(net, geneve_net_id);
> >+ struct geneve_dev *geneve = netdev_priv(dev);
> >+ __u32 vni;
>
> why not "u32" ?
I think I copied that from vxlan.c. In fact, I'm not really sure I
understand why both exist?
> >+ int err;
> >+
> >+ /* TODO: need to support multiple tunnels in a namespace */
> >+ if (!list_empty(&gn->geneve_list))
> >+ return -EBUSY;
>
> Interesting limitation :)
That should disappear, of course. :-)
> ...
>
> >+static void __net_exit geneve_exit_net(struct net *net)
> >+{
> >+ struct geneve_net *gn = net_generic(net, geneve_net_id);
> >+ struct geneve_dev *geneve, *next;
> >+ struct net_device *dev, *aux;
> >+ LIST_HEAD(list);
> >+
> >+ rtnl_lock();
> >+ for_each_netdev_safe(net, dev, aux)
> >+ if (dev->rtnl_link_ops == &geneve_link_ops)
> >+ unregister_netdevice_queue(dev, &list);
> >+
> >+ list_for_each_entry_safe(geneve, next, &gn->geneve_list, next) {
> >+ /* If geneve->dev is in the same netns, it was already added
> >+ * to the list by the previous loop.
> >+ */
> >+ if (!net_eq(dev_net(geneve->dev), net))
> >+ unregister_netdevice_queue(dev, &list);
> >+ }
>
> I know this is c&p of vxlan, but I do not understand why the first loop
> is there. The second loop will take care of all since all devs are
> listed in ->geneve_list, right?
>
> Also you do not need _safe variant since you traverse through
> ->geneve_list, which is not modified.
Yes, it is boilerplate from vxlan. Maybe Stephen can explain it?
Maybe it relates to the the ordering of the unregister queue?
I'll try to figure it out...
> >+
> >+ unregister_netdevice_many(&list);
> >+ rtnl_unlock();
> >+}
Thanks for the review and suggestions!
John
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
next prev parent reply other threads:[~2015-04-03 15:00 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-02 19:17 [RFC] add GENEVE netdev tunnel driver John W. Linville
2015-04-02 19:17 ` [RFC PATCH 1/5] geneve: remove MODULE_ALIAS_RTNL_LINK from net/ipv4/geneve.c John W. Linville
2015-04-02 23:39 ` Stephen Hemminger
2015-04-03 12:17 ` Jiri Pirko
2015-04-03 14:27 ` John W. Linville
2015-04-02 19:17 ` [RFC PATCH 2/5] geneve: move definition of geneve_hdr() to geneve.h John W. Linville
2015-04-02 19:17 ` [RFC PATCH 3/5] Rename support library for geneve John W. Linville
2015-04-03 0:05 ` Cong Wang
2015-04-03 14:40 ` John W. Linville
2015-04-03 15:54 ` Nicolas Dichtel
2015-04-03 18:25 ` John W. Linville
2015-04-02 19:17 ` [RFC PATCH 4/5] libgeneve: identify as driver library in modules description John W. Linville
2015-04-02 19:17 ` [RFC PATCH 5/5] geneve: add initial netdev driver for GENEVE tunnels John W. Linville
2015-04-02 20:20 ` Jiri Pirko
2015-04-03 14:57 ` John W. Linville [this message]
2015-04-03 15:07 ` John W. Linville
2015-04-03 15:20 ` Jiri Pirko
2015-04-03 18:31 ` John W. Linville
2015-04-03 5:55 ` Simon Horman
2015-04-03 14:41 ` John W. Linville
2015-04-03 21:05 ` Jesse Gross
2015-04-04 1:01 ` Francois Romieu
2015-04-06 18:06 ` Jesse Gross
2015-04-06 18:44 ` John W. Linville
2015-04-06 20:44 ` Francois Romieu
2015-04-06 18:43 ` John W. Linville
2015-04-06 22:52 ` Jesse Gross
2015-04-02 19:17 ` [RFC PATCH] iproute2: GENEVE support John W. Linville
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150403145711.GD31348@tuxdriver.com \
--to=linville@tuxdriver.com \
--cc=alexander.h.duyck@redhat.com \
--cc=azhou@nicira.com \
--cc=davem@davemloft.net \
--cc=jesse@nicira.com \
--cc=jiri@resnulli.us \
--cc=netdev@vger.kernel.org \
--cc=stephen@networkplumber.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).