]>
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 | { | |
fc0ba8e8 | 28 | struct vic_provinfo *vp; |
f8bd9091 | 29 | |
29046f9b VK |
30 | if (!oui) |
31 | return NULL; | |
32 | ||
fc0ba8e8 DC |
33 | vp = kzalloc(VIC_PROVINFO_MAX_DATA, flags); |
34 | if (!vp) | |
f8bd9091 SF |
35 | return NULL; |
36 | ||
37 | memcpy(vp->oui, oui, sizeof(vp->oui)); | |
38 | vp->type = type; | |
39 | vp->length = htonl(sizeof(vp->num_tlvs)); | |
40 | ||
41 | return vp; | |
42 | } | |
43 | ||
44 | void vic_provinfo_free(struct vic_provinfo *vp) | |
45 | { | |
46 | kfree(vp); | |
47 | } | |
48 | ||
49 | int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length, | |
50 | void *value) | |
51 | { | |
52 | struct vic_provinfo_tlv *tlv; | |
53 | ||
54 | if (!vp || !value) | |
55 | return -EINVAL; | |
56 | ||
7c46835e RP |
57 | if (ntohl(vp->length) + offsetof(struct vic_provinfo_tlv, value) + |
58 | length > VIC_PROVINFO_MAX_TLV_DATA) | |
f8bd9091 SF |
59 | return -ENOMEM; |
60 | ||
61 | tlv = (struct vic_provinfo_tlv *)((u8 *)vp->tlv + | |
62 | ntohl(vp->length) - sizeof(vp->num_tlvs)); | |
63 | ||
64 | tlv->type = htons(type); | |
65 | tlv->length = htons(length); | |
66 | memcpy(tlv->value, value, length); | |
67 | ||
68 | vp->num_tlvs = htonl(ntohl(vp->num_tlvs) + 1); | |
7c46835e RP |
69 | vp->length = htonl(ntohl(vp->length) + |
70 | offsetof(struct vic_provinfo_tlv, value) + length); | |
f8bd9091 SF |
71 | |
72 | return 0; | |
73 | } | |
74 | ||
75 | size_t vic_provinfo_size(struct vic_provinfo *vp) | |
76 | { | |
77 | return vp ? ntohl(vp->length) + sizeof(*vp) - sizeof(vp->num_tlvs) : 0; | |
78 | } |