diff options
Diffstat (limited to 'proto/babel')
-rw-r--r-- | proto/babel/babel.c | 163 | ||||
-rw-r--r-- | proto/babel/babel.h | 8 | ||||
-rw-r--r-- | proto/babel/config.Y | 9 | ||||
-rw-r--r-- | proto/babel/packets.c | 111 |
4 files changed, 200 insertions, 91 deletions
diff --git a/proto/babel/babel.c b/proto/babel/babel.c index 8e104d60..38be6909 100644 --- a/proto/babel/babel.c +++ b/proto/babel/babel.c @@ -565,6 +565,11 @@ babel_select_route(struct babel_entry *e) babel_send_seqno_request(e); babel_announce_rte(p, e); + + /* Section 3.6 of the RFC forbids an infeasible from being selected. This + is cleared after announcing the route to the core to make sure an + unreachable route is propagated first. */ + e->selected_in = NULL; } else { @@ -783,16 +788,21 @@ babel_send_update(struct babel_iface *ifa, bird_clock_t changed) msg.update.prefix = e->n.prefix; msg.update.router_id = r->router_id; - /* Update feasibility distance */ - struct babel_source *s = babel_get_source(e, r->router_id); - s->expires = now + BABEL_GARBAGE_INTERVAL; - if ((msg.update.seqno > s->seqno) || - ((msg.update.seqno == s->seqno) && (msg.update.metric < s->metric))) + babel_enqueue(&msg, ifa); + + /* Update feasibility distance for redistributed routes */ + if (!OUR_ROUTE(r)) { - s->seqno = msg.update.seqno; - s->metric = msg.update.metric; + struct babel_source *s = babel_get_source(e, r->router_id); + s->expires = now + BABEL_GARBAGE_INTERVAL; + + if ((msg.update.seqno > s->seqno) || + ((msg.update.seqno == s->seqno) && (msg.update.metric < s->metric))) + { + s->seqno = msg.update.seqno; + s->metric = msg.update.metric; + } } - babel_enqueue(&msg, ifa); } FIB_WALK_END; } @@ -834,8 +844,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 +853,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); } @@ -1040,17 +1066,18 @@ babel_handle_update(union babel_msg *m, struct babel_iface *ifa) struct babel_proto *p = ifa->proto; struct babel_msg_update *msg = &m->update; - struct babel_neighbor *n; + struct babel_neighbor *nbr; struct babel_entry *e; struct babel_source *s; struct babel_route *r; + node *n; int feasible; TRACE(D_PACKETS, "Handling update for %I/%d with seqno %d metric %d", msg->prefix, msg->plen, msg->seqno, msg->metric); - n = babel_find_neighbor(ifa, msg->sender); - if (!n) + nbr = babel_find_neighbor(ifa, msg->sender); + if (!nbr) { DBG("Babel: Haven't heard from neighbor %I; ignoring update.\n", msg->sender); return; @@ -1095,55 +1122,88 @@ babel_handle_update(union babel_msg *m, struct babel_iface *ifa) * of the Interval value included in the update. */ + /* Retraction */ if (msg->metric == BABEL_INFINITY) - e = babel_find_entry(p, msg->prefix, msg->plen); - else - e = babel_get_entry(p, msg->prefix, msg->plen); + { + if (msg->wildcard) + { + /* + * Special case: This is a retraction of all prefixes announced by this + * neighbour (see second-to-last paragraph of section 4.4.9 in the RFC). + */ + WALK_LIST(n, nbr->routes) + { + r = SKIP_BACK(struct babel_route, neigh_route, n); + r->metric = BABEL_INFINITY; + babel_select_route(r->e); + } + } + else + { + e = babel_find_entry(p, msg->prefix, msg->plen); - if (!e) + if (!e) + return; + + /* The route entry indexed by neighbour */ + r = babel_find_route(e, nbr); + + if (!r) + return; + + r->metric = BABEL_INFINITY; + babel_select_route(e); + } + + /* Done with retractions */ return; + } + e = babel_get_entry(p, msg->prefix, msg->plen); + r = babel_find_route(e, nbr); /* the route entry indexed by neighbour */ s = babel_find_source(e, msg->router_id); /* for feasibility */ - r = babel_find_route(e, n); /* the route entry indexed by neighbour */ feasible = babel_is_feasible(s, msg->seqno, msg->metric); if (!r) { - if (!feasible || (msg->metric == BABEL_INFINITY)) + if (!feasible) return; - r = babel_get_route(e, n); + r = babel_get_route(e, nbr); r->advert_metric = msg->metric; r->router_id = msg->router_id; - r->metric = babel_compute_metric(n, msg->metric); + r->metric = babel_compute_metric(nbr, msg->metric); r->next_hop = msg->next_hop; r->seqno = msg->seqno; } else if (r == r->e->selected_in && !feasible) { - /* Route is installed and update is infeasible - we may lose the route, so - send a unicast seqno request (section 3.8.2.2 second paragraph). */ + /* + * Route is installed and update is infeasible - we may lose the route, + * so send a unicast seqno request (section 3.8.2.2 second paragraph). + */ babel_unicast_seqno_request(r); - if (msg->router_id == r->router_id) return; - r->metric = BABEL_INFINITY; /* retraction */ + if (msg->router_id == r->router_id) + return; + + /* Treat as retraction */ + r->metric = BABEL_INFINITY; } else { /* Last paragraph above - update the entry */ r->advert_metric = msg->metric; - r->metric = babel_compute_metric(n, msg->metric); - r->router_id = msg->router_id; + r->metric = babel_compute_metric(nbr, msg->metric); r->next_hop = msg->next_hop; + + r->router_id = msg->router_id; r->seqno = msg->seqno; - if (msg->metric != BABEL_INFINITY) - { - r->expiry_interval = BABEL_ROUTE_EXPIRY_FACTOR(msg->interval); - r->expires = now + r->expiry_interval; - if (r->expiry_interval > BABEL_ROUTE_REFRESH_INTERVAL) - r->refresh_time = now + r->expiry_interval - BABEL_ROUTE_REFRESH_INTERVAL; - } + r->expiry_interval = BABEL_ROUTE_EXPIRY_FACTOR(msg->interval); + r->expires = now + r->expiry_interval; + if (r->expiry_interval > BABEL_ROUTE_REFRESH_INTERVAL) + r->refresh_time = now + r->expiry_interval - BABEL_ROUTE_REFRESH_INTERVAL; /* If the route is not feasible at this point, it means it is from another neighbour than the one currently selected; so send a unicast seqno @@ -1313,6 +1373,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 */ } @@ -1529,6 +1590,9 @@ babel_reconfigure_iface(struct babel_proto *p, struct babel_iface *ifa, struct b ifa->cf = new; + if (ifa->next_hello > (now + new->hello_interval)) + ifa->next_hello = now + (random() % new->hello_interval) + 1; + if (ifa->next_regular > (now + new->update_interval)) ifa->next_regular = now + (random() % new->update_interval) + 1; @@ -1659,7 +1723,7 @@ babel_dump(struct proto *P) } static void -babel_get_route_info(rte *rte, byte *buf, ea_list *attrs) +babel_get_route_info(rte *rte, byte *buf, ea_list *attrs UNUSED) { buf += bsprintf(buf, " (%d/%d) [%lR]", rte->pref, rte->u.babel.metric, rte->u.babel.router_id); } @@ -1901,7 +1965,7 @@ babel_store_tmp_attrs(struct rte *rt, struct ea_list *attrs) */ static void babel_rt_notify(struct proto *P, struct rtable *table UNUSED, struct network *net, - struct rte *new, struct rte *old, struct ea_list *attrs) + struct rte *new, struct rte *old UNUSED, struct ea_list *attrs UNUSED) { struct babel_proto *p = (void *) P; struct babel_entry *e; @@ -2022,6 +2086,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) { @@ -2049,6 +2137,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 04689976..e8b6c314 100644 --- a/proto/babel/babel.h +++ b/proto/babel/babel.h @@ -46,10 +46,12 @@ #define BABEL_INITIAL_HOP_COUNT 255 #define BABEL_MAX_SEND_INTERVAL 5 #define BABEL_TIME_UNITS 100 /* On-wire times are counted in centiseconds */ - #define BABEL_SEQNO_REQUEST_EXPIRY 60 #define BABEL_GARBAGE_INTERVAL 300 +/* Max interval that will not overflow when carried as 16-bit centiseconds */ +#define BABEL_MAX_INTERVAL (0xFFFF/BABEL_TIME_UNITS) + #define BABEL_OVERHEAD (SIZE_OF_IP_HEADER+UDP_HEADER_LENGTH) #define BABEL_MIN_MTU (512 + BABEL_OVERHEAD) @@ -105,7 +107,7 @@ struct babel_iface_config { u16 rxcost; u8 type; u8 check_link; - int port; + uint port; u16 hello_interval; u16 ihu_interval; u16 update_interval; @@ -262,7 +264,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/config.Y b/proto/babel/config.Y index e7ce6a93..b6170852 100644 --- a/proto/babel/config.Y +++ b/proto/babel/config.Y @@ -77,17 +77,18 @@ babel_iface_finish: BABEL_IFACE->rxcost = BABEL_RXCOST_WIRED; } + /* Make sure we do not overflow the 16-bit centisec fields */ if (!BABEL_IFACE->update_interval) - BABEL_IFACE->update_interval = BABEL_IFACE->hello_interval*BABEL_UPDATE_INTERVAL_FACTOR; - BABEL_IFACE->ihu_interval = BABEL_IFACE->hello_interval*BABEL_IHU_INTERVAL_FACTOR; + BABEL_IFACE->update_interval = MIN_(BABEL_IFACE->hello_interval*BABEL_UPDATE_INTERVAL_FACTOR, BABEL_MAX_INTERVAL); + BABEL_IFACE->ihu_interval = MIN_(BABEL_IFACE->hello_interval*BABEL_IHU_INTERVAL_FACTOR, BABEL_MAX_INTERVAL); }; babel_iface_item: | PORT expr { BABEL_IFACE->port = $2; if (($2<1) || ($2>65535)) cf_error("Invalid port number"); } | RXCOST expr { BABEL_IFACE->rxcost = $2; if (($2<1) || ($2>65535)) cf_error("Invalid rxcost"); } - | HELLO INTERVAL expr { BABEL_IFACE->hello_interval = $3; if (($3<1) || ($3>65535)) cf_error("Invalid hello interval"); } - | UPDATE INTERVAL expr { BABEL_IFACE->update_interval = $3; if (($3<1) || ($3>65535)) cf_error("Invalid hello interval"); } + | HELLO INTERVAL expr { BABEL_IFACE->hello_interval = $3; if (($3<1) || ($3>BABEL_MAX_INTERVAL)) cf_error("Invalid hello interval"); } + | UPDATE INTERVAL expr { BABEL_IFACE->update_interval = $3; if (($3<1) || ($3>BABEL_MAX_INTERVAL)) cf_error("Invalid update interval"); } | TYPE WIRED { BABEL_IFACE->type = BABEL_IFACE_TYPE_WIRED; } | TYPE WIRELESS { BABEL_IFACE->type = BABEL_IFACE_TYPE_WIRELESS; } | RX BUFFER expr { BABEL_IFACE->rx_buffer = $3; if (($3<256) || ($3>65535)) cf_error("RX buffer must be in range 256-65535"); } diff --git a/proto/babel/packets.c b/proto/babel/packets.c index be47aa75..08054832 100644 --- a/proto/babel/packets.c +++ b/proto/babel/packets.c @@ -146,6 +146,7 @@ struct babel_write_state { #define TLV_HDR(tlv,t,l) ({ tlv->type = t; tlv->length = l - sizeof(struct babel_tlv); }) #define TLV_HDR0(tlv,t) TLV_HDR(tlv, t, tlv_data[t].min_length) +#define BYTES(n) ((((uint) n) + 7) / 8) static inline u16 get_time16(const void *p) @@ -161,18 +162,18 @@ put_time16(void *p, u16 v) } static inline ip6_addr -get_ip6_px(const void *p, int plen) +get_ip6_px(const void *p, uint plen) { ip6_addr addr = IPA_NONE; - memcpy(&addr, p, (plen + 7) / 8); + memcpy(&addr, p, BYTES(plen)); return ip6_ntoh(addr); } static inline void -put_ip6_px(void *p, ip6_addr addr, int plen) +put_ip6_px(void *p, ip6_addr addr, uint plen) { addr = ip6_hton(addr); - memcpy(p, &addr, (plen + 7) / 8); + memcpy(p, &addr, BYTES(plen)); } static inline ip6_addr @@ -202,21 +203,21 @@ static int babel_read_update(struct babel_tlv *hdr, union babel_msg *msg, struct static int babel_read_route_request(struct babel_tlv *hdr, union babel_msg *msg, struct babel_parse_state *state); static int babel_read_seqno_request(struct babel_tlv *hdr, union babel_msg *msg, struct babel_parse_state *state); -static int babel_write_ack(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, int max_len); -static int babel_write_hello(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, int max_len); -static int babel_write_ihu(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, int max_len); -static int babel_write_update(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, int max_len); -static int babel_write_route_request(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, int max_len); -static int babel_write_seqno_request(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, int max_len); +static uint babel_write_ack(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, uint max_len); +static uint babel_write_hello(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, uint max_len); +static uint babel_write_ihu(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, uint max_len); +static uint babel_write_update(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, uint max_len); +static uint babel_write_route_request(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, uint max_len); +static uint babel_write_seqno_request(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, uint max_len); struct babel_tlv_data { u8 min_length; int (*read_tlv)(struct babel_tlv *hdr, union babel_msg *m, struct babel_parse_state *state); - int (*write_tlv)(struct babel_tlv *hdr, union babel_msg *m, struct babel_write_state *state, int max_len); + uint (*write_tlv)(struct babel_tlv *hdr, union babel_msg *m, struct babel_write_state *state, uint max_len); void (*handle_tlv)(union babel_msg *m, struct babel_iface *ifa); }; -const static struct babel_tlv_data tlv_data[BABEL_TLV_MAX] = { +static const struct babel_tlv_data tlv_data[BABEL_TLV_MAX] = { [BABEL_TLV_ACK_REQ] = { sizeof(struct babel_tlv_ack_req), babel_read_ack_req, @@ -291,9 +292,9 @@ babel_read_ack_req(struct babel_tlv *hdr, union babel_msg *m, return PARSE_SUCCESS; } -static int +static uint babel_write_ack(struct babel_tlv *hdr, union babel_msg *m, - struct babel_write_state *state, int max_len) + struct babel_write_state *state UNUSED, uint max_len UNUSED) { struct babel_tlv_ack *tlv = (void *) hdr; struct babel_msg_ack *msg = &m->ack; @@ -319,9 +320,9 @@ babel_read_hello(struct babel_tlv *hdr, union babel_msg *m, return PARSE_SUCCESS; } -static int +static uint babel_write_hello(struct babel_tlv *hdr, union babel_msg *m, - struct babel_write_state *state, int max_len) + struct babel_write_state *state UNUSED, uint max_len UNUSED) { struct babel_tlv_hello *tlv = (void *) hdr; struct babel_msg_hello *msg = &m->hello; @@ -363,9 +364,9 @@ babel_read_ihu(struct babel_tlv *hdr, union babel_msg *m, return PARSE_SUCCESS; } -static int +static uint babel_write_ihu(struct babel_tlv *hdr, union babel_msg *m, - struct babel_write_state *state, int max_len) + struct babel_write_state *state UNUSED, uint max_len) { struct babel_tlv_ihu *tlv = (void *) hdr; struct babel_msg_ihu *msg = &m->ihu; @@ -401,9 +402,9 @@ babel_read_router_id(struct babel_tlv *hdr, union babel_msg *m UNUSED, } /* This is called directly from babel_write_update() */ -static int +static uint babel_write_router_id(struct babel_tlv *hdr, u64 router_id, - struct babel_write_state *state, int max_len UNUSED) + struct babel_write_state *state, uint max_len UNUSED) { struct babel_tlv_router_id *tlv = (void *) hdr; @@ -462,16 +463,15 @@ 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); /* Length of received prefix data without omitted part */ - int len = (tlv->plen + 7)/8 - (int) tlv->omitted; + int len = BYTES(tlv->plen) - (int) tlv->omitted; u8 buf[16] = {}; - if ((len < 0) || (len > TLV_OPT_LENGTH(tlv))) + if ((len < 0) || ((uint) len > TLV_OPT_LENGTH(tlv))) return PARSE_ERROR; switch (tlv->ae) @@ -480,7 +480,7 @@ babel_read_update(struct babel_tlv *hdr, union babel_msg *m, if (tlv->plen > 0) return PARSE_ERROR; - msg->prefix = IPA_NONE; + msg->wildcard = 1; break; case BABEL_AE_IP4: @@ -523,7 +523,8 @@ babel_read_update(struct babel_tlv *hdr, union babel_msg *m, return PARSE_IGNORE; } - if (!state->router_id_seen) + /* Update must have Router ID, unless it is retraction */ + if (!state->router_id_seen && (msg->metric != BABEL_INFINITY)) { DBG("Babel: No router ID seen before update\n"); return PARSE_ERROR; @@ -536,45 +537,58 @@ babel_read_update(struct babel_tlv *hdr, union babel_msg *m, return PARSE_SUCCESS; } -static int +static uint babel_write_update(struct babel_tlv *hdr, union babel_msg *m, - struct babel_write_state *state, int max_len) + struct babel_write_state *state, uint max_len) { struct babel_tlv_update *tlv = (void *) hdr; struct babel_msg_update *msg = &m->update; - int len0 = 0; + uint len0 = 0; /* * 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); } - int len = sizeof(struct babel_tlv_update) + (msg->plen + 7)/8; + uint len = sizeof(struct babel_tlv_update) + BYTES(msg->plen); if (len0 + len > max_len) return 0; 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; } static int babel_read_route_request(struct babel_tlv *hdr, union babel_msg *m, - struct babel_parse_state *state) + struct babel_parse_state *state UNUSED) { struct babel_tlv_route_request *tlv = (void *) hdr; struct babel_msg_route_request *msg = &m->route_request; @@ -599,7 +613,7 @@ babel_read_route_request(struct babel_tlv *hdr, union babel_msg *m, if (tlv->plen > MAX_PREFIX_LENGTH) return PARSE_ERROR; - if (TLV_OPT_LENGTH(tlv) < (tlv->plen + 7)/8) + if (TLV_OPT_LENGTH(tlv) < BYTES(tlv->plen)) return PARSE_ERROR; msg->plen = tlv->plen; @@ -616,14 +630,14 @@ babel_read_route_request(struct babel_tlv *hdr, union babel_msg *m, return PARSE_IGNORE; } -static int +static uint babel_write_route_request(struct babel_tlv *hdr, union babel_msg *m, - struct babel_write_state *state, int max_len) + struct babel_write_state *state UNUSED, uint max_len) { struct babel_tlv_route_request *tlv = (void *) hdr; struct babel_msg_route_request *msg = &m->route_request; - int len = sizeof(struct babel_tlv_route_request) + (msg->plen + 7)/8; + uint len = sizeof(struct babel_tlv_route_request) + BYTES(msg->plen); if (len > max_len) return 0; @@ -674,7 +688,7 @@ babel_read_seqno_request(struct babel_tlv *hdr, union babel_msg *m, if (tlv->plen > MAX_PREFIX_LENGTH) return PARSE_ERROR; - if (TLV_OPT_LENGTH(tlv) < (tlv->plen + 7)/8) + if (TLV_OPT_LENGTH(tlv) < BYTES(tlv->plen)) return PARSE_ERROR; msg->plen = tlv->plen; @@ -691,14 +705,14 @@ babel_read_seqno_request(struct babel_tlv *hdr, union babel_msg *m, return PARSE_IGNORE; } -static int +static uint babel_write_seqno_request(struct babel_tlv *hdr, union babel_msg *m, - struct babel_write_state *state, int max_len) + struct babel_write_state *state UNUSED, uint max_len) { struct babel_tlv_seqno_request *tlv = (void *) hdr; struct babel_msg_seqno_request *msg = &m->seqno_request; - int len = sizeof(struct babel_tlv_seqno_request) + (msg->plen + 7)/8; + uint len = sizeof(struct babel_tlv_seqno_request) + BYTES(msg->plen); if (len > max_len) return 0; @@ -731,11 +745,11 @@ babel_read_tlv(struct babel_tlv *hdr, return tlv_data[hdr->type].read_tlv(hdr, msg, state); } -static int +static uint babel_write_tlv(struct babel_tlv *hdr, union babel_msg *msg, struct babel_write_state *state, - int max_len) + uint max_len) { if ((msg->type <= BABEL_TLV_PADN) || (msg->type >= BABEL_TLV_MAX) || @@ -779,7 +793,7 @@ babel_send_to(struct babel_iface *ifa, ip_addr dest) * * The TLVs in the queue are freed after they are written to the buffer. */ -static int +static uint babel_write_queue(struct babel_iface *ifa, list *queue) { struct babel_proto *p = ifa->proto; @@ -800,6 +814,9 @@ babel_write_queue(struct babel_iface *ifa, list *queue) struct babel_msg_node *msg; WALK_LIST_FIRST(msg, *queue) { + if (pos >= end) + break; + int len = babel_write_tlv((struct babel_tlv *) pos, &msg->msg, &state, end - pos); if (!len) @@ -810,7 +827,7 @@ babel_write_queue(struct babel_iface *ifa, list *queue) sl_free(p->msg_slab, msg); } - int plen = pos - (byte *) pkt; + uint plen = pos - (byte *) pkt; put_u16(&pkt->length, plen - sizeof(struct babel_pkt_header)); return plen; @@ -1014,7 +1031,7 @@ babel_tx_hook(sock *sk) static int -babel_rx_hook(sock *sk, int len) +babel_rx_hook(sock *sk, uint len) { struct babel_iface *ifa = sk->data; struct babel_proto *p = ifa->proto; |