diff options
author | Thomas Graf <tgraf@suug.ch> | 2013-03-21 03:45:28 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-03-22 10:31:16 -0400 |
commit | 58d7d8f9b20ee6f883532b952f246e4289fe06eb (patch) | |
tree | 9d57be6839dd056ab37a63043ae871d36e0cf548 /net/decnet/dn_route.c | |
parent | 9b924dbd5e903aa6394ff6feee8275b9bde313d1 (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.c | 27 |
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: | |||
1619 | static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg) | 1619 | static 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 | ||