*
* Returns 0 in case of success or -1 on failure
*/
+#if defined(HAVE_STRUCT_IFREQ) && defined(SIOCBRADDBR)
+static int
+virNetDevBridgeCreateWithIoctl(const char *brname)
+{
+ int fd = -1;
+ int ret = -1;
+
+ if ((fd = virNetDevSetupControl(NULL, NULL)) < 0)
+ return -1;
+
+ if (ioctl(fd, SIOCBRADDBR, brname) < 0) {
+ virReportSystemError(errno,
+ _("Unable to create bridge %s"), brname);
+ goto cleanup;
+ }
+
+ ret = 0;
+
+ cleanup:
+ VIR_FORCE_CLOSE(fd);
+ return ret;
+}
+#endif
+
#if defined(__linux__) && defined(HAVE_LIBNL)
-int virNetDevBridgeCreate(const char *brname)
+int
+virNetDevBridgeCreate(const char *brname)
{
/* use a netlink RTM_NEWLINK message to create the bridge */
const char *type = "bridge";
switch (err->error) {
case 0:
break;
+ case -EOPNOTSUPP:
+# if defined(HAVE_STRUCT_IFREQ) && defined(SIOCBRADDBR)
+ /* fallback to ioctl if netlink doesn't support creating
+ * bridges
+ */
+ rc = virNetDevBridgeCreateWithIoctl(brname);
+ goto cleanup;
+# endif
+ /* intentionally fall through if virNetDevBridgeCreateWithIoctl()
+ * isn't available.
+ */
default:
virReportSystemError(-err->error,
_("error creating bridge interface %s"),
_("allocated netlink buffer is too small"));
goto cleanup;
}
-#elif defined(HAVE_STRUCT_IFREQ) && defined(SIOCBRADDBR)
-int virNetDevBridgeCreate(const char *brname)
-{
- int fd = -1;
- int ret = -1;
- if ((fd = virNetDevSetupControl(NULL, NULL)) < 0)
- return -1;
- if (ioctl(fd, SIOCBRADDBR, brname) < 0) {
- virReportSystemError(errno,
- _("Unable to create bridge %s"), brname);
- goto cleanup;
- }
+#elif defined(HAVE_STRUCT_IFREQ) && defined(SIOCBRADDBR)
+int
+virNetDevBridgeCreate(const char *brname)
+{
+ return virNetDevBridgeCreateWithIoctl(brname);
+}
- ret = 0;
- cleanup:
- VIR_FORCE_CLOSE(fd);
- return ret;
-}
#elif defined(HAVE_STRUCT_IFREQ) && defined(SIOCIFCREATE2)
-int virNetDevBridgeCreate(const char *brname)
+int
+virNetDevBridgeCreate(const char *brname)
{
int s;
struct ifreq ifr;