]>
Commit | Line | Data |
---|---|---|
344b47e1 AS |
1 | /* |
2 | * Copyright (c) 2008, 2009, 2010, 2011, 2013, 2014 Nicira, 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 | #ifndef __NETLINK_H_ | |
18 | #define __NETLINK_H_ 1 | |
19 | ||
fa1324c9 | 20 | #include "Types.h" |
344b47e1 | 21 | #include "NetlinkProto.h" |
edf3fb0f | 22 | #include "NetlinkBuf.h" |
08288ce0 AS |
23 | #include "..\..\include\OvsDpInterface.h" |
24 | ||
25 | /* | |
26 | * Structure of any message passed between userspace and kernel. | |
27 | */ | |
28 | typedef struct _OVS_MESSAGE { | |
29 | NL_MSG_HDR nlMsg; | |
9f8407b9 SV |
30 | union { |
31 | GENL_MSG_HDR genlMsg; | |
32 | NF_GEN_MSG_HDR nfGenMsg; | |
33 | }; | |
08288ce0 AS |
34 | OVS_HDR ovsHdr; |
35 | /* Variable length nl_attrs follow. */ | |
36 | } OVS_MESSAGE, *POVS_MESSAGE; | |
9f8407b9 | 37 | BUILD_ASSERT_DECL(sizeof(GENL_MSG_HDR) == sizeof(NF_GEN_MSG_HDR)); |
344b47e1 | 38 | |
fa8266a8 NR |
39 | /* |
40 | * Structure of an error message sent as a reply from kernel. | |
41 | */ | |
42 | typedef struct _OVS_MESSAGE_ERROR { | |
43 | NL_MSG_HDR nlMsg; | |
44 | NL_MSG_ERR errorMsg; | |
45 | } OVS_MESSAGE_ERROR, *POVS_MESSAGE_ERROR; | |
46 | ||
344b47e1 AS |
47 | /* Netlink attribute types. */ |
48 | typedef enum | |
49 | { | |
50 | NL_A_NO_ATTR = 0, | |
5ab37d7a | 51 | NL_A_VAR_LEN, |
344b47e1 AS |
52 | NL_A_UNSPEC, |
53 | NL_A_U8, | |
54 | NL_A_U16, | |
55 | NL_A_BE16 = NL_A_U16, | |
56 | NL_A_U32, | |
57 | NL_A_BE32 = NL_A_U32, | |
58 | NL_A_U64, | |
59 | NL_A_BE64 = NL_A_U64, | |
60 | NL_A_STRING, | |
61 | NL_A_FLAG, | |
62 | NL_A_NESTED, | |
63 | N_NL_ATTR_TYPES | |
64 | } NL_ATTR_TYPE; | |
65 | ||
66 | /* Netlink attribute policy. | |
67 | * Specifies the policy for parsing for netlink attribute. */ | |
68 | typedef struct _NL_POLICY | |
69 | { | |
70 | NL_ATTR_TYPE type; | |
71 | UINT32 minLen; | |
72 | UINT32 maxLen; | |
cd002ede | 73 | BOOLEAN optional; |
344b47e1 AS |
74 | } NL_POLICY, *PNL_POLICY; |
75 | ||
76 | /* This macro is careful to check for attributes with bad lengths. */ | |
77 | #define NL_ATTR_FOR_EACH(ITER, LEFT, ATTRS, ATTRS_LEN) \ | |
78 | for ((ITER) = (ATTRS), (LEFT) = (ATTRS_LEN); \ | |
e6b298ef | 79 | ((INT)LEFT) >= (INT)NLA_ALIGN(sizeof(NL_ATTR)) && \ |
344b47e1 AS |
80 | NlAttrIsValid(ITER, LEFT); \ |
81 | (LEFT) -= NlAttrLenPad(ITER, LEFT), (ITER) = NlAttrNext(ITER)) | |
82 | ||
83 | /* This macro does not check for attributes with bad lengths. It should only | |
84 | * be used with messages from trusted sources or with messages that have | |
85 | * already been validated (e.g. with NL_ATTR_FOR_EACH). */ | |
86 | #define NL_ATTR_FOR_EACH_UNSAFE(ITER, LEFT, ATTRS, ATTRS_LEN) \ | |
87 | for ((ITER) = (ATTRS), (LEFT) = (ATTRS_LEN); \ | |
e6b298ef | 88 | ((INT)LEFT) >= (INT)NLA_ALIGN(sizeof(NL_ATTR)); \ |
344b47e1 AS |
89 | (LEFT) -= NLA_ALIGN((ITER)->nlaLen), (ITER) = NlAttrNext(ITER)) |
90 | ||
91 | #define NL_ATTR_GET_AS(NLA, TYPE) \ | |
92 | (*(TYPE*) NlAttrGetUnspec(nla, sizeof(TYPE))) | |
93 | ||
1ad44ad4 | 94 | BOOLEAN NlFillOvsMsg(PNL_BUFFER nlBuf, |
e6ac5e9e | 95 | UINT16 nlmsgType, UINT16 nlmsgFlags, |
1ad44ad4 NR |
96 | UINT32 nlmsgSeq, UINT32 nlmsgPid, |
97 | UINT8 genlCmd, UINT8 genlVer, UINT32 dpNo); | |
d115da85 SV |
98 | BOOLEAN NlFillOvsMsgForNfGenMsg(PNL_BUFFER nlBuf, UINT16 nlmsgType, |
99 | UINT16 nlmsgFlags, UINT32 nlmsgSeq, | |
100 | UINT32 nlmsgPid, UINT8 nfgenFamily, | |
101 | UINT8 nfGenVersion, UINT32 dpNo); | |
1ad44ad4 NR |
102 | BOOLEAN NlFillNlHdr(PNL_BUFFER nlBuf, |
103 | UINT16 nlmsgType, UINT16 nlmsgFlags, | |
104 | UINT32 nlmsgSeq, UINT32 nlmsgPid); | |
d5f1e533 | 105 | |
e6b298ef | 106 | VOID NlBuildErrorMsg(POVS_MESSAGE msgIn, POVS_MESSAGE_ERROR msgError, |
e6b298ef | 107 | UINT errorCode, UINT32 *msgLen); |
fa8266a8 | 108 | |
344b47e1 AS |
109 | /* Netlink message accessing the payload */ |
110 | PVOID NlMsgAt(const PNL_MSG_HDR nlh, UINT32 offset); | |
111 | UINT32 NlMsgSize(const PNL_MSG_HDR nlh); | |
e6ac5e9e AS |
112 | VOID NlMsgAlignSize(const PNL_MSG_HDR nlh); |
113 | VOID NlMsgSetSize(const PNL_MSG_HDR nlh, UINT32 msgLen); | |
5b224954 AS |
114 | PCHAR NlHdrPayload(const PNL_MSG_HDR nlh); |
115 | UINT32 NlHdrPayloadLen(const PNL_MSG_HDR nlh); | |
344b47e1 | 116 | PNL_ATTR NlMsgAttrs(const PNL_MSG_HDR nlh); |
5b224954 | 117 | UINT32 NlMsgAttrsLen(const PNL_MSG_HDR nlh); |
9f8407b9 | 118 | UINT32 NlNfMsgAttrsLen(const PNL_MSG_HDR nlh); |
344b47e1 AS |
119 | |
120 | /* Netlink message parse */ | |
121 | PNL_MSG_HDR NlMsgNext(const PNL_MSG_HDR nlh); | |
122 | INT NlAttrIsValid(const PNL_ATTR nla, UINT32 maxlen); | |
123 | UINT32 NlAttrLenPad(const PNL_ATTR nla, UINT32 maxlen); | |
124 | ||
125 | /* Netlink attribute parsing. */ | |
126 | UINT32 NlAttrMinLen(NL_ATTR_TYPE type); | |
127 | UINT32 NlAttrMinLen(NL_ATTR_TYPE type); | |
128 | PNL_ATTR NlAttrNext(const PNL_ATTR nla); | |
129 | UINT16 NlAttrType(const PNL_ATTR nla); | |
130 | PVOID NlAttrData(const PNL_ATTR nla); | |
131 | UINT32 NlAttrGetSize(const PNL_ATTR nla); | |
132 | const PVOID NlAttrGet(const PNL_ATTR nla); | |
133 | const PVOID NlAttrGetUnspec(const PNL_ATTR nla, UINT32 size); | |
134 | BE64 NlAttrGetBe64(const PNL_ATTR nla); | |
135 | BE32 NlAttrGetBe32(const PNL_ATTR nla); | |
5874d571 | 136 | BE16 NlAttrGetBe16(const PNL_ATTR nla); |
344b47e1 | 137 | UINT8 NlAttrGetU8(const PNL_ATTR nla); |
8722e8f3 | 138 | UINT16 NlAttrGetU16(const PNL_ATTR nla); |
344b47e1 | 139 | UINT32 NlAttrGetU32(const PNL_ATTR nla); |
8722e8f3 | 140 | UINT64 NlAttrGetU64(const PNL_ATTR nla); |
e68988b8 | 141 | PCHAR NlAttrGetString(const PNL_ATTR nla); |
344b47e1 AS |
142 | const PNL_ATTR NlAttrFind__(const PNL_ATTR attrs, |
143 | UINT32 size, UINT16 type); | |
144 | const PNL_ATTR NlAttrFindNested(const PNL_ATTR nla, | |
145 | UINT16 type); | |
146 | BOOLEAN NlAttrParse(const PNL_MSG_HDR nlMsg, UINT32 attrOffset, | |
5b224954 | 147 | UINT32 totalAttrLen, const NL_POLICY policy[], |
9f8407b9 | 148 | const UINT32 numPolicy, PNL_ATTR attrs[], |
b8b00f0c | 149 | UINT32 numAttrs); |
5b224954 AS |
150 | BOOLEAN NlAttrParseNested(const PNL_MSG_HDR nlMsg, UINT32 attrOffset, |
151 | UINT32 totalAttrLen, const NL_POLICY policy[], | |
b8b00f0c SV |
152 | const UINT32 numPolicy, PNL_ATTR attrs[], |
153 | UINT32 numAttrs); | |
dac95740 AS |
154 | /* |
155 | * -------------------------------------------------------------------------- | |
156 | * Returns the length of attribute. | |
157 | * -------------------------------------------------------------------------- | |
158 | */ | |
159 | static __inline UINT16 | |
160 | NlAttrLen(const PNL_ATTR nla) | |
161 | { | |
162 | return nla->nlaLen; | |
163 | } | |
164 | ||
152f11b6 EE |
165 | /* |
166 | * --------------------------------------------------------------------------- | |
167 | * Default maximum payload size for each type of attribute. | |
168 | * --------------------------------------------------------------------------- | |
169 | */ | |
170 | UINT32 | |
171 | static __inline NlAttrSize(UINT32 payloadSize) | |
172 | { | |
173 | return NLA_HDRLEN + payloadSize; | |
174 | } | |
175 | ||
176 | /* | |
177 | * --------------------------------------------------------------------------- | |
178 | * Total length including padding. | |
179 | * --------------------------------------------------------------------------- | |
180 | */ | |
181 | UINT32 | |
182 | static __inline NlAttrTotalSize(UINT32 payloadSize) | |
183 | { | |
184 | return NLA_ALIGN(NlAttrSize(payloadSize)); | |
185 | } | |
186 | ||
ee25964a SV |
187 | /* |
188 | * --------------------------------------------------------------------------- | |
189 | * Returns true if the last attribute is reached. | |
190 | * --------------------------------------------------------------------------- | |
191 | */ | |
192 | BOOLEAN | |
193 | static __inline NlAttrIsLast(const PNL_ATTR nla, int rem) | |
194 | { | |
195 | return nla->nlaLen == rem; | |
196 | } | |
197 | ||
344b47e1 AS |
198 | /* Netlink attribute validation */ |
199 | BOOLEAN NlAttrValidate(const PNL_ATTR, const PNL_POLICY); | |
200 | ||
e6b298ef PB |
201 | /* Netlink attribute stream validation */ |
202 | BOOLEAN NlValidateAllAttrs(const PNL_MSG_HDR nlMsg, UINT32 attrOffset, | |
203 | UINT32 totalAttrLen, | |
204 | const NL_POLICY policy[], const UINT32 numPolicy); | |
205 | ||
edf3fb0f AS |
206 | /* Put APis */ |
207 | BOOLEAN NlMsgPutNlHdr(PNL_BUFFER buf, PNL_MSG_HDR nlMsg); | |
208 | BOOLEAN NlMsgPutGenlHdr(PNL_BUFFER buf, PGENL_MSG_HDR genlMsg); | |
209 | BOOLEAN NlMsgPutOvsHdr(PNL_BUFFER buf, POVS_HDR ovsHdr); | |
210 | ||
211 | BOOLEAN NlMsgPutTail(PNL_BUFFER buf, const PCHAR data, UINT32 len); | |
212 | PCHAR NlMsgPutTailUninit(PNL_BUFFER buf, UINT32 len); | |
213 | PCHAR NlMsgPutTailUnspecUninit(PNL_BUFFER buf, UINT16 type, UINT16 len); | |
214 | BOOLEAN NlMsgPutTailUnspec(PNL_BUFFER buf, UINT16 type, PCHAR data, UINT16 len); | |
215 | BOOLEAN NlMsgPutTailFlag(PNL_BUFFER buf, UINT16 type); | |
216 | BOOLEAN NlMsgPutTailU8(PNL_BUFFER buf, UINT16 type, UINT8 value); | |
217 | BOOLEAN NlMsgPutTailU16(PNL_BUFFER buf, UINT16 type, UINT16 value); | |
218 | BOOLEAN NlMsgPutTailU32(PNL_BUFFER buf, UINT16 type, UINT32 value); | |
219 | BOOLEAN NlMsgPutTailU64(PNL_BUFFER buf, UINT16 type, UINT64 value); | |
220 | BOOLEAN NlMsgPutTailString(PNL_BUFFER buf, UINT16 type, PCHAR value); | |
221 | ||
222 | BOOLEAN NlMsgPutHead(PNL_BUFFER buf, const PCHAR data, UINT32 len); | |
223 | PCHAR NlMsgPutHeadUninit(PNL_BUFFER buf, UINT32 len); | |
224 | PCHAR NlMsgPutHeadUnspecUninit(PNL_BUFFER buf, UINT16 type, UINT16 len); | |
225 | BOOLEAN NlMsgPutHeadUnspec(PNL_BUFFER buf, UINT16 type, PCHAR data, UINT16 len); | |
226 | BOOLEAN NlMsgPutHeadFlag(PNL_BUFFER buf, UINT16 type); | |
227 | BOOLEAN NlMsgPutHeadU8(PNL_BUFFER buf, UINT16 type, UINT8 value); | |
228 | BOOLEAN NlMsgPutHeadU16(PNL_BUFFER buf, UINT16 type, UINT16 value); | |
229 | BOOLEAN NlMsgPutHeadU32(PNL_BUFFER buf, UINT16 type, UINT32 value); | |
230 | BOOLEAN NlMsgPutHeadU64(PNL_BUFFER buf, UINT16 type, UINT64 value); | |
231 | BOOLEAN NlMsgPutHeadString(PNL_BUFFER buf, UINT16 type, PCHAR value); | |
988672a7 AS |
232 | UINT32 NlMsgStartNested(PNL_BUFFER buf, UINT16 type); |
233 | VOID NlMsgEndNested(PNL_BUFFER buf, UINT32 offset); | |
b113e510 AS |
234 | BOOLEAN NlMsgPutNested(PNL_BUFFER buf, UINT16 type, |
235 | const PVOID data, UINT32 size); | |
988672a7 AS |
236 | |
237 | /* These variants are convenient for iterating nested attributes. */ | |
238 | #define NL_NESTED_FOR_EACH(ITER, LEFT, A) \ | |
239 | NL_ATTR_FOR_EACH(ITER, LEFT, NlAttrGet(A), NlAttrGetSize(A)) | |
240 | #define NL_NESTED_FOR_EACH_UNSAFE(ITER, LEFT, A) \ | |
241 | NL_ATTR_FOR_EACH_UNSAFE(ITER, LEFT, NlAttrGet(A), NlAttrGetSize(A)) | |
edf3fb0f | 242 | |
344b47e1 | 243 | #endif /* __NETLINK_H_ */ |