blob: a7dc5ea8370ea3535158c570e8b7a53d43b3db04 [file] [log] [blame]
Or Gerlitz9baa0b02012-09-13 05:56:36 +00001/*
2 * Copyright (c) 2012 Mellanox Technologies. - All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
33#include <linux/netdevice.h>
34#include <linux/module.h>
35#include <net/rtnetlink.h>
36#include "ipoib.h"
37
38static const struct nla_policy ipoib_policy[IFLA_IPOIB_MAX + 1] = {
39 [IFLA_IPOIB_PKEY] = { .type = NLA_U16 },
40};
41
42static int ipoib_new_child_link(struct net *src_net, struct net_device *dev,
43 struct nlattr *tb[], struct nlattr *data[])
44{
45 struct net_device *pdev;
46 struct ipoib_dev_priv *ppriv;
47 u16 child_pkey;
48 int err;
49
50 if (!tb[IFLA_LINK])
51 return -EINVAL;
52
53 pdev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK]));
54 if (!pdev)
55 return -ENODEV;
56
57 ppriv = netdev_priv(pdev);
58
59 if (test_bit(IPOIB_FLAG_SUBINTERFACE, &ppriv->flags)) {
60 ipoib_warn(ppriv, "child creation disallowed for child devices\n");
61 return -EINVAL;
62 }
63
64 if (!data || !data[IFLA_IPOIB_PKEY]) {
65 ipoib_dbg(ppriv, "no pkey specified, using parent pkey\n");
66 child_pkey = ppriv->pkey;
67 } else
68 child_pkey = nla_get_u16(data[IFLA_IPOIB_PKEY]);
69
70 err = __ipoib_vlan_add(ppriv, netdev_priv(dev), child_pkey, IPOIB_RTNL_CHILD);
71
72 return err;
73}
74
75static void ipoib_unregister_child_dev(struct net_device *dev, struct list_head *head)
76{
77 struct ipoib_dev_priv *priv, *ppriv;
78
79 priv = netdev_priv(dev);
80 ppriv = netdev_priv(priv->parent);
81
82 mutex_lock(&ppriv->vlan_mutex);
83 unregister_netdevice_queue(dev, head);
84 list_del(&priv->list);
85 mutex_unlock(&ppriv->vlan_mutex);
86}
87
88static size_t ipoib_get_size(const struct net_device *dev)
89{
90 return nla_total_size(2); /* IFLA_IPOIB_PKEY */
91}
92
93static struct rtnl_link_ops ipoib_link_ops __read_mostly = {
94 .kind = "ipoib",
95 .maxtype = IFLA_IPOIB_MAX,
96 .policy = ipoib_policy,
97 .priv_size = sizeof(struct ipoib_dev_priv),
98 .setup = ipoib_setup,
99 .newlink = ipoib_new_child_link,
100 .dellink = ipoib_unregister_child_dev,
101 .get_size = ipoib_get_size,
102};
103
104int __init ipoib_netlink_init(void)
105{
106 return rtnl_link_register(&ipoib_link_ops);
107}
108
109void __exit ipoib_netlink_fini(void)
110{
111 rtnl_link_unregister(&ipoib_link_ops);
112}
113
114MODULE_ALIAS_RTNL_LINK("ipoib");