diff --git a/proto/babel/babel.c b/proto/babel/babel.c index 8204838b..67e1d8be 100644 --- a/proto/babel/babel.c +++ b/proto/babel/babel.c @@ -834,8 +834,8 @@ babel_send_retraction(struct babel_iface *ifa, ip_addr prefix, int plen) struct babel_proto *p = ifa->proto; union babel_msg msg = {}; - TRACE(D_PACKETS, "Sending retraction for %I/%d router-id %lR seqno %d", - prefix, plen, p->router_id, p->update_seqno); + TRACE(D_PACKETS, "Sending retraction for %I/%d seqno %d", + prefix, plen, p->update_seqno); msg.type = BABEL_TLV_UPDATE; 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.metric = BABEL_INFINITY; 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); } @@ -1099,7 +1115,7 @@ babel_handle_update(union babel_msg *m, struct babel_iface *ifa) /* Retraction */ 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 @@ -1347,6 +1363,7 @@ babel_iface_start(struct babel_iface *ifa) ifa->up = 1; babel_send_hello(ifa, 0); + babel_send_wildcard_retraction(ifa); babel_send_wildcard_request(ifa); babel_send_update(ifa, 0); /* Full update */ } @@ -2056,6 +2073,30 @@ babel_start(struct proto *P) 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 babel_reconfigure(struct proto *P, struct proto_config *c) { @@ -2083,6 +2124,7 @@ struct protocol proto_babel = { .init = babel_init, .dump = babel_dump, .start = babel_start, + .shutdown = babel_shutdown, .reconfigure = babel_reconfigure, .get_route_info = babel_get_route_info, .get_attr = babel_get_attr diff --git a/proto/babel/babel.h b/proto/babel/babel.h index 7b5037ab..481c88a7 100644 --- a/proto/babel/babel.h +++ b/proto/babel/babel.h @@ -268,7 +268,7 @@ struct babel_msg_ihu { struct babel_msg_update { u8 type; - u8 ae; + u8 wildcard; u8 plen; u16 interval; u16 seqno; diff --git a/proto/babel/packets.c b/proto/babel/packets.c index d0cc613e..65dd6853 100644 --- a/proto/babel/packets.c +++ b/proto/babel/packets.c @@ -462,7 +462,6 @@ babel_read_update(struct babel_tlv *hdr, union babel_msg *m, struct babel_msg_update *msg = &m->update; msg->type = BABEL_TLV_UPDATE; - msg->ae = tlv->ae; msg->interval = get_time16(&tlv->interval); msg->seqno = get_u16(&tlv->seqno); 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) return PARSE_ERROR; - msg->plen = 0; - msg->prefix = IPA_NONE; + msg->wildcard = 1; break; 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 * both of them. There is enough space for the Router-ID TLV, because * 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); 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)); TLV_HDR(tlv, BABEL_TLV_UPDATE, len); - tlv->ae = BABEL_AE_IP6; - tlv->plen = msg->plen; + + if (msg->wildcard) + { + tlv->ae = BABEL_AE_WILDCARD; + tlv->plen = 0; + } + else + { + tlv->ae = BABEL_AE_IP6; + tlv->plen = msg->plen; + put_ip6_px(tlv->addr, msg->prefix, msg->plen); + } + put_time16(&tlv->interval, msg->interval); put_u16(&tlv->seqno, msg->seqno); put_u16(&tlv->metric, msg->metric); - put_ip6_px(tlv->addr, msg->prefix, msg->plen); return len0 + len; }