Lines Matching +full:mctp +full:- +full:handling

1 // SPDX-License-Identifier: GPL-2.0
3 * Management Component Transport Protocol (MCTP) - device implementation.
11 #include <linux/mctp.h>
18 #include <net/mctp.h>
32 struct mctp_dev *mdev = rcu_dereference(dev->mctp_ptr); in __mctp_dev_get()
38 if (!refcount_inc_not_zero(&mdev->refs)) in __mctp_dev_get()
48 return rtnl_dereference(dev->mctp_ptr); in mctp_dev_get_rtnl()
70 return -EMSGSIZE; in mctp_fill_addrinfo()
73 hdr->ifa_family = AF_MCTP; in mctp_fill_addrinfo()
74 hdr->ifa_prefixlen = 0; in mctp_fill_addrinfo()
75 hdr->ifa_flags = 0; in mctp_fill_addrinfo()
76 hdr->ifa_scope = 0; in mctp_fill_addrinfo()
77 hdr->ifa_index = mdev->dev->ifindex; in mctp_fill_addrinfo()
91 return -EMSGSIZE; in mctp_fill_addrinfo()
97 struct mctp_dump_cb *mcb = (void *)cb->ctx; in mctp_dump_dev_addrinfo()
101 portid = NETLINK_CB(cb->skb).portid; in mctp_dump_dev_addrinfo()
102 seq = cb->nlh->nlmsg_seq; in mctp_dump_dev_addrinfo()
103 for (; mcb->a_idx < mdev->num_addrs; mcb->a_idx++) { in mctp_dump_dev_addrinfo()
104 rc = mctp_fill_addrinfo(skb, mdev, mdev->addrs[mcb->a_idx], in mctp_dump_dev_addrinfo()
115 struct mctp_dump_cb *mcb = (void *)cb->ctx; in mctp_dump_addrinfo()
116 struct net *net = sock_net(skb->sk); in mctp_dump_addrinfo()
122 hdr = nlmsg_data(cb->nlh); in mctp_dump_addrinfo()
124 ifindex = hdr->ifa_index; in mctp_dump_addrinfo()
127 for_each_netdev_dump(net, dev, mcb->ifindex) { in mctp_dump_addrinfo()
128 if (ifindex && ifindex != dev->ifindex) in mctp_dump_addrinfo()
137 mcb->a_idx = 0; in mctp_dump_addrinfo()
141 return skb->len; in mctp_dump_addrinfo()
148 struct net *net = dev_net(mdev->dev); in mctp_addr_notify()
150 int rc = -ENOBUFS; in mctp_addr_notify()
157 portid, req_nlh->nlmsg_seq, 0); in mctp_addr_notify()
159 WARN_ON_ONCE(rc == -EMSGSIZE); in mctp_addr_notify()
178 struct net *net = sock_net(skb->sk); in mctp_rtm_newaddr()
200 return -EINVAL; in mctp_rtm_newaddr()
203 dev = __dev_get_by_index(net, ifm->ifa_index); in mctp_rtm_newaddr()
205 return -ENODEV; in mctp_rtm_newaddr()
209 return -ENODEV; in mctp_rtm_newaddr()
211 if (!mctp_address_unicast(addr->s_addr)) in mctp_rtm_newaddr()
212 return -EINVAL; in mctp_rtm_newaddr()
215 if (memchr(mdev->addrs, addr->s_addr, mdev->num_addrs)) in mctp_rtm_newaddr()
216 return -EEXIST; in mctp_rtm_newaddr()
218 tmp_addrs = kmalloc(mdev->num_addrs + 1, GFP_KERNEL); in mctp_rtm_newaddr()
220 return -ENOMEM; in mctp_rtm_newaddr()
221 memcpy(tmp_addrs, mdev->addrs, mdev->num_addrs); in mctp_rtm_newaddr()
222 tmp_addrs[mdev->num_addrs] = addr->s_addr; in mctp_rtm_newaddr()
225 spin_lock_irqsave(&mdev->addrs_lock, flags); in mctp_rtm_newaddr()
226 mdev->num_addrs++; in mctp_rtm_newaddr()
227 swap(mdev->addrs, tmp_addrs); in mctp_rtm_newaddr()
228 spin_unlock_irqrestore(&mdev->addrs_lock, flags); in mctp_rtm_newaddr()
232 mctp_addr_notify(mdev, addr->s_addr, RTM_NEWADDR, skb, nlh); in mctp_rtm_newaddr()
233 mctp_route_add_local(mdev, addr->s_addr); in mctp_rtm_newaddr()
241 struct net *net = sock_net(skb->sk); in mctp_rtm_deladdr()
263 return -EINVAL; in mctp_rtm_deladdr()
266 dev = __dev_get_by_index(net, ifm->ifa_index); in mctp_rtm_deladdr()
268 return -ENODEV; in mctp_rtm_deladdr()
272 return -ENODEV; in mctp_rtm_deladdr()
274 pos = memchr(mdev->addrs, addr->s_addr, mdev->num_addrs); in mctp_rtm_deladdr()
276 return -ENOENT; in mctp_rtm_deladdr()
278 rc = mctp_route_remove_local(mdev, addr->s_addr); in mctp_rtm_deladdr()
279 // we can ignore -ENOENT in the case a route was already removed in mctp_rtm_deladdr()
280 if (rc < 0 && rc != -ENOENT) in mctp_rtm_deladdr()
283 spin_lock_irqsave(&mdev->addrs_lock, flags); in mctp_rtm_deladdr()
284 memmove(pos, pos + 1, mdev->num_addrs - 1 - (pos - mdev->addrs)); in mctp_rtm_deladdr()
285 mdev->num_addrs--; in mctp_rtm_deladdr()
286 spin_unlock_irqrestore(&mdev->addrs_lock, flags); in mctp_rtm_deladdr()
288 mctp_addr_notify(mdev, addr->s_addr, RTM_DELADDR, skb, nlh); in mctp_rtm_deladdr()
295 refcount_inc(&mdev->refs); in mctp_dev_hold()
300 if (mdev && refcount_dec_and_test(&mdev->refs)) { in mctp_dev_put()
301 kfree(mdev->addrs); in mctp_dev_put()
302 dev_put(mdev->dev); in mctp_dev_put()
308 __must_hold(&key->lock) in mctp_dev_release_key()
312 if (dev->ops && dev->ops->release_flow) in mctp_dev_release_key()
313 dev->ops->release_flow(dev, key); in mctp_dev_release_key()
314 key->dev = NULL; in mctp_dev_release_key()
319 __must_hold(&key->lock) in mctp_dev_set_key()
322 key->dev = dev; in mctp_dev_set_key()
333 return ERR_PTR(-ENOMEM); in mctp_add_dev()
335 spin_lock_init(&mdev->addrs_lock); in mctp_add_dev()
337 mdev->net = mctp_default_net(dev_net(dev)); in mctp_add_dev()
340 refcount_set(&mdev->refs, 1); in mctp_add_dev()
341 rcu_assign_pointer(dev->mctp_ptr, mdev); in mctp_add_dev()
344 mdev->dev = dev; in mctp_add_dev()
356 return -ENODATA; in mctp_fill_link_af()
357 if (nla_put_u32(skb, IFLA_MCTP_NET, mdev->net)) in mctp_fill_link_af()
358 return -EMSGSIZE; in mctp_fill_link_af()
359 if (nla_put_u8(skb, IFLA_MCTP_PHYS_BINDING, mdev->binding)) in mctp_fill_link_af()
360 return -EMSGSIZE; in mctp_fill_link_af()
401 WRITE_ONCE(mdev->net, nla_get_u32(tb[IFLA_MCTP_NET])); in mctp_set_link_af()
406 /* Matches netdev types that should have MCTP handling */
410 return dev->type == ARPHRD_MCTP || in mctp_known()
411 dev->type == ARPHRD_LOOPBACK || in mctp_known()
412 dev->type == ARPHRD_NONE; in mctp_known()
423 RCU_INIT_POINTER(mdev->dev->mctp_ptr, NULL); in mctp_unregister()
436 if (rtnl_dereference(dev->mctp_ptr)) in mctp_register()
480 mdev->ops = ops; in mctp_register_netdevice()
481 mdev->binding = binding; in mctp_register_netdevice()