netdev
[Top] [All Lists]

Re: [Vpn-failover] [RFC] IPSEC failover - Netlink part

To: Ulrich Weber <uweber@xxxxxxxxx>
Subject: Re: [Vpn-failover] [RFC] IPSEC failover - Netlink part
From: Patrick McHardy <kaber@xxxxxxxxx>
Date: Thu, 04 Nov 2004 19:15:54 +0100
Cc: vpn-failover@xxxxxxxxxxxxxxxx, netdev@xxxxxxxxxxx, ipsec-tools-devel@xxxxxxxxxxxxxxxxxxxxx
In-reply-to: <418A3630.1040900@xxxxxxxxx>
References: <1099045435.2888.47.camel@xxxxxxxxxxxxxx> <418A3630.1040900@xxxxxxxxx>
Sender: netdev-bounce@xxxxxxxxxxx
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.7.3) Gecko/20041008 Debian/1.7.3-5
Ulrich Weber wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

I take the opportunity to post my code as well. At the moment I'm working at
the same as Krisztian. My solutions however is for openswan, which uses
netlink instead of pfkey.

Please find attached the appropriate netlink modifications to
include/linux/xfrm.h and net/xfrm/xfrm_users.c

In theses patches, a new netlink group (XFRMGRP_REPLAY) is added to notify
about seq number changes. Each notify message contains a xfrm_usersa_id
struct with the replay struct attached as rt attribute. In addition, these
replay struct is also attached at ipsec sa dumps.

Any comments are welcome :)


Some minor bugs, see below.

Regards
Patrick

------------------------------------------------------------------------

--- linux.org/include/linux/xfrm.h.     2004-10-11 04:57:07.000000000 +0200
+++ linux/include/linux/xfrm.h  2004-10-18 17:00:43.000000000 +0200
@@ -140,6 +140,9 @@
        XFRM_MSG_FLUSHPOLICY,
#define XFRM_MSG_FLUSHPOLICY XFRM_MSG_FLUSHPOLICY

+       XFRM_MSG_UPDSEQ,
+#define XFRM_MSG_UPDSEQ XFRM_MSG_UPDSEQ
+
        XFRM_MSG_MAX
};

@@ -171,6 +174,7 @@
        XFRMA_ALG_COMP,         /* struct xfrm_algo */
        XFRMA_ENCAP,            /* struct xfrm_algo + struct xfrm_encap_tmpl */
        XFRMA_TMPL,             /* 1 or more struct xfrm_user_tmpl */
+ XFRMA_REPLAY, /* struct xfrm_replay_state */ __XFRMA_MAX

#define XFRMA_MAX (__XFRMA_MAX - 1)
@@ -258,5 +258,6 @@

#define XFRMGRP_ACQUIRE                1
#define XFRMGRP_EXPIRE         2
+#define XFRMGRP_REPLAY         3

#endif /* _LINUX_XFRM_H */
------------------------------------------------------------------------

--- linux.org/net/xfrm/xfrm_user.c      2004-10-18 23:54:32.000000000 +0200
+++ linux/net/xfrm/xfrm_user.c  2004-10-21 16:27:59.000000000 +0200
@@ -240,6 +240,12 @@
        if ((err = attach_encap_tmpl(&x->encap, xfrma[XFRMA_ENCAP-1])))
                goto error;

+        if(xfrma[XFRMA_REPLAY-1]) {
+                struct xfrm_replay_state *replay;
+                replay = RTA_DATA(xfrma[XFRMA_REPLAY - 1]);
+                x->replay = *replay;
+        }
+
        err = -ENOENT;
        x->type = xfrm_get_type(x->id.proto, x->props.family);
        if (x->type == NULL)
@@ -368,6 +375,8 @@
        if (x->encap)
                RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);

+       RTA_PUT(skb, XFRMA_REPLAY, sizeof(x->replay), &x->replay);
+
        nlh->nlmsg_len = skb->tail - b;
out:
        sp->this_idx++;
@@ -852,6 +861,27 @@
        return 0;
}

+static int xfrm_update_seq(struct sk_buff *skb, struct nlmsghdr *nlh, void 
**xfrma)
+{
+        struct xfrm_state *x;
+        struct xfrm_usersa_id *p = NLMSG_DATA(nlh);
+       struct xfrm_replay_state *replay;
+ + x = xfrm_state_lookup(&p->daddr, p->spi, p->proto, p->family);
+        if (x == NULL) {
+               printk(KERN_INFO "Found no xfrm state for sa seq update\n");
+                return -ESRCH;
+               }
+
+       if(xfrma[XFRMA_REPLAY-1]) {
+               replay = RTA_DATA(xfrma[XFRMA_REPLAY - 1]);
+               x->replay = *replay;
+               }
+       else return -EINVAL;
^^ leaks xfrm_state reference

+               
+       return 0;
^^ same here

+} +
static const int xfrm_msg_min[(XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)] = {
        NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)),  /* NEW SA */
        NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)),    /* DEL SA */
@@ -867,6 +897,7 @@
        NLMSG_LENGTH(sizeof(struct xfrm_user_polexpire)), /* POLEXPIRE */
        NLMSG_LENGTH(sizeof(struct xfrm_usersa_flush)), /* FLUSH SA */
        NLMSG_LENGTH(0),                                /* FLUSH POLICY */
+       NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)),/* UPD SEQ */
^^ what about struct xfrm_replay_state ?



<Prev in Thread] Current Thread [Next in Thread>