void (*free) (const void *data);
        void *data;
 };
+#define NETLBL_SECATTR_NONE             0x00000000
+#define NETLBL_SECATTR_DOMAIN           0x00000001
+#define NETLBL_SECATTR_CACHE            0x00000002
+#define NETLBL_SECATTR_MLS_LVL          0x00000004
+#define NETLBL_SECATTR_MLS_CAT          0x00000008
 struct netlbl_lsm_secattr {
+       u32 flags;
+
        char *domain;
 
        u32 mls_lvl;
-       u32 mls_lvl_vld;
        unsigned char *mls_cat;
        size_t mls_cat_len;
 
  */
 static inline void netlbl_secattr_init(struct netlbl_lsm_secattr *secattr)
 {
-       memset(secattr, 0, sizeof(*secattr));
+       secattr->flags = 0;
+       secattr->domain = NULL;
+       secattr->mls_cat = NULL;
+       secattr->cache = NULL;
 }
 
 /**
 
                        entry->activity += 1;
                        atomic_inc(&entry->lsm_data->refcount);
                        secattr->cache = entry->lsm_data;
+                       secattr->flags |= NETLBL_SECATTR_CACHE;
                        if (prev_entry == NULL) {
                                spin_unlock_bh(&cipso_v4_cache[bkt].lock);
                                return 0;
                               unsigned char **buffer,
                               u32 *buffer_len)
 {
-       int ret_val = -EPERM;
+       int ret_val;
        unsigned char *buf = NULL;
        u32 buf_len;
        u32 level;
 
-       if (secattr->mls_cat) {
+       if ((secattr->flags & NETLBL_SECATTR_MLS_LVL) == 0)
+               return -EPERM;
+
+       if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
                buf = kzalloc(CIPSO_V4_HDR_LEN + 4 + CIPSO_V4_TAG1_CAT_LEN,
                              GFP_ATOMIC);
                if (buf == NULL)
                /* This will send packets using the "optimized" format when
                 * possibile as specified in  section 3.4.2.6 of the
                 * CIPSO draft. */
-               if (cipso_v4_rbm_optfmt && (ret_val > 0 && ret_val < 10))
-                       ret_val = 10;
-
-               buf_len = 4 + ret_val;
+               if (cipso_v4_rbm_optfmt && ret_val > 0 && ret_val <= 10)
+                       buf_len = 14;
+               else
+                       buf_len = 4 + ret_val;
        } else {
                buf = kzalloc(CIPSO_V4_HDR_LEN + 4, GFP_ATOMIC);
                if (buf == NULL)
        if (ret_val != 0)
                return ret_val;
        secattr->mls_lvl = level;
-       secattr->mls_lvl_vld = 1;
+       secattr->flags |= NETLBL_SECATTR_MLS_LVL;
 
        if (tag_len > 4) {
                switch (doi_def->type) {
                if (ret_val < 0) {
                        kfree(secattr->mls_cat);
                        return ret_val;
+               } else if (ret_val > 0) {
+                       secattr->mls_cat_len = ret_val;
+                       secattr->flags |= NETLBL_SECATTR_MLS_CAT;
                }
-               secattr->mls_cat_len = ret_val;
        }
 
        return 0;
 
        cache = kzalloc(sizeof(*cache), GFP_ATOMIC);
        if (cache == NULL)
                goto netlbl_cache_add_return;
-       secattr.cache->free = selinux_netlbl_cache_free;
-       secattr.cache->data = (void *)cache;
 
        cache->type = NETLBL_CACHE_T_MLS;
        if (ebitmap_cpy(&cache->data.mls_label.level[0].cat,
        cache->data.mls_label.level[0].sens = ctx->range.level[0].sens;
        cache->data.mls_label.level[1].sens = ctx->range.level[0].sens;
 
+       secattr.cache->free = selinux_netlbl_cache_free;
+       secattr.cache->data = (void *)cache;
+       secattr.flags = NETLBL_SECATTR_CACHE;
+
        netlbl_cache_add(skb, &secattr);
 
 netlbl_cache_add_return:
 
        POLICY_RDLOCK;
 
-       if (secattr->cache) {
+       if (secattr->flags & NETLBL_SECATTR_CACHE) {
                cache = NETLBL_CACHE(secattr->cache->data);
                switch (cache->type) {
                case NETLBL_CACHE_T_SID:
                default:
                        goto netlbl_secattr_to_sid_return;
                }
-       } else if (secattr->mls_lvl_vld) {
+       } else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) {
                ctx = sidtab_search(&sidtab, base_sid);
                if (ctx == NULL)
                        goto netlbl_secattr_to_sid_return;
                ctx_new.role = ctx->role;
                ctx_new.type = ctx->type;
                mls_import_lvl(&ctx_new, secattr->mls_lvl, secattr->mls_lvl);
-               if (secattr->mls_cat) {
+               if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
                        if (mls_import_cat(&ctx_new,
                                           secattr->mls_cat,
                                           secattr->mls_cat_len,
 
        netlbl_secattr_init(&secattr);
        rc = netlbl_skbuff_getattr(skb, &secattr);
-       if (rc == 0)
+       if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
                rc = selinux_netlbl_secattr_to_sid(skb,
                                                   &secattr,
                                                   base_sid,
                                                   sid);
+       else
+               *sid = SECSID_NULL;
        netlbl_secattr_destroy(&secattr);
 
        return rc;
        secattr.domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1],
                                 GFP_ATOMIC);
        mls_export_lvl(ctx, &secattr.mls_lvl, NULL);
-       secattr.mls_lvl_vld = 1;
        rc = mls_export_cat(ctx,
                            &secattr.mls_cat,
                            &secattr.mls_cat_len,
        if (rc != 0)
                goto netlbl_socket_setsid_return;
 
+       secattr.flags |= NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL;
+       if (secattr.mls_cat)
+               secattr.flags |= NETLBL_SECATTR_MLS_CAT;
+
        rc = netlbl_socket_setattr(sock, &secattr);
        if (rc == 0)
                sksec->nlbl_state = NLBL_LABELED;
 
        netlbl_secattr_init(&secattr);
        if (netlbl_sock_getattr(sk, &secattr) == 0 &&
+           secattr.flags != NETLBL_SECATTR_NONE &&
            selinux_netlbl_secattr_to_sid(NULL,
                                          &secattr,
                                          SECINITSID_UNLABELED,
            sksec->nlbl_state == NLBL_LABELED) {
                netlbl_secattr_init(&secattr);
                rc = netlbl_socket_getattr(sock, &secattr);
-               if (rc == 0 && (secattr.cache || secattr.mls_lvl_vld))
+               if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
                        rc = -EACCES;
                netlbl_secattr_destroy(&secattr);
        }