Revision: 577
http://sourceforge.net/p/vde/svn/577
Author: rd235
Date: 2014-02-10 08:42:37 +0000 (Mon, 10 Feb 2014)
Log Message:
-----------
vxvde complete. reasonably solved ipv6 mcast pbm
Modified Paths:
--------------
branches/rd235/vde-2/src/lib/libvdeplug/libvdeplug_vxhash.c
branches/rd235/vde-2/src/lib/libvdeplug/libvdeplug_vxhash.h
branches/rd235/vde-2/src/lib/libvdeplug/libvdeplug_vxlan.c
branches/rd235/vde-2/src/lib/libvdeplug/libvdeplug_vxvde.c
Modified: branches/rd235/vde-2/src/lib/libvdeplug/libvdeplug_vxhash.c
===================================================================
--- branches/rd235/vde-2/src/lib/libvdeplug/libvdeplug_vxhash.c 2014-02-08
21:35:19 UTC (rev 576)
+++ branches/rd235/vde-2/src/lib/libvdeplug/libvdeplug_vxhash.c 2014-02-10
08:42:37 UTC (rev 577)
@@ -127,3 +127,8 @@
return calloc(hash_mask+1, elsize);
}
+void vx_hash_fini(void *table)
+{
+ if (table != NULL)
+ free(table);
+}
Modified: branches/rd235/vde-2/src/lib/libvdeplug/libvdeplug_vxhash.h
===================================================================
--- branches/rd235/vde-2/src/lib/libvdeplug/libvdeplug_vxhash.h 2014-02-08
21:35:19 UTC (rev 576)
+++ branches/rd235/vde-2/src/lib/libvdeplug/libvdeplug_vxhash.h 2014-02-10
08:42:37 UTC (rev 577)
@@ -31,5 +31,7 @@
/* init the hash table */
/* hash_mask must be 2^n - 1 */
void *vx_hash_init(int sa_family, int hash_mask);
+
+void vx_hash_fini(void *table);
#endif
Modified: branches/rd235/vde-2/src/lib/libvdeplug/libvdeplug_vxlan.c
===================================================================
--- branches/rd235/vde-2/src/lib/libvdeplug/libvdeplug_vxlan.c 2014-02-08
21:35:19 UTC (rev 576)
+++ branches/rd235/vde-2/src/lib/libvdeplug/libvdeplug_vxlan.c 2014-02-10
08:42:37 UTC (rev 577)
@@ -300,6 +300,7 @@
static int vde_vxlan_close(VDECONN *conn) {
struct vde_vxlan_conn *vde_conn = (struct vde_vxlan_conn *)conn;
close(vde_conn->multifd);
+ vx_hash_fini(vde_conn->table);
free(vde_conn);
return 0;
}
Modified: branches/rd235/vde-2/src/lib/libvdeplug/libvdeplug_vxvde.c
===================================================================
--- branches/rd235/vde-2/src/lib/libvdeplug/libvdeplug_vxvde.c 2014-02-08
21:35:19 UTC (rev 576)
+++ branches/rd235/vde-2/src/lib/libvdeplug/libvdeplug_vxvde.c 2014-02-10
08:42:37 UTC (rev 577)
@@ -34,7 +34,16 @@
#include <netdb.h>
#include "libvdeplug_mod.h"
#include "libvdeplug_vxhash.h"
+/* two alternatives to check whether an ip addr is local:
+LOCALBIND: try to open and bind a socket to the same addr (any port), if it
succeeds it is local!
+!LOCALBIND: use getifaddrs and look through the list */
+//#define LOCALBIND
+#ifndef LOCALBIND
+#include <ifaddrs.h>
+#endif
+
+//#define DEBUGADDR
#define STDPORTSTR "14879"
#define STDTTL 1
#define STDVNI 1
@@ -74,21 +83,24 @@
static int vde_vxvde_ctlfd(VDECONN *conn);
static int vde_vxvde_close(VDECONN *conn);
+union sockaddr46 {
+ struct sockaddr vx;
+ struct sockaddr_in v4;
+ struct sockaddr_in6 v6;
+};
+
struct vde_vxvde_conn {
struct vdeplug_module *module;
void *table;
int hash_mask; // hash table size - 1. This must be 2^n-1
int vni;
- union {
- struct sockaddr vx;
- struct sockaddr_in v4;
- struct sockaddr_in6 v6;
- } multiaddr;
+ union sockaddr46 multiaddr;
+ union sockaddr46 localaddr;
+ in_port_t multiport;
+ in_port_t uniport;
int multifd;
int unifd;
int pollfd;
- in_port_t multiport;
- in_port_t uniport;
int expiretime;
};
@@ -125,7 +137,67 @@
}
}
-#if 0
+static int is_a_localaddr(void *sockaddr)
+{
+ struct sockaddr *s=sockaddr;
+ int retval=0;
+#ifdef LOCALBIND
+ switch (s->sa_family) {
+ case AF_INET: {
+
int tmpfd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
if (tmpfd >= 0) {
+
struct sockaddr_in s4=*((struct sockaddr_in *)s);
+
s4.sin_port = 0;
+
if (bind(tmpfd, (struct sockaddr *) &s4, sizeof(s4))==0)
+
retval=1;
+
close(tmpfd);
+
}
+ }
+ break;
+ case AF_INET6: {
+
int tmpfd=socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+
if (tmpfd >= 0) {
+
struct sockaddr_in6 s6=*((struct sockaddr_in6 *)s);
+
s6.sin6_port = 0;
+
if (bind(tmpfd, (struct sockaddr *) &s6, sizeof(s6))==0)
+
retval=1;
+
close(tmpfd);
+
}
+ }
+ break;
+ }
+#else /* GETIFADDRS */
+ struct ifaddrs *addrs;
+ if (getifaddrs(&addrs) == 0) {
+ struct ifaddrs *ifa;
+ for (ifa = addrs; ifa != NULL && retval == 0; ifa =
ifa->ifa_next){
+ if (s->sa_family == ifa->ifa_addr->sa_family) {
+ switch (s->sa_family) {
+ case AF_INET: {
+
struct sockaddr_in *s6=(struct sockaddr_in *)s;
+
struct sockaddr_in *i6=(struct sockaddr_in
*)ifa->ifa_addr;
+
if (s6->sin_addr.s_addr == i6->sin_addr.s_addr)
+
retval=1;
+
}
+
break;
+ case AF_INET6: {
+
struct sockaddr_in6 *s6=(struct sockaddr_in6 *)s;
+
struct sockaddr_in6 *i6=(struct sockaddr_in6
*)ifa->ifa_addr;
+
if (memcmp(&s6->sin6_addr,&i6->sin6_addr,sizeof(struct
in6_addr)) == 0)
+
retval=1;
+
}
+
break;
+ }
+ }
+ }
+ freeifaddrs(addrs);
+ }
+#endif
+ return retval;
+}
+
+
+#ifdef DEBUGADDR
static inline void printaddr(char *msg, void *sockaddr)
{
struct sockaddr *s=sockaddr;
@@ -297,12 +369,12 @@
goto error;
uniport=bindaddr.sin_port;
//fprintf(stderr,"local port %d\n",ntohs(bindaddr.sin_port));
-
/*static char buf[]="test";
-
socklen_t addrs=sizeof(struct sockaddr_in);
-
sendto(unifd, buf, strlen(buf)+1, 0, (struct sockaddr *) addr, addrs);*/
}
+ default:
+
uniport=0;
}
}
+ freeaddrinfo(result);
if (multifd < 0)
return NULL;
@@ -332,10 +404,12 @@
switch (multiaddr->sa_family) {
case AF_INET:
memcpy(&(newconn->multiaddr.v4), multiaddr,
sizeof(struct sockaddr_in));
+ memcpy(&(newconn->localaddr.v4), multiaddr,
sizeof(struct sockaddr_in));
newconn->multiport = newconn->multiaddr.v4.sin_port;
break;
case AF_INET6:
memcpy(&(newconn->multiaddr.v6), multiaddr,
sizeof(struct sockaddr_in6));
+ memcpy(&(newconn->localaddr.v6), multiaddr,
sizeof(struct sockaddr_in6));
newconn->multiport = newconn->multiaddr.v6.sin6_port;
break;
}
@@ -381,7 +455,7 @@
char cmsg[CMSG_SPACE(sizeof(struct
in6_pktinfo)+sizeof(struct in_pktinfo))];
int retval;
msg.msg_name=&sender;
- msg.msg_namelen = fam2socklen(&vde_conn->multiaddr.vx);
+ msg.msg_namelen = sizeof(sender);
msg.msg_iov=iov;
msg.msg_iovlen=2;
msg.msg_control=cmsg;
@@ -392,6 +466,10 @@
//printaddr("recv multi",&sender);
if (__builtin_expect((retval > ETH_HEADER_SIZE), 1)) {
struct eth_hdr *ehdr=(struct eth_hdr *) buf;
+ if (vhdr.flags != (1<<3) || ntoh24(vhdr.id) !=
vde_conn->vni) {
+ //fprintf(stderr,"wrong net id or
flags: rejected \n");
+ goto error;
+ }
switch (sender.ss_family) {
case AF_INET: {
struct sockaddr_in *sender4=(struct sockaddr_in
*)&sender;
@@ -405,29 +483,26 @@
}
}
case AF_INET6: {
+
/* workaround: there is not (yet) an ancillary msg for
IPv6 returning
+
the IP address of the local interface
where the packet was received,
+
i.e. the IPV6 counterpart of
ipi_spec_dst */
struct sockaddr_in6 *sender6=(struct sockaddr_in6
*)&sender;
-#if 0
-
{
-
struct cmsghdr *cmsgptr=CMSG_FIRSTHDR(&msg);
-
struct in6_pktinfo *pki=(struct in6_pktinfo
*)(CMSG_DATA(cmsgptr));
-
char saddr[INET6_ADDRSTRLEN];
-
fprintf(stderr,"CMPCMP %s
%d\n",inet_ntop(AF_INET6, &pki->ipi6_addr, saddr,
sizeof(pki->ipi6_addr)),pki->ipi6_ifindex);
-
}
-#endif
-
/* XXX this fails to recognize self sent packets */
if (sender6->sin6_port == vde_conn->uniport) {
-
struct cmsghdr *cmsgptr=CMSG_FIRSTHDR(&msg);
-
struct in6_pktinfo *pki=(struct in6_pktinfo
*)(CMSG_DATA(cmsgptr));
-
if (memcmp(&sender6->sin6_addr,
&pki->ipi6_addr, sizeof(struct in6_addr)) == 0) {
-
//fprintf(stderr,"self packet, rejected
\n");
+
if (memcmp(&sender6->sin6_addr,
&vde_conn->localaddr.v6.sin6_addr,
+
sizeof(struct
in6_addr)) == 0) {
+
//fprintf(stderr,"self packet short
path, rejected \n");
goto error;
+
}
+
else if (is_a_localaddr(sender6)) {
+
memcpy(&vde_conn->localaddr, sender6,
sizeof(struct sockaddr_in6));
+
//fprintf(stderr,"self packet long
path, rejected \n");
+
goto error;
}
}
}
}
- if (vhdr.flags != (1<<0) || ntoh24(vhdr.id) !=
vde_conn->vni)
- vx_find_in_hash_update(vde_conn->table,
vde_conn->hash_mask,
- ehdr->src, 1,
msg.msg_name, time(NULL));
+ vx_find_in_hash_update(vde_conn->table,
vde_conn->hash_mask,
+ ehdr->src, 1, msg.msg_name,
time(NULL));
return retval;
}
goto error;
@@ -452,13 +527,16 @@
0)) {
struct vxvde_hdr vhdr;
struct iovec iov[]={{&vhdr, sizeof(vhdr)},{(char *)buf, len}};
- static struct msghdr msg;
+ struct msghdr msg;
int retval;
destaddr=&(vde_conn->multiaddr.vx);
msg.msg_iov=iov;
msg.msg_iovlen=2;
msg.msg_name = destaddr;
msg.msg_namelen = fam2socklen(destaddr);
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
//printaddr("send multi",destaddr);
memset(&vhdr, 0, sizeof(vhdr));
vhdr.flags = (1 << 3);
@@ -489,7 +567,9 @@
static int vde_vxvde_close(VDECONN *conn) {
struct vde_vxvde_conn *vde_conn = (struct vde_vxvde_conn *)conn;
+ close(vde_conn->unifd);
close(vde_conn->multifd);
+ vx_hash_fini(vde_conn->table);
free(vde_conn);
return 0;
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Managing the Performance of Cloud-Based Applications
Take advantage of what the Cloud has to offer - Avoid Common Pitfalls.
Read the Whitepaper.
http://pubads.g.doubleclick.net/gampad/clk?id=121051231&iu=/4140/ostg.clktrk
_______________________________________________
vde-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/vde-users