xref: /linux/net/ipv4/cipso_ipv4.c (revision c537b994505099b7197e7d3125b942ecbcc51eb6)
1 /*
2  * CIPSO - Commercial IP Security Option
3  *
4  * This is an implementation of the CIPSO 2.2 protocol as specified in
5  * draft-ietf-cipso-ipsecurity-01.txt with additional tag types as found in
6  * FIPS-188, copies of both documents can be found in the Documentation
7  * directory.  While CIPSO never became a full IETF RFC standard many vendors
8  * have chosen to adopt the protocol and over the years it has become a
9  * de-facto standard for labeled networking.
10  *
11  * Author: Paul Moore <paul.moore@hp.com>
12  *
13  */
14 
15 /*
16  * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
17  *
18  * This program is free software;  you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 2 of the License, or
21  * (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY;  without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
26  * the GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program;  if not, write to the Free Software
30  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31  *
32  */
33 
34 #include <linux/init.h>
35 #include <linux/types.h>
36 #include <linux/rcupdate.h>
37 #include <linux/list.h>
38 #include <linux/spinlock.h>
39 #include <linux/string.h>
40 #include <linux/jhash.h>
41 #include <net/ip.h>
42 #include <net/icmp.h>
43 #include <net/tcp.h>
44 #include <net/netlabel.h>
45 #include <net/cipso_ipv4.h>
46 #include <asm/atomic.h>
47 #include <asm/bug.h>
48 
49 struct cipso_v4_domhsh_entry {
50 	char *domain;
51 	u32 valid;
52 	struct list_head list;
53 	struct rcu_head rcu;
54 };
55 
56 /* List of available DOI definitions */
57 /* XXX - Updates should be minimal so having a single lock for the
58  * cipso_v4_doi_list and the cipso_v4_doi_list->dom_list should be
59  * okay. */
60 /* XXX - This currently assumes a minimal number of different DOIs in use,
61  * if in practice there are a lot of different DOIs this list should
62  * probably be turned into a hash table or something similar so we
63  * can do quick lookups. */
64 static DEFINE_SPINLOCK(cipso_v4_doi_list_lock);
65 static struct list_head cipso_v4_doi_list = LIST_HEAD_INIT(cipso_v4_doi_list);
66 
67 /* Label mapping cache */
68 int cipso_v4_cache_enabled = 1;
69 int cipso_v4_cache_bucketsize = 10;
70 #define CIPSO_V4_CACHE_BUCKETBITS     7
71 #define CIPSO_V4_CACHE_BUCKETS        (1 << CIPSO_V4_CACHE_BUCKETBITS)
72 #define CIPSO_V4_CACHE_REORDERLIMIT   10
73 struct cipso_v4_map_cache_bkt {
74 	spinlock_t lock;
75 	u32 size;
76 	struct list_head list;
77 };
78 struct cipso_v4_map_cache_entry {
79 	u32 hash;
80 	unsigned char *key;
81 	size_t key_len;
82 
83 	struct netlbl_lsm_cache *lsm_data;
84 
85 	u32 activity;
86 	struct list_head list;
87 };
88 static struct cipso_v4_map_cache_bkt *cipso_v4_cache = NULL;
89 
90 /* Restricted bitmap (tag #1) flags */
91 int cipso_v4_rbm_optfmt = 0;
92 int cipso_v4_rbm_strictvalid = 1;
93 
94 /*
95  * Helper Functions
96  */
97 
98 /**
99  * cipso_v4_bitmap_walk - Walk a bitmap looking for a bit
100  * @bitmap: the bitmap
101  * @bitmap_len: length in bits
102  * @offset: starting offset
103  * @state: if non-zero, look for a set (1) bit else look for a cleared (0) bit
104  *
105  * Description:
106  * Starting at @offset, walk the bitmap from left to right until either the
107  * desired bit is found or we reach the end.  Return the bit offset, -1 if
108  * not found, or -2 if error.
109  */
110 static int cipso_v4_bitmap_walk(const unsigned char *bitmap,
111 				u32 bitmap_len,
112 				u32 offset,
113 				u8 state)
114 {
115 	u32 bit_spot;
116 	u32 byte_offset;
117 	unsigned char bitmask;
118 	unsigned char byte;
119 
120 	/* gcc always rounds to zero when doing integer division */
121 	byte_offset = offset / 8;
122 	byte = bitmap[byte_offset];
123 	bit_spot = offset;
124 	bitmask = 0x80 >> (offset % 8);
125 
126 	while (bit_spot < bitmap_len) {
127 		if ((state && (byte & bitmask) == bitmask) ||
128 		    (state == 0 && (byte & bitmask) == 0))
129 			return bit_spot;
130 
131 		bit_spot++;
132 		bitmask >>= 1;
133 		if (bitmask == 0) {
134 			byte = bitmap[++byte_offset];
135 			bitmask = 0x80;
136 		}
137 	}
138 
139 	return -1;
140 }
141 
142 /**
143  * cipso_v4_bitmap_setbit - Sets a single bit in a bitmap
144  * @bitmap: the bitmap
145  * @bit: the bit
146  * @state: if non-zero, set the bit (1) else clear the bit (0)
147  *
148  * Description:
149  * Set a single bit in the bitmask.  Returns zero on success, negative values
150  * on error.
151  */
152 static void cipso_v4_bitmap_setbit(unsigned char *bitmap,
153 				   u32 bit,
154 				   u8 state)
155 {
156 	u32 byte_spot;
157 	u8 bitmask;
158 
159 	/* gcc always rounds to zero when doing integer division */
160 	byte_spot = bit / 8;
161 	bitmask = 0x80 >> (bit % 8);
162 	if (state)
163 		bitmap[byte_spot] |= bitmask;
164 	else
165 		bitmap[byte_spot] &= ~bitmask;
166 }
167 
168 /**
169  * cipso_v4_doi_domhsh_free - Frees a domain list entry
170  * @entry: the entry's RCU field
171  *
172  * Description:
173  * This function is designed to be used as a callback to the call_rcu()
174  * function so that the memory allocated to a domain list entry can be released
175  * safely.
176  *
177  */
178 static void cipso_v4_doi_domhsh_free(struct rcu_head *entry)
179 {
180 	struct cipso_v4_domhsh_entry *ptr;
181 
182 	ptr = container_of(entry, struct cipso_v4_domhsh_entry, rcu);
183 	kfree(ptr->domain);
184 	kfree(ptr);
185 }
186 
187 /**
188  * cipso_v4_cache_entry_free - Frees a cache entry
189  * @entry: the entry to free
190  *
191  * Description:
192  * This function frees the memory associated with a cache entry including the
193  * LSM cache data if there are no longer any users, i.e. reference count == 0.
194  *
195  */
196 static void cipso_v4_cache_entry_free(struct cipso_v4_map_cache_entry *entry)
197 {
198 	if (entry->lsm_data)
199 		netlbl_secattr_cache_free(entry->lsm_data);
200 	kfree(entry->key);
201 	kfree(entry);
202 }
203 
204 /**
205  * cipso_v4_map_cache_hash - Hashing function for the CIPSO cache
206  * @key: the hash key
207  * @key_len: the length of the key in bytes
208  *
209  * Description:
210  * The CIPSO tag hashing function.  Returns a 32-bit hash value.
211  *
212  */
213 static u32 cipso_v4_map_cache_hash(const unsigned char *key, u32 key_len)
214 {
215 	return jhash(key, key_len, 0);
216 }
217 
218 /*
219  * Label Mapping Cache Functions
220  */
221 
222 /**
223  * cipso_v4_cache_init - Initialize the CIPSO cache
224  *
225  * Description:
226  * Initializes the CIPSO label mapping cache, this function should be called
227  * before any of the other functions defined in this file.  Returns zero on
228  * success, negative values on error.
229  *
230  */
231 static int cipso_v4_cache_init(void)
232 {
233 	u32 iter;
234 
235 	cipso_v4_cache = kcalloc(CIPSO_V4_CACHE_BUCKETS,
236 				 sizeof(struct cipso_v4_map_cache_bkt),
237 				 GFP_KERNEL);
238 	if (cipso_v4_cache == NULL)
239 		return -ENOMEM;
240 
241 	for (iter = 0; iter < CIPSO_V4_CACHE_BUCKETS; iter++) {
242 		spin_lock_init(&cipso_v4_cache[iter].lock);
243 		cipso_v4_cache[iter].size = 0;
244 		INIT_LIST_HEAD(&cipso_v4_cache[iter].list);
245 	}
246 
247 	return 0;
248 }
249 
250 /**
251  * cipso_v4_cache_invalidate - Invalidates the current CIPSO cache
252  *
253  * Description:
254  * Invalidates and frees any entries in the CIPSO cache.  Returns zero on
255  * success and negative values on failure.
256  *
257  */
258 void cipso_v4_cache_invalidate(void)
259 {
260 	struct cipso_v4_map_cache_entry *entry, *tmp_entry;
261 	u32 iter;
262 
263 	for (iter = 0; iter < CIPSO_V4_CACHE_BUCKETS; iter++) {
264 		spin_lock_bh(&cipso_v4_cache[iter].lock);
265 		list_for_each_entry_safe(entry,
266 					 tmp_entry,
267 					 &cipso_v4_cache[iter].list, list) {
268 			list_del(&entry->list);
269 			cipso_v4_cache_entry_free(entry);
270 		}
271 		cipso_v4_cache[iter].size = 0;
272 		spin_unlock_bh(&cipso_v4_cache[iter].lock);
273 	}
274 
275 	return;
276 }
277 
278 /**
279  * cipso_v4_cache_check - Check the CIPSO cache for a label mapping
280  * @key: the buffer to check
281  * @key_len: buffer length in bytes
282  * @secattr: the security attribute struct to use
283  *
284  * Description:
285  * This function checks the cache to see if a label mapping already exists for
286  * the given key.  If there is a match then the cache is adjusted and the
287  * @secattr struct is populated with the correct LSM security attributes.  The
288  * cache is adjusted in the following manner if the entry is not already the
289  * first in the cache bucket:
290  *
291  *  1. The cache entry's activity counter is incremented
292  *  2. The previous (higher ranking) entry's activity counter is decremented
293  *  3. If the difference between the two activity counters is geater than
294  *     CIPSO_V4_CACHE_REORDERLIMIT the two entries are swapped
295  *
296  * Returns zero on success, -ENOENT for a cache miss, and other negative values
297  * on error.
298  *
299  */
300 static int cipso_v4_cache_check(const unsigned char *key,
301 				u32 key_len,
302 				struct netlbl_lsm_secattr *secattr)
303 {
304 	u32 bkt;
305 	struct cipso_v4_map_cache_entry *entry;
306 	struct cipso_v4_map_cache_entry *prev_entry = NULL;
307 	u32 hash;
308 
309 	if (!cipso_v4_cache_enabled)
310 		return -ENOENT;
311 
312 	hash = cipso_v4_map_cache_hash(key, key_len);
313 	bkt = hash & (CIPSO_V4_CACHE_BUCKETBITS - 1);
314 	spin_lock_bh(&cipso_v4_cache[bkt].lock);
315 	list_for_each_entry(entry, &cipso_v4_cache[bkt].list, list) {
316 		if (entry->hash == hash &&
317 		    entry->key_len == key_len &&
318 		    memcmp(entry->key, key, key_len) == 0) {
319 			entry->activity += 1;
320 			atomic_inc(&entry->lsm_data->refcount);
321 			secattr->cache = entry->lsm_data;
322 			secattr->flags |= NETLBL_SECATTR_CACHE;
323 			if (prev_entry == NULL) {
324 				spin_unlock_bh(&cipso_v4_cache[bkt].lock);
325 				return 0;
326 			}
327 
328 			if (prev_entry->activity > 0)
329 				prev_entry->activity -= 1;
330 			if (entry->activity > prev_entry->activity &&
331 			    entry->activity - prev_entry->activity >
332 			    CIPSO_V4_CACHE_REORDERLIMIT) {
333 				__list_del(entry->list.prev, entry->list.next);
334 				__list_add(&entry->list,
335 					   prev_entry->list.prev,
336 					   &prev_entry->list);
337 			}
338 
339 			spin_unlock_bh(&cipso_v4_cache[bkt].lock);
340 			return 0;
341 		}
342 		prev_entry = entry;
343 	}
344 	spin_unlock_bh(&cipso_v4_cache[bkt].lock);
345 
346 	return -ENOENT;
347 }
348 
349 /**
350  * cipso_v4_cache_add - Add an entry to the CIPSO cache
351  * @skb: the packet
352  * @secattr: the packet's security attributes
353  *
354  * Description:
355  * Add a new entry into the CIPSO label mapping cache.  Add the new entry to
356  * head of the cache bucket's list, if the cache bucket is out of room remove
357  * the last entry in the list first.  It is important to note that there is
358  * currently no checking for duplicate keys.  Returns zero on success,
359  * negative values on failure.
360  *
361  */
362 int cipso_v4_cache_add(const struct sk_buff *skb,
363 		       const struct netlbl_lsm_secattr *secattr)
364 {
365 	int ret_val = -EPERM;
366 	u32 bkt;
367 	struct cipso_v4_map_cache_entry *entry = NULL;
368 	struct cipso_v4_map_cache_entry *old_entry = NULL;
369 	unsigned char *cipso_ptr;
370 	u32 cipso_ptr_len;
371 
372 	if (!cipso_v4_cache_enabled || cipso_v4_cache_bucketsize <= 0)
373 		return 0;
374 
375 	cipso_ptr = CIPSO_V4_OPTPTR(skb);
376 	cipso_ptr_len = cipso_ptr[1];
377 
378 	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
379 	if (entry == NULL)
380 		return -ENOMEM;
381 	entry->key = kmemdup(cipso_ptr, cipso_ptr_len, GFP_ATOMIC);
382 	if (entry->key == NULL) {
383 		ret_val = -ENOMEM;
384 		goto cache_add_failure;
385 	}
386 	entry->key_len = cipso_ptr_len;
387 	entry->hash = cipso_v4_map_cache_hash(cipso_ptr, cipso_ptr_len);
388 	atomic_inc(&secattr->cache->refcount);
389 	entry->lsm_data = secattr->cache;
390 
391 	bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETBITS - 1);
392 	spin_lock_bh(&cipso_v4_cache[bkt].lock);
393 	if (cipso_v4_cache[bkt].size < cipso_v4_cache_bucketsize) {
394 		list_add(&entry->list, &cipso_v4_cache[bkt].list);
395 		cipso_v4_cache[bkt].size += 1;
396 	} else {
397 		old_entry = list_entry(cipso_v4_cache[bkt].list.prev,
398 				       struct cipso_v4_map_cache_entry, list);
399 		list_del(&old_entry->list);
400 		list_add(&entry->list, &cipso_v4_cache[bkt].list);
401 		cipso_v4_cache_entry_free(old_entry);
402 	}
403 	spin_unlock_bh(&cipso_v4_cache[bkt].lock);
404 
405 	return 0;
406 
407 cache_add_failure:
408 	if (entry)
409 		cipso_v4_cache_entry_free(entry);
410 	return ret_val;
411 }
412 
413 /*
414  * DOI List Functions
415  */
416 
417 /**
418  * cipso_v4_doi_search - Searches for a DOI definition
419  * @doi: the DOI to search for
420  *
421  * Description:
422  * Search the DOI definition list for a DOI definition with a DOI value that
423  * matches @doi.  The caller is responsibile for calling rcu_read_[un]lock().
424  * Returns a pointer to the DOI definition on success and NULL on failure.
425  */
426 static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi)
427 {
428 	struct cipso_v4_doi *iter;
429 
430 	list_for_each_entry_rcu(iter, &cipso_v4_doi_list, list)
431 		if (iter->doi == doi && iter->valid)
432 			return iter;
433 	return NULL;
434 }
435 
436 /**
437  * cipso_v4_doi_add - Add a new DOI to the CIPSO protocol engine
438  * @doi_def: the DOI structure
439  *
440  * Description:
441  * The caller defines a new DOI for use by the CIPSO engine and calls this
442  * function to add it to the list of acceptable domains.  The caller must
443  * ensure that the mapping table specified in @doi_def->map meets all of the
444  * requirements of the mapping type (see cipso_ipv4.h for details).  Returns
445  * zero on success and non-zero on failure.
446  *
447  */
448 int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
449 {
450 	u32 iter;
451 
452 	if (doi_def == NULL || doi_def->doi == CIPSO_V4_DOI_UNKNOWN)
453 		return -EINVAL;
454 	for (iter = 0; iter < CIPSO_V4_TAG_MAXCNT; iter++) {
455 		switch (doi_def->tags[iter]) {
456 		case CIPSO_V4_TAG_RBITMAP:
457 			break;
458 		case CIPSO_V4_TAG_RANGE:
459 			if (doi_def->type != CIPSO_V4_MAP_PASS)
460 				return -EINVAL;
461 			break;
462 		case CIPSO_V4_TAG_INVALID:
463 			if (iter == 0)
464 				return -EINVAL;
465 			break;
466 		case CIPSO_V4_TAG_ENUM:
467 			if (doi_def->type != CIPSO_V4_MAP_PASS)
468 				return -EINVAL;
469 			break;
470 		default:
471 			return -EINVAL;
472 		}
473 	}
474 
475 	doi_def->valid = 1;
476 	INIT_RCU_HEAD(&doi_def->rcu);
477 	INIT_LIST_HEAD(&doi_def->dom_list);
478 
479 	rcu_read_lock();
480 	if (cipso_v4_doi_search(doi_def->doi) != NULL)
481 		goto doi_add_failure_rlock;
482 	spin_lock(&cipso_v4_doi_list_lock);
483 	if (cipso_v4_doi_search(doi_def->doi) != NULL)
484 		goto doi_add_failure_slock;
485 	list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list);
486 	spin_unlock(&cipso_v4_doi_list_lock);
487 	rcu_read_unlock();
488 
489 	return 0;
490 
491 doi_add_failure_slock:
492 	spin_unlock(&cipso_v4_doi_list_lock);
493 doi_add_failure_rlock:
494 	rcu_read_unlock();
495 	return -EEXIST;
496 }
497 
498 /**
499  * cipso_v4_doi_remove - Remove an existing DOI from the CIPSO protocol engine
500  * @doi: the DOI value
501  * @audit_secid: the LSM secid to use in the audit message
502  * @callback: the DOI cleanup/free callback
503  *
504  * Description:
505  * Removes a DOI definition from the CIPSO engine, @callback is called to
506  * free any memory.  The NetLabel routines will be called to release their own
507  * LSM domain mappings as well as our own domain list.  Returns zero on
508  * success and negative values on failure.
509  *
510  */
511 int cipso_v4_doi_remove(u32 doi,
512 			struct netlbl_audit *audit_info,
513 			void (*callback) (struct rcu_head * head))
514 {
515 	struct cipso_v4_doi *doi_def;
516 	struct cipso_v4_domhsh_entry *dom_iter;
517 
518 	rcu_read_lock();
519 	if (cipso_v4_doi_search(doi) != NULL) {
520 		spin_lock(&cipso_v4_doi_list_lock);
521 		doi_def = cipso_v4_doi_search(doi);
522 		if (doi_def == NULL) {
523 			spin_unlock(&cipso_v4_doi_list_lock);
524 			rcu_read_unlock();
525 			return -ENOENT;
526 		}
527 		doi_def->valid = 0;
528 		list_del_rcu(&doi_def->list);
529 		spin_unlock(&cipso_v4_doi_list_lock);
530 		list_for_each_entry_rcu(dom_iter, &doi_def->dom_list, list)
531 			if (dom_iter->valid)
532 				netlbl_domhsh_remove(dom_iter->domain,
533 						     audit_info);
534 		cipso_v4_cache_invalidate();
535 		rcu_read_unlock();
536 
537 		call_rcu(&doi_def->rcu, callback);
538 		return 0;
539 	}
540 	rcu_read_unlock();
541 
542 	return -ENOENT;
543 }
544 
545 /**
546  * cipso_v4_doi_getdef - Returns a pointer to a valid DOI definition
547  * @doi: the DOI value
548  *
549  * Description:
550  * Searches for a valid DOI definition and if one is found it is returned to
551  * the caller.  Otherwise NULL is returned.  The caller must ensure that
552  * rcu_read_lock() is held while accessing the returned definition.
553  *
554  */
555 struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi)
556 {
557 	return cipso_v4_doi_search(doi);
558 }
559 
560 /**
561  * cipso_v4_doi_walk - Iterate through the DOI definitions
562  * @skip_cnt: skip past this number of DOI definitions, updated
563  * @callback: callback for each DOI definition
564  * @cb_arg: argument for the callback function
565  *
566  * Description:
567  * Iterate over the DOI definition list, skipping the first @skip_cnt entries.
568  * For each entry call @callback, if @callback returns a negative value stop
569  * 'walking' through the list and return.  Updates the value in @skip_cnt upon
570  * return.  Returns zero on success, negative values on failure.
571  *
572  */
573 int cipso_v4_doi_walk(u32 *skip_cnt,
574 		     int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
575 		     void *cb_arg)
576 {
577 	int ret_val = -ENOENT;
578 	u32 doi_cnt = 0;
579 	struct cipso_v4_doi *iter_doi;
580 
581 	rcu_read_lock();
582 	list_for_each_entry_rcu(iter_doi, &cipso_v4_doi_list, list)
583 		if (iter_doi->valid) {
584 			if (doi_cnt++ < *skip_cnt)
585 				continue;
586 			ret_val = callback(iter_doi, cb_arg);
587 			if (ret_val < 0) {
588 				doi_cnt--;
589 				goto doi_walk_return;
590 			}
591 		}
592 
593 doi_walk_return:
594 	rcu_read_unlock();
595 	*skip_cnt = doi_cnt;
596 	return ret_val;
597 }
598 
599 /**
600  * cipso_v4_doi_domhsh_add - Adds a domain entry to a DOI definition
601  * @doi_def: the DOI definition
602  * @domain: the domain to add
603  *
604  * Description:
605  * Adds the @domain to the the DOI specified by @doi_def, this function
606  * should only be called by external functions (i.e. NetLabel).  This function
607  * does allocate memory.  Returns zero on success, negative values on failure.
608  *
609  */
610 int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain)
611 {
612 	struct cipso_v4_domhsh_entry *iter;
613 	struct cipso_v4_domhsh_entry *new_dom;
614 
615 	new_dom = kzalloc(sizeof(*new_dom), GFP_KERNEL);
616 	if (new_dom == NULL)
617 		return -ENOMEM;
618 	if (domain) {
619 		new_dom->domain = kstrdup(domain, GFP_KERNEL);
620 		if (new_dom->domain == NULL) {
621 			kfree(new_dom);
622 			return -ENOMEM;
623 		}
624 	}
625 	new_dom->valid = 1;
626 	INIT_RCU_HEAD(&new_dom->rcu);
627 
628 	rcu_read_lock();
629 	spin_lock(&cipso_v4_doi_list_lock);
630 	list_for_each_entry_rcu(iter, &doi_def->dom_list, list)
631 		if (iter->valid &&
632 		    ((domain != NULL && iter->domain != NULL &&
633 		      strcmp(iter->domain, domain) == 0) ||
634 		     (domain == NULL && iter->domain == NULL))) {
635 			spin_unlock(&cipso_v4_doi_list_lock);
636 			rcu_read_unlock();
637 			kfree(new_dom->domain);
638 			kfree(new_dom);
639 			return -EEXIST;
640 		}
641 	list_add_tail_rcu(&new_dom->list, &doi_def->dom_list);
642 	spin_unlock(&cipso_v4_doi_list_lock);
643 	rcu_read_unlock();
644 
645 	return 0;
646 }
647 
648 /**
649  * cipso_v4_doi_domhsh_remove - Removes a domain entry from a DOI definition
650  * @doi_def: the DOI definition
651  * @domain: the domain to remove
652  *
653  * Description:
654  * Removes the @domain from the DOI specified by @doi_def, this function
655  * should only be called by external functions (i.e. NetLabel).   Returns zero
656  * on success and negative values on error.
657  *
658  */
659 int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
660 			       const char *domain)
661 {
662 	struct cipso_v4_domhsh_entry *iter;
663 
664 	rcu_read_lock();
665 	spin_lock(&cipso_v4_doi_list_lock);
666 	list_for_each_entry_rcu(iter, &doi_def->dom_list, list)
667 		if (iter->valid &&
668 		    ((domain != NULL && iter->domain != NULL &&
669 		      strcmp(iter->domain, domain) == 0) ||
670 		     (domain == NULL && iter->domain == NULL))) {
671 			iter->valid = 0;
672 			list_del_rcu(&iter->list);
673 			spin_unlock(&cipso_v4_doi_list_lock);
674 			rcu_read_unlock();
675 			call_rcu(&iter->rcu, cipso_v4_doi_domhsh_free);
676 
677 			return 0;
678 		}
679 	spin_unlock(&cipso_v4_doi_list_lock);
680 	rcu_read_unlock();
681 
682 	return -ENOENT;
683 }
684 
685 /*
686  * Label Mapping Functions
687  */
688 
689 /**
690  * cipso_v4_map_lvl_valid - Checks to see if the given level is understood
691  * @doi_def: the DOI definition
692  * @level: the level to check
693  *
694  * Description:
695  * Checks the given level against the given DOI definition and returns a
696  * negative value if the level does not have a valid mapping and a zero value
697  * if the level is defined by the DOI.
698  *
699  */
700 static int cipso_v4_map_lvl_valid(const struct cipso_v4_doi *doi_def, u8 level)
701 {
702 	switch (doi_def->type) {
703 	case CIPSO_V4_MAP_PASS:
704 		return 0;
705 	case CIPSO_V4_MAP_STD:
706 		if (doi_def->map.std->lvl.cipso[level] < CIPSO_V4_INV_LVL)
707 			return 0;
708 		break;
709 	}
710 
711 	return -EFAULT;
712 }
713 
714 /**
715  * cipso_v4_map_lvl_hton - Perform a level mapping from the host to the network
716  * @doi_def: the DOI definition
717  * @host_lvl: the host MLS level
718  * @net_lvl: the network/CIPSO MLS level
719  *
720  * Description:
721  * Perform a label mapping to translate a local MLS level to the correct
722  * CIPSO level using the given DOI definition.  Returns zero on success,
723  * negative values otherwise.
724  *
725  */
726 static int cipso_v4_map_lvl_hton(const struct cipso_v4_doi *doi_def,
727 				 u32 host_lvl,
728 				 u32 *net_lvl)
729 {
730 	switch (doi_def->type) {
731 	case CIPSO_V4_MAP_PASS:
732 		*net_lvl = host_lvl;
733 		return 0;
734 	case CIPSO_V4_MAP_STD:
735 		if (host_lvl < doi_def->map.std->lvl.local_size &&
736 		    doi_def->map.std->lvl.local[host_lvl] < CIPSO_V4_INV_LVL) {
737 			*net_lvl = doi_def->map.std->lvl.local[host_lvl];
738 			return 0;
739 		}
740 		return -EPERM;
741 	}
742 
743 	return -EINVAL;
744 }
745 
746 /**
747  * cipso_v4_map_lvl_ntoh - Perform a level mapping from the network to the host
748  * @doi_def: the DOI definition
749  * @net_lvl: the network/CIPSO MLS level
750  * @host_lvl: the host MLS level
751  *
752  * Description:
753  * Perform a label mapping to translate a CIPSO level to the correct local MLS
754  * level using the given DOI definition.  Returns zero on success, negative
755  * values otherwise.
756  *
757  */
758 static int cipso_v4_map_lvl_ntoh(const struct cipso_v4_doi *doi_def,
759 				 u32 net_lvl,
760 				 u32 *host_lvl)
761 {
762 	struct cipso_v4_std_map_tbl *map_tbl;
763 
764 	switch (doi_def->type) {
765 	case CIPSO_V4_MAP_PASS:
766 		*host_lvl = net_lvl;
767 		return 0;
768 	case CIPSO_V4_MAP_STD:
769 		map_tbl = doi_def->map.std;
770 		if (net_lvl < map_tbl->lvl.cipso_size &&
771 		    map_tbl->lvl.cipso[net_lvl] < CIPSO_V4_INV_LVL) {
772 			*host_lvl = doi_def->map.std->lvl.cipso[net_lvl];
773 			return 0;
774 		}
775 		return -EPERM;
776 	}
777 
778 	return -EINVAL;
779 }
780 
781 /**
782  * cipso_v4_map_cat_rbm_valid - Checks to see if the category bitmap is valid
783  * @doi_def: the DOI definition
784  * @bitmap: category bitmap
785  * @bitmap_len: bitmap length in bytes
786  *
787  * Description:
788  * Checks the given category bitmap against the given DOI definition and
789  * returns a negative value if any of the categories in the bitmap do not have
790  * a valid mapping and a zero value if all of the categories are valid.
791  *
792  */
793 static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def,
794 				      const unsigned char *bitmap,
795 				      u32 bitmap_len)
796 {
797 	int cat = -1;
798 	u32 bitmap_len_bits = bitmap_len * 8;
799 	u32 cipso_cat_size;
800 	u32 *cipso_array;
801 
802 	switch (doi_def->type) {
803 	case CIPSO_V4_MAP_PASS:
804 		return 0;
805 	case CIPSO_V4_MAP_STD:
806 		cipso_cat_size = doi_def->map.std->cat.cipso_size;
807 		cipso_array = doi_def->map.std->cat.cipso;
808 		for (;;) {
809 			cat = cipso_v4_bitmap_walk(bitmap,
810 						   bitmap_len_bits,
811 						   cat + 1,
812 						   1);
813 			if (cat < 0)
814 				break;
815 			if (cat >= cipso_cat_size ||
816 			    cipso_array[cat] >= CIPSO_V4_INV_CAT)
817 				return -EFAULT;
818 		}
819 
820 		if (cat == -1)
821 			return 0;
822 		break;
823 	}
824 
825 	return -EFAULT;
826 }
827 
828 /**
829  * cipso_v4_map_cat_rbm_hton - Perform a category mapping from host to network
830  * @doi_def: the DOI definition
831  * @secattr: the security attributes
832  * @net_cat: the zero'd out category bitmap in network/CIPSO format
833  * @net_cat_len: the length of the CIPSO bitmap in bytes
834  *
835  * Description:
836  * Perform a label mapping to translate a local MLS category bitmap to the
837  * correct CIPSO bitmap using the given DOI definition.  Returns the minimum
838  * size in bytes of the network bitmap on success, negative values otherwise.
839  *
840  */
841 static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
842 				     const struct netlbl_lsm_secattr *secattr,
843 				     unsigned char *net_cat,
844 				     u32 net_cat_len)
845 {
846 	int host_spot = -1;
847 	u32 net_spot = CIPSO_V4_INV_CAT;
848 	u32 net_spot_max = 0;
849 	u32 net_clen_bits = net_cat_len * 8;
850 	u32 host_cat_size = 0;
851 	u32 *host_cat_array = NULL;
852 
853 	if (doi_def->type == CIPSO_V4_MAP_STD) {
854 		host_cat_size = doi_def->map.std->cat.local_size;
855 		host_cat_array = doi_def->map.std->cat.local;
856 	}
857 
858 	for (;;) {
859 		host_spot = netlbl_secattr_catmap_walk(secattr->mls_cat,
860 						       host_spot + 1);
861 		if (host_spot < 0)
862 			break;
863 
864 		switch (doi_def->type) {
865 		case CIPSO_V4_MAP_PASS:
866 			net_spot = host_spot;
867 			break;
868 		case CIPSO_V4_MAP_STD:
869 			if (host_spot >= host_cat_size)
870 				return -EPERM;
871 			net_spot = host_cat_array[host_spot];
872 			if (net_spot >= CIPSO_V4_INV_CAT)
873 				return -EPERM;
874 			break;
875 		}
876 		if (net_spot >= net_clen_bits)
877 			return -ENOSPC;
878 		cipso_v4_bitmap_setbit(net_cat, net_spot, 1);
879 
880 		if (net_spot > net_spot_max)
881 			net_spot_max = net_spot;
882 	}
883 
884 	if (++net_spot_max % 8)
885 		return net_spot_max / 8 + 1;
886 	return net_spot_max / 8;
887 }
888 
889 /**
890  * cipso_v4_map_cat_rbm_ntoh - Perform a category mapping from network to host
891  * @doi_def: the DOI definition
892  * @net_cat: the category bitmap in network/CIPSO format
893  * @net_cat_len: the length of the CIPSO bitmap in bytes
894  * @secattr: the security attributes
895  *
896  * Description:
897  * Perform a label mapping to translate a CIPSO bitmap to the correct local
898  * MLS category bitmap using the given DOI definition.  Returns zero on
899  * success, negative values on failure.
900  *
901  */
902 static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
903 				     const unsigned char *net_cat,
904 				     u32 net_cat_len,
905 				     struct netlbl_lsm_secattr *secattr)
906 {
907 	int ret_val;
908 	int net_spot = -1;
909 	u32 host_spot = CIPSO_V4_INV_CAT;
910 	u32 net_clen_bits = net_cat_len * 8;
911 	u32 net_cat_size = 0;
912 	u32 *net_cat_array = NULL;
913 
914 	if (doi_def->type == CIPSO_V4_MAP_STD) {
915 		net_cat_size = doi_def->map.std->cat.cipso_size;
916 		net_cat_array = doi_def->map.std->cat.cipso;
917 	}
918 
919 	for (;;) {
920 		net_spot = cipso_v4_bitmap_walk(net_cat,
921 						net_clen_bits,
922 						net_spot + 1,
923 						1);
924 		if (net_spot < 0) {
925 			if (net_spot == -2)
926 				return -EFAULT;
927 			return 0;
928 		}
929 
930 		switch (doi_def->type) {
931 		case CIPSO_V4_MAP_PASS:
932 			host_spot = net_spot;
933 			break;
934 		case CIPSO_V4_MAP_STD:
935 			if (net_spot >= net_cat_size)
936 				return -EPERM;
937 			host_spot = net_cat_array[net_spot];
938 			if (host_spot >= CIPSO_V4_INV_CAT)
939 				return -EPERM;
940 			break;
941 		}
942 		ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat,
943 						       host_spot,
944 						       GFP_ATOMIC);
945 		if (ret_val != 0)
946 			return ret_val;
947 	}
948 
949 	return -EINVAL;
950 }
951 
952 /**
953  * cipso_v4_map_cat_enum_valid - Checks to see if the categories are valid
954  * @doi_def: the DOI definition
955  * @enumcat: category list
956  * @enumcat_len: length of the category list in bytes
957  *
958  * Description:
959  * Checks the given categories against the given DOI definition and returns a
960  * negative value if any of the categories do not have a valid mapping and a
961  * zero value if all of the categories are valid.
962  *
963  */
964 static int cipso_v4_map_cat_enum_valid(const struct cipso_v4_doi *doi_def,
965 				       const unsigned char *enumcat,
966 				       u32 enumcat_len)
967 {
968 	u16 cat;
969 	int cat_prev = -1;
970 	u32 iter;
971 
972 	if (doi_def->type != CIPSO_V4_MAP_PASS || enumcat_len & 0x01)
973 		return -EFAULT;
974 
975 	for (iter = 0; iter < enumcat_len; iter += 2) {
976 		cat = ntohs(*((__be16 *)&enumcat[iter]));
977 		if (cat <= cat_prev)
978 			return -EFAULT;
979 		cat_prev = cat;
980 	}
981 
982 	return 0;
983 }
984 
985 /**
986  * cipso_v4_map_cat_enum_hton - Perform a category mapping from host to network
987  * @doi_def: the DOI definition
988  * @secattr: the security attributes
989  * @net_cat: the zero'd out category list in network/CIPSO format
990  * @net_cat_len: the length of the CIPSO category list in bytes
991  *
992  * Description:
993  * Perform a label mapping to translate a local MLS category bitmap to the
994  * correct CIPSO category list using the given DOI definition.   Returns the
995  * size in bytes of the network category bitmap on success, negative values
996  * otherwise.
997  *
998  */
999 static int cipso_v4_map_cat_enum_hton(const struct cipso_v4_doi *doi_def,
1000 				      const struct netlbl_lsm_secattr *secattr,
1001 				      unsigned char *net_cat,
1002 				      u32 net_cat_len)
1003 {
1004 	int cat = -1;
1005 	u32 cat_iter = 0;
1006 
1007 	for (;;) {
1008 		cat = netlbl_secattr_catmap_walk(secattr->mls_cat, cat + 1);
1009 		if (cat < 0)
1010 			break;
1011 		if ((cat_iter + 2) > net_cat_len)
1012 			return -ENOSPC;
1013 
1014 		*((__be16 *)&net_cat[cat_iter]) = htons(cat);
1015 		cat_iter += 2;
1016 	}
1017 
1018 	return cat_iter;
1019 }
1020 
1021 /**
1022  * cipso_v4_map_cat_enum_ntoh - Perform a category mapping from network to host
1023  * @doi_def: the DOI definition
1024  * @net_cat: the category list in network/CIPSO format
1025  * @net_cat_len: the length of the CIPSO bitmap in bytes
1026  * @secattr: the security attributes
1027  *
1028  * Description:
1029  * Perform a label mapping to translate a CIPSO category list to the correct
1030  * local MLS category bitmap using the given DOI definition.  Returns zero on
1031  * success, negative values on failure.
1032  *
1033  */
1034 static int cipso_v4_map_cat_enum_ntoh(const struct cipso_v4_doi *doi_def,
1035 				      const unsigned char *net_cat,
1036 				      u32 net_cat_len,
1037 				      struct netlbl_lsm_secattr *secattr)
1038 {
1039 	int ret_val;
1040 	u32 iter;
1041 
1042 	for (iter = 0; iter < net_cat_len; iter += 2) {
1043 		ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat,
1044 					    ntohs(*((__be16 *)&net_cat[iter])),
1045 					    GFP_ATOMIC);
1046 		if (ret_val != 0)
1047 			return ret_val;
1048 	}
1049 
1050 	return 0;
1051 }
1052 
1053 /**
1054  * cipso_v4_map_cat_rng_valid - Checks to see if the categories are valid
1055  * @doi_def: the DOI definition
1056  * @rngcat: category list
1057  * @rngcat_len: length of the category list in bytes
1058  *
1059  * Description:
1060  * Checks the given categories against the given DOI definition and returns a
1061  * negative value if any of the categories do not have a valid mapping and a
1062  * zero value if all of the categories are valid.
1063  *
1064  */
1065 static int cipso_v4_map_cat_rng_valid(const struct cipso_v4_doi *doi_def,
1066 				      const unsigned char *rngcat,
1067 				      u32 rngcat_len)
1068 {
1069 	u16 cat_high;
1070 	u16 cat_low;
1071 	u32 cat_prev = CIPSO_V4_MAX_REM_CATS + 1;
1072 	u32 iter;
1073 
1074 	if (doi_def->type != CIPSO_V4_MAP_PASS || rngcat_len & 0x01)
1075 		return -EFAULT;
1076 
1077 	for (iter = 0; iter < rngcat_len; iter += 4) {
1078 		cat_high = ntohs(*((__be16 *)&rngcat[iter]));
1079 		if ((iter + 4) <= rngcat_len)
1080 			cat_low = ntohs(*((__be16 *)&rngcat[iter + 2]));
1081 		else
1082 			cat_low = 0;
1083 
1084 		if (cat_high > cat_prev)
1085 			return -EFAULT;
1086 
1087 		cat_prev = cat_low;
1088 	}
1089 
1090 	return 0;
1091 }
1092 
1093 /**
1094  * cipso_v4_map_cat_rng_hton - Perform a category mapping from host to network
1095  * @doi_def: the DOI definition
1096  * @secattr: the security attributes
1097  * @net_cat: the zero'd out category list in network/CIPSO format
1098  * @net_cat_len: the length of the CIPSO category list in bytes
1099  *
1100  * Description:
1101  * Perform a label mapping to translate a local MLS category bitmap to the
1102  * correct CIPSO category list using the given DOI definition.   Returns the
1103  * size in bytes of the network category bitmap on success, negative values
1104  * otherwise.
1105  *
1106  */
1107 static int cipso_v4_map_cat_rng_hton(const struct cipso_v4_doi *doi_def,
1108 				     const struct netlbl_lsm_secattr *secattr,
1109 				     unsigned char *net_cat,
1110 				     u32 net_cat_len)
1111 {
1112 	/* The constant '16' is not random, it is the maximum number of
1113 	 * high/low category range pairs as permitted by the CIPSO draft based
1114 	 * on a maximum IPv4 header length of 60 bytes - the BUG_ON() assertion
1115 	 * does a sanity check to make sure we don't overflow the array. */
1116 	int iter = -1;
1117 	u16 array[16];
1118 	u32 array_cnt = 0;
1119 	u32 cat_size = 0;
1120 
1121 	BUG_ON(net_cat_len > 30);
1122 
1123 	for (;;) {
1124 		iter = netlbl_secattr_catmap_walk(secattr->mls_cat, iter + 1);
1125 		if (iter < 0)
1126 			break;
1127 		cat_size += (iter == 0 ? 0 : sizeof(u16));
1128 		if (cat_size > net_cat_len)
1129 			return -ENOSPC;
1130 		array[array_cnt++] = iter;
1131 
1132 		iter = netlbl_secattr_catmap_walk_rng(secattr->mls_cat, iter);
1133 		if (iter < 0)
1134 			return -EFAULT;
1135 		cat_size += sizeof(u16);
1136 		if (cat_size > net_cat_len)
1137 			return -ENOSPC;
1138 		array[array_cnt++] = iter;
1139 	}
1140 
1141 	for (iter = 0; array_cnt > 0;) {
1142 		*((__be16 *)&net_cat[iter]) = htons(array[--array_cnt]);
1143 		iter += 2;
1144 		array_cnt--;
1145 		if (array[array_cnt] != 0) {
1146 			*((__be16 *)&net_cat[iter]) = htons(array[array_cnt]);
1147 			iter += 2;
1148 		}
1149 	}
1150 
1151 	return cat_size;
1152 }
1153 
1154 /**
1155  * cipso_v4_map_cat_rng_ntoh - Perform a category mapping from network to host
1156  * @doi_def: the DOI definition
1157  * @net_cat: the category list in network/CIPSO format
1158  * @net_cat_len: the length of the CIPSO bitmap in bytes
1159  * @secattr: the security attributes
1160  *
1161  * Description:
1162  * Perform a label mapping to translate a CIPSO category list to the correct
1163  * local MLS category bitmap using the given DOI definition.  Returns zero on
1164  * success, negative values on failure.
1165  *
1166  */
1167 static int cipso_v4_map_cat_rng_ntoh(const struct cipso_v4_doi *doi_def,
1168 				     const unsigned char *net_cat,
1169 				     u32 net_cat_len,
1170 				     struct netlbl_lsm_secattr *secattr)
1171 {
1172 	int ret_val;
1173 	u32 net_iter;
1174 	u16 cat_low;
1175 	u16 cat_high;
1176 
1177 	for(net_iter = 0; net_iter < net_cat_len; net_iter += 4) {
1178 		cat_high = ntohs(*((__be16 *)&net_cat[net_iter]));
1179 		if ((net_iter + 4) <= net_cat_len)
1180 			cat_low = ntohs(*((__be16 *)&net_cat[net_iter + 2]));
1181 		else
1182 			cat_low = 0;
1183 
1184 		ret_val = netlbl_secattr_catmap_setrng(secattr->mls_cat,
1185 						       cat_low,
1186 						       cat_high,
1187 						       GFP_ATOMIC);
1188 		if (ret_val != 0)
1189 			return ret_val;
1190 	}
1191 
1192 	return 0;
1193 }
1194 
1195 /*
1196  * Protocol Handling Functions
1197  */
1198 
1199 #define CIPSO_V4_OPT_LEN_MAX          40
1200 #define CIPSO_V4_HDR_LEN              6
1201 
1202 /**
1203  * cipso_v4_gentag_hdr - Generate a CIPSO option header
1204  * @doi_def: the DOI definition
1205  * @len: the total tag length in bytes, not including this header
1206  * @buf: the CIPSO option buffer
1207  *
1208  * Description:
1209  * Write a CIPSO header into the beginning of @buffer.
1210  *
1211  */
1212 static void cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def,
1213 				unsigned char *buf,
1214 				u32 len)
1215 {
1216 	buf[0] = IPOPT_CIPSO;
1217 	buf[1] = CIPSO_V4_HDR_LEN + len;
1218 	*(__be32 *)&buf[2] = htonl(doi_def->doi);
1219 }
1220 
1221 /**
1222  * cipso_v4_gentag_rbm - Generate a CIPSO restricted bitmap tag (type #1)
1223  * @doi_def: the DOI definition
1224  * @secattr: the security attributes
1225  * @buffer: the option buffer
1226  * @buffer_len: length of buffer in bytes
1227  *
1228  * Description:
1229  * Generate a CIPSO option using the restricted bitmap tag, tag type #1.  The
1230  * actual buffer length may be larger than the indicated size due to
1231  * translation between host and network category bitmaps.  Returns the size of
1232  * the tag on success, negative values on failure.
1233  *
1234  */
1235 static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def,
1236 			       const struct netlbl_lsm_secattr *secattr,
1237 			       unsigned char *buffer,
1238 			       u32 buffer_len)
1239 {
1240 	int ret_val;
1241 	u32 tag_len;
1242 	u32 level;
1243 
1244 	if ((secattr->flags & NETLBL_SECATTR_MLS_LVL) == 0)
1245 		return -EPERM;
1246 
1247 	ret_val = cipso_v4_map_lvl_hton(doi_def, secattr->mls_lvl, &level);
1248 	if (ret_val != 0)
1249 		return ret_val;
1250 
1251 	if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
1252 		ret_val = cipso_v4_map_cat_rbm_hton(doi_def,
1253 						    secattr,
1254 						    &buffer[4],
1255 						    buffer_len - 4);
1256 		if (ret_val < 0)
1257 			return ret_val;
1258 
1259 		/* This will send packets using the "optimized" format when
1260 		 * possibile as specified in  section 3.4.2.6 of the
1261 		 * CIPSO draft. */
1262 		if (cipso_v4_rbm_optfmt && ret_val > 0 && ret_val <= 10)
1263 			tag_len = 14;
1264 		else
1265 			tag_len = 4 + ret_val;
1266 	} else
1267 		tag_len = 4;
1268 
1269 	buffer[0] = 0x01;
1270 	buffer[1] = tag_len;
1271 	buffer[3] = level;
1272 
1273 	return tag_len;
1274 }
1275 
1276 /**
1277  * cipso_v4_parsetag_rbm - Parse a CIPSO restricted bitmap tag
1278  * @doi_def: the DOI definition
1279  * @tag: the CIPSO tag
1280  * @secattr: the security attributes
1281  *
1282  * Description:
1283  * Parse a CIPSO restricted bitmap tag (tag type #1) and return the security
1284  * attributes in @secattr.  Return zero on success, negatives values on
1285  * failure.
1286  *
1287  */
1288 static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def,
1289 				 const unsigned char *tag,
1290 				 struct netlbl_lsm_secattr *secattr)
1291 {
1292 	int ret_val;
1293 	u8 tag_len = tag[1];
1294 	u32 level;
1295 
1296 	ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level);
1297 	if (ret_val != 0)
1298 		return ret_val;
1299 	secattr->mls_lvl = level;
1300 	secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1301 
1302 	if (tag_len > 4) {
1303 		secattr->mls_cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1304 		if (secattr->mls_cat == NULL)
1305 			return -ENOMEM;
1306 
1307 		ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def,
1308 						    &tag[4],
1309 						    tag_len - 4,
1310 						    secattr);
1311 		if (ret_val != 0) {
1312 			netlbl_secattr_catmap_free(secattr->mls_cat);
1313 			return ret_val;
1314 		}
1315 
1316 		secattr->flags |= NETLBL_SECATTR_MLS_CAT;
1317 	}
1318 
1319 	return 0;
1320 }
1321 
1322 /**
1323  * cipso_v4_gentag_enum - Generate a CIPSO enumerated tag (type #2)
1324  * @doi_def: the DOI definition
1325  * @secattr: the security attributes
1326  * @buffer: the option buffer
1327  * @buffer_len: length of buffer in bytes
1328  *
1329  * Description:
1330  * Generate a CIPSO option using the enumerated tag, tag type #2.  Returns the
1331  * size of the tag on success, negative values on failure.
1332  *
1333  */
1334 static int cipso_v4_gentag_enum(const struct cipso_v4_doi *doi_def,
1335 				const struct netlbl_lsm_secattr *secattr,
1336 				unsigned char *buffer,
1337 				u32 buffer_len)
1338 {
1339 	int ret_val;
1340 	u32 tag_len;
1341 	u32 level;
1342 
1343 	if (!(secattr->flags & NETLBL_SECATTR_MLS_LVL))
1344 		return -EPERM;
1345 
1346 	ret_val = cipso_v4_map_lvl_hton(doi_def, secattr->mls_lvl, &level);
1347 	if (ret_val != 0)
1348 		return ret_val;
1349 
1350 	if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
1351 		ret_val = cipso_v4_map_cat_enum_hton(doi_def,
1352 						     secattr,
1353 						     &buffer[4],
1354 						     buffer_len - 4);
1355 		if (ret_val < 0)
1356 			return ret_val;
1357 
1358 		tag_len = 4 + ret_val;
1359 	} else
1360 		tag_len = 4;
1361 
1362 	buffer[0] = 0x02;
1363 	buffer[1] = tag_len;
1364 	buffer[3] = level;
1365 
1366 	return tag_len;
1367 }
1368 
1369 /**
1370  * cipso_v4_parsetag_enum - Parse a CIPSO enumerated tag
1371  * @doi_def: the DOI definition
1372  * @tag: the CIPSO tag
1373  * @secattr: the security attributes
1374  *
1375  * Description:
1376  * Parse a CIPSO enumerated tag (tag type #2) and return the security
1377  * attributes in @secattr.  Return zero on success, negatives values on
1378  * failure.
1379  *
1380  */
1381 static int cipso_v4_parsetag_enum(const struct cipso_v4_doi *doi_def,
1382 				  const unsigned char *tag,
1383 				  struct netlbl_lsm_secattr *secattr)
1384 {
1385 	int ret_val;
1386 	u8 tag_len = tag[1];
1387 	u32 level;
1388 
1389 	ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level);
1390 	if (ret_val != 0)
1391 		return ret_val;
1392 	secattr->mls_lvl = level;
1393 	secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1394 
1395 	if (tag_len > 4) {
1396 		secattr->mls_cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1397 		if (secattr->mls_cat == NULL)
1398 			return -ENOMEM;
1399 
1400 		ret_val = cipso_v4_map_cat_enum_ntoh(doi_def,
1401 						     &tag[4],
1402 						     tag_len - 4,
1403 						     secattr);
1404 		if (ret_val != 0) {
1405 			netlbl_secattr_catmap_free(secattr->mls_cat);
1406 			return ret_val;
1407 		}
1408 
1409 		secattr->flags |= NETLBL_SECATTR_MLS_CAT;
1410 	}
1411 
1412 	return 0;
1413 }
1414 
1415 /**
1416  * cipso_v4_gentag_rng - Generate a CIPSO ranged tag (type #5)
1417  * @doi_def: the DOI definition
1418  * @secattr: the security attributes
1419  * @buffer: the option buffer
1420  * @buffer_len: length of buffer in bytes
1421  *
1422  * Description:
1423  * Generate a CIPSO option using the ranged tag, tag type #5.  Returns the
1424  * size of the tag on success, negative values on failure.
1425  *
1426  */
1427 static int cipso_v4_gentag_rng(const struct cipso_v4_doi *doi_def,
1428 			       const struct netlbl_lsm_secattr *secattr,
1429 			       unsigned char *buffer,
1430 			       u32 buffer_len)
1431 {
1432 	int ret_val;
1433 	u32 tag_len;
1434 	u32 level;
1435 
1436 	if (!(secattr->flags & NETLBL_SECATTR_MLS_LVL))
1437 		return -EPERM;
1438 
1439 	ret_val = cipso_v4_map_lvl_hton(doi_def, secattr->mls_lvl, &level);
1440 	if (ret_val != 0)
1441 		return ret_val;
1442 
1443 	if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
1444 		ret_val = cipso_v4_map_cat_rng_hton(doi_def,
1445 						    secattr,
1446 						    &buffer[4],
1447 						    buffer_len - 4);
1448 		if (ret_val < 0)
1449 			return ret_val;
1450 
1451 		tag_len = 4 + ret_val;
1452 	} else
1453 		tag_len = 4;
1454 
1455 	buffer[0] = 0x05;
1456 	buffer[1] = tag_len;
1457 	buffer[3] = level;
1458 
1459 	return tag_len;
1460 }
1461 
1462 /**
1463  * cipso_v4_parsetag_rng - Parse a CIPSO ranged tag
1464  * @doi_def: the DOI definition
1465  * @tag: the CIPSO tag
1466  * @secattr: the security attributes
1467  *
1468  * Description:
1469  * Parse a CIPSO ranged tag (tag type #5) and return the security attributes
1470  * in @secattr.  Return zero on success, negatives values on failure.
1471  *
1472  */
1473 static int cipso_v4_parsetag_rng(const struct cipso_v4_doi *doi_def,
1474 				 const unsigned char *tag,
1475 				 struct netlbl_lsm_secattr *secattr)
1476 {
1477 	int ret_val;
1478 	u8 tag_len = tag[1];
1479 	u32 level;
1480 
1481 	ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level);
1482 	if (ret_val != 0)
1483 		return ret_val;
1484 	secattr->mls_lvl = level;
1485 	secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1486 
1487 	if (tag_len > 4) {
1488 		secattr->mls_cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1489 		if (secattr->mls_cat == NULL)
1490 			return -ENOMEM;
1491 
1492 		ret_val = cipso_v4_map_cat_rng_ntoh(doi_def,
1493 						    &tag[4],
1494 						    tag_len - 4,
1495 						    secattr);
1496 		if (ret_val != 0) {
1497 			netlbl_secattr_catmap_free(secattr->mls_cat);
1498 			return ret_val;
1499 		}
1500 
1501 		secattr->flags |= NETLBL_SECATTR_MLS_CAT;
1502 	}
1503 
1504 	return 0;
1505 }
1506 
1507 /**
1508  * cipso_v4_validate - Validate a CIPSO option
1509  * @option: the start of the option, on error it is set to point to the error
1510  *
1511  * Description:
1512  * This routine is called to validate a CIPSO option, it checks all of the
1513  * fields to ensure that they are at least valid, see the draft snippet below
1514  * for details.  If the option is valid then a zero value is returned and
1515  * the value of @option is unchanged.  If the option is invalid then a
1516  * non-zero value is returned and @option is adjusted to point to the
1517  * offending portion of the option.  From the IETF draft ...
1518  *
1519  *  "If any field within the CIPSO options, such as the DOI identifier, is not
1520  *   recognized the IP datagram is discarded and an ICMP 'parameter problem'
1521  *   (type 12) is generated and returned.  The ICMP code field is set to 'bad
1522  *   parameter' (code 0) and the pointer is set to the start of the CIPSO field
1523  *   that is unrecognized."
1524  *
1525  */
1526 int cipso_v4_validate(unsigned char **option)
1527 {
1528 	unsigned char *opt = *option;
1529 	unsigned char *tag;
1530 	unsigned char opt_iter;
1531 	unsigned char err_offset = 0;
1532 	u8 opt_len;
1533 	u8 tag_len;
1534 	struct cipso_v4_doi *doi_def = NULL;
1535 	u32 tag_iter;
1536 
1537 	/* caller already checks for length values that are too large */
1538 	opt_len = opt[1];
1539 	if (opt_len < 8) {
1540 		err_offset = 1;
1541 		goto validate_return;
1542 	}
1543 
1544 	rcu_read_lock();
1545 	doi_def = cipso_v4_doi_search(ntohl(*((__be32 *)&opt[2])));
1546 	if (doi_def == NULL) {
1547 		err_offset = 2;
1548 		goto validate_return_locked;
1549 	}
1550 
1551 	opt_iter = 6;
1552 	tag = opt + opt_iter;
1553 	while (opt_iter < opt_len) {
1554 		for (tag_iter = 0; doi_def->tags[tag_iter] != tag[0];)
1555 			if (doi_def->tags[tag_iter] == CIPSO_V4_TAG_INVALID ||
1556 			    ++tag_iter == CIPSO_V4_TAG_MAXCNT) {
1557 				err_offset = opt_iter;
1558 				goto validate_return_locked;
1559 			}
1560 
1561 		tag_len = tag[1];
1562 		if (tag_len > (opt_len - opt_iter)) {
1563 			err_offset = opt_iter + 1;
1564 			goto validate_return_locked;
1565 		}
1566 
1567 		switch (tag[0]) {
1568 		case CIPSO_V4_TAG_RBITMAP:
1569 			if (tag_len < 4) {
1570 				err_offset = opt_iter + 1;
1571 				goto validate_return_locked;
1572 			}
1573 
1574 			/* We are already going to do all the verification
1575 			 * necessary at the socket layer so from our point of
1576 			 * view it is safe to turn these checks off (and less
1577 			 * work), however, the CIPSO draft says we should do
1578 			 * all the CIPSO validations here but it doesn't
1579 			 * really specify _exactly_ what we need to validate
1580 			 * ... so, just make it a sysctl tunable. */
1581 			if (cipso_v4_rbm_strictvalid) {
1582 				if (cipso_v4_map_lvl_valid(doi_def,
1583 							   tag[3]) < 0) {
1584 					err_offset = opt_iter + 3;
1585 					goto validate_return_locked;
1586 				}
1587 				if (tag_len > 4 &&
1588 				    cipso_v4_map_cat_rbm_valid(doi_def,
1589 							    &tag[4],
1590 							    tag_len - 4) < 0) {
1591 					err_offset = opt_iter + 4;
1592 					goto validate_return_locked;
1593 				}
1594 			}
1595 			break;
1596 		case CIPSO_V4_TAG_ENUM:
1597 			if (tag_len < 4) {
1598 				err_offset = opt_iter + 1;
1599 				goto validate_return_locked;
1600 			}
1601 
1602 			if (cipso_v4_map_lvl_valid(doi_def,
1603 						   tag[3]) < 0) {
1604 				err_offset = opt_iter + 3;
1605 				goto validate_return_locked;
1606 			}
1607 			if (tag_len > 4 &&
1608 			    cipso_v4_map_cat_enum_valid(doi_def,
1609 							&tag[4],
1610 							tag_len - 4) < 0) {
1611 				err_offset = opt_iter + 4;
1612 				goto validate_return_locked;
1613 			}
1614 			break;
1615 		case CIPSO_V4_TAG_RANGE:
1616 			if (tag_len < 4) {
1617 				err_offset = opt_iter + 1;
1618 				goto validate_return_locked;
1619 			}
1620 
1621 			if (cipso_v4_map_lvl_valid(doi_def,
1622 						   tag[3]) < 0) {
1623 				err_offset = opt_iter + 3;
1624 				goto validate_return_locked;
1625 			}
1626 			if (tag_len > 4 &&
1627 			    cipso_v4_map_cat_rng_valid(doi_def,
1628 						       &tag[4],
1629 						       tag_len - 4) < 0) {
1630 				err_offset = opt_iter + 4;
1631 				goto validate_return_locked;
1632 			}
1633 			break;
1634 		default:
1635 			err_offset = opt_iter;
1636 			goto validate_return_locked;
1637 		}
1638 
1639 		tag += tag_len;
1640 		opt_iter += tag_len;
1641 	}
1642 
1643 validate_return_locked:
1644 	rcu_read_unlock();
1645 validate_return:
1646 	*option = opt + err_offset;
1647 	return err_offset;
1648 }
1649 
1650 /**
1651  * cipso_v4_error - Send the correct reponse for a bad packet
1652  * @skb: the packet
1653  * @error: the error code
1654  * @gateway: CIPSO gateway flag
1655  *
1656  * Description:
1657  * Based on the error code given in @error, send an ICMP error message back to
1658  * the originating host.  From the IETF draft ...
1659  *
1660  *  "If the contents of the CIPSO [option] are valid but the security label is
1661  *   outside of the configured host or port label range, the datagram is
1662  *   discarded and an ICMP 'destination unreachable' (type 3) is generated and
1663  *   returned.  The code field of the ICMP is set to 'communication with
1664  *   destination network administratively prohibited' (code 9) or to
1665  *   'communication with destination host administratively prohibited'
1666  *   (code 10).  The value of the code is dependent on whether the originator
1667  *   of the ICMP message is acting as a CIPSO host or a CIPSO gateway.  The
1668  *   recipient of the ICMP message MUST be able to handle either value.  The
1669  *   same procedure is performed if a CIPSO [option] can not be added to an
1670  *   IP packet because it is too large to fit in the IP options area."
1671  *
1672  *  "If the error is triggered by receipt of an ICMP message, the message is
1673  *   discarded and no response is permitted (consistent with general ICMP
1674  *   processing rules)."
1675  *
1676  */
1677 void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway)
1678 {
1679 	if (skb->nh.iph->protocol == IPPROTO_ICMP || error != -EACCES)
1680 		return;
1681 
1682 	if (gateway)
1683 		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_ANO, 0);
1684 	else
1685 		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_ANO, 0);
1686 }
1687 
1688 /**
1689  * cipso_v4_socket_setattr - Add a CIPSO option to a socket
1690  * @sock: the socket
1691  * @doi_def: the CIPSO DOI to use
1692  * @secattr: the specific security attributes of the socket
1693  *
1694  * Description:
1695  * Set the CIPSO option on the given socket using the DOI definition and
1696  * security attributes passed to the function.  This function requires
1697  * exclusive access to @sock->sk, which means it either needs to be in the
1698  * process of being created or locked via lock_sock(sock->sk).  Returns zero on
1699  * success and negative values on failure.
1700  *
1701  */
1702 int cipso_v4_socket_setattr(const struct socket *sock,
1703 			    const struct cipso_v4_doi *doi_def,
1704 			    const struct netlbl_lsm_secattr *secattr)
1705 {
1706 	int ret_val = -EPERM;
1707 	u32 iter;
1708 	unsigned char *buf;
1709 	u32 buf_len = 0;
1710 	u32 opt_len;
1711 	struct ip_options *opt = NULL;
1712 	struct sock *sk;
1713 	struct inet_sock *sk_inet;
1714 	struct inet_connection_sock *sk_conn;
1715 
1716 	/* In the case of sock_create_lite(), the sock->sk field is not
1717 	 * defined yet but it is not a problem as the only users of these
1718 	 * "lite" PF_INET sockets are functions which do an accept() call
1719 	 * afterwards so we will label the socket as part of the accept(). */
1720 	sk = sock->sk;
1721 	if (sk == NULL)
1722 		return 0;
1723 
1724 	/* We allocate the maximum CIPSO option size here so we are probably
1725 	 * being a little wasteful, but it makes our life _much_ easier later
1726 	 * on and after all we are only talking about 40 bytes. */
1727 	buf_len = CIPSO_V4_OPT_LEN_MAX;
1728 	buf = kmalloc(buf_len, GFP_ATOMIC);
1729 	if (buf == NULL) {
1730 		ret_val = -ENOMEM;
1731 		goto socket_setattr_failure;
1732 	}
1733 
1734 	/* XXX - This code assumes only one tag per CIPSO option which isn't
1735 	 * really a good assumption to make but since we only support the MAC
1736 	 * tags right now it is a safe assumption. */
1737 	iter = 0;
1738 	do {
1739 		memset(buf, 0, buf_len);
1740 		switch (doi_def->tags[iter]) {
1741 		case CIPSO_V4_TAG_RBITMAP:
1742 			ret_val = cipso_v4_gentag_rbm(doi_def,
1743 						   secattr,
1744 						   &buf[CIPSO_V4_HDR_LEN],
1745 						   buf_len - CIPSO_V4_HDR_LEN);
1746 			break;
1747 		case CIPSO_V4_TAG_ENUM:
1748 			ret_val = cipso_v4_gentag_enum(doi_def,
1749 						   secattr,
1750 						   &buf[CIPSO_V4_HDR_LEN],
1751 						   buf_len - CIPSO_V4_HDR_LEN);
1752 			break;
1753 		case CIPSO_V4_TAG_RANGE:
1754 			ret_val = cipso_v4_gentag_rng(doi_def,
1755 						   secattr,
1756 						   &buf[CIPSO_V4_HDR_LEN],
1757 						   buf_len - CIPSO_V4_HDR_LEN);
1758 			break;
1759 		default:
1760 			ret_val = -EPERM;
1761 			goto socket_setattr_failure;
1762 		}
1763 
1764 		iter++;
1765 	} while (ret_val < 0 &&
1766 		 iter < CIPSO_V4_TAG_MAXCNT &&
1767 		 doi_def->tags[iter] != CIPSO_V4_TAG_INVALID);
1768 	if (ret_val < 0)
1769 		goto socket_setattr_failure;
1770 	cipso_v4_gentag_hdr(doi_def, buf, ret_val);
1771 	buf_len = CIPSO_V4_HDR_LEN + ret_val;
1772 
1773 	/* We can't use ip_options_get() directly because it makes a call to
1774 	 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and
1775 	 * we won't always have CAP_NET_RAW even though we _always_ want to
1776 	 * set the IPOPT_CIPSO option. */
1777 	opt_len = (buf_len + 3) & ~3;
1778 	opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC);
1779 	if (opt == NULL) {
1780 		ret_val = -ENOMEM;
1781 		goto socket_setattr_failure;
1782 	}
1783 	memcpy(opt->__data, buf, buf_len);
1784 	opt->optlen = opt_len;
1785 	opt->is_data = 1;
1786 	opt->cipso = sizeof(struct iphdr);
1787 	kfree(buf);
1788 	buf = NULL;
1789 
1790 	sk_inet = inet_sk(sk);
1791 	if (sk_inet->is_icsk) {
1792 		sk_conn = inet_csk(sk);
1793 		if (sk_inet->opt)
1794 			sk_conn->icsk_ext_hdr_len -= sk_inet->opt->optlen;
1795 		sk_conn->icsk_ext_hdr_len += opt->optlen;
1796 		sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie);
1797 	}
1798 	opt = xchg(&sk_inet->opt, opt);
1799 	kfree(opt);
1800 
1801 	return 0;
1802 
1803 socket_setattr_failure:
1804 	kfree(buf);
1805 	kfree(opt);
1806 	return ret_val;
1807 }
1808 
1809 /**
1810  * cipso_v4_sock_getattr - Get the security attributes from a sock
1811  * @sk: the sock
1812  * @secattr: the security attributes
1813  *
1814  * Description:
1815  * Query @sk to see if there is a CIPSO option attached to the sock and if
1816  * there is return the CIPSO security attributes in @secattr.  This function
1817  * requires that @sk be locked, or privately held, but it does not do any
1818  * locking itself.  Returns zero on success and negative values on failure.
1819  *
1820  */
1821 int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
1822 {
1823 	int ret_val = -ENOMSG;
1824 	struct inet_sock *sk_inet;
1825 	unsigned char *cipso_ptr;
1826 	u32 doi;
1827 	struct cipso_v4_doi *doi_def;
1828 
1829 	sk_inet = inet_sk(sk);
1830 	if (sk_inet->opt == NULL || sk_inet->opt->cipso == 0)
1831 		return -ENOMSG;
1832 	cipso_ptr = sk_inet->opt->__data + sk_inet->opt->cipso -
1833 		sizeof(struct iphdr);
1834 	ret_val = cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr);
1835 	if (ret_val == 0)
1836 		return ret_val;
1837 
1838 	doi = ntohl(*(__be32 *)&cipso_ptr[2]);
1839 	rcu_read_lock();
1840 	doi_def = cipso_v4_doi_search(doi);
1841 	if (doi_def == NULL) {
1842 		rcu_read_unlock();
1843 		return -ENOMSG;
1844 	}
1845 
1846 	/* XXX - This code assumes only one tag per CIPSO option which isn't
1847 	 * really a good assumption to make but since we only support the MAC
1848 	 * tags right now it is a safe assumption. */
1849 	switch (cipso_ptr[6]) {
1850 	case CIPSO_V4_TAG_RBITMAP:
1851 		ret_val = cipso_v4_parsetag_rbm(doi_def,
1852 						&cipso_ptr[6],
1853 						secattr);
1854 		break;
1855 	case CIPSO_V4_TAG_ENUM:
1856 		ret_val = cipso_v4_parsetag_enum(doi_def,
1857 						 &cipso_ptr[6],
1858 						 secattr);
1859 		break;
1860 	case CIPSO_V4_TAG_RANGE:
1861 		ret_val = cipso_v4_parsetag_rng(doi_def,
1862 						&cipso_ptr[6],
1863 						secattr);
1864 		break;
1865 	}
1866 	rcu_read_unlock();
1867 
1868 	return ret_val;
1869 }
1870 
1871 /**
1872  * cipso_v4_socket_getattr - Get the security attributes from a socket
1873  * @sock: the socket
1874  * @secattr: the security attributes
1875  *
1876  * Description:
1877  * Query @sock to see if there is a CIPSO option attached to the socket and if
1878  * there is return the CIPSO security attributes in @secattr.  Returns zero on
1879  * success and negative values on failure.
1880  *
1881  */
1882 int cipso_v4_socket_getattr(const struct socket *sock,
1883 			    struct netlbl_lsm_secattr *secattr)
1884 {
1885 	int ret_val;
1886 
1887 	lock_sock(sock->sk);
1888 	ret_val = cipso_v4_sock_getattr(sock->sk, secattr);
1889 	release_sock(sock->sk);
1890 
1891 	return ret_val;
1892 }
1893 
1894 /**
1895  * cipso_v4_skbuff_getattr - Get the security attributes from the CIPSO option
1896  * @skb: the packet
1897  * @secattr: the security attributes
1898  *
1899  * Description:
1900  * Parse the given packet's CIPSO option and return the security attributes.
1901  * Returns zero on success and negative values on failure.
1902  *
1903  */
1904 int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
1905 			    struct netlbl_lsm_secattr *secattr)
1906 {
1907 	int ret_val = -ENOMSG;
1908 	unsigned char *cipso_ptr;
1909 	u32 doi;
1910 	struct cipso_v4_doi *doi_def;
1911 
1912 	cipso_ptr = CIPSO_V4_OPTPTR(skb);
1913 	if (cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr) == 0)
1914 		return 0;
1915 
1916 	doi = ntohl(*(__be32 *)&cipso_ptr[2]);
1917 	rcu_read_lock();
1918 	doi_def = cipso_v4_doi_search(doi);
1919 	if (doi_def == NULL)
1920 		goto skbuff_getattr_return;
1921 
1922 	/* XXX - This code assumes only one tag per CIPSO option which isn't
1923 	 * really a good assumption to make but since we only support the MAC
1924 	 * tags right now it is a safe assumption. */
1925 	switch (cipso_ptr[6]) {
1926 	case CIPSO_V4_TAG_RBITMAP:
1927 		ret_val = cipso_v4_parsetag_rbm(doi_def,
1928 						&cipso_ptr[6],
1929 						secattr);
1930 		break;
1931 	case CIPSO_V4_TAG_ENUM:
1932 		ret_val = cipso_v4_parsetag_enum(doi_def,
1933 						 &cipso_ptr[6],
1934 						 secattr);
1935 		break;
1936 	case CIPSO_V4_TAG_RANGE:
1937 		ret_val = cipso_v4_parsetag_rng(doi_def,
1938 						&cipso_ptr[6],
1939 						secattr);
1940 		break;
1941 	}
1942 
1943 skbuff_getattr_return:
1944 	rcu_read_unlock();
1945 	return ret_val;
1946 }
1947 
1948 /*
1949  * Setup Functions
1950  */
1951 
1952 /**
1953  * cipso_v4_init - Initialize the CIPSO module
1954  *
1955  * Description:
1956  * Initialize the CIPSO module and prepare it for use.  Returns zero on success
1957  * and negative values on failure.
1958  *
1959  */
1960 static int __init cipso_v4_init(void)
1961 {
1962 	int ret_val;
1963 
1964 	ret_val = cipso_v4_cache_init();
1965 	if (ret_val != 0)
1966 		panic("Failed to initialize the CIPSO/IPv4 cache (%d)\n",
1967 		      ret_val);
1968 
1969 	return 0;
1970 }
1971 
1972 subsys_initcall(cipso_v4_init);
1973