| 
									
										
										
										
											2010-05-17 22:50:19 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright 2010 Cisco Systems, Inc.  All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you may redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |  * the Free Software Foundation; version 2 of the License. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 
					
						
							|  |  |  |  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | 
					
						
							|  |  |  |  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 
					
						
							|  |  |  |  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | 
					
						
							|  |  |  |  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | 
					
						
							|  |  |  |  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | 
					
						
							|  |  |  |  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 
					
						
							|  |  |  |  * SOFTWARE. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/kernel.h>
 | 
					
						
							|  |  |  | #include <linux/errno.h>
 | 
					
						
							|  |  |  | #include <linux/types.h>
 | 
					
						
							|  |  |  | #include <linux/slab.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "vnic_vic.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-29 20:36:02 +00:00
										 |  |  | struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, const u8 *oui, | 
					
						
							|  |  |  | 	const u8 type) | 
					
						
							| 
									
										
										
										
											2010-05-17 22:50:19 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-09 21:59:03 +00:00
										 |  |  | 	struct vic_provinfo *vp; | 
					
						
							| 
									
										
										
										
											2010-05-17 22:50:19 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-24 10:52:26 +00:00
										 |  |  | 	if (!oui) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-09 21:59:03 +00:00
										 |  |  | 	vp = kzalloc(VIC_PROVINFO_MAX_DATA, flags); | 
					
						
							|  |  |  | 	if (!vp) | 
					
						
							| 
									
										
										
										
											2010-05-17 22:50:19 -07:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memcpy(vp->oui, oui, sizeof(vp->oui)); | 
					
						
							|  |  |  | 	vp->type = type; | 
					
						
							|  |  |  | 	vp->length = htonl(sizeof(vp->num_tlvs)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return vp; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void vic_provinfo_free(struct vic_provinfo *vp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	kfree(vp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length, | 
					
						
							| 
									
										
										
										
											2011-03-29 20:36:02 +00:00
										 |  |  | 	const void *value) | 
					
						
							| 
									
										
										
										
											2010-05-17 22:50:19 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct vic_provinfo_tlv *tlv; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!vp || !value) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 18:55:10 +00:00
										 |  |  | 	if (ntohl(vp->length) + offsetof(struct vic_provinfo_tlv, value) + | 
					
						
							|  |  |  | 		length > VIC_PROVINFO_MAX_TLV_DATA) | 
					
						
							| 
									
										
										
										
											2010-05-17 22:50:19 -07:00
										 |  |  | 		return -ENOMEM; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tlv = (struct vic_provinfo_tlv *)((u8 *)vp->tlv + | 
					
						
							|  |  |  | 		ntohl(vp->length) - sizeof(vp->num_tlvs)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tlv->type = htons(type); | 
					
						
							|  |  |  | 	tlv->length = htons(length); | 
					
						
							|  |  |  | 	memcpy(tlv->value, value, length); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vp->num_tlvs = htonl(ntohl(vp->num_tlvs) + 1); | 
					
						
							| 
									
										
										
										
											2010-08-10 18:55:10 +00:00
										 |  |  | 	vp->length = htonl(ntohl(vp->length) + | 
					
						
							|  |  |  | 		offsetof(struct vic_provinfo_tlv, value) + length); | 
					
						
							| 
									
										
										
										
											2010-05-17 22:50:19 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | size_t vic_provinfo_size(struct vic_provinfo *vp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return vp ?  ntohl(vp->length) + sizeof(*vp) - sizeof(vp->num_tlvs) : 0; | 
					
						
							|  |  |  | } |