[JFFS2] Fix node allocation leak
[safe/jmp/linux-2.6] / net / key / af_key.c
index d086c11..4879743 100644 (file)
@@ -656,13 +656,18 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
        sa->sadb_sa_exttype = SADB_EXT_SA;
        sa->sadb_sa_spi = x->id.spi;
        sa->sadb_sa_replay = x->props.replay_window;
-       sa->sadb_sa_state = SADB_SASTATE_DYING;
-       if (x->km.state == XFRM_STATE_VALID && !x->km.dying)
-               sa->sadb_sa_state = SADB_SASTATE_MATURE;
-       else if (x->km.state == XFRM_STATE_ACQ)
+       switch (x->km.state) {
+       case XFRM_STATE_VALID:
+               sa->sadb_sa_state = x->km.dying ?
+                       SADB_SASTATE_DYING : SADB_SASTATE_MATURE;
+               break;
+       case XFRM_STATE_ACQ:
                sa->sadb_sa_state = SADB_SASTATE_LARVAL;
-       else if (x->km.state == XFRM_STATE_EXPIRED)
+               break;
+       default:
                sa->sadb_sa_state = SADB_SASTATE_DEAD;
+               break;
+       }
        sa->sadb_sa_auth = 0;
        if (x->aalg) {
                struct xfrm_algo_desc *a = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
@@ -685,6 +690,8 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
                sa->sadb_sa_flags |= SADB_SAFLAGS_NOECN;
        if (x->props.flags & XFRM_STATE_DECAP_DSCP)
                sa->sadb_sa_flags |= SADB_SAFLAGS_DECAP_DSCP;
+       if (x->props.flags & XFRM_STATE_NOPMTUDISC)
+               sa->sadb_sa_flags |= SADB_SAFLAGS_NOPMTUDISC;
 
        /* hard time */
        if (hsc & 2) {
@@ -969,6 +976,8 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
                x->props.flags |= XFRM_STATE_NOECN;
        if (sa->sadb_sa_flags & SADB_SAFLAGS_DECAP_DSCP)
                x->props.flags |= XFRM_STATE_DECAP_DSCP;
+       if (sa->sadb_sa_flags & SADB_SAFLAGS_NOPMTUDISC)
+               x->props.flags |= XFRM_STATE_NOPMTUDISC;
 
        lifetime = (struct sadb_lifetime*) ext_hdrs[SADB_EXT_LIFETIME_HARD-1];
        if (lifetime != NULL) {
@@ -1091,17 +1100,11 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
                }
        }
 
-       x->type = xfrm_get_type(proto, x->props.family);
-       if (x->type == NULL) {
-               err = -ENOPROTOOPT;
-               goto out;
-       }
-       if (x->type->init_state(x, NULL)) {
-               err = -EINVAL;
+       err = xfrm_init_state(x);
+       if (err)
                goto out;
-       }
+
        x->km.seq = hdr->sadb_msg_seq;
-       x->km.state = XFRM_STATE_VALID;
        return x;
 
 out:
@@ -1243,13 +1246,13 @@ static int pfkey_acquire(struct sock *sk, struct sk_buff *skb, struct sadb_msg *
 static inline int event2poltype(int event)
 {
        switch (event) {
-       case XFRM_SAP_DELETED:
+       case XFRM_MSG_DELPOLICY:
                return SADB_X_SPDDELETE;
-       case XFRM_SAP_ADDED:
+       case XFRM_MSG_NEWPOLICY:
                return SADB_X_SPDADD;
-       case XFRM_SAP_UPDATED:
+       case XFRM_MSG_UPDPOLICY:
                return SADB_X_SPDUPDATE;
-       case XFRM_SAP_EXPIRED:
+       case XFRM_MSG_POLEXPIRE:
        //      return SADB_X_SPDEXPIRE;
        default:
                printk("pfkey: Unknown policy event %d\n", event);
@@ -1262,13 +1265,13 @@ static inline int event2poltype(int event)
 static inline int event2keytype(int event)
 {
        switch (event) {
-       case XFRM_SAP_DELETED:
+       case XFRM_MSG_DELSA:
                return SADB_DELETE;
-       case XFRM_SAP_ADDED:
+       case XFRM_MSG_NEWSA:
                return SADB_ADD;
-       case XFRM_SAP_UPDATED:
+       case XFRM_MSG_UPDSA:
                return SADB_UPDATE;
-       case XFRM_SAP_EXPIRED:
+       case XFRM_MSG_EXPIRE:
                return SADB_EXPIRE;
        default:
                printk("pfkey: Unknown SA event %d\n", event);
@@ -1285,16 +1288,9 @@ static int key_notify_sa(struct xfrm_state *x, struct km_event *c)
        struct sadb_msg *hdr;
        int hsc = 3;
 
-       if (c->event == XFRM_SAP_DELETED)
+       if (c->event == XFRM_MSG_DELSA)
                hsc = 0;
 
-       if (c->event == XFRM_SAP_EXPIRED) {
-               if (c->data)
-                       hsc = 2;
-               else
-                       hsc = 1;
-       }
-
        skb = pfkey_xfrm_state2msg(x, 0, hsc);
 
        if (IS_ERR(skb))
@@ -1335,18 +1331,18 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
        if (err < 0) {
                x->km.state = XFRM_STATE_DEAD;
                xfrm_state_put(x);
-               return err;
+               goto out;
        }
 
        if (hdr->sadb_msg_type == SADB_ADD)
-               c.event = XFRM_SAP_ADDED;
+               c.event = XFRM_MSG_NEWSA;
        else
-               c.event = XFRM_SAP_UPDATED;
+               c.event = XFRM_MSG_UPDSA;
        c.seq = hdr->sadb_msg_seq;
        c.pid = hdr->sadb_msg_pid;
        km_state_notify(x, &c);
+out:
        xfrm_state_put(x);
-
        return err;
 }
 
@@ -1378,7 +1374,7 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
 
        c.seq = hdr->sadb_msg_seq;
        c.pid = hdr->sadb_msg_pid;
-       c.event = XFRM_SAP_DELETED;
+       c.event = XFRM_MSG_DELSA;
        km_state_notify(x, &c);
        xfrm_state_put(x);
 
@@ -1529,7 +1525,7 @@ static int key_notify_sa_flush(struct km_event *c)
        if (!skb)
                return -ENOBUFS;
        hdr = (struct sadb_msg *) skb_put(skb, sizeof(struct sadb_msg));
-       hdr->sadb_msg_satype = pfkey_proto2satype(c->data);
+       hdr->sadb_msg_satype = pfkey_proto2satype(c->data.proto);
        hdr->sadb_msg_seq = c->seq;
        hdr->sadb_msg_pid = c->pid;
        hdr->sadb_msg_version = PF_KEY_V2;
@@ -1551,10 +1547,10 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
                return -EINVAL;
 
        xfrm_state_flush(proto);
-       c.data = proto;
+       c.data.proto = proto;
        c.seq = hdr->sadb_msg_seq;
        c.pid = hdr->sadb_msg_pid;
-       c.event = XFRM_SAP_FLUSHED;
+       c.event = XFRM_MSG_FLUSHSA;
        km_state_notify(NULL, &c);
 
        return 0;
@@ -1964,7 +1960,7 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c
        out_hdr = (struct sadb_msg *) out_skb->data;
        out_hdr->sadb_msg_version = PF_KEY_V2;
 
-       if (c->data && c->event == XFRM_SAP_DELETED)
+       if (c->data.byid && c->event == XFRM_MSG_DELPOLICY)
                out_hdr->sadb_msg_type = SADB_X_SPDDELETE2;
        else
                out_hdr->sadb_msg_type = event2poltype(c->event);
@@ -2060,9 +2056,9 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
        }
 
        if (hdr->sadb_msg_type == SADB_X_SPDUPDATE)
-               c.event = XFRM_SAP_UPDATED;
-       else
-               c.event = XFRM_SAP_ADDED;
+               c.event = XFRM_MSG_UPDPOLICY;
+       else 
+               c.event = XFRM_MSG_NEWPOLICY;
 
        c.seq = hdr->sadb_msg_seq;
        c.pid = hdr->sadb_msg_pid;
@@ -2120,7 +2116,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
 
        c.seq = hdr->sadb_msg_seq;
        c.pid = hdr->sadb_msg_pid;
-       c.event = XFRM_SAP_DELETED;
+       c.event = XFRM_MSG_DELPOLICY;
        km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c);
 
        xfrm_pol_put(xp);
@@ -2175,8 +2171,8 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
        c.seq = hdr->sadb_msg_seq;
        c.pid = hdr->sadb_msg_pid;
        if (hdr->sadb_msg_type == SADB_X_SPDDELETE2) {
-               c.data = 1; // to signal pfkey of SADB_X_SPDDELETE2
-               c.event = XFRM_SAP_DELETED;
+               c.data.byid = 1;
+               c.event = XFRM_MSG_DELPOLICY;
                km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c);
        } else {
                err = key_pol_get_resp(sk, xp, hdr, pol->sadb_x_policy_dir-1);
@@ -2240,7 +2236,7 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg
        struct km_event c;
 
        xfrm_policy_flush();
-       c.event = XFRM_SAP_FLUSHED;
+       c.event = XFRM_MSG_FLUSHPOLICY;
        c.pid = hdr->sadb_msg_pid;
        c.seq = hdr->sadb_msg_seq;
        km_policy_notify(NULL, 0, &c);
@@ -2455,7 +2451,7 @@ static int key_notify_sa_expire(struct xfrm_state *x, struct km_event *c)
        int hard;
        int hsc;
 
-       hard = c->data;
+       hard = c->data.hard;
        if (hard)
                hsc = 2;
        else
@@ -2481,13 +2477,13 @@ static int key_notify_sa_expire(struct xfrm_state *x, struct km_event *c)
 static int pfkey_send_notify(struct xfrm_state *x, struct km_event *c)
 {
        switch (c->event) {
-       case XFRM_SAP_EXPIRED:
+       case XFRM_MSG_EXPIRE:
                return key_notify_sa_expire(x, c);
-       case XFRM_SAP_DELETED:
-       case XFRM_SAP_ADDED:
-       case XFRM_SAP_UPDATED:
+       case XFRM_MSG_DELSA:
+       case XFRM_MSG_NEWSA:
+       case XFRM_MSG_UPDSA:
                return key_notify_sa(x, c);
-       case XFRM_SAP_FLUSHED:
+       case XFRM_MSG_FLUSHSA:
                return key_notify_sa_flush(c);
        default:
                printk("pfkey: Unknown SA event %d\n", c->event);
@@ -2500,13 +2496,13 @@ static int pfkey_send_notify(struct xfrm_state *x, struct km_event *c)
 static int pfkey_send_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c)
 {
        switch (c->event) {
-       case XFRM_SAP_EXPIRED:
+       case XFRM_MSG_POLEXPIRE:
                return key_notify_policy_expire(xp, c);
-       case XFRM_SAP_DELETED:
-       case XFRM_SAP_ADDED:
-       case XFRM_SAP_UPDATED:
+       case XFRM_MSG_DELPOLICY:
+       case XFRM_MSG_NEWPOLICY:
+       case XFRM_MSG_UPDPOLICY:
                return key_notify_policy(xp, dir, c);
-       case XFRM_SAP_FLUSHED:
+       case XFRM_MSG_FLUSHPOLICY:
                return key_notify_policy_flush(c);
        default:
                printk("pfkey: Unknown policy event %d\n", c->event);