| .. | .. |
|---|
| 122 | 122 | } else |
|---|
| 123 | 123 | child_pkey = nla_get_u16(data[IFLA_IPOIB_PKEY]); |
|---|
| 124 | 124 | |
|---|
| 125 | + err = ipoib_intf_init(ppriv->ca, ppriv->port, dev->name, dev); |
|---|
| 126 | + if (err) { |
|---|
| 127 | + ipoib_warn(ppriv, "failed to initialize pkey device\n"); |
|---|
| 128 | + return err; |
|---|
| 129 | + } |
|---|
| 130 | + |
|---|
| 125 | 131 | err = __ipoib_vlan_add(ppriv, ipoib_priv(dev), |
|---|
| 126 | 132 | child_pkey, IPOIB_RTNL_CHILD); |
|---|
| 133 | + if (err) |
|---|
| 134 | + return err; |
|---|
| 127 | 135 | |
|---|
| 128 | | - if (!err && data) |
|---|
| 136 | + if (data) { |
|---|
| 129 | 137 | err = ipoib_changelink(dev, tb, data, extack); |
|---|
| 130 | | - return err; |
|---|
| 138 | + if (err) { |
|---|
| 139 | + unregister_netdevice(dev); |
|---|
| 140 | + return err; |
|---|
| 141 | + } |
|---|
| 142 | + } |
|---|
| 143 | + |
|---|
| 144 | + return 0; |
|---|
| 145 | +} |
|---|
| 146 | + |
|---|
| 147 | +static void ipoib_del_child_link(struct net_device *dev, struct list_head *head) |
|---|
| 148 | +{ |
|---|
| 149 | + struct ipoib_dev_priv *priv = ipoib_priv(dev); |
|---|
| 150 | + |
|---|
| 151 | + if (!priv->parent) |
|---|
| 152 | + return; |
|---|
| 153 | + |
|---|
| 154 | + unregister_netdevice_queue(dev, head); |
|---|
| 131 | 155 | } |
|---|
| 132 | 156 | |
|---|
| 133 | 157 | static size_t ipoib_get_size(const struct net_device *dev) |
|---|
| .. | .. |
|---|
| 139 | 163 | |
|---|
| 140 | 164 | static struct rtnl_link_ops ipoib_link_ops __read_mostly = { |
|---|
| 141 | 165 | .kind = "ipoib", |
|---|
| 166 | + .netns_refund = true, |
|---|
| 142 | 167 | .maxtype = IFLA_IPOIB_MAX, |
|---|
| 143 | 168 | .policy = ipoib_policy, |
|---|
| 144 | 169 | .priv_size = sizeof(struct ipoib_dev_priv), |
|---|
| 145 | 170 | .setup = ipoib_setup_common, |
|---|
| 146 | 171 | .newlink = ipoib_new_child_link, |
|---|
| 172 | + .dellink = ipoib_del_child_link, |
|---|
| 147 | 173 | .changelink = ipoib_changelink, |
|---|
| 148 | 174 | .get_size = ipoib_get_size, |
|---|
| 149 | 175 | .fill_info = ipoib_fill_info, |
|---|
| 150 | 176 | }; |
|---|
| 151 | 177 | |
|---|
| 178 | +struct rtnl_link_ops *ipoib_get_link_ops(void) |
|---|
| 179 | +{ |
|---|
| 180 | + return &ipoib_link_ops; |
|---|
| 181 | +} |
|---|
| 182 | + |
|---|
| 152 | 183 | int __init ipoib_netlink_init(void) |
|---|
| 153 | 184 | { |
|---|
| 154 | 185 | return rtnl_link_register(&ipoib_link_ops); |
|---|