forked from openvswitch/ovs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
byte-order.h
142 lines (130 loc) · 5.28 KB
/
byte-order.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
* Copyright (c) 2008, 2010, 2011, 2013, 2016 Nicira, 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.
*/
#ifndef BYTE_ORDER_H
#define BYTE_ORDER_H 1
#include <arpa/inet.h>
#include <sys/types.h>
#include <inttypes.h>
#include "openvswitch/types.h"
#ifndef __CHECKER__
#if !(defined(_WIN32) || defined(htonll))
static inline ovs_be64
htonll(uint64_t n)
{
return htonl(1) == 1 ? n : ((uint64_t) htonl(n) << 32) | htonl(n >> 32);
}
static inline uint64_t
ntohll(ovs_be64 n)
{
return htonl(1) == 1 ? n : ((uint64_t) ntohl(n) << 32) | ntohl(n >> 32);
}
#endif /* !(defined(_WIN32) || defined(htonll)) */
#else
/* Making sparse happy with these functions also makes them unreadable, so
* don't bother to show it their implementations. */
ovs_be64 htonll(uint64_t);
uint64_t ntohll(ovs_be64);
#endif
static inline ovs_be128
hton128(const ovs_u128 src)
{
ovs_be128 dst;
dst.be64.hi = htonll(src.u64.hi);
dst.be64.lo = htonll(src.u64.lo);
return dst;
}
static inline ovs_u128
ntoh128(const ovs_be128 src)
{
ovs_u128 dst;
dst.u64.hi = ntohll(src.be64.hi);
dst.u64.lo = ntohll(src.be64.lo);
return dst;
}
static inline uint32_t
uint32_byteswap(uint32_t crc) {
return (((crc & 0x000000ff) << 24) |
((crc & 0x0000ff00) << 8) |
((crc & 0x00ff0000) >> 8) |
((crc & 0xff000000) >> 24));
}
/* These macros may substitute for htons(), htonl(), and htonll() in contexts
* where function calls are not allowed, such as case labels. They should not
* be used elsewhere because all of them evaluate their argument many times. */
#if defined(WORDS_BIGENDIAN) || __CHECKER__
#define CONSTANT_HTONS(VALUE) ((OVS_FORCE ovs_be16) ((VALUE) & 0xffff))
#define CONSTANT_HTONL(VALUE) ((OVS_FORCE ovs_be32) ((VALUE) & 0xffffffff))
#define CONSTANT_HTONLL(VALUE) \
((OVS_FORCE ovs_be64) ((VALUE) & UINT64_C(0xffffffffffffffff)))
#else
#define CONSTANT_HTONS(VALUE) \
(((((ovs_be16) (VALUE)) & 0xff00) >> 8) | \
((((ovs_be16) (VALUE)) & 0x00ff) << 8))
#define CONSTANT_HTONL(VALUE) \
(((((ovs_be32) (VALUE)) & 0x000000ff) << 24) | \
((((ovs_be32) (VALUE)) & 0x0000ff00) << 8) | \
((((ovs_be32) (VALUE)) & 0x00ff0000) >> 8) | \
((((ovs_be32) (VALUE)) & 0xff000000) >> 24))
#define CONSTANT_HTONLL(VALUE) \
(((((ovs_be64) (VALUE)) & UINT64_C(0x00000000000000ff)) << 56) | \
((((ovs_be64) (VALUE)) & UINT64_C(0x000000000000ff00)) << 40) | \
((((ovs_be64) (VALUE)) & UINT64_C(0x0000000000ff0000)) << 24) | \
((((ovs_be64) (VALUE)) & UINT64_C(0x00000000ff000000)) << 8) | \
((((ovs_be64) (VALUE)) & UINT64_C(0x000000ff00000000)) >> 8) | \
((((ovs_be64) (VALUE)) & UINT64_C(0x0000ff0000000000)) >> 24) | \
((((ovs_be64) (VALUE)) & UINT64_C(0x00ff000000000000)) >> 40) | \
((((ovs_be64) (VALUE)) & UINT64_C(0xff00000000000000)) >> 56))
#endif
#if WORDS_BIGENDIAN
#define BYTES_TO_BE32(B1, B2, B3, B4) \
(OVS_FORCE ovs_be32)((uint32_t)(B1) << 24 | (B2) << 16 | (B3) << 8 | (B4))
#define BE16S_TO_BE32(B1, B2) \
(OVS_FORCE ovs_be32)((uint32_t)(B1) << 16 | (B2))
#else
#define BYTES_TO_BE32(B1, B2, B3, B4) \
(OVS_FORCE ovs_be32)((uint32_t)(B1) | (B2) << 8 | (B3) << 16 | (B4) << 24)
#define BE16S_TO_BE32(B1, B2) \
(OVS_FORCE ovs_be32)((uint32_t)(B1) | (B2) << 16)
#endif
/* These functions zero-extend big-endian values to longer ones,
* or truncate long big-endian value to shorter ones. */
#ifndef __CHECKER__
#if WORDS_BIGENDIAN
static inline ovs_be32 be16_to_be32(ovs_be16 x) { return x; }
static inline ovs_be64 be16_to_be64(ovs_be16 x) { return x; }
static inline ovs_be64 be32_to_be64(ovs_be32 x) { return x; }
static inline ovs_be32 be64_to_be32(ovs_be64 x) { return x; }
static inline ovs_be16 be64_to_be16(ovs_be64 x) { return x; }
static inline ovs_be16 be32_to_be16(ovs_be32 x) { return x; }
#else /* !WORDS_BIGENDIAN */
static inline ovs_be32 be16_to_be32(ovs_be16 x) { return (ovs_be32) x << 16; }
static inline ovs_be64 be16_to_be64(ovs_be16 x) { return (ovs_be64) x << 48; }
static inline ovs_be64 be32_to_be64(ovs_be32 x) { return (ovs_be64) x << 32; }
static inline ovs_be32 be64_to_be32(ovs_be64 x) { return x >> 32; }
static inline ovs_be16 be64_to_be16(ovs_be64 x) { return x >> 48; }
static inline ovs_be16 be32_to_be16(ovs_be32 x) { return x >> 16; }
#endif /* !WORDS_BIGENDIAN */
#else /* __CHECKER__ */
/* Making sparse happy with these functions also makes them unreadable, so
* don't bother to show it their implementations. */
ovs_be32 be16_to_be32(ovs_be16);
ovs_be64 be16_to_be64(ovs_be16);
ovs_be64 be32_to_be64(ovs_be32);
ovs_be32 be64_to_be32(ovs_be64);
ovs_be16 be64_to_be16(ovs_be64);
ovs_be16 be32_to_be16(ovs_be32);
#endif
#endif /* byte-order.h */