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
= ipoib_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
, struct nlattr
*tb
[],
68 struct nlattr
*data
[],
69 struct netlink_ext_ack
*extack
)
74 if (data
[IFLA_IPOIB_MODE
]) {
75 mode
= nla_get_u16(data
[IFLA_IPOIB_MODE
]);
76 if (mode
== IPOIB_MODE_DATAGRAM
)
77 ret
= ipoib_set_mode(dev
, "datagram\n");
78 else if (mode
== IPOIB_MODE_CONNECTED
)
79 ret
= ipoib_set_mode(dev
, "connected\n");
87 if (data
[IFLA_IPOIB_UMCAST
]) {
88 umcast
= nla_get_u16(data
[IFLA_IPOIB_UMCAST
]);
89 ipoib_set_umcast(dev
, umcast
);
96 static int ipoib_new_child_link(struct net
*src_net
, struct net_device
*dev
,
97 struct nlattr
*tb
[], struct nlattr
*data
[],
98 struct netlink_ext_ack
*extack
)
100 struct net_device
*pdev
;
101 struct ipoib_dev_priv
*ppriv
;
108 pdev
= __dev_get_by_index(src_net
, nla_get_u32(tb
[IFLA_LINK
]));
109 if (!pdev
|| pdev
->type
!= ARPHRD_INFINIBAND
)
112 ppriv
= ipoib_priv(pdev
);
114 if (test_bit(IPOIB_FLAG_SUBINTERFACE
, &ppriv
->flags
)) {
115 ipoib_warn(ppriv
, "child creation disallowed for child devices\n");
119 if (!data
|| !data
[IFLA_IPOIB_PKEY
]) {
120 ipoib_dbg(ppriv
, "no pkey specified, using parent pkey\n");
121 child_pkey
= ppriv
->pkey
;
123 child_pkey
= nla_get_u16(data
[IFLA_IPOIB_PKEY
]);
125 err
= ipoib_intf_init(ppriv
->ca
, ppriv
->port
, dev
->name
, dev
);
127 ipoib_warn(ppriv
, "failed to initialize pkey device\n");
131 err
= __ipoib_vlan_add(ppriv
, ipoib_priv(dev
),
132 child_pkey
, IPOIB_RTNL_CHILD
);
137 err
= ipoib_changelink(dev
, tb
, data
, extack
);
139 unregister_netdevice(dev
);
147 static void ipoib_del_child_link(struct net_device
*dev
, struct list_head
*head
)
149 struct ipoib_dev_priv
*priv
= ipoib_priv(dev
);
154 unregister_netdevice_queue(dev
, head
);
157 static size_t ipoib_get_size(const struct net_device
*dev
)
159 return nla_total_size(2) + /* IFLA_IPOIB_PKEY */
160 nla_total_size(2) + /* IFLA_IPOIB_MODE */
161 nla_total_size(2); /* IFLA_IPOIB_UMCAST */
164 static struct rtnl_link_ops ipoib_link_ops __read_mostly
= {
166 .maxtype
= IFLA_IPOIB_MAX
,
167 .policy
= ipoib_policy
,
168 .priv_size
= sizeof(struct ipoib_dev_priv
),
169 .setup
= ipoib_setup_common
,
170 .newlink
= ipoib_new_child_link
,
171 .dellink
= ipoib_del_child_link
,
172 .changelink
= ipoib_changelink
,
173 .get_size
= ipoib_get_size
,
174 .fill_info
= ipoib_fill_info
,
177 struct rtnl_link_ops
*ipoib_get_link_ops(void)
179 return &ipoib_link_ops
;
182 int __init
ipoib_netlink_init(void)
184 return rtnl_link_register(&ipoib_link_ops
);
187 void __exit
ipoib_netlink_fini(void)
189 rtnl_link_unregister(&ipoib_link_ops
);
192 MODULE_ALIAS_RTNL_LINK("ipoib");