Commit 9fb50fd6 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek Committed by Juliusz Chroboczek

Move interface buffer into dedicated structure.

parent 1616ee4a
...@@ -603,7 +603,7 @@ main(int argc, char **argv) ...@@ -603,7 +603,7 @@ main(int argc, char **argv)
FOR_ALL_INTERFACES(ifp) { FOR_ALL_INTERFACES(ifp) {
if(!if_up(ifp)) if(!if_up(ifp))
continue; continue;
timeval_min(&tv, &ifp->flush_timeout); timeval_min(&tv, &ifp->buf.timeout);
timeval_min(&tv, &ifp->hello_timeout); timeval_min(&tv, &ifp->hello_timeout);
timeval_min(&tv, &ifp->update_timeout); timeval_min(&tv, &ifp->update_timeout);
timeval_min(&tv, &ifp->update_flush_timeout); timeval_min(&tv, &ifp->update_flush_timeout);
...@@ -778,8 +778,8 @@ main(int argc, char **argv) ...@@ -778,8 +778,8 @@ main(int argc, char **argv)
FOR_ALL_INTERFACES(ifp) { FOR_ALL_INTERFACES(ifp) {
if(!if_up(ifp)) if(!if_up(ifp))
continue; continue;
if(ifp->flush_timeout.tv_sec != 0) { if(ifp->buf.timeout.tv_sec != 0) {
if(timeval_compare(&now, &ifp->flush_timeout) >= 0) if(timeval_compare(&now, &ifp->buf.timeout) >= 0)
flushbuf(ifp); flushbuf(ifp);
} }
} }
......
...@@ -319,15 +319,15 @@ interface_up(struct interface *ifp, int up) ...@@ -319,15 +319,15 @@ interface_up(struct interface *ifp, int up)
mtu = 128; mtu = 128;
} }
if(ifp->sendbuf) if(ifp->buf.buf)
free(ifp->sendbuf); free(ifp->buf.buf);
/* 40 for IPv6 header, 8 for UDP header, 12 for good luck. */ /* 40 for IPv6 header, 8 for UDP header, 12 for good luck. */
ifp->bufsize = mtu - sizeof(packet_header) - 60; ifp->buf.size = mtu - sizeof(packet_header) - 60;
ifp->sendbuf = malloc(ifp->bufsize); ifp->buf.buf = malloc(ifp->buf.size);
if(ifp->sendbuf == NULL) { if(ifp->buf.buf == NULL) {
fprintf(stderr, "Couldn't allocate sendbuf.\n"); fprintf(stderr, "Couldn't allocate sendbuf.\n");
ifp->bufsize = 0; ifp->buf.size = 0;
goto fail; goto fail;
} }
...@@ -474,15 +474,15 @@ interface_up(struct interface *ifp, int up) ...@@ -474,15 +474,15 @@ interface_up(struct interface *ifp, int up)
send_update(ifp, 0, NULL, 0, NULL, 0); send_update(ifp, 0, NULL, 0, NULL, 0);
} else { } else {
flush_interface_routes(ifp, 0); flush_interface_routes(ifp, 0);
ifp->buffered = 0; ifp->buf.len = 0;
ifp->bufsize = 0; ifp->buf.size = 0;
free(ifp->sendbuf); free(ifp->buf.buf);
ifp->num_buffered_updates = 0; ifp->num_buffered_updates = 0;
ifp->update_bufsize = 0; ifp->update_bufsize = 0;
if(ifp->buffered_updates) if(ifp->buffered_updates)
free(ifp->buffered_updates); free(ifp->buffered_updates);
ifp->buffered_updates = NULL; ifp->buffered_updates = NULL;
ifp->sendbuf = NULL; ifp->buf.buf = NULL;
if(ifp->ifindex > 0) { if(ifp->ifindex > 0) {
memset(&mreq, 0, sizeof(mreq)); memset(&mreq, 0, sizeof(mreq));
memcpy(&mreq.ipv6mr_multiaddr, protocol_group, 16); memcpy(&mreq.ipv6mr_multiaddr, protocol_group, 16);
......
...@@ -79,6 +79,22 @@ struct interface_conf { ...@@ -79,6 +79,22 @@ struct interface_conf {
#define IF_CHANNEL_INTERFERING 255 #define IF_CHANNEL_INTERFERING 255
#define IF_CHANNEL_NONINTERFERING -2 #define IF_CHANNEL_NONINTERFERING -2
struct buffered {
char *buf;
int len;
int size;
struct timeval timeout;
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 {
struct interface *next; struct interface *next;
struct interface_conf *conf; struct interface_conf *conf;
...@@ -88,24 +104,12 @@ struct interface { ...@@ -88,24 +104,12 @@ struct interface {
int channel; int channel;
struct timeval hello_timeout; struct timeval hello_timeout;
struct timeval update_timeout; struct timeval update_timeout;
struct timeval flush_timeout;
struct timeval update_flush_timeout; struct timeval update_flush_timeout;
char name[IF_NAMESIZE]; char name[IF_NAMESIZE];
unsigned char *ipv4; unsigned char *ipv4;
int numll; int numll;
unsigned char (*ll)[16]; unsigned char (*ll)[16];
int buffered; struct buffered buf;
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_update *buffered_updates; struct buffered_update *buffered_updates;
int num_buffered_updates; int num_buffered_updates;
int update_bufsize; int update_bufsize;
......
...@@ -919,15 +919,15 @@ check_bucket(struct interface *ifp) ...@@ -919,15 +919,15 @@ check_bucket(struct interface *ifp)
static int static int
fill_rtt_message(struct interface *ifp) fill_rtt_message(struct interface *ifp)
{ {
if((ifp->flags & IF_TIMESTAMPS) && (ifp->buffered_hello >= 0)) { if((ifp->flags & IF_TIMESTAMPS) && (ifp->buf.hello >= 0)) {
if(ifp->sendbuf[ifp->buffered_hello + 8] == SUBTLV_PADN && if(ifp->buf.buf[ifp->buf.hello + 8] == SUBTLV_PADN &&
ifp->sendbuf[ifp->buffered_hello + 9] == 4) { ifp->buf.buf[ifp->buf.hello + 9] == 4) {
unsigned int time; unsigned int time;
/* Change the type of sub-TLV. */ /* Change the type of sub-TLV. */
ifp->sendbuf[ifp->buffered_hello + 8] = SUBTLV_TIMESTAMP; ifp->buf.buf[ifp->buf.hello + 8] = SUBTLV_TIMESTAMP;
gettime(&now); gettime(&now);
time = time_us(now); time = time_us(now);
DO_HTONL(ifp->sendbuf + ifp->buffered_hello + 10, time); DO_HTONL(ifp->buf.buf + ifp->buf.hello + 10, time);
return 1; return 1;
} else { } else {
fprintf(stderr, fprintf(stderr,
...@@ -945,24 +945,24 @@ flushbuf(struct interface *ifp) ...@@ -945,24 +945,24 @@ flushbuf(struct interface *ifp)
int rc; int rc;
struct sockaddr_in6 sin6; struct sockaddr_in6 sin6;
assert(ifp->buffered <= ifp->bufsize); assert(ifp->buf.len <= ifp->buf.size);
flushupdates(ifp); flushupdates(ifp);
if(ifp->buffered > 0) { if(ifp->buf.len > 0) {
debugf(" (flushing %d buffered bytes on %s)\n", debugf(" (flushing %d buffered bytes on %s)\n",
ifp->buffered, ifp->name); ifp->buf.len, ifp->name);
if(check_bucket(ifp)) { if(check_bucket(ifp)) {
memset(&sin6, 0, sizeof(sin6)); memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6; sin6.sin6_family = AF_INET6;
memcpy(&sin6.sin6_addr, protocol_group, 16); memcpy(&sin6.sin6_addr, protocol_group, 16);
sin6.sin6_port = htons(protocol_port); sin6.sin6_port = htons(protocol_port);
sin6.sin6_scope_id = ifp->ifindex; sin6.sin6_scope_id = ifp->ifindex;
DO_HTONS(packet_header + 2, ifp->buffered); DO_HTONS(packet_header + 2, ifp->buf.len);
fill_rtt_message(ifp); fill_rtt_message(ifp);
rc = babel_send(protocol_socket, rc = babel_send(protocol_socket,
packet_header, sizeof(packet_header), packet_header, sizeof(packet_header),
ifp->sendbuf, ifp->buffered, ifp->buf.buf, ifp->buf.len,
(struct sockaddr*)&sin6, sizeof(sin6)); (struct sockaddr*)&sin6, sizeof(sin6));
if(rc < 0) if(rc < 0)
perror("send"); perror("send");
...@@ -971,24 +971,24 @@ flushbuf(struct interface *ifp) ...@@ -971,24 +971,24 @@ flushbuf(struct interface *ifp)
ifp->name); ifp->name);
} }
} }
VALGRIND_MAKE_MEM_UNDEFINED(ifp->sendbuf, ifp->bufsize); VALGRIND_MAKE_MEM_UNDEFINED(ifp->buf.buf, ifp->buf.size);
ifp->buffered = 0; ifp->buf.len = 0;
ifp->buffered_hello = -1; ifp->buf.hello = -1;
ifp->have_buffered_id = 0; ifp->buf.have_id = 0;
ifp->have_buffered_nh = 0; ifp->buf.have_nh = 0;
ifp->have_buffered_prefix = 0; ifp->buf.have_prefix = 0;
ifp->flush_timeout.tv_sec = 0; ifp->buf.timeout.tv_sec = 0;
ifp->flush_timeout.tv_usec = 0; ifp->buf.timeout.tv_usec = 0;
} }
static void static void
schedule_flush(struct interface *ifp) schedule_flush(struct interface *ifp)
{ {
unsigned msecs = jitter(ifp, 0); unsigned msecs = jitter(ifp, 0);
if(ifp->flush_timeout.tv_sec != 0 && if(ifp->buf.timeout.tv_sec != 0 &&
timeval_minus_msec(&ifp->flush_timeout, &now) < msecs) timeval_minus_msec(&ifp->buf.timeout, &now) < msecs)
return; return;
set_timeout(&ifp->flush_timeout, msecs); set_timeout(&ifp->buf.timeout, msecs);
} }
static void static void
...@@ -996,10 +996,10 @@ schedule_flush_now(struct interface *ifp) ...@@ -996,10 +996,10 @@ schedule_flush_now(struct interface *ifp)
{ {
/* Almost now */ /* Almost now */
unsigned msecs = roughly(10); unsigned msecs = roughly(10);
if(ifp->flush_timeout.tv_sec != 0 && if(ifp->buf.timeout.tv_sec != 0 &&
timeval_minus_msec(&ifp->flush_timeout, &now) < msecs) timeval_minus_msec(&ifp->buf.timeout, &now) < msecs)
return; return;
set_timeout(&ifp->flush_timeout, msecs); set_timeout(&ifp->buf.timeout, msecs);
} }
static void static void
...@@ -1018,54 +1018,54 @@ schedule_unicast_flush(unsigned msecs) ...@@ -1018,54 +1018,54 @@ schedule_unicast_flush(unsigned msecs)
static void static void
ensure_space(struct interface *ifp, int space) ensure_space(struct interface *ifp, int space)
{ {
if(ifp->bufsize - ifp->buffered < space) if(ifp->buf.size - ifp->buf.len < space)
flushbuf(ifp); flushbuf(ifp);
} }
static void static void
start_message(struct interface *ifp, int type, int len) start_message(struct interface *ifp, int type, int len)
{ {
if(ifp->bufsize - ifp->buffered < len + 2) if(ifp->buf.size - ifp->buf.len < len + 2)
flushbuf(ifp); flushbuf(ifp);
ifp->sendbuf[ifp->buffered++] = type; ifp->buf.buf[ifp->buf.len++] = type;
ifp->sendbuf[ifp->buffered++] = len; ifp->buf.buf[ifp->buf.len++] = len;
} }
static void static void
end_message(struct interface *ifp, int type, int bytes) end_message(struct interface *ifp, int type, int bytes)
{ {
assert(ifp->buffered >= bytes + 2 && assert(ifp->buf.len >= bytes + 2 &&
ifp->sendbuf[ifp->buffered - bytes - 2] == type && ifp->buf.buf[ifp->buf.len - bytes - 2] == type &&
ifp->sendbuf[ifp->buffered - bytes - 1] == bytes); ifp->buf.buf[ifp->buf.len - bytes - 1] == bytes);
schedule_flush(ifp); schedule_flush(ifp);
} }
static void static void
accumulate_byte(struct interface *ifp, unsigned char value) accumulate_byte(struct interface *ifp, unsigned char value)
{ {
ifp->sendbuf[ifp->buffered++] = value; ifp->buf.buf[ifp->buf.len++] = value;
} }
static void static void
accumulate_short(struct interface *ifp, unsigned short value) accumulate_short(struct interface *ifp, unsigned short value)
{ {
DO_HTONS(ifp->sendbuf + ifp->buffered, value); DO_HTONS(ifp->buf.buf + ifp->buf.len, value);
ifp->buffered += 2; ifp->buf.len += 2;
} }
static void static void
accumulate_int(struct interface *ifp, unsigned int value) accumulate_int(struct interface *ifp, unsigned int value)
{ {
DO_HTONL(ifp->sendbuf + ifp->buffered, value); DO_HTONL(ifp->buf.buf + ifp->buf.len, value);
ifp->buffered += 4; ifp->buf.len += 4;
} }
static void static void
accumulate_bytes(struct interface *ifp, accumulate_bytes(struct interface *ifp,
const unsigned char *value, unsigned len) const unsigned char *value, unsigned len)
{ {
memcpy(ifp->sendbuf + ifp->buffered, value, len); memcpy(ifp->buf.buf + ifp->buf.len, value, len);
ifp->buffered += len; ifp->buf.len += len;
} }
static int static int
...@@ -1074,7 +1074,7 @@ start_unicast_message(struct neighbour *neigh, int type, int len) ...@@ -1074,7 +1074,7 @@ start_unicast_message(struct neighbour *neigh, int type, int len)
if(unicast_neighbour) { if(unicast_neighbour) {
if(neigh != unicast_neighbour || if(neigh != unicast_neighbour ||
unicast_buffered + len + 2 >= unicast_buffered + len + 2 >=
MIN(UNICAST_BUFSIZE, neigh->ifp->bufsize)) MIN(UNICAST_BUFSIZE, neigh->ifp->buf.size))
flush_unicast(0); flush_unicast(0);
} }
if(!unicast_buffer) if(!unicast_buffer)
...@@ -1146,7 +1146,7 @@ send_hello_noupdate(struct interface *ifp, unsigned interval) ...@@ -1146,7 +1146,7 @@ send_hello_noupdate(struct interface *ifp, unsigned interval)
{ {
/* This avoids sending multiple hellos in a single packet, which breaks /* This avoids sending multiple hellos in a single packet, which breaks
link quality estimation. */ link quality estimation. */
if(ifp->buffered_hello >= 0) if(ifp->buf.hello >= 0)
flushbuf(ifp); flushbuf(ifp);
ifp->hello_seqno = seqno_plus(ifp->hello_seqno, 1); ifp->hello_seqno = seqno_plus(ifp->hello_seqno, 1);
...@@ -1159,7 +1159,7 @@ send_hello_noupdate(struct interface *ifp, unsigned interval) ...@@ -1159,7 +1159,7 @@ send_hello_noupdate(struct interface *ifp, unsigned interval)
ifp->hello_seqno, interval, ifp->name); ifp->hello_seqno, interval, ifp->name);
start_message(ifp, MESSAGE_HELLO, (ifp->flags & IF_TIMESTAMPS) ? 12 : 6); start_message(ifp, MESSAGE_HELLO, (ifp->flags & IF_TIMESTAMPS) ? 12 : 6);
ifp->buffered_hello = ifp->buffered - 2; ifp->buf.hello = ifp->buf.len - 2;
accumulate_short(ifp, 0); accumulate_short(ifp, 0);
accumulate_short(ifp, ifp->hello_seqno); accumulate_short(ifp, ifp->hello_seqno);
accumulate_short(ifp, interval > 0xFFFF ? 0xFFFF : interval); accumulate_short(ifp, interval > 0xFFFF ? 0xFFFF : interval);
...@@ -1271,15 +1271,15 @@ really_send_update(struct interface *ifp, ...@@ -1271,15 +1271,15 @@ really_send_update(struct interface *ifp,
if(v4) { if(v4) {
if(!ifp->ipv4) if(!ifp->ipv4)
return; return;
if(!ifp->have_buffered_nh || if(!ifp->buf.have_nh ||
memcmp(ifp->buffered_nh, ifp->ipv4, 4) != 0) { memcmp(ifp->buf.nh, ifp->ipv4, 4) != 0) {
start_message(ifp, MESSAGE_NH, 6); start_message(ifp, MESSAGE_NH, 6);
accumulate_byte(ifp, 1); accumulate_byte(ifp, 1);
accumulate_byte(ifp, 0); accumulate_byte(ifp, 0);
accumulate_bytes(ifp, ifp->ipv4, 4); accumulate_bytes(ifp, ifp->ipv4, 4);
end_message(ifp, MESSAGE_NH, 6); end_message(ifp, MESSAGE_NH, 6);
memcpy(ifp->buffered_nh, ifp->ipv4, 4); memcpy(ifp->buf.nh, ifp->ipv4, 4);
ifp->have_buffered_nh = 1; ifp->buf.have_nh = 1;
} }
real_prefix = prefix + 12; real_prefix = prefix + 12;
...@@ -1287,12 +1287,12 @@ really_send_update(struct interface *ifp, ...@@ -1287,12 +1287,12 @@ really_send_update(struct interface *ifp,
real_src_prefix = src_prefix + 12; real_src_prefix = src_prefix + 12;
real_src_plen = src_plen - 96; real_src_plen = src_plen - 96;
} else { } else {
if(ifp->have_buffered_prefix) { if(ifp->buf.have_prefix) {
while(omit < plen / 8 && while(omit < plen / 8 &&
ifp->buffered_prefix[omit] == prefix[omit]) ifp->buf.prefix[omit] == prefix[omit])
omit++; omit++;
} }
if(!is_ss && (!ifp->have_buffered_prefix || plen >= 48)) if(!is_ss && (!ifp->buf.have_prefix || plen >= 48))
flags |= 0x80; flags |= 0x80;
real_prefix = prefix; real_prefix = prefix;
real_plen = plen; real_plen = plen;
...@@ -1300,7 +1300,7 @@ really_send_update(struct interface *ifp, ...@@ -1300,7 +1300,7 @@ really_send_update(struct interface *ifp,
real_src_plen = src_plen; real_src_plen = src_plen;
} }
if(!ifp->have_buffered_id || memcmp(id, ifp->buffered_id, 8) != 0) { if(!ifp->buf.have_id || memcmp(id, ifp->buf.id, 8) != 0) {
if(!is_ss && real_plen == 128 && if(!is_ss && real_plen == 128 &&
memcmp(real_prefix + 8, id, 8) == 0) { memcmp(real_prefix + 8, id, 8) == 0) {
flags |= 0x40; flags |= 0x40;
...@@ -1310,8 +1310,8 @@ really_send_update(struct interface *ifp, ...@@ -1310,8 +1310,8 @@ really_send_update(struct interface *ifp,
accumulate_bytes(ifp, id, 8); accumulate_bytes(ifp, id, 8);
end_message(ifp, MESSAGE_ROUTER_ID, 10); end_message(ifp, MESSAGE_ROUTER_ID, 10);
} }
memcpy(ifp->buffered_id, id, 8); memcpy(ifp->buf.id, id, 8);
ifp->have_buffered_id = 1; ifp->buf.have_id = 1;
} }
if(!is_ss) if(!is_ss)
...@@ -1349,8 +1349,8 @@ really_send_update(struct interface *ifp, ...@@ -1349,8 +1349,8 @@ really_send_update(struct interface *ifp,
(real_src_plen + 7) / 8 + channels_size); (real_src_plen + 7) / 8 + channels_size);
if(flags & 0x80) { if(flags & 0x80) {
memcpy(ifp->buffered_prefix, prefix, 16); memcpy(ifp->buf.prefix, prefix, 16);
ifp->have_buffered_prefix = 1; ifp->buf.have_prefix = 1;
} }
} }
...@@ -1563,7 +1563,7 @@ buffer_update(struct interface *ifp, ...@@ -1563,7 +1563,7 @@ buffer_update(struct interface *ifp,
number of installed routes will grow over time, make sure we number of installed routes will grow over time, make sure we
have enough space to send a full-ish frame. */ have enough space to send a full-ish frame. */
n = installed_routes_estimate() + xroutes_estimate() + 4; n = installed_routes_estimate() + xroutes_estimate() + 4;
n = MAX(n, ifp->bufsize / 16); n = MAX(n, ifp->buf.size / 16);
again: again:
ifp->buffered_updates = malloc(n * sizeof(struct buffered_update)); ifp->buffered_updates = malloc(n * sizeof(struct buffered_update));
if(ifp->buffered_updates == NULL) { if(ifp->buffered_updates == NULL) {
...@@ -1689,7 +1689,7 @@ send_wildcard_retraction(struct interface *ifp) ...@@ -1689,7 +1689,7 @@ send_wildcard_retraction(struct interface *ifp)
accumulate_short(ifp, 0xFFFF); accumulate_short(ifp, 0xFFFF);
end_message(ifp, MESSAGE_UPDATE, 10); end_message(ifp, MESSAGE_UPDATE, 10);
ifp->have_buffered_id = 0; ifp->buf.have_id = 0;
} }
void void
......
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