Skip to content

Commit 67a7848

Browse files
author
Luigi Rizzo
committed
merge with current code from my internal tree.
Macro renaming, additional documentation, and various bugfixes. Should compile a a module on both stable/10 and head
1 parent 62cca46 commit 67a7848

File tree

7 files changed

+240
-130
lines changed

7 files changed

+240
-130
lines changed

bsd_nlsock.c

+7-7
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ int
8282
bsd_netlink_send_msg(struct socket *so, struct mbuf *m)
8383
{
8484
D("m %p proto %d pid %d plen %d so %p", _P32(m),
85-
_MP(m), NETLINK_CB(m).portid, m->m_pkthdr.len, _P32(so));
85+
_M_NLPROTO(m), NETLINK_CB(m).portid, m->m_pkthdr.len, _P32(so));
8686
return netisr_queue(NETISR_NETLINK, m);
8787
}
8888

@@ -149,7 +149,7 @@ raw_input_netlink_cb(struct mbuf *m, struct sockproto *proto,
149149
msg = mtod(m, struct nlmsghdr *);
150150

151151
D("m %p proto %d src_portid %d dst_portid %d ty %d so_portid %d len %d so %p",
152-
_P32(m), _MP(m), NETLINK_CB(m).portid,
152+
_P32(m), _M_NLPROTO(m), NETLINK_CB(m).portid,
153153
msg->nlmsg_pid, msg->nlmsg_type,
154154
key, m->m_pkthdr.len, _P32(so));
155155
/* return 0 on match, 1 on fail */
@@ -175,11 +175,11 @@ netlink_input(struct mbuf *m)
175175
.nl_family = PF_NETLINK,
176176
.nl_pid = 0 /* comes from the kernel */ };
177177
struct sockproto nl_proto = {
178-
.sp_family = PF_NETLINK, .sp_protocol = _MP(m)};
178+
.sp_family = PF_NETLINK, .sp_protocol = _M_NLPROTO(m)};
179179

180180
D("m %p proto %d src_portid %d len %d",
181-
_P32(m), _MP(m), NETLINK_CB(m).portid, m->m_pkthdr.len);
182-
_MP(m) = 0; // clear protocol in case it is not zero
181+
_P32(m), _M_NLPROTO(m), NETLINK_CB(m).portid, m->m_pkthdr.len);
182+
_M_NLPROTO(m) = 0; // clear protocol in case it is not zero
183183
D("calling input proto");
184184
/* the dispatcher matches sockets using raw_input_netlink_cb(),
185185
* and replicates messages as needed.
@@ -380,10 +380,10 @@ netlink_output(struct mbuf *m, struct socket *so NLO_EXTRA )
380380
rp = sotorawcb(so);
381381
proto = rp->rcb_proto.sp_protocol;
382382
/* save protocol and portid into the mbuf */
383-
_MP(m) = proto;
383+
_M_NLPROTO(m) = proto;
384384
NETLINK_CB(m).portid = so->nl_src_portid;
385385
D("so %p m %p m_portid %d m_proto %d plen %d len %d",
386-
_P32(so), _P32(m), NETLINK_CB(m).portid, _MP(m),
386+
_P32(so), _P32(m), NETLINK_CB(m).portid, _M_NLPROTO(m),
387387
m->m_pkthdr.len, m->m_len);
388388
ret = netlink_receive_packet(m, so, proto);
389389
D("returns %d", ret);

genetlink.c

+13-26
Original file line numberDiff line numberDiff line change
@@ -156,32 +156,19 @@ void *
156156
genlmsg_put(struct mbuf *m, uint32_t portid, uint32_t seq,
157157
struct genl_family *family, int flags, uint8_t cmd)
158158
{
159-
struct a {
160-
union {
161-
struct nlmsghdr n;
162-
char pad[NLMSG_HDRLEN];
163-
} n;
164-
union {
165-
struct genlmsghdr g;
166-
char pad[NLMSG_HDRLEN];
167-
} g;
168-
} *hdr;
169-
int need = NLMSG_HDRLEN + GENL_HDRLEN + family->hdrsize;
170-
void *ret;
171-
172-
if (m->m_pkthdr.len + need > _ML(m))
173-
return NULL;
174-
175-
hdr = (struct a *)_MC(m);
176-
bzero(hdr, sizeof(struct a));
177-
hdr->n.n.nlmsg_type = family->id;
178-
hdr->n.n.nlmsg_flags = flags;
179-
hdr->n.n.nlmsg_seq = seq;
180-
hdr->n.n.nlmsg_pid = portid;
181-
hdr->g.g.cmd = cmd; // XXX what about version and reserved
182-
ret = _MC(m) + NLMSG_HDRLEN + GENL_HDRLEN; // return value
183-
m->m_pkthdr.len += need;
184-
return ret;
159+
struct nlmsghdr *nlh;
160+
struct genlmsghdr *g;
161+
162+
nlh = nlmsg_put(m, portid, seq, family->id,
163+
GENL_HDRLEN + family->hdrsize, flags);
164+
if (nlh == NULL)
165+
return nlh; /* no space */
166+
g = nlmsg_data(nlh);
167+
g->cmd = cmd;
168+
g->version = family->version;
169+
g->reserved = 0;
170+
171+
return g;
185172
}
186173

187174
// XXX check

linux/netlink.h

+12-39
Original file line numberDiff line numberDiff line change
@@ -87,48 +87,13 @@ struct socket;
8787
struct mbuf; /* we must be compilable with an opaque type */
8888

8989
/*
90-
* Some mbuf pkthdr fields have special meaning when used with netlink:
91-
*
92-
* FIELD MACRO DESCRIPTION
93-
*
94-
* rcvif _MA() linear buffer, possibly external
95-
* fibnum _ML() linear buffer length
96-
* len -- current write offset
97-
* flowid NETLINK_CB() src_portid, 32 bit
98-
* rsstype _MP() protocol (NETLINK_GENERIC etc.)
99-
*
100-
* In more detail:
101-
*
102-
* 1. netlink messages are built incrementally in a linear buffer of
103-
* predefined size. This is a poor match with mbuf chains,
104-
* which may be split and have no predefined size.
105-
* Hence we use two mbuf fields (see above, _MA() and _ML() )
106-
* for the linear buffer pointer and max len,
107-
* and use m_pkthdr.len to record the space used so far
108-
* (remember of course to copy back and fix things before sending).
109-
* These are abstracted by the three macros _MA)(), _ML() and _MC()
110-
* _MA() and _ML() are cleared when passing the buffer back to the kernel
111-
*
112-
* 2. The protocol is mapped through _MP(m) into rsstype, and is used
113-
* in netlink_input()
114-
*
115-
* 3. sk_buff have a 48-byte "control buffer" (cb) to carry aux info.
116-
* In netlink this is wrapped by NETLINK_CB() into a pointer to a
117-
* struct netlink_skb_parms.
118-
* We need at least the portid, the source port for
119-
* messages coming from userspace, which in turn is used to locate the
120-
* destination socket when building a reply.
121-
* Netlink messages do not need flowid, so we store the portid there.
122-
*
90+
* Some mbuf pkthdr fields have special meaning when used with netlink
91+
* messages, see netlink.c (only used there, except NETLINK_CB()
12392
*/
12493

12594
#ifndef __COMPAT_MBUF_TYPE /* mappings only work in native systems */
12695

127-
#define _MA(m) (m)->m_pkthdr.rcvif /* linear buffer pointer */
128-
#define _ML(m) ((m)->m_pkthdr.fibnum) /* max length, 16 bit */
129-
#define _MC(m) ((char *)_MA(m) + (m)->m_pkthdr.len) /* cur data ptr */
130-
131-
#define _MP(m) ((m)->m_pkthdr.rsstype) /* netlink proto, 8 bit */
96+
#define _M_NLPROTO(m) ((m)->m_pkthdr.rsstype) /* netlink proto, 8 bit */
13297

13398
#define NETLINK_CB(_m) (*(struct netlink_skb_parms*)&((_m)->m_pkthdr.flowid))
13499

@@ -154,12 +119,20 @@ CTASSERT(sizeof(struct netlink_skb_parms) <= sizeof(uint32_t));
154119

155120
/* TODO: this function is not really remapped.
156121
* It is just a stub that logs the error
122+
*
123+
* The function should report error to broadcast listeners.
124+
* sock is the kernel netlink socket, pid is the process to skip,
125+
* group is the broadcast group that should receive the error,
126+
* err is the error code (on linux is negative, the info
127+
* is sent to receivers as a positive value.
128+
* Returns the number of recipients.
157129
*/
158130
#include <sys/syslog.h> /* LOG_INFO */
159-
static inline void
131+
static inline int
160132
netlink_set_err(void *sock, uint32_t pid, uint32_t group, int err)
161133
{
162134
log(LOG_INFO, "Netlink set err, func:%s\n", __func__);
135+
return 0;
163136
}
164137

165138
/*

linux/uapi_genetlink.h

+4
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ struct genlmsghdr {
5555

5656
#define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr))
5757

58+
#ifdef CTASSERT
59+
CTASSERT(GENL_HDRLEN == sizeof(struct genlmsghdr));
60+
#endif
61+
5862
/**************************************************************************
5963
* Controller
6064
**************************************************************************/

net/genetlink.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ genl_register_family(struct genl_family *family)
153153
int genl_unregister_family(struct genl_family *family);
154154

155155
/*
156-
* XXX incomplete
156+
* XXX incomplete same as netlink_set_err()
157157
*/
158158
static inline int
159159
genl_set_err(struct genl_family *fam, struct net *net,
@@ -163,8 +163,7 @@ genl_set_err(struct genl_family *fam, struct net *net,
163163
return EINVAL;
164164
group += fam->mcgrp_offset;
165165
/* we do not support namespaces yet */
166-
netlink_set_err(NULL /* net->genl_sock */, portid, group, code);
167-
return 0;
166+
return netlink_set_err(NULL /* net->genl_sock */, portid, group, code);
168167
}
169168

170169
/**
@@ -207,6 +206,9 @@ genlmsg_new(size_t payload, int flags)
207206
static inline void
208207
genlmsg_cancel(struct mbuf *m, void *hdr)
209208
{
209+
if (hdr)
210+
nlmsg_cancel(m, (struct nlmsghdr *)
211+
((char *)hdr - GENL_HDRLEN - NLMSG_HDRLEN) );
210212
}
211213

212214
void *genlmsg_put(struct mbuf *m, uint32_t portid, uint32_t seq,

net/netlink.h

+66-12
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ int bsd_netlink_send_msg(struct socket *so, struct mbuf *m);
7070
int netlink_receive_packet(struct mbuf *, struct socket *, int);
7171

7272
#define M_NETLINK_MULTICAST M_PROTO1
73+
#define M_NEGATIVE_ERROR M_PROTO2
7374

7475
#define nl_src_portid so_fibnum
7576
#define nl_dst_portid so_user_cookie
@@ -105,8 +106,46 @@ struct nla_policy {
105106
uint16_t len;
106107
};
107108

109+
static inline int
110+
nlmsg_msg_size(int payload_size)
111+
{
112+
return NLMSG_HDRLEN + payload_size;
113+
}
114+
115+
/*
116+
* create a new mbuf for a netlink msg.
117+
* Flags includes M_NEGATIVE_ERROR to indicate how we want nla_put()
118+
* to return errors (linux clients need negative error values).
119+
*/
108120
struct mbuf *nlmsg_new(size_t payload, int flags);
109121

122+
static inline void *
123+
nlmsg_data(const struct nlmsghdr *nlh)
124+
{
125+
return (unsigned char *)(uintptr_t) nlh + NLMSG_HDRLEN;
126+
}
127+
128+
void nlmsg_trim(struct mbuf *m, const void *mark); /* in netlink.c */
129+
130+
static inline void
131+
nlmsg_cancel(struct mbuf *m, struct nlmsghdr *nlh)
132+
{
133+
nlmsg_trim(m, nlh);
134+
}
135+
136+
int nlmsg_end(struct mbuf *m, struct nlmsghdr *nlh);
137+
138+
struct nlmsghdr *nlmsg_put(struct mbuf *m, uint32_t portid,
139+
uint32_t seq, int type, int payload, int flags);
140+
141+
struct genl_info; // XXX
142+
int nlmsg_reply(struct mbuf *m, struct genl_info *info);
143+
144+
145+
/*
146+
* kernel routines to manipulate netlink attributes (nla_*)
147+
*/
148+
110149
/*
111150
* nla_put() and __nla_put() append data to a nlmsg.
112151
* __nla_put() does not check for space.
@@ -185,7 +224,12 @@ static inline uint64_t nla_get_u64(const struct nlattr *nla)
185224

186225
struct nlattr *nla_nest_start(struct mbuf *m, int attrtype);
187226
int nla_nest_end(struct mbuf *m, struct nlattr *start);
188-
void nla_nest_cancel(struct mbuf *m, struct nlattr* start);
227+
static inline void
228+
nla_nest_cancel(struct mbuf *m, struct nlattr* start)
229+
{
230+
nlmsg_trim(m, start);
231+
}
232+
189233
struct nlattr * nla_reserve(struct mbuf *m, int attrtype, int attrlen);
190234
#define __nla_reserve nla_reserve
191235

@@ -209,12 +253,6 @@ nla_total_size(int payload)
209253
return NLA_ALIGN(nla_attr_size(payload));
210254
}
211255

212-
static inline void *
213-
nlmsg_data(const struct nlmsghdr *nlh)
214-
{
215-
return (unsigned char *)(uintptr_t) nlh + NLMSG_HDRLEN;
216-
}
217-
218256

219257

220258
static inline int
@@ -279,19 +317,35 @@ nla_padlen(int payload)
279317
#define nla_get_be32 nla_get_u32
280318
#define nla_get_be64 nla_get_u64
281319

282-
int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
320+
/*
321+
* nla_parse*() should return a negative error on linux,
322+
* but we have no way to discriminate the caller.
323+
* XXX perhaps introduce bsd_nla_parse*() with the bsd return values.
324+
*/
325+
int bsd_nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
283326
int len, const struct nla_policy *policy);
284327

328+
static inline int
329+
bsd_nla_parse_nested(struct nlattr *tb[], int maxtype,
330+
const struct nlattr *nla, const struct nla_policy *policy)
331+
{
332+
return bsd_nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
333+
}
334+
335+
static inline int
336+
nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
337+
int len, const struct nla_policy *policy)
338+
{
339+
return -nla_parse(tb, maxtype, head, len, policy);
340+
}
341+
285342
static inline int
286343
nla_parse_nested(struct nlattr *tb[], int maxtype,
287344
const struct nlattr *nla, const struct nla_policy *policy)
288345
{
289-
return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
346+
return -bsd_nla_parse_nested(tb, maxtype, nla, policy);
290347
}
291348

292-
int nlmsg_end(struct mbuf *m, struct nlmsghdr *nlh);
293-
struct genl_info; // XXX
294-
int nlmsg_reply(struct mbuf *m, struct genl_info *info);
295349

296350
#define nla_memcpy(dest, src, len) \
297351
memcpy(dest, nla_data(src), min(len,nla_len(src)))

0 commit comments

Comments
 (0)