Subject: [IPsec] [PF_KEY] Kernel is not identifying the SADB_ACQUIRE (error) message to indicate key management failure [SADB_ACQUIRE message from a user process to the kernel].

From: venkatgiri <[email-masked]>
Date: Mon, 30 May 2011 12:25:19 +0530

Hi all,

I'm receiving the SADB_ACQUIRE message from the kernel to establish the 
required SA, as i have registered my *pfkey* socket with the kernel.
The Key management in my application is failing to get the require key 
information from the server, so I'm sending the same SADB_ACQUIRE 
message to the kernel with same sequence number which have received in 
the SADB_ACQUIRE message with errno set to ENOENT to indicate the Key 
management has failed.

Here i'm constructing only the base header (struct sadb_msg) as 
described in the RFC 2367. As per the RFC 2367 it has to return me the 
SADB_ACQUIRE message with the same errno set.

The problem here I'm facing is, the kernel is dropping the message which 
i have sent to the kernel to indicate the Key management has failed. The 
Kernel is sending the same (last SADB_ACQUIRE for which key management 
is failed) SADB_ACQUIRE message with *errno* set to ZERO.  The OS i'm 
using is Fedora core 8 (2.6.23.1-42.fc8).

Is this feature(kernel should respond with SADB_ACQUIRE with error no ) 
handled in the above mentioned Linux Kernel version ?

can any please let me know what is wrong i'm doing here. It will be very 
helpful for me.

This is code snippet which i'm sending to kernel.

/*
  * send error against acquire message to kenrel.
  */
int
send_acquire_msg_fail(struct acquire *acquire)
{
     struct sadb_msg *newmsg;
     int len;

     len = sizeof(struct sadb_msg);
     newmsg = calloc(1, len);
     if (newmsg == NULL) {
         ERROR_RETURN("failed to get buffer to send acquire.\n");
         return -1;
     }

     memset(newmsg, 0, len);
     newmsg->sadb_msg_version = PF_KEY_V2;
     newmsg->sadb_msg_type = SADB_ACQUIRE;
     newmsg->sadb_msg_errno = ENOENT;
     newmsg->sadb_msg_satype = SADB_SATYPE_ESP;
     newmsg->sadb_msg_len = (len/8);
     newmsg->sadb_msg_reserved = 0;
     newmsg->sadb_msg_seq = acquire->seq;
     newmsg->sadb_msg_pid = (u_int32_t)getpid();

     /* send message */
     if (len != write(pfkey_socket, (void*)msg, len)) {
           ERROR_RETURN (("SORRY, failed to write the SADB_ACQUIRE 
message to the kernel\n"));
      }
      free(newmsg);
      return 0;
}

*Rfc 2367 reference :*

If a KMd has any error at all during its negotiation, it can send
    down:

KMd->Kernel:         SADB_ACQUIRE for AH, assoc (with an error)
*Kernel->All:         SADB_ACQUIRE for AH, assoc (same error)*

-- 
Regards,
Venkatgiri