Commit 2382d0c2 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Move MTU sizing to network_up.

parent 123c69f2
...@@ -56,8 +56,6 @@ struct timeval now; ...@@ -56,8 +56,6 @@ struct timeval now;
unsigned char myid[16]; unsigned char myid[16];
int debug = 0; int debug = 0;
static int maxmtu;
int reboot_time; int reboot_time;
int idle_time = 320; int idle_time = 320;
...@@ -68,6 +66,9 @@ int wired_hello_interval = -1; ...@@ -68,6 +66,9 @@ int wired_hello_interval = -1;
int idle_hello_interval = -1; int idle_hello_interval = -1;
int update_interval = -1; int update_interval = -1;
unsigned char *receive_buffer = NULL;
int receive_buffer_size = 0;
const unsigned char zeroes[16] = {0}; const unsigned char zeroes[16] = {0};
const unsigned char ones[16] = const unsigned char ones[16] =
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
...@@ -92,7 +93,6 @@ main(int argc, char **argv) ...@@ -92,7 +93,6 @@ main(int argc, char **argv)
{ {
struct sockaddr_in6 sin6; struct sockaddr_in6 sin6;
int i, rc, fd; int i, rc, fd;
static unsigned char *buf;
struct timeval check_neighbours_time; struct timeval check_neighbours_time;
int expiry_time, kernel_dump_time; int expiry_time, kernel_dump_time;
char *config_file = NULL; char *config_file = NULL;
...@@ -334,45 +334,7 @@ main(int argc, char **argv) ...@@ -334,45 +334,7 @@ main(int argc, char **argv)
goto fail; goto fail;
} }
/* Just in case. */
maxmtu = 1500;
while(*arg) { while(*arg) {
int ifindex;
int mtu;
ifindex = if_nametoindex(*arg);
if(ifindex <= 0) {
fprintf(stderr, "Unknown interface %s.\n", *arg);
goto fail;
}
mtu = kernel_interface_mtu(*arg, ifindex);
if(mtu < 0) {
fprintf(stderr, "Warning: couldn't get MTU of interface %s (%d).\n",
*arg, ifindex);
mtu = 1280;
maxmtu = MAX(maxmtu, 0x10000);
} else if(mtu < 1280) {
fprintf(stderr,
"Warning: suspiciously low MTU %d on interface %s (%d).\n",
mtu, *arg, ifindex);
mtu = 1280;
maxmtu = MAX(maxmtu, 0x10000);
} else {
if(mtu >= 0x10000) {
fprintf(stderr,
"Warning: "
"suspiciously high MTU %d on interface %s (%d).\n",
mtu, *arg, ifindex);
maxmtu = MAX(maxmtu, mtu);
mtu = 32768;
}
}
maxmtu = MAX(maxmtu, mtu);
/* 40 for IPv6 header, 8 for UDP header, 12 for good luck. */
mtu -= 60;
debugf("Adding network %s.\n", *arg); debugf("Adding network %s.\n", *arg);
vrc = add_network(*arg); vrc = add_network(*arg);
if(vrc == NULL) if(vrc == NULL)
...@@ -380,9 +342,10 @@ main(int argc, char **argv) ...@@ -380,9 +342,10 @@ main(int argc, char **argv)
SHIFT(); SHIFT();
} }
buf = malloc(maxmtu); if(receive_buffer == NULL) {
if(buf == NULL) { /* No networks currently up ? */
perror("malloc"); resize_receive_buffer(1500);
if(receive_buffer == NULL)
goto fail; goto fail;
} }
...@@ -471,7 +434,8 @@ main(int argc, char **argv) ...@@ -471,7 +434,8 @@ main(int argc, char **argv)
kernel_callback(kernel_routes_callback, NULL); kernel_callback(kernel_routes_callback, NULL);
if(FD_ISSET(protocol_socket, &readfds)) { if(FD_ISSET(protocol_socket, &readfds)) {
rc = babel_recv(protocol_socket, buf, maxmtu, rc = babel_recv(protocol_socket,
receive_buffer, receive_buffer_size,
(struct sockaddr*)&sin6, sizeof(sin6)); (struct sockaddr*)&sin6, sizeof(sin6));
if(rc < 0) { if(rc < 0) {
if(errno != EAGAIN && errno != EINTR) { if(errno != EAGAIN && errno != EINTR) {
...@@ -484,8 +448,9 @@ main(int argc, char **argv) ...@@ -484,8 +448,9 @@ main(int argc, char **argv)
continue; continue;
if(nets[i].ifindex == sin6.sin6_scope_id) { if(nets[i].ifindex == sin6.sin6_scope_id) {
parse_packet((unsigned char*)&sin6.sin6_addr, &nets[i], parse_packet((unsigned char*)&sin6.sin6_addr, &nets[i],
buf, rc); receive_buffer, rc);
VALGRIND_MAKE_MEM_UNDEFINED(buf, maxmtu); VALGRIND_MAKE_MEM_UNDEFINED(receive_buffer,
receive_buffer_size);
break; break;
} }
} }
...@@ -651,6 +616,29 @@ main(int argc, char **argv) ...@@ -651,6 +616,29 @@ main(int argc, char **argv)
exit(1); exit(1);
} }
void
resize_receive_buffer(int size)
{
char *new;
if(size <= receive_buffer_size)
return;
if(receive_buffer == NULL) {
receive_buffer = malloc(size);
if(receive_buffer == NULL)
return;
receive_buffer_size = size;
}
new = realloc(receive_buffer, size);
if(new == NULL) {
perror("malloc(receive_buffer)");
return;
}
receive_buffer_size = size;
}
static void static void
sigexit(int signo) sigexit(int signo)
{ {
......
...@@ -77,3 +77,5 @@ extern unsigned char protocol_group[16]; ...@@ -77,3 +77,5 @@ extern unsigned char protocol_group[16];
extern int protocol_socket; extern int protocol_socket;
extern int kernel_socket; extern int kernel_socket;
extern int max_request_hopcount; extern int max_request_hopcount;
void resize_receive_buffer(int size);
...@@ -171,6 +171,8 @@ network_up(struct network *net, int up) ...@@ -171,6 +171,8 @@ network_up(struct network *net, int up)
return network_up(net, 0); return network_up(net, 0);
} }
resize_receive_buffer(mtu);
if(all_wireless) { if(all_wireless) {
wired = 1; wired = 1;
} else { } else {
...@@ -231,6 +233,25 @@ check_networks(void) ...@@ -231,6 +233,25 @@ check_networks(void)
unsigned char ipv4[4]; unsigned char ipv4[4];
for(i = 0; i < numnets; i++) { for(i = 0; i < numnets; i++) {
rc = kernel_interface_ipv4(nets[i].ifname, nets[i].ifindex, ipv4);
if(rc > 0) {
if(!nets[i].ipv4 || memcmp(ipv4, nets[i].ipv4, 4) != 0) {
debugf("Noticed IPv4 change for %s.\n", nets[i].ifname);
if(!nets[i].ipv4)
nets[i].ipv4 = malloc(4);
if(nets[i].ipv4)
memcpy(nets[i].ipv4, ipv4, 4);
changed = 1;
}
} else {
debugf("Noticed IPv4 change for %s.\n", nets[i].ifname);
if(nets[i].ipv4) {
free(nets[i].ipv4);
nets[i].ipv4 = NULL;
changed = 1;
}
}
ifindex = if_nametoindex(nets[i].ifname); ifindex = if_nametoindex(nets[i].ifname);
if(ifindex != nets[i].ifindex) { if(ifindex != nets[i].ifindex) {
debugf("Noticed ifindex change for %s.\n", nets[i].ifname); debugf("Noticed ifindex change for %s.\n", nets[i].ifname);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment