blob: ce96cc43dc6c6eb090e6ac9823bf784fd53bc6e4 [file] [log] [blame]
/*
* Copyright (c) 2015 PLUMgrid, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
namespace ebpf {
namespace cc {
// Represent the numeric type of a protocol field
enum FieldType {
INVALID = 0,
UINT8_T,
UINT16_T,
UINT32_T,
UINT64_T,
#ifdef __SIZEOF_INT128__
UINT128_T,
#endif
VOID
};
static inline size_t enum_to_size(const FieldType t) {
switch (t) {
case UINT8_T: return sizeof(uint8_t);
case UINT16_T: return sizeof(uint16_t);
case UINT32_T: return sizeof(uint32_t);
case UINT64_T: return sizeof(uint64_t);
#ifdef __SIZEOF_INT128__
case UINT128_T: return sizeof(__uint128_t);
#endif
default:
return 0;
}
}
/// Convert a bit size to the next highest power of 2
static inline int next_base2(int v) {
--v;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
++v;
return v;
}
static inline const char* bits_to_uint(int v) {
v = next_base2(v);
if (v <= 8) {
return "uint8_t";
} else if (v == 16) {
return "uint16_t";
} else if (v == 32) {
return "uint32_t";
} else if (v == 64) {
return "uint64_t";
} else if (v >= 128) {
/* in plumlet 128-bit integers should be 8-byte aligned,
* all other ints should have natural alignment */
return "unsigned __int128 __attribute__((packed, aligned(8)))";
}
return "void";
}
static inline FieldType bits_to_enum(int v) {
v = next_base2(v);
if (v <= 8) {
return UINT8_T;
} else if (v == 16) {
return UINT16_T;
} else if (v == 32) {
return UINT32_T;
} else if (v == 64) {
return UINT64_T;
#ifdef __SIZEOF_INT128__
} else if (v >= 128) {
return UINT128_T;
#endif
}
return VOID;
}
static inline size_t bits_to_size(int v) {
return enum_to_size(bits_to_enum(v));
}
static inline size_t align_offset(size_t offset, FieldType ft) {
switch (ft) {
case UINT8_T:
return offset % 8 > 0 ? offset + (8 - offset % 8) : offset;
case UINT16_T:
return offset % 16 > 0 ? offset + (16 - offset % 16) : offset;
case UINT32_T:
return offset % 32 > 0 ? offset + (32 - offset % 32) : offset;
case UINT64_T:
#ifdef __SIZEOF_INT128__
case UINT128_T:
#endif
return offset % 64 > 0 ? offset + (64 - offset % 64) : offset;
default:
;
}
return offset;
}
} // namespace cc
} // namespace ebpf