* [net-next-2.6 PATCH 3/7] xfrm: SA lookups with mark
2010-02-14 15:18 ` [net-next-2.6 PATCH 2/7] xfrm: SA lookups signature with mark jamal
@ 2010-02-14 15:18 ` jamal
0 siblings, 0 replies; 12+ messages in thread
From: jamal @ 2010-02-14 15:18 UTC (permalink / raw)
To: timo.teras, kaber, herbert, davem; +Cc: netdev, Jamal Hadi Salim
From: Jamal Hadi Salim <hadi@cyberus.ca>
Allow mark to be added to the SA lookup
Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
---
net/xfrm/xfrm_state.c | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index fcf0d9f..151c6d6 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -678,6 +678,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;
}
@@ -698,6 +700,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;
}
@@ -790,6 +794,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 &&
@@ -805,6 +810,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 &&
@@ -888,6 +894,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 &&
@@ -950,11 +957,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;
@@ -976,6 +985,7 @@ static struct xfrm_state *__find_acq_core(struct net *net, struct xfrm_kmark *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 ||
@@ -984,6 +994,7 @@ static struct xfrm_state *__find_acq_core(struct net *net, struct xfrm_kmark *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;
@@ -1444,6 +1455,7 @@ static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 mark, u32 s
hlist_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;
--
1.6.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [net-next-2.6 PATCH 0/7] xfrm by MARK
[not found] <xfrm-mark-take2>
@ 2010-02-20 20:55 ` jamal
2010-02-20 20:55 ` [net-next-2.6 PATCH 1/7] xfrm: introduce basic mark infrastructure jamal
0 siblings, 1 reply; 12+ messages in thread
From: jamal @ 2010-02-20 20:55 UTC (permalink / raw)
To: davem, timo.teras; +Cc: kaber, herbert, netdev, Jamal Hadi Salim
From: Jamal Hadi Salim <hadi@cyberus.ca>
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.
Changes since last time:
----------------------
Patch 1/7: Feedback from Patrick McHardy; We pass to user space any
mark as long as it has non-zero mask.
Example usage:
---
#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
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
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
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
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 | 56 +++++++++++++++++++++++----
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, 222 insertions(+), 75 deletions(-)
^ permalink raw reply [flat|nested] 12+ messages in thread
* [net-next-2.6 PATCH 1/7] xfrm: introduce basic mark infrastructure
2010-02-20 20:55 ` [net-next-2.6 PATCH 0/7] xfrm by MARK jamal
@ 2010-02-20 20:55 ` jamal
2010-02-20 20:55 ` [net-next-2.6 PATCH 2/7] xfrm: SA lookups signature with mark jamal
2010-02-22 6:26 ` [net-next-2.6 PATCH 1/7] xfrm: introduce basic mark infrastructure David Miller
0 siblings, 2 replies; 12+ messages in thread
From: jamal @ 2010-02-20 20:55 UTC (permalink / raw)
To: davem, timo.teras; +Cc: kaber, herbert, netdev, Jamal Hadi Salim
From: Jamal Hadi Salim <hadi@cyberus.ca>
Add basic structuring and accessors for xfrm mark
Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
---
include/linux/xfrm.h | 12 +++++++++---
include/net/xfrm.h | 28 ++++++++++++++++++++++++++++
2 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index 29e04be..887c533 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -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, /* u32 */
__XFRMA_MAX
#define XFRMA_MAX (__XFRMA_MAX - 1)
};
+struct xfrm_umark {
+ __u32 v; /* value */
+ __u32 m; /* mask */
+};
+
enum xfrm_sadattr_type_t {
XFRMA_SAD_UNSPEC,
XFRMA_SAD_CNT,
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 0beb413..4778520 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -123,6 +123,11 @@ struct xfrm_state_walk {
u32 seq;
};
+struct xfrm_kmark {
+ u32 v; /* value */
+ u32 m; /* mask */
+};
+
/* Full description of state of transformer. */
struct xfrm_state {
#ifdef CONFIG_NET_NS
@@ -140,6 +145,7 @@ struct xfrm_state {
struct xfrm_id id;
struct xfrm_selector sel;
+ struct xfrm_kmark mark;
u32 genid;
@@ -456,6 +462,7 @@ struct xfrm_tmpl {
#define XFRM_MAX_DEPTH 6
+
struct xfrm_policy_walk_entry {
struct list_head all;
u8 dead;
@@ -481,6 +488,7 @@ struct xfrm_policy {
u32 priority;
u32 index;
+ struct xfrm_kmark mark;
struct xfrm_selector selector;
struct xfrm_lifetime_cfg lft;
struct xfrm_lifetime_cur curlft;
@@ -1570,4 +1578,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_kmark *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_kmark *m)
+{
+ if (m->m | m->v)
+ NLA_PUT(skb, XFRMA_MARK, sizeof(struct xfrm_kmark), m);
+ return 0;
+
+nla_put_failure:
+ return -1;
+}
+
#endif /* _NET_XFRM_H */
--
1.6.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [net-next-2.6 PATCH 2/7] xfrm: SA lookups signature with mark
2010-02-20 20:55 ` [net-next-2.6 PATCH 1/7] xfrm: introduce basic mark infrastructure jamal
@ 2010-02-20 20:55 ` jamal
2010-02-20 20:55 ` [net-next-2.6 PATCH 3/7] xfrm: SA lookups " jamal
2010-02-22 6:26 ` [net-next-2.6 PATCH 1/7] xfrm: introduce basic mark infrastructure David Miller
1 sibling, 1 reply; 12+ messages in thread
From: jamal @ 2010-02-20 20:55 UTC (permalink / raw)
To: davem, timo.teras; +Cc: kaber, herbert, netdev, Jamal Hadi Salim
From: Jamal Hadi Salim <hadi@cyberus.ca>
pass mark to all SA lookups to prepare them for when we add code
to have them search.
Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
---
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(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 4778520..047ae52 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1325,7 +1325,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,
@@ -1334,8 +1334,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);
@@ -1372,7 +1378,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);
@@ -1457,9 +1464,11 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net, u8, int dir, u32 id, int d
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);
-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_kmark *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);
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 2e692af..4392381 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -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 0
static 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,
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 7ed3e4a..987b47d 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -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",
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 1948895..14ca1f1 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -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",
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 83ed715..6290675 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -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);
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index c2f300c..5ac8902 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -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;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 668a46b..ee9b93b 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -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",
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index bb42f39..85cccd6 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -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);
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 9084582..2bc98ed 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -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;
diff --git a/net/key/af_key.c b/net/key/af_key.c
index a20d2fa..96598a9 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -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_kmark 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 *h
return -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;
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index e0009c1..45f1c98 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -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);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 9fa3322..5771008 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -669,7 +669,7 @@ xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl,
return 0;
}
-static struct xfrm_state *__xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family)
+static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark, xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family)
{
unsigned int h = xfrm_spi_hash(net, daddr, spi, proto, family);
struct xfrm_state *x;
@@ -689,7 +689,7 @@ static struct xfrm_state *__xfrm_state_lookup(struct net *net, xfrm_address_t *d
return NULL;
}
-static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family)
+static 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)
{
unsigned int h = xfrm_src_hash(net, daddr, saddr, family);
struct xfrm_state *x;
@@ -713,12 +713,14 @@ static inline struct xfrm_state *
__xfrm_state_locate(struct xfrm_state *x, int use_spi, int family)
{
struct net *net = xs_net(x);
+ u32 mark = x->mark.v & x->mark.m;
if (use_spi)
- return __xfrm_state_lookup(net, &x->id.daddr, x->id.spi,
- x->id.proto, family);
+ return __xfrm_state_lookup(net, mark, &x->id.daddr,
+ x->id.spi, x->id.proto, family);
else
- return __xfrm_state_lookup_byaddr(net, &x->id.daddr,
+ return __xfrm_state_lookup_byaddr(net, mark,
+ &x->id.daddr,
&x->props.saddr,
x->id.proto, family);
}
@@ -783,6 +785,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
int acquire_in_progress = 0;
int error = 0;
struct xfrm_state *best = NULL;
+ u32 mark = pol->mark.v & pol->mark.m;
to_put = NULL;
@@ -819,7 +822,7 @@ found:
x = best;
if (!x && !error && !acquire_in_progress) {
if (tmpl->id.spi &&
- (x0 = __xfrm_state_lookup(net, daddr, tmpl->id.spi,
+ (x0 = __xfrm_state_lookup(net, mark, daddr, tmpl->id.spi,
tmpl->id.proto, family)) != NULL) {
to_put = x0;
error = -EEXIST;
@@ -833,6 +836,7 @@ found:
/* Initialize temporary selector matching only
* to current session. */
xfrm_init_tempsel(x, fl, tmpl, daddr, saddr, family);
+ memcpy(&x->mark, &pol->mark, sizeof(x->mark));
error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid);
if (error) {
@@ -875,7 +879,7 @@ out:
}
struct xfrm_state *
-xfrm_stateonly_find(struct net *net,
+xfrm_stateonly_find(struct net *net, u32 mark,
xfrm_address_t *daddr, xfrm_address_t *saddr,
unsigned short family, u8 mode, u8 proto, u32 reqid)
{
@@ -971,7 +975,7 @@ void xfrm_state_insert(struct xfrm_state *x)
EXPORT_SYMBOL(xfrm_state_insert);
/* xfrm_state_lock is held */
-static struct xfrm_state *__find_acq_core(struct net *net, unsigned short family, u8 mode, u32 reqid, u8 proto, xfrm_address_t *daddr, xfrm_address_t *saddr, int create)
+static struct xfrm_state *__find_acq_core(struct net *net, struct xfrm_kmark *m, unsigned short family, u8 mode, u32 reqid, u8 proto, xfrm_address_t *daddr, xfrm_address_t *saddr, int create)
{
unsigned int h = xfrm_dst_hash(net, daddr, saddr, reqid, family);
struct hlist_node *entry;
@@ -1026,6 +1030,8 @@ static struct xfrm_state *__find_acq_core(struct net *net, unsigned short family
x->props.family = family;
x->props.mode = mode;
x->props.reqid = reqid;
+ x->mark.v = m->v;
+ x->mark.m = m->m;
x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires;
xfrm_state_hold(x);
tasklet_hrtimer_start(&x->mtimer, ktime_set(net->xfrm.sysctl_acq_expires, 0), HRTIMER_MODE_REL);
@@ -1042,7 +1048,7 @@ static struct xfrm_state *__find_acq_core(struct net *net, unsigned short family
return x;
}
-static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq);
+static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq);
int xfrm_state_add(struct xfrm_state *x)
{
@@ -1050,6 +1056,7 @@ int xfrm_state_add(struct xfrm_state *x)
struct xfrm_state *x1, *to_put;
int family;
int err;
+ u32 mark = x->mark.v & x->mark.m;
int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
family = x->props.family;
@@ -1067,7 +1074,7 @@ int xfrm_state_add(struct xfrm_state *x)
}
if (use_spi && x->km.seq) {
- x1 = __xfrm_find_acq_byseq(net, x->km.seq);
+ x1 = __xfrm_find_acq_byseq(net, mark, x->km.seq);
if (x1 && ((x1->id.proto != x->id.proto) ||
xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family))) {
to_put = x1;
@@ -1076,8 +1083,8 @@ int xfrm_state_add(struct xfrm_state *x)
}
if (use_spi && !x1)
- x1 = __find_acq_core(net, family, x->props.mode, x->props.reqid,
- x->id.proto,
+ x1 = __find_acq_core(net, &x->mark, family, x->props.mode,
+ x->props.reqid, x->id.proto,
&x->id.daddr, &x->props.saddr, 0);
__xfrm_state_bump_genids(x);
@@ -1151,6 +1158,8 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp)
goto error;
}
+ memcpy(&x->mark, &orig->mark, sizeof(x->mark));
+
err = xfrm_init_state(x);
if (err)
goto error;
@@ -1342,41 +1351,41 @@ int xfrm_state_check_expire(struct xfrm_state *x)
EXPORT_SYMBOL(xfrm_state_check_expire);
struct xfrm_state *
-xfrm_state_lookup(struct net *net, xfrm_address_t *daddr, __be32 spi, u8 proto,
- unsigned short family)
+xfrm_state_lookup(struct net *net, u32 mark, xfrm_address_t *daddr, __be32 spi,
+ u8 proto, unsigned short family)
{
struct xfrm_state *x;
spin_lock_bh(&xfrm_state_lock);
- x = __xfrm_state_lookup(net, daddr, spi, proto, family);
+ x = __xfrm_state_lookup(net, mark, daddr, spi, proto, family);
spin_unlock_bh(&xfrm_state_lock);
return x;
}
EXPORT_SYMBOL(xfrm_state_lookup);
struct xfrm_state *
-xfrm_state_lookup_byaddr(struct net *net,
+xfrm_state_lookup_byaddr(struct net *net, u32 mark,
xfrm_address_t *daddr, xfrm_address_t *saddr,
u8 proto, unsigned short family)
{
struct xfrm_state *x;
spin_lock_bh(&xfrm_state_lock);
- x = __xfrm_state_lookup_byaddr(net, daddr, saddr, proto, family);
+ x = __xfrm_state_lookup_byaddr(net, mark, daddr, saddr, proto, family);
spin_unlock_bh(&xfrm_state_lock);
return x;
}
EXPORT_SYMBOL(xfrm_state_lookup_byaddr);
struct xfrm_state *
-xfrm_find_acq(struct net *net, u8 mode, u32 reqid, u8 proto,
+xfrm_find_acq(struct net *net, struct xfrm_kmark *mark, u8 mode, u32 reqid, u8 proto,
xfrm_address_t *daddr, xfrm_address_t *saddr,
int create, unsigned short family)
{
struct xfrm_state *x;
spin_lock_bh(&xfrm_state_lock);
- x = __find_acq_core(net, family, mode, reqid, proto, daddr, saddr, create);
+ x = __find_acq_core(net, mark, family, mode, reqid, proto, daddr, saddr, create);
spin_unlock_bh(&xfrm_state_lock);
return x;
@@ -1423,7 +1432,7 @@ EXPORT_SYMBOL(xfrm_state_sort);
/* Silly enough, but I'm lazy to build resolution list */
-static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq)
+static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq)
{
int i;
@@ -1442,12 +1451,12 @@ static struct xfrm_state *__xfrm_find_acq_byseq(struct net *net, u32 seq)
return NULL;
}
-struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 seq)
+struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq)
{
struct xfrm_state *x;
spin_lock_bh(&xfrm_state_lock);
- x = __xfrm_find_acq_byseq(net, seq);
+ x = __xfrm_find_acq_byseq(net, mark, seq);
spin_unlock_bh(&xfrm_state_lock);
return x;
}
@@ -1474,6 +1483,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
int err = -ENOENT;
__be32 minspi = htonl(low);
__be32 maxspi = htonl(high);
+ u32 mark = x->mark.v & x->mark.m;
spin_lock_bh(&x->lock);
if (x->km.state == XFRM_STATE_DEAD)
@@ -1486,7 +1496,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
err = -ENOENT;
if (minspi == maxspi) {
- x0 = xfrm_state_lookup(net, &x->id.daddr, minspi, x->id.proto, x->props.family);
+ x0 = xfrm_state_lookup(net, mark, &x->id.daddr, minspi, x->id.proto, x->props.family);
if (x0) {
xfrm_state_put(x0);
goto unlock;
@@ -1496,7 +1506,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
u32 spi = 0;
for (h=0; h<high-low+1; h++) {
spi = low + net_random()%(high-low+1);
- x0 = xfrm_state_lookup(net, &x->id.daddr, htonl(spi), x->id.proto, x->props.family);
+ x0 = xfrm_state_lookup(net, mark, &x->id.daddr, htonl(spi), x->id.proto, x->props.family);
if (x0 == NULL) {
x->id.spi = htonl(spi);
break;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index ee04e6b..1054754 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -31,6 +31,9 @@
#include <linux/in6.h>
#endif
+#define DUMMY_MARK 0
+static struct xfrm_kmark 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)
--
1.6.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [net-next-2.6 PATCH 3/7] xfrm: SA lookups with mark
2010-02-20 20:55 ` [net-next-2.6 PATCH 2/7] xfrm: SA lookups signature with mark jamal
@ 2010-02-20 20:55 ` jamal
2010-02-20 20:55 ` [net-next-2.6 PATCH 4/7] xfrm: SP lookups signature " jamal
0 siblings, 1 reply; 12+ messages in thread
From: jamal @ 2010-02-20 20:55 UTC (permalink / raw)
To: davem, timo.teras; +Cc: kaber, herbert, netdev, Jamal Hadi Salim
From: Jamal Hadi Salim <hadi@cyberus.ca>
Allow mark to be added to the SA lookup
Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
---
net/xfrm/xfrm_state.c | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 5771008..1711a2b 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -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_kmark *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_kmark *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 s
hlist_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;
--
1.6.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [net-next-2.6 PATCH 4/7] xfrm: SP lookups signature with mark
2010-02-20 20:55 ` [net-next-2.6 PATCH 3/7] xfrm: SA lookups " jamal
@ 2010-02-20 20:55 ` jamal
2010-02-20 20:55 ` [net-next-2.6 PATCH 5/7] xfrm: SP lookups " jamal
0 siblings, 1 reply; 12+ messages in thread
From: jamal @ 2010-02-20 20:55 UTC (permalink / raw)
To: davem, timo.teras; +Cc: kaber, herbert, netdev, Jamal Hadi Salim
From: Jamal Hadi Salim <hadi@cyberus.ca>
pass mark to all SP lookups to prepare them for when we add code
to have them search.
Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
---
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(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 047ae52..81d376f 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1456,11 +1456,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);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 96598a9..627e14a 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2370,7 +2370,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
return 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 *h
return -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;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index d6eb16d..e67d3ca 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -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;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 1054754..1cb04ad 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -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)
--
1.6.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [net-next-2.6 PATCH 5/7] xfrm: SP lookups with mark
2010-02-20 20:55 ` [net-next-2.6 PATCH 4/7] xfrm: SP lookups signature " jamal
@ 2010-02-20 20:55 ` jamal
2010-02-20 20:55 ` [net-next-2.6 PATCH 6/7] xfrm: Allow user space config of SAD mark jamal
0 siblings, 1 reply; 12+ messages in thread
From: jamal @ 2010-02-20 20:55 UTC (permalink / raw)
To: davem, timo.teras; +Cc: kaber, herbert, netdev, Jamal Hadi Salim
From: Jamal Hadi Salim <hadi@cyberus.ca>
Allow mark to be used when doing SP lookup
Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
---
net/xfrm/xfrm_policy.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index e67d3ca..2a6e646 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -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, struc
int 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;
}
--
1.6.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [net-next-2.6 PATCH 6/7] xfrm: Allow user space config of SAD mark
2010-02-20 20:55 ` [net-next-2.6 PATCH 5/7] xfrm: SP lookups " jamal
@ 2010-02-20 20:55 ` jamal
2010-02-20 20:55 ` [net-next-2.6 PATCH 7/7] xfrm: Allow user space manipulation of SPD mark jamal
0 siblings, 1 reply; 12+ messages in thread
From: jamal @ 2010-02-20 20:55 UTC (permalink / raw)
To: davem, timo.teras; +Cc: kaber, herbert, netdev, Jamal Hadi Salim
From: Jamal Hadi Salim <hadi@cyberus.ca>
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.
Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
---
net/xfrm/xfrm_user.c | 72 +++++++++++++++++++++++++++++++++++++++----------
1 files changed, 57 insertions(+), 15 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 1cb04ad..dbc4b68 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -32,7 +32,6 @@
#endif
#define DUMMY_MARK 0
-static struct xfrm_kmark 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_kmark 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 && copy_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_kmark 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_umark))
+ 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_eve
NLA_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_kmark 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_kmark 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_kmark 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_kmark 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_umark) },
};
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_umark));
}
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_eve
copy_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_umark));
}
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_umark))
+ nla_total_size(xfrm_user_sec_ctx_size(x->security))
+ userpolicy_type_attrsize();
}
--
1.6.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [net-next-2.6 PATCH 7/7] xfrm: Allow user space manipulation of SPD mark
2010-02-20 20:55 ` [net-next-2.6 PATCH 6/7] xfrm: Allow user space config of SAD mark jamal
@ 2010-02-20 20:55 ` jamal
0 siblings, 0 replies; 12+ messages in thread
From: jamal @ 2010-02-20 20:55 UTC (permalink / raw)
To: davem, timo.teras; +Cc: kaber, herbert, netdev, Jamal Hadi Salim
From: Jamal Hadi Salim <hadi@cyberus.ca>
Add ability for netlink userspace to manipulate the SPD
and manipulate the mark, retrieve it and get events with a defined
mark, etc.
Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
---
net/xfrm/xfrm_user.c | 31 +++++++++++++++++++++++++------
1 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index dbc4b68..8041793 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -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_us
if (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_kmark 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_kmark 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_umark))
+ 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_umark));
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;
--
1.6.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [net-next-2.6 PATCH 1/7] xfrm: introduce basic mark infrastructure
2010-02-20 20:55 ` [net-next-2.6 PATCH 1/7] xfrm: introduce basic mark infrastructure jamal
2010-02-20 20:55 ` [net-next-2.6 PATCH 2/7] xfrm: SA lookups signature with mark jamal
@ 2010-02-22 6:26 ` David Miller
2010-02-22 14:09 ` jamal
1 sibling, 1 reply; 12+ messages in thread
From: David Miller @ 2010-02-22 6:26 UTC (permalink / raw)
To: hadi; +Cc: timo.teras, kaber, herbert, netdev
From: jamal <hadi@cyberus.ca>
Date: Sat, 20 Feb 2010 15:55:34 -0500
> XFRMA_ALG_AUTH_TRUNC, /* struct xfrm_algo_auth */
> + XFRMA_MARK, /* u32 */
> __XFRMA_MAX
>
XFRM_MARK is "struct xfrm_*mask" not "u32".
> +struct xfrm_kmark {
> + u32 v; /* value */
> + u32 m; /* mask */
> +};
> +
You absolutely don't need this song and dance.
If the userspace attribute type equals the kernel one, you can just
define one "struct xfrm_mark" in linux/xfrm.h and use it universally.
This is how we handle this with other XFRM userspace visible
datastructures.
We only make seperate internal ones when they have to be different for
some reason, which is not true here.
Please respin your entire patch set once you've fixed this.
Thanks.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [net-next-2.6 PATCH 1/7] xfrm: introduce basic mark infrastructure
2010-02-22 6:26 ` [net-next-2.6 PATCH 1/7] xfrm: introduce basic mark infrastructure David Miller
@ 2010-02-22 14:09 ` jamal
0 siblings, 0 replies; 12+ messages in thread
From: jamal @ 2010-02-22 14:09 UTC (permalink / raw)
To: David Miller; +Cc: timo.teras, kaber, herbert, netdev
I will fix both and resubmit. Thanks for taking the time Dave.
cheers,
jamal
^ permalink raw reply [flat|nested] 12+ messages in thread
* [net-next-2.6 PATCH 3/7] xfrm: SA lookups with mark
2010-02-22 21:32 ` [net-next-2.6 PATCH 2/7] xfrm: SA lookups signature with mark jamal
@ 2010-02-22 21:32 ` jamal
0 siblings, 0 replies; 12+ messages in thread
From: jamal @ 2010-02-22 21:32 UTC (permalink / raw)
To: davem; +Cc: timo.teras, kaber, herbert, netdev, Jamal Hadi Salim
From: Jamal Hadi Salim <hadi@cyberus.ca>
Allow mark to be added to the SA lookup
Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
---
net/xfrm/xfrm_state.c | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 9f85303..17d5b96 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -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 s
hlist_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;
--
1.6.0.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2010-02-22 21:33 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <xfrm-mark-take2>
2010-02-20 20:55 ` [net-next-2.6 PATCH 0/7] xfrm by MARK jamal
2010-02-20 20:55 ` [net-next-2.6 PATCH 1/7] xfrm: introduce basic mark infrastructure jamal
2010-02-20 20:55 ` [net-next-2.6 PATCH 2/7] xfrm: SA lookups signature with mark jamal
2010-02-20 20:55 ` [net-next-2.6 PATCH 3/7] xfrm: SA lookups " jamal
2010-02-20 20:55 ` [net-next-2.6 PATCH 4/7] xfrm: SP lookups signature " jamal
2010-02-20 20:55 ` [net-next-2.6 PATCH 5/7] xfrm: SP lookups " jamal
2010-02-20 20:55 ` [net-next-2.6 PATCH 6/7] xfrm: Allow user space config of SAD mark jamal
2010-02-20 20:55 ` [net-next-2.6 PATCH 7/7] xfrm: Allow user space manipulation of SPD mark jamal
2010-02-22 6:26 ` [net-next-2.6 PATCH 1/7] xfrm: introduce basic mark infrastructure David Miller
2010-02-22 14:09 ` jamal
[not found] <xfrm-mark-v3>
2010-02-22 21:32 ` [net-next-2.6 PATCH 0/7] xfrm by MARK jamal
2010-02-22 21:32 ` [net-next-2.6 PATCH 1/7] xfrm: introduce basic mark infrastructure jamal
2010-02-22 21:32 ` [net-next-2.6 PATCH 2/7] xfrm: SA lookups signature with mark jamal
2010-02-22 21:32 ` [net-next-2.6 PATCH 3/7] xfrm: SA lookups " jamal
[not found] <xfrm-mark-net-next>
2010-02-14 15:18 ` [net-next-2.6 PATCH 0/7] xfrm by MARK jamal
2010-02-14 15:18 ` [net-next-2.6 PATCH 1/7] xfrm: introduce basic mark infrastructure jamal
2010-02-14 15:18 ` [net-next-2.6 PATCH 2/7] xfrm: SA lookups signature with mark jamal
2010-02-14 15:18 ` [net-next-2.6 PATCH 3/7] xfrm: SA lookups " jamal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).