mirror of
https://github.com/ntop/n2n.git
synced 2024-09-08 04:01:11 +02:00
support linux l2 bridge (#1044)
* support linux l2 bridge * unified timeout name * typo * minor code style adaptions * feature define * feature define * feature define * feature define * added hint to bridging to help output * added hint to bridging * drafted bridging documentation * added bridging hint --------- Co-authored-by: Logan oos Even <46396513+Logan007@users.noreply.github.com>
This commit is contained in:
parent
39b9c6b1c0
commit
e01daf4a85
|
@ -31,10 +31,12 @@ It is available a special community which provides interconnection between super
|
|||
The [TAP Configuration Guide](TapConfiguration.md) contains hints on various settings that can be applied to the virtual network device, including IPv6 addresses as well as notes on MTU and on how to draw IP addresses from DHCP servers.
|
||||
|
||||
|
||||
## Routing the Traffic
|
||||
## Bridging and Routing the Traffic
|
||||
|
||||
Reaching a remote network or tunneling all the internet traffic via n2n are two common tasks which require a proper routing setup. n2n supports routing needs by temporarily modifying the routing table (`tools/n2n-route`). Details can be found in the [Routing document](Routing.md).
|
||||
|
||||
Also, n2n supports [Bridging](Bridging.md) of LANs, e.g. to connect otherwise un-connected LANs by an encrypted n2n tunnel on level 2.
|
||||
|
||||
|
||||
## Traffic Restrictions
|
||||
|
||||
|
|
27
doc/Bridging.md
Normal file
27
doc/Bridging.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Bridging (Linux)
|
||||
|
||||
## General Remarks
|
||||
|
||||
`edge`s can be part of network bridges. As such, n2n can connect otherwise un-connected LANs.
|
||||
|
||||
## How To Use with `brctl`
|
||||
|
||||
... requires `-r`
|
||||
... general syntax
|
||||
... one example connecting two remote sites' LANs, including commands
|
||||
|
||||
## How it works
|
||||
|
||||
... remembers peer info MAC
|
||||
... ageing
|
||||
... internal MAC replaced inside usually encrypted packet data (no disclosure then)
|
||||
... initial learning
|
||||
|
||||
## Broadcasts
|
||||
|
||||
... note on broadcast domain
|
||||
|
||||
## Compile Time Option
|
||||
|
||||
The `-r`option at edge does not differentiate between the use cases _routing_ and _bridging_. In case the MAC-learning and MAC-replacing bridging code
|
||||
interfers with some special routing scenario, removal of the `#define HAVE_BRIDGING_SUPPORT` from `/include/n2n.h` file disables it at compile time.
|
3
edge.8
3
edge.8
|
@ -132,7 +132,8 @@ specify n2n MTU of TAP interface, default 1290
|
|||
\fB\-r\fR
|
||||
enable IP packet forwarding/routing through the n2n virtual LAN. Without this
|
||||
option, IP packets arriving over n2n are dropped if not for the -a <addr> (or
|
||||
DHCP assigned) IP address of the edge interface.
|
||||
DHCP assigned) IP address of the edge interface. This option is also required
|
||||
to allow n2n device being used in network bridging, e.g. with brctl.
|
||||
.TP
|
||||
\fB\-E\fR
|
||||
accept packets destined for multicast ethernet MAC addresses. These addresses
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#define N2N_HAVE_DAEMON /* needs to be defined before it gets undefined */
|
||||
#define N2N_HAVE_TCP /* needs to be defined before it gets undefined */
|
||||
#define HAVE_BRIDGING_SUPPORT
|
||||
|
||||
/* #define N2N_CAN_NAME_IFACE */
|
||||
|
||||
|
|
|
@ -51,7 +51,9 @@
|
|||
#define REGISTER_SUPER_INTERVAL_DFL 20 /* sec, usually UDP NAT entries in a firewall expire after 30 seconds */
|
||||
#define SWEEP_TIME 30 /* sec, indicates the value after which we have to sort the hash list of supernodes in edges
|
||||
* and when we send out packets to query selection-relevant informations from supernodes. */
|
||||
|
||||
#ifdef HAVE_BRIDGING_SUPPORT
|
||||
#define HOSTINFO_TIMEOUT 300 /* sec, how long after last seen will the hostinfo be deleted */
|
||||
#endif
|
||||
#define NUMBER_SN_PINGS_INITIAL 15 /* number of supernodes to concurrently ping during bootstrap and immediately afterwards */
|
||||
#define NUMBER_SN_PINGS_REGULAR 5 /* number of supernodes to concurrently ping during regular edge operation */
|
||||
|
||||
|
|
|
@ -470,6 +470,15 @@ struct peer_info {
|
|||
|
||||
typedef struct peer_info peer_info_t;
|
||||
|
||||
#ifdef HAVE_BRIDGING_SUPPORT
|
||||
struct host_info {
|
||||
n2n_mac_t mac_addr;
|
||||
n2n_mac_t edge_addr;
|
||||
time_t last_seen;
|
||||
UT_hash_handle hh; /* makes this structure hashable */
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct n2n_edge n2n_edge_t;
|
||||
|
||||
/* *************************************************** */
|
||||
|
@ -723,8 +732,10 @@ struct n2n_edge {
|
|||
/* Peers */
|
||||
struct peer_info * known_peers; /**< Edges we are connected to. */
|
||||
struct peer_info * pending_peers; /**< Edges we have tried to register with. */
|
||||
|
||||
/* Timers */
|
||||
#ifdef HAVE_BRIDGING_SUPPORT
|
||||
struct host_info * known_hosts; /**< hosts we know. */
|
||||
#endif
|
||||
/* Timers */
|
||||
time_t last_register_req; /**< Check if time to re-register with super*/
|
||||
time_t last_p2p; /**< Last time p2p traffic was received. */
|
||||
time_t last_sup; /**< Last time a packet arrived from supernode. */
|
||||
|
|
|
@ -306,7 +306,8 @@ static void help (int level) {
|
|||
printf(" -d <device> | TAP device name\n");
|
||||
#endif
|
||||
printf(" -M <mtu> | specify n2n MTU of TAP interface, default %d\n", DEFAULT_MTU);
|
||||
printf(" -r | enable packet forwarding through n2n community\n");
|
||||
printf(" -r | enable packet forwarding through n2n community,\n"
|
||||
" | also required for bridging\n");
|
||||
printf(" -E | accept multicast MAC addresses, drop by default\n");
|
||||
printf(" -I <description> | annotate the edge's description used for easier\n"
|
||||
" | identification in management port output or username\n");
|
||||
|
|
|
@ -1763,6 +1763,24 @@ static int handle_PACKET (n2n_edge_t * eee,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_BRIDGING_SUPPORT
|
||||
if((eee->conf.allow_routing) && (!is_multi_broadcast(eh->shost))) {
|
||||
struct host_info *host = NULL;
|
||||
|
||||
HASH_FIND(hh, eee->known_hosts, eh->shost, sizeof(n2n_mac_t), host);
|
||||
if(host == NULL) {
|
||||
struct host_info *host = calloc(1, sizeof(struct host_info));
|
||||
memcpy(host->mac_addr, eh->shost, sizeof(n2n_mac_t));
|
||||
memcpy(host->edge_addr, pkt->srcMac, sizeof(n2n_mac_t));
|
||||
host->last_seen = now;
|
||||
HASH_ADD(hh, eee->known_hosts, mac_addr, sizeof(n2n_mac_t), host);
|
||||
} else {
|
||||
memcpy(host->edge_addr, pkt->srcMac, sizeof(n2n_mac_t));
|
||||
host->last_seen = now;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(eee->network_traffic_filter->filter_packet_from_peer(eee->network_traffic_filter, eee, orig_sender,
|
||||
eth_payload, eth_size) == N2N_DROP) {
|
||||
traceEvent(TRACE_DEBUG, "filtered packet of size %u", (unsigned int)eth_size);
|
||||
|
@ -2014,6 +2032,16 @@ void edge_send_packet2net (n2n_edge_t * eee,
|
|||
/* Once processed, send to destination in PACKET */
|
||||
|
||||
memcpy(destMac, tap_pkt, N2N_MAC_SIZE); /* dest MAC is first in ethernet header */
|
||||
#ifdef HAVE_BRIDGING_SUPPORT
|
||||
/* find the destMac behind which edge, and change dest to this edge */
|
||||
if((eee->conf.allow_routing) && (!is_multi_broadcast(destMac))) {
|
||||
struct host_info *host = NULL;
|
||||
HASH_FIND(hh, eee->known_hosts, destMac, sizeof(n2n_mac_t), host);
|
||||
if(host) {
|
||||
memcpy(destMac, host->edge_addr, N2N_MAC_SIZE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(&cmn, 0, sizeof(cmn));
|
||||
cmn.ttl = N2N_DEFAULT_TTL;
|
||||
|
@ -2821,6 +2849,9 @@ int run_edge_loop (n2n_edge_t *eee) {
|
|||
time_t lastTransop = 0;
|
||||
time_t last_purge_known = 0;
|
||||
time_t last_purge_pending = 0;
|
||||
#ifdef HAVE_BRIDGING_SUPPORT
|
||||
time_t last_purge_host = 0;
|
||||
#endif
|
||||
|
||||
uint16_t expected = sizeof(uint16_t);
|
||||
uint16_t position = 0;
|
||||
|
@ -2956,6 +2987,19 @@ int run_edge_loop (n2n_edge_t *eee) {
|
|||
HASH_COUNT(eee->known_peers));
|
||||
}
|
||||
|
||||
#ifdef HAVE_BRIDGING_SUPPORT
|
||||
if((eee->conf.allow_routing) && (now > last_purge_host + SWEEP_TIME)) {
|
||||
struct host_info *host, *host_tmp;
|
||||
HASH_ITER(hh, eee->known_hosts, host, host_tmp) {
|
||||
if(now > host->last_seen + HOSTINFO_TIMEOUT) {
|
||||
HASH_DEL(eee->known_hosts, host);
|
||||
free(host);
|
||||
}
|
||||
}
|
||||
last_purge_host = now;
|
||||
}
|
||||
#endif
|
||||
|
||||
if((eee->conf.tuntap_ip_mode == TUNTAP_IP_MODE_DHCP) &&
|
||||
((now - lastIfaceCheck) > IFACE_UPDATE_INTERVAL)) {
|
||||
uint32_t old_ip = eee->device.ip_addr;
|
||||
|
@ -3010,6 +3054,16 @@ void edge_term (n2n_edge_t * eee) {
|
|||
clear_peer_list(&eee->known_peers);
|
||||
clear_peer_list(&eee->conf.supernodes);
|
||||
|
||||
#ifdef HAVE_BRIDGING_SUPPORT
|
||||
if(eee->conf.allow_routing) {
|
||||
struct host_info *host, *host_tmp;
|
||||
HASH_ITER(hh, eee->known_hosts, host, host_tmp) {
|
||||
HASH_DEL(eee->known_hosts, host);
|
||||
free(host);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
eee->transop.deinit(&eee->transop);
|
||||
eee->transop_lzo.deinit(&eee->transop_lzo);
|
||||
#ifdef HAVE_ZSTD
|
||||
|
|
Loading…
Reference in New Issue
Block a user