Commit 5afde873 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Merge branch 'rfc6126bis'

parents 8627b6fc 3a4fbbf0
......@@ -582,8 +582,9 @@ main(int argc, char **argv)
send_hello(ifp);
send_wildcard_retraction(ifp);
send_self_update(ifp);
send_multicast_request(ifp, NULL, 0, NULL, 0);
flushupdates(ifp);
flushbuf(ifp);
flushbuf(&ifp->buf);
}
debugf("Entering main loop.\n");
......@@ -591,6 +592,7 @@ main(int argc, char **argv)
while(1) {
struct timeval tv;
fd_set readfds;
struct neighbour *neigh;
gettime(&now);
......@@ -603,12 +605,14 @@ main(int argc, char **argv)
FOR_ALL_INTERFACES(ifp) {
if(!if_up(ifp))
continue;
timeval_min(&tv, &ifp->flush_timeout);
timeval_min(&tv, &ifp->buf.timeout);
timeval_min(&tv, &ifp->hello_timeout);
timeval_min(&tv, &ifp->update_timeout);
timeval_min(&tv, &ifp->update_flush_timeout);
}
timeval_min(&tv, &unicast_flush_timeout);
FOR_ALL_NEIGHBOURS(neigh) {
timeval_min(&tv, &neigh->buf.timeout);
}
FD_ZERO(&readfds);
if(timeval_compare(&tv, &now) > 0) {
int maxfd = 0;
......@@ -770,17 +774,22 @@ main(int argc, char **argv)
do_resend();
}
if(unicast_flush_timeout.tv_sec != 0) {
if(timeval_compare(&now, &unicast_flush_timeout) >= 0)
flush_unicast(1);
}
FOR_ALL_INTERFACES(ifp) {
if(!if_up(ifp))
continue;
if(ifp->flush_timeout.tv_sec != 0) {
if(timeval_compare(&now, &ifp->flush_timeout) >= 0)
flushbuf(ifp);
if(ifp->buf.timeout.tv_sec != 0) {
if(timeval_compare(&now, &ifp->buf.timeout) >= 0) {
flushupdates(ifp);
flushbuf(&ifp->buf);
}
}
}
FOR_ALL_NEIGHBOURS(neigh) {
if(neigh->buf.timeout.tv_sec != 0) {
if(timeval_compare(&now, &neigh->buf.timeout) >= 0) {
flushbuf(&neigh->buf);
}
}
}
......@@ -803,8 +812,8 @@ main(int argc, char **argv)
send_wildcard_retraction(ifp);
/* Make sure that we expire quickly from our neighbours'
association caches. */
send_hello_noupdate(ifp, 10);
flushbuf(ifp);
send_hello_noihu(ifp, 10);
flushbuf(&ifp->buf);
usleep(roughly(1000));
gettime(&now);
}
......@@ -813,8 +822,8 @@ main(int argc, char **argv)
continue;
/* Make sure they got it. */
send_wildcard_retraction(ifp);
send_hello_noupdate(ifp, 1);
flushbuf(ifp);
send_hello_noihu(ifp, 1);
flushbuf(&ifp->buf);
usleep(roughly(10000));
gettime(&now);
interface_up(ifp, 0);
......@@ -1113,7 +1122,7 @@ dump_tables(FILE *out)
FOR_ALL_NEIGHBOURS(neigh) {
fprintf(out, "Neighbour %s dev %s reach %04x ureach %04x "
"rxcost %d txcost %d rtt %s rttcost %d chan %d%s.\n",
"rxcost %u txcost %d rtt %s rttcost %u chan %d%s.\n",
format_address(neigh->address),
neigh->ifp->name,
neigh->hello.reach,
......
......@@ -24,6 +24,8 @@ THE SOFTWARE.
#include <string.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <assert.h>
#ifdef __linux
......@@ -560,6 +562,12 @@ parse_anonymous_ifconf(int c, gnc_t gnc, void *closure,
if(c < -1)
goto error;
if_conf->faraway = v;
} else if(strcmp(token, "unicast") == 0) {
int v;
c = getbool(c, &v, gnc, closure);
if(c < -1)
goto error;
if_conf->unicast = v;
} else if(strcmp(token, "link-quality") == 0) {
int v;
c = getbool(c, &v, gnc, closure);
......@@ -711,6 +719,7 @@ merge_ifconf(struct interface_conf *dest,
MERGE(split_horizon);
MERGE(lq);
MERGE(faraway);
MERGE(unicast);
MERGE(channel);
MERGE(enable_timestamps);
MERGE(rfc6126);
......
......@@ -25,6 +25,8 @@ THE SOFTWARE.
#include <stdio.h>
#include <errno.h>
#include <assert.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include "babeld.h"
......
......@@ -80,8 +80,6 @@ add_interface(char *ifname, struct interface_conf *if_conf)
strncpy(ifp->name, ifname, IF_NAMESIZE);
ifp->conf = if_conf ? if_conf : default_interface_conf;
ifp->bucket_time = now.tv_sec;
ifp->bucket = BUCKET_TOKENS_MAX;
ifp->hello_seqno = (random() & 0xFFFF);
if(interfaces == NULL)
......@@ -132,14 +130,14 @@ flush_interface(char *ifname)
/* This should be no more than half the hello interval, so that hellos
aren't sent late. The result is in milliseconds. */
unsigned
jitter(struct interface *ifp, int urgent)
jitter(struct buffered *buf, int urgent)
{
unsigned interval = ifp->hello_interval;
unsigned interval = buf->flush_interval;
if(urgent)
interval = MIN(interval, 100);
interval = MIN(interval, 20);
else
interval = MIN(interval, 4000);
return roughly(interval) / 4;
interval = MIN(interval, 2000);
return roughly(interval / 2);
}
unsigned
......@@ -297,14 +295,20 @@ interface_up(struct interface *ifp, int up)
rc = kernel_setup_interface(1, ifp->name, ifp->ifindex);
if(rc < 0) {
fprintf(stderr, "kernel_setup_interface(%s, %d) failed.\n",
fprintf(stderr, "kernel_setup_interface(%s, %u) failed.\n",
ifp->name, ifp->ifindex);
goto fail;
}
memset(&ifp->buf.sin6, 0, sizeof(ifp->buf.sin6));
ifp->buf.sin6.sin6_family = AF_INET6;
memcpy(&ifp->buf.sin6.sin6_addr, protocol_group, 16);
ifp->buf.sin6.sin6_port = htons(protocol_port);
ifp->buf.sin6.sin6_scope_id = ifp->ifindex;
mtu = kernel_interface_mtu(ifp->name, ifp->ifindex);
if(mtu < 0) {
fprintf(stderr, "Warning: couldn't get MTU of interface %s (%d).\n",
fprintf(stderr, "Warning: couldn't get MTU of interface %s (%u).\n",
ifp->name, ifp->ifindex);
mtu = 1280;
}
......@@ -314,27 +318,27 @@ interface_up(struct interface *ifp, int up)
/* In IPv6, the minimum MTU is 1280, and every host must be able
to reassemble up to 1500 bytes, but I'd rather not rely on this. */
if(mtu < 128) {
fprintf(stderr, "Suspiciously low MTU %d on interface %s (%d).\n",
fprintf(stderr, "Suspiciously low MTU %d on interface %s (%u).\n",
mtu, ifp->name, ifp->ifindex);
mtu = 128;
}
if(ifp->sendbuf)
free(ifp->sendbuf);
if(ifp->buf.buf)
free(ifp->buf.buf);
/* 40 for IPv6 header, 8 for UDP header, 12 for good luck. */
ifp->bufsize = mtu - sizeof(packet_header) - 60;
ifp->sendbuf = malloc(ifp->bufsize);
if(ifp->sendbuf == NULL) {
ifp->buf.size = mtu - sizeof(packet_header) - 60;
ifp->buf.buf = malloc(ifp->buf.size);
if(ifp->buf.buf == NULL) {
fprintf(stderr, "Couldn't allocate sendbuf.\n");
ifp->bufsize = 0;
ifp->buf.size = 0;
goto fail;
}
rc = resize_receive_buffer(mtu);
if(rc < 0)
fprintf(stderr, "Warning: couldn't resize "
"receive buffer for interface %s (%d) (%d bytes).\n",
"receive buffer for interface %s (%u) (%d bytes).\n",
ifp->name, ifp->ifindex, mtu);
type = IF_CONF(ifp, type);
......@@ -345,7 +349,7 @@ interface_up(struct interface *ifp, int up)
rc = kernel_interface_wireless(ifp->name, ifp->ifindex);
if(rc < 0) {
fprintf(stderr,
"Warning: couldn't determine whether %s (%d) "
"Warning: couldn't determine whether %s (%u) "
"is a wireless interface.\n",
ifp->name, ifp->ifindex);
} else if(rc) {
......@@ -387,6 +391,9 @@ interface_up(struct interface *ifp, int up)
if(IF_CONF(ifp, faraway) == CONFIG_YES)
ifp->flags |= IF_FARAWAY;
if(IF_CONF(ifp, unicast) == CONFIG_YES)
ifp->flags |= IF_UNICAST;
if(IF_CONF(ifp, hello_interval) > 0)
ifp->hello_interval = IF_CONF(ifp, hello_interval);
else if(type == IF_TYPE_WIRELESS)
......@@ -399,6 +406,10 @@ interface_up(struct interface *ifp, int up)
IF_CONF(ifp, update_interval) :
ifp->hello_interval * 4;
/* This must be no more than half the Hello interval, or else
Hellos will arrive late. */
ifp->buf.flush_interval = ifp->hello_interval / 2;
ifp->rtt_decay =
IF_CONF(ifp, rtt_decay) > 0 ?
IF_CONF(ifp, rtt_decay) : 42;
......@@ -411,8 +422,8 @@ interface_up(struct interface *ifp, int up)
IF_CONF(ifp, rtt_max) : 120000;
if(ifp->rtt_max <= ifp->rtt_min) {
fprintf(stderr,
"Uh, rtt-max is less than or equal to rtt-min (%d <= %d). "
"Setting it to %d.\n", ifp->rtt_max, ifp->rtt_min,
"Uh, rtt-max is less than or equal to rtt-min (%u <= %u). "
"Setting it to %u.\n", ifp->rtt_max, ifp->rtt_min,
ifp->rtt_min + 10000);
ifp->rtt_max = ifp->rtt_min + 10000;
}
......@@ -421,23 +432,20 @@ interface_up(struct interface *ifp, int up)
ifp->max_rtt_penalty = 96;
if(IF_CONF(ifp, enable_timestamps) == CONFIG_YES)
ifp->flags |= IF_TIMESTAMPS;
ifp->buf.enable_timestamps = 1;
else if(IF_CONF(ifp, enable_timestamps) == CONFIG_NO)
ifp->flags &= ~IF_TIMESTAMPS;
ifp->buf.enable_timestamps = 0;
else if(type == IF_TYPE_TUNNEL)
ifp->flags |= IF_TIMESTAMPS;
ifp->buf.enable_timestamps = 1;
else
ifp->flags &= ~IF_TIMESTAMPS;
if(ifp->max_rtt_penalty > 0 && !(ifp->flags & IF_TIMESTAMPS))
ifp->buf.enable_timestamps = 0;
if(ifp->max_rtt_penalty > 0 && !ifp->buf.enable_timestamps)
fprintf(stderr,
"Warning: max_rtt_penalty is set "
"but timestamps are disabled on interface %s.\n",
ifp->name);
if(IF_CONF(ifp, rfc6126) == CONFIG_YES)
ifp->flags |= IF_RFC6126;
else
ifp->flags &= ~IF_RFC6126;
ifp->buf.rfc6126_compatible = (IF_CONF(ifp, rfc6126) == CONFIG_YES);
rc = check_link_local_addresses(ifp);
if(rc < 0) {
......@@ -472,17 +480,18 @@ interface_up(struct interface *ifp, int up)
send_hello(ifp);
if(rc > 0)
send_update(ifp, 0, NULL, 0, NULL, 0);
send_multicast_request(ifp, NULL, 0, NULL, 0);
} else {
flush_interface_routes(ifp, 0);
ifp->buffered = 0;
ifp->bufsize = 0;
free(ifp->sendbuf);
ifp->buf.len = 0;
ifp->buf.size = 0;
free(ifp->buf.buf);
ifp->num_buffered_updates = 0;
ifp->update_bufsize = 0;
if(ifp->buffered_updates)
free(ifp->buffered_updates);
ifp->buffered_updates = NULL;
ifp->sendbuf = NULL;
ifp->buf.buf = NULL;
if(ifp->ifindex > 0) {
memset(&mreq, 0, sizeof(mreq));
memcpy(&mreq.ipv6mr_multiaddr, protocol_group, 16);
......@@ -558,6 +567,7 @@ check_interfaces(void)
check_interface_channel(ifp);
rc = check_interface_ipv4(ifp);
if(rc > 0) {
send_multicast_request(ifp, NULL, 0, NULL, 0);
send_update(ifp, 0, NULL, 0, NULL, 0);
}
}
......
......@@ -45,6 +45,7 @@ struct interface_conf {
char split_horizon;
char lq;
char faraway;
char unicast;
int channel;
int enable_timestamps;
int rfc6126;
......@@ -69,16 +70,34 @@ struct interface_conf {
#define IF_LQ (1 << 3)
/* Nodes on the far end don't interfere with nodes on the near end. */
#define IF_FARAWAY (1 << 4)
/* Send timestamps in Hello and IHU. */
#define IF_TIMESTAMPS (1 << 5)
/* Remain compatible with RFC 6126. */
#define IF_RFC6126 (1 << 6)
/* Send most TLVs over unicast. */
#define IF_UNICAST (1 << 5)
/* Only INTERFERING can appear on the wire. */
#define IF_CHANNEL_UNKNOWN 0
#define IF_CHANNEL_INTERFERING 255
#define IF_CHANNEL_NONINTERFERING -2
struct buffered {
struct sockaddr_in6 sin6;
char *buf;
int len;
int size;
int flush_interval;
struct timeval timeout;
char enable_timestamps;
char rfc6126_compatible;
char have_id;
char have_nh;
char have_prefix;
unsigned char id[8];
unsigned char nh[4];
unsigned char prefix[16];
/* Relative position of the Hello message in the send buffer, or
(-1) if there is none. */
int hello;
};
struct interface {
struct interface *next;
struct interface_conf *conf;
......@@ -88,31 +107,16 @@ struct interface {
int channel;
struct timeval hello_timeout;
struct timeval update_timeout;
struct timeval flush_timeout;
struct timeval update_flush_timeout;
char name[IF_NAMESIZE];
unsigned char *ipv4;
int numll;
unsigned char (*ll)[16];
int buffered;
int bufsize;
/* Relative position of the Hello message in the send buffer, or
(-1) if there is none. */
int buffered_hello;
char have_buffered_id;
char have_buffered_nh;
char have_buffered_prefix;
unsigned char buffered_id[8];
unsigned char buffered_nh[4];
unsigned char buffered_prefix[16];
unsigned char *sendbuf;
struct buffered buf;
struct buffered_update *buffered_updates;
int num_buffered_updates;
int update_bufsize;
time_t bucket_time;
unsigned int bucket;
time_t last_update_time;
time_t last_specific_update_time;
unsigned short hello_seqno;
unsigned hello_interval;
unsigned update_interval;
......@@ -140,7 +144,7 @@ if_up(struct interface *ifp)
struct interface *add_interface(char *ifname, struct interface_conf *if_conf);
int flush_interface(char *ifname);
unsigned jitter(struct interface *ifp, int urgent);
unsigned jitter(struct buffered *buf, int urgent);
unsigned update_jitter(struct interface *ifp, int urgent);
void set_timeout(struct timeval *timeout, int msecs);
int interface_up(struct interface *ifp, int up);
......
......@@ -446,7 +446,7 @@ netlink_talk(struct nlmsghdr *nh)
nh->nlmsg_seq = ++nl_command.seqno;
kdebugf("Sending seqno %d from address %p (talk)\n",
nl_command.seqno, &nl_command.seqno);
nl_command.seqno, (void*)&nl_command.seqno);
rc = sendmsg(nl_command.sock, &msg, 0);
if(rc < 0 && (errno == EAGAIN || errno == EINTR)) {
......@@ -514,7 +514,7 @@ netlink_send_dump(int type, void *data, int len) {
buf.nh.nlmsg_len = NLMSG_LENGTH(len);
kdebugf("Sending seqno %d from address %p (dump)\n",
nl_command.seqno, &nl_command.seqno);
nl_command.seqno, (void*)&nl_command.seqno);
rc = sendmsg(nl_command.sock, &msg, 0);
if(rc < buf.nh.nlmsg_len) {
......@@ -677,14 +677,18 @@ kernel_setup_interface(int setup, const char *ifname, int ifindex)
fprintf(stderr,
"Warning: cannot save old configuration for %s.\n",
ifname);
rc = write_proc(buf, 0);
if(rc < 0)
return -1;
if(old_if[i].rp_filter) {
rc = write_proc(buf, 0);
if(rc < 0)
return -1;
}
} else {
if(i >= 0 && old_if[i].rp_filter >= 0)
if(i >= 0 && old_if[i].rp_filter > 0)
rc = write_proc(buf, old_if[i].rp_filter);
else
else if(i < 0)
rc = -1;
else
rc = 1;
if(rc < 0)
fprintf(stderr,
......@@ -1590,7 +1594,7 @@ add_rule(int prio, const unsigned char *src_prefix, int src_plen, int table)
message_header->nlmsg_len += current_attribute->rta_len;
current_attribute = (void*)
((char*)current_attribute) + current_attribute->rta_len;
((char*)current_attribute + current_attribute->rta_len);
/* src */
current_attribute->rta_len = RTA_LENGTH(addr_size);
......@@ -1599,7 +1603,7 @@ add_rule(int prio, const unsigned char *src_prefix, int src_plen, int table)
message_header->nlmsg_len += current_attribute->rta_len;
current_attribute = (void*)
((char*)current_attribute) + current_attribute->rta_len;
((char*)current_attribute + current_attribute->rta_len);
/* send message */
if(message_header->nlmsg_len > 64) {
......@@ -1652,7 +1656,7 @@ flush_rule(int prio, int family)
message_header->nlmsg_len += current_attribute->rta_len;
current_attribute = (void*)
((char*)current_attribute) + current_attribute->rta_len;
((char*)current_attribute + current_attribute->rta_len);
/* send message */
if(message_header->nlmsg_len > 64) {
......
......@@ -44,11 +44,13 @@ THE SOFTWARE.
#include <net/route.h>
#include "babeld.h"
#include "interface.h"
#include "neighbour.h"
#include "kernel.h"
#include "util.h"
static int get_sdl(struct sockaddr_dl *sdl, char *ifname);
static const unsigned char v4prefix[16] =
......@@ -586,7 +588,7 @@ print_kernel_route(int add, struct kernel_route *route)
memcpy(ifname,"unk",4);
fprintf(stderr,
"%s kernel route: dest: %s gw: %s metric: %d if: %s(%d) \n",
"%s kernel route: dest: %s gw: %s metric: %d if: %s(%u) \n",
add == RTM_ADD ? "Add" :
add == RTM_DELETE ? "Delete" : "Change",
format_prefix(route->prefix, route->plen),
......
......@@ -145,7 +145,7 @@ local_notify_neighbour_1(struct local_socket *s,
rttbuf[0] = '\0';
if(valid_rtt(neigh)) {
rc = snprintf(rttbuf, 64, " rtt %s rttcost %d",
rc = snprintf(rttbuf, 64, " rtt %s rttcost %u",
format_thousands(neigh->rtt), neighbour_rttcost(neigh));
if(rc < 0 || rc >= 64)
rttbuf[0] = '\0';
......@@ -154,7 +154,7 @@ local_notify_neighbour_1(struct local_socket *s,
rc = snprintf(buf, 512,
"%s neighbour %lx address %s "
"if %s reach %04x ureach %04x "
"rxcost %d txcost %d%s cost %d\n",
"rxcost %u txcost %u%s cost %u\n",
local_kind(kind),
/* Neighbours never move around in memory , so we can use the
address as a unique identifier. */
......
This diff is collapsed.
......@@ -22,9 +22,6 @@ THE SOFTWARE.
#define MAX_BUFFERED_UPDATES 200
#define BUCKET_TOKENS_MAX 4000
#define BUCKET_TOKENS_PER_SEC 1000
#define MESSAGE_PAD1 0
#define MESSAGE_PADN 1
#define MESSAGE_ACK_REQ 2
......@@ -37,15 +34,13 @@ THE SOFTWARE.
#define MESSAGE_REQUEST 9
#define MESSAGE_MH_REQUEST 10
/* 11 and 12 are for authentication */
#define MESSAGE_UPDATE_SRC_SPECIFIC 13
#define MESSAGE_REQUEST_SRC_SPECIFIC 14
#define MESSAGE_MH_REQUEST_SRC_SPECIFIC 15
/* Protocol extension through sub-TLVs. */
#define SUBTLV_PAD1 0
#define SUBTLV_PADN 1
#define SUBTLV_DIVERSITY 2 /* Also known as babelz. */
#define SUBTLV_TIMESTAMP 3 /* Used to compute RTT. */
#define SUBTLV_DIVERSITY 2 /* Also known as babelz. */
#define SUBTLV_TIMESTAMP 3 /* Used to compute RTT. */
#define SUBTLV_SOURCE_PREFIX 128 /* Source-specific routing. */
extern unsigned short myseqno;
extern struct timeval seqno_time;
......@@ -55,16 +50,13 @@ extern int split_horizon;
extern unsigned char packet_header[4];
extern struct neighbour *unicast_neighbour;
extern struct timeval unicast_flush_timeout;
void parse_packet(const unsigned char *from, struct interface *ifp,
const unsigned char *packet, int packetlen);
void flushbuf(struct interface *ifp);
void flushbuf(struct buffered *buf);
void flushupdates(struct interface *ifp);
void send_ack(struct neighbour *neigh, unsigned short nonce,
unsigned short interval);
void send_hello_noupdate(struct interface *ifp, unsigned interval);
void send_hello_noihu(struct interface *ifp, unsigned interval);
void send_hello(struct interface *ifp);
void flush_unicast(int dofree);
void send_update(struct interface *ifp, int urgent,
......@@ -79,19 +71,20 @@ void update_myseqno(void);
void send_self_update(struct interface *ifp);
void send_ihu(struct neighbour *neigh, struct interface *ifp);
void send_marginal_ihu(struct interface *ifp);
void send_request(struct interface *ifp,
void send_multicast_request(struct interface *ifp,
const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix, unsigned char src_plen);
void send_unicast_request(struct neighbour *neigh,
const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix,
unsigned char src_plen);
void send_multihop_request(struct interface *ifp,
const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix,
unsigned char src_plen,
unsigned short seqno, const unsigned char *id,
unsigned short hop_count);
void
send_multicast_multihop_request(struct interface *ifp,
const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix,
unsigned char src_plen,
unsigned short seqno, const unsigned char *id,
unsigned short hop_count);
void
send_unicast_multihop_request(struct neighbour *neigh,
const unsigned char *prefix, unsigned char plen,
......
......@@ -24,6 +24,8 @@ THE SOFTWARE.
#include <string.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h>
#include <assert.h>
......@@ -55,8 +57,6 @@ void
flush_neighbour(struct neighbour *neigh)
{
flush_neighbour_routes(neigh);
if(unicast_neighbour == neigh)
flush_unicast(1);
flush_resends(neigh);
if(neighs == neigh) {
......@@ -68,6 +68,7 @@ flush_neighbour(struct neighbour *neigh)
previous->next = neigh->next;
}
local_notify_neighbour(neigh, LOCAL_FLUSH);
free(neigh->buf.buf);
free(neigh);
}
......@@ -76,6 +77,7 @@ find_neighbour(const unsigned char *address, struct interface *ifp)
{
struct neighbour *neigh;
const struct timeval zero = {0, 0};
char *buf;
neigh = find_neighbour_nocreate(address, ifp);
if(neigh)
......@@ -84,8 +86,15 @@ find_neighbour(const unsigned char *address, struct interface *ifp)
debugf("Creating neighbour %s on %s.\n",
format_address(address), ifp->name);
buf = malloc(ifp->buf.size);
if(buf == NULL) {
perror("malloc(neighbour->buf)");
return NULL;
}
neigh = calloc(1, sizeof(struct neighbour));
if(neigh == NULL) {
free(buf);
perror("malloc(neighbour)");
return NULL;
}
......@@ -98,6 +107,13 @@ find_neighbour(const unsigned char *address, struct interface *ifp)
neigh->hello_rtt_receive_time = zero;
neigh->rtt_time = zero;
neigh->ifp = ifp;
neigh->buf.buf = buf;
neigh->buf.size = ifp->buf.size;
neigh->buf.flush_interval = ifp->buf.flush_interval;
neigh->buf.sin6.sin6_family = AF_INET6;
memcpy(&neigh->buf.sin6.sin6_addr, address, 16);
neigh->buf.sin6.sin6_port = htons(protocol_port);
neigh->buf.sin6.sin6_scope_id = ifp->ifindex;
neigh->next = neighs;
neighs = neigh;
local_notify_neighbour(neigh, LOCAL_ADD);
......@@ -135,6 +151,11 @@ update_neighbour(struct neighbour *neigh, struct hello_history *hist,
missed_hellos = 0;
rc = 1;
} else if(missed_hellos < 0) {
/* Late hello. Probably due to the link layer buffering
packets during a link outage or a cpu overload. */
fprintf(stderr,
"Late hello: bufferbloated neighbor %s\n",
format_address(neigh->address));
hist->reach <<= -missed_hellos;
missed_hellos = 0;
rc = 1;
......
......@@ -44,6 +44,7 @@ struct neighbour {
unsigned int rtt;
struct timeval rtt_time;
struct interface *ifp;
struct buffered buf;
};
extern struct neighbour *neighs;
......
......@@ -24,13 +24,15 @@ THE SOFTWARE.
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "babeld.h"
#include "util.h"
#include "interface.h"
#include "neighbour.h"
#include "resend.h"
#include "message.h"
#include "interface.h"
#include "configuration.h"
struct timeval resend_time = {0, 0};
......@@ -304,10 +306,12 @@ do_resend()
if(timeval_compare(&now, &timeout) >= 0) {
switch(resend->kind) {
case RESEND_REQUEST:
send_multihop_request(resend->ifp,
resend->prefix, resend->plen,
resend->src_prefix, resend->src_plen,
resend->seqno, resend->id, 127);
send_multicast_multihop_request(resend->ifp,
resend->prefix, resend->plen,
resend->src_prefix,
resend->src_plen,
resend->seqno, resend->id,
127);
break;
case RESEND_UPDATE:
send_update(resend->ifp, 1,
......
......@@ -1139,8 +1139,8 @@ send_triggered_update(struct babel_route *route, struct source *oldsrc,
if(oldmetric < INFINITY) {
if(newmetric >= oldmetric + 288) {
send_request(NULL, route->src->prefix, route->src->plen,
route->src->src_prefix, route->src->src_plen);
send_multicast_request(NULL, route->src->prefix, route->src->plen,
route->src->src_prefix, route->src->src_plen);
}
}
}
......
......@@ -24,6 +24,8 @@ THE SOFTWARE.
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <assert.h>
#include "babeld.h"
......
......@@ -302,7 +302,7 @@ format_thousands(unsigned int value)
static char buf[4][15];
static int i = 0;
i = (i + 1) % 4;
snprintf(buf[i], 15, "%d.%.3d", value / 1000, value % 1000);
snprintf(buf[i], 15, "%u.%.3u", value / 1000, value % 1000);
return buf[i];
}
......
......@@ -88,7 +88,7 @@ unsigned char *normalize_prefix(unsigned char *restrict ret,
const unsigned char *restrict prefix,
unsigned char plen);
const char *format_address(const unsigned char *address);
const char *format_prefix(const unsigned char *address, unsigned char prefix);
const char *format_prefix(const unsigned char *prefix, unsigned char plen);
const char *format_eui64(const unsigned char *eui);
const char *format_thousands(unsigned int value);
int parse_address(const char *address, unsigned char *addr_r, int *af_r);
......@@ -161,4 +161,3 @@ static inline void kdebugf(const char *format, ...) { return; }
#endif
#endif
This diff is collapsed.
......@@ -34,10 +34,10 @@ struct xroute_stream;
struct xroute *find_xroute(const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix, unsigned char src_plen);
void flush_xroute(struct xroute *xroute);
int add_xroute(unsigned char prefix[16], unsigned char plen,
unsigned char src_prefix[16], unsigned char src_plen,
unsigned short metric, unsigned int ifindex, int proto);
void flush_xroute(struct xroute *xroute);
int xroutes_estimate(void);
struct xroute_stream *xroute_stream();
struct xroute *xroute_stream_next(struct xroute_stream *stream);
......
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