diff --git a/src/drivers/drivers.mak b/src/drivers/drivers.mak index 9434078..7d8786c 100644 --- a/src/drivers/drivers.mak +++ b/src/drivers/drivers.mak @@ -145,6 +145,10 @@ DRV_WPA_OBJS += ../src/drivers/driver_wext.o NEED_RFKILL=y endif +ifdef CONFIG_OPENVSWITCH +DRV_CFLAGS += -DCONFIG_OPENVSWITCH +endif + ifdef NEED_NETLINK DRV_OBJS += ../src/drivers/netlink.o endif diff --git a/src/drivers/drivers.mk b/src/drivers/drivers.mk index 8da4c53..4cee638 100644 --- a/src/drivers/drivers.mk +++ b/src/drivers/drivers.mk @@ -132,6 +132,10 @@ DRV_WPA_OBJS += src/drivers/driver_wext.c NEED_RFKILL=y endif +ifdef CONFIG_OPENVSWITCH +DRV_CFLAGS += -DCONFIG_OPENVSWITCH +endif + ifdef NEED_NETLINK DRV_OBJS += src/drivers/netlink.c endif diff --git a/src/drivers/linux_ioctl.c b/src/drivers/linux_ioctl.c index 837971d..f666e27 100644 --- a/src/drivers/linux_ioctl.c +++ b/src/drivers/linux_ioctl.c @@ -14,6 +14,69 @@ #include "utils/common.h" #include "linux_ioctl.h" +#ifdef CONFIG_OPENVSWITCH +#include +#include + +#define run_prog(p, ...) ({ \ + struct stat q; \ + int rc = -1, status; \ + if(stat(p, &q) == 0) \ + { \ + pid_t pid = fork(); \ + if (!pid) \ + exit(execl(p, p, ##__VA_ARGS__, NULL)); \ + if (pid < 0) { \ + rc = -1; \ + } else { \ + while ((rc = waitpid(pid, &status, 0)) == -1 && errno == EINTR); \ + rc = (rc == pid && WIFEXITED(status)) ? WEXITSTATUS(status) : -1; \ + } \ + } \ + rc; \ +}) + +int ovs_br_get(char *brname, const char *ifname) +{ + FILE *f; + char cmd[64]; + char *c; + struct stat q; + + if(stat("/usr/bin/ovs-vsctl", &q) != 0) + return -1; + + brname[0] = '\0'; + sprintf(cmd, "/usr/bin/ovs-vsctl iface-to-br %s", ifname); + f = popen(cmd, "r"); + if (!f) + return -1; + c = fgets(brname, IFNAMSIZ, f); + pclose(f); + if (c && strlen(brname)) { + /* Ignore newline */ + if ((c = strchr(brname, '\n'))) + *c = '\0'; + return 0; + } + return -1; +} + +int ovs_br_add_if(const char *brname, const char *ifname) +{ + if (run_prog("/usr/bin/ovs-vsctl", "add-port", brname, ifname)) + return -1; + return 0; +} + +int ovs_br_del_if(const char *brname, const char *ifname) +{ + if (run_prog("/usr/bin/ovs-vsctl", "del-port", brname, ifname)) + return -1; + return 0; +} + +#endif int linux_set_iface_flags(int sock, const char *ifname, int dev_up) { @@ -118,7 +181,6 @@ int linux_set_ifhwaddr(int sock, const char *ifname, const u8 *addr) return 0; } - #ifndef SIOCBRADDBR #define SIOCBRADDBR 0x89a0 #endif @@ -162,6 +224,11 @@ int linux_br_add_if(int sock, const char *brname, const char *ifname) struct ifreq ifr; int ifindex; +#ifdef CONFIG_OPENVSWITCH + if (!ovs_br_add_if(brname, ifname)) + return 0; +#endif + ifindex = if_nametoindex(ifname); if (ifindex == 0) return -1; @@ -184,6 +251,11 @@ int linux_br_del_if(int sock, const char *brname, const char *ifname) struct ifreq ifr; int ifindex; +#ifdef CONFIG_OPENVSWITCH + if (!ovs_br_del_if(brname, ifname)) + return 0; +#endif + ifindex = if_nametoindex(ifname); if (ifindex == 0) return -1; @@ -206,6 +278,11 @@ int linux_br_get(char *brname, const char *ifname) char path[128], brlink[128], *pos; ssize_t res; +#ifdef CONFIG_OPENVSWITCH + if (!ovs_br_get(brname, ifname)) + return 0; +#endif + os_snprintf(path, sizeof(path), "/sys/class/net/%s/brport/bridge", ifname); res = readlink(path, brlink, sizeof(brlink)); @@ -219,3 +296,4 @@ int linux_br_get(char *brname, const char *ifname) os_strlcpy(brname, pos, IFNAMSIZ); return 0; } +