aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_user.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2007-08-22 16:57:39 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:48:22 -0400
commit7deb2264909ec82ae4696dd73d8ffce6814c9114 (patch)
treebee682118f12c19c2cd8cbdfe89165a221bfdc77 /net/xfrm/xfrm_user.c
parentcfbfd45a8c4c0c8dd8ed491caefdeffd94acf9e4 (diff)
[XFRM] netlink: Use nlmsg_new() and type-safe size calculation helpers
Moves all complex message size calculation into own inlined helper functions and makes use of the type-safe netlink interface. Using nlmsg_new() simplifies the calculation itself as it takes care of the netlink header length by itself. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r--net/xfrm/xfrm_user.c152
1 files changed, 83 insertions, 69 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 5efaf458270..78333298749 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -670,7 +670,7 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb,
670 struct xfrm_dump_info info; 670 struct xfrm_dump_info info;
671 struct sk_buff *skb; 671 struct sk_buff *skb;
672 672
673 skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC); 673 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
674 if (!skb) 674 if (!skb)
675 return ERR_PTR(-ENOMEM); 675 return ERR_PTR(-ENOMEM);
676 676
@@ -688,6 +688,13 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb,
688 return skb; 688 return skb;
689} 689}
690 690
691static inline size_t xfrm_spdinfo_msgsize(void)
692{
693 return NLMSG_ALIGN(4)
694 + nla_total_size(sizeof(struct xfrmu_spdinfo))
695 + nla_total_size(sizeof(struct xfrmu_spdhinfo));
696}
697
691static int build_spdinfo(struct sk_buff *skb, u32 pid, u32 seq, u32 flags) 698static int build_spdinfo(struct sk_buff *skb, u32 pid, u32 seq, u32 flags)
692{ 699{
693 struct xfrmk_spdinfo si; 700 struct xfrmk_spdinfo si;
@@ -729,12 +736,8 @@ static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
729 u32 *flags = nlmsg_data(nlh); 736 u32 *flags = nlmsg_data(nlh);
730 u32 spid = NETLINK_CB(skb).pid; 737 u32 spid = NETLINK_CB(skb).pid;
731 u32 seq = nlh->nlmsg_seq; 738 u32 seq = nlh->nlmsg_seq;
732 int len = NLMSG_LENGTH(sizeof(u32));
733 739
734 len += RTA_SPACE(sizeof(struct xfrmu_spdinfo)); 740 r_skb = nlmsg_new(xfrm_spdinfo_msgsize(), GFP_ATOMIC);
735 len += RTA_SPACE(sizeof(struct xfrmu_spdhinfo));
736
737 r_skb = alloc_skb(len, GFP_ATOMIC);
738 if (r_skb == NULL) 741 if (r_skb == NULL)
739 return -ENOMEM; 742 return -ENOMEM;
740 743
@@ -744,6 +747,13 @@ static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
744 return nlmsg_unicast(xfrm_nl, r_skb, spid); 747 return nlmsg_unicast(xfrm_nl, r_skb, spid);
745} 748}
746 749
750static inline size_t xfrm_sadinfo_msgsize(void)
751{
752 return NLMSG_ALIGN(4)
753 + nla_total_size(sizeof(struct xfrmu_sadhinfo))
754 + nla_total_size(4); /* XFRMA_SAD_CNT */
755}
756
747static int build_sadinfo(struct sk_buff *skb, u32 pid, u32 seq, u32 flags) 757static int build_sadinfo(struct sk_buff *skb, u32 pid, u32 seq, u32 flags)
748{ 758{
749 struct xfrmk_sadinfo si; 759 struct xfrmk_sadinfo si;
@@ -779,13 +789,8 @@ static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
779 u32 *flags = nlmsg_data(nlh); 789 u32 *flags = nlmsg_data(nlh);
780 u32 spid = NETLINK_CB(skb).pid; 790 u32 spid = NETLINK_CB(skb).pid;
781 u32 seq = nlh->nlmsg_seq; 791 u32 seq = nlh->nlmsg_seq;
782 int len = NLMSG_LENGTH(sizeof(u32));
783
784 len += RTA_SPACE(sizeof(struct xfrmu_sadhinfo));
785 len += RTA_SPACE(sizeof(u32));
786
787 r_skb = alloc_skb(len, GFP_ATOMIC);
788 792
793 r_skb = nlmsg_new(xfrm_sadinfo_msgsize(), GFP_ATOMIC);
789 if (r_skb == NULL) 794 if (r_skb == NULL)
790 return -ENOMEM; 795 return -ENOMEM;
791 796
@@ -1311,7 +1316,7 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb,
1311 struct xfrm_dump_info info; 1316 struct xfrm_dump_info info;
1312 struct sk_buff *skb; 1317 struct sk_buff *skb;
1313 1318
1314 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 1319 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1315 if (!skb) 1320 if (!skb)
1316 return ERR_PTR(-ENOMEM); 1321 return ERR_PTR(-ENOMEM);
1317 1322
@@ -1425,6 +1430,14 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
1425 return 0; 1430 return 0;
1426} 1431}
1427 1432
1433static inline size_t xfrm_aevent_msgsize(void)
1434{
1435 return NLMSG_ALIGN(sizeof(struct xfrm_aevent_id))
1436 + nla_total_size(sizeof(struct xfrm_replay_state))
1437 + nla_total_size(sizeof(struct xfrm_lifetime_cur))
1438 + nla_total_size(4) /* XFRM_AE_RTHR */
1439 + nla_total_size(4); /* XFRM_AE_ETHR */
1440}
1428 1441
1429static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, struct km_event *c) 1442static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, struct km_event *c)
1430{ 1443{
@@ -1469,19 +1482,9 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
1469 int err; 1482 int err;
1470 struct km_event c; 1483 struct km_event c;
1471 struct xfrm_aevent_id *p = nlmsg_data(nlh); 1484 struct xfrm_aevent_id *p = nlmsg_data(nlh);
1472 int len = NLMSG_LENGTH(sizeof(struct xfrm_aevent_id));
1473 struct xfrm_usersa_id *id = &p->sa_id; 1485 struct xfrm_usersa_id *id = &p->sa_id;
1474 1486
1475 len += RTA_SPACE(sizeof(struct xfrm_replay_state)); 1487 r_skb = nlmsg_new(xfrm_aevent_msgsize(), GFP_ATOMIC);
1476 len += RTA_SPACE(sizeof(struct xfrm_lifetime_cur));
1477
1478 if (p->flags&XFRM_AE_RTHR)
1479 len+=RTA_SPACE(sizeof(u32));
1480
1481 if (p->flags&XFRM_AE_ETHR)
1482 len+=RTA_SPACE(sizeof(u32));
1483
1484 r_skb = alloc_skb(len, GFP_ATOMIC);
1485 if (r_skb == NULL) 1488 if (r_skb == NULL)
1486 return -ENOMEM; 1489 return -ENOMEM;
1487 1490
@@ -1824,6 +1827,13 @@ static int copy_to_user_migrate(struct xfrm_migrate *m, struct sk_buff *skb)
1824 return nla_put(skb, XFRMA_MIGRATE, sizeof(um), &um); 1827 return nla_put(skb, XFRMA_MIGRATE, sizeof(um), &um);
1825} 1828}
1826 1829
1830static inline size_t xfrm_migrate_msgsize(int num_migrate)
1831{
1832 return NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_id))
1833 + nla_total_size(sizeof(struct xfrm_user_migrate) * num_migrate)
1834 + userpolicy_type_attrsize();
1835}
1836
1827static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m, 1837static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m,
1828 int num_migrate, struct xfrm_selector *sel, 1838 int num_migrate, struct xfrm_selector *sel,
1829 u8 dir, u8 type) 1839 u8 dir, u8 type)
@@ -1861,12 +1871,8 @@ static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
1861 struct xfrm_migrate *m, int num_migrate) 1871 struct xfrm_migrate *m, int num_migrate)
1862{ 1872{
1863 struct sk_buff *skb; 1873 struct sk_buff *skb;
1864 size_t len;
1865 1874
1866 len = RTA_SPACE(sizeof(struct xfrm_user_migrate) * num_migrate); 1875 skb = nlmsg_new(xfrm_migrate_msgsize(num_migrate), GFP_ATOMIC);
1867 len += NLMSG_SPACE(sizeof(struct xfrm_userpolicy_id));
1868 len += userpolicy_type_attrsize();
1869 skb = alloc_skb(len, GFP_ATOMIC);
1870 if (skb == NULL) 1876 if (skb == NULL)
1871 return -ENOMEM; 1877 return -ENOMEM;
1872 1878
@@ -2002,6 +2008,11 @@ static void xfrm_netlink_rcv(struct sock *sk, int len)
2002 } while (qlen); 2008 } while (qlen);
2003} 2009}
2004 2010
2011static inline size_t xfrm_expire_msgsize(void)
2012{
2013 return NLMSG_ALIGN(sizeof(struct xfrm_user_expire));
2014}
2015
2005static int build_expire(struct sk_buff *skb, struct xfrm_state *x, struct km_event *c) 2016static int build_expire(struct sk_buff *skb, struct xfrm_state *x, struct km_event *c)
2006{ 2017{
2007 struct xfrm_user_expire *ue; 2018 struct xfrm_user_expire *ue;
@@ -2021,9 +2032,8 @@ static int build_expire(struct sk_buff *skb, struct xfrm_state *x, struct km_eve
2021static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c) 2032static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c)
2022{ 2033{
2023 struct sk_buff *skb; 2034 struct sk_buff *skb;
2024 int len = NLMSG_LENGTH(sizeof(struct xfrm_user_expire));
2025 2035
2026 skb = alloc_skb(len, GFP_ATOMIC); 2036 skb = nlmsg_new(xfrm_expire_msgsize(), GFP_ATOMIC);
2027 if (skb == NULL) 2037 if (skb == NULL)
2028 return -ENOMEM; 2038 return -ENOMEM;
2029 2039
@@ -2036,11 +2046,8 @@ static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c)
2036static int xfrm_aevent_state_notify(struct xfrm_state *x, struct km_event *c) 2046static int xfrm_aevent_state_notify(struct xfrm_state *x, struct km_event *c)
2037{ 2047{
2038 struct sk_buff *skb; 2048 struct sk_buff *skb;
2039 int len = NLMSG_LENGTH(sizeof(struct xfrm_aevent_id));
2040 2049
2041 len += RTA_SPACE(sizeof(struct xfrm_replay_state)); 2050 skb = nlmsg_new(xfrm_aevent_msgsize(), GFP_ATOMIC);
2042 len += RTA_SPACE(sizeof(struct xfrm_lifetime_cur));
2043 skb = alloc_skb(len, GFP_ATOMIC);
2044 if (skb == NULL) 2051 if (skb == NULL)
2045 return -ENOMEM; 2052 return -ENOMEM;
2046 2053
@@ -2055,9 +2062,9 @@ static int xfrm_notify_sa_flush(struct km_event *c)
2055 struct xfrm_usersa_flush *p; 2062 struct xfrm_usersa_flush *p;
2056 struct nlmsghdr *nlh; 2063 struct nlmsghdr *nlh;
2057 struct sk_buff *skb; 2064 struct sk_buff *skb;
2058 int len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_flush)); 2065 int len = NLMSG_ALIGN(sizeof(struct xfrm_usersa_flush));
2059 2066
2060 skb = alloc_skb(len, GFP_ATOMIC); 2067 skb = nlmsg_new(len, GFP_ATOMIC);
2061 if (skb == NULL) 2068 if (skb == NULL)
2062 return -ENOMEM; 2069 return -ENOMEM;
2063 2070
@@ -2075,17 +2082,17 @@ static int xfrm_notify_sa_flush(struct km_event *c)
2075 return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC); 2082 return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC);
2076} 2083}
2077 2084
2078static inline int xfrm_sa_len(struct xfrm_state *x) 2085static inline size_t xfrm_sa_len(struct xfrm_state *x)
2079{ 2086{
2080 int l = 0; 2087 size_t l = 0;
2081 if (x->aalg) 2088 if (x->aalg)
2082 l += RTA_SPACE(alg_len(x->aalg)); 2089 l += nla_total_size(alg_len(x->aalg));
2083 if (x->ealg) 2090 if (x->ealg)
2084 l += RTA_SPACE(alg_len(x->ealg)); 2091 l += nla_total_size(alg_len(x->ealg));
2085 if (x->calg) 2092 if (x->calg)
2086 l += RTA_SPACE(sizeof(*x->calg)); 2093 l += nla_total_size(sizeof(*x->calg));
2087 if (x->encap) 2094 if (x->encap)
2088 l += RTA_SPACE(sizeof(*x->encap)); 2095 l += nla_total_size(sizeof(*x->encap));
2089 2096
2090 return l; 2097 return l;
2091} 2098}
@@ -2101,12 +2108,12 @@ static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c)
2101 2108
2102 headlen = sizeof(*p); 2109 headlen = sizeof(*p);
2103 if (c->event == XFRM_MSG_DELSA) { 2110 if (c->event == XFRM_MSG_DELSA) {
2104 len += RTA_SPACE(headlen); 2111 len += nla_total_size(headlen);
2105 headlen = sizeof(*id); 2112 headlen = sizeof(*id);
2106 } 2113 }
2107 len += NLMSG_SPACE(headlen); 2114 len += NLMSG_ALIGN(headlen);
2108 2115
2109 skb = alloc_skb(len, GFP_ATOMIC); 2116 skb = nlmsg_new(len, GFP_ATOMIC);
2110 if (skb == NULL) 2117 if (skb == NULL)
2111 return -ENOMEM; 2118 return -ENOMEM;
2112 2119
@@ -2175,6 +2182,15 @@ static int xfrm_send_state_notify(struct xfrm_state *x, struct km_event *c)
2175 2182
2176} 2183}
2177 2184
2185static inline size_t xfrm_acquire_msgsize(struct xfrm_state *x,
2186 struct xfrm_policy *xp)
2187{
2188 return NLMSG_ALIGN(sizeof(struct xfrm_user_acquire))
2189 + nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr)
2190 + nla_total_size(xfrm_user_sec_ctx_size(x->security))
2191 + userpolicy_type_attrsize();
2192}
2193
2178static int build_acquire(struct sk_buff *skb, struct xfrm_state *x, 2194static int build_acquire(struct sk_buff *skb, struct xfrm_state *x,
2179 struct xfrm_tmpl *xt, struct xfrm_policy *xp, 2195 struct xfrm_tmpl *xt, struct xfrm_policy *xp,
2180 int dir) 2196 int dir)
@@ -2215,13 +2231,8 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt,
2215 struct xfrm_policy *xp, int dir) 2231 struct xfrm_policy *xp, int dir)
2216{ 2232{
2217 struct sk_buff *skb; 2233 struct sk_buff *skb;
2218 size_t len;
2219 2234
2220 len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); 2235 skb = nlmsg_new(xfrm_acquire_msgsize(x, xp), GFP_ATOMIC);
2221 len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire));
2222 len += RTA_SPACE(xfrm_user_sec_ctx_size(x->security));
2223 len += userpolicy_type_attrsize();
2224 skb = alloc_skb(len, GFP_ATOMIC);
2225 if (skb == NULL) 2236 if (skb == NULL)
2226 return -ENOMEM; 2237 return -ENOMEM;
2227 2238
@@ -2290,6 +2301,14 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
2290 return xp; 2301 return xp;
2291} 2302}
2292 2303
2304static inline size_t xfrm_polexpire_msgsize(struct xfrm_policy *xp)
2305{
2306 return NLMSG_ALIGN(sizeof(struct xfrm_user_polexpire))
2307 + nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr)
2308 + nla_total_size(xfrm_user_sec_ctx_size(xp->security))
2309 + userpolicy_type_attrsize();
2310}
2311
2293static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp, 2312static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp,
2294 int dir, struct km_event *c) 2313 int dir, struct km_event *c)
2295{ 2314{
@@ -2321,13 +2340,8 @@ nlmsg_failure:
2321static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c) 2340static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c)
2322{ 2341{
2323 struct sk_buff *skb; 2342 struct sk_buff *skb;
2324 size_t len;
2325 2343
2326 len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); 2344 skb = nlmsg_new(xfrm_polexpire_msgsize(xp), GFP_ATOMIC);
2327 len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire));
2328 len += RTA_SPACE(xfrm_user_sec_ctx_size(xp->security));
2329 len += userpolicy_type_attrsize();
2330 skb = alloc_skb(len, GFP_ATOMIC);
2331 if (skb == NULL) 2345 if (skb == NULL)
2332 return -ENOMEM; 2346 return -ENOMEM;
2333 2347
@@ -2343,18 +2357,18 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *
2343 struct xfrm_userpolicy_id *id; 2357 struct xfrm_userpolicy_id *id;
2344 struct nlmsghdr *nlh; 2358 struct nlmsghdr *nlh;
2345 struct sk_buff *skb; 2359 struct sk_buff *skb;
2346 int len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); 2360 int len = nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
2347 int headlen; 2361 int headlen;
2348 2362
2349 headlen = sizeof(*p); 2363 headlen = sizeof(*p);
2350 if (c->event == XFRM_MSG_DELPOLICY) { 2364 if (c->event == XFRM_MSG_DELPOLICY) {
2351 len += RTA_SPACE(headlen); 2365 len += nla_total_size(headlen);
2352 headlen = sizeof(*id); 2366 headlen = sizeof(*id);
2353 } 2367 }
2354 len += userpolicy_type_attrsize(); 2368 len += userpolicy_type_attrsize();
2355 len += NLMSG_SPACE(headlen); 2369 len += NLMSG_ALIGN(headlen);
2356 2370
2357 skb = alloc_skb(len, GFP_ATOMIC); 2371 skb = nlmsg_new(len, GFP_ATOMIC);
2358 if (skb == NULL) 2372 if (skb == NULL)
2359 return -ENOMEM; 2373 return -ENOMEM;
2360 2374
@@ -2400,11 +2414,8 @@ static int xfrm_notify_policy_flush(struct km_event *c)
2400{ 2414{
2401 struct nlmsghdr *nlh; 2415 struct nlmsghdr *nlh;
2402 struct sk_buff *skb; 2416 struct sk_buff *skb;
2403 int len = 0;
2404 len += userpolicy_type_attrsize();
2405 len += NLMSG_LENGTH(0);
2406 2417
2407 skb = alloc_skb(len, GFP_ATOMIC); 2418 skb = nlmsg_new(userpolicy_type_attrsize(), GFP_ATOMIC);
2408 if (skb == NULL) 2419 if (skb == NULL)
2409 return -ENOMEM; 2420 return -ENOMEM;
2410 2421
@@ -2443,6 +2454,11 @@ static int xfrm_send_policy_notify(struct xfrm_policy *xp, int dir, struct km_ev
2443 2454
2444} 2455}
2445 2456
2457static inline size_t xfrm_report_msgsize(void)
2458{
2459 return NLMSG_ALIGN(sizeof(struct xfrm_user_report));
2460}
2461
2446static int build_report(struct sk_buff *skb, u8 proto, 2462static int build_report(struct sk_buff *skb, u8 proto,
2447 struct xfrm_selector *sel, xfrm_address_t *addr) 2463 struct xfrm_selector *sel, xfrm_address_t *addr)
2448{ 2464{
@@ -2471,10 +2487,8 @@ static int xfrm_send_report(u8 proto, struct xfrm_selector *sel,
2471 xfrm_address_t *addr) 2487 xfrm_address_t *addr)
2472{ 2488{
2473 struct sk_buff *skb; 2489 struct sk_buff *skb;
2474 size_t len;
2475 2490
2476 len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct xfrm_user_report))); 2491 skb = nlmsg_new(xfrm_report_msgsize(), GFP_ATOMIC);
2477 skb = alloc_skb(len, GFP_ATOMIC);
2478 if (skb == NULL) 2492 if (skb == NULL)
2479 return -ENOMEM; 2493 return -ENOMEM;
2480 2494