[XFRM] netlink: Use nla_put()/NLA_PUT() variantes

Also makes use of copy_sec_ctx() in another place and removes
duplicated code.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Thomas Graf 2007-08-22 13:55:43 -07:00 committed by David S. Miller
parent 082a1ad573
commit c0144beaec
1 changed files with 67 additions and 89 deletions

View File

@ -576,6 +576,27 @@ struct xfrm_dump_info {
int this_idx; int this_idx;
}; };
static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb)
{
int ctx_size = sizeof(struct xfrm_sec_ctx) + s->ctx_len;
struct xfrm_user_sec_ctx *uctx;
struct nlattr *attr;
attr = nla_reserve(skb, XFRMA_SEC_CTX, ctx_size);
if (attr == NULL)
return -EMSGSIZE;
uctx = nla_data(attr);
uctx->exttype = XFRMA_SEC_CTX;
uctx->len = ctx_size;
uctx->ctx_doi = s->ctx_doi;
uctx->ctx_alg = s->ctx_alg;
uctx->ctx_len = s->ctx_len;
memcpy(uctx + 1, s->ctx_str, s->ctx_len);
return 0;
}
static int dump_one_state(struct xfrm_state *x, int count, void *ptr) static int dump_one_state(struct xfrm_state *x, int count, void *ptr)
{ {
struct xfrm_dump_info *sp = ptr; struct xfrm_dump_info *sp = ptr;
@ -596,43 +617,32 @@ static int dump_one_state(struct xfrm_state *x, int count, void *ptr)
copy_to_user_state(x, p); copy_to_user_state(x, p);
if (x->aalg) if (x->aalg)
RTA_PUT(skb, XFRMA_ALG_AUTH, NLA_PUT(skb, XFRMA_ALG_AUTH,
sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg); sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg);
if (x->ealg) if (x->ealg)
RTA_PUT(skb, XFRMA_ALG_CRYPT, NLA_PUT(skb, XFRMA_ALG_CRYPT,
sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg); sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg);
if (x->calg) if (x->calg)
RTA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg); NLA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg);
if (x->encap) if (x->encap)
RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
if (x->security) { if (x->security && copy_sec_ctx(x->security, skb) < 0)
int ctx_size = sizeof(struct xfrm_sec_ctx) + goto nla_put_failure;
x->security->ctx_len;
struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size);
struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
uctx->exttype = XFRMA_SEC_CTX;
uctx->len = ctx_size;
uctx->ctx_doi = x->security->ctx_doi;
uctx->ctx_alg = x->security->ctx_alg;
uctx->ctx_len = x->security->ctx_len;
memcpy(uctx + 1, x->security->ctx_str, x->security->ctx_len);
}
if (x->coaddr) if (x->coaddr)
RTA_PUT(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr); NLA_PUT(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr);
if (x->lastused) if (x->lastused)
RTA_PUT(skb, XFRMA_LASTUSED, sizeof(x->lastused), &x->lastused); NLA_PUT_U64(skb, XFRMA_LASTUSED, x->lastused);
nlmsg_end(skb, nlh); nlmsg_end(skb, nlh);
out: out:
sp->this_idx++; sp->this_idx++;
return 0; return 0;
rtattr_failure: nla_put_failure:
nlmsg_cancel(skb, nlh); nlmsg_cancel(skb, nlh);
return -EMSGSIZE; return -EMSGSIZE;
} }
@ -1193,32 +1203,9 @@ static int copy_to_user_tmpl(struct xfrm_policy *xp, struct sk_buff *skb)
up->ealgos = kp->ealgos; up->ealgos = kp->ealgos;
up->calgos = kp->calgos; up->calgos = kp->calgos;
} }
RTA_PUT(skb, XFRMA_TMPL,
(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr),
vec);
return 0; return nla_put(skb, XFRMA_TMPL,
sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr, vec);
rtattr_failure:
return -1;
}
static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb)
{
int ctx_size = sizeof(struct xfrm_sec_ctx) + s->ctx_len;
struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size);
struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
uctx->exttype = XFRMA_SEC_CTX;
uctx->len = ctx_size;
uctx->ctx_doi = s->ctx_doi;
uctx->ctx_alg = s->ctx_alg;
uctx->ctx_len = s->ctx_len;
memcpy(uctx + 1, s->ctx_str, s->ctx_len);
return 0;
rtattr_failure:
return -1;
} }
static inline int copy_to_user_state_sec_ctx(struct xfrm_state *x, struct sk_buff *skb) static inline int copy_to_user_state_sec_ctx(struct xfrm_state *x, struct sk_buff *skb)
@ -1240,17 +1227,11 @@ static inline int copy_to_user_sec_ctx(struct xfrm_policy *xp, struct sk_buff *s
#ifdef CONFIG_XFRM_SUB_POLICY #ifdef CONFIG_XFRM_SUB_POLICY
static int copy_to_user_policy_type(u8 type, struct sk_buff *skb) static int copy_to_user_policy_type(u8 type, struct sk_buff *skb)
{ {
struct xfrm_userpolicy_type upt; struct xfrm_userpolicy_type upt = {
.type = type,
};
memset(&upt, 0, sizeof(upt)); return nla_put(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt);
upt.type = type;
RTA_PUT(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt);
return 0;
rtattr_failure:
return -1;
} }
#else #else
@ -1440,7 +1421,6 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, struct km_eve
{ {
struct xfrm_aevent_id *id; struct xfrm_aevent_id *id;
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
struct xfrm_lifetime_cur ltime;
nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_NEWAE, sizeof(*id), 0); nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_NEWAE, sizeof(*id), 0);
if (nlh == NULL) if (nlh == NULL)
@ -1455,27 +1435,19 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, struct km_eve
id->reqid = x->props.reqid; id->reqid = x->props.reqid;
id->flags = c->data.aevent; id->flags = c->data.aevent;
RTA_PUT(skb, XFRMA_REPLAY_VAL, sizeof(x->replay), &x->replay); NLA_PUT(skb, XFRMA_REPLAY_VAL, sizeof(x->replay), &x->replay);
NLA_PUT(skb, XFRMA_LTIME_VAL, sizeof(x->curlft), &x->curlft);
ltime.bytes = x->curlft.bytes; if (id->flags & XFRM_AE_RTHR)
ltime.packets = x->curlft.packets; NLA_PUT_U32(skb, XFRMA_REPLAY_THRESH, x->replay_maxdiff);
ltime.add_time = x->curlft.add_time;
ltime.use_time = x->curlft.use_time;
RTA_PUT(skb, XFRMA_LTIME_VAL, sizeof(struct xfrm_lifetime_cur), &ltime); if (id->flags & XFRM_AE_ETHR)
NLA_PUT_U32(skb, XFRMA_ETIMER_THRESH,
if (id->flags&XFRM_AE_RTHR) { x->replay_maxage * 10 / HZ);
RTA_PUT(skb,XFRMA_REPLAY_THRESH,sizeof(u32),&x->replay_maxdiff);
}
if (id->flags&XFRM_AE_ETHR) {
u32 etimer = x->replay_maxage*10/HZ;
RTA_PUT(skb,XFRMA_ETIMER_THRESH,sizeof(u32),&etimer);
}
return nlmsg_end(skb, nlh); return nlmsg_end(skb, nlh);
rtattr_failure: nla_put_failure:
nlmsg_cancel(skb, nlh); nlmsg_cancel(skb, nlh);
return -EMSGSIZE; return -EMSGSIZE;
} }
@ -1840,11 +1812,7 @@ static int copy_to_user_migrate(struct xfrm_migrate *m, struct sk_buff *skb)
memcpy(&um.new_daddr, &m->new_daddr, sizeof(um.new_daddr)); memcpy(&um.new_daddr, &m->new_daddr, sizeof(um.new_daddr));
memcpy(&um.new_saddr, &m->new_saddr, sizeof(um.new_saddr)); memcpy(&um.new_saddr, &m->new_saddr, sizeof(um.new_saddr));
RTA_PUT(skb, XFRMA_MIGRATE, sizeof(um), &um); return nla_put(skb, XFRMA_MIGRATE, sizeof(um), &um);
return 0;
rtattr_failure:
return -1;
} }
static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m, static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m,
@ -2137,39 +2105,44 @@ static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c)
nlh = nlmsg_put(skb, c->pid, c->seq, c->event, headlen, 0); nlh = nlmsg_put(skb, c->pid, c->seq, c->event, headlen, 0);
if (nlh == NULL) if (nlh == NULL)
goto nlmsg_failure; goto nla_put_failure;
p = nlmsg_data(nlh); p = nlmsg_data(nlh);
if (c->event == XFRM_MSG_DELSA) { if (c->event == XFRM_MSG_DELSA) {
struct nlattr *attr;
id = nlmsg_data(nlh); id = nlmsg_data(nlh);
memcpy(&id->daddr, &x->id.daddr, sizeof(id->daddr)); memcpy(&id->daddr, &x->id.daddr, sizeof(id->daddr));
id->spi = x->id.spi; id->spi = x->id.spi;
id->family = x->props.family; id->family = x->props.family;
id->proto = x->id.proto; id->proto = x->id.proto;
p = RTA_DATA(__RTA_PUT(skb, XFRMA_SA, sizeof(*p))); attr = nla_reserve(skb, XFRMA_SA, sizeof(*p));
if (attr == NULL)
goto nla_put_failure;
p = nla_data(attr);
} }
copy_to_user_state(x, p); copy_to_user_state(x, p);
if (x->aalg) if (x->aalg)
RTA_PUT(skb, XFRMA_ALG_AUTH, NLA_PUT(skb, XFRMA_ALG_AUTH,
sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg); sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg);
if (x->ealg) if (x->ealg)
RTA_PUT(skb, XFRMA_ALG_CRYPT, NLA_PUT(skb, XFRMA_ALG_CRYPT,
sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg); sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg);
if (x->calg) if (x->calg)
RTA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg); NLA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg);
if (x->encap) if (x->encap)
RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
nlmsg_end(skb, nlh); nlmsg_end(skb, nlh);
return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC); return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC);
nlmsg_failure: nla_put_failure:
rtattr_failure:
kfree_skb(skb); kfree_skb(skb);
return -1; return -1;
} }
@ -2392,6 +2365,8 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *
p = nlmsg_data(nlh); p = nlmsg_data(nlh);
if (c->event == XFRM_MSG_DELPOLICY) { if (c->event == XFRM_MSG_DELPOLICY) {
struct nlattr *attr;
id = nlmsg_data(nlh); id = nlmsg_data(nlh);
memset(id, 0, sizeof(*id)); memset(id, 0, sizeof(*id));
id->dir = dir; id->dir = dir;
@ -2400,7 +2375,11 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *
else else
memcpy(&id->sel, &xp->selector, sizeof(id->sel)); memcpy(&id->sel, &xp->selector, sizeof(id->sel));
p = RTA_DATA(__RTA_PUT(skb, XFRMA_POLICY, sizeof(*p))); attr = nla_reserve(skb, XFRMA_POLICY, sizeof(*p));
if (attr == NULL)
goto nlmsg_failure;
p = nla_data(attr);
} }
copy_to_user_policy(xp, p, dir); copy_to_user_policy(xp, p, dir);
@ -2414,7 +2393,6 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *
return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);
nlmsg_failure: nlmsg_failure:
rtattr_failure:
kfree_skb(skb); kfree_skb(skb);
return -1; return -1;
} }
@ -2483,11 +2461,11 @@ static int build_report(struct sk_buff *skb, u8 proto,
memcpy(&ur->sel, sel, sizeof(ur->sel)); memcpy(&ur->sel, sel, sizeof(ur->sel));
if (addr) if (addr)
RTA_PUT(skb, XFRMA_COADDR, sizeof(*addr), addr); NLA_PUT(skb, XFRMA_COADDR, sizeof(*addr), addr);
return nlmsg_end(skb, nlh); return nlmsg_end(skb, nlh);
rtattr_failure: nla_put_failure:
nlmsg_cancel(skb, nlh); nlmsg_cancel(skb, nlh);
return -EMSGSIZE; return -EMSGSIZE;
} }