Skip to content

Commit dd4f33b

Browse files
committed
Merge branch 'tools-ynl-c-basic-netlink-raw-support'
Jakub Kicinski says: ==================== tools: ynl: c: basic netlink-raw support Basic support for netlink-raw AKA classic netlink in user space C codegen. This series is enough to read routes and addresses from the kernel (see the samples in patches 12 and 13). Specs need to be slightly adjusted and decorated with the c naming info. In terms of codegen this series includes just the basic plumbing required to skip genlmsghdr and handle request types which may technically also be legal in genetlink-legacy but are very uncommon there. Subsequent series will add support for: - handling CRUD-style notifications - code gen for array types classic netlink uses - sub-message support v1: https://lore.kernel.org/[email protected] ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 4145f00 + 54d7908 commit dd4f33b

File tree

16 files changed

+263
-77
lines changed

16 files changed

+263
-77
lines changed

Documentation/netlink/specs/rt_addr.yaml renamed to Documentation/netlink/specs/rt-addr.yaml

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
name: rt-addr
44
protocol: netlink-raw
5+
uapi-header: linux/rtnetlink.h
56
protonum: 0
67

78
doc:
@@ -49,6 +50,8 @@ definitions:
4950
-
5051
name: ifa-flags
5152
type: flags
53+
name-prefix: ifa-f-
54+
enum-name:
5255
entries:
5356
-
5457
name: secondary
@@ -124,6 +127,7 @@ attribute-sets:
124127
operations:
125128
fixed-header: ifaddrmsg
126129
enum-model: directional
130+
name-prefix: rtm-
127131
list:
128132
-
129133
name: newaddr
@@ -133,11 +137,6 @@ operations:
133137
request:
134138
value: 20
135139
attributes: &ifaddr-all
136-
- ifa-family
137-
- ifa-flags
138-
- ifa-prefixlen
139-
- ifa-scope
140-
- ifa-index
141140
- address
142141
- label
143142
- local
@@ -150,11 +149,6 @@ operations:
150149
request:
151150
value: 21
152151
attributes:
153-
- ifa-family
154-
- ifa-flags
155-
- ifa-prefixlen
156-
- ifa-scope
157-
- ifa-index
158152
- address
159153
- local
160154
-
@@ -164,8 +158,7 @@ operations:
164158
dump:
165159
request:
166160
value: 22
167-
attributes:
168-
- ifa-index
161+
attributes: []
169162
reply:
170163
value: 20
171164
attributes: *ifaddr-all
@@ -177,9 +170,7 @@ operations:
177170
do:
178171
request:
179172
value: 58
180-
attributes:
181-
- ifa-family
182-
- ifa-index
173+
attributes: []
183174
reply:
184175
value: 58
185176
attributes: &mcaddr-attrs
@@ -188,8 +179,7 @@ operations:
188179
dump:
189180
request:
190181
value: 58
191-
attributes:
192-
- ifa-family
182+
attributes: []
193183
reply:
194184
value: 58
195185
attributes: *mcaddr-attrs

Documentation/netlink/specs/rt_route.yaml renamed to Documentation/netlink/specs/rt-route.yaml

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
name: rt-route
44
protocol: netlink-raw
5+
uapi-header: linux/rtnetlink.h
56
protonum: 0
67

78
doc:
@@ -11,6 +12,7 @@ definitions:
1112
-
1213
name: rtm-type
1314
name-prefix: rtn-
15+
enum-name:
1416
type: enum
1517
entries:
1618
- unspec
@@ -245,21 +247,19 @@ attribute-sets:
245247

246248
operations:
247249
enum-model: directional
250+
fixed-header: rtmsg
251+
name-prefix: rtm-
248252
list:
249253
-
250254
name: getroute
251255
doc: Dump route information.
252256
attribute-set: route-attrs
253-
fixed-header: rtmsg
254257
do:
255258
request:
256259
value: 26
257260
attributes:
258-
- rtm-family
259261
- src
260-
- rtm-src-len
261262
- dst
262-
- rtm-dst-len
263263
- iif
264264
- oif
265265
- ip-proto
@@ -271,15 +271,6 @@ operations:
271271
reply:
272272
value: 24
273273
attributes: &all-route-attrs
274-
- rtm-family
275-
- rtm-dst-len
276-
- rtm-src-len
277-
- rtm-tos
278-
- rtm-table
279-
- rtm-protocol
280-
- rtm-scope
281-
- rtm-type
282-
- rtm-flags
283274
- dst
284275
- src
285276
- iif
@@ -311,16 +302,14 @@ operations:
311302
dump:
312303
request:
313304
value: 26
314-
attributes:
315-
- rtm-family
305+
attributes: []
316306
reply:
317307
value: 24
318308
attributes: *all-route-attrs
319309
-
320310
name: newroute
321311
doc: Create a new route
322312
attribute-set: route-attrs
323-
fixed-header: rtmsg
324313
do:
325314
request:
326315
value: 24
@@ -329,7 +318,6 @@ operations:
329318
name: delroute
330319
doc: Delete an existing route
331320
attribute-set: route-attrs
332-
fixed-header: rtmsg
333321
do:
334322
request:
335323
value: 25

Documentation/userspace-api/netlink/netlink-raw.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ Sub-messages
6262
------------
6363

6464
Several raw netlink families such as
65-
:doc:`rt_link<../../networking/netlink_spec/rt_link>` and
65+
:doc:`rt-link<../../networking/netlink_spec/rt-link>` and
6666
:doc:`tc<../../networking/netlink_spec/tc>` use attribute nesting as an
6767
abstraction to carry module specific information.
6868

tools/net/ynl/Makefile.deps

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,6 @@ CFLAGS_nfsd:=$(call get_hdr_inc,_LINUX_NFSD_NETLINK_H,nfsd_netlink.h)
2929
CFLAGS_ovs_datapath:=$(call get_hdr_inc,__LINUX_OPENVSWITCH_H,openvswitch.h)
3030
CFLAGS_ovs_flow:=$(call get_hdr_inc,__LINUX_OPENVSWITCH_H,openvswitch.h)
3131
CFLAGS_ovs_vport:=$(call get_hdr_inc,__LINUX_OPENVSWITCH_H,openvswitch.h)
32+
CFLAGS_rt-addr:=$(call get_hdr_inc,__LINUX_RTNETLINK_H,rtnetlink.h)
33+
CFLAGS_rt-route:=$(call get_hdr_inc,__LINUX_RTNETLINK_H,rtnetlink.h)
3234
CFLAGS_tcp_metrics:=$(call get_hdr_inc,_LINUX_TCP_METRICS_H,tcp_metrics.h)

tools/net/ynl/generated/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ SPECS_DIR:=../../../../Documentation/netlink/specs
2525
GENS_PATHS=$(shell grep -nrI --files-without-match \
2626
'protocol: netlink' \
2727
$(SPECS_DIR))
28-
GENS=$(patsubst $(SPECS_DIR)/%.yaml,%,${GENS_PATHS})
28+
GENS=$(patsubst $(SPECS_DIR)/%.yaml,%,${GENS_PATHS}) rt-addr rt-route
2929
SRCS=$(patsubst %,%-user.c,${GENS})
3030
HDRS=$(patsubst %,%-user.h,${GENS})
3131
OBJS=$(patsubst %,%-user.o,${GENS})

tools/net/ynl/lib/ynl-priv.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ struct ynl_ntf_base_type {
9494
unsigned char data[] __attribute__((aligned(8)));
9595
};
9696

97+
struct nlmsghdr *ynl_msg_start_req(struct ynl_sock *ys, __u32 id);
98+
struct nlmsghdr *ynl_msg_start_dump(struct ynl_sock *ys, __u32 id);
99+
97100
struct nlmsghdr *
98101
ynl_gemsg_start_req(struct ynl_sock *ys, __u32 id, __u8 cmd, __u8 version);
99102
struct nlmsghdr *

tools/net/ynl/lib/ynl.c

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -451,14 +451,14 @@ ynl_gemsg_start(struct ynl_sock *ys, __u32 id, __u16 flags,
451451
return nlh;
452452
}
453453

454-
void ynl_msg_start_req(struct ynl_sock *ys, __u32 id)
454+
struct nlmsghdr *ynl_msg_start_req(struct ynl_sock *ys, __u32 id)
455455
{
456-
ynl_msg_start(ys, id, NLM_F_REQUEST | NLM_F_ACK);
456+
return ynl_msg_start(ys, id, NLM_F_REQUEST | NLM_F_ACK);
457457
}
458458

459-
void ynl_msg_start_dump(struct ynl_sock *ys, __u32 id)
459+
struct nlmsghdr *ynl_msg_start_dump(struct ynl_sock *ys, __u32 id)
460460
{
461-
ynl_msg_start(ys, id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP);
461+
return ynl_msg_start(ys, id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP);
462462
}
463463

464464
struct nlmsghdr *
@@ -663,6 +663,7 @@ ynl_sock_create(const struct ynl_family *yf, struct ynl_error *yse)
663663
struct sockaddr_nl addr;
664664
struct ynl_sock *ys;
665665
socklen_t addrlen;
666+
int sock_type;
666667
int one = 1;
667668

668669
ys = malloc(sizeof(*ys) + 2 * YNL_SOCKET_BUFFER_SIZE);
@@ -675,7 +676,9 @@ ynl_sock_create(const struct ynl_family *yf, struct ynl_error *yse)
675676
ys->rx_buf = &ys->raw_buf[YNL_SOCKET_BUFFER_SIZE];
676677
ys->ntf_last_next = &ys->ntf_first;
677678

678-
ys->socket = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
679+
sock_type = yf->is_classic ? yf->classic_id : NETLINK_GENERIC;
680+
681+
ys->socket = socket(AF_NETLINK, SOCK_RAW, sock_type);
679682
if (ys->socket < 0) {
680683
__perr(yse, "failed to create a netlink socket");
681684
goto err_free_sock;
@@ -708,8 +711,9 @@ ynl_sock_create(const struct ynl_family *yf, struct ynl_error *yse)
708711
ys->portid = addr.nl_pid;
709712
ys->seq = random();
710713

711-
712-
if (ynl_sock_read_family(ys, yf->name)) {
714+
if (yf->is_classic) {
715+
ys->family_id = yf->classic_id;
716+
} else if (ynl_sock_read_family(ys, yf->name)) {
713717
if (yse)
714718
memcpy(yse, &ys->err, sizeof(*yse));
715719
goto err_close_sock;
@@ -791,13 +795,21 @@ static int ynl_ntf_parse(struct ynl_sock *ys, const struct nlmsghdr *nlh)
791795
struct ynl_parse_arg yarg = { .ys = ys, };
792796
const struct ynl_ntf_info *info;
793797
struct ynl_ntf_base_type *rsp;
794-
struct genlmsghdr *gehdr;
798+
__u32 cmd;
795799
int ret;
796800

797-
gehdr = ynl_nlmsg_data(nlh);
798-
if (gehdr->cmd >= ys->family->ntf_info_size)
801+
if (ys->family->is_classic) {
802+
cmd = nlh->nlmsg_type;
803+
} else {
804+
struct genlmsghdr *gehdr;
805+
806+
gehdr = ynl_nlmsg_data(nlh);
807+
cmd = gehdr->cmd;
808+
}
809+
810+
if (cmd >= ys->family->ntf_info_size)
799811
return YNL_PARSE_CB_ERROR;
800-
info = &ys->family->ntf_info[gehdr->cmd];
812+
info = &ys->family->ntf_info[cmd];
801813
if (!info->cb)
802814
return YNL_PARSE_CB_ERROR;
803815

@@ -811,7 +823,7 @@ static int ynl_ntf_parse(struct ynl_sock *ys, const struct nlmsghdr *nlh)
811823
goto err_free;
812824

813825
rsp->family = nlh->nlmsg_type;
814-
rsp->cmd = gehdr->cmd;
826+
rsp->cmd = cmd;
815827

816828
*ys->ntf_last_next = rsp;
817829
ys->ntf_last_next = &rsp->next;
@@ -863,17 +875,22 @@ int ynl_error_parse(struct ynl_parse_arg *yarg, const char *msg)
863875
static int
864876
ynl_check_alien(struct ynl_sock *ys, const struct nlmsghdr *nlh, __u32 rsp_cmd)
865877
{
866-
struct genlmsghdr *gehdr;
878+
if (ys->family->is_classic) {
879+
if (nlh->nlmsg_type != rsp_cmd)
880+
return ynl_ntf_parse(ys, nlh);
881+
} else {
882+
struct genlmsghdr *gehdr;
867883

868-
if (ynl_nlmsg_data_len(nlh) < sizeof(*gehdr)) {
869-
yerr(ys, YNL_ERROR_INV_RESP,
870-
"Kernel responded with truncated message");
871-
return -1;
872-
}
884+
if (ynl_nlmsg_data_len(nlh) < sizeof(*gehdr)) {
885+
yerr(ys, YNL_ERROR_INV_RESP,
886+
"Kernel responded with truncated message");
887+
return -1;
888+
}
873889

874-
gehdr = ynl_nlmsg_data(nlh);
875-
if (gehdr->cmd != rsp_cmd)
876-
return ynl_ntf_parse(ys, nlh);
890+
gehdr = ynl_nlmsg_data(nlh);
891+
if (gehdr->cmd != rsp_cmd)
892+
return ynl_ntf_parse(ys, nlh);
893+
}
877894

878895
return 0;
879896
}

0 commit comments

Comments
 (0)