-static size_t br_nlmsg_size(void)
-{
- return NLMSG_ALIGN(sizeof(struct ifinfomsg))
- + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
- + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
- + nla_total_size(4) /* IFLA_MASTER */
- + nla_total_size(4) /* IFLA_MTU */
- + nla_total_size(1); /* IFLA_OPERSTATE */
-}
-
-/* Caller must hold RTNL lock. */
-static int dp_fill_ifinfo(struct sk_buff *skb,
- const struct vport *port,
- int event, unsigned int flags)
-{
- struct datapath *dp = port->dp;
- struct ifinfomsg *hdr;
- struct nlmsghdr *nlh;
-
- if (!port->ops->get_ifindex)
- return -ENODEV;
-
- nlh = nlmsg_put(skb, 0, 0, event, sizeof(*hdr), flags);
- if (nlh == NULL)
- return -EMSGSIZE;
-
- hdr = nlmsg_data(nlh);
- hdr->ifi_family = AF_BRIDGE;
- hdr->__ifi_pad = 0;
- hdr->ifi_type = ARPHRD_ETHER;
- hdr->ifi_index = port->ops->get_ifindex(port);
- hdr->ifi_flags = port->ops->get_dev_flags(port);
- hdr->ifi_change = 0;
-
- if (nla_put_string(skb, IFLA_IFNAME, port->ops->get_name(port)) ||
- nla_put_u32(skb, IFLA_MASTER, get_dpifindex(dp)) ||
- nla_put_u32(skb, IFLA_MTU, port->ops->get_mtu(port)) ||
-#ifdef IFLA_OPERSTATE
- nla_put_u8(skb, IFLA_OPERSTATE,
- port->ops->is_running(port) ?
- port->ops->get_operstate(port) :
- IF_OPER_DOWN) ||
-#endif
- nla_put(skb, IFLA_ADDRESS, ETH_ALEN, port->ops->get_addr(port)))
- goto nla_put_failure;
-
- return nlmsg_end(skb, nlh);
-
-nla_put_failure:
- nlmsg_cancel(skb, nlh);
- return -EMSGSIZE;
-}
-
-/* Caller must hold RTNL lock. */
-static void dp_ifinfo_notify(int event, struct vport *port)
-{
- struct sk_buff *skb;
- int err;
-
- skb = nlmsg_new(br_nlmsg_size(), GFP_KERNEL);
- if (!skb) {
- err = -ENOBUFS;
- goto err;
- }
-
- err = dp_fill_ifinfo(skb, port, event, 0);
- if (err < 0) {
- if (err == -ENODEV) {
- goto out;
- } else {
- /* -EMSGSIZE implies BUG in br_nlmsg_size() */
- WARN_ON(err == -EMSGSIZE);
- goto err;
- }
- }
-
- rtnl_notify(skb, ovs_dp_get_net(port->dp), 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
-
- return;
-err:
- rtnl_set_sk_err(ovs_dp_get_net(port->dp), RTNLGRP_LINK, err);
-out:
- kfree_skb(skb);
-}
-
-static void release_dp(struct kobject *kobj)
-{
- struct datapath *dp = container_of(kobj, struct datapath, ifobj);
- kfree(dp);
-}
-
-static struct kobj_type dp_ktype = {
- .release = release_dp
-};
-