aboutsummaryrefslogtreecommitdiffstats
path: root/net/key
diff options
context:
space:
mode:
authorNicolas Dichtel <nicolas.dichtel@6wind.com>2014-02-14 09:30:36 -0500
committerSteffen Klassert <steffen.klassert@secunet.com>2014-02-17 01:18:19 -0500
commitd3623099d3509fa68fa28235366049dd3156c63a (patch)
treeff5daaf9b564f3a073a50ed461c7b823b899af7b /net/key
parent0f24558e91563888d51e9be5b70981da920c37ac (diff)
ipsec: add support of limited SA dump
The goal of this patch is to allow userland to dump only a part of SA by specifying a filter during the dump. The kernel is in charge to filter SA, this avoids to generate useless netlink traffic (it save also some cpu cycles). This is particularly useful when there is a big number of SA set on the system. Note that I removed the union in struct xfrm_state_walk to fix a problem on arm. struct netlink_callback->args is defined as a array of 6 long and the first long is used in xfrm code to flag the cb as initialized. Hence, we must have: sizeof(struct xfrm_state_walk) <= sizeof(long) * 5. With the union, it was false on arm (sizeof(struct xfrm_state_walk) was sizeof(long) * 7), due to the padding. In fact, whatever the arch is, this union seems useless, there will be always padding after it. Removing it will not increase the size of this struct (and reduce it on arm). Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/key')
-rw-r--r--net/key/af_key.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c
index e1c69d024197..f0879c19f452 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1798,6 +1798,7 @@ static void pfkey_dump_sa_done(struct pfkey_sock *pfk)
1798static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs) 1798static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs)
1799{ 1799{
1800 u8 proto; 1800 u8 proto;
1801 struct xfrm_filter *filter = NULL;
1801 struct pfkey_sock *pfk = pfkey_sk(sk); 1802 struct pfkey_sock *pfk = pfkey_sk(sk);
1802 1803
1803 if (pfk->dump.dump != NULL) 1804 if (pfk->dump.dump != NULL)
@@ -1807,11 +1808,27 @@ static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_ms
1807 if (proto == 0) 1808 if (proto == 0)
1808 return -EINVAL; 1809 return -EINVAL;
1809 1810
1811 if (ext_hdrs[SADB_X_EXT_FILTER - 1]) {
1812 struct sadb_x_filter *xfilter = ext_hdrs[SADB_X_EXT_FILTER - 1];
1813
1814 filter = kmalloc(sizeof(*filter), GFP_KERNEL);
1815 if (filter == NULL)
1816 return -ENOMEM;
1817
1818 memcpy(&filter->saddr, &xfilter->sadb_x_filter_saddr,
1819 sizeof(xfrm_address_t));
1820 memcpy(&filter->daddr, &xfilter->sadb_x_filter_daddr,
1821 sizeof(xfrm_address_t));
1822 filter->family = xfilter->sadb_x_filter_family;
1823 filter->splen = xfilter->sadb_x_filter_splen;
1824 filter->dplen = xfilter->sadb_x_filter_dplen;
1825 }
1826
1810 pfk->dump.msg_version = hdr->sadb_msg_version; 1827 pfk->dump.msg_version = hdr->sadb_msg_version;
1811 pfk->dump.msg_portid = hdr->sadb_msg_pid; 1828 pfk->dump.msg_portid = hdr->sadb_msg_pid;
1812 pfk->dump.dump = pfkey_dump_sa; 1829 pfk->dump.dump = pfkey_dump_sa;
1813 pfk->dump.done = pfkey_dump_sa_done; 1830 pfk->dump.done = pfkey_dump_sa_done;
1814 xfrm_state_walk_init(&pfk->dump.u.state, proto); 1831 xfrm_state_walk_init(&pfk->dump.u.state, proto, filter);
1815 1832
1816 return pfkey_do_dump(pfk); 1833 return pfkey_do_dump(pfk);
1817} 1834}