Re: [PATCH RFC ipsec-next] xfrm: Extend the output_mark to support input direction and masking.

2018-06-25 Thread Steffen Klassert
On Fri, Jun 15, 2018 at 08:55:14AM +0200, Steffen Klassert wrote:
> We already support setting an output mark at the xfrm_state,
> unfortunately this does not support the input direction and
> masking the marks that will be applied to the skb. This change
> adds support applying a masked value in both directions.
> 
> The existing XFRMA_OUTPUT_MARK number is reused for this purpose
> and as it is now bi-directional, it is renamed to XFRMA_SET_MARK.
> 
> An additional XFRMA_SET_MARK_MASK attribute is added for setting the
> mask. If the attribute mask not provided, it is set to 0x,
> keeping the XFRMA_OUTPUT_MARK existing 'full mask' semantics.
> 
> Co-developed-by: Tobias Brunner 
> Co-developed-by: Eyal Birger 
> Co-developed-by: Lorenzo Colitti 
> Signed-off-by: Steffen Klassert 
> Signed-off-by: Tobias Brunner 
> Signed-off-by: Eyal Birger 
> Signed-off-by: Lorenzo Colitti 

This is now applied to ipsec-next.


[PATCH RFC ipsec-next] xfrm: Extend the output_mark to support input direction and masking.

2018-06-14 Thread Steffen Klassert
We already support setting an output mark at the xfrm_state,
unfortunately this does not support the input direction and
masking the marks that will be applied to the skb. This change
adds support applying a masked value in both directions.

The existing XFRMA_OUTPUT_MARK number is reused for this purpose
and as it is now bi-directional, it is renamed to XFRMA_SET_MARK.

An additional XFRMA_SET_MARK_MASK attribute is added for setting the
mask. If the attribute mask not provided, it is set to 0x,
keeping the XFRMA_OUTPUT_MARK existing 'full mask' semantics.

Co-developed-by: Tobias Brunner 
Co-developed-by: Eyal Birger 
Co-developed-by: Lorenzo Colitti 
Signed-off-by: Steffen Klassert 
Signed-off-by: Tobias Brunner 
Signed-off-by: Eyal Birger 
Signed-off-by: Lorenzo Colitti 
---
 include/net/xfrm.h|  9 -
 include/uapi/linux/xfrm.h |  4 +++-
 net/xfrm/xfrm_input.c |  2 ++
 net/xfrm/xfrm_output.c|  3 +--
 net/xfrm/xfrm_policy.c|  5 +++--
 net/xfrm/xfrm_user.c  | 48 +--
 6 files changed, 55 insertions(+), 16 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 45e75c36b738..8727b2484855 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -166,7 +166,7 @@ struct xfrm_state {
int header_len;
int trailer_len;
u32 extra_flags;
-   u32 output_mark;
+   struct xfrm_marksmark;
} props;
 
struct xfrm_lifetime_cfg lft;
@@ -2012,6 +2012,13 @@ static inline int xfrm_mark_put(struct sk_buff *skb, 
const struct xfrm_mark *m)
return ret;
 }
 
+static inline __u32 xfrm_smark_get(__u32 mark, struct xfrm_state *x)
+{
+   struct xfrm_mark *m = &x->props.smark;
+
+   return (m->v & m->m) | (mark & ~m->m);
+}
+
 static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x,
unsigned int family)
 {
diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h
index e3af2859188b..5a6ed7ce5a29 100644
--- a/include/uapi/linux/xfrm.h
+++ b/include/uapi/linux/xfrm.h
@@ -305,9 +305,11 @@ enum xfrm_attr_type_t {
XFRMA_ADDRESS_FILTER,   /* struct xfrm_address_filter */
XFRMA_PAD,
XFRMA_OFFLOAD_DEV,  /* struct xfrm_state_offload */
-   XFRMA_OUTPUT_MARK,  /* __u32 */
+   XFRMA_SET_MARK, /* __u32 */
+   XFRMA_SET_MARK_MASK,/* __u32 */
__XFRMA_MAX
 
+#define XFRMA_OUTPUT_MARK XFRMA_SET_MARK   /* Compatibility */
 #define XFRMA_MAX (__XFRMA_MAX - 1)
 };
 
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 352abca2605f..074810436242 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -339,6 +339,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 
spi, int encap_type)
goto drop;
}
 
+   skb->mark = xfrm_smark_get(skb->mark, x);
+
skb->sp->xvec[skb->sp->len++] = x;
 
 lock:
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 89b178a78dc7..45ba07ab3e4f 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -66,8 +66,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
goto error_nolock;
}
 
-   if (x->props.output_mark)
-   skb->mark = x->props.output_mark;
+   skb->mark = xfrm_smark_get(skb->mark, x);
 
err = x->outer_mode->output(x, skb);
if (err) {
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 40b54cc64243..f95f5f75748c 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1607,10 +1607,11 @@ static struct dst_entry *xfrm_bundle_create(struct 
xfrm_policy *policy,
dst_copy_metrics(dst1, dst);
 
if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
+   __u32 mark = xfrm_smark_get(fl->flowi_mark, xfrm[i]);
+
family = xfrm[i]->props.family;
dst = xfrm_dst_lookup(xfrm[i], tos, fl->flowi_oif,
- &saddr, &daddr, family,
- xfrm[i]->props.output_mark);
+ &saddr, &daddr, family, mark);
err = PTR_ERR(dst);
if (IS_ERR(dst))
goto put_states;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 080035f056d9..9602cc9e05ab 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -527,6 +527,19 @@ static void xfrm_update_ae_params(struct xfrm_state *x, 
struct nlattr **attrs,
x->replay_maxdiff = nla_get_u32(rt);
 }
 
+static void xfrm_smark_init(struct nlattr **attrs, struct xfrm_mark *m)
+{
+   if (attrs[XFRMA_SET_MARK]) {
+   m-