Babel: Send wildcard retractions on shutdown and startup
This makes BIRD send a wildcard retraction on all interfaces before shutting down and right after starting up. This helps ensure that neighbours will discard the announced routes as soon as possible, rather than only after the normal timeout procedures. Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
This commit is contained in:
parent
ecae2f43f3
commit
5d6ca22085
3 changed files with 65 additions and 12 deletions
|
@ -834,8 +834,8 @@ babel_send_retraction(struct babel_iface *ifa, ip_addr prefix, int plen)
|
||||||
struct babel_proto *p = ifa->proto;
|
struct babel_proto *p = ifa->proto;
|
||||||
union babel_msg msg = {};
|
union babel_msg msg = {};
|
||||||
|
|
||||||
TRACE(D_PACKETS, "Sending retraction for %I/%d router-id %lR seqno %d",
|
TRACE(D_PACKETS, "Sending retraction for %I/%d seqno %d",
|
||||||
prefix, plen, p->router_id, p->update_seqno);
|
prefix, plen, p->update_seqno);
|
||||||
|
|
||||||
msg.type = BABEL_TLV_UPDATE;
|
msg.type = BABEL_TLV_UPDATE;
|
||||||
msg.update.plen = plen;
|
msg.update.plen = plen;
|
||||||
|
@ -843,7 +843,23 @@ babel_send_retraction(struct babel_iface *ifa, ip_addr prefix, int plen)
|
||||||
msg.update.seqno = p->update_seqno;
|
msg.update.seqno = p->update_seqno;
|
||||||
msg.update.metric = BABEL_INFINITY;
|
msg.update.metric = BABEL_INFINITY;
|
||||||
msg.update.prefix = prefix;
|
msg.update.prefix = prefix;
|
||||||
msg.update.router_id = p->router_id;
|
|
||||||
|
babel_enqueue(&msg, ifa);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
babel_send_wildcard_retraction(struct babel_iface *ifa)
|
||||||
|
{
|
||||||
|
struct babel_proto *p = ifa->proto;
|
||||||
|
union babel_msg msg = {};
|
||||||
|
|
||||||
|
TRACE(D_PACKETS, "Sending wildcard retraction on %s", ifa->ifname);
|
||||||
|
|
||||||
|
msg.type = BABEL_TLV_UPDATE;
|
||||||
|
msg.update.wildcard = 1;
|
||||||
|
msg.update.interval = ifa->cf->update_interval;
|
||||||
|
msg.update.seqno = p->update_seqno;
|
||||||
|
msg.update.metric = BABEL_INFINITY;
|
||||||
|
|
||||||
babel_enqueue(&msg, ifa);
|
babel_enqueue(&msg, ifa);
|
||||||
}
|
}
|
||||||
|
@ -1099,7 +1115,7 @@ babel_handle_update(union babel_msg *m, struct babel_iface *ifa)
|
||||||
/* Retraction */
|
/* Retraction */
|
||||||
if (msg->metric == BABEL_INFINITY)
|
if (msg->metric == BABEL_INFINITY)
|
||||||
{
|
{
|
||||||
if (msg->ae == BABEL_AE_WILDCARD)
|
if (msg->wildcard)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Special case: This is a retraction of all prefixes announced by this
|
* Special case: This is a retraction of all prefixes announced by this
|
||||||
|
@ -1347,6 +1363,7 @@ babel_iface_start(struct babel_iface *ifa)
|
||||||
ifa->up = 1;
|
ifa->up = 1;
|
||||||
|
|
||||||
babel_send_hello(ifa, 0);
|
babel_send_hello(ifa, 0);
|
||||||
|
babel_send_wildcard_retraction(ifa);
|
||||||
babel_send_wildcard_request(ifa);
|
babel_send_wildcard_request(ifa);
|
||||||
babel_send_update(ifa, 0); /* Full update */
|
babel_send_update(ifa, 0); /* Full update */
|
||||||
}
|
}
|
||||||
|
@ -2056,6 +2073,30 @@ babel_start(struct proto *P)
|
||||||
return PS_UP;
|
return PS_UP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
babel_iface_shutdown(struct babel_iface *ifa)
|
||||||
|
{
|
||||||
|
if (ifa->sk)
|
||||||
|
{
|
||||||
|
babel_send_wildcard_retraction(ifa);
|
||||||
|
babel_send_queue(ifa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
babel_shutdown(struct proto *P)
|
||||||
|
{
|
||||||
|
struct babel_proto *p = (void *) P;
|
||||||
|
struct babel_iface *ifa;
|
||||||
|
|
||||||
|
TRACE(D_EVENTS, "Shutdown requested");
|
||||||
|
|
||||||
|
WALK_LIST(ifa, p->interfaces)
|
||||||
|
babel_iface_shutdown(ifa);
|
||||||
|
|
||||||
|
return PS_DOWN;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
babel_reconfigure(struct proto *P, struct proto_config *c)
|
babel_reconfigure(struct proto *P, struct proto_config *c)
|
||||||
{
|
{
|
||||||
|
@ -2083,6 +2124,7 @@ struct protocol proto_babel = {
|
||||||
.init = babel_init,
|
.init = babel_init,
|
||||||
.dump = babel_dump,
|
.dump = babel_dump,
|
||||||
.start = babel_start,
|
.start = babel_start,
|
||||||
|
.shutdown = babel_shutdown,
|
||||||
.reconfigure = babel_reconfigure,
|
.reconfigure = babel_reconfigure,
|
||||||
.get_route_info = babel_get_route_info,
|
.get_route_info = babel_get_route_info,
|
||||||
.get_attr = babel_get_attr
|
.get_attr = babel_get_attr
|
||||||
|
|
|
@ -268,7 +268,7 @@ struct babel_msg_ihu {
|
||||||
|
|
||||||
struct babel_msg_update {
|
struct babel_msg_update {
|
||||||
u8 type;
|
u8 type;
|
||||||
u8 ae;
|
u8 wildcard;
|
||||||
u8 plen;
|
u8 plen;
|
||||||
u16 interval;
|
u16 interval;
|
||||||
u16 seqno;
|
u16 seqno;
|
||||||
|
|
|
@ -462,7 +462,6 @@ babel_read_update(struct babel_tlv *hdr, union babel_msg *m,
|
||||||
struct babel_msg_update *msg = &m->update;
|
struct babel_msg_update *msg = &m->update;
|
||||||
|
|
||||||
msg->type = BABEL_TLV_UPDATE;
|
msg->type = BABEL_TLV_UPDATE;
|
||||||
msg->ae = tlv->ae;
|
|
||||||
msg->interval = get_time16(&tlv->interval);
|
msg->interval = get_time16(&tlv->interval);
|
||||||
msg->seqno = get_u16(&tlv->seqno);
|
msg->seqno = get_u16(&tlv->seqno);
|
||||||
msg->metric = get_u16(&tlv->metric);
|
msg->metric = get_u16(&tlv->metric);
|
||||||
|
@ -480,8 +479,7 @@ babel_read_update(struct babel_tlv *hdr, union babel_msg *m,
|
||||||
if (tlv->plen > 0)
|
if (tlv->plen > 0)
|
||||||
return PARSE_ERROR;
|
return PARSE_ERROR;
|
||||||
|
|
||||||
msg->plen = 0;
|
msg->wildcard = 1;
|
||||||
msg->prefix = IPA_NONE;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BABEL_AE_IP4:
|
case BABEL_AE_IP4:
|
||||||
|
@ -550,8 +548,11 @@ babel_write_update(struct babel_tlv *hdr, union babel_msg *m,
|
||||||
* When needed, we write Router-ID TLV before Update TLV and return size of
|
* When needed, we write Router-ID TLV before Update TLV and return size of
|
||||||
* both of them. There is enough space for the Router-ID TLV, because
|
* both of them. There is enough space for the Router-ID TLV, because
|
||||||
* sizeof(struct babel_tlv_router_id) == sizeof(struct babel_tlv_update).
|
* sizeof(struct babel_tlv_router_id) == sizeof(struct babel_tlv_update).
|
||||||
|
*
|
||||||
|
* Router ID is not used for retractions, so do not us it in such case.
|
||||||
*/
|
*/
|
||||||
if (!state->router_id_seen || (msg->router_id != state->router_id))
|
if ((msg->metric < BABEL_INFINITY) &&
|
||||||
|
(!state->router_id_seen || (msg->router_id != state->router_id)))
|
||||||
{
|
{
|
||||||
len0 = babel_write_router_id(hdr, msg->router_id, state, max_len);
|
len0 = babel_write_router_id(hdr, msg->router_id, state, max_len);
|
||||||
tlv = (struct babel_tlv_update *) NEXT_TLV(tlv);
|
tlv = (struct babel_tlv_update *) NEXT_TLV(tlv);
|
||||||
|
@ -564,12 +565,22 @@ babel_write_update(struct babel_tlv *hdr, union babel_msg *m,
|
||||||
|
|
||||||
memset(tlv, 0, sizeof(struct babel_tlv_update));
|
memset(tlv, 0, sizeof(struct babel_tlv_update));
|
||||||
TLV_HDR(tlv, BABEL_TLV_UPDATE, len);
|
TLV_HDR(tlv, BABEL_TLV_UPDATE, len);
|
||||||
|
|
||||||
|
if (msg->wildcard)
|
||||||
|
{
|
||||||
|
tlv->ae = BABEL_AE_WILDCARD;
|
||||||
|
tlv->plen = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tlv->ae = BABEL_AE_IP6;
|
tlv->ae = BABEL_AE_IP6;
|
||||||
tlv->plen = msg->plen;
|
tlv->plen = msg->plen;
|
||||||
|
put_ip6_px(tlv->addr, msg->prefix, msg->plen);
|
||||||
|
}
|
||||||
|
|
||||||
put_time16(&tlv->interval, msg->interval);
|
put_time16(&tlv->interval, msg->interval);
|
||||||
put_u16(&tlv->seqno, msg->seqno);
|
put_u16(&tlv->seqno, msg->seqno);
|
||||||
put_u16(&tlv->metric, msg->metric);
|
put_u16(&tlv->metric, msg->metric);
|
||||||
put_ip6_px(tlv->addr, msg->prefix, msg->plen);
|
|
||||||
|
|
||||||
return len0 + len;
|
return len0 + len;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue