/* Security Association flags */
 #define SADB_SAFLAGS_PFS       1
+#define SADB_SAFLAGS_NOPMTUDISC        0x20000000
 #define SADB_SAFLAGS_DECAP_DSCP        0x40000000
 #define SADB_SAFLAGS_NOECN     0x80000000
 
 
        __u8                            flags;
 #define XFRM_STATE_NOECN       1
 #define XFRM_STATE_DECAP_DSCP  2
+#define XFRM_STATE_NOPMTUDISC  4
 };
 
 struct xfrm_usersa_id {
 
        struct dst_entry *dst = skb->dst;
        struct xfrm_state *x = dst->xfrm;
        struct iphdr *iph, *top_iph;
+       int flags;
 
        iph = skb->nh.iph;
        skb->h.ipiph = iph;
 
        /* DS disclosed */
        top_iph->tos = INET_ECN_encapsulate(iph->tos, iph->tos);
-       if (x->props.flags & XFRM_STATE_NOECN)
+
+       flags = x->props.flags;
+       if (flags & XFRM_STATE_NOECN)
                IP_ECN_clear(top_iph);
 
-       top_iph->frag_off = iph->frag_off & htons(IP_DF);
+       top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?
+               0 : (iph->frag_off & htons(IP_DF));
        if (!top_iph->frag_off)
                __ip_select_ident(top_iph, dst, 0);
 
 
  *
  */
 
+#include <net/ip.h>
 #include <net/xfrm.h>
 #include <linux/pfkeyv2.h>
 #include <linux/ipsec.h>
 
 static struct xfrm_state_afinfo xfrm4_state_afinfo;
 
+static int xfrm4_init_flags(struct xfrm_state *x)
+{
+       if (ipv4_config.no_pmtu_disc)
+               x->props.flags |= XFRM_STATE_NOPMTUDISC;
+       return 0;
+}
+
 static void
 __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
                     struct xfrm_tmpl *tmpl,
 static struct xfrm_state_afinfo xfrm4_state_afinfo = {
        .family                 = AF_INET,
        .lock                   = RW_LOCK_UNLOCKED,
+       .init_flags             = xfrm4_init_flags,
        .init_tempsel           = __xfrm4_init_tempsel,
        .state_lookup           = __xfrm4_state_lookup,
        .find_acq               = __xfrm4_find_acq,
 
                sa->sadb_sa_flags |= SADB_SAFLAGS_NOECN;
        if (x->props.flags & XFRM_STATE_DECAP_DSCP)
                sa->sadb_sa_flags |= SADB_SAFLAGS_DECAP_DSCP;
+       if (x->props.flags & XFRM_STATE_NOPMTUDISC)
+               sa->sadb_sa_flags |= SADB_SAFLAGS_NOPMTUDISC;
 
        /* hard time */
        if (hsc & 2) {
                x->props.flags |= XFRM_STATE_NOECN;
        if (sa->sadb_sa_flags & SADB_SAFLAGS_DECAP_DSCP)
                x->props.flags |= XFRM_STATE_DECAP_DSCP;
+       if (sa->sadb_sa_flags & SADB_SAFLAGS_NOPMTUDISC)
+               x->props.flags |= XFRM_STATE_NOPMTUDISC;
 
        lifetime = (struct sadb_lifetime*) ext_hdrs[SADB_EXT_LIFETIME_HARD-1];
        if (lifetime != NULL) {