Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 // Copyright 2010 Cisco Systems, Inc.  All rights reserved.
0003 
0004 #include <linux/kernel.h>
0005 #include <linux/errno.h>
0006 #include <linux/types.h>
0007 #include <linux/slab.h>
0008 
0009 #include "vnic_vic.h"
0010 
0011 struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, const u8 *oui,
0012     const u8 type)
0013 {
0014     struct vic_provinfo *vp;
0015 
0016     if (!oui)
0017         return NULL;
0018 
0019     vp = kzalloc(VIC_PROVINFO_MAX_DATA, flags);
0020     if (!vp)
0021         return NULL;
0022 
0023     memcpy(vp->oui, oui, sizeof(vp->oui));
0024     vp->type = type;
0025     vp->length = htonl(sizeof(vp->num_tlvs));
0026 
0027     return vp;
0028 }
0029 
0030 void vic_provinfo_free(struct vic_provinfo *vp)
0031 {
0032     kfree(vp);
0033 }
0034 
0035 int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length,
0036     const void *value)
0037 {
0038     struct vic_provinfo_tlv *tlv;
0039 
0040     if (!vp || !value)
0041         return -EINVAL;
0042 
0043     if (ntohl(vp->length) + offsetof(struct vic_provinfo_tlv, value) +
0044         length > VIC_PROVINFO_MAX_TLV_DATA)
0045         return -ENOMEM;
0046 
0047     tlv = (struct vic_provinfo_tlv *)((u8 *)vp->tlv +
0048         ntohl(vp->length) - sizeof(vp->num_tlvs));
0049 
0050     tlv->type = htons(type);
0051     tlv->length = htons(length);
0052     memcpy(tlv->value, value, length);
0053 
0054     vp->num_tlvs = htonl(ntohl(vp->num_tlvs) + 1);
0055     vp->length = htonl(ntohl(vp->length) +
0056         offsetof(struct vic_provinfo_tlv, value) + length);
0057 
0058     return 0;
0059 }
0060 
0061 size_t vic_provinfo_size(struct vic_provinfo *vp)
0062 {
0063     return vp ?  ntohl(vp->length) + sizeof(*vp) - sizeof(vp->num_tlvs) : 0;
0064 }