]>
git.proxmox.com Git - mirror_iproute2.git/blob - tipc/msg.c
2 * msg.c Messaging (netlink) helper functions.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Richard Alpe <richard.alpe@ericsson.com>
16 #include <linux/tipc_netlink.h>
17 #include <linux/tipc.h>
18 #include <linux/genetlink.h>
19 #include <libmnl/libmnl.h>
23 int parse_attrs(const struct nlattr
*attr
, void *data
)
25 const struct nlattr
**tb
= data
;
26 int type
= mnl_attr_get_type(attr
);
33 static int family_id_cb(const struct nlmsghdr
*nlh
, void *data
)
35 struct nlattr
*tb
[CTRL_ATTR_MAX
+ 1] = {};
36 struct genlmsghdr
*genl
= mnl_nlmsg_get_payload(nlh
);
39 mnl_attr_parse(nlh
, sizeof(*genl
), parse_attrs
, tb
);
40 if (!tb
[CTRL_ATTR_FAMILY_ID
])
43 *id
= mnl_attr_get_u16(tb
[CTRL_ATTR_FAMILY_ID
]);
48 static struct mnl_socket
*msg_send(struct nlmsghdr
*nlh
)
51 struct mnl_socket
*nl
;
53 nl
= mnl_socket_open(NETLINK_GENERIC
);
55 perror("mnl_socket_open");
59 ret
= mnl_socket_bind(nl
, 0, MNL_SOCKET_AUTOPID
);
61 perror("mnl_socket_bind");
65 ret
= mnl_socket_sendto(nl
, nlh
, nlh
->nlmsg_len
);
67 perror("mnl_socket_send");
74 static int msg_recv(struct mnl_socket
*nl
, mnl_cb_t callback
, void *data
, int seq
)
78 char buf
[MNL_SOCKET_BUFFER_SIZE
];
80 portid
= mnl_socket_get_portid(nl
);
82 ret
= mnl_socket_recvfrom(nl
, buf
, sizeof(buf
));
84 ret
= mnl_cb_run(buf
, ret
, seq
, portid
, callback
, data
);
87 ret
= mnl_socket_recvfrom(nl
, buf
, sizeof(buf
));
97 static int msg_query(struct nlmsghdr
*nlh
, mnl_cb_t callback
, void *data
)
100 struct mnl_socket
*nl
;
103 nlh
->nlmsg_seq
= seq
;
109 return msg_recv(nl
, callback
, data
, seq
);
112 static int get_family(void)
116 struct nlmsghdr
*nlh
;
117 struct genlmsghdr
*genl
;
118 char buf
[MNL_SOCKET_BUFFER_SIZE
];
120 nlh
= mnl_nlmsg_put_header(buf
);
121 nlh
->nlmsg_type
= GENL_ID_CTRL
;
122 nlh
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
124 genl
= mnl_nlmsg_put_extra_header(nlh
, sizeof(struct genlmsghdr
));
125 genl
->cmd
= CTRL_CMD_GETFAMILY
;
128 mnl_attr_put_u32(nlh
, CTRL_ATTR_FAMILY_ID
, GENL_ID_CTRL
);
129 mnl_attr_put_strz(nlh
, CTRL_ATTR_FAMILY_NAME
, TIPC_GENL_V2_NAME
);
131 if ((err
= msg_query(nlh
, family_id_cb
, &nl_family
)))
137 int msg_doit(struct nlmsghdr
*nlh
, mnl_cb_t callback
, void *data
)
139 nlh
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_ACK
;
140 return msg_query(nlh
, callback
, data
);
143 int msg_dumpit(struct nlmsghdr
*nlh
, mnl_cb_t callback
, void *data
)
145 nlh
->nlmsg_flags
= NLM_F_REQUEST
| NLM_F_DUMP
;
146 return msg_query(nlh
, callback
, data
);
149 struct nlmsghdr
*msg_init(char *buf
, int cmd
)
152 struct nlmsghdr
*nlh
;
153 struct genlmsghdr
*genl
;
155 family
= get_family();
158 "Unable to get TIPC nl family id (module loaded?)\n");
162 nlh
= mnl_nlmsg_put_header(buf
);
163 nlh
->nlmsg_type
= family
;
165 genl
= mnl_nlmsg_put_extra_header(nlh
, sizeof(struct genlmsghdr
));