Revision: 570
http://sourceforge.net/p/vde/svn/570
Author: rd235
Date: 2014-01-30 10:52:17 +0000 (Thu, 30 Jan 2014)
Log Message:
-----------
vde_vxlan: initial release on experimental version
Modified Paths:
--------------
branches/rd235/vde-2/.gitignore
branches/rd235/vde-2/configure.ac
branches/rd235/vde-2/man/Makefile.am
branches/rd235/vde-2/src/Makefile.am
Added Paths:
-----------
branches/rd235/vde-2/man/vde_vxlan.1
branches/rd235/vde-2/src/vde_vxlan/
branches/rd235/vde-2/src/vde_vxlan/Makefile.am
branches/rd235/vde-2/src/vde_vxlan/log.c
branches/rd235/vde-2/src/vde_vxlan/log.h
branches/rd235/vde-2/src/vde_vxlan/plug.c
branches/rd235/vde-2/src/vde_vxlan/plug.h
branches/rd235/vde-2/src/vde_vxlan/vde_vxlan.c
branches/rd235/vde-2/src/vde_vxlan/vxlan.c
branches/rd235/vde-2/src/vde_vxlan/vxlan.h
branches/rd235/vde-2/src/vde_vxlan/vxlan_hash.c
branches/rd235/vde-2/src/vde_vxlan/vxlan_hash.h
Modified: branches/rd235/vde-2/.gitignore
===================================================================
--- branches/rd235/vde-2/.gitignore 2014-01-30 10:32:16 UTC (rev 569)
+++ branches/rd235/vde-2/.gitignore 2014-01-30 10:52:17 UTC (rev 570)
@@ -42,6 +42,7 @@
src/vde_cryptcab/vde_cryptcab
src/vde_l3/vde_l3
src/vde_over_ns/vde_over_ns
+src/vde_vxlan/vde_vxlan
src/vde_pcapplug
src/vde_plug
src/vde_plug2tap
Modified: branches/rd235/vde-2/configure.ac
===================================================================
--- branches/rd235/vde-2/configure.ac 2014-01-30 10:32:16 UTC (rev 569)
+++ branches/rd235/vde-2/configure.ac 2014-01-30 10:52:17 UTC (rev 570)
@@ -124,6 +124,13 @@
[Disable libcrypto-dependend vde_cryptcab compilation]),
[if test $enableval = "no" ; then add_cryptcab_support=no ; warn_cryptcab=no
; fi])
+enable_vxlan=yes
+# Disable vde_vxlan?
+AC_ARG_ENABLE([vxlan],
+ AS_HELP_STRING([--disable-vxlan],
+ [Disable vde_vxlan compilation]),
+ [if test $enableval = "no" ; then enable_vxlan=no ;
warn_vxlan=no ; fi])
+
# Check of tuntap device
AC_ARG_ENABLE([tuntap],
AS_HELP_STRING([--disable-tuntap], [Disable tuntap compilation]), [:],
@@ -212,6 +219,7 @@
AM_CONDITIONAL(ENABLE_CRYPTCAB, test "$add_cryptcab_support" = yes)
+AM_CONDITIONAL(ENABLE_VXLAN, test "$enable_vxlan" = yes)
AM_CONDITIONAL(ENABLE_PYTHON, test "$enable_python" = yes)
AM_CONDITIONAL(ENABLE_PCAP, test "$add_pcap" = yes)
AM_CONDITIONAL(CAN_MAKE_LIBVDETAP, test "$can_make_libvdetap" = yes)
@@ -245,6 +253,7 @@
[src/vdetaplib/Makefile]
[src/vde_l3/Makefile]
[src/vde_cryptcab/Makefile]
+ [src/vde_vxlan/Makefile]
[src/slirpvde/Makefile]
[src/vde_switch/plugins/Makefile]
)
@@ -261,12 +270,25 @@
AS_ECHO " - VDE CryptCab............ disabled"
fi
+if test x$enable_vxlan = "xyes" ; then
+ AS_ECHO " + VDE VXLAN............... enabled"
+else
+ AS_ECHO " - VDE VXLAN............... disabled"
+fi
+
if test x$enable_python = "xyes" ; then
AS_ECHO " + Python Libraries........ enabled"
else
AS_ECHO " - Python Libraries........ disabled"
fi
+if ! test x$enable_vxlan = "xyes" ; then
+ if test x$warn_vxlan = "xyes" ; then
+ AC_MSG_WARN([VDE VXLAN support has been disabled.])
+ AS_ECHO
+ fi
+fi
+
if test x$warn_tuntap = "xyes" ; then
AS_ECHO " - TAP support............. disabled"
else
Modified: branches/rd235/vde-2/man/Makefile.am
===================================================================
--- branches/rd235/vde-2/man/Makefile.am 2014-01-30 10:32:16 UTC (rev
569)
+++ branches/rd235/vde-2/man/Makefile.am 2014-01-30 10:52:17 UTC (rev
570)
@@ -1,4 +1,5 @@
-static_mans = dpipe.1 slirpvde.1 unixterm.1 vde_plug.1 vdeq.1 vde_switch.1
wirefilter.1 vde_cryptcab.1 vde_plug2tap.1 vde_over_ns.1 vde_l3.1 vde_tunctl.8
vde_autolink.1 unixcmd.1 vdeterm.1
+static_mans = dpipe.1 slirpvde.1 unixterm.1 vde_plug.1 vdeq.1 vde_switch.1
wirefilter.1 vde_cryptcab.1 vde_plug2tap.1 vde_over_ns.1 vde_l3.1 vde_tunctl.8
vde_autolink.1 unixcmd.1 vdeterm.1 vde_vxlan.1
+
if ENABLE_PCAP
static_mans += vde_pcapplug.1
endif
Added: branches/rd235/vde-2/man/vde_vxlan.1
===================================================================
--- branches/rd235/vde-2/man/vde_vxlan.1 (rev 0)
+++ branches/rd235/vde-2/man/vde_vxlan.1 2014-01-30 10:52:17 UTC (rev
570)
@@ -0,0 +1,78 @@
+.TH VDE_VXLAN 1 "October 26, 2013" "Virtual Distributed Ethernet"
+.SH NAME
+vde_vxlan \- VXLAN tunnel endpoint for VDE
+.SH SYNOPSIS
+.B vde_vxlan
+.BI --vxlan-id
+.I vxlan_id
+.BI --vxlan-addr
+.I multicast_address
+[
+.BI --vxlan-port
+.I udp_port
+]
+[
+.BI --vxlan-mttl
+.I multicast_ttl
+]
+[
+.BI --sock
+.I vde_socket_dir
+]
+[
+.BI --port
+.I vde_port
+]
+[
+.BI --daemon
+]
+[
+.BI --verbose
+]
+.br
+.SH DESCRIPTION
+A
+\fBvde_vxlan\fP
+is a Virtual eXtensible LAN (VXLAN) tunnel endpoint for the vde architecture,
+that can connect a \fBvde_switch (1)\fP to a VXLAN segment.
+
+.SH OPTIONS
+
+.TP
+.B --vxlan-id
+ID of the VXLAN (VNI)
+.TP
+.B --vxlan-addr
+Multicast address of the VXLAN
+.TP
+.B --vxlan-port
+Port of the VXLAN (default 4879)
+.TP
+.B --vxlan-mttl
+Multicast TTL (default 1)
+.TP
+.B --sock
+Socket directory of the VDE switch
+.TP
+.B --port
+Port of the VDE switch
+.TP
+.B --daemon
+Run in background
+.TP
+.B --verbose
+Show debug output
+
+.SH NOTICE
+Virtual Distributed Ethernet is not related in any way with
+www.vde.com ("Verband der Elektrotechnik, Elektronik und Informationstechnik"
+i.e. the German "Association for Electrical, Electronic & Information
+Technologies").
+
+.SH SEE ALSO
+\fBvde_switch\fP(1),
+.br
+.SH AUTHORS
+vde_vxlan is a tool by Alessandro Ghedini <[email protected]>
+
+VDE is a project by Renzo Davoli <[email protected]>
Modified: branches/rd235/vde-2/src/Makefile.am
===================================================================
--- branches/rd235/vde-2/src/Makefile.am 2014-01-30 10:32:16 UTC (rev
569)
+++ branches/rd235/vde-2/src/Makefile.am 2014-01-30 10:52:17 UTC (rev
570)
@@ -31,6 +31,10 @@
SUBDIRS += vde_cryptcab
endif
+if ENABLE_VXLAN
+ SUBDIRS += vde_vxlan
+endif
+
if ENABLE_KERNEL_SWITCH
SUBDIRS += kvde_switch
endif
Added: branches/rd235/vde-2/src/vde_vxlan/Makefile.am
===================================================================
--- branches/rd235/vde-2/src/vde_vxlan/Makefile.am
(rev 0)
+++ branches/rd235/vde-2/src/vde_vxlan/Makefile.am 2014-01-30 10:52:17 UTC
(rev 570)
@@ -0,0 +1,14 @@
+moddir = $(pkglibdir)/vde_vxlan
+
+AM_LDFLAGS =
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src/vde_switch -I.
+
+if ENABLE_PROFILE
+ AM_CFLAGS = -pg --coverage
+ AM_LDFLAGS += -pg --coverage
+endif
+
+bin_PROGRAMS = vde_vxlan
+vde_vxlan_SOURCES = vde_vxlan.c vxlan_hash.c log.c plug.c vxlan.c
+vde_vxlan_LDADD = $(top_builddir)/src/common/libvdecommon.la \
+ $(top_builddir)/src/lib/libvdeplug/libvdeplug.la
Added: branches/rd235/vde-2/src/vde_vxlan/log.c
===================================================================
--- branches/rd235/vde-2/src/vde_vxlan/log.c (rev 0)
+++ branches/rd235/vde-2/src/vde_vxlan/log.c 2014-01-30 10:52:17 UTC (rev
570)
@@ -0,0 +1,56 @@
+/*
+ * VDE - vde_vxlan Network emulator for vde
+ * Copyright (C) 2014 Renzo Davoli, Alessandro Ghedini VirtualSquare
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdarg.h>
+
+#include "log.h"
+
+static const char *prog = "vde_vxlan";
+
+int logok = 0;
+int debug = 0;
+
+void printlog(int priority, const char *format, ...) {
+ va_list arg;
+
+ if (!debug && priority == LOG_DEBUG)
+ return;
+
+ va_start(arg, format);
+ if (logok)
+ vsyslog(priority, format, arg);
+ else {
+ fprintf(stderr, "%s: ", prog);
+ vfprintf(stderr, format, arg);
+ fprintf(stderr, "\n");
+ }
+ va_end(arg);
+}
+
+void printoutc(FILE *f, const char *format, ...) {
+ va_list arg;
+
+ va_start (arg, format);
+ if (f) {
+ vfprintf(f,format,arg);
+ fprintf(f,"\n");
+ } else
+ printlog(LOG_INFO,format,arg);
+ va_end(arg);
+}
Added: branches/rd235/vde-2/src/vde_vxlan/log.h
===================================================================
--- branches/rd235/vde-2/src/vde_vxlan/log.h (rev 0)
+++ branches/rd235/vde-2/src/vde_vxlan/log.h 2014-01-30 10:52:17 UTC (rev
570)
@@ -0,0 +1,29 @@
+/*
+ * VDE - vde_vxlan Network emulator for vde
+ * Copyright (C) 2014 Renzo Davoli, Alessandro Ghedini VirtualSquare
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <syslog.h>
+
+extern int logok;
+extern int debug;
+
+void printlog(int priority, const char *format, ...);
+void printoutc(FILE *f, const char *format, ...);
Added: branches/rd235/vde-2/src/vde_vxlan/plug.c
===================================================================
--- branches/rd235/vde-2/src/vde_vxlan/plug.c (rev 0)
+++ branches/rd235/vde-2/src/vde_vxlan/plug.c 2014-01-30 10:52:17 UTC (rev
570)
@@ -0,0 +1,107 @@
+/*
+ * VDE - vde_vxlan Network emulator for vde
+ * Copyright (C) 2014 Renzo Davoli, Alessandro Ghedini VirtualSquare
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdlib.h>
+#include <poll.h>
+
+#include <libvdeplug.h>
+
+#include "vxlan_hash.h"
+#include "log.h"
+#include "vxlan.h"
+#include "plug.h"
+
+static VDECONN *conn;
+
+void plug_open(char *path, int port, struct pollfd *pfd) {
+ struct vde_open_args open_args = {
+ .port = port,
+ .group = NULL,
+ .mode = 0700
+ };
+
+ conn = vde_open(path, "vde_vxlan:", &open_args);
+
+ if (conn == NULL) {
+ printlog(LOG_ERR,"vde_open(\"%s\"): %s", path ? path
+ : "DEF_SWITCH", strerror(errno));
+ exit(1);
+ }
+
+ pfd[0].fd = vde_ctlfd(conn);
+ pfd[0].events = POLLIN | POLLHUP;
+
+ pfd[1].fd = vde_datafd(conn);
+ pfd[1].events = POLLIN | POLLHUP;
+}
+
+void plug_process() {
+ struct vxlan_pkt pkt;
+
+ in_addr_t dest_addr;
+
+ int nx = vde_recv(conn, (void *) &pkt.pkt, sizeof(pkt), 0);
+
+ if (nx < 0)
+ printlog(LOG_ERR, "vde_recv(): %s",
+ strerror(errno));
+
+ printlog(LOG_DEBUG, "VDE packet");
+
+ find_in_hash_update(pkt.pkt.header.src, vxlan_id, 1, NULL);
+
+ if ((pkt.pkt.header.dest[0] == 0xff) &&
+ (pkt.pkt.header.dest[1] == 0xff) &&
+ (pkt.pkt.header.dest[2] == 0xff) &&
+ (pkt.pkt.header.dest[3] == 0xff) &&
+ (pkt.pkt.header.dest[4] == 0xff) &&
+ (pkt.pkt.header.dest[5] == 0xff)) {
+ printlog(LOG_DEBUG, "Broadcast send");
+
+ vxlan_send(0, &pkt, nx);
+ return;
+ }
+
+ find_in_hash(pkt.pkt.header.dest, vxlan_id, &dest_addr);
+
+ if (dest_addr == 0) {
+ printlog(LOG_DEBUG, "Multicast send");
+ vxlan_send(0, &pkt, nx);
+ return;
+ }
+
+ if (dest_addr > 1) {
+ struct in_addr a;
+ a.s_addr = dest_addr;
+ printlog(LOG_DEBUG, "Send to %s", inet_ntoa(a));
+
+ vxlan_send(dest_addr, &pkt, nx);
+ }
+}
+
+void plug_send(struct eth_pkt *pkt, size_t len) {
+ int nx = vde_send(conn, pkt, len, 0);
+
+ if (nx < 0)
+ printlog(LOG_ERR, "vde_send(): %s", strerror(errno));
+}
+
+void plug_close() {
+ vde_close(conn);
+}
Added: branches/rd235/vde-2/src/vde_vxlan/plug.h
===================================================================
--- branches/rd235/vde-2/src/vde_vxlan/plug.h (rev 0)
+++ branches/rd235/vde-2/src/vde_vxlan/plug.h 2014-01-30 10:52:17 UTC (rev
570)
@@ -0,0 +1,24 @@
+/*
+ * VDE - vde_vxlan Network emulator for vde
+ * Copyright (C) 2014 Renzo Davoli, Alessandro Ghedini VirtualSquare
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+void plug_open(char *path, int port, struct pollfd *pfd);
+void plug_close();
+
+void plug_process();
+void plug_send(struct eth_pkt *p, size_t len);
Added: branches/rd235/vde-2/src/vde_vxlan/vde_vxlan.c
===================================================================
--- branches/rd235/vde-2/src/vde_vxlan/vde_vxlan.c
(rev 0)
+++ branches/rd235/vde-2/src/vde_vxlan/vde_vxlan.c 2014-01-30 10:52:17 UTC
(rev 570)
@@ -0,0 +1,169 @@
+/*
+ * VDE - vde_vxlan Network emulator for vde
+ * Copyright (C) 2014 Renzo Davoli, Alessandro Ghedini VirtualSquare
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdlib.h>
+#include <getopt.h>
+#include <poll.h>
+#include <unistd.h>
+
+#include "vxlan_hash.h"
+#include "log.h"
+#include "vxlan.h"
+#include "plug.h"
+
+/* from vde_switch/switch.h */
+
+#define INIT_HASH_SIZE 128
+
+void cleanup();
+void help();
+
+int main(int argc, char *argv[]) {
+ int opts;
+ struct pollfd pfd[3];
+
+ char *plug_addr = NULL;
+ int plug_port = 0;
+
+ int daemonize = 0;
+
+ const char *short_opts = "I:A:P:T:s:p:dvh";
+ struct option long_opts[] = {
+ { "vxlan-id", required_argument, 0, 'I' },
+ { "vxlan-addr", required_argument, 0, 'A' },
+ { "vxlan-port", required_argument, 0, 'P' },
+ { "vxlan-mttl", required_argument, 0, 'T' },
+
+ { "sock", required_argument, 0, 's' },
+ { "port", required_argument, 0, 'p' },
+
+ { "daemon", no_argument, 0, 'd' },
+ { "verbose", no_argument, 0, 'v' },
+
+ { "help", no_argument, 0, 'h' },
+ {0, 0, 0, 0}
+ };
+
+ while ((opts = getopt_long(argc, argv, short_opts, long_opts, 0)) !=
-1) {
+ switch (opts) {
+ /* VXLAN opts */
+ case 'I': { vxlan_id = atoi(optarg); break; }
+ /* TODO: IPv6 support */
+ case 'A': { vxlan_addr = inet_addr(optarg); break; }
+ case 'P': { vxlan_port = atoi(optarg); break; }
+ case 'T': { vxlan_mttl = atoi(optarg); break; }
+
+ /* VDE opts */
+ case 's': { plug_addr = strdup(optarg); break; }
+ case 'p': { plug_port = atoi(optarg); break; }
+
+ case 'd': { daemonize = 1; break; }
+ case 'v': { debug = 1; break; }
+
+ default :
+ case 'h': { help(); exit(1); }
+ }
+ }
+
+ if (vxlan_id == -1) {
+ printlog(LOG_ERR, "Invalid VXLAN ID");
+ exit(1);
+ }
+
+ if (vxlan_addr == INADDR_NONE) {
+ printlog(LOG_ERR, "Invalid VXLAN multicast address");
+ exit(1);
+ }
+
+ atexit(cleanup);
+
+ plug_open(plug_addr, plug_port, pfd);
+
+ vxlan_open(pfd);
+
+ hash_init(INIT_HASH_SIZE);
+
+ if (daemonize && daemon(0, 0)) {
+ printlog(LOG_ERR, "daemon(): %s", strerror(errno));
+ return 1;
+ } else if (daemonize) {
+ logok = 1;
+ openlog("vde_vxlan", LOG_PID, 0);
+ printlog(LOG_INFO, "VDE_VXLAN started");
+ }
+
+ while (1) {
+ int n = poll(pfd, 3, 1000);
+
+ if ((n < 0) && (errno != EINTR)) {
+ printlog(LOG_ERR, "poll(): %s", strerror(errno));
+ return 1;
+ }
+
+ if (pfd[0].revents & POLLHUP) {
+ printlog(LOG_INFO, "VDE connection closed");
+ return 0;
+ }
+
+ if (pfd[1].revents & POLLHUP) {
+ printlog(LOG_ERR, "VDE connection error");
+ }
+
+ if (pfd[1].revents & POLLIN) {
+ plug_process();
+ }
+
+ if (pfd[2].revents & POLLIN) {
+ vxlan_process();
+ }
+
+ hash_gc();
+ }
+
+ return 0;
+}
+
+void cleanup() {
+ vxlan_close();
+ plug_close();
+}
+
+void help() {
+ #define CMD_HELP(CMDL, CMDS, MSG) printf(" %s, %s\t%s.\n", CMDS, CMDL,
MSG);
+
+ puts("Usage: vde_vxlan [OPTIONS]\n");
+ puts(" VXLAN Options:");
+
+ CMD_HELP("--vxlan-id", "-I", "ID of the VXLAN");
+ CMD_HELP("--vxlan-addr", "-A", "Multicast address of the VXLAN");
+ CMD_HELP("--vxlan-port", "-P", "Port of the VXLAN (default 4879)");
+ CMD_HELP("--vxlan-mttl", "-T", "Multicast TTL (default 1)");
+
+ puts("\n VDE Options:");
+
+ CMD_HELP("--sock", "-s", "Socket directory of the VDE switch");
+ CMD_HELP("--port", "-p", "Port of the VDE switch");
+
+ CMD_HELP("--daemon", "-d", "Run in background");
+ CMD_HELP("--verbose", "-v", "Show debug output");
+
+ CMD_HELP("--help", "-h", "Show this help");
+
+ puts("");
+}
Added: branches/rd235/vde-2/src/vde_vxlan/vxlan.c
===================================================================
--- branches/rd235/vde-2/src/vde_vxlan/vxlan.c (rev 0)
+++ branches/rd235/vde-2/src/vde_vxlan/vxlan.c 2014-01-30 10:52:17 UTC (rev
570)
@@ -0,0 +1,187 @@
+/*
+ * VDE - vde_vxlan Network emulator for vde
+ * Copyright (C) 2014 Renzo Davoli, Alessandro Ghedini VirtualSquare
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <poll.h>
+
+#include <netinet/in.h>
+#include <sys/un.h>
+
+#include "vxlan_hash.h"
+#include "log.h"
+#include "vxlan.h"
+#include "plug.h"
+
+#define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2]))
+#define hton24(p, v) { \
+ p[0] = (((v) >> 16) & 0xFF); \
+ p[1] = (((v) >> 8) & 0xFF); \
+ p[2] = ((v) & 0xFF); \
+}
+
+int vxlan_id = -1;
+in_addr_t vxlan_addr = INADDR_NONE;
+int vxlan_port = 4879;
+int vxlan_mttl = 1;
+
+static int vxlan_fd = -1;
+
+void vxlan_open(struct pollfd *pfd) {
+ int sock;
+ int loop = 0;
+
+ struct ip_mreq mc_req;
+ struct sockaddr_in addr_in;
+
+ if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+ printlog(LOG_ERR, "socket(): %s", strerror(errno));
+ exit(1);
+ }
+
+ if ((setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL,
+ &vxlan_mttl, sizeof(vxlan_mttl))) < 0) {
+ printlog(LOG_ERR, "setsockopt(TTL): %s", strerror(errno));
+ exit(1);
+ }
+
+ if ((setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP,
+ &loop, sizeof(loop))) < 0) {
+ printlog(LOG_ERR, "setsockopt(LOOP): %s", strerror(errno));
+ exit(1);
+ }
+
+ memset(&addr_in, 0, sizeof(addr_in));
+ addr_in.sin_family = AF_INET;
+ addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
+ addr_in.sin_port = htons(vxlan_port);
+
+ if ((bind(sock, (struct sockaddr *) &addr_in, sizeof(addr_in))) < 0) {
+ printlog(LOG_ERR, "bind(): %s", strerror(errno));
+ exit(1);
+ }
+
+ /* send an IGMP join request */
+ mc_req.imr_multiaddr.s_addr = vxlan_addr;
+ mc_req.imr_interface.s_addr = htonl(INADDR_ANY);
+
+ if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ &mc_req, sizeof(mc_req))) < 0) {
+ printlog(LOG_ERR, "setsockopt(ADD): %s", strerror(errno));
+ exit(1);
+ }
+
+ vxlan_fd = sock;
+
+ pfd[2].fd = sock;
+ pfd[2].events = POLLIN | POLLHUP;
+}
+
+void vxlan_process() {
+ struct vxlan_pkt pkt;
+
+ struct sockaddr_in src_addr;
+ socklen_t src_addr_len=sizeof(src_addr);
+
+ in_addr_t dest_addr;
+
+ size_t len = recvfrom(vxlan_fd, &pkt, sizeof(pkt), 0,
+ (struct sockaddr *) &src_addr, &src_addr_len);
+
+ if (len < 0)
+ printlog(LOG_ERR, "recvfrom(): %s", strerror(errno));
+
+ printlog(LOG_DEBUG, "VXLAN packet from
%s",inet_ntoa(src_addr.sin_addr));
+
+ if (pkt.flags != (1<<3)) {
+ printlog(LOG_ERR, "Invalid flags");
+ return;
+ }
+
+ if (ntoh24(pkt.id) != vxlan_id) {
+ printlog(LOG_DEBUG, "Invalid VNI");
+ return;
+ }
+
+ find_in_hash_update(pkt.pkt.header.src, vxlan_id,
+ src_addr.sin_addr.s_addr, NULL);
+
+ if ((pkt.pkt.header.dest[0] == 0xff) &&
+ (pkt.pkt.header.dest[1] == 0xff) &&
+ (pkt.pkt.header.dest[2] == 0xff) &&
+ (pkt.pkt.header.dest[3] == 0xff) &&
+ (pkt.pkt.header.dest[4] == 0xff) &&
+ (pkt.pkt.header.dest[5] == 0xff)) {
+ printlog(LOG_DEBUG, "Broadcast send");
+
+ plug_send(&pkt.pkt, len-offsetof(struct vxlan_pkt,pkt));
+ return;
+ }
+
+ find_in_hash(pkt.pkt.header.dest, vxlan_id, &dest_addr);
+
+ switch (dest_addr) {
+ case 0:
+ printlog(LOG_DEBUG, "Not found");
+ case 1:
+ plug_send(&pkt.pkt,len-offsetof(struct vxlan_pkt,pkt));
+ printlog(LOG_DEBUG, "Send to VDE");
+ break;
+
+ default:
+ printlog(LOG_DEBUG, "Drop");
+ break;
+ }
+}
+
+void vxlan_send(in_addr_t addr_s, struct vxlan_pkt *pkt, size_t len) {
+ struct sockaddr_in addr;
+
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = addr_s ? addr_s : vxlan_addr;
+ addr.sin_port = htons(vxlan_port);
+
+ memset(pkt, 0, offsetof(struct vxlan_pkt,pkt));
+ pkt->flags = (1 << 3);
+
+ hton24(pkt->id, vxlan_id);
+
+ if (sendto(vxlan_fd, pkt, len+offsetof(struct vxlan_pkt,pkt), 0,
+ (struct sockaddr *) &addr, sizeof(addr)) < 0)
+ printlog(LOG_ERR, "sendto(): %s", strerror(errno));
+}
+
+void vxlan_close() {
+ if (vxlan_fd == -1)
+ return;
+
+ struct ip_mreq mc_req;
+
+ mc_req.imr_multiaddr.s_addr = vxlan_addr;
+ mc_req.imr_interface.s_addr = htonl(INADDR_ANY);
+
+ if ((setsockopt(vxlan_fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+ (void *) &mc_req, sizeof(mc_req))) < 0) {
+ printlog(LOG_ERR, "setsockopt(DROP): %s", strerror(errno));
+ exit(1);
+ }
+
+ close(vxlan_fd);
+}
Added: branches/rd235/vde-2/src/vde_vxlan/vxlan.h
===================================================================
--- branches/rd235/vde-2/src/vde_vxlan/vxlan.h (rev 0)
+++ branches/rd235/vde-2/src/vde_vxlan/vxlan.h 2014-01-30 10:52:17 UTC (rev
570)
@@ -0,0 +1,56 @@
+/*
+ * VDE - vde_vxlan Network emulator for vde
+ * Copyright (C) 2014 Renzo Davoli, Alessandro Ghedini VirtualSquare
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+/* from vde_switch/port.h */
+
+#define ETH_ALEN 6
+#define ETH_HEADER_SIZE 14
+
+struct eth_hdr {
+ unsigned char dest[ETH_ALEN];
+ unsigned char src[ETH_ALEN];
+ unsigned char proto[2];
+};
+
+struct eth_pkt {
+ struct eth_hdr header;
+ unsigned char data[1504]; /*including trailer, IF ANY */
+};
+
+struct vxlan_pkt {
+ unsigned char flags;
+ unsigned char priv1[3];
+ unsigned char id[3];
+ unsigned char priv2[1];
+ struct eth_pkt pkt;
+};
+
+extern int vxlan_id;
+extern in_addr_t vxlan_addr;
+extern int vxlan_port;
+extern int vxlan_mttl;
+
+void vxlan_open(struct pollfd *pfd);
+void vxlan_close();
+
+void vxlan_process();
+void vxlan_send(in_addr_t addr, struct vxlan_pkt *p, size_t len);
Added: branches/rd235/vde-2/src/vde_vxlan/vxlan_hash.c
===================================================================
--- branches/rd235/vde-2/src/vde_vxlan/vxlan_hash.c
(rev 0)
+++ branches/rd235/vde-2/src/vde_vxlan/vxlan_hash.c 2014-01-30 10:52:17 UTC
(rev 570)
@@ -0,0 +1,244 @@
+/*
+ * VDE - vde_vxlan Network emulator for vde
+ * Copyright (C) 2014 Renzo Davoli, Alessandro Ghedini VirtualSquare
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/signal.h>
+
+#include <config.h>
+#include <vde.h>
+#include <vdecommon.h>
+
+#include "log.h"
+#include "switch.h"
+#include "vxlan_hash.h"
+#include "consmgmt.h"
+#include "bitarray.h"
+
+#define MIN_PERSISTENCE_DFL 3
+static int min_persistence=MIN_PERSISTENCE_DFL;
+#define HASH_INIT_BITS 7
+static int hash_bits;
+static int hash_mask;
+#define HASH_SIZE (1 << hash_bits)
+
+struct hash_entry {
+ struct hash_entry *next;
+ struct hash_entry **prev;
+ time_t last_seen;
+ in_addr_t port;
+ u_int64_t dst;
+};
+
+static struct hash_entry **h;
+
+static int calc_hash(u_int64_t src)
+{
+ src ^= src >> 33;
+ src *= 0xff51afd7ed558ccd;
+ src ^= src >> 33;
+ src *= 0xc4ceb9fe1a85ec53;
+ return src & hash_mask;
+}
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define EMAC2MAC6(X) \
+ (u_int)((X)&0xff), (u_int)(((X)>>8)&0xff), (u_int)(((X)>>16)&0xff), \
+ (u_int)(((X)>>24)&0xff), (u_int)(((X)>>32)&0xff), (u_int)(((X)>>40)&0xff)
+#elif BYTE_ORDER == BIG_ENDIAN
+#define EMAC2MAC6(X) \
+ (u_int)(((X)>>24)&0xff), (u_int)(((X)>>16)&0xff),
(u_int)(((X)>>8)&0xff), \
+ (u_int)((X)&0xff), (u_int)(((X)>>40)&0xff), (u_int)(((X)>>32)&0xff)
+#else
+#error Unknown Endianess
+#endif
+
+#define EMAC2VLAN(X) ((u_int16_t) ((X)>>48))
+#define EMAC2VLAN2(X) ((u_int) (((X)>>48) &0xff)), ((u_int) (((X)>>56) &0xff))
+
+#define find_entry(MAC) \
+ ({struct hash_entry *e; \
+ int k = calc_hash(MAC);\
+ for(e = h[k]; e && e->dst != (MAC); e = e->next)\
+ ;\
+ e; })
+
+
+#define extmac(MAC,VLAN) \
+ ((*(u_int32_t *) &((MAC)[0])) + ((u_int64_t) ((*(u_int16_t *)
&((MAC)[4]))+ ((u_int64_t) (VLAN) << 16)) << 32))
+
+/* looks in global hash table 'h' for given address, and return associated
+ * port */
+int find_in_hash(unsigned char *dst, int vlan, in_addr_t *out)
+{
+ struct hash_entry *e = find_entry(extmac(dst,vlan));
+ *out = 0;
+ if(e == NULL) return 0;
+ *out = e->port;
+ return 1;
+}
+
+int find_in_hash_update(unsigned char *src, int vlan, in_addr_t port,
in_addr_t *out)
+{
+ struct hash_entry *e;
+ u_int64_t esrc=extmac(src,vlan);
+ int k = calc_hash(esrc);
+ in_addr_t oldport;
+ time_t now;
+ for(e = h[k]; e && e->dst != esrc; e = e->next)
+ ;
+ if(e == NULL) {
+ e = (struct hash_entry *) malloc(sizeof(*e));
+ if(e == NULL){
+ printlog(LOG_WARNING,"Failed to malloc hash entry
%s",strerror(errno));
+ return 0;
+ }
+
+ DBGOUT(DBGHASHNEW,"%02x:%02x:%02x:%02x:%02x:%02x VLAN %02x:%02x
Port %d",
+ EMAC2MAC6(esrc), EMAC2VLAN2(esrc), port);
+ EVENTOUT(DBGHASHNEW,esrc);
+ e->dst = esrc;
+ if(h[k] != NULL) h[k]->prev = &(e->next);
+ e->next = h[k];
+ e->prev = &(h[k]);
+ e->port = port;
+ h[k] = e;
+ }
+ oldport=e->port;
+ now=time(NULL);
+ if (oldport!=port) {
+ if ((now - e->last_seen) > min_persistence) {
+ e->port=port;
+ e->last_seen = now;
+ }
+ } else {
+ e->last_seen = now;
+ }
+ if (out != NULL) *out = oldport;
+ return 1;
+}
+
+#define delete_hash_entry(OLD) \
+ ({ \
+ DBGOUT(DBGHASHDEL,"%02x:%02x:%02x:%02x:%02x:%02x VLAN %02x:%02x Port
%d", EMAC2MAC6(OLD->dst), EMAC2VLAN2(OLD->dst), OLD->port); \
+ EVENTOUT(DBGHASHDEL,OLD->dst);\
+ *((OLD)->prev)=(OLD)->next; \
+ if((OLD)->next != NULL) (OLD)->next->prev = (OLD)->prev; \
+ free((OLD)); \
+ })
+
+
+/* for each entry of the global hash table 'h', calls function f, passing to it
+ * the hash entry and the additional arg 'arg' */
+static void for_all_hash(void (*f)(struct hash_entry *, void *), void *arg)
+{
+ int i;
+ struct hash_entry *e, *next;
+
+ for(i = 0; i < HASH_SIZE; i++){
+ for(e = h[i]; e; e = next){
+ next = e->next;
+ (*f)(e, arg);
+ }
+ }
+}
+
+#define GC_INTERVAL 2
+#define GC_EXPIRE 100
+static int gc_interval;
+static int gc_expire;
+
+/* clean from the hash table entries older than GC_EXPIRE seconds, given that
+ * 'now' points to a time_t structure describing the current time */
+static void gc(struct hash_entry *e, void *now)
+{
+ time_t t = *(time_t *) now;
+ if(e->last_seen + gc_expire < t)
+ delete_hash_entry(e);
+}
+
+/* clean old entries in the hash table 'h', and prepare the timer to be called
+ * again between GC_INTERVAL seconds */
+void hash_gc(void)
+{
+ time_t t = time(NULL);
+ static time_t last_t;
+ if (t - last_t > GC_INTERVAL) {
+ for_all_hash(&gc, &t);
+ last_t=t;
+ }
+}
+
+#define HASH_INIT(BIT) \
+ ({ hash_bits=(BIT);\
+ hash_mask=HASH_SIZE-1;\
+ if ((h=(struct hash_entry **) calloc (HASH_SIZE,sizeof (struct
hash_entry *))) == NULL) {\
+ printlog(LOG_WARNING,"Failed to malloc hash table
%s",strerror(errno));\
+ exit(1); \
+ }\
+ })
+
+static inline int po2round(int vx)
+{
+ if (vx == 0)
+ return 0;
+ else {
+ register int i=0;
+ register int x=vx-1;
+ while (x) { x>>=1; i++; }
+ if (vx != 1<<i)
+ printlog(LOG_WARNING,"Hash size must be a power of 2.
%d rounded to %d",vx,1<<i);
+ return i;
+ }
+}
+
+int hash_set_gc_interval(int p)
+{
+ gc_interval=p;
+ return 0;
+}
+
+int hash_set_gc_expire(int e)
+{
+ gc_expire=e;
+ return 0;
+}
+
+int hash_set_minper(int e)
+{
+ min_persistence=e;
+ return 0;
+}
+
+/* sets sig_alarm as handler for SIGALRM, and run it a first time */
+void hash_init(int hash_size)
+{
+ HASH_INIT(po2round(hash_size));
+
+ gc_interval=GC_INTERVAL;
+ gc_expire=GC_EXPIRE;
+}
Added: branches/rd235/vde-2/src/vde_vxlan/vxlan_hash.h
===================================================================
--- branches/rd235/vde-2/src/vde_vxlan/vxlan_hash.h
(rev 0)
+++ branches/rd235/vde-2/src/vde_vxlan/vxlan_hash.h 2014-01-30 10:52:17 UTC
(rev 570)
@@ -0,0 +1,35 @@
+/*
+ * VDE - vde_vxlan Network emulator for vde
+ * Copyright (C) 2014 Renzo Davoli, Alessandro Ghedini VirtualSquare
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <netinet/in.h>
+
+#ifndef __HASH_H__
+#define __HASH_H__
+
+extern int find_in_hash(unsigned char *dst, int vlan, in_addr_t *out);
+extern int find_in_hash_update(unsigned char *dst, int vlan, in_addr_t port,
in_addr_t *out);
+
+extern in_addr_t find_in_hash_v6(unsigned char *dst, int vlan, unsigned char
*out);
+extern in_addr_t find_in_hash_update_v6(unsigned char *dst, int vlan, unsigned
char *port, unsigned char *out);
+
+extern void hash_gc(void);
+
+extern void hash_init(int hash_size);
+
+#endif
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
WatchGuard Dimension instantly turns raw network data into actionable
security intelligence. It gives you real-time visual feedback on key
security issues and trends. Skip the complicated setup - simply import
a virtual appliance and go from zero to informed in seconds.
http://pubads.g.doubleclick.net/gampad/clk?id=123612991&iu=/4140/ostg.clktrk
_______________________________________________
vde-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/vde-users