1 /* 2 * Copyright (c) 2015 PLUMgrid, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 namespace ebpf { 20 namespace cc { 21 22 // Represent the numeric type of a protocol field 23 enum FieldType { 24 INVALID = 0, 25 UINT8_T, 26 UINT16_T, 27 UINT32_T, 28 UINT64_T, 29 #ifdef __SIZEOF_INT128__ 30 UINT128_T, 31 #endif 32 VOID 33 }; 34 35 static inline size_t enum_to_size(const FieldType t) { 36 switch (t) { 37 case UINT8_T: return sizeof(uint8_t); 38 case UINT16_T: return sizeof(uint16_t); 39 case UINT32_T: return sizeof(uint32_t); 40 case UINT64_T: return sizeof(uint64_t); 41 #ifdef __SIZEOF_INT128__ 42 case UINT128_T: return sizeof(__uint128_t); 43 #endif 44 default: 45 return 0; 46 } 47 } 48 49 /// Convert a bit size to the next highest power of 2 50 static inline int next_base2(int v) { 51 --v; 52 v |= v >> 1; 53 v |= v >> 2; 54 v |= v >> 4; 55 v |= v >> 8; 56 v |= v >> 16; 57 ++v; 58 return v; 59 } 60 61 static inline const char* bits_to_uint(int v) { 62 v = next_base2(v); 63 if (v <= 8) { 64 return "uint8_t"; 65 } else if (v == 16) { 66 return "uint16_t"; 67 } else if (v == 32) { 68 return "uint32_t"; 69 } else if (v == 64) { 70 return "uint64_t"; 71 } else if (v >= 128) { 72 /* in plumlet 128-bit integers should be 8-byte aligned, 73 * all other ints should have natural alignment */ 74 return "unsigned __int128 __attribute__((packed, aligned(8)))"; 75 } 76 return "void"; 77 } 78 79 static inline FieldType bits_to_enum(int v) { 80 v = next_base2(v); 81 if (v <= 8) { 82 return UINT8_T; 83 } else if (v == 16) { 84 return UINT16_T; 85 } else if (v == 32) { 86 return UINT32_T; 87 } else if (v == 64) { 88 return UINT64_T; 89 #ifdef __SIZEOF_INT128__ 90 } else if (v >= 128) { 91 return UINT128_T; 92 #endif 93 } 94 return VOID; 95 } 96 97 static inline size_t bits_to_size(int v) { 98 return enum_to_size(bits_to_enum(v)); 99 } 100 101 static inline size_t align_offset(size_t offset, FieldType ft) { 102 switch (ft) { 103 case UINT8_T: 104 return offset % 8 > 0 ? offset + (8 - offset % 8) : offset; 105 case UINT16_T: 106 return offset % 16 > 0 ? offset + (16 - offset % 16) : offset; 107 case UINT32_T: 108 return offset % 32 > 0 ? offset + (32 - offset % 32) : offset; 109 case UINT64_T: 110 #ifdef __SIZEOF_INT128__ 111 case UINT128_T: 112 #endif 113 return offset % 64 > 0 ? offset + (64 - offset % 64) : offset; 114 default: 115 ; 116 } 117 return offset; 118 } 119 120 } // namespace cc 121 } // namespace ebpf 122