diff options
author | Thomas Graf <tgraf@suug.ch> | 2013-03-21 03:45:29 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-03-22 10:31:16 -0400 |
commit | 661d2967b3f1b34eeaa7e212e7b9bbe8ee072b59 (patch) | |
tree | 66090f1be05a40962838114d66cb085875f58c8a /net/core/rtnetlink.c | |
parent | 58d7d8f9b20ee6f883532b952f246e4289fe06eb (diff) |
rtnetlink: Remove passing of attributes into rtnl_doit functions
With decnet converted, we can finally get rid of rta_buf and its
computations around it. It also gets rid of the minimal header
length verification since all message handlers do that explicitly
anyway.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r-- | net/core/rtnetlink.c | 82 |
1 files changed, 9 insertions, 73 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 9a9b99e1fb70..751f1244b648 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -515,32 +515,6 @@ out: | |||
515 | return err; | 515 | return err; |
516 | } | 516 | } |
517 | 517 | ||
518 | static const int rtm_min[RTM_NR_FAMILIES] = | ||
519 | { | ||
520 | [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)), | ||
521 | [RTM_FAM(RTM_NEWADDR)] = NLMSG_LENGTH(sizeof(struct ifaddrmsg)), | ||
522 | [RTM_FAM(RTM_NEWROUTE)] = NLMSG_LENGTH(sizeof(struct rtmsg)), | ||
523 | [RTM_FAM(RTM_NEWRULE)] = NLMSG_LENGTH(sizeof(struct fib_rule_hdr)), | ||
524 | [RTM_FAM(RTM_NEWQDISC)] = NLMSG_LENGTH(sizeof(struct tcmsg)), | ||
525 | [RTM_FAM(RTM_NEWTCLASS)] = NLMSG_LENGTH(sizeof(struct tcmsg)), | ||
526 | [RTM_FAM(RTM_NEWTFILTER)] = NLMSG_LENGTH(sizeof(struct tcmsg)), | ||
527 | [RTM_FAM(RTM_NEWACTION)] = NLMSG_LENGTH(sizeof(struct tcamsg)), | ||
528 | [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), | ||
529 | [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), | ||
530 | }; | ||
531 | |||
532 | static const int rta_max[RTM_NR_FAMILIES] = | ||
533 | { | ||
534 | [RTM_FAM(RTM_NEWLINK)] = IFLA_MAX, | ||
535 | [RTM_FAM(RTM_NEWADDR)] = IFA_MAX, | ||
536 | [RTM_FAM(RTM_NEWROUTE)] = RTA_MAX, | ||
537 | [RTM_FAM(RTM_NEWRULE)] = FRA_MAX, | ||
538 | [RTM_FAM(RTM_NEWQDISC)] = TCA_MAX, | ||
539 | [RTM_FAM(RTM_NEWTCLASS)] = TCA_MAX, | ||
540 | [RTM_FAM(RTM_NEWTFILTER)] = TCA_MAX, | ||
541 | [RTM_FAM(RTM_NEWACTION)] = TCAA_MAX, | ||
542 | }; | ||
543 | |||
544 | int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned int group, int echo) | 518 | int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned int group, int echo) |
545 | { | 519 | { |
546 | struct sock *rtnl = net->rtnl; | 520 | struct sock *rtnl = net->rtnl; |
@@ -1537,7 +1511,7 @@ errout: | |||
1537 | return err; | 1511 | return err; |
1538 | } | 1512 | } |
1539 | 1513 | ||
1540 | static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1514 | static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh) |
1541 | { | 1515 | { |
1542 | struct net *net = sock_net(skb->sk); | 1516 | struct net *net = sock_net(skb->sk); |
1543 | struct ifinfomsg *ifm; | 1517 | struct ifinfomsg *ifm; |
@@ -1578,7 +1552,7 @@ errout: | |||
1578 | return err; | 1552 | return err; |
1579 | } | 1553 | } |
1580 | 1554 | ||
1581 | static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1555 | static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh) |
1582 | { | 1556 | { |
1583 | struct net *net = sock_net(skb->sk); | 1557 | struct net *net = sock_net(skb->sk); |
1584 | const struct rtnl_link_ops *ops; | 1558 | const struct rtnl_link_ops *ops; |
@@ -1709,7 +1683,7 @@ static int rtnl_group_changelink(struct net *net, int group, | |||
1709 | return 0; | 1683 | return 0; |
1710 | } | 1684 | } |
1711 | 1685 | ||
1712 | static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1686 | static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh) |
1713 | { | 1687 | { |
1714 | struct net *net = sock_net(skb->sk); | 1688 | struct net *net = sock_net(skb->sk); |
1715 | const struct rtnl_link_ops *ops; | 1689 | const struct rtnl_link_ops *ops; |
@@ -1864,7 +1838,7 @@ out: | |||
1864 | } | 1838 | } |
1865 | } | 1839 | } |
1866 | 1840 | ||
1867 | static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | 1841 | static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh) |
1868 | { | 1842 | { |
1869 | struct net *net = sock_net(skb->sk); | 1843 | struct net *net = sock_net(skb->sk); |
1870 | struct ifinfomsg *ifm; | 1844 | struct ifinfomsg *ifm; |
@@ -2081,7 +2055,7 @@ int ndo_dflt_fdb_add(struct ndmsg *ndm, | |||
2081 | } | 2055 | } |
2082 | EXPORT_SYMBOL(ndo_dflt_fdb_add); | 2056 | EXPORT_SYMBOL(ndo_dflt_fdb_add); |
2083 | 2057 | ||
2084 | static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 2058 | static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh) |
2085 | { | 2059 | { |
2086 | struct net *net = sock_net(skb->sk); | 2060 | struct net *net = sock_net(skb->sk); |
2087 | struct ndmsg *ndm; | 2061 | struct ndmsg *ndm; |
@@ -2179,7 +2153,7 @@ int ndo_dflt_fdb_del(struct ndmsg *ndm, | |||
2179 | } | 2153 | } |
2180 | EXPORT_SYMBOL(ndo_dflt_fdb_del); | 2154 | EXPORT_SYMBOL(ndo_dflt_fdb_del); |
2181 | 2155 | ||
2182 | static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 2156 | static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh) |
2183 | { | 2157 | { |
2184 | struct net *net = sock_net(skb->sk); | 2158 | struct net *net = sock_net(skb->sk); |
2185 | struct ndmsg *ndm; | 2159 | struct ndmsg *ndm; |
@@ -2478,8 +2452,7 @@ errout: | |||
2478 | return err; | 2452 | return err; |
2479 | } | 2453 | } |
2480 | 2454 | ||
2481 | static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, | 2455 | static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh) |
2482 | void *arg) | ||
2483 | { | 2456 | { |
2484 | struct net *net = sock_net(skb->sk); | 2457 | struct net *net = sock_net(skb->sk); |
2485 | struct ifinfomsg *ifm; | 2458 | struct ifinfomsg *ifm; |
@@ -2549,8 +2522,7 @@ out: | |||
2549 | return err; | 2522 | return err; |
2550 | } | 2523 | } |
2551 | 2524 | ||
2552 | static int rtnl_bridge_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, | 2525 | static int rtnl_bridge_dellink(struct sk_buff *skb, struct nlmsghdr *nlh) |
2553 | void *arg) | ||
2554 | { | 2526 | { |
2555 | struct net *net = sock_net(skb->sk); | 2527 | struct net *net = sock_net(skb->sk); |
2556 | struct ifinfomsg *ifm; | 2528 | struct ifinfomsg *ifm; |
@@ -2620,10 +2592,6 @@ out: | |||
2620 | return err; | 2592 | return err; |
2621 | } | 2593 | } |
2622 | 2594 | ||
2623 | /* Protected by RTNL sempahore. */ | ||
2624 | static struct rtattr **rta_buf; | ||
2625 | static int rtattr_max; | ||
2626 | |||
2627 | /* Process one rtnetlink message. */ | 2595 | /* Process one rtnetlink message. */ |
2628 | 2596 | ||
2629 | static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | 2597 | static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
@@ -2631,7 +2599,6 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2631 | struct net *net = sock_net(skb->sk); | 2599 | struct net *net = sock_net(skb->sk); |
2632 | rtnl_doit_func doit; | 2600 | rtnl_doit_func doit; |
2633 | int sz_idx, kind; | 2601 | int sz_idx, kind; |
2634 | int min_len; | ||
2635 | int family; | 2602 | int family; |
2636 | int type; | 2603 | int type; |
2637 | int err; | 2604 | int err; |
@@ -2679,32 +2646,11 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2679 | return err; | 2646 | return err; |
2680 | } | 2647 | } |
2681 | 2648 | ||
2682 | memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *))); | ||
2683 | |||
2684 | min_len = rtm_min[sz_idx]; | ||
2685 | if (nlh->nlmsg_len < min_len) | ||
2686 | return -EINVAL; | ||
2687 | |||
2688 | if (nlh->nlmsg_len > min_len) { | ||
2689 | int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); | ||
2690 | struct rtattr *attr = (void *)nlh + NLMSG_ALIGN(min_len); | ||
2691 | |||
2692 | while (RTA_OK(attr, attrlen)) { | ||
2693 | unsigned int flavor = attr->rta_type & NLA_TYPE_MASK; | ||
2694 | if (flavor) { | ||
2695 | if (flavor > rta_max[sz_idx]) | ||
2696 | return -EINVAL; | ||
2697 | rta_buf[flavor-1] = attr; | ||
2698 | } | ||
2699 | attr = RTA_NEXT(attr, attrlen); | ||
2700 | } | ||
2701 | } | ||
2702 | |||
2703 | doit = rtnl_get_doit(family, type); | 2649 | doit = rtnl_get_doit(family, type); |
2704 | if (doit == NULL) | 2650 | if (doit == NULL) |
2705 | return -EOPNOTSUPP; | 2651 | return -EOPNOTSUPP; |
2706 | 2652 | ||
2707 | return doit(skb, nlh, (void *)&rta_buf[0]); | 2653 | return doit(skb, nlh); |
2708 | } | 2654 | } |
2709 | 2655 | ||
2710 | static void rtnetlink_rcv(struct sk_buff *skb) | 2656 | static void rtnetlink_rcv(struct sk_buff *skb) |
@@ -2774,16 +2720,6 @@ static struct pernet_operations rtnetlink_net_ops = { | |||
2774 | 2720 | ||
2775 | void __init rtnetlink_init(void) | 2721 | void __init rtnetlink_init(void) |
2776 | { | 2722 | { |
2777 | int i; | ||
2778 | |||
2779 | rtattr_max = 0; | ||
2780 | for (i = 0; i < ARRAY_SIZE(rta_max); i++) | ||
2781 | if (rta_max[i] > rtattr_max) | ||
2782 | rtattr_max = rta_max[i]; | ||
2783 | rta_buf = kmalloc(rtattr_max * sizeof(struct rtattr *), GFP_KERNEL); | ||
2784 | if (!rta_buf) | ||
2785 | panic("rtnetlink_init: cannot allocate rta_buf\n"); | ||
2786 | |||
2787 | if (register_pernet_subsys(&rtnetlink_net_ops)) | 2723 | if (register_pernet_subsys(&rtnetlink_net_ops)) |
2788 | panic("rtnetlink_init: cannot initialize rtnetlink\n"); | 2724 | panic("rtnetlink_init: cannot initialize rtnetlink\n"); |
2789 | 2725 | ||