static atomic_t pfkey_socks_nr = ATOMIC_INIT(0);
-struct pfkey_opt {
- int registered;
- int promisc;
+struct pfkey_sock {
+ /* struct sock must be the first member of struct pfkey_sock */
+ struct sock sk;
+ int registered;
+ int promisc;
};
-#define pfkey_sk(__sk) ((struct pfkey_opt *)(__sk)->sk_protinfo)
+
+static inline struct pfkey_sock *pfkey_sk(struct sock *sk)
+{
+ return (struct pfkey_sock *)sk;
+}
static void pfkey_sock_destruct(struct sock *sk)
{
BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc));
BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc));
- kfree(pfkey_sk(sk));
-
atomic_dec(&pfkey_socks_nr);
}
pfkey_table_ungrab();
}
+static struct proto key_proto = {
+ .name = "KEY",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct pfkey_sock),
+};
+
static int pfkey_create(struct socket *sock, int protocol)
{
struct sock *sk;
- struct pfkey_opt *pfk;
int err;
if (!capable(CAP_NET_ADMIN))
return -EPROTONOSUPPORT;
err = -ENOMEM;
- sk = sk_alloc(PF_KEY, GFP_KERNEL, 1, NULL);
+ sk = sk_alloc(PF_KEY, GFP_KERNEL, &key_proto, 1);
if (sk == NULL)
goto out;
sock->ops = &pfkey_ops;
sock_init_data(sock, sk);
- sk_set_owner(sk, THIS_MODULE);
-
- err = -ENOMEM;
- pfk = sk->sk_protinfo = kmalloc(sizeof(*pfk), GFP_KERNEL);
- if (!pfk) {
- sk_free(sk);
- goto out;
- }
- memset(pfk, 0, sizeof(*pfk));
sk->sk_family = PF_KEY;
sk->sk_destruct = pfkey_sock_destruct;
pfkey_lock_table();
sk_for_each(sk, node, &pfkey_table) {
- struct pfkey_opt *pfk = pfkey_sk(sk);
+ struct pfkey_sock *pfk = pfkey_sk(sk);
int err2;
/* Yes, it means that if you are meant to receive this
/* address family check */
sockaddr_size = pfkey_sockaddr_size(x->props.family);
if (!sockaddr_size)
- ERR_PTR(-EINVAL);
+ return ERR_PTR(-EINVAL);
/* base, SA, (lifetime (HSC),) address(SD), (address(P),)
key(AE), (identity(SD),) (sensitivity)> */
static int pfkey_register(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
{
- struct pfkey_opt *pfk = pfkey_sk(sk);
+ struct pfkey_sock *pfk = pfkey_sk(sk);
struct sk_buff *supp_skb;
if (hdr->sadb_msg_satype > SADB_SATYPE_MAX)
static int pfkey_promisc(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
{
- struct pfkey_opt *pfk = pfkey_sk(sk);
+ struct pfkey_sock *pfk = pfkey_sk(sk);
int satype = hdr->sadb_msg_satype;
if (hdr->sadb_msg_len == (sizeof(*hdr) / sizeof(uint64_t))) {
xfrm_unregister_km(&pfkeyv2_mgr);
remove_proc_entry("net/pfkey", NULL);
sock_unregister(PF_KEY);
+ proto_unregister(&key_proto);
}
static int __init ipsec_pfkey_init(void)
{
- sock_register(&pfkey_family_ops);
+ int err = proto_register(&key_proto, 0);
+
+ if (err != 0)
+ goto out;
+
+ err = sock_register(&pfkey_family_ops);
+ if (err != 0)
+ goto out_unregister_key_proto;
#ifdef CONFIG_PROC_FS
- create_proc_read_entry("net/pfkey", 0, NULL, pfkey_read_proc, NULL);
+ err = -ENOMEM;
+ if (create_proc_read_entry("net/pfkey", 0, NULL, pfkey_read_proc, NULL) == NULL)
+ goto out_sock_unregister;
#endif
- xfrm_register_km(&pfkeyv2_mgr);
- return 0;
+ err = xfrm_register_km(&pfkeyv2_mgr);
+ if (err != 0)
+ goto out_remove_proc_entry;
+out:
+ return err;
+out_remove_proc_entry:
+#ifdef CONFIG_PROC_FS
+ remove_proc_entry("net/pfkey", NULL);
+out_sock_unregister:
+#endif
+ sock_unregister(PF_KEY);
+out_unregister_key_proto:
+ proto_unregister(&key_proto);
+ goto out;
}
module_init(ipsec_pfkey_init);