summaryrefslogtreecommitdiff
path: root/net/decnet/dn_route.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2013-03-21 11:45:28 +0400
committerDavid S. Miller <davem@davemloft.net>2013-03-22 18:31:16 +0400
commit58d7d8f9b20ee6f883532b952f246e4289fe06eb (patch)
tree9d57be6839dd056ab37a63043ae871d36e0cf548 /net/decnet/dn_route.c
parent9b924dbd5e903aa6394ff6feee8275b9bde313d1 (diff)
downloadlinux-58d7d8f9b20ee6f883532b952f246e4289fe06eb.tar.xz
decnet: Parse netlink attributes on our own
decnet is the only subsystem left that is relying on the global netlink attribute buffer rta_buf. It's horrible design and we want to get rid of it. This converts all of decnet to do implicit attribute parsing. It also gets rid of the error prone struct dn_kern_rta. Yes, the fib_magic() stuff is not pretty. It's compiled tested but I need someone with appropriate hardware to test the patch since I don't have access to it. Cc: linux-decnet-user@lists.sourceforge.net Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/decnet/dn_route.c')
-rw-r--r--net/decnet/dn_route.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 5ac0e153ef83..b4b3508e77f0 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1619,17 +1619,21 @@ errout:
static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg)
{
struct net *net = sock_net(in_skb->sk);
- struct rtattr **rta = arg;
struct rtmsg *rtm = nlmsg_data(nlh);
struct dn_route *rt = NULL;
struct dn_skb_cb *cb;
int err;
struct sk_buff *skb;
struct flowidn fld;
+ struct nlattr *tb[RTA_MAX+1];
if (!net_eq(net, &init_net))
return -EINVAL;
+ err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_dn_policy);
+ if (err < 0)
+ return err;
+
memset(&fld, 0, sizeof(fld));
fld.flowidn_proto = DNPROTO_NSP;
@@ -1639,12 +1643,14 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
skb_reset_mac_header(skb);
cb = DN_SKB_CB(skb);
- if (rta[RTA_SRC-1])
- memcpy(&fld.saddr, RTA_DATA(rta[RTA_SRC-1]), 2);
- if (rta[RTA_DST-1])
- memcpy(&fld.daddr, RTA_DATA(rta[RTA_DST-1]), 2);
- if (rta[RTA_IIF-1])
- memcpy(&fld.flowidn_iif, RTA_DATA(rta[RTA_IIF-1]), sizeof(int));
+ if (tb[RTA_SRC])
+ fld.saddr = nla_get_le16(tb[RTA_SRC]);
+
+ if (tb[RTA_DST])
+ fld.daddr = nla_get_le16(tb[RTA_DST]);
+
+ if (tb[RTA_IIF])
+ fld.flowidn_iif = nla_get_u32(tb[RTA_IIF]);
if (fld.flowidn_iif) {
struct net_device *dev;
@@ -1669,10 +1675,9 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
if (!err && -rt->dst.error)
err = rt->dst.error;
} else {
- int oif = 0;
- if (rta[RTA_OIF - 1])
- memcpy(&oif, RTA_DATA(rta[RTA_OIF - 1]), sizeof(int));
- fld.flowidn_oif = oif;
+ if (tb[RTA_OIF])
+ fld.flowidn_oif = nla_get_u32(tb[RTA_OIF]);
+
err = dn_route_output_key((struct dst_entry **)&rt, &fld, 0);
}