Added Cisco and Quagga capability workaround option.

This commit is contained in:
Ondrej Zajicek 2009-03-05 11:52:47 +01:00
parent 82a79586e5
commit e3299ab148
4 changed files with 37 additions and 4 deletions

View file

@ -762,6 +762,16 @@ for each neighbor using the following configuration parameters:
Even when disabled (off), BIRD behaves internally as AS4-aware BGP router. Even when disabled (off), BIRD behaves internally as AS4-aware BGP router.
Default: on. Default: on.
<tag>advertise ipv4</tag> Advertise IPv4 multiprotocol capability.
This is not correct behavior but it is required by some BGP
implementations (Cisco and Quagga). Without this option,
the session establishment with these implementations takes
more time, session is degraded (no optional capabilities)
and the problem is logged. When the option is used, there might
be compatibility issues with other BGP implementations.
This option is relevant to IPv4 mode only.
Default: disabled.
<tag>disable after error <m/switch/</tag> When an error is encountered (either <tag>disable after error <m/switch/</tag> When an error is encountered (either
locally or by the other side), disable the instance automatically locally or by the other side), disable the instance automatically
and wait for an administrator to fix the problem manually. Default: off. and wait for an administrator to fix the problem manually. Default: off.

View file

@ -29,6 +29,7 @@ struct bgp_config {
u32 rr_cluster_id; /* Route reflector cluster ID, if different from local ID */ u32 rr_cluster_id; /* Route reflector cluster ID, if different from local ID */
int rr_client; /* Whether neighbor is RR client of me */ int rr_client; /* Whether neighbor is RR client of me */
int rs_client; /* Whether neighbor is RS client of me */ int rs_client; /* Whether neighbor is RS client of me */
int advertise_ipv4; /* Whether we should add IPv4 capability advertisement to OPEN message */
unsigned connect_retry_time; unsigned connect_retry_time;
unsigned hold_time, initial_hold_time; unsigned hold_time, initial_hold_time;
unsigned keepalive_time; unsigned keepalive_time;
@ -259,6 +260,7 @@ void bgp_log_error(struct bgp_proto *p, char *msg, unsigned code, unsigned subco
/* Address families */ /* Address families */
#define BGP_AF_IPV4 1
#define BGP_AF_IPV6 2 #define BGP_AF_IPV6 2
#endif #endif

View file

@ -21,7 +21,7 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE,
ERROR, START, DELAY, FORGET, WAIT, ENABLE, DISABLE, AFTER, ERROR, START, DELAY, FORGET, WAIT, ENABLE, DISABLE, AFTER,
BGP_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN, BGP_NEXT_HOP, BGP_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN, BGP_NEXT_HOP,
BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY, SOURCE, ADDRESS, BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY, SOURCE, ADDRESS,
PASSWORD, RR, RS, CLIENT, CLUSTER, ID, AS4) PASSWORD, RR, RS, CLIENT, CLUSTER, ID, AS4, ADVERTISE, IPV4)
CF_GRAMMAR CF_GRAMMAR
@ -71,6 +71,7 @@ bgp_proto:
| bgp_proto ERROR WAIT TIME expr ',' expr ';' { BGP_CFG->error_delay_time_min = $5; BGP_CFG->error_delay_time_max = $7; } | bgp_proto ERROR WAIT TIME expr ',' expr ';' { BGP_CFG->error_delay_time_min = $5; BGP_CFG->error_delay_time_max = $7; }
| bgp_proto DISABLE AFTER ERROR bool ';' { BGP_CFG->disable_after_error = $5; } | bgp_proto DISABLE AFTER ERROR bool ';' { BGP_CFG->disable_after_error = $5; }
| bgp_proto ENABLE AS4 bool ';' { BGP_CFG->enable_as4 = $4; } | bgp_proto ENABLE AS4 bool ';' { BGP_CFG->enable_as4 = $4; }
| bgp_proto ADVERTISE IPV4 ';' { BGP_CFG->advertise_ipv4 = 1; }
| bgp_proto PASSWORD TEXT ';' { BGP_CFG->password = $3; } | bgp_proto PASSWORD TEXT ';' { BGP_CFG->password = $3; }
; ;

View file

@ -47,6 +47,20 @@ bgp_put_cap_ipv6(struct bgp_conn *conn UNUSED, byte *buf)
*buf++ = 1; /* and SAFI 1 */ *buf++ = 1; /* and SAFI 1 */
return buf; return buf;
} }
#else
static byte *
bgp_put_cap_ipv4(struct bgp_conn *conn UNUSED, byte *buf)
{
*buf++ = 1; /* Capability 1: Multiprotocol extensions */
*buf++ = 4; /* Capability data length */
*buf++ = 0; /* We support AF IPv4 */
*buf++ = BGP_AF_IPV4;
*buf++ = 0; /* RFU */
*buf++ = 1; /* and SAFI 1 */
return buf;
}
#endif #endif
static byte * static byte *
@ -82,6 +96,11 @@ bgp_create_open(struct bgp_conn *conn, byte *buf)
/* Skipped 3 B for length field and Capabilities parameter header */ /* Skipped 3 B for length field and Capabilities parameter header */
cap = buf + 12; cap = buf + 12;
#ifndef IPV6
if (p->cf->advertise_ipv4)
cap = bgp_put_cap_ipv4(conn, cap);
#endif
#ifdef IPV6 #ifdef IPV6
cap = bgp_put_cap_ipv6(conn, cap); cap = bgp_put_cap_ipv6(conn, cap);
#endif #endif
@ -940,6 +959,9 @@ bgp_rx_notification(struct bgp_conn *conn, byte *pkt, int len)
unsigned subcode = pkt[20]; unsigned subcode = pkt[20];
int delay = 1; int delay = 1;
bgp_log_error(conn->bgp, "Received error notification", code, subcode, pkt+21, len-21);
bgp_store_error(conn->bgp, conn, BE_BGP_RX, (code << 16) | subcode);
#ifndef IPV6 #ifndef IPV6
if ((code == 2) && ((subcode == 4) || (subcode == 7))) if ((code == 2) && ((subcode == 4) || (subcode == 7)))
{ {
@ -948,14 +970,12 @@ bgp_rx_notification(struct bgp_conn *conn, byte *pkt, int len)
* 7 - Peer request some capability. Strange unless it is IPv6 only peer. * 7 - Peer request some capability. Strange unless it is IPv6 only peer.
* We try connect without capabilities * We try connect without capabilities
*/ */
BGP_TRACE(D_EVENTS, "Capability related error received, capabilities disabled"); log(L_WARN "%s: Capability related error received, capabilities disabled", p->p.name);
conn->bgp->start_state = BSS_CONNECT_NOCAP; conn->bgp->start_state = BSS_CONNECT_NOCAP;
delay = 0; delay = 0;
} }
#endif #endif
bgp_log_error(conn->bgp, "Received error notification", code, subcode, pkt+21, len-21);
bgp_store_error(conn->bgp, conn, BE_BGP_RX, (code << 16) | subcode);
if (delay) bgp_update_startup_delay(conn->bgp, conn, code, subcode); if (delay) bgp_update_startup_delay(conn->bgp, conn, code, subcode);
bgp_conn_enter_close_state(conn); bgp_conn_enter_close_state(conn);
bgp_schedule_packet(conn, PKT_SCHEDULE_CLOSE); bgp_schedule_packet(conn, PKT_SCHEDULE_CLOSE);