summaryrefslogtreecommitdiff
path: root/proto/bgp
diff options
context:
space:
mode:
Diffstat (limited to 'proto/bgp')
-rw-r--r--proto/bgp/attrs.c3
-rw-r--r--proto/bgp/bgp.c15
-rw-r--r--proto/bgp/bgp.h1
-rw-r--r--proto/bgp/config.Y4
4 files changed, 20 insertions, 3 deletions
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index 4495c039..e5bc84dd 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -1258,7 +1258,8 @@ same_group(rte *r, u32 lpref, u32 lasn)
static inline int
use_deterministic_med(rte *r)
{
- return ((struct bgp_proto *) r->attrs->proto)->cf->deterministic_med;
+ struct proto *P = r->attrs->proto;
+ return (P->proto == &proto_bgp) && ((struct bgp_proto *) P)->cf->deterministic_med;
}
int
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index 3b9f7cc5..dbc59eea 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -870,6 +870,7 @@ bgp_shutdown(struct proto *P)
break;
case PDC_CMD_DISABLE:
+ case PDC_CMD_SHUTDOWN:
subcode = 2; // Errcode 6, 2 - administrative shutdown
break;
@@ -923,7 +924,7 @@ bgp_init(struct proto_config *C)
struct proto *P = proto_new(C, sizeof(struct bgp_proto));
struct bgp_proto *p = (struct bgp_proto *) P;
- P->accept_ra_types = RA_OPTIMAL;
+ P->accept_ra_types = c->secondary ? RA_ACCEPTED : RA_OPTIMAL;
P->rt_notify = bgp_rt_notify;
P->rte_better = bgp_rte_better;
P->import_control = bgp_import_control;
@@ -969,6 +970,7 @@ bgp_check_config(struct bgp_config *c)
if (internal && c->rs_client)
cf_error("Only external neighbor can be RS client");
+
if (c->multihop && (c->gw_mode == GW_DIRECT))
cf_error("Multihop BGP cannot use direct gateway mode");
@@ -976,6 +978,7 @@ bgp_check_config(struct bgp_config *c)
ipa_has_link_scope(c->source_addr)))
cf_error("Multihop BGP cannot be used with link-local addresses");
+
/* Different default based on rs_client */
if (!c->missing_lladdr)
c->missing_lladdr = c->rs_client ? MLL_IGNORE : MLL_SELF;
@@ -987,6 +990,16 @@ bgp_check_config(struct bgp_config *c)
/* Disable after error incompatible with restart limit action */
if (c->c.in_limit && (c->c.in_limit->action == PLA_RESTART) && c->disable_after_error)
c->c.in_limit->action = PLA_DISABLE;
+
+
+ if ((c->gw_mode == GW_RECURSIVE) && c->c.table->sorted)
+ cf_error("BGP in recursive mode prohibits sorted table");
+
+ if (c->deterministic_med && c->c.table->sorted)
+ cf_error("BGP with deterministic MED prohibits sorted table");
+
+ if (c->secondary && !c->c.table->sorted)
+ cf_error("BGP with secondary option requires sorted table");
}
static int
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index 1c16f485..c3adf254 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -42,6 +42,7 @@ struct bgp_config {
int advertise_ipv4; /* Whether we should add IPv4 capability advertisement to OPEN message */
int passive; /* Do not initiate outgoing connection */
int interpret_communities; /* Hardwired handling of well-known communities */
+ int secondary; /* Accept also non-best routes (i.e. RA_ACCEPTED) */
unsigned connect_retry_time;
unsigned hold_time, initial_hold_time;
unsigned keepalive_time;
diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y
index 5feaea0d..8b80d7fd 100644
--- a/proto/bgp/config.Y
+++ b/proto/bgp/config.Y
@@ -25,7 +25,8 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY,
CLUSTER, ID, AS4, ADVERTISE, IPV4, CAPABILITIES, LIMIT, PASSIVE,
PREFER, OLDER, MISSING, LLADDR, DROP, IGNORE, ROUTE, REFRESH,
INTERPRET, COMMUNITIES, BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP,
- TABLE, GATEWAY, DIRECT, RECURSIVE, MED, TTL, SECURITY, DETERMINISTIC)
+ TABLE, GATEWAY, DIRECT, RECURSIVE, MED, TTL, SECURITY, DETERMINISTIC,
+ SECONDARY)
CF_GRAMMAR
@@ -105,6 +106,7 @@ bgp_proto:
}
| bgp_proto PASSIVE bool ';' { BGP_CFG->passive = $3; }
| bgp_proto INTERPRET COMMUNITIES bool ';' { BGP_CFG->interpret_communities = $4; }
+ | bgp_proto SECONDARY bool ';' { BGP_CFG->secondary = $3; }
| bgp_proto IGP TABLE rtable ';' { BGP_CFG->igp_table = $4; }
| bgp_proto TTL SECURITY bool ';' { BGP_CFG->ttl_security = $4; }
;