[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <200809241430.45344.remi.denis-courmont@nokia.com>
Date: Wed, 24 Sep 2008 14:30:45 +0300
From: "Rémi Denis-Courmont"
<remi.denis-courmont@...ia.com>
To: "ext Thomas Graf" <tgraf@...g.ch>
Cc: netdev@...r.kernel.org
Subject: Re: [PATCH 05/11] Phonet: Netlink interface
Hello,
On Tuesday 23 September 2008 15:10:02, you wrote:
> Please do not use the old attribute buffer anymore. It's use is racy
> ever since we started dropping the rtnl semaphore in order to load
> modules. It would be safe in this particular case but it shouldn't be
> used for new code.
>
> Take a look at rtnl_setlink() for an example on how to use the interface
> correctly. (...)
Ok, thanks. Would this work?
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
index b1ea19a..136622b 100644
--- a/net/phonet/pn_netlink.c
+++ b/net/phonet/pn_netlink.c
@@ -54,11 +54,17 @@ errout:
rtnl_set_sk_err(dev_net(dev), RTNLGRP_PHONET_IFADDR, err);
}
-static int newaddr_doit(struct sk_buff *skb, struct nlmsghdr *nlm, void *attr)
+static const struct nla_policy ifa_phonet_policy[IFA_MAX+1] = {
+ [IFA_LOCAL] = { .type = NLA_U8 },
+};
+
+static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr,
+ int op)
{
- struct rtattr **rta = attr;
- struct ifaddrmsg *ifm = NLMSG_DATA(nlm);
+ struct net *net = sock_net(skb->sk);
+ struct nlattr *tb[IFA_MAX+1];
struct net_device *dev;
+ struct ifaddrmsg *ifm;
int err;
u8 pnaddr;
@@ -67,53 +73,39 @@ static int newaddr_doit(struct sk_buff *skb, struct nlmsghdr *nlm, void *attr)
ASSERT_RTNL();
- if (rta[IFA_LOCAL - 1] == NULL)
+ err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_phonet_policy);
+ if (err < 0)
+ return err;
+
+ ifm = nlmsg_data(nlh);
+ if (tb[IFA_LOCAL] == NULL)
+ return -EINVAL;
+ pnaddr = nla_get_u8(tb[IFA_LOCAL]);
+ if (pnaddr & 3)
+ /* Phonet addresses only have 6 high-order bits */
return -EINVAL;
- dev = __dev_get_by_index(&init_net, ifm->ifa_index);
+ dev = __dev_get_by_index(net, ifm->ifa_index);
if (dev == NULL)
return -ENODEV;
- if (ifm->ifa_prefixlen > 0)
- return -EINVAL;
-
- memcpy(&pnaddr, RTA_DATA(rta[IFA_LOCAL - 1]), 1);
-
- err = phonet_address_add(dev, pnaddr);
+ if (op == RTM_NEWADDR)
+ err = phonet_address_add(dev, pnaddr);
+ else
+ err = phonet_address_del(dev, pnaddr);
if (!err)
- rtmsg_notify(RTM_NEWADDR, dev, pnaddr);
+ rtmsg_notify(op, dev, pnaddr);
return err;
}
-static int deladdr_doit(struct sk_buff *skb, struct nlmsghdr *nlm, void *attr)
+static int newaddr_doit(struct sk_buff *skb, struct nlmsghdr *nlm, void *attr)
{
- struct rtattr **rta = attr;
- struct ifaddrmsg *ifm = NLMSG_DATA(nlm);
- struct net_device *dev;
- int err;
- u8 pnaddr;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- ASSERT_RTNL();
-
- if (rta[IFA_LOCAL - 1] == NULL)
- return -EINVAL;
-
- dev = __dev_get_by_index(&init_net, ifm->ifa_index);
- if (dev == NULL)
- return -ENODEV;
-
- if (ifm->ifa_prefixlen > 0)
- return -EADDRNOTAVAIL;
-
- memcpy(&pnaddr, RTA_DATA(rta[IFA_LOCAL - 1]), 1);
+ return addr_doit(skb, nlm, attr, RTM_NEWADDR);
+}
- err = phonet_address_del(dev, pnaddr);
- if (!err)
- rtmsg_notify(RTM_DELADDR, dev, pnaddr);
- return err;
+static int deladdr_doit(struct sk_buff *skb, struct nlmsghdr *nlm, void *attr)
+{
+ return addr_doit(skb, nlm, attr, RTM_DELADDR);
}
static int fill_addr(struct sk_buff *skb, struct net_device *dev, u8 addr,
@@ -121,25 +113,23 @@ static int fill_addr(struct sk_buff *skb, struct net_device *dev, u8 addr,
{
struct ifaddrmsg *ifm;
struct nlmsghdr *nlh;
- unsigned int orig_len = skb->len;
- nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(struct ifaddrmsg));
- ifm = NLMSG_DATA(nlh);
+ nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), 0);
+ if (nlh == NULL)
+ return -EMSGSIZE;
+
+ ifm = nlmsg_data(nlh);
ifm->ifa_family = AF_PHONET;
ifm->ifa_prefixlen = 0;
ifm->ifa_flags = IFA_F_PERMANENT;
- ifm->ifa_scope = RT_SCOPE_HOST;
+ ifm->ifa_scope = RT_SCOPE_LINK;
ifm->ifa_index = dev->ifindex;
- RTA_PUT(skb, IFA_LOCAL, 1, &addr);
- nlh->nlmsg_len = skb->len - orig_len;
-
- return 0;
-
-nlmsg_failure:
-rtattr_failure:
- skb_trim(skb, orig_len);
+ NLA_PUT_U8(skb, IFA_LOCAL, addr);
+ return nlmsg_end(skb, nlh);
- return -1;
+nla_put_failure:
+ nlmsg_cancel(skb, nlh);
+ return -EMSGSIZE;
}
static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
_
--
Rémi Denis-Courmont
Maemo Software, Nokia Devices R&D
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists