void process_fdb_etherflame_from_vxlan (struct vxlan_instance * vins, struct ether_header * ether, struct sockaddr_storage * vtep_addr) { struct fdb_entry * entry; entry = fdb_search_entry (vins->fdb, (u_int8_t *) ether->ether_shost); if (entry == NULL) { EXTRACT_PORT (*vtep_addr) = htons (VXLAN_PORT_BASE); fdb_add_entry (vins->fdb, (u_int8_t *) ether->ether_shost, *vtep_addr); #ifdef LOGGING_FDB_CHANGE syslog (LOG_INFO, "add entry %02x:%02x:%02x:%02x:%02x:%02x", ether->ether_shost[0], ether->ether_shost[1], ether->ether_shost[2], ether->ether_shost[3], ether->ether_shost[4], ether->ether_shost[5]); syslog (LOG_INFO, "Add, Number of FDB entry is %d", vins->fdb->fdb.count); #endif } else { if (MEMCMP_SOCKADDR (*vtep_addr, entry->vtep_addr) == 0) { entry->ttl = vins->fdb->fdb_max_ttl; } else { entry->vtep_addr = * vtep_addr; entry->ttl = vins->fdb->fdb_max_ttl; } } return; }
void send_etherframe_from_local_to_vxlan( struct vxlan_instance *instance, struct ether_header *ether, size_t len ) { assert( vxlan != NULL ); assert( instance != NULL ); assert( ether != NULL ); assert( len > 0 ); if ( !instance->activated || !vxlan->active ) { return; } struct vxlanhdr vhdr; memset( &vhdr, 0, sizeof( vhdr ) ); vhdr.flags = VXLAN_VALIDFLAG; memcpy( vhdr.vni, instance->vni, VXLAN_VNISIZE ); struct iovec iov[ 2 ]; memset( iov, 0, sizeof( iov ) ); iov[ 0 ].iov_base = &vhdr; iov[ 0 ].iov_len = sizeof( vhdr ); iov[ 1 ].iov_base = ether; iov[ 1 ].iov_len = len; struct msghdr mhdr; memset( &mhdr, 0, sizeof( mhdr ) ); mhdr.msg_iov = iov; mhdr.msg_iovlen = 2; mhdr.msg_controllen = 0; char buf[ 256 ]; struct fdb_entry *entry = fdb_search_entry( instance->fdb, ether->ether_dhost ); if ( entry == NULL ) { mhdr.msg_name = &instance->addr; mhdr.msg_namelen = sizeof( instance->addr ); if ( sendmsg( instance->udp_sock, &mhdr, 0 ) < 0 ) { char *error_string = safe_strerror_r( errno, buf, sizeof( buf ) ); warn( "Failed to send a vxlan message ( errno = %s [%d] ).", error_string, errno ); } } else { entry->vtep_addr.sin_port = htons( instance->port ); mhdr.msg_name = &entry->vtep_addr; mhdr.msg_namelen = sizeof( entry->vtep_addr ); if ( sendmsg( instance->udp_sock, &mhdr, 0 ) < 0 ) { char *error_string = safe_strerror_r( errno, buf, sizeof( buf ) ); warn( "Failed to send a vxlan message ( errno = %s [%d] ).", error_string, errno ); } } }
void process_fdb_etherflame_from_vxlan (struct ether_header * ether, struct in_addr * vtep_addr) { struct fdb_entry * entry; struct sockaddr_in * saddr_in; entry = fdb_search_entry (&vxlan.fdb, (u_int8_t *) ether->ether_shost); if (entry == NULL) fdb_add_entry (&vxlan.fdb, (u_int8_t *) ether->ether_shost, *vtep_addr); else { saddr_in = (struct sockaddr_in *) &entry->vtep_addr; if (saddr_in->sin_addr.s_addr != vtep_addr->s_addr) { saddr_in->sin_addr = *vtep_addr; } entry->ttl = FDB_CACHE_TTL; } return; }
void send_etherflame_from_local_to_vxlan (struct ether_header * ether, int len) { struct vxlan_hdr vhdr; struct fdb_entry * entry; struct msghdr mhdr; struct iovec iov[2]; memset (&vhdr, 0, sizeof (vhdr)); vhdr.vxlan_flags = VXLAN_VALIDFLAG; memcpy (vhdr.vxlan_vni, vxlan.vni, VXLAN_VNISIZE); iov[0].iov_base = &vhdr; iov[0].iov_len = sizeof (vhdr); iov[1].iov_base = ether; iov[1].iov_len = len; if ((entry = fdb_search_entry (&vxlan.fdb, (u_int8_t *)ether->ether_dhost)) == NULL) { mhdr.msg_name = &vxlan.mcast_saddr; mhdr.msg_namelen = sizeof (vxlan.mcast_saddr); mhdr.msg_iov = iov; mhdr.msg_iovlen = 2; mhdr.msg_controllen = 0; if (sendmsg (vxlan.mst_send_sock, &mhdr, 0) < 0) warn ("sendmsg to multicast failed"); } else { mhdr.msg_name = &entry->vtep_addr; mhdr.msg_namelen = sizeof (entry->vtep_addr); mhdr.msg_iov = iov; mhdr.msg_iovlen = 2; mhdr.msg_controllen = 0; if (sendmsg (vxlan.udp_sock, &mhdr, 0) < 0) warn ("sendmsg to unicast failed"); } return; }