Commit | Line | Data |
---|---|---|
f8bd9091 SF |
1 | /* |
2 | * Copyright 2010 Cisco Systems, Inc. All rights reserved. | |
3 | * | |
4 | * This program is free software; you may redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; version 2 of the License. | |
7 | * | |
8 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
9 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
10 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
11 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
12 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
13 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
14 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
15 | * SOFTWARE. | |
16 | * | |
17 | */ | |
18 | ||
19 | #include <linux/kernel.h> | |
20 | #include <linux/errno.h> | |
21 | #include <linux/types.h> | |
22 | #include <linux/slab.h> | |
23 | ||
24 | #include "vnic_vic.h" | |
25 | ||
26 | struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, u8 *oui, u8 type) | |
27 | { | |
28 | struct vic_provinfo *vp = kzalloc(VIC_PROVINFO_MAX_DATA, flags); | |
29 | ||
30 | if (!vp || !oui) | |
31 | return NULL; | |
32 | ||
33 | memcpy(vp->oui, oui, sizeof(vp->oui)); | |
34 | vp->type = type; | |
35 | vp->length = htonl(sizeof(vp->num_tlvs)); | |
36 | ||
37 | return vp; | |
38 | } | |
39 | ||
40 | void vic_provinfo_free(struct vic_provinfo *vp) | |
41 | { | |
42 | kfree(vp); | |
43 | } | |
44 | ||
45 | int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length, | |
46 | void *value) | |
47 | { | |
48 | struct vic_provinfo_tlv *tlv; | |
49 | ||
50 | if (!vp || !value) | |
51 | return -EINVAL; | |
52 | ||
53 | if (ntohl(vp->length) + sizeof(*tlv) + length > | |
54 | VIC_PROVINFO_MAX_TLV_DATA) | |
55 | return -ENOMEM; | |
56 | ||
57 | tlv = (struct vic_provinfo_tlv *)((u8 *)vp->tlv + | |
58 | ntohl(vp->length) - sizeof(vp->num_tlvs)); | |
59 | ||
60 | tlv->type = htons(type); | |
61 | tlv->length = htons(length); | |
62 | memcpy(tlv->value, value, length); | |
63 | ||
64 | vp->num_tlvs = htonl(ntohl(vp->num_tlvs) + 1); | |
65 | vp->length = htonl(ntohl(vp->length) + sizeof(*tlv) + length); | |
66 | ||
67 | return 0; | |
68 | } | |
69 | ||
70 | size_t vic_provinfo_size(struct vic_provinfo *vp) | |
71 | { | |
72 | return vp ? ntohl(vp->length) + sizeof(*vp) - sizeof(vp->num_tlvs) : 0; | |
73 | } |