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 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
|
/*
* Copyright (c) 2008, 2009, 2010, 2011, 2013, 2014 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 __NETLINK_H_
#define __NETLINK_H_ 1
#include "Types.h"
#include "NetlinkProto.h"
#include "NetlinkBuf.h"
#include "..\..\include\OvsDpInterface.h"
/*
* Structure of any message passed between userspace and kernel.
*/
typedef struct _OVS_MESSAGE {
NL_MSG_HDR nlMsg;
union {
GENL_MSG_HDR genlMsg;
NF_GEN_MSG_HDR nfGenMsg;
};
OVS_HDR ovsHdr;
/* Variable length nl_attrs follow. */
} OVS_MESSAGE, *POVS_MESSAGE;
BUILD_ASSERT_DECL(sizeof(GENL_MSG_HDR) == sizeof(NF_GEN_MSG_HDR));
/*
* Structure of an error message sent as a reply from kernel.
*/
typedef struct _OVS_MESSAGE_ERROR {
NL_MSG_HDR nlMsg;
NL_MSG_ERR errorMsg;
} OVS_MESSAGE_ERROR, *POVS_MESSAGE_ERROR;
/* Netlink attribute types. */
typedef enum
{
NL_A_NO_ATTR = 0,
NL_A_VAR_LEN,
NL_A_UNSPEC,
NL_A_U8,
NL_A_U16,
NL_A_BE16 = NL_A_U16,
NL_A_U32,
NL_A_BE32 = NL_A_U32,
NL_A_U64,
NL_A_BE64 = NL_A_U64,
NL_A_STRING,
NL_A_FLAG,
NL_A_NESTED,
N_NL_ATTR_TYPES
} NL_ATTR_TYPE;
/* Netlink attribute policy.
* Specifies the policy for parsing for netlink attribute. */
typedef struct _NL_POLICY
{
NL_ATTR_TYPE type;
UINT32 minLen;
UINT32 maxLen;
BOOLEAN optional;
} NL_POLICY, *PNL_POLICY;
/* This macro is careful to check for attributes with bad lengths. */
#define NL_ATTR_FOR_EACH(ITER, LEFT, ATTRS, ATTRS_LEN) \
for ((ITER) = (ATTRS), (LEFT) = (ATTRS_LEN); \
((INT)LEFT) >= (INT)NLA_ALIGN(sizeof(NL_ATTR)) && \
NlAttrIsValid(ITER, LEFT); \
(LEFT) -= NlAttrLenPad(ITER, LEFT), (ITER) = NlAttrNext(ITER))
/* This macro does not check for attributes with bad lengths. It should only
* be used with messages from trusted sources or with messages that have
* already been validated (e.g. with NL_ATTR_FOR_EACH). */
#define NL_ATTR_FOR_EACH_UNSAFE(ITER, LEFT, ATTRS, ATTRS_LEN) \
for ((ITER) = (ATTRS), (LEFT) = (ATTRS_LEN); \
((INT)LEFT) >= (INT)NLA_ALIGN(sizeof(NL_ATTR)); \
(LEFT) -= NLA_ALIGN((ITER)->nlaLen), (ITER) = NlAttrNext(ITER))
#define NL_ATTR_GET_AS(NLA, TYPE) \
(*(TYPE*) NlAttrGetUnspec(nla, sizeof(TYPE)))
BOOLEAN NlFillOvsMsg(PNL_BUFFER nlBuf,
UINT16 nlmsgType, UINT16 nlmsgFlags,
UINT32 nlmsgSeq, UINT32 nlmsgPid,
UINT8 genlCmd, UINT8 genlVer, UINT32 dpNo);
BOOLEAN NlFillOvsMsgForNfGenMsg(PNL_BUFFER nlBuf, UINT16 nlmsgType,
UINT16 nlmsgFlags, UINT32 nlmsgSeq,
UINT32 nlmsgPid, UINT8 nfgenFamily,
UINT8 nfGenVersion, UINT32 dpNo);
BOOLEAN NlFillNlHdr(PNL_BUFFER nlBuf,
UINT16 nlmsgType, UINT16 nlmsgFlags,
UINT32 nlmsgSeq, UINT32 nlmsgPid);
VOID NlBuildErrorMsg(POVS_MESSAGE msgIn, POVS_MESSAGE_ERROR msgError,
UINT errorCode, UINT32 *msgLen);
/* Netlink message accessing the payload */
PVOID NlMsgAt(const PNL_MSG_HDR nlh, UINT32 offset);
UINT32 NlMsgSize(const PNL_MSG_HDR nlh);
VOID NlMsgAlignSize(const PNL_MSG_HDR nlh);
VOID NlMsgSetSize(const PNL_MSG_HDR nlh, UINT32 msgLen);
PCHAR NlHdrPayload(const PNL_MSG_HDR nlh);
UINT32 NlHdrPayloadLen(const PNL_MSG_HDR nlh);
PNL_ATTR NlMsgAttrs(const PNL_MSG_HDR nlh);
UINT32 NlMsgAttrsLen(const PNL_MSG_HDR nlh);
UINT32 NlNfMsgAttrsLen(const PNL_MSG_HDR nlh);
/* Netlink message parse */
PNL_MSG_HDR NlMsgNext(const PNL_MSG_HDR nlh);
INT NlAttrIsValid(const PNL_ATTR nla, UINT32 maxlen);
UINT32 NlAttrLenPad(const PNL_ATTR nla, UINT32 maxlen);
/* Netlink attribute parsing. */
UINT32 NlAttrMinLen(NL_ATTR_TYPE type);
UINT32 NlAttrMinLen(NL_ATTR_TYPE type);
PNL_ATTR NlAttrNext(const PNL_ATTR nla);
UINT16 NlAttrType(const PNL_ATTR nla);
PVOID NlAttrData(const PNL_ATTR nla);
UINT32 NlAttrGetSize(const PNL_ATTR nla);
const PVOID NlAttrGet(const PNL_ATTR nla);
const PVOID NlAttrGetUnspec(const PNL_ATTR nla, UINT32 size);
BE64 NlAttrGetBe64(const PNL_ATTR nla);
BE32 NlAttrGetBe32(const PNL_ATTR nla);
BE16 NlAttrGetBe16(const PNL_ATTR nla);
UINT8 NlAttrGetU8(const PNL_ATTR nla);
UINT16 NlAttrGetU16(const PNL_ATTR nla);
UINT32 NlAttrGetU32(const PNL_ATTR nla);
UINT64 NlAttrGetU64(const PNL_ATTR nla);
PCHAR NlAttrGetString(const PNL_ATTR nla);
const PNL_ATTR NlAttrFind__(const PNL_ATTR attrs,
UINT32 size, UINT16 type);
const PNL_ATTR NlAttrFindNested(const PNL_ATTR nla,
UINT16 type);
BOOLEAN NlAttrParse(const PNL_MSG_HDR nlMsg, UINT32 attrOffset,
UINT32 totalAttrLen, const NL_POLICY policy[],
const UINT32 numPolicy, PNL_ATTR attrs[],
UINT32 numAttrs);
BOOLEAN NlAttrParseNested(const PNL_MSG_HDR nlMsg, UINT32 attrOffset,
UINT32 totalAttrLen, const NL_POLICY policy[],
const UINT32 numPolicy, PNL_ATTR attrs[],
UINT32 numAttrs);
/*
* --------------------------------------------------------------------------
* Returns the length of attribute.
* --------------------------------------------------------------------------
*/
static __inline UINT16
NlAttrLen(const PNL_ATTR nla)
{
return nla->nlaLen;
}
/*
* ---------------------------------------------------------------------------
* Default maximum payload size for each type of attribute.
* ---------------------------------------------------------------------------
*/
UINT32
static __inline NlAttrSize(UINT32 payloadSize)
{
return NLA_HDRLEN + payloadSize;
}
/*
* ---------------------------------------------------------------------------
* Total length including padding.
* ---------------------------------------------------------------------------
*/
UINT32
static __inline NlAttrTotalSize(UINT32 payloadSize)
{
return NLA_ALIGN(NlAttrSize(payloadSize));
}
/*
* ---------------------------------------------------------------------------
* Returns true if the last attribute is reached.
* ---------------------------------------------------------------------------
*/
BOOLEAN
static __inline NlAttrIsLast(const PNL_ATTR nla, int rem)
{
return nla->nlaLen == rem;
}
/* Netlink attribute validation */
BOOLEAN NlAttrValidate(const PNL_ATTR, const PNL_POLICY);
/* Netlink attribute stream validation */
BOOLEAN NlValidateAllAttrs(const PNL_MSG_HDR nlMsg, UINT32 attrOffset,
UINT32 totalAttrLen,
const NL_POLICY policy[], const UINT32 numPolicy);
/* Put APis */
BOOLEAN NlMsgPutNlHdr(PNL_BUFFER buf, PNL_MSG_HDR nlMsg);
BOOLEAN NlMsgPutGenlHdr(PNL_BUFFER buf, PGENL_MSG_HDR genlMsg);
BOOLEAN NlMsgPutOvsHdr(PNL_BUFFER buf, POVS_HDR ovsHdr);
BOOLEAN NlMsgPutTail(PNL_BUFFER buf, const PCHAR data, UINT32 len);
PCHAR NlMsgPutTailUninit(PNL_BUFFER buf, UINT32 len);
PCHAR NlMsgPutTailUnspecUninit(PNL_BUFFER buf, UINT16 type, UINT16 len);
BOOLEAN NlMsgPutTailUnspec(PNL_BUFFER buf, UINT16 type, PCHAR data, UINT16 len);
BOOLEAN NlMsgPutTailFlag(PNL_BUFFER buf, UINT16 type);
BOOLEAN NlMsgPutTailU8(PNL_BUFFER buf, UINT16 type, UINT8 value);
BOOLEAN NlMsgPutTailU16(PNL_BUFFER buf, UINT16 type, UINT16 value);
BOOLEAN NlMsgPutTailU32(PNL_BUFFER buf, UINT16 type, UINT32 value);
BOOLEAN NlMsgPutTailU64(PNL_BUFFER buf, UINT16 type, UINT64 value);
BOOLEAN NlMsgPutTailString(PNL_BUFFER buf, UINT16 type, PCHAR value);
BOOLEAN NlMsgPutHead(PNL_BUFFER buf, const PCHAR data, UINT32 len);
PCHAR NlMsgPutHeadUninit(PNL_BUFFER buf, UINT32 len);
PCHAR NlMsgPutHeadUnspecUninit(PNL_BUFFER buf, UINT16 type, UINT16 len);
BOOLEAN NlMsgPutHeadUnspec(PNL_BUFFER buf, UINT16 type, PCHAR data, UINT16 len);
BOOLEAN NlMsgPutHeadFlag(PNL_BUFFER buf, UINT16 type);
BOOLEAN NlMsgPutHeadU8(PNL_BUFFER buf, UINT16 type, UINT8 value);
BOOLEAN NlMsgPutHeadU16(PNL_BUFFER buf, UINT16 type, UINT16 value);
BOOLEAN NlMsgPutHeadU32(PNL_BUFFER buf, UINT16 type, UINT32 value);
BOOLEAN NlMsgPutHeadU64(PNL_BUFFER buf, UINT16 type, UINT64 value);
BOOLEAN NlMsgPutHeadString(PNL_BUFFER buf, UINT16 type, PCHAR value);
UINT32 NlMsgStartNested(PNL_BUFFER buf, UINT16 type);
VOID NlMsgEndNested(PNL_BUFFER buf, UINT32 offset);
BOOLEAN NlMsgPutNested(PNL_BUFFER buf, UINT16 type,
const PVOID data, UINT32 size);
/* These variants are convenient for iterating nested attributes. */
#define NL_NESTED_FOR_EACH(ITER, LEFT, A) \
NL_ATTR_FOR_EACH(ITER, LEFT, NlAttrGet(A), NlAttrGetSize(A))
#define NL_NESTED_FOR_EACH_UNSAFE(ITER, LEFT, A) \
NL_ATTR_FOR_EACH_UNSAFE(ITER, LEFT, NlAttrGet(A), NlAttrGetSize(A))
#endif /* __NETLINK_H_ */
|