aboutsummaryrefslogtreecommitdiffstats
path: root/net/decnet/dn_route.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2013-03-21 03:45:28 -0400
committerDavid S. Miller <davem@davemloft.net>2013-03-22 10:31:16 -0400
commit58d7d8f9b20ee6f883532b952f246e4289fe06eb (patch)
tree9d57be6839dd056ab37a63043ae871d36e0cf548 /net/decnet/dn_route.c
parent9b924dbd5e903aa6394ff6feee8275b9bde313d1 (diff)
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:
1619static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg) 1619static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg)
1620{ 1620{
1621 struct net *net = sock_net(in_skb->sk); 1621 struct net *net = sock_net(in_skb->sk);
1622 struct rtattr **rta = arg;
1623 struct rtmsg *rtm = nlmsg_data(nlh); 1622 struct rtmsg *rtm = nlmsg_data(nlh);
1624 struct dn_route *rt = NULL; 1623 struct dn_route *rt = NULL;
1625 struct dn_skb_cb *cb; 1624 struct dn_skb_cb *cb;
1626 int err; 1625 int err;
1627 struct sk_buff *skb; 1626 struct sk_buff *skb;
1628 struct flowidn fld; 1627 struct flowidn fld;
1628 struct nlattr *tb[RTA_MAX+1];
1629 1629
1630 if (!net_eq(net, &init_net)) 1630 if (!net_eq(net, &init_net))
1631 return -EINVAL; 1631 return -EINVAL;
1632 1632
1633 err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_dn_policy);
1634 if (err < 0)
1635 return err;
1636
1633 memset(&fld, 0, sizeof(fld)); 1637 memset(&fld, 0, sizeof(fld));
1634 fld.flowidn_proto = DNPROTO_NSP; 1638 fld.flowidn_proto = DNPROTO_NSP;
1635 1639
@@ -1639,12 +1643,14 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
1639 skb_reset_mac_header(skb); 1643 skb_reset_mac_header(skb);
1640 cb = DN_SKB_CB(skb); 1644 cb = DN_SKB_CB(skb);
1641 1645
1642 if (rta[RTA_SRC-1]) 1646 if (tb[RTA_SRC])
1643 memcpy(&fld.saddr, RTA_DATA(rta[RTA_SRC-1]), 2); 1647 fld.saddr = nla_get_le16(tb[RTA_SRC]);
1644 if (rta[RTA_DST-1]) 1648
1645 memcpy(&fld.daddr, RTA_DATA(rta[RTA_DST-1]), 2); 1649 if (tb[RTA_DST])
1646 if (rta[RTA_IIF-1]) 1650 fld.daddr = nla_get_le16(tb[RTA_DST]);
1647 memcpy(&fld.flowidn_iif, RTA_DATA(rta[RTA_IIF-1]), sizeof(int)); 1651
1652 if (tb[RTA_IIF])
1653 fld.flowidn_iif = nla_get_u32(tb[RTA_IIF]);
1648 1654
1649 if (fld.flowidn_iif) { 1655 if (fld.flowidn_iif) {
1650 struct net_device *dev; 1656 struct net_device *dev;
@@ -1669,10 +1675,9 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
1669 if (!err && -rt->dst.error) 1675 if (!err && -rt->dst.error)
1670 err = rt->dst.error; 1676 err = rt->dst.error;
1671 } else { 1677 } else {
1672 int oif = 0; 1678 if (tb[RTA_OIF])
1673 if (rta[RTA_OIF - 1]) 1679 fld.flowidn_oif = nla_get_u32(tb[RTA_OIF]);
1674 memcpy(&oif, RTA_DATA(rta[RTA_OIF - 1]), sizeof(int)); 1680
1675 fld.flowidn_oif = oif;
1676 err = dn_route_output_key((struct dst_entry **)&rt, &fld, 0); 1681 err = dn_route_output_key((struct dst_entry **)&rt, &fld, 0);
1677 } 1682 }
1678 1683