xfrm by MARK
Subsystems (4)
A message that is not in the archive (sent off-list or not yet received): xfrm-mark-v3
cover xfrm by MARK
From: Jamal Hadi Salim <[email protected]>
Changes since last time:
----------------------
Patch 1/7: Feedback from David Miller; aggregate xfrm_*mark and correct comment on the type of xfrm_mark
Changes since first time:
----------------------
Patch 1/7: Feedback from Patrick McHardy; We pass to user space any mark as long as it has non-zero mask.
This patchset implements manipulation of ipsec tables with the "mark" tag. You can config the SAD and SPD from user space with a specified mark.
Example:
---
#ip xfrm state add src 192.168.2.100 dst 192.168.1.10 proto esp spi 0x00000301 mode tunnel mark 7 auth md5 0x96358c90783bbfa3d7b196ceabe0536b enc des3_ede 0xf6ddb555acfd9d77b03ea3843f2653255afe8eb5573965df
#ip xfrm state get mark 7 src 192.168.2.100 dst 192.168.1.10 proto esp spi 0x00000301 output:
src 192.168.2.100 dst 192.168.1.10
proto esp spi 0x00000301 reqid 0 mode tunnel
replay-window 0
mark 7/0xffffffff
auth hmac(md5) 0x96358c90783bbfa3d7b196ceabe0536b
enc cbc(des3_ede) 0xf6ddb555acfd9d77b03ea3843f2653255afe8eb5573965df
sel src 0.0.0.0/0 dst 0.0.0.0/0
#
#
#ip xfrm policy add src 172.16.2.0/24 dst 172.16.1.0/24 \
dir fwd ptype main \
tmpl src 192.168.2.100 dst 192.168.1.100 \
proto esp mode tunnel mark 7 mask 0xffffffff#
#ip xfrm policy ls
output:
src 172.16.2.0/24 dst 172.16.1.0/24
dir fwd priority 0 ptype main
mark 7/0xffffffff
tmpl src 192.168.2.100 dst 192.168.1.100
proto esp reqid 0 mode tunnel
-----
A mark-configured SAD/SPD entry will use the mark as part of the lookup key (both in data and control path).
Example:
---
# ip xfrm pol get src 172.16.2.0/24 dst 172.16.1.0/24 dir fwd
output:
RTNETLINK answers: No such file or directory
# ip xfrm pol get src 172.16.2.0/24 dst 172.16.1.0/24 dir fwd mark 7
output:
src 172.16.2.0/24 dst 172.16.1.0/24
dir fwd priority 0 ptype main
mark 7/0xffffffff
tmpl src 192.168.2.100 dst 192.168.1.100
proto esp reqid 0 mode tunnel
---Jamal Hadi Salim (7):
xfrm: introduce basic mark infrastructure
xfrm: SA lookups signature with mark
xfrm: SA lookups with mark
xfrm: SP lookups signature with mark
xfrm: SP lookups with mark
xfrm: Allow user space config of SAD mark
xfrm: Allow user space manipulation of SPD mark
include/linux/xfrm.h | 12 ++++- include/net/xfrm.h | 50 ++++++++++++++++++++---- net/core/pktgen.c | 3 +- net/ipv4/ah4.c | 2 +- net/ipv4/esp4.c | 2 +- net/ipv4/ipcomp.c | 6 ++- net/ipv6/ah6.c | 2 +- net/ipv6/esp6.c | 2 +- net/ipv6/ipcomp6.c | 6 ++- net/ipv6/xfrm6_input.c | 2 +- net/key/af_key.c | 16 ++++--- net/xfrm/xfrm_input.c | 2 +- net/xfrm/xfrm_policy.c | 20 +++++++-- net/xfrm/xfrm_state.c | 70 +++++++++++++++++++++++------------ net/xfrm/xfrm_user.c | 96 ++++++++++++++++++++++++++++++++++++++++-------- 15 files changed, 216 insertions(+), 75 deletions(-)
PATCH 1/7 xfrm: introduce basic mark infrastructure
From: Jamal Hadi Salim <[email protected]>
Add basic structuring and accessors for xfrm mark
--- include/linux/xfrm.h | 12 +++++++++--- include/net/xfrm.h | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-)
include/linux/xfrm.h +9 -3
@@ -267,8 +267,8 @@ enum xfrm_attr_type_t {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_SA , -XFRMA_POLICY , +XFRMA_SA ,/* struct xfrm_usersa_info */ +XFRMA_POLICY ,/*struct xfrm_userpolicy_info */ XFRMA_SEC_CTX ,/* struct xfrm_sec_ctx */ XFRMA_LTIME_VAL , XFRMA_REPLAY_VAL,
@@ -276,17 +276,23 @@ enum xfrm_attr_type_t {XFRMA_ETIMER_THRESH ,XFRMA_SRCADDR ,/* xfrm_address_t */ XFRMA_COADDR ,/* xfrm_address_t */ -XFRMA_LASTUSED , +XFRMA_LASTUSED ,/* unsigned long */ XFRMA_POLICY_TYPE ,/* struct xfrm_userpolicy_type */ XFRMA_MIGRATE ,XFRMA_ALG_AEAD ,/* struct xfrm_algo_aead */ XFRMA_KMADDRESS ,/* struct xfrm_user_kmaddress */ XFRMA_ALG_AUTH_TRUNC ,/* struct xfrm_algo_auth */ +XFRMA_MARK ,/* struct xfrm_mark */ __XFRMA_MAX #define XFRMA_MAX (__XFRMA_MAX - 1) }; +struct xfrm_mark { +__u32 v;/* value */ +__u32 m;/* mask */ +}; +enum xfrm_sadattr_type_t {XFRMA_SAD_UNSPEC , XFRMA_SAD_CNT,
include/net/xfrm.h +22 -0
@@ -140,6 +140,7 @@ struct xfrm_state {struct xfrm_id id;struct xfrm_selector sel; +struct xfrm_mark mark;u32 genid;
@@ -481,6 +482,7 @@ struct xfrm_policy {u32 priority;u32 index; +struct xfrm_mark mark;struct xfrm_selector selector;struct xfrm_lifetime_cfg lft;struct xfrm_lifetime_cur curlft;
@@ -1570,4 +1572,24 @@ static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb) }#endif +static inline int xfrm_mark_get (struct nlattr **attrs,struct xfrm_mark *m) +{ +if (attrs[XFRMA_MARK ]) +memcpy (m,nla_data (attrs[XFRMA_MARK ]),sizeof (m)); +else + m->v = m->m =0 ; + +return m->v & m->m; +} + +static inline int xfrm_mark_put (struct sk_buff *skb,struct xfrm_mark *m) +{ +if (m->m | m->v) +NLA_PUT (skb,XFRMA_MARK ,sizeof (struct xfrm_mark ), m); +return 0 ; + +nla_put_failure: +return -1 ; +} +#endif /* _NET_XFRM_H */
Signature · 1 line
1.6.0.4
PATCH 2/7 xfrm: SA lookups signature with mark
From: Jamal Hadi Salim <[email protected]>
pass mark to all SA lookups to prepare them for when we add code to have them search.
--- include/net/xfrm.h | 23 +++++++++++++----- net/core/pktgen.c | 3 +- net/ipv4/ah4.c | 2 +- net/ipv4/esp4.c | 2 +- net/ipv4/ipcomp.c | 6 +++- net/ipv6/ah6.c | 2 +- net/ipv6/esp6.c | 2 +- net/ipv6/ipcomp6.c | 6 +++- net/ipv6/xfrm6_input.c | 2 +- net/key/af_key.c | 14 ++++++----- net/xfrm/xfrm_input.c | 2 +- net/xfrm/xfrm_state.c | 58 ++++++++++++++++++++++++++++------------------- net/xfrm/xfrm_user.c | 17 ++++++++----- 13 files changed, 84 insertions(+), 55 deletions(-)
include/net/xfrm.h +16 -7
@@ -1319,7 +1319,7 @@ extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t struct flowi *fl, struct xfrm_tmpl *tmpl, struct xfrm_policy *pol, int *err, unsigned short family); -extern struct xfrm_state * xfrm_stateonly_find(struct net *net, +extern struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, xfrm_address_t *daddr, xfrm_address_t *saddr, unsigned short family,
@@ -1328,8 +1328,14 @@ extern int xfrm_state_check_expire(struct xfrm_state *x);extern void xfrm_state_insert (struct xfrm_state *x);extern int xfrm_state_add (struct xfrm_state *x);extern int xfrm_state_update (struct xfrm_state *x); -extern struct xfrm_state *xfrm_state_lookup (struct net *net,xfrm_address_t *daddr,__be32 spi,u8 proto,unsigned short family); -extern struct xfrm_state *xfrm_state_lookup_byaddr (struct net *net,xfrm_address_t *daddr,xfrm_address_t *saddr,u8 proto,unsigned short family); +extern struct xfrm_state *xfrm_state_lookup (struct net *net,u32 mark, +xfrm_address_t *daddr,__be32 spi, +u8 proto,unsigned short family); +extern struct xfrm_state *xfrm_state_lookup_byaddr (struct net *net,u32 mark, +xfrm_address_t *daddr, +xfrm_address_t *saddr, +u8 proto, +unsigned short family);#ifdef CONFIG_XFRM_SUB_POLICY extern int xfrm_tmpl_sort (struct xfrm_tmpl **dst,struct xfrm_tmpl **src,int n,unsigned short family);
@@ -1366,7 +1372,8 @@ struct xfrmk_spdinfo {u32 spdhmcnt; }; -extern struct xfrm_state *xfrm_find_acq_byseq (struct net *net,u32 seq); +extern struct xfrm_state *xfrm_find_acq_byseq (struct net *net,u32 mark, +u32 seq);extern int xfrm_state_delete (struct xfrm_state *x);extern int xfrm_state_flush (struct net *net,u8 proto,struct xfrm_audit *audit_info);extern void xfrm_sad_getinfo (struct net *net,struct xfrmk_sadinfo *si);
@@ -1451,9 +1458,11 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net, u8, int dir, u32 id, int dint xfrm_policy_flush (struct net *net,u8 type,struct xfrm_audit *audit_info);u32 xfrm_get_acqseq (void );extern int xfrm_alloc_spi (struct xfrm_state *x,u32 minspi,u32 maxspi); -struct xfrm_state *xfrm_find_acq (struct net *net,u8 mode,u32 reqid,u8 proto, -xfrm_address_t *daddr,xfrm_address_t *saddr, -int create,unsigned short family); +struct xfrm_state *xfrm_find_acq (struct net *net,struct xfrm_mark *mark, +u8 mode,u32 reqid,u8 proto, +xfrm_address_t *daddr, +xfrm_address_t *saddr,int create, +unsigned short family);extern int xfrm_sk_policy_insert (struct sock *sk,int dir,struct xfrm_policy *pol);extern int xfrm_bundle_ok (struct xfrm_policy *pol,struct xfrm_dst *xdst,struct flowi *fl,int family,int strict);
net/core/pktgen.c +2 -1
@@ -2188,12 +2188,13 @@ static inline int f_pick(struct pktgen_dev *pkt_dev)/* If there was already an IPSEC SA, we keep it as is, else * we go look for it ... */ +#define DUMMY_MARK 0static void get_ipsec_sa (struct pktgen_dev *pkt_dev,int flow) {struct xfrm_state *x = pkt_dev->flows[flow].x;if (!x) {/*slow path: we dont already have xfrm_state*/ - x = xfrm_stateonly_find(&init_net, + x = xfrm_stateonly_find(&init_net, DUMMY_MARK, (xfrm_address_t *)&pkt_dev->cur_daddr, (xfrm_address_t *)&pkt_dev->cur_saddr, AF_INET,
net/ipv4/ah4.c +1 -1
@@ -393,7 +393,7 @@ static void ah4_err(struct sk_buff *skb, u32 info) icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)return ; - x =xfrm_state_lookup (net, (xfrm_address_t *)&iph->daddr, ah->spi,IPPROTO_AH ,AF_INET ); + x =xfrm_state_lookup (net, skb->mark, (xfrm_address_t *)&iph->daddr, ah->spi,IPPROTO_AH ,AF_INET );if (!x)return ; printk(KERN_DEBUG "pmtu discovery on SA AH/%08x/%08x\n",
net/ipv4/esp4.c +1 -1
@@ -422,7 +422,7 @@ static void esp4_err(struct sk_buff *skb, u32 info) icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)return ; - x =xfrm_state_lookup (net, (xfrm_address_t *)&iph->daddr, esph->spi,IPPROTO_ESP ,AF_INET ); + x =xfrm_state_lookup (net, skb->mark, (xfrm_address_t *)&iph->daddr, esph->spi,IPPROTO_ESP ,AF_INET );if (!x)return ; NETDEBUG(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%08x\n",
net/ipv4/ipcomp.c +4 -2
@@ -36,7 +36,7 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info)return ; spi =htonl (ntohs (ipch->cpi)); - x =xfrm_state_lookup (net, (xfrm_address_t *)&iph->daddr, + x =xfrm_state_lookup (net, skb->mark, (xfrm_address_t *)&iph->daddr, spi,IPPROTO_COMP ,AF_INET );if (!x)return ;
@@ -63,6 +63,7 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x) t->props.mode = x->props.mode; t->props.saddr.a4 = x->props.saddr.a4; t->props.flags = x->props.flags; +memcpy (&t->mark, &x->mark,sizeof (t->mark));if (xfrm_init_state (t)) goto error;
@@ -87,8 +88,9 @@ static int ipcomp_tunnel_attach(struct xfrm_state *x)struct net *net =xs_net (x);int err =0 ;struct xfrm_state *t; +u32 mark = x->mark.v & x->mark.m; - t =xfrm_state_lookup (net, (xfrm_address_t *)&x->id.daddr.a4, + t =xfrm_state_lookup (net, mark, (xfrm_address_t *)&x->id.daddr.a4, x->props.saddr.a4,IPPROTO_IPIP ,AF_INET );if (!t) { t =ipcomp_tunnel_create (x);
net/ipv6/ah6.c +1 -1
@@ -614,7 +614,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, type != ICMPV6_PKT_TOOBIG)return ; - x =xfrm_state_lookup (net, (xfrm_address_t *)&iph->daddr, ah->spi,IPPROTO_AH ,AF_INET6 ); + x =xfrm_state_lookup (net, skb->mark, (xfrm_address_t *)&iph->daddr, ah->spi,IPPROTO_AH ,AF_INET6 );if (!x)return ;
net/ipv6/esp6.c +1 -1
@@ -365,7 +365,7 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, type != ICMPV6_PKT_TOOBIG)return ; - x =xfrm_state_lookup (net, (xfrm_address_t *)&iph->daddr, esph->spi,IPPROTO_ESP ,AF_INET6 ); + x =xfrm_state_lookup (net, skb->mark, (xfrm_address_t *)&iph->daddr, esph->spi,IPPROTO_ESP ,AF_INET6 );if (!x)return ; printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%pI6\n",
net/ipv6/ipcomp6.c +4 -2
@@ -64,7 +64,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,return ; spi =htonl (ntohs (ipcomph->cpi)); - x =xfrm_state_lookup (net, (xfrm_address_t *)&iph->daddr, spi,IPPROTO_COMP ,AF_INET6 ); + x =xfrm_state_lookup (net, skb->mark, (xfrm_address_t *)&iph->daddr, spi,IPPROTO_COMP ,AF_INET6 );if (!x)return ;
@@ -92,6 +92,7 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x) t->props.family =AF_INET6 ; t->props.mode = x->props.mode;memcpy (t->props.saddr.a6, x->props.saddr.a6,sizeof (struct in6_addr )); +memcpy (&t->mark, &x->mark,sizeof (t->mark));if (xfrm_init_state (t)) goto error;
@@ -114,10 +115,11 @@ static int ipcomp6_tunnel_attach(struct xfrm_state *x)int err =0 ;struct xfrm_state *t =NULL ;__be32 spi; +u32 mark = x->mark.m & x->mark.v; spi =xfrm6_tunnel_spi_lookup (net, (xfrm_address_t *)&x->props.saddr);if (spi) - t =xfrm_state_lookup (net, (xfrm_address_t *)&x->id.daddr, + t =xfrm_state_lookup (net, mark, (xfrm_address_t *)&x->id.daddr, spi,IPPROTO_IPV6 ,AF_INET6 );if (!t) { t =ipcomp6_tunnel_create (x);
net/ipv6/xfrm6_input.c +1 -1
@@ -101,7 +101,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,break ; } - x =xfrm_state_lookup_byaddr (net, dst, src, proto,AF_INET6 ); + x =xfrm_state_lookup_byaddr (net, skb->mark, dst, src, proto,AF_INET6 );if (!x)continue ;
net/key/af_key.c +8 -6
@@ -45,6 +45,8 @@ static DECLARE_WAIT_QUEUE_HEAD(pfkey_table_wait);static DEFINE_RWLOCK (pfkey_table_lock);static atomic_t pfkey_table_users =ATOMIC_INIT (0 ); +#define DUMMY_MARK 0 +static struct xfrm_mark dummy_mark = {0 ,0 };struct pfkey_sock {/* struct sock must be the first member of struct pfkey_sock */ struct sock sk;
@@ -691,7 +693,7 @@ static struct xfrm_state *pfkey_xfrm_state_lookup(struct net *net, struct sadb_if (!xaddr)return NULL ; -return xfrm_state_lookup (net, xaddr, sa->sadb_sa_spi, proto, family); +return xfrm_state_lookup (net,DUMMY_MARK , xaddr, sa->sadb_sa_spi, proto, family); }#define PFKEY_ALIGN8 (a) (1 + (((a) - 1) | (8 - 1)))
@@ -1360,7 +1362,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h }if (hdr->sadb_msg_seq) { - x =xfrm_find_acq_byseq (net, hdr->sadb_msg_seq); + x =xfrm_find_acq_byseq (net,DUMMY_MARK , hdr->sadb_msg_seq);if (x &&xfrm_addr_cmp (&x->id.daddr, xdaddr, family)) {xfrm_state_put (x); x =NULL ;
@@ -1368,7 +1370,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h }if (!x) - x =xfrm_find_acq (net, mode, reqid, proto, xdaddr, xsaddr,1 , family); + x =xfrm_find_acq (net, &dummy_mark, mode, reqid, proto, xdaddr, xsaddr,1 , family);if (x ==NULL )return -ENOENT ;
@@ -1417,7 +1419,7 @@ static int pfkey_acquire(struct sock *sk, struct sk_buff *skb, struct sadb_msg *if (hdr->sadb_msg_seq ==0 || hdr->sadb_msg_errno ==0 )return 0 ; - x =xfrm_find_acq_byseq (net, hdr->sadb_msg_seq); + x =xfrm_find_acq_byseq (net,DUMMY_MARK , hdr->sadb_msg_seq);if (x ==NULL )return 0 ;
@@ -2616,8 +2618,8 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hreturn -EINVAL ; delete = (hdr->sadb_msg_type ==SADB_X_SPDDELETE2 ); - xp =xfrm_policy_byid (net,XFRM_POLICY_TYPE_MAIN , dir, - pol->sadb_x_policy_id, delete, &err); + xp =xfrm_policy_byid (net,XFRM_POLICY_TYPE_MAIN , + dir, pol->sadb_x_policy_id, delete, &err);if (xp ==NULL )return -ENOENT ;
net/xfrm/xfrm_input.c +1 -1
@@ -152,7 +152,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) goto drop; } - x =xfrm_state_lookup (net, daddr, spi, nexthdr, family); + x =xfrm_state_lookup (net, skb->mark, daddr, spi, nexthdr, family);if (x ==NULL ) {XFRM_INC_STATS (net,LINUX_MIB_XFRMINNOSTATES );xfrm_audit_state_notfound (skb, family, spi, seq);
net/xfrm/xfrm_state.c +34 -24
213 lines not on this page · raw message
net/xfrm/xfrm_user.c +10 -7
@@ -31,6 +31,9 @@#include <linux/in6.h> #endif +#define DUMMY_MARK 0 +static struct xfrm_mark dummy_mark = {0 ,0 }; +static inline int aead_len (struct xfrm_algo_aead *alg) {return sizeof (*alg) + ((alg->alg_key_len +7 ) /8 );
@@ -530,7 +533,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct net *net,if (xfrm_id_proto_match (p->proto,IPSEC_PROTO_ANY )) { err = -ESRCH ; - x =xfrm_state_lookup (net, &p->daddr, p->spi, p->proto, p->family); + x =xfrm_state_lookup (net,DUMMY_MARK , &p->daddr, p->spi, p->proto, p->family); }else {xfrm_address_t *saddr =NULL ;
@@ -541,7 +544,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct net *net, } err = -ESRCH ; - x =xfrm_state_lookup_byaddr (net, &p->daddr, saddr, + x =xfrm_state_lookup_byaddr (net,DUMMY_MARK , &p->daddr, saddr, p->proto, p->family); }
@@ -958,7 +961,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, x =NULL ;if (p->info.seq) { - x =xfrm_find_acq_byseq (net, p->info.seq); + x =xfrm_find_acq_byseq (net,DUMMY_MARK , p->info.seq);if (x &&xfrm_addr_cmp (&x->id.daddr, daddr, family)) {xfrm_state_put (x); x =NULL ;
@@ -966,7 +969,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, }if (!x) - x =xfrm_find_acq (net, p->info.mode, p->info.reqid, + x =xfrm_find_acq (net, &dummy_mark, p->info.mode, p->info.reqid, p->info.id.proto, daddr, &p->info.saddr,1 , family);
@@ -1598,7 +1601,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,if (r_skb ==NULL )return -ENOMEM ; - x =xfrm_state_lookup (net, &id->daddr, id->spi, id->proto, id->family); + x =xfrm_state_lookup (net,DUMMY_MARK , &id->daddr, id->spi, id->proto, id->family);if (x ==NULL ) {kfree_skb (r_skb);return -ESRCH ;
@@ -1640,7 +1643,7 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,if (!(nlh->nlmsg_flags&NLM_F_REPLACE ))return err; - x =xfrm_state_lookup (net, &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family); + x =xfrm_state_lookup (net,DUMMY_MARK , &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family);if (x ==NULL )return -ESRCH ;
@@ -1767,7 +1770,7 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,struct xfrm_user_expire *ue =nlmsg_data (nlh);struct xfrm_usersa_info *p = &ue->state; - x =xfrm_state_lookup (net, &p->id.daddr, p->id.spi, p->id.proto, p->family); + x =xfrm_state_lookup (net,DUMMY_MARK , &p->id.daddr, p->id.spi, p->id.proto, p->family); err = -ENOENT ;if (x ==NULL )
Signature · 1 line
1.6.0.4
PATCH 3/7 xfrm: SA lookups with mark
From: Jamal Hadi Salim <[email protected]>
Allow mark to be added to the SA lookup
--- net/xfrm/xfrm_state.c | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-)
net/xfrm/xfrm_state.c +12 -0
@@ -682,6 +682,8 @@ static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark, xfrm_ad xfrm_addr_cmp(&x->id.daddr, daddr, family))continue ; +if ((mark & x->mark.m) != x->mark.v) +continue ;xfrm_state_hold (x);return x; }
@@ -702,6 +704,8 @@ static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, u32 mark, xfrm_addr_cmp(&x->props.saddr, saddr, family)) continue; +if ((mark & x->mark.m) != x->mark.v) +continue ;xfrm_state_hold (x);return x; }
@@ -794,6 +798,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,hlist_for_each_entry (x, entry, net->xfrm.state_bydst+h, bydst) { if (x->props.family == family && x->props.reqid == tmpl->reqid && + (mark & x->mark.m) == x->mark.v && !(x->props.flags & XFRM_STATE_WILDRECV) && xfrm_state_addr_check(x, daddr, saddr, family) && tmpl->mode == x->props.mode &&
@@ -809,6 +814,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,hlist_for_each_entry (x, entry, net->xfrm.state_bydst+h_wildcard, bydst) { if (x->props.family == family && x->props.reqid == tmpl->reqid && + (mark & x->mark.m) == x->mark.v && !(x->props.flags & XFRM_STATE_WILDRECV) && xfrm_state_addr_check(x, daddr, saddr, family) && tmpl->mode == x->props.mode &&
@@ -892,6 +898,7 @@ xfrm_stateonly_find(struct net *net, u32 mark,hlist_for_each_entry (x, entry, net->xfrm.state_bydst+h, bydst) { if (x->props.family == family && x->props.reqid == reqid && + (mark & x->mark.m) == x->mark.v && !(x->props.flags & XFRM_STATE_WILDRECV) && xfrm_state_addr_check(x, daddr, saddr, family) && mode == x->props.mode &&
@@ -954,11 +961,13 @@ static void __xfrm_state_bump_genids(struct xfrm_state *xnew)struct xfrm_state *x;struct hlist_node *entry;unsigned int h; +u32 mark = xnew->mark.v & xnew->mark.m; h =xfrm_dst_hash (net, &xnew->id.daddr, &xnew->props.saddr, reqid, family);hlist_for_each_entry (x, entry, net->xfrm.state_bydst+h, bydst) {if (x->props.family == family && x->props.reqid == reqid && + (mark & x->mark.m) == x->mark.v && !xfrm_addr_cmp (&x->id.daddr, &xnew->id.daddr, family) && !xfrm_addr_cmp (&x->props.saddr, &xnew->props.saddr, family)) x->genid = xfrm_state_genid;
@@ -980,6 +989,7 @@ static struct xfrm_state *__find_acq_core(struct net *net, struct xfrm_mark *m,unsigned int h =xfrm_dst_hash (net, daddr, saddr, reqid, family);struct hlist_node *entry;struct xfrm_state *x; +u32 mark = m->v & m->m;hlist_for_each_entry (x, entry, net->xfrm.state_bydst+h, bydst) { if (x->props.reqid != reqid ||
@@ -988,6 +998,7 @@ static struct xfrm_state *__find_acq_core(struct net *net, struct xfrm_mark *m, x->km.state !=XFRM_STATE_ACQ || x->id.spi !=0 || x->id.proto != proto || + (mark & x->mark.m) != x->mark.v ||xfrm_addr_cmp (&x->id.daddr, daddr, family) || xfrm_addr_cmp(&x->props.saddr, saddr, family)) continue;
@@ -1442,6 +1453,7 @@ static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 mark, u32 shlist_for_each_entry (x, entry, net->xfrm.state_bydst+i, bydst) {if (x->km.seq == seq && + (mark & x->mark.m) == x->mark.v && x->km.state ==XFRM_STATE_ACQ ) {xfrm_state_hold (x);return x;
Signature · 1 line
1.6.0.4
PATCH 4/7 xfrm: SP lookups signature with mark
From: Jamal Hadi Salim <[email protected]>
pass mark to all SP lookups to prepare them for when we add code to have them search.
--- include/net/xfrm.h | 5 +++-- net/key/af_key.c | 4 ++-- net/xfrm/xfrm_policy.c | 8 ++++---- net/xfrm/xfrm_user.c | 10 +++++----- 4 files changed, 14 insertions(+), 13 deletions(-)
include/net/xfrm.h +3 -2
@@ -1450,11 +1450,12 @@ extern int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk, int (*func)(struct xfrm_policy *, int, int, void*), void *);extern void xfrm_policy_walk_done (struct xfrm_policy_walk *walk);int xfrm_policy_insert (int dir,struct xfrm_policy *policy,int excl); -struct xfrm_policy *xfrm_policy_bysel_ctx (struct net *net,u8 type,int dir, +struct xfrm_policy *xfrm_policy_bysel_ctx (struct net *net,u32 mark, +u8 type,int dir,struct xfrm_selector *sel,struct xfrm_sec_ctx *ctx,int delete,int *err); -struct xfrm_policy *xfrm_policy_byid (struct net *net,u8 ,int dir,u32 id,int delete,int *err); +struct xfrm_policy *xfrm_policy_byid (struct net *net,u32 mark,u8 ,int dir,u32 id,int delete,int *err);int xfrm_policy_flush (struct net *net,u8 type,struct xfrm_audit *audit_info);u32 xfrm_get_acqseq (void );extern int xfrm_alloc_spi (struct xfrm_state *x,u32 minspi,u32 maxspi);
net/key/af_key.c +2 -2
@@ -2370,7 +2370,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msgreturn err; } - xp =xfrm_policy_bysel_ctx (net,XFRM_POLICY_TYPE_MAIN , + xp =xfrm_policy_bysel_ctx (net,DUMMY_MARK ,XFRM_POLICY_TYPE_MAIN , pol->sadb_x_policy_dir -1 , &sel, pol_ctx,1 , &err);security_xfrm_policy_free (pol_ctx);
@@ -2618,7 +2618,7 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hreturn -EINVAL ; delete = (hdr->sadb_msg_type ==SADB_X_SPDDELETE2 ); - xp =xfrm_policy_byid (net,XFRM_POLICY_TYPE_MAIN , + xp =xfrm_policy_byid (net,DUMMY_MARK ,XFRM_POLICY_TYPE_MAIN , dir, pol->sadb_x_policy_id, delete, &err);if (xp ==NULL )return -ENOENT ;
net/xfrm/xfrm_policy.c +4 -4
@@ -635,8 +635,8 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) }EXPORT_SYMBOL (xfrm_policy_insert); -struct xfrm_policy *xfrm_policy_bysel_ctx (struct net *net,u8 type,int dir, -struct xfrm_selector *sel, +struct xfrm_policy *xfrm_policy_bysel_ctx (struct net *net,u32 mark,u8 type, +int dir,struct xfrm_selector *sel,struct xfrm_sec_ctx *ctx,int delete,int *err) {
@@ -676,8 +676,8 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u8 type, int dir, }EXPORT_SYMBOL (xfrm_policy_bysel_ctx); -struct xfrm_policy *xfrm_policy_byid (struct net *net,u8 type,int dir,u32 id, -int delete,int *err) +struct xfrm_policy *xfrm_policy_byid (struct net *net,u32 mark,u8 type, +int dir,u32 id,int delete,int *err) {struct xfrm_policy *pol, *ret;struct hlist_head *chain;
net/xfrm/xfrm_user.c +5 -5
@@ -1457,7 +1457,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,return err;if (p->index) - xp =xfrm_policy_byid (net, type, p->dir, p->index, delete, &err); + xp =xfrm_policy_byid (net,DUMMY_MARK , type, p->dir, p->index, delete, &err);else {struct nlattr *rt = attrs[XFRMA_SEC_CTX ];struct xfrm_sec_ctx *ctx;
@@ -1474,8 +1474,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,if (err)return err; } - xp =xfrm_policy_bysel_ctx (net, type, p->dir, &p->sel, ctx, - delete, &err); + xp =xfrm_policy_bysel_ctx (net,DUMMY_MARK , type, p->dir, + &p->sel, ctx, delete, &err);security_xfrm_policy_free (ctx); }if (xp ==NULL )
@@ -1712,7 +1712,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,return err;if (p->index) - xp =xfrm_policy_byid (net, type, p->dir, p->index,0 , &err); + xp =xfrm_policy_byid (net,DUMMY_MARK , type, p->dir, p->index,0 , &err);else {struct nlattr *rt = attrs[XFRMA_SEC_CTX ];struct xfrm_sec_ctx *ctx;
@@ -1729,7 +1729,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,if (err)return err; } - xp =xfrm_policy_bysel_ctx (net, type, p->dir, &p->sel, ctx,0 , &err); + xp =xfrm_policy_bysel_ctx (net,DUMMY_MARK , type, p->dir, &p->sel, ctx,0 , &err);security_xfrm_policy_free (ctx); }if (xp ==NULL )
Signature · 1 line
1.6.0.4
PATCH 5/7 xfrm: SP lookups with mark
From: Jamal Hadi Salim <[email protected]>
Allow mark to be used when doing SP lookup
--- net/xfrm/xfrm_policy.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-)
net/xfrm/xfrm_policy.c +11 -1
@@ -556,6 +556,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)struct hlist_head *chain;struct hlist_node *entry, *newpos;struct dst_entry *gc_list; +u32 mark = policy->mark.v & policy->mark.m;write_lock_bh (&xfrm_policy_lock); chain =policy_hash_bysel (net, &policy->selector, policy->family, dir);
@@ -564,6 +565,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)hlist_for_each_entry (pol, entry, chain, bydst) {if (pol->type == policy->type && !selector_cmp (&pol->selector, &policy->selector) && + (mark & pol->mark.m) == pol->mark.v &&xfrm_sec_ctx_match (pol->security, policy->security) && !WARN_ON (delpol)) {if (excl) {
@@ -650,6 +652,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u8 type, ret =NULL ;hlist_for_each_entry (pol, entry, chain, bydst) {if (pol->type == type && + (mark & pol->mark.m) == pol->mark.v && !selector_cmp (sel, &pol->selector) &&xfrm_sec_ctx_match (ctx, pol->security)) {xfrm_pol_hold (pol);
@@ -692,7 +695,8 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8 type, chain = net->xfrm.policy_byidx +idx_hash (net, id); ret =NULL ;hlist_for_each_entry (pol, entry, chain, byidx) { -if (pol->type == type && pol->index == id) { +if (pol->type == type && pol->index == id && + (mark & pol->mark.m) == pol->mark.v) {xfrm_pol_hold (pol);if (delete) { *err = security_xfrm_policy_delete(
@@ -916,6 +920,7 @@ static int xfrm_policy_match(struct xfrm_policy *pol, struct flowi *fl,int match, ret = -ESRCH ;if (pol->family != family || + (fl->mark & pol->mark.m) != pol->mark.v || pol->type != type)return ret;
@@ -1040,6 +1045,10 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, strucint err =0 ;if (match) { +if ((sk->sk_mark & pol->mark.m) != pol->mark.v) { + pol =NULL ; + goto out; + } err =security_xfrm_policy_lookup (pol->security, fl->secid,policy_to_flow_dir (dir));
@@ -1052,6 +1061,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc }else pol =NULL ; } +out:read_unlock_bh (&xfrm_policy_lock);return pol; }
Signature · 1 line
1.6.0.4
PATCH 6/7 xfrm: Allow user space config of SAD mark
From: Jamal Hadi Salim <[email protected]>
Add ability for netlink userspace to manipulate the SAD and manipulate the mark, retrieve it and get events with a defined mark.
MIGRATE may be added later.
--- net/xfrm/xfrm_user.c | 72 +++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 57 insertions(+), 15 deletions(-)
net/xfrm/xfrm_user.c +57 -15
@@ -32,7 +32,6 @@#endif #define DUMMY_MARK 0 -static struct xfrm_mark dummy_mark = {0 ,0 };static inline int aead_len (struct xfrm_algo_aead *alg) {
@@ -449,6 +448,8 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, goto error; } +xfrm_mark_get (attrs, &x->mark); + err =xfrm_init_state (x);if (err) goto error;
@@ -529,11 +530,13 @@ static struct xfrm_state *xfrm_user_state_lookup(struct net *net, int *errp) {struct xfrm_state *x =NULL ; +struct xfrm_mark m;int err; +u32 mark =xfrm_mark_get (attrs, &m);if (xfrm_id_proto_match (p->proto,IPSEC_PROTO_ANY )) { err = -ESRCH ; - x =xfrm_state_lookup (net,DUMMY_MARK , &p->daddr, p->spi, p->proto, p->family); + x =xfrm_state_lookup (net, mark, &p->daddr, p->spi, p->proto, p->family); }else {xfrm_address_t *saddr =NULL ;
@@ -544,7 +547,8 @@ static struct xfrm_state *xfrm_user_state_lookup(struct net *net, } err = -ESRCH ; - x =xfrm_state_lookup_byaddr (net,DUMMY_MARK , &p->daddr, saddr, + x =xfrm_state_lookup_byaddr (net, mark, + &p->daddr, saddr, p->proto, p->family); }
@@ -686,6 +690,9 @@ static int copy_to_user_state_extra(struct xfrm_state *x,if (x->encap)NLA_PUT (skb,XFRMA_ENCAP ,sizeof (*x->encap), x->encap); +if (xfrm_mark_put (skb, &x->mark)) + goto nla_put_failure; +if (x->security &©_sec_ctx (x->security, skb) <0 ) goto nla_put_failure;
@@ -950,6 +957,8 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,xfrm_address_t *daddr;int family;int err; +u32 mark; +struct xfrm_mark m; p =nlmsg_data (nlh); err =verify_userspi_info (p);
@@ -960,8 +969,10 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, daddr = &p->info.id.daddr; x =NULL ; + + mark =xfrm_mark_get (attrs, &m);if (p->info.seq) { - x =xfrm_find_acq_byseq (net,DUMMY_MARK , p->info.seq); + x =xfrm_find_acq_byseq (net, mark, p->info.seq);if (x &&xfrm_addr_cmp (&x->id.daddr, daddr, family)) {xfrm_state_put (x); x =NULL ;
@@ -969,7 +980,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, }if (!x) - x =xfrm_find_acq (net, &dummy_mark, p->info.mode, p->info.reqid, + x =xfrm_find_acq (net, &m, p->info.mode, p->info.reqid, p->info.id.proto, daddr, &p->info.saddr,1 , family);
@@ -1474,8 +1485,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,if (err)return err; } - xp =xfrm_policy_bysel_ctx (net,DUMMY_MARK , type, p->dir, - &p->sel, ctx, delete, &err); + xp =xfrm_policy_bysel_ctx (net,DUMMY_MARK , type, p->dir, &p->sel, + ctx, delete, &err);security_xfrm_policy_free (ctx); }if (xp ==NULL )
@@ -1547,6 +1558,7 @@ static inline size_t xfrm_aevent_msgsize(void)return NLMSG_ALIGN (sizeof (struct xfrm_aevent_id )) +nla_total_size (sizeof (struct xfrm_replay_state )) +nla_total_size (sizeof (struct xfrm_lifetime_cur )) + +nla_total_size (sizeof (struct xfrm_mark )) +nla_total_size (4 )/* XFRM_AE_RTHR */ +nla_total_size (4 );/* XFRM_AE_ETHR */ }
@@ -1579,6 +1591,9 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, struct km_eveNLA_PUT_U32 (skb,XFRMA_ETIMER_THRESH , x->replay_maxage *10 /HZ ); +if (xfrm_mark_put (skb, &x->mark)) + goto nla_put_failure; +return nlmsg_end (skb, nlh); nla_put_failure:
@@ -1594,6 +1609,8 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,struct sk_buff *r_skb;int err;struct km_event c; +u32 mark; +struct xfrm_mark m;struct xfrm_aevent_id *p =nlmsg_data (nlh);struct xfrm_usersa_id *id = &p->sa_id;
@@ -1601,7 +1618,9 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,if (r_skb ==NULL )return -ENOMEM ; - x =xfrm_state_lookup (net,DUMMY_MARK , &id->daddr, id->spi, id->proto, id->family); + mark =xfrm_mark_get (attrs, &m); + + x =xfrm_state_lookup (net, mark, &id->daddr, id->spi, id->proto, id->family);if (x ==NULL ) {kfree_skb (r_skb);return -ESRCH ;
@@ -1632,6 +1651,8 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,struct xfrm_state *x;struct km_event c;int err = -EINVAL ; +u32 mark =0 ; +struct xfrm_mark m;struct xfrm_aevent_id *p =nlmsg_data (nlh);struct nlattr *rp = attrs[XFRMA_REPLAY_VAL ];struct nlattr *lt = attrs[XFRMA_LTIME_VAL ];
@@ -1643,7 +1664,9 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,if (!(nlh->nlmsg_flags&NLM_F_REPLACE ))return err; - x =xfrm_state_lookup (net,DUMMY_MARK , &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family); + mark =xfrm_mark_get (attrs, &m); + + x =xfrm_state_lookup (net, mark, &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family);if (x ==NULL )return -ESRCH ;
@@ -1729,7 +1752,8 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,if (err)return err; } - xp =xfrm_policy_bysel_ctx (net,DUMMY_MARK , type, p->dir, &p->sel, ctx,0 , &err); + xp =xfrm_policy_bysel_ctx (net,DUMMY_MARK , type, p->dir, + &p->sel, ctx,0 , &err);security_xfrm_policy_free (ctx); }if (xp ==NULL )
@@ -1769,8 +1793,10 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,int err;struct xfrm_user_expire *ue =nlmsg_data (nlh);struct xfrm_usersa_info *p = &ue->state; +struct xfrm_mark m; +u32 mark =xfrm_mark_get (attrs, &m);; - x =xfrm_state_lookup (net,DUMMY_MARK , &p->id.daddr, p->id.spi, p->id.proto, p->family); + x =xfrm_state_lookup (net, mark, &p->id.daddr, p->id.spi, p->id.proto, p->family); err = -ENOENT ;if (x ==NULL )
@@ -1804,6 +1830,7 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,struct xfrm_user_tmpl *ut;int i;struct nlattr *rt = attrs[XFRMA_TMPL ]; +struct xfrm_mark mark;struct xfrm_user_acquire *ua =nlmsg_data (nlh);struct xfrm_state *x =xfrm_state_alloc (net);
@@ -1812,6 +1839,8 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,if (!x) goto nomem; +xfrm_mark_get (attrs, &mark); + err =verify_newpolicy_info (&ua->policy);if (err) goto bad_policy;
@@ -1824,7 +1853,8 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,memcpy (&x->id, &ua->id,sizeof (ua->id));memcpy (&x->props.saddr, &ua->saddr,sizeof (ua->saddr));memcpy (&x->sel, &ua->sel,sizeof (ua->sel)); - + xp->mark.m = x->mark.m = mark.m; + xp->mark.v = x->mark.v = mark.v; ut =nla_data (rt);/* extract the templates and for each call km_key */ for (i =0 ; i < xp->xfrm_nr; i++, ut++) {
@@ -2084,6 +2114,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = { [XFRMA_POLICY_TYPE] = { .len = sizeof(struct xfrm_userpolicy_type)}, [XFRMA_MIGRATE] = { .len = sizeof(struct xfrm_user_migrate) }, [XFRMA_KMADDRESS] = { .len = sizeof(struct xfrm_user_kmaddress) }, + [XFRMA_MARK] = { .len = sizeof(struct xfrm_mark) }, }; static struct xfrm_link {
@@ -2163,7 +2194,8 @@ static void xfrm_netlink_rcv(struct sk_buff *skb)static inline size_t xfrm_expire_msgsize (void ) { -return NLMSG_ALIGN (sizeof (struct xfrm_user_expire )); +return NLMSG_ALIGN (sizeof (struct xfrm_user_expire )) + +nla_total_size (sizeof (struct xfrm_mark )); }static int build_expire (struct sk_buff *skb,struct xfrm_state *x,struct km_event *c)
@@ -2179,7 +2211,13 @@ static int build_expire(struct sk_buff *skb, struct xfrm_state *x, struct km_evecopy_to_user_state (x, &ue->state); ue->hard = (c->data.hard !=0 ) ?1 :0 ; +if (xfrm_mark_put (skb, &x->mark)) + goto nla_put_failure; +return nlmsg_end (skb, nlh); + +nla_put_failure: +return -EMSGSIZE ; }static int xfrm_exp_state_notify (struct xfrm_state *x,struct km_event *c)
@@ -2191,8 +2229,10 @@ static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c)if (skb ==NULL )return -ENOMEM ; -if (build_expire (skb, x, c) <0 ) -BUG (); +if (build_expire (skb, x, c) <0 ) { +kfree_skb (skb); +return -EMSGSIZE ; + }return nlmsg_multicast (net->xfrm.nlsk, skb,0 ,XFRMNLGRP_EXPIRE ,GFP_ATOMIC ); }
@@ -2280,6 +2320,7 @@ static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c)if (c->event ==XFRM_MSG_DELSA ) { len +=nla_total_size (headlen); headlen =sizeof (*id); + len +=nla_total_size (sizeof (struct xfrm_mark )); } len +=NLMSG_ALIGN (headlen);
@@ -2350,6 +2391,7 @@ static inline size_t xfrm_acquire_msgsize(struct xfrm_state *x, {return NLMSG_ALIGN (sizeof (struct xfrm_user_acquire )) +nla_total_size (sizeof (struct xfrm_user_tmpl ) * xp->xfrm_nr) + +nla_total_size (sizeof (struct xfrm_mark )) +nla_total_size (xfrm_user_sec_ctx_size (x->security)) +userpolicy_type_attrsize (); }
Signature · 1 line
1.6.0.4
PATCH 7/7 xfrm: Allow user space manipulation of SPD mark
From: Jamal Hadi Salim <[email protected]>
Add ability for netlink userspace to manipulate the SPD and manipulate the mark, retrieve it and get events with a defined mark, etc.
--- net/xfrm/xfrm_user.c | 31 +++++++++++++++++++++++++------ 1 files changed, 25 insertions(+), 6 deletions(-)
net/xfrm/xfrm_user.c +25 -6
@@ -31,8 +31,6 @@#include <linux/in6.h> #endif -#define DUMMY_MARK 0 -static inline int aead_len (struct xfrm_algo_aead *alg) {return sizeof (*alg) + ((alg->alg_key_len +7 ) /8 );
@@ -1234,6 +1232,8 @@ static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_usif (err) goto error; +xfrm_mark_get (attrs, &xp->mark); +return xp; error: *errp = err;
@@ -1380,10 +1380,13 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr goto nlmsg_failure;if (copy_to_user_policy_type (xp->type, skb) <0 ) goto nlmsg_failure; +if (xfrm_mark_put (skb, &xp->mark)) + goto nla_put_failure;nlmsg_end (skb, nlh);return 0 ; +nla_put_failure: nlmsg_failure:nlmsg_cancel (skb, nlh);return -EMSGSIZE ;
@@ -1455,6 +1458,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,int err;struct km_event c;int delete; +struct xfrm_mark m; +u32 mark =xfrm_mark_get (attrs, &m); p =nlmsg_data (nlh); delete = nlh->nlmsg_type ==XFRM_MSG_DELPOLICY ;
@@ -1468,7 +1473,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,return err;if (p->index) - xp =xfrm_policy_byid (net,DUMMY_MARK , type, p->dir, p->index, delete, &err); + xp =xfrm_policy_byid (net, mark, type, p->dir, p->index, delete, &err);else {struct nlattr *rt = attrs[XFRMA_SEC_CTX ];struct xfrm_sec_ctx *ctx;
@@ -1485,7 +1490,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,if (err)return err; } - xp =xfrm_policy_bysel_ctx (net,DUMMY_MARK , type, p->dir, &p->sel, + xp =xfrm_policy_bysel_ctx (net, mark, type, p->dir, &p->sel, ctx, delete, &err);security_xfrm_policy_free (ctx); }
@@ -1729,13 +1734,15 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,struct xfrm_userpolicy_info *p = &up->pol;u8 type =XFRM_POLICY_TYPE_MAIN ;int err = -ENOENT ; +struct xfrm_mark m; +u32 mark =xfrm_mark_get (attrs, &m); err =copy_from_user_policy_type (&type, attrs);if (err)return err;if (p->index) - xp =xfrm_policy_byid (net,DUMMY_MARK , type, p->dir, p->index,0 , &err); + xp =xfrm_policy_byid (net, mark, type, p->dir, p->index,0 , &err);else {struct nlattr *rt = attrs[XFRMA_SEC_CTX ];struct xfrm_sec_ctx *ctx;
@@ -1752,7 +1759,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,if (err)return err; } - xp =xfrm_policy_bysel_ctx (net,DUMMY_MARK , type, p->dir, + xp =xfrm_policy_bysel_ctx (net, mark, type, p->dir, &p->sel, ctx,0 , &err);security_xfrm_policy_free (ctx); }
@@ -2424,9 +2431,12 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x, goto nlmsg_failure;if (copy_to_user_policy_type (xp->type, skb) <0 ) goto nlmsg_failure; +if (xfrm_mark_put (skb, &xp->mark)) + goto nla_put_failure;return nlmsg_end (skb, nlh); +nla_put_failure: nlmsg_failure:nlmsg_cancel (skb, nlh);return -EMSGSIZE ;
@@ -2513,6 +2523,7 @@ static inline size_t xfrm_polexpire_msgsize(struct xfrm_policy *xp)return NLMSG_ALIGN (sizeof (struct xfrm_user_polexpire )) +nla_total_size (sizeof (struct xfrm_user_tmpl ) * xp->xfrm_nr) +nla_total_size (xfrm_user_sec_ctx_size (xp->security)) + +nla_total_size (sizeof (struct xfrm_mark )) +userpolicy_type_attrsize (); }
@@ -2535,10 +2546,13 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp, goto nlmsg_failure;if (copy_to_user_policy_type (xp->type, skb) <0 ) goto nlmsg_failure; +if (xfrm_mark_put (skb, &xp->mark)) + goto nla_put_failure; upe->hard = !!hard;return nlmsg_end (skb, nlh); +nla_put_failure: nlmsg_failure:nlmsg_cancel (skb, nlh);return -EMSGSIZE ;
@@ -2575,6 +2589,7 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event * headlen =sizeof (*id); } len +=userpolicy_type_attrsize (); + len +=nla_total_size (sizeof (struct xfrm_mark )); len +=NLMSG_ALIGN (headlen); skb =nlmsg_new (len,GFP_ATOMIC );
@@ -2610,10 +2625,14 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *if (copy_to_user_policy_type (xp->type, skb) <0 ) goto nlmsg_failure; +if (xfrm_mark_put (skb, &xp->mark)) + goto nla_put_failure; +nlmsg_end (skb, nlh);return nlmsg_multicast (net->xfrm.nlsk, skb,0 ,XFRMNLGRP_POLICY ,GFP_ATOMIC ); +nla_put_failure: nlmsg_failure:kfree_skb (skb);return -1 ;
Signature · 1 line
1.6.0.4
David Miller
maintainerFrom: jamal <[email protected]>
Date: Mon, 22 Feb 2010 16:32:53 -0500
Quoted 3 lines
This patchset implements manipulation of ipsec tables with the "mark" tag. You can config the SAD and SPD from user space with a specified mark.
Looks good, all applied to net-next-2.6, thanks!