mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-30 03:00:24 +00:00
Merge pull request #13354 from zmw12306/parse_request_subtlv
babeld: add parse_request_subtlv into parse_packet
This commit is contained in:
commit
c12a40fee3
@ -48,6 +48,13 @@ static const unsigned char tlv_min_length[MESSAGE_MAX + 1] =
|
|||||||
[ MESSAGE_MH_REQUEST ] = 14,
|
[ MESSAGE_MH_REQUEST ] = 14,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Checks whether an AE exists or must be silently ignored */
|
||||||
|
static bool
|
||||||
|
known_ae(int ae)
|
||||||
|
{
|
||||||
|
return ae <= 4;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse a network prefix, encoded in the somewhat baroque compressed
|
/* Parse a network prefix, encoded in the somewhat baroque compressed
|
||||||
representation used by Babel. Return the number of bytes parsed. */
|
representation used by Babel. Return the number of bytes parsed. */
|
||||||
static int
|
static int
|
||||||
@ -276,6 +283,62 @@ parse_ihu_subtlv(const unsigned char *a, int alen,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
parse_request_subtlv(int ae, const unsigned char *a, int alen,
|
||||||
|
unsigned char *src_prefix, unsigned char *src_plen)
|
||||||
|
{
|
||||||
|
int type, len, i = 0;
|
||||||
|
int have_src_prefix = 0;
|
||||||
|
|
||||||
|
while(i < alen) {
|
||||||
|
type = a[0];
|
||||||
|
if(type == SUBTLV_PAD1) {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i + 2 > alen)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
len = a[i + 1];
|
||||||
|
if(i + 2 + len > alen)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if(type == SUBTLV_PADN) {
|
||||||
|
/* Nothing to do. */
|
||||||
|
} else if(type == SUBTLV_SOURCE_PREFIX) {
|
||||||
|
int rc;
|
||||||
|
if(len < 1)
|
||||||
|
goto fail;
|
||||||
|
if(a[i + 2] == 0)
|
||||||
|
goto fail;
|
||||||
|
if(have_src_prefix != 0)
|
||||||
|
goto fail;
|
||||||
|
rc = network_prefix(ae, a[i + 2], 0, a + i + 3, NULL,
|
||||||
|
len - 1, src_prefix);
|
||||||
|
if(rc < 0)
|
||||||
|
goto fail;
|
||||||
|
if(ae==1)
|
||||||
|
*src_plen = a[i + 2] + 96;
|
||||||
|
else
|
||||||
|
*src_plen = a[i + 2];
|
||||||
|
have_src_prefix = 1;
|
||||||
|
} else {
|
||||||
|
debugf(BABEL_DEBUG_COMMON,"Received unknown%s Route Request sub-TLV %d.",
|
||||||
|
((type & 0x80) != 0) ? " mandatory" : "", type);
|
||||||
|
if((type & 0x80) != 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
i += len + 2;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
flog_err(EC_BABEL_PACKET, "Received truncated sub-TLV on Route Request.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
network_address(int ae, const unsigned char *a, unsigned int len,
|
network_address(int ae, const unsigned char *a, unsigned int len,
|
||||||
unsigned char *a_r)
|
unsigned char *a_r)
|
||||||
@ -612,8 +675,14 @@ parse_packet(const unsigned char *from, struct interface *ifp,
|
|||||||
interval, neigh, nh, channels,
|
interval, neigh, nh, channels,
|
||||||
channels_len(channels));
|
channels_len(channels));
|
||||||
} else if(type == MESSAGE_REQUEST) {
|
} else if(type == MESSAGE_REQUEST) {
|
||||||
unsigned char prefix[16], plen;
|
unsigned char prefix[16], src_prefix[16], plen, src_plen;
|
||||||
int rc;
|
int rc, is_ss;
|
||||||
|
if(len < 2) goto fail;
|
||||||
|
if(!known_ae(message[2])) {
|
||||||
|
debugf(BABEL_DEBUG_COMMON,"Received request with unknown AE %d. Ignoring.",
|
||||||
|
message[2]);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
rc = network_prefix(message[2], message[3], 0,
|
rc = network_prefix(message[2], message[3], 0,
|
||||||
message + 4, NULL, len - 2, prefix);
|
message + 4, NULL, len - 2, prefix);
|
||||||
if(rc < 0) goto fail;
|
if(rc < 0) goto fail;
|
||||||
@ -621,8 +690,26 @@ parse_packet(const unsigned char *from, struct interface *ifp,
|
|||||||
debugf(BABEL_DEBUG_COMMON,"Received request for %s from %s on %s.",
|
debugf(BABEL_DEBUG_COMMON,"Received request for %s from %s on %s.",
|
||||||
message[2] == 0 ? "any" : format_prefix(prefix, plen),
|
message[2] == 0 ? "any" : format_prefix(prefix, plen),
|
||||||
format_address(from), ifp->name);
|
format_address(from), ifp->name);
|
||||||
|
if(message[2] == 1) {
|
||||||
|
v4tov6(src_prefix, zeroes);
|
||||||
|
src_plen = 96;
|
||||||
|
} else {
|
||||||
|
memcpy(src_prefix, zeroes, 16);
|
||||||
|
src_plen = 0;
|
||||||
|
}
|
||||||
|
rc = parse_request_subtlv(message[2], message + 4 + rc,
|
||||||
|
len - 2 - rc, src_prefix, &src_plen);
|
||||||
|
if(rc < 0)
|
||||||
|
goto done;
|
||||||
|
is_ss = !is_default(src_prefix, src_plen);
|
||||||
if(message[2] == 0) {
|
if(message[2] == 0) {
|
||||||
struct babel_interface *neigh_ifp =babel_get_if_nfo(neigh->ifp);
|
struct babel_interface *neigh_ifp =babel_get_if_nfo(neigh->ifp);
|
||||||
|
if(is_ss) {
|
||||||
|
/* Wildcard requests don't carry a source prefix. */
|
||||||
|
flog_err(EC_BABEL_PACKET,
|
||||||
|
"Received source-specific wildcard request.");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
/* If a neighbour is requesting a full route dump from us,
|
/* If a neighbour is requesting a full route dump from us,
|
||||||
we might as well send it an IHU. */
|
we might as well send it an IHU. */
|
||||||
send_ihu(neigh, NULL);
|
send_ihu(neigh, NULL);
|
||||||
|
@ -34,6 +34,7 @@ Copyright (c) 2007, 2008 by Juliusz Chroboczek
|
|||||||
#define SUBTLV_PADN 1
|
#define SUBTLV_PADN 1
|
||||||
#define SUBTLV_DIVERSITY 2 /* Also known as babelz. */
|
#define SUBTLV_DIVERSITY 2 /* Also known as babelz. */
|
||||||
#define SUBTLV_TIMESTAMP 3 /* Used to compute RTT. */
|
#define SUBTLV_TIMESTAMP 3 /* Used to compute RTT. */
|
||||||
|
#define SUBTLV_SOURCE_PREFIX 128 /* Source-specific routing. */
|
||||||
#define SUBTLV_MANDATORY 0x80
|
#define SUBTLV_MANDATORY 0x80
|
||||||
|
|
||||||
extern unsigned short myseqno;
|
extern unsigned short myseqno;
|
||||||
|
@ -104,6 +104,12 @@ void uchar_to_in6addr(struct in6_addr *dest, const unsigned char *src);
|
|||||||
int daemonise(void);
|
int daemonise(void);
|
||||||
extern const unsigned char v4prefix[16];
|
extern const unsigned char v4prefix[16];
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
is_default(const unsigned char *prefix, int plen)
|
||||||
|
{
|
||||||
|
return plen == 0 || (plen == 96 && v4mapped(prefix));
|
||||||
|
}
|
||||||
|
|
||||||
/* If debugging is disabled, we want to avoid calling format_address
|
/* If debugging is disabled, we want to avoid calling format_address
|
||||||
for every omitted debugging message. So debug is a macro. But
|
for every omitted debugging message. So debug is a macro. But
|
||||||
vararg macros are not portable. */
|
vararg macros are not portable. */
|
||||||
|
Loading…
Reference in New Issue
Block a user