a->tx_compressed = b->tx_compressed;
};
-static inline size_t if_nlmsg_size(int iwbuflen)
+static inline size_t if_nlmsg_size(void)
{
return NLMSG_ALIGN(sizeof(struct ifinfomsg))
+ nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
+ nla_total_size(4) /* IFLA_LINK */
+ nla_total_size(4) /* IFLA_MASTER */
+ nla_total_size(1) /* IFLA_OPERSTATE */
- + nla_total_size(1) /* IFLA_LINKMODE */
- + nla_total_size(iwbuflen);
+ + nla_total_size(1); /* IFLA_LINKMODE */
}
static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
- void *iwbuf, int iwbuflen, int type, u32 pid,
- u32 seq, u32 change, unsigned int flags)
+ int type, u32 pid, u32 seq, u32 change,
+ unsigned int flags)
{
struct ifinfomsg *ifm;
struct nlmsghdr *nlh;
}
}
- if (iwbuf)
- NLA_PUT(skb, IFLA_WIRELESS, iwbuflen, iwbuf);
-
return nlmsg_end(skb, nlh);
nla_put_failure:
int s_idx = cb->args[0];
struct net_device *dev;
- for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
+ idx = 0;
+ for_each_netdev(dev) {
if (idx < s_idx)
- continue;
- if (rtnl_fill_ifinfo(skb, dev, NULL, 0, RTM_NEWLINK,
+ goto cont;
+ if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0)
break;
+cont:
+ idx++;
}
cb->args[0] = idx;
return skb->len;
}
-static struct nla_policy ifla_policy[IFLA_MAX+1] __read_mostly = {
+static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
[IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 },
[IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) },
[IFLA_MTU] = { .type = NLA_U32 },
err = -EINVAL;
ifm = nlmsg_data(nlh);
- if (ifm->ifi_index >= 0)
+ if (ifm->ifi_index > 0)
dev = dev_get_by_index(ifm->ifi_index);
else if (tb[IFLA_IFNAME])
dev = dev_get_by_name(ifname);
* name provided implies that a name change has been
* requested.
*/
- if (ifm->ifi_index >= 0 && ifname[0]) {
+ if (ifm->ifi_index > 0 && ifname[0]) {
err = dev_change_name(dev, ifname);
if (err < 0)
goto errout_dev;
}
- if (ifm->ifi_flags)
- dev_change_flags(dev, ifm->ifi_flags);
+ if (ifm->ifi_flags || ifm->ifi_change) {
+ unsigned int flags = ifm->ifi_flags;
+
+ /* bugwards compatibility: ifi_change == 0 is treated as ~0 */
+ if (ifm->ifi_change)
+ flags = (flags & ifm->ifi_change) |
+ (dev->flags & ~ifm->ifi_change);
+ dev_change_flags(dev, flags);
+ }
if (tb[IFLA_TXQLEN])
dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
struct nlattr *tb[IFLA_MAX+1];
struct net_device *dev = NULL;
struct sk_buff *nskb;
- char *iw_buf = NULL, *iw = NULL;
- int iw_buf_len = 0;
int err;
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
return err;
ifm = nlmsg_data(nlh);
- if (ifm->ifi_index >= 0) {
+ if (ifm->ifi_index > 0) {
dev = dev_get_by_index(ifm->ifi_index);
if (dev == NULL)
return -ENODEV;
} else
return -EINVAL;
- nskb = nlmsg_new(if_nlmsg_size(iw_buf_len), GFP_KERNEL);
+ nskb = nlmsg_new(if_nlmsg_size(), GFP_KERNEL);
if (nskb == NULL) {
err = -ENOBUFS;
goto errout;
}
- err = rtnl_fill_ifinfo(nskb, dev, iw, iw_buf_len, RTM_NEWLINK,
- NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, 0);
+ err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).pid,
+ nlh->nlmsg_seq, 0, 0);
if (err < 0) {
/* -EMSGSIZE implies BUG in if_nlmsg_size */
WARN_ON(err == -EMSGSIZE);
}
err = rtnl_unicast(nskb, NETLINK_CB(skb).pid);
errout:
- kfree(iw_buf);
dev_put(dev);
return err;
struct sk_buff *skb;
int err = -ENOBUFS;
- skb = nlmsg_new(if_nlmsg_size(0), GFP_KERNEL);
+ skb = nlmsg_new(if_nlmsg_size(), GFP_KERNEL);
if (skb == NULL)
goto errout;
- err = rtnl_fill_ifinfo(skb, dev, NULL, 0, type, 0, 0, change, 0);
+ err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0);
if (err < 0) {
/* -EMSGSIZE implies BUG in if_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);