summaryrefslogtreecommitdiff
path: root/proto/babel
diff options
context:
space:
mode:
Diffstat (limited to 'proto/babel')
-rw-r--r--proto/babel/babel.c163
-rw-r--r--proto/babel/babel.h8
-rw-r--r--proto/babel/config.Y9
-rw-r--r--proto/babel/packets.c111
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;