diff options
-rw-r--r-- | proto/bgp/attrs.c | 14 | ||||
-rw-r--r-- | proto/bgp/bgp.c | 6 | ||||
-rw-r--r-- | proto/bgp/bgp.h | 2 | ||||
-rw-r--r-- | proto/bgp/config.Y | 6 | ||||
-rw-r--r-- | proto/bgp/packets.c | 5 |
5 files changed, 20 insertions, 13 deletions
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index a42a488..0fcd1ce 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -73,13 +73,13 @@ bgp_check_path(byte *a, int len, int bs, int errcode) static int bgp_check_as_path(struct bgp_proto *p, byte *a, int len) { - return bgp_check_path(a, len, (bgp_as4_support && p->as4_support) ? 4 : 2, 11); + return bgp_check_path(a, len, p->as4_session ? 4 : 2, 11); } static int bgp_check_as4_path(struct bgp_proto *p, byte *a, int len) { - if (bgp_as4_support && (! p->as4_support)) + if (bgp_as4_support && (! p->as4_session)) return bgp_check_path(a, len, 4, 9); else return 0; @@ -106,7 +106,7 @@ bgp_check_next_hop(struct bgp_proto *p UNUSED, byte *a, int len) static int bgp_check_aggregator(struct bgp_proto *p, UNUSED byte *a, int len) { - int exp_len = (bgp_as4_support && p->as4_support) ? 8 : 6; + int exp_len = p->as4_session ? 8 : 6; return (len == exp_len) ? 0 : 5; } @@ -344,7 +344,7 @@ bgp_encode_attrs(struct bgp_proto *p, byte *w, ea_list *attrs, int remains) * we have to convert our 4B AS_PATH to 2B AS_PATH and send our AS_PATH * as optional AS4_PATH attribute. */ - if ((code == BA_AS_PATH) && bgp_as4_support && (! p->as4_support)) + if ((code == BA_AS_PATH) && bgp_as4_support && (! p->as4_session)) { len = a->u.ptr->length; @@ -384,7 +384,7 @@ bgp_encode_attrs(struct bgp_proto *p, byte *w, ea_list *attrs, int remains) } /* The same issue with AGGREGATOR attribute */ - if ((code == BA_AGGREGATOR) && bgp_as4_support && (! p->as4_support)) + if ((code == BA_AGGREGATOR) && bgp_as4_support && (! p->as4_session)) { int new_used; @@ -1082,7 +1082,7 @@ bgp_remove_as4_attrs(struct bgp_proto *p, rta *a) if ((fid == id1) || (fid == id2)) { *el = (*el)->next; - if (p->as4_support) + if (p->as4_session) log(L_WARN "BGP: Unexpected AS4_* attributes received"); } else @@ -1246,7 +1246,7 @@ bgp_decode_attrs(struct bgp_conn *conn, byte *attr, unsigned int len, struct lin /* When receiving attributes from non-AS4-aware BGP speaker, * we have to reconstruct 4B AS_PATH and AGGREGATOR attributes */ - if (bgp_as4_support && (! bgp->as4_support)) + if (bgp_as4_support && (! bgp->as4_session)) bgp_reconstruct_4b_atts(bgp, a, pool); if (bgp_as4_support) diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 5fa1249..0d580be 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -636,9 +636,11 @@ bgp_check(struct bgp_config *c) cf_error("Local AS number must be set"); if (!c->remote_as) cf_error("Neighbor must be configured"); - if (!bgp_as4_support && (c->local_as > 0xFFFF)) + if (!bgp_as4_support && c->enable_as4) + cf_error("AS4 support disabled globbaly"); + if (!c->enable_as4 && (c->local_as > 0xFFFF)) cf_error("Local AS number out of range"); - if (!bgp_as4_support && (c->remote_as > 0xFFFF)) + if (!c->enable_as4 && (c->remote_as > 0xFFFF)) cf_error("Neighbor AS number out of range"); if ((c->local_as != c->remote_as) && (c->rr_client)) cf_error("Only internal neighbor can be RR client"); diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index af3c5c5..1d67e33 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -25,6 +25,7 @@ struct bgp_config { int compare_path_lengths; /* Use path lengths when selecting best route */ u32 default_local_pref; /* Default value for LOCAL_PREF attribute */ u32 default_med; /* Default value for MULTI_EXIT_DISC attribute */ + int enable_as4; /* Enable local support for 4B AS numbers [RFC4893] */ u32 rr_cluster_id; /* Route reflector cluster ID, if different from local ID */ int rr_client; /* Whether neighbor is RR client of me */ unsigned connect_retry_time; @@ -60,6 +61,7 @@ struct bgp_proto { u32 local_as, remote_as; int is_internal; /* Internal BGP connection (local_as == remote_as) */ int as4_support; /* Peer supports 4B AS numbers [RFC4893] */ + int as4_session; /* Session uses 4B AS numbers in AS_PATH (both sides support it) */ u32 local_id; /* BGP identifier of this router */ u32 remote_id; /* BGP identifier of the neighbor */ u32 rr_cluster_id; /* Route reflector cluster ID */ diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index b23b66c..d7bba57 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -18,10 +18,10 @@ CF_DECLS CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE, MULTIHOP, STARTUP, VIA, NEXT, HOP, SELF, DEFAULT, PATH, METRIC, - ERROR, START, DELAY, FORGET, WAIT, DISABLE, AFTER, + ERROR, START, DELAY, FORGET, WAIT, ENABLE, DISABLE, AFTER, BGP_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN, BGP_NEXT_HOP, BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY, SOURCE, ADDRESS, - PASSWORD, RR, CLIENT, CLUSTER, ID) + PASSWORD, RR, CLIENT, CLUSTER, ID, AS4) CF_GRAMMAR @@ -39,6 +39,7 @@ bgp_proto_start: proto_start BGP { BGP_CFG->error_amnesia_time = 300; BGP_CFG->error_delay_time_min = 60; BGP_CFG->error_delay_time_max = 300; + BGP_CFG->enable_as4 = bgp_as4_support; } ; @@ -68,6 +69,7 @@ bgp_proto: | bgp_proto ERROR FORGET TIME expr ';' { BGP_CFG->error_amnesia_time = $5; } | 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 ENABLE AS4 bool ';' { BGP_CFG->enable_as4 = $4; } | bgp_proto PASSWORD TEXT ';' { BGP_CFG->password = $3; } ; diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 8a352c6..c18c6e4 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -73,7 +73,7 @@ bgp_create_open(struct bgp_conn *conn, byte *buf) #ifdef IPV6 cap = bgp_put_cap_ipv6(conn, cap); #endif - if (bgp_as4_support) + if (p->cf->enable_as4) cap = bgp_put_cap_as4(conn, cap); cap_len = cap - buf - 12; @@ -407,7 +407,8 @@ bgp_parse_capabilities(struct bgp_conn *conn, byte *opt, int len) if (cl != 4) goto err; p->as4_support = 1; - if (bgp_as4_support) + p->as4_session = p->cf->enable_as4; + if (p->as4_session) conn->advertised_as = get_u32(opt + 2); break; |