aboutsummaryrefslogtreecommitdiffstats
path: root/net/key
diff options
context:
space:
mode:
Diffstat (limited to 'net/key')
-rw-r--r--net/key/af_key.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 79326978517a..e72589a8400d 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -365,6 +365,7 @@ static const u8 sadb_ext_min_len[] = {
365 [SADB_X_EXT_NAT_T_OA] = (u8) sizeof(struct sadb_address), 365 [SADB_X_EXT_NAT_T_OA] = (u8) sizeof(struct sadb_address),
366 [SADB_X_EXT_SEC_CTX] = (u8) sizeof(struct sadb_x_sec_ctx), 366 [SADB_X_EXT_SEC_CTX] = (u8) sizeof(struct sadb_x_sec_ctx),
367 [SADB_X_EXT_KMADDRESS] = (u8) sizeof(struct sadb_x_kmaddress), 367 [SADB_X_EXT_KMADDRESS] = (u8) sizeof(struct sadb_x_kmaddress),
368 [SADB_X_EXT_FILTER] = (u8) sizeof(struct sadb_x_filter),
368}; 369};
369 370
370/* Verify sadb_address_{len,prefixlen} against sa_family. */ 371/* Verify sadb_address_{len,prefixlen} against sa_family. */
@@ -1799,6 +1800,7 @@ static void pfkey_dump_sa_done(struct pfkey_sock *pfk)
1799static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs) 1800static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_msg *hdr, void * const *ext_hdrs)
1800{ 1801{
1801 u8 proto; 1802 u8 proto;
1803 struct xfrm_address_filter *filter = NULL;
1802 struct pfkey_sock *pfk = pfkey_sk(sk); 1804 struct pfkey_sock *pfk = pfkey_sk(sk);
1803 1805
1804 if (pfk->dump.dump != NULL) 1806 if (pfk->dump.dump != NULL)
@@ -1808,11 +1810,27 @@ static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_ms
1808 if (proto == 0) 1810 if (proto == 0)
1809 return -EINVAL; 1811 return -EINVAL;
1810 1812
1813 if (ext_hdrs[SADB_X_EXT_FILTER - 1]) {
1814 struct sadb_x_filter *xfilter = ext_hdrs[SADB_X_EXT_FILTER - 1];
1815
1816 filter = kmalloc(sizeof(*filter), GFP_KERNEL);
1817 if (filter == NULL)
1818 return -ENOMEM;
1819
1820 memcpy(&filter->saddr, &xfilter->sadb_x_filter_saddr,
1821 sizeof(xfrm_address_t));
1822 memcpy(&filter->daddr, &xfilter->sadb_x_filter_daddr,
1823 sizeof(xfrm_address_t));
1824 filter->family = xfilter->sadb_x_filter_family;
1825 filter->splen = xfilter->sadb_x_filter_splen;
1826 filter->dplen = xfilter->sadb_x_filter_dplen;
1827 }
1828
1811 pfk->dump.msg_version = hdr->sadb_msg_version; 1829 pfk->dump.msg_version = hdr->sadb_msg_version;
1812 pfk->dump.msg_portid = hdr->sadb_msg_pid; 1830 pfk->dump.msg_portid = hdr->sadb_msg_pid;
1813 pfk->dump.dump = pfkey_dump_sa; 1831 pfk->dump.dump = pfkey_dump_sa;
1814 pfk->dump.done = pfkey_dump_sa_done; 1832 pfk->dump.done = pfkey_dump_sa_done;
1815 xfrm_state_walk_init(&pfk->dump.u.state, proto); 1833 xfrm_state_walk_init(&pfk->dump.u.state, proto, filter);
1816 1834
1817 return pfkey_do_dump(pfk); 1835 return pfkey_do_dump(pfk);
1818} 1836}
@@ -3060,6 +3078,24 @@ static u32 get_acqseq(void)
3060 return res; 3078 return res;
3061} 3079}
3062 3080
3081static bool pfkey_is_alive(const struct km_event *c)
3082{
3083 struct netns_pfkey *net_pfkey = net_generic(c->net, pfkey_net_id);
3084 struct sock *sk;
3085 bool is_alive = false;
3086
3087 rcu_read_lock();
3088 sk_for_each_rcu(sk, &net_pfkey->table) {
3089 if (pfkey_sk(sk)->registered) {
3090 is_alive = true;
3091 break;
3092 }
3093 }
3094 rcu_read_unlock();
3095
3096 return is_alive;
3097}
3098
3063static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *xp) 3099static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *xp)
3064{ 3100{
3065 struct sk_buff *skb; 3101 struct sk_buff *skb;
@@ -3785,6 +3821,7 @@ static struct xfrm_mgr pfkeyv2_mgr =
3785 .new_mapping = pfkey_send_new_mapping, 3821 .new_mapping = pfkey_send_new_mapping,
3786 .notify_policy = pfkey_send_policy_notify, 3822 .notify_policy = pfkey_send_policy_notify,
3787 .migrate = pfkey_send_migrate, 3823 .migrate = pfkey_send_migrate,
3824 .is_alive = pfkey_is_alive,
3788}; 3825};
3789 3826
3790static int __net_init pfkey_net_init(struct net *net) 3827static int __net_init pfkey_net_init(struct net *net)