extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);
 extern int xfrm_state_delete(struct xfrm_state *x);
-extern void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info);
+extern int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info);
 extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si);
 extern void xfrm_spd_getinfo(struct xfrmk_spdinfo *si);
 extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq);
                                          struct xfrm_sec_ctx *ctx, int delete,
                                          int *err);
 struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err);
-void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
+int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
 u32 xfrm_get_acqseq(void);
 void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi);
 struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto,
                                  xfrm_address_t *daddr, xfrm_address_t *saddr,
                                  int create, unsigned short family);
-extern void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
+extern int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
 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);
 
        unsigned proto;
        struct km_event c;
        struct xfrm_audit audit_info;
+       int err;
 
        proto = pfkey_satype2proto(hdr->sadb_msg_satype);
        if (proto == 0)
 
        audit_info.loginuid = audit_get_loginuid(current->audit_context);
        audit_info.secid = 0;
-       xfrm_state_flush(proto, &audit_info);
+       err = xfrm_state_flush(proto, &audit_info);
+       if (err)
+               return err;
        c.data.proto = proto;
        c.seq = hdr->sadb_msg_seq;
        c.pid = hdr->sadb_msg_pid;
 {
        struct km_event c;
        struct xfrm_audit audit_info;
+       int err;
 
        audit_info.loginuid = audit_get_loginuid(current->audit_context);
        audit_info.secid = 0;
-       xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info);
+       err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info);
+       if (err)
+               return err;
        c.data.type = XFRM_POLICY_TYPE_MAIN;
        c.event = XFRM_MSG_FLUSHPOLICY;
        c.pid = hdr->sadb_msg_pid;
 
 }
 EXPORT_SYMBOL(xfrm_policy_byid);
 
-void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+static inline int
+xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
 {
-       int dir;
+       int dir, err = 0;
+
+       for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
+               struct xfrm_policy *pol;
+               struct hlist_node *entry;
+               int i;
+
+               hlist_for_each_entry(pol, entry,
+                                    &xfrm_policy_inexact[dir], bydst) {
+                       if (pol->type != type)
+                               continue;
+                       err = security_xfrm_policy_delete(pol);
+                       if (err) {
+                               xfrm_audit_log(audit_info->loginuid,
+                                              audit_info->secid,
+                                              AUDIT_MAC_IPSEC_DELSPD, 0,
+                                              pol, NULL);
+                               return err;
+                       }
+                }
+               for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) {
+                       hlist_for_each_entry(pol, entry,
+                                            xfrm_policy_bydst[dir].table + i,
+                                            bydst) {
+                               if (pol->type != type)
+                                       continue;
+                               err = security_xfrm_policy_delete(pol);
+                               if (err) {
+                                       xfrm_audit_log(audit_info->loginuid,
+                                                      audit_info->secid,
+                                                      AUDIT_MAC_IPSEC_DELSPD,
+                                                      0, pol, NULL);
+                                       return err;
+                               }
+                       }
+               }
+       }
+       return err;
+}
+#else
+static inline int
+xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
+{
+       return 0;
+}
+#endif
+
+int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
+{
+       int dir, err = 0;
 
        write_lock_bh(&xfrm_policy_lock);
+
+       err = xfrm_policy_flush_secctx_check(type, audit_info);
+       if (err)
+               goto out;
+
        for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
                struct xfrm_policy *pol;
                struct hlist_node *entry;
                xfrm_policy_count[dir] -= killed;
        }
        atomic_inc(&flow_cache_genid);
+out:
        write_unlock_bh(&xfrm_policy_lock);
+       return err;
 }
 EXPORT_SYMBOL(xfrm_policy_flush);
 
 }
 EXPORT_SYMBOL(xfrm_migrate);
 #endif
-
 
 }
 EXPORT_SYMBOL(xfrm_state_delete);
 
-void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info)
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+static inline int
+xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
 {
-       int i;
-       int err = 0;
+       int i, err = 0;
+
+       for (i = 0; i <= xfrm_state_hmask; i++) {
+               struct hlist_node *entry;
+               struct xfrm_state *x;
+
+               hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) {
+                       if (xfrm_id_proto_match(x->id.proto, proto) &&
+                          (err = security_xfrm_state_delete(x)) != 0) {
+                               xfrm_audit_log(audit_info->loginuid,
+                                              audit_info->secid,
+                                              AUDIT_MAC_IPSEC_DELSA,
+                                               0, NULL, x);
+
+                               return err;
+                       }
+               }
+       }
+
+       return err;
+}
+#else
+static inline int
+xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info)
+{
+       return 0;
+}
+#endif
+
+int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info)
+{
+       int i, err = 0;
 
        spin_lock_bh(&xfrm_state_lock);
+       err = xfrm_state_flush_secctx_check(proto, audit_info);
+       if (err)
+               goto out;
+
        for (i = 0; i <= xfrm_state_hmask; i++) {
                struct hlist_node *entry;
                struct xfrm_state *x;
                        }
                }
        }
+       err = 0;
+
+out:
        spin_unlock_bh(&xfrm_state_lock);
        wake_up(&km_waitq);
+       return err;
 }
 EXPORT_SYMBOL(xfrm_state_flush);
 
 
        struct km_event c;
        struct xfrm_usersa_flush *p = NLMSG_DATA(nlh);
        struct xfrm_audit audit_info;
+       int err;
 
        audit_info.loginuid = NETLINK_CB(skb).loginuid;
        audit_info.secid = NETLINK_CB(skb).sid;
-       xfrm_state_flush(p->proto, &audit_info);
+       err = xfrm_state_flush(p->proto, &audit_info);
+       if (err)
+               return err;
        c.data.proto = p->proto;
        c.event = nlh->nlmsg_type;
        c.seq = nlh->nlmsg_seq;
 
        audit_info.loginuid = NETLINK_CB(skb).loginuid;
        audit_info.secid = NETLINK_CB(skb).sid;
-       xfrm_policy_flush(type, &audit_info);
+       err = xfrm_policy_flush(type, &audit_info);
+       if (err)
+               return err;
        c.data.type = type;
        c.event = nlh->nlmsg_type;
        c.seq = nlh->nlmsg_seq;