Home | History | Annotate | Download | only in b
      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