Commit f107b49e authored by Juliusz Chroboczek's avatar Juliusz Chroboczek Committed by Juliusz Chroboczek

Use a per-neighbour unicast buffer.

This removes duplication between unicast and multicast variants of message
formatting.
parent 09a59d51
...@@ -582,6 +582,7 @@ main(int argc, char **argv) ...@@ -582,6 +582,7 @@ main(int argc, char **argv)
send_hello(ifp); send_hello(ifp);
send_wildcard_retraction(ifp); send_wildcard_retraction(ifp);
send_self_update(ifp); send_self_update(ifp);
send_multicast_request(ifp, NULL, 0, NULL, 0);
flushupdates(ifp); flushupdates(ifp);
flushbuf(&ifp->buf); flushbuf(&ifp->buf);
} }
...@@ -591,6 +592,7 @@ main(int argc, char **argv) ...@@ -591,6 +592,7 @@ main(int argc, char **argv)
while(1) { while(1) {
struct timeval tv; struct timeval tv;
fd_set readfds; fd_set readfds;
struct neighbour *neigh;
gettime(&now); gettime(&now);
...@@ -608,7 +610,9 @@ main(int argc, char **argv) ...@@ -608,7 +610,9 @@ main(int argc, char **argv)
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);
} }
timeval_min(&tv, &unicast_flush_timeout); FOR_ALL_NEIGHBOURS(neigh) {
timeval_min(&tv, &neigh->buf.timeout);
}
FD_ZERO(&readfds); FD_ZERO(&readfds);
if(timeval_compare(&tv, &now) > 0) { if(timeval_compare(&tv, &now) > 0) {
int maxfd = 0; int maxfd = 0;
...@@ -770,11 +774,6 @@ main(int argc, char **argv) ...@@ -770,11 +774,6 @@ main(int argc, char **argv)
do_resend(); do_resend();
} }
if(unicast_flush_timeout.tv_sec != 0) {
if(timeval_compare(&now, &unicast_flush_timeout) >= 0)
flush_unicast(1);
}
FOR_ALL_INTERFACES(ifp) { FOR_ALL_INTERFACES(ifp) {
if(!if_up(ifp)) if(!if_up(ifp))
continue; continue;
...@@ -786,6 +785,14 @@ main(int argc, char **argv) ...@@ -786,6 +785,14 @@ main(int argc, char **argv)
} }
} }
FOR_ALL_NEIGHBOURS(neigh) {
if(neigh->buf.timeout.tv_sec != 0) {
if(timeval_compare(&now, &neigh->buf.timeout) >= 0) {
flushbuf(&neigh->buf);
}
}
}
if(UNLIKELY(debug || dumping)) { if(UNLIKELY(debug || dumping)) {
dump_tables(stdout); dump_tables(stdout);
dumping = 0; dumping = 0;
......
...@@ -480,6 +480,7 @@ interface_up(struct interface *ifp, int up) ...@@ -480,6 +480,7 @@ interface_up(struct interface *ifp, int up)
send_hello(ifp); send_hello(ifp);
if(rc > 0) if(rc > 0)
send_update(ifp, 0, NULL, 0, NULL, 0); send_update(ifp, 0, NULL, 0, NULL, 0);
send_multicast_request(ifp, NULL, 0, NULL, 0);
} else { } else {
flush_interface_routes(ifp, 0); flush_interface_routes(ifp, 0);
ifp->buf.len = 0; ifp->buf.len = 0;
...@@ -566,6 +567,7 @@ check_interfaces(void) ...@@ -566,6 +567,7 @@ check_interfaces(void)
check_interface_channel(ifp); check_interface_channel(ifp);
rc = check_interface_ipv4(ifp); rc = check_interface_ipv4(ifp);
if(rc > 0) { if(rc > 0) {
send_multicast_request(ifp, NULL, 0, NULL, 0);
send_update(ifp, 0, NULL, 0, NULL, 0); send_update(ifp, 0, NULL, 0, NULL, 0);
} }
} }
......
This diff is collapsed.
...@@ -52,9 +52,6 @@ extern int split_horizon; ...@@ -52,9 +52,6 @@ extern int split_horizon;
extern unsigned char packet_header[4]; 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, void parse_packet(const unsigned char *from, struct interface *ifp,
const unsigned char *packet, int packetlen); const unsigned char *packet, int packetlen);
void flushbuf(struct buffered *buf); void flushbuf(struct buffered *buf);
...@@ -76,19 +73,20 @@ void update_myseqno(void); ...@@ -76,19 +73,20 @@ void update_myseqno(void);
void send_self_update(struct interface *ifp); void send_self_update(struct interface *ifp);
void send_ihu(struct neighbour *neigh, struct interface *ifp); void send_ihu(struct neighbour *neigh, struct interface *ifp);
void send_marginal_ihu(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 *prefix, unsigned char plen,
const unsigned char *src_prefix, unsigned char src_plen); const unsigned char *src_prefix, unsigned char src_plen);
void send_unicast_request(struct neighbour *neigh, void send_unicast_request(struct neighbour *neigh,
const unsigned char *prefix, unsigned char plen, const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix, const unsigned char *src_prefix,
unsigned char src_plen); unsigned char src_plen);
void send_multihop_request(struct interface *ifp, void
const unsigned char *prefix, unsigned char plen, send_multicast_multihop_request(struct interface *ifp,
const unsigned char *src_prefix, const unsigned char *prefix, unsigned char plen,
unsigned char src_plen, const unsigned char *src_prefix,
unsigned short seqno, const unsigned char *id, unsigned char src_plen,
unsigned short hop_count); unsigned short seqno, const unsigned char *id,
unsigned short hop_count);
void void
send_unicast_multihop_request(struct neighbour *neigh, send_unicast_multihop_request(struct neighbour *neigh,
const unsigned char *prefix, unsigned char plen, const unsigned char *prefix, unsigned char plen,
......
...@@ -57,8 +57,6 @@ void ...@@ -57,8 +57,6 @@ void
flush_neighbour(struct neighbour *neigh) flush_neighbour(struct neighbour *neigh)
{ {
flush_neighbour_routes(neigh); flush_neighbour_routes(neigh);
if(unicast_neighbour == neigh)
flush_unicast(1);
flush_resends(neigh); flush_resends(neigh);
if(neighs == neigh) { if(neighs == neigh) {
...@@ -70,6 +68,7 @@ flush_neighbour(struct neighbour *neigh) ...@@ -70,6 +68,7 @@ flush_neighbour(struct neighbour *neigh)
previous->next = neigh->next; previous->next = neigh->next;
} }
local_notify_neighbour(neigh, LOCAL_FLUSH); local_notify_neighbour(neigh, LOCAL_FLUSH);
free(neigh->buf.buf);
free(neigh); free(neigh);
} }
...@@ -78,6 +77,7 @@ find_neighbour(const unsigned char *address, struct interface *ifp) ...@@ -78,6 +77,7 @@ find_neighbour(const unsigned char *address, struct interface *ifp)
{ {
struct neighbour *neigh; struct neighbour *neigh;
const struct timeval zero = {0, 0}; const struct timeval zero = {0, 0};
char *buf;
neigh = find_neighbour_nocreate(address, ifp); neigh = find_neighbour_nocreate(address, ifp);
if(neigh) if(neigh)
...@@ -86,6 +86,12 @@ find_neighbour(const unsigned char *address, struct interface *ifp) ...@@ -86,6 +86,12 @@ find_neighbour(const unsigned char *address, struct interface *ifp)
debugf("Creating neighbour %s on %s.\n", debugf("Creating neighbour %s on %s.\n",
format_address(address), ifp->name); 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)); neigh = calloc(1, sizeof(struct neighbour));
if(neigh == NULL) { if(neigh == NULL) {
perror("malloc(neighbour)"); perror("malloc(neighbour)");
...@@ -100,6 +106,13 @@ find_neighbour(const unsigned char *address, struct interface *ifp) ...@@ -100,6 +106,13 @@ find_neighbour(const unsigned char *address, struct interface *ifp)
neigh->hello_rtt_receive_time = zero; neigh->hello_rtt_receive_time = zero;
neigh->rtt_time = zero; neigh->rtt_time = zero;
neigh->ifp = ifp; 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; neigh->next = neighs;
neighs = neigh; neighs = neigh;
local_notify_neighbour(neigh, LOCAL_ADD); local_notify_neighbour(neigh, LOCAL_ADD);
......
...@@ -44,6 +44,7 @@ struct neighbour { ...@@ -44,6 +44,7 @@ struct neighbour {
unsigned int rtt; unsigned int rtt;
struct timeval rtt_time; struct timeval rtt_time;
struct interface *ifp; struct interface *ifp;
struct buffered buf;
}; };
extern struct neighbour *neighs; extern struct neighbour *neighs;
......
...@@ -306,10 +306,12 @@ do_resend() ...@@ -306,10 +306,12 @@ do_resend()
if(timeval_compare(&now, &timeout) >= 0) { if(timeval_compare(&now, &timeout) >= 0) {
switch(resend->kind) { switch(resend->kind) {
case RESEND_REQUEST: case RESEND_REQUEST:
send_multihop_request(resend->ifp, send_multicast_multihop_request(resend->ifp,
resend->prefix, resend->plen, resend->prefix, resend->plen,
resend->src_prefix, resend->src_plen, resend->src_prefix,
resend->seqno, resend->id, 127); resend->src_plen,
resend->seqno, resend->id,
127);
break; break;
case RESEND_UPDATE: case RESEND_UPDATE:
send_update(resend->ifp, 1, send_update(resend->ifp, 1,
......
...@@ -1139,8 +1139,8 @@ send_triggered_update(struct babel_route *route, struct source *oldsrc, ...@@ -1139,8 +1139,8 @@ send_triggered_update(struct babel_route *route, struct source *oldsrc,
if(oldmetric < INFINITY) { if(oldmetric < INFINITY) {
if(newmetric >= oldmetric + 288) { if(newmetric >= oldmetric + 288) {
send_request(NULL, route->src->prefix, route->src->plen, send_multicast_request(NULL, route->src->prefix, route->src->plen,
route->src->src_prefix, route->src->src_plen); route->src->src_prefix, route->src->src_plen);
} }
} }
} }
......
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