X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=net%2Fxfrm%2Fxfrm_user.c;h=ecade4893a139cc35d4fe345ce70242ede5358c4;hb=72cb6962a91f2af9eef69a06198e1949c10259ae;hp=bc4fd74568738041b5501d6f0de847f36b23f36d;hpb=f60f6b8f70c756fc786d68f02ec17a1e84db645f;p=powerpc.git diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index bc4fd74568..ecade4893a 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -249,17 +249,10 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p, if ((err = attach_encap_tmpl(&x->encap, xfrma[XFRMA_ENCAP-1]))) goto error; - err = -ENOENT; - x->type = xfrm_get_type(x->id.proto, x->props.family); - if (x->type == NULL) - goto error; - - err = x->type->init_state(x, NULL); + err = xfrm_init_state(x); if (err) goto error; - x->curlft.add_time = (unsigned long) xtime.tv_sec; - x->km.state = XFRM_STATE_VALID; x->km.seq = p->seq; return x; @@ -296,7 +289,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) if (err < 0) { x->km.state = XFRM_STATE_DEAD; xfrm_state_put(x); - return err; + goto out; } c.seq = nlh->nlmsg_seq; @@ -304,8 +297,8 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) c.event = nlh->nlmsg_type; km_state_notify(x, &c); +out: xfrm_state_put(x); - return err; } @@ -1123,9 +1116,9 @@ nlmsg_failure: static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c) { struct sk_buff *skb; + int len = NLMSG_LENGTH(sizeof(struct xfrm_user_expire)); - /* fix to do alloc using NLM macros */ - skb = alloc_skb(sizeof(struct xfrm_user_expire) + 16, GFP_ATOMIC); + skb = alloc_skb(len, GFP_ATOMIC); if (skb == NULL) return -ENOMEM; @@ -1168,7 +1161,7 @@ nlmsg_failure: static int inline xfrm_sa_len(struct xfrm_state *x) { - int l = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)); + int l = 0; if (x->aalg) l += RTA_SPACE(sizeof(*x->aalg) + (x->aalg->alg_key_len+7)/8); if (x->ealg) @@ -1184,20 +1177,39 @@ static int inline xfrm_sa_len(struct xfrm_state *x) static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c) { struct xfrm_usersa_info *p; + struct xfrm_usersa_id *id; struct nlmsghdr *nlh; struct sk_buff *skb; unsigned char *b; int len = xfrm_sa_len(x); + int headlen; + + headlen = sizeof(*p); + if (c->event == XFRM_MSG_DELSA) { + len += RTA_SPACE(headlen); + headlen = sizeof(*id); + } + len += NLMSG_SPACE(headlen); skb = alloc_skb(len, GFP_ATOMIC); if (skb == NULL) return -ENOMEM; b = skb->tail; - nlh = NLMSG_PUT(skb, c->pid, c->seq, c->event, sizeof(*p)); + nlh = NLMSG_PUT(skb, c->pid, c->seq, c->event, headlen); nlh->nlmsg_flags = 0; p = NLMSG_DATA(nlh); + if (c->event == XFRM_MSG_DELSA) { + id = NLMSG_DATA(nlh); + memcpy(&id->daddr, &x->id.daddr, sizeof(id->daddr)); + id->spi = x->id.spi; + id->family = x->props.family; + id->proto = x->id.proto; + + p = RTA_DATA(__RTA_PUT(skb, XFRMA_SA, sizeof(*p))); + } + copy_to_user_state(x, p); if (x->aalg) @@ -1398,20 +1410,39 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c) { struct xfrm_userpolicy_info *p; + struct xfrm_userpolicy_id *id; struct nlmsghdr *nlh; struct sk_buff *skb; unsigned char *b; int len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); - len += NLMSG_SPACE(sizeof(struct xfrm_userpolicy_info)); + int headlen; + + headlen = sizeof(*p); + if (c->event == XFRM_MSG_DELPOLICY) { + len += RTA_SPACE(headlen); + headlen = sizeof(*id); + } + len += NLMSG_SPACE(headlen); skb = alloc_skb(len, GFP_ATOMIC); if (skb == NULL) return -ENOMEM; b = skb->tail; - nlh = NLMSG_PUT(skb, c->pid, c->seq, c->event, sizeof(*p)); + nlh = NLMSG_PUT(skb, c->pid, c->seq, c->event, headlen); p = NLMSG_DATA(nlh); + if (c->event == XFRM_MSG_DELPOLICY) { + id = NLMSG_DATA(nlh); + memset(id, 0, sizeof(*id)); + id->dir = dir; + if (c->data.byid) + id->index = xp->index; + else + memcpy(&id->sel, &xp->selector, sizeof(id->sel)); + + p = RTA_DATA(__RTA_PUT(skb, XFRMA_POLICY, sizeof(*p))); + } nlh->nlmsg_flags = 0; @@ -1424,6 +1455,7 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event * return netlink_broadcast(xfrm_nl, skb, 0, XFRMGRP_POLICY, GFP_ATOMIC); nlmsg_failure: +rtattr_failure: kfree_skb(skb); return -1; }