*
* Returns 0 in case of success or -1 on failure
*/
-#if defined(HAVE_STRUCT_IFREQ) && defined(SIOCBRADDBR)
+#if defined(__linux__) && defined(HAVE_LIBNL)
+int virNetDevBridgeCreate(const char *brname)
+{
+ /* use a netlink RTM_NEWLINK message to create the bridge */
+ const char *type = "bridge";
+ int rc = -1;
+ struct nlmsghdr *resp = NULL;
+ struct nlmsgerr *err;
+ struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC };
+ unsigned int recvbuflen;
+ struct nl_msg *nl_msg;
+ struct nlattr *linkinfo;
+
+ nl_msg = nlmsg_alloc_simple(RTM_NEWLINK,
+ NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
+ if (!nl_msg) {
+ virReportOOMError();
+ return -1;
+ }
+
+ if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
+ goto buffer_too_small;
+ if (nla_put(nl_msg, IFLA_IFNAME, strlen(brname)+1, brname) < 0)
+ goto buffer_too_small;
+ if (!(linkinfo = nla_nest_start(nl_msg, IFLA_LINKINFO)))
+ goto buffer_too_small;
+ if (nla_put(nl_msg, IFLA_INFO_KIND, strlen(type), type) < 0)
+ goto buffer_too_small;
+ nla_nest_end(nl_msg, linkinfo);
+
+ if (virNetlinkCommand(nl_msg, &resp, &recvbuflen, 0, 0,
+ NETLINK_ROUTE, 0) < 0) {
+ goto cleanup;
+ }
+
+ if (recvbuflen < NLMSG_LENGTH(0) || resp == NULL)
+ goto malformed_resp;
+
+ switch (resp->nlmsg_type) {
+ case NLMSG_ERROR:
+ err = (struct nlmsgerr *)NLMSG_DATA(resp);
+ if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
+ goto malformed_resp;
+
+ switch (err->error) {
+ case 0:
+ break;
+ default:
+ virReportSystemError(-err->error,
+ _("error creating bridge interface %s"),
+ brname);
+ goto cleanup;
+ }
+ break;
+
+ case NLMSG_DONE:
+ break;
+ default:
+ goto malformed_resp;
+ }
+
+ rc = 0;
+ cleanup:
+ nlmsg_free(nl_msg);
+ VIR_FREE(resp);
+ return rc;
+
+ malformed_resp:
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed netlink response message"));
+ goto cleanup;
+ buffer_too_small:
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("allocated netlink buffer is too small"));
+ goto cleanup;
+}
+#elif defined(HAVE_STRUCT_IFREQ) && defined(SIOCBRADDBR)
int virNetDevBridgeCreate(const char *brname)
{
int fd = -1;