2 * Copyright (c) 2012 Mellanox Technologies. - All rights reserved.
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:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
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.
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
33 #include <linux/netdevice.h>
34 #include <linux/if_arp.h> /* For ARPHRD_xxx */
35 #include <linux/module.h>
36 #include <net/rtnetlink.h>
39 static const struct nla_policy ipoib_policy
[IFLA_IPOIB_MAX
+ 1] = {
40 [IFLA_IPOIB_PKEY
] = { .type
= NLA_U16
},
41 [IFLA_IPOIB_MODE
] = { .type
= NLA_U16
},
42 [IFLA_IPOIB_UMCAST
] = { .type
= NLA_U16
},
45 static int ipoib_fill_info(struct sk_buff
*skb
, const struct net_device
*dev
)
47 struct ipoib_dev_priv
*priv
= netdev_priv(dev
);
50 if (nla_put_u16(skb
, IFLA_IPOIB_PKEY
, priv
->pkey
))
53 val
= test_bit(IPOIB_FLAG_ADMIN_CM
, &priv
->flags
);
54 if (nla_put_u16(skb
, IFLA_IPOIB_MODE
, val
))
57 val
= test_bit(IPOIB_FLAG_UMCAST
, &priv
->flags
);
58 if (nla_put_u16(skb
, IFLA_IPOIB_UMCAST
, val
))
67 static int ipoib_changelink(struct net_device
*dev
,
68 struct nlattr
*tb
[], struct nlattr
*data
[])
73 if (data
[IFLA_IPOIB_MODE
]) {
74 mode
= nla_get_u16(data
[IFLA_IPOIB_MODE
]);
75 if (mode
== IPOIB_MODE_DATAGRAM
)
76 ret
= ipoib_set_mode(dev
, "datagram\n");
77 else if (mode
== IPOIB_MODE_CONNECTED
)
78 ret
= ipoib_set_mode(dev
, "connected\n");
86 if (data
[IFLA_IPOIB_UMCAST
]) {
87 umcast
= nla_get_u16(data
[IFLA_IPOIB_UMCAST
]);
88 ipoib_set_umcast(dev
, umcast
);
95 static int ipoib_new_child_link(struct net
*src_net
, struct net_device
*dev
,
96 struct nlattr
*tb
[], struct nlattr
*data
[])
98 struct net_device
*pdev
;
99 struct ipoib_dev_priv
*ppriv
;
106 pdev
= __dev_get_by_index(src_net
, nla_get_u32(tb
[IFLA_LINK
]));
107 if (!pdev
|| pdev
->type
!= ARPHRD_INFINIBAND
)
110 ppriv
= netdev_priv(pdev
);
112 if (test_bit(IPOIB_FLAG_SUBINTERFACE
, &ppriv
->flags
)) {
113 ipoib_warn(ppriv
, "child creation disallowed for child devices\n");
117 if (!data
|| !data
[IFLA_IPOIB_PKEY
]) {
118 ipoib_dbg(ppriv
, "no pkey specified, using parent pkey\n");
119 child_pkey
= ppriv
->pkey
;
121 child_pkey
= nla_get_u16(data
[IFLA_IPOIB_PKEY
]);
123 if (child_pkey
== 0 || child_pkey
== 0x8000)
127 * Set the full membership bit, so that we join the right
128 * broadcast group, etc.
130 child_pkey
|= 0x8000;
132 err
= __ipoib_vlan_add(ppriv
, netdev_priv(dev
), child_pkey
, IPOIB_RTNL_CHILD
);
135 err
= ipoib_changelink(dev
, tb
, data
);
139 static void ipoib_unregister_child_dev(struct net_device
*dev
, struct list_head
*head
)
141 struct ipoib_dev_priv
*priv
, *ppriv
;
143 priv
= netdev_priv(dev
);
144 ppriv
= netdev_priv(priv
->parent
);
146 down_write(&ppriv
->vlan_rwsem
);
147 unregister_netdevice_queue(dev
, head
);
148 list_del(&priv
->list
);
149 up_write(&ppriv
->vlan_rwsem
);
152 static size_t ipoib_get_size(const struct net_device
*dev
)
154 return nla_total_size(2) + /* IFLA_IPOIB_PKEY */
155 nla_total_size(2) + /* IFLA_IPOIB_MODE */
156 nla_total_size(2); /* IFLA_IPOIB_UMCAST */
159 static struct rtnl_link_ops ipoib_link_ops __read_mostly
= {
161 .maxtype
= IFLA_IPOIB_MAX
,
162 .policy
= ipoib_policy
,
163 .priv_size
= sizeof(struct ipoib_dev_priv
),
164 .setup
= ipoib_setup
,
165 .newlink
= ipoib_new_child_link
,
166 .changelink
= ipoib_changelink
,
167 .dellink
= ipoib_unregister_child_dev
,
168 .get_size
= ipoib_get_size
,
169 .fill_info
= ipoib_fill_info
,
172 int __init
ipoib_netlink_init(void)
174 return rtnl_link_register(&ipoib_link_ops
);
177 void __exit
ipoib_netlink_fini(void)
179 rtnl_link_unregister(&ipoib_link_ops
);
182 MODULE_ALIAS_RTNL_LINK("ipoib");