0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #include <linux/netdevice.h>
0034 #include <linux/if_arp.h> /* For ARPHRD_xxx */
0035 #include <net/rtnetlink.h>
0036 #include "ipoib.h"
0037
0038 static const struct nla_policy ipoib_policy[IFLA_IPOIB_MAX + 1] = {
0039 [IFLA_IPOIB_PKEY] = { .type = NLA_U16 },
0040 [IFLA_IPOIB_MODE] = { .type = NLA_U16 },
0041 [IFLA_IPOIB_UMCAST] = { .type = NLA_U16 },
0042 };
0043
0044 static int ipoib_fill_info(struct sk_buff *skb, const struct net_device *dev)
0045 {
0046 struct ipoib_dev_priv *priv = ipoib_priv(dev);
0047 u16 val;
0048
0049 if (nla_put_u16(skb, IFLA_IPOIB_PKEY, priv->pkey))
0050 goto nla_put_failure;
0051
0052 val = test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
0053 if (nla_put_u16(skb, IFLA_IPOIB_MODE, val))
0054 goto nla_put_failure;
0055
0056 val = test_bit(IPOIB_FLAG_UMCAST, &priv->flags);
0057 if (nla_put_u16(skb, IFLA_IPOIB_UMCAST, val))
0058 goto nla_put_failure;
0059
0060 return 0;
0061
0062 nla_put_failure:
0063 return -EMSGSIZE;
0064 }
0065
0066 static int ipoib_changelink(struct net_device *dev, struct nlattr *tb[],
0067 struct nlattr *data[],
0068 struct netlink_ext_ack *extack)
0069 {
0070 u16 mode, umcast;
0071 int ret = 0;
0072
0073 if (data[IFLA_IPOIB_MODE]) {
0074 mode = nla_get_u16(data[IFLA_IPOIB_MODE]);
0075 if (mode == IPOIB_MODE_DATAGRAM)
0076 ret = ipoib_set_mode(dev, "datagram\n");
0077 else if (mode == IPOIB_MODE_CONNECTED)
0078 ret = ipoib_set_mode(dev, "connected\n");
0079 else
0080 ret = -EINVAL;
0081
0082 if (ret < 0)
0083 goto out_err;
0084 }
0085
0086 if (data[IFLA_IPOIB_UMCAST]) {
0087 umcast = nla_get_u16(data[IFLA_IPOIB_UMCAST]);
0088 ipoib_set_umcast(dev, umcast);
0089 }
0090
0091 out_err:
0092 return ret;
0093 }
0094
0095 static int ipoib_new_child_link(struct net *src_net, struct net_device *dev,
0096 struct nlattr *tb[], struct nlattr *data[],
0097 struct netlink_ext_ack *extack)
0098 {
0099 struct net_device *pdev;
0100 struct ipoib_dev_priv *ppriv;
0101 u16 child_pkey;
0102 int err;
0103
0104 if (!tb[IFLA_LINK])
0105 return -EINVAL;
0106
0107 pdev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK]));
0108 if (!pdev || pdev->type != ARPHRD_INFINIBAND)
0109 return -ENODEV;
0110
0111 ppriv = ipoib_priv(pdev);
0112
0113 if (test_bit(IPOIB_FLAG_SUBINTERFACE, &ppriv->flags)) {
0114 ipoib_warn(ppriv, "child creation disallowed for child devices\n");
0115 return -EINVAL;
0116 }
0117
0118 if (!data || !data[IFLA_IPOIB_PKEY]) {
0119 ipoib_dbg(ppriv, "no pkey specified, using parent pkey\n");
0120 child_pkey = ppriv->pkey;
0121 } else
0122 child_pkey = nla_get_u16(data[IFLA_IPOIB_PKEY]);
0123
0124 err = ipoib_intf_init(ppriv->ca, ppriv->port, dev->name, dev);
0125 if (err) {
0126 ipoib_warn(ppriv, "failed to initialize pkey device\n");
0127 return err;
0128 }
0129
0130 err = __ipoib_vlan_add(ppriv, ipoib_priv(dev),
0131 child_pkey, IPOIB_RTNL_CHILD);
0132 if (err)
0133 return err;
0134
0135 if (data) {
0136 err = ipoib_changelink(dev, tb, data, extack);
0137 if (err) {
0138 unregister_netdevice(dev);
0139 return err;
0140 }
0141 }
0142
0143 return 0;
0144 }
0145
0146 static void ipoib_del_child_link(struct net_device *dev, struct list_head *head)
0147 {
0148 struct ipoib_dev_priv *priv = ipoib_priv(dev);
0149
0150 if (!priv->parent)
0151 return;
0152
0153 unregister_netdevice_queue(dev, head);
0154 }
0155
0156 static size_t ipoib_get_size(const struct net_device *dev)
0157 {
0158 return nla_total_size(2) +
0159 nla_total_size(2) +
0160 nla_total_size(2);
0161 }
0162
0163 static struct rtnl_link_ops ipoib_link_ops __read_mostly = {
0164 .kind = "ipoib",
0165 .netns_refund = true,
0166 .maxtype = IFLA_IPOIB_MAX,
0167 .policy = ipoib_policy,
0168 .priv_size = sizeof(struct ipoib_dev_priv),
0169 .setup = ipoib_setup_common,
0170 .newlink = ipoib_new_child_link,
0171 .dellink = ipoib_del_child_link,
0172 .changelink = ipoib_changelink,
0173 .get_size = ipoib_get_size,
0174 .fill_info = ipoib_fill_info,
0175 };
0176
0177 struct rtnl_link_ops *ipoib_get_link_ops(void)
0178 {
0179 return &ipoib_link_ops;
0180 }
0181
0182 int __init ipoib_netlink_init(void)
0183 {
0184 return rtnl_link_register(&ipoib_link_ops);
0185 }
0186
0187 void __exit ipoib_netlink_fini(void)
0188 {
0189 rtnl_link_unregister(&ipoib_link_ops);
0190 }
0191
0192 MODULE_ALIAS_RTNL_LINK("ipoib");