RIP: Improvements to demand circuit mode
Restart iface after changing demand circuit mode during reconfiguration. Fix next_regular interval reset during reconfiguration. Send flushing response when iface goes down.
This commit is contained in:
parent
dc042d87cb
commit
d516c68ad8
3 changed files with 51 additions and 4 deletions
|
@ -780,6 +780,25 @@ rip_receive_response(struct rip_proto *p, struct rip_iface *ifa, struct rip_pack
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rip_send_flush(struct rip_proto *p, struct rip_iface *ifa)
|
||||||
|
{
|
||||||
|
/* Caller should handle cleanup of pending response */
|
||||||
|
if (ifa->tx_pending)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
struct rip_packet *pkt = rip_tx_buffer(ifa);
|
||||||
|
|
||||||
|
rip_fill_header(ifa, pkt, RIP_CMD_UPDATE_RESPONSE);
|
||||||
|
rip_fill_update_hdr(pkt, 1, ifa->tx_seqnum);
|
||||||
|
|
||||||
|
/* We suppose that iface is going down, so we do not expect ACK */
|
||||||
|
ifa->tx_seqnum++;
|
||||||
|
|
||||||
|
TRACE(D_PACKETS, "Sending response via %s", ifa->iface->name);
|
||||||
|
return rip_send_to(p, ifa, pkt, rip_pkt_hdrlen(ifa), ifa->tx_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rip_send_ack(struct rip_proto *p, struct rip_iface *ifa, uint flush, uint seqnum)
|
rip_send_ack(struct rip_proto *p, struct rip_iface *ifa, uint flush, uint seqnum)
|
||||||
|
|
|
@ -550,9 +550,15 @@ rip_iface_stop(struct rip_iface *ifa)
|
||||||
ifa->next_triggered = 0;
|
ifa->next_triggered = 0;
|
||||||
ifa->want_triggered = 0;
|
ifa->want_triggered = 0;
|
||||||
|
|
||||||
|
if (ifa->tx_pending)
|
||||||
|
ifa->tx_seqnum++;
|
||||||
|
|
||||||
ifa->tx_pending = 0;
|
ifa->tx_pending = 0;
|
||||||
ifa->req_pending = 0;
|
ifa->req_pending = 0;
|
||||||
|
|
||||||
|
if (ifa->cf->demand_circuit)
|
||||||
|
rip_send_flush(p, ifa);
|
||||||
|
|
||||||
WALK_LIST_FIRST(n, ifa->neigh_list)
|
WALK_LIST_FIRST(n, ifa->neigh_list)
|
||||||
rip_remove_neighbor(p, n);
|
rip_remove_neighbor(p, n);
|
||||||
|
|
||||||
|
@ -710,7 +716,8 @@ rip_reconfigure_iface(struct rip_proto *p, struct rip_iface *ifa, struct rip_ifa
|
||||||
(new->port != old->port) ||
|
(new->port != old->port) ||
|
||||||
(new->tx_tos != old->tx_tos) ||
|
(new->tx_tos != old->tx_tos) ||
|
||||||
(new->tx_priority != old->tx_priority) ||
|
(new->tx_priority != old->tx_priority) ||
|
||||||
(new->ttl_security != old->ttl_security))
|
(new->ttl_security != old->ttl_security) ||
|
||||||
|
(new->demand_circuit != old->demand_circuit))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
TRACE(D_EVENTS, "Reconfiguring interface %s", ifa->iface->name);
|
TRACE(D_EVENTS, "Reconfiguring interface %s", ifa->iface->name);
|
||||||
|
@ -719,7 +726,8 @@ rip_reconfigure_iface(struct rip_proto *p, struct rip_iface *ifa, struct rip_ifa
|
||||||
|
|
||||||
rip_iface_update_buffers(ifa);
|
rip_iface_update_buffers(ifa);
|
||||||
|
|
||||||
if (ifa->next_regular > (current_time() + new->update_time))
|
if ((! ifa->cf->demand_circuit) &&
|
||||||
|
(ifa->next_regular > (current_time() + new->update_time)))
|
||||||
ifa->next_regular = current_time() + (random() % new->update_time) + 100 MS;
|
ifa->next_regular = current_time() + (random() % new->update_time) + 100 MS;
|
||||||
|
|
||||||
if (new->check_link != old->check_link)
|
if (new->check_link != old->check_link)
|
||||||
|
@ -1130,6 +1138,20 @@ rip_start(struct proto *P)
|
||||||
return PS_UP;
|
return PS_UP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rip_shutdown(struct proto *P)
|
||||||
|
{
|
||||||
|
struct rip_proto *p = (void *) P;
|
||||||
|
|
||||||
|
TRACE(D_EVENTS, "Shutdown requested");
|
||||||
|
|
||||||
|
struct rip_iface *ifa;
|
||||||
|
WALK_LIST(ifa, p->iface_list)
|
||||||
|
rip_iface_stop(ifa);
|
||||||
|
|
||||||
|
return PS_DOWN;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rip_reconfigure(struct proto *P, struct proto_config *CF)
|
rip_reconfigure(struct proto *P, struct proto_config *CF)
|
||||||
{
|
{
|
||||||
|
@ -1271,8 +1293,12 @@ rip_dump(struct proto *P)
|
||||||
FIB_WALK(&p->rtable, struct rip_entry, en)
|
FIB_WALK(&p->rtable, struct rip_entry, en)
|
||||||
{
|
{
|
||||||
debug("RIP: entry #%d: %N via %I dev %s valid %d metric %d age %t\n",
|
debug("RIP: entry #%d: %N via %I dev %s valid %d metric %d age %t\n",
|
||||||
i++, en->n.addr, en->next_hop, en->iface->name,
|
i++, en->n.addr, en->next_hop, en->iface ? en->iface->name : "(null)",
|
||||||
en->valid, en->metric, current_time() - en->changed);
|
en->valid, en->metric, current_time() - en->changed);
|
||||||
|
|
||||||
|
for (struct rip_rte *e = en->routes; e; e = e->next)
|
||||||
|
debug("RIP: via %I metric %d expires %t\n",
|
||||||
|
e->next_hop, e->metric, e->expires - current_time());
|
||||||
}
|
}
|
||||||
FIB_WALK_END;
|
FIB_WALK_END;
|
||||||
|
|
||||||
|
@ -1298,6 +1324,7 @@ struct protocol proto_rip = {
|
||||||
.init = rip_init,
|
.init = rip_init,
|
||||||
.dump = rip_dump,
|
.dump = rip_dump,
|
||||||
.start = rip_start,
|
.start = rip_start,
|
||||||
|
.shutdown = rip_shutdown,
|
||||||
.reconfigure = rip_reconfigure,
|
.reconfigure = rip_reconfigure,
|
||||||
.get_route_info = rip_get_route_info,
|
.get_route_info = rip_get_route_info,
|
||||||
.get_attr = rip_get_attr
|
.get_attr = rip_get_attr
|
||||||
|
|
|
@ -227,6 +227,7 @@ void rip_show_neighbors(struct proto *P, char *iff);
|
||||||
/* packets.c */
|
/* packets.c */
|
||||||
void rip_send_request(struct rip_proto *p, struct rip_iface *ifa);
|
void rip_send_request(struct rip_proto *p, struct rip_iface *ifa);
|
||||||
void rip_send_table(struct rip_proto *p, struct rip_iface *ifa, ip_addr addr, btime changed);
|
void rip_send_table(struct rip_proto *p, struct rip_iface *ifa, ip_addr addr, btime changed);
|
||||||
|
int rip_send_flush(struct rip_proto *p, struct rip_iface *ifa);
|
||||||
void rip_rxmt_timeout(timer *t);
|
void rip_rxmt_timeout(timer *t);
|
||||||
int rip_open_socket(struct rip_iface *ifa);
|
int rip_open_socket(struct rip_iface *ifa);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue