From ca87e1d37b3c30648e9bacb476a3c89729512f6d Mon Sep 17 00:00:00 2001 From: Vasilis Tsiligiannis Date: Mon, 20 Jul 2009 01:28:35 +0300 Subject: bgpd: Implement BGP confederation error handling (RFC5065, Par. 5) This patch implements BGP confederation error handling in Quagga as described in RFC5065, paragraph 5. * bgp_aspath.c: (aspath_confed_check, aspath_left_confed_check) new functions * bgp_attr.c: (bgp_attr_aspath_check) apply previous and NOTIFY if there's a problem. --- bgpd/bgp_aspath.c | 36 ++++++++++++++++++++++++++++++++++++ bgpd/bgp_aspath.h | 2 ++ bgpd/bgp_attr.c | 11 +++++++++++ 3 files changed, 49 insertions(+) diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c index 13f32b86..e65541f9 100644 --- a/bgpd/bgp_aspath.c +++ b/bgpd/bgp_aspath.c @@ -1122,6 +1122,42 @@ aspath_private_as_check (struct aspath *aspath) return 1; } +/* AS path confed check. If aspath contains confed set or sequence then return 1. */ +int +aspath_confed_check (struct aspath *aspath) +{ + struct assegment *seg; + + if ( !(aspath && aspath->segments) ) + return 0; + + seg = aspath->segments; + + while (seg) + { + if (seg->type == AS_CONFED_SET || seg->type == AS_CONFED_SEQUENCE) + return 1; + seg = seg->next; + } + return 0; +} + +/* Leftmost AS path segment confed check. If leftmost AS segment is of type + AS_CONFED_SEQUENCE or AS_CONFED_SET then return 1. */ +int +aspath_left_confed_check (struct aspath *aspath) +{ + + if ( !(aspath && aspath->segments) ) + return 0; + + if ( (aspath->segments->type == AS_CONFED_SEQUENCE) + || (aspath->segments->type == AS_CONFED_SET) ) + return 1; + + return 0; +} + /* Merge as1 to as2. as2 should be uninterned aspath. */ static struct aspath * aspath_merge (struct aspath *as1, struct aspath *as2) diff --git a/bgpd/bgp_aspath.h b/bgpd/bgp_aspath.h index 2b4625c8..9854d186 100644 --- a/bgpd/bgp_aspath.h +++ b/bgpd/bgp_aspath.h @@ -88,6 +88,8 @@ extern unsigned int aspath_key_make (void *); extern int aspath_loop_check (struct aspath *, as_t); extern int aspath_private_as_check (struct aspath *); extern int aspath_firstas_check (struct aspath *, as_t); +extern int aspath_confed_check (struct aspath *); +extern int aspath_left_confed_check (struct aspath *); extern unsigned long aspath_count (void); extern unsigned int aspath_count_hops (struct aspath *); extern unsigned int aspath_count_confeds (struct aspath *); diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 94168372..a664858c 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -872,6 +872,17 @@ static int bgp_attr_aspath_check( struct peer *peer, bgp = peer->bgp; + /* Confederation sanity check. */ + if ((peer_sort (peer) == BGP_PEER_CONFED && ! aspath_left_confed_check (attr->aspath)) || + (peer_sort (peer) == BGP_PEER_EBGP && aspath_confed_check (attr->aspath))) + { + zlog (peer->log, LOG_ERR, "Malformed AS path from %s", peer->host); + bgp_notify_send (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_MAL_AS_PATH); + return -1; + } + /* First AS check for EBGP. */ if (bgp != NULL && bgp_flag_check (bgp, BGP_FLAG_ENFORCE_FIRST_AS)) { -- cgit v1.2.1