aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2006-11-10 17:10:15 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-03 00:22:11 -0500
commit339bf98ffc6a8d8eb16fc532ac57ffbced2f8a68 (patch)
tree499ad948863d2753ca10283dcf006ad28954538e /net/ipv6/addrconf.c
parenta94f723d595ee085f81b1788d18e031af7eeba91 (diff)
[NETLINK]: Do precise netlink message allocations where possible
Account for the netlink message header size directly in nlmsg_new() instead of relying on the caller calculate it correctly. Replaces error handling of message construction functions when constructing notifications with bug traps since a failure implies a bug in calculating the size of the skb. Signed-off-by: Thomas Graf <tgraf@suug.ch> Acked-by: Paul Moore <paul.moore@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c70
1 files changed, 32 insertions, 38 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6a98f68348cb..967ea320a9ca 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3098,10 +3098,9 @@ static inline int rt_scope(int ifa_scope)
3098 3098
3099static inline int inet6_ifaddr_msgsize(void) 3099static inline int inet6_ifaddr_msgsize(void)
3100{ 3100{
3101 return nlmsg_total_size(sizeof(struct ifaddrmsg) + 3101 return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
3102 nla_total_size(16) + 3102 + nla_total_size(16) /* IFA_ADDRESS */
3103 nla_total_size(sizeof(struct ifa_cacheinfo)) + 3103 + nla_total_size(sizeof(struct ifa_cacheinfo));
3104 128);
3105} 3104}
3106 3105
3107static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, 3106static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
@@ -3329,10 +3328,8 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
3329 3328
3330 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid, 3329 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid,
3331 nlh->nlmsg_seq, RTM_NEWADDR, 0); 3330 nlh->nlmsg_seq, RTM_NEWADDR, 0);
3332 if (err < 0) { 3331 /* failure implies BUG in inet6_ifaddr_msgsize() */
3333 kfree_skb(skb); 3332 BUG_ON(err < 0);
3334 goto errout_ifa;
3335 }
3336 3333
3337 err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid); 3334 err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
3338errout_ifa: 3335errout_ifa:
@@ -3351,10 +3348,8 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
3351 goto errout; 3348 goto errout;
3352 3349
3353 err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0); 3350 err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0);
3354 if (err < 0) { 3351 /* failure implies BUG in inet6_ifaddr_msgsize() */
3355 kfree_skb(skb); 3352 BUG_ON(err < 0);
3356 goto errout;
3357 }
3358 3353
3359 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); 3354 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
3360errout: 3355errout:
@@ -3397,16 +3392,19 @@ static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
3397 array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp; 3392 array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp;
3398} 3393}
3399 3394
3400/* Maximum length of ifinfomsg attributes */ 3395static inline size_t inet6_if_nlmsg_size(void)
3401#define INET6_IFINFO_RTA_SPACE \ 3396{
3402 RTA_SPACE(IFNAMSIZ) /* IFNAME */ + \ 3397 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
3403 RTA_SPACE(MAX_ADDR_LEN) /* ADDRESS */ + \ 3398 + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
3404 RTA_SPACE(sizeof(u32)) /* MTU */ + \ 3399 + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
3405 RTA_SPACE(sizeof(int)) /* LINK */ + \ 3400 + nla_total_size(4) /* IFLA_MTU */
3406 RTA_SPACE(0) /* PROTINFO */ + \ 3401 + nla_total_size(4) /* IFLA_LINK */
3407 RTA_SPACE(sizeof(u32)) /* FLAGS */ + \ 3402 + nla_total_size( /* IFLA_PROTINFO */
3408 RTA_SPACE(sizeof(struct ifla_cacheinfo)) /* CACHEINFO */ + \ 3403 nla_total_size(4) /* IFLA_INET6_FLAGS */
3409 RTA_SPACE(sizeof(__s32[DEVCONF_MAX])) /* CONF */ 3404 + nla_total_size(sizeof(struct ifla_cacheinfo))
3405 + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */
3406 );
3407}
3410 3408
3411static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, 3409static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
3412 u32 pid, u32 seq, int event, unsigned int flags) 3410 u32 pid, u32 seq, int event, unsigned int flags)
@@ -3501,18 +3499,15 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
3501void inet6_ifinfo_notify(int event, struct inet6_dev *idev) 3499void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
3502{ 3500{
3503 struct sk_buff *skb; 3501 struct sk_buff *skb;
3504 int payload = sizeof(struct ifinfomsg) + INET6_IFINFO_RTA_SPACE;
3505 int err = -ENOBUFS; 3502 int err = -ENOBUFS;
3506 3503
3507 skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC); 3504 skb = nlmsg_new(inet6_if_nlmsg_size(), GFP_ATOMIC);
3508 if (skb == NULL) 3505 if (skb == NULL)
3509 goto errout; 3506 goto errout;
3510 3507
3511 err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0); 3508 err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0);
3512 if (err < 0) { 3509 /* failure implies BUG in inet6_if_nlmsg_size() */
3513 kfree_skb(skb); 3510 BUG_ON(err < 0);
3514 goto errout;
3515 }
3516 3511
3517 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); 3512 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
3518errout: 3513errout:
@@ -3520,10 +3515,12 @@ errout:
3520 rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err); 3515 rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
3521} 3516}
3522 3517
3523/* Maximum length of prefix_cacheinfo attributes */ 3518static inline size_t inet6_prefix_nlmsg_size(void)
3524#define INET6_PREFIX_RTA_SPACE \ 3519{
3525 RTA_SPACE(sizeof(((struct prefix_info *)NULL)->prefix)) /* ADDRESS */ + \ 3520 return NLMSG_ALIGN(sizeof(struct prefixmsg))
3526 RTA_SPACE(sizeof(struct prefix_cacheinfo)) /* CACHEINFO */ 3521 + nla_total_size(sizeof(struct in6_addr))
3522 + nla_total_size(sizeof(struct prefix_cacheinfo));
3523}
3527 3524
3528static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, 3525static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
3529 struct prefix_info *pinfo, u32 pid, u32 seq, 3526 struct prefix_info *pinfo, u32 pid, u32 seq,
@@ -3569,18 +3566,15 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
3569 struct prefix_info *pinfo) 3566 struct prefix_info *pinfo)
3570{ 3567{
3571 struct sk_buff *skb; 3568 struct sk_buff *skb;
3572 int payload = sizeof(struct prefixmsg) + INET6_PREFIX_RTA_SPACE;
3573 int err = -ENOBUFS; 3569 int err = -ENOBUFS;
3574 3570
3575 skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC); 3571 skb = nlmsg_new(inet6_prefix_nlmsg_size(), GFP_ATOMIC);
3576 if (skb == NULL) 3572 if (skb == NULL)
3577 goto errout; 3573 goto errout;
3578 3574
3579 err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0); 3575 err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0);
3580 if (err < 0) { 3576 /* failure implies BUG in inet6_prefix_nlmsg_size() */
3581 kfree_skb(skb); 3577 BUG_ON(err < 0);
3582 goto errout;
3583 }
3584 3578
3585 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC); 3579 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
3586errout: 3580errout: