/* Security Association flags */
#define SADB_SAFLAGS_PFS 1
+#define SADB_SAFLAGS_DECAP_DSCP 0x40000000
#define SADB_SAFLAGS_NOECN 0x80000000
/* Security Association states */
__u8 replay_window;
__u8 flags;
#define XFRM_STATE_NOECN 1
+#define XFRM_STATE_DECAP_DSCP 2
};
struct xfrm_usersa_id {
iph->tos &= ~INET_ECN_MASK;
}
+static inline void ipv4_copy_dscp(struct iphdr *outer, struct iphdr *inner)
+{
+ u32 dscp = ipv4_get_dsfield(outer) & ~INET_ECN_MASK;
+ ipv4_change_dsfield(inner, INET_ECN_MASK, dscp);
+}
+
struct ipv6hdr;
static inline void IP6_ECN_set_ce(struct ipv6hdr *iph)
if (skb_cloned(skb) &&
pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
goto drop;
+ if (x->props.flags & XFRM_STATE_DECAP_DSCP)
+ ipv4_copy_dscp(iph, skb->h.ipiph);
if (!(x->props.flags & XFRM_STATE_NOECN))
ipip_ecn_decapsulate(skb);
skb->mac.raw = memmove(skb->data - skb->mac_len,
if (skb_cloned(skb) &&
pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
goto drop;
+ if (x->props.flags & XFRM_STATE_DECAP_DSCP)
+ ipv6_copy_dscp(skb->nh.ipv6h, skb->h.ipv6h);
if (!(x->props.flags & XFRM_STATE_NOECN))
ipip6_ecn_decapsulate(skb);
skb->mac.raw = memmove(skb->data - skb->mac_len,
sa->sadb_sa_flags = 0;
if (x->props.flags & XFRM_STATE_NOECN)
sa->sadb_sa_flags |= SADB_SAFLAGS_NOECN;
+ if (x->props.flags & XFRM_STATE_DECAP_DSCP)
+ sa->sadb_sa_flags |= SADB_SAFLAGS_DECAP_DSCP;
/* hard time */
if (hsc & 2) {
x->props.replay_window = sa->sadb_sa_replay;
if (sa->sadb_sa_flags & SADB_SAFLAGS_NOECN)
x->props.flags |= XFRM_STATE_NOECN;
+ if (sa->sadb_sa_flags & SADB_SAFLAGS_DECAP_DSCP)
+ x->props.flags |= XFRM_STATE_DECAP_DSCP;
lifetime = (struct sadb_lifetime*) ext_hdrs[SADB_EXT_LIFETIME_HARD-1];
if (lifetime != NULL) {