summaryrefslogtreecommitdiffstats
path: root/babeld/message.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@nvidia.com>2022-06-08 15:01:31 +0200
committerDonald Sharp <sharpd@nvidia.com>2022-06-09 13:04:01 +0200
commita76cf7e49e62b60d5aedd1e6d6f562cb90ed051b (patch)
tree54d69f9e730400347f0d9b47015972ac5f31154e /babeld/message.c
parentbabeld: Update to ignore unicast hellos (diff)
downloadfrr-a76cf7e49e62b60d5aedd1e6d6f562cb90ed051b.tar.xz
frr-a76cf7e49e62b60d5aedd1e6d6f562cb90ed051b.zip
babeld: Ignore sub-tlv's with mandatory bit set
RFC 8966 4.4 If the mandatory bit is set, then the whole enclosing TLV MUST be silently ignored (except for updating the parser state by a Router-Id, Next Hop, or Update TLV, as described in the next section). Fixes: #11349 Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Diffstat (limited to 'babeld/message.c')
-rw-r--r--babeld/message.c133
1 files changed, 81 insertions, 52 deletions
diff --git a/babeld/message.c b/babeld/message.c
index 8d3ee6f34..c2ea2a268 100644
--- a/babeld/message.c
+++ b/babeld/message.c
@@ -127,9 +127,8 @@ network_prefix(int ae, int plen, unsigned int omitted,
return ret;
}
-static void
-parse_update_subtlv(const unsigned char *a, int alen,
- unsigned char *channels)
+static bool parse_update_subtlv(const unsigned char *a, int alen,
+ unsigned char *channels)
{
int type, len, i = 0;
@@ -142,37 +141,51 @@ parse_update_subtlv(const unsigned char *a, int alen,
if(i + 1 >= alen) {
flog_err(EC_BABEL_PACKET, "Received truncated attributes.");
- return;
- }
+ return false;
+ }
len = a[i + 1];
if(i + len + 2 > alen) {
flog_err(EC_BABEL_PACKET, "Received truncated attributes.");
- return;
- }
+ return false;
+ }
- if(type == SUBTLV_PADN) {
- /* Nothing. */
- } else if(type == SUBTLV_DIVERSITY) {
- if(len > DIVERSITY_HOPS) {
- flog_err(EC_BABEL_PACKET,
- "Received overlong channel information (%d > %d).n",
- len, DIVERSITY_HOPS);
- len = DIVERSITY_HOPS;
- }
- if(memchr(a + i + 2, 0, len) != NULL) {
- /* 0 is reserved. */
- flog_err(EC_BABEL_PACKET, "Channel information contains 0!");
- return;
- }
- memset(channels, 0, DIVERSITY_HOPS);
- memcpy(channels, a + i + 2, len);
- } else {
- debugf(BABEL_DEBUG_COMMON,
- "Received unknown route attribute %d.", type);
- }
+ if (type & SUBTLV_MANDATORY) {
+ /*
+ * RFC 8966 - 4.4
+ * If the mandatory bit is set, then the whole enclosing
+ * TLV MUST be silently ignored (except for updating the
+ * parser state by a Router-Id, Next Hop, or Update TLV,
+ * as described in the next section).
+ */
+ debugf(BABEL_DEBUG_COMMON,
+ "Received Mandatory bit set but this FRR version is not prepared to handle it at this point");
+ return true;
+ } else if (type == SUBTLV_PADN) {
+ /* Nothing. */
+ } else if (type == SUBTLV_DIVERSITY) {
+ if (len > DIVERSITY_HOPS) {
+ flog_err(
+ EC_BABEL_PACKET,
+ "Received overlong channel information (%d > %d).n",
+ len, DIVERSITY_HOPS);
+ len = DIVERSITY_HOPS;
+ }
+ if (memchr(a + i + 2, 0, len) != NULL) {
+ /* 0 is reserved. */
+ flog_err(EC_BABEL_PACKET,
+ "Channel information contains 0!");
+ return false;
+ }
+ memset(channels, 0, DIVERSITY_HOPS);
+ memcpy(channels, a + i + 2, len);
+ } else {
+ debugf(BABEL_DEBUG_COMMON,
+ "Received unknown route attribute %d.", type);
+ }
- i += len + 2;
+ i += len + 2;
}
+ return false;
}
static int
@@ -200,22 +213,34 @@ parse_hello_subtlv(const unsigned char *a, int alen,
return -1;
}
- if(type == SUBTLV_PADN) {
- /* Nothing to do. */
- } else if(type == SUBTLV_TIMESTAMP) {
- if(len >= 4) {
- DO_NTOHL(*hello_send_us, a + i + 2);
- ret = 1;
- } else {
- flog_err(EC_BABEL_PACKET,
- "Received incorrect RTT sub-TLV on Hello message.");
- }
- } else {
- debugf(BABEL_DEBUG_COMMON,
- "Received unknown Hello sub-TLV type %d.", type);
- }
+ if (type & SUBTLV_MANDATORY) {
+ /*
+ * RFC 8966 4.4
+ * If the mandatory bit is set, then the whole enclosing
+ * TLV MUST be silently ignored (except for updating the
+ * parser state by a Router-Id, Next Hop, or Update TLV, as
+ * described in the next section).
+ */
+ debugf(BABEL_DEBUG_COMMON,
+ "Received subtlv with Mandatory bit, this version of FRR is not prepared to handle this currently");
+ return -2;
+ } else if (type == SUBTLV_PADN) {
+ /* Nothing to do. */
+ } else if (type == SUBTLV_TIMESTAMP) {
+ if (len >= 4) {
+ DO_NTOHL(*hello_send_us, a + i + 2);
+ ret = 1;
+ } else {
+ flog_err(
+ EC_BABEL_PACKET,
+ "Received incorrect RTT sub-TLV on Hello message.");
+ }
+ } else {
+ debugf(BABEL_DEBUG_COMMON,
+ "Received unknown Hello sub-TLV type %d.", type);
+ }
- i += len + 2;
+ i += len + 2;
}
return ret;
}
@@ -518,7 +543,9 @@ parse_packet(const unsigned char *from, struct interface *ifp,
unsigned char channels[DIVERSITY_HOPS];
unsigned short interval, seqno, metric;
int rc, parsed_len;
- DO_NTOHS(interval, message + 6);
+ bool ignore_update = false;
+
+ DO_NTOHS(interval, message + 6);
DO_NTOHS(seqno, message + 8);
DO_NTOHS(metric, message + 10);
if(message[5] == 0 ||
@@ -604,14 +631,16 @@ parse_packet(const unsigned char *from, struct interface *ifp,
}
if(parsed_len < len)
- parse_update_subtlv(message + 2 + parsed_len,
- len - parsed_len, channels);
- }
-
- update_route(router_id, prefix, plen, seqno, metric, interval,
- neigh, nh,
- channels, channels_len(channels));
- } else if(type == MESSAGE_REQUEST) {
+ ignore_update =
+ parse_update_subtlv(message + 2 + parsed_len,
+ len - parsed_len, channels);
+ }
+
+ if (ignore_update)
+ update_route(router_id, prefix, plen, seqno, metric,
+ interval, neigh, nh, channels,
+ channels_len(channels));
+ } else if(type == MESSAGE_REQUEST) {
unsigned char prefix[16], plen;
int rc;
rc = network_prefix(message[2], message[3], 0,