Commit 7ced8237 authored by David S. Miller's avatar David S. Miller

[NET]: Calculate RTATTR_MAX at run time.

This also solved a problem noticed by Thomas Graf
in that RTATTR_MAX had become incorrect recently
due to IFLA_MAX increasing and thus becomming the
largest one.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 48ae6c29
...@@ -660,10 +660,6 @@ enum ...@@ -660,10 +660,6 @@ enum
#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg)) #define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
/* SUMMARY: maximal rtattr understood by kernel */
#define RTATTR_MAX RTA_MAX
/* RTnetlink multicast groups */ /* RTnetlink multicast groups */
#define RTMGRP_LINK 1 #define RTMGRP_LINK 1
......
...@@ -401,6 +401,10 @@ static int rtnetlink_done(struct netlink_callback *cb) ...@@ -401,6 +401,10 @@ static int rtnetlink_done(struct netlink_callback *cb)
return 0; return 0;
} }
/* Protected by RTNL sempahore. */
static struct rtattr **rta_buf;
static int rtattr_max;
/* Process one rtnetlink message. */ /* Process one rtnetlink message. */
static __inline__ int static __inline__ int
...@@ -408,8 +412,6 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) ...@@ -408,8 +412,6 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
{ {
struct rtnetlink_link *link; struct rtnetlink_link *link;
struct rtnetlink_link *link_tab; struct rtnetlink_link *link_tab;
struct rtattr *rta[RTATTR_MAX];
int sz_idx, kind; int sz_idx, kind;
int min_len; int min_len;
int family; int family;
...@@ -476,7 +478,7 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) ...@@ -476,7 +478,7 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
return -1; return -1;
} }
memset(&rta, 0, sizeof(rta)); memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *)));
min_len = rtm_min[sz_idx]; min_len = rtm_min[sz_idx];
if (nlh->nlmsg_len < min_len) if (nlh->nlmsg_len < min_len)
...@@ -491,7 +493,7 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) ...@@ -491,7 +493,7 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
if (flavor) { if (flavor) {
if (flavor > rta_max[sz_idx]) if (flavor > rta_max[sz_idx])
goto err_inval; goto err_inval;
rta[flavor-1] = attr; rta_buf[flavor-1] = attr;
} }
attr = RTA_NEXT(attr, attrlen); attr = RTA_NEXT(attr, attrlen);
} }
...@@ -501,7 +503,7 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) ...@@ -501,7 +503,7 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
link = &(rtnetlink_links[PF_UNSPEC][type]); link = &(rtnetlink_links[PF_UNSPEC][type]);
if (link->doit == NULL) if (link->doit == NULL)
goto err_inval; goto err_inval;
err = link->doit(skb, nlh, (void *)&rta); err = link->doit(skb, nlh, (void *)&rta_buf[0]);
*errp = err; *errp = err;
return err; return err;
...@@ -621,6 +623,16 @@ static struct notifier_block rtnetlink_dev_notifier = { ...@@ -621,6 +623,16 @@ static struct notifier_block rtnetlink_dev_notifier = {
void __init rtnetlink_init(void) void __init rtnetlink_init(void)
{ {
int i;
rtattr_max = 0;
for (i = 0; i < ARRAY_SIZE(rta_max); i++)
if (rta_max[i] > rtattr_max)
rtattr_max = rta_max[i];
rta_buf = kmalloc(rtattr_max * sizeof(struct rtattr *), GFP_KERNEL);
if (!rta_buf)
panic("rtnetlink_init: cannot allocate rta_buf\n");
rtnl = netlink_kernel_create(NETLINK_ROUTE, rtnetlink_rcv); rtnl = netlink_kernel_create(NETLINK_ROUTE, rtnetlink_rcv);
if (rtnl == NULL) if (rtnl == NULL)
panic("rtnetlink_init: cannot initialize rtnetlink\n"); panic("rtnetlink_init: cannot initialize rtnetlink\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment