BGP: Minor cleanups
This commit is contained in:
parent
d8022d26fc
commit
82f42ea091
4 changed files with 67 additions and 52 deletions
|
@ -2040,6 +2040,16 @@ using the following configuration parameters:
|
||||||
source address for the BGP session. Default: the address of the local
|
source address for the BGP session. Default: the address of the local
|
||||||
end of the interface our neighbor is connected to.
|
end of the interface our neighbor is connected to.
|
||||||
|
|
||||||
|
<tag><label id="bgp-strict-bind">strict bind <m/switch/</tag>
|
||||||
|
Specify whether BGP listening socket should be bound to a specific local
|
||||||
|
address (the same as the <cf/source address/) and associated interface,
|
||||||
|
or to all addresses. Binding to a specific address could be useful in
|
||||||
|
cases like running multiple BIRD instances on a machine, each using its
|
||||||
|
IP address. Note that listening sockets bound to a specific address and
|
||||||
|
to all addresses collide, therefore either all BGP protocols (of the
|
||||||
|
same address family and using the same local port) should have set
|
||||||
|
<cf/strict bind/, or none of them. Default: disabled.
|
||||||
|
|
||||||
<tag><label id="bgp-next-hop-self">next hop self</tag>
|
<tag><label id="bgp-next-hop-self">next hop self</tag>
|
||||||
Avoid calculation of the Next Hop attribute and always advertise our own
|
Avoid calculation of the Next Hop attribute and always advertise our own
|
||||||
source address as a next hop. This needs to be used only occasionally to
|
source address as a next hop. This needs to be used only occasionally to
|
||||||
|
@ -2112,7 +2122,7 @@ using the following configuration parameters:
|
||||||
Note that full (ICMP protection, for example) <rfc id="5082"> support is
|
Note that full (ICMP protection, for example) <rfc id="5082"> support is
|
||||||
provided by Linux only. Default: disabled.
|
provided by Linux only. Default: disabled.
|
||||||
|
|
||||||
<tag><label id="bgp-pass">password <m/string/</tag>
|
<tag><label id="bgp-password">password <m/string/</tag>
|
||||||
Use this password for MD5 authentication of BGP sessions (<rfc id="2385">). When
|
Use this password for MD5 authentication of BGP sessions (<rfc id="2385">). When
|
||||||
used on BSD systems, see also <cf/setkey/ option below. Default: no
|
used on BSD systems, see also <cf/setkey/ option below. Default: no
|
||||||
authentication.
|
authentication.
|
||||||
|
@ -2270,13 +2280,6 @@ using the following configuration parameters:
|
||||||
This option is relevant to IPv4 mode with enabled capability
|
This option is relevant to IPv4 mode with enabled capability
|
||||||
advertisement only. Default: on.
|
advertisement only. Default: on.
|
||||||
|
|
||||||
<tag><label id="bgp-route-limit">route limit <m/number/</tag>
|
|
||||||
The maximal number of routes that may be imported from the protocol. If
|
|
||||||
the route limit is exceeded, the connection is closed with an error.
|
|
||||||
Limit is currently implemented as <cf>import limit <m/number/ action
|
|
||||||
restart</cf>. This option is obsolete and it is replaced by
|
|
||||||
<ref id="proto-import-limit" name="import limit option">. Default: no limit.
|
|
||||||
|
|
||||||
<tag><label id="bgp-disable-after-error">disable after error <m/switch/</tag>
|
<tag><label id="bgp-disable-after-error">disable after error <m/switch/</tag>
|
||||||
When an error is encountered (either locally or by the other side),
|
When an error is encountered (either locally or by the other side),
|
||||||
disable the instance automatically and wait for an administrator to fix
|
disable the instance automatically and wait for an administrator to fix
|
||||||
|
|
|
@ -1325,29 +1325,23 @@ bgp_import_control(struct proto *P, rte **new, ea_list **attrs UNUSED, struct li
|
||||||
|
|
||||||
static adata null_adata; /* adata of length 0 */
|
static adata null_adata; /* adata of length 0 */
|
||||||
|
|
||||||
static inline void
|
|
||||||
bgp_cluster_list_prepend(ea_list **attrs, struct linpool *pool, u32 id)
|
|
||||||
{
|
|
||||||
eattr *a = bgp_find_attr(*attrs, BA_CLUSTER_LIST);
|
|
||||||
adata *d = int_set_add(pool, a ? a->u.ptr : NULL, id);
|
|
||||||
bgp_set_attr_ptr(attrs, pool, BA_CLUSTER_LIST, 0, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ea_list *
|
static ea_list *
|
||||||
bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *attrs, struct linpool *pool)
|
bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *attrs0, struct linpool *pool)
|
||||||
{
|
{
|
||||||
struct proto *SRC = e->attrs->src->proto;
|
struct proto *SRC = e->attrs->src->proto;
|
||||||
struct bgp_proto *src = (SRC->proto == &proto_bgp) ? (void *) SRC : NULL;
|
struct bgp_proto *src = (SRC->proto == &proto_bgp) ? (void *) SRC : NULL;
|
||||||
struct bgp_export_state s = { .proto = p, .channel =c, .pool = pool, .src = src, .route = e };
|
struct bgp_export_state s = { .proto = p, .channel =c, .pool = pool, .src = src, .route = e };
|
||||||
|
ea_list *attrs = attrs0;
|
||||||
eattr *a;
|
eattr *a;
|
||||||
|
adata *ad;
|
||||||
|
|
||||||
/* ORIGIN attribute - mandatory, attach if missing */
|
/* ORIGIN attribute - mandatory, attach if missing */
|
||||||
if (! bgp_find_attr(attrs, BA_ORIGIN))
|
if (! bgp_find_attr(attrs0, BA_ORIGIN))
|
||||||
bgp_set_attr_u32(&attrs, pool, BA_ORIGIN, 0, src ? ORIGIN_INCOMPLETE : ORIGIN_IGP);
|
bgp_set_attr_u32(&attrs, pool, BA_ORIGIN, 0, src ? ORIGIN_INCOMPLETE : ORIGIN_IGP);
|
||||||
|
|
||||||
/* AS_PATH attribute */
|
/* AS_PATH attribute - mandatory */
|
||||||
a = bgp_find_attr(attrs, BA_AS_PATH);
|
a = bgp_find_attr(attrs0, BA_AS_PATH);
|
||||||
adata *ad = a ? a->u.ptr : &null_adata;
|
ad = a ? a->u.ptr : &null_adata;
|
||||||
|
|
||||||
/* AS_PATH attribute - strip AS_CONFED* segments outside confederation */
|
/* AS_PATH attribute - strip AS_CONFED* segments outside confederation */
|
||||||
if ((!p->cf->confederation || !p->is_interior) && as_path_contains_confed(ad))
|
if ((!p->cf->confederation || !p->is_interior) && as_path_contains_confed(ad))
|
||||||
|
@ -1374,33 +1368,40 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at
|
||||||
bgp_set_attr_ptr(&attrs, pool, BA_AS_PATH, 0, ad);
|
bgp_set_attr_ptr(&attrs, pool, BA_AS_PATH, 0, ad);
|
||||||
|
|
||||||
/* MULTI_EXIT_DESC attribute - accept only if set in export filter */
|
/* MULTI_EXIT_DESC attribute - accept only if set in export filter */
|
||||||
a = bgp_find_attr(attrs, BA_MULTI_EXIT_DISC);
|
a = bgp_find_attr(attrs0, BA_MULTI_EXIT_DISC);
|
||||||
if (a && !(a->type & EAF_FRESH))
|
if (a && !(a->type & EAF_FRESH))
|
||||||
bgp_unset_attr(&attrs, pool, BA_MULTI_EXIT_DISC);
|
bgp_unset_attr(&attrs, pool, BA_MULTI_EXIT_DISC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NEXT_HOP attribute - delegated to AF-specific hook */
|
/* NEXT_HOP attribute - delegated to AF-specific hook */
|
||||||
a = bgp_find_attr(attrs, BA_NEXT_HOP);
|
a = bgp_find_attr(attrs0, BA_NEXT_HOP);
|
||||||
bgp_update_next_hop(&s, a, &attrs);
|
bgp_update_next_hop(&s, a, &attrs);
|
||||||
|
|
||||||
/* LOCAL_PREF attribute - required for IBGP, attach if missing */
|
/* LOCAL_PREF attribute - required for IBGP, attach if missing */
|
||||||
if (p->is_interior && ! bgp_find_attr(attrs, BA_LOCAL_PREF))
|
if (p->is_interior && ! bgp_find_attr(attrs0, BA_LOCAL_PREF))
|
||||||
bgp_set_attr_u32(&attrs, pool, BA_LOCAL_PREF, 0, p->cf->default_local_pref);
|
bgp_set_attr_u32(&attrs, pool, BA_LOCAL_PREF, 0, p->cf->default_local_pref);
|
||||||
|
|
||||||
/* IBGP route reflection, RFC 4456 */
|
/* IBGP route reflection, RFC 4456 */
|
||||||
if (src && src->is_internal && p->is_internal && (src->local_as == p->local_as))
|
if (src && src->is_internal && p->is_internal && (src->local_as == p->local_as))
|
||||||
{
|
{
|
||||||
/* ORIGINATOR_ID attribute - attach if not already set */
|
/* ORIGINATOR_ID attribute - attach if not already set */
|
||||||
if (! bgp_find_attr(attrs, BA_ORIGINATOR_ID))
|
if (! bgp_find_attr(attrs0, BA_ORIGINATOR_ID))
|
||||||
bgp_set_attr_u32(&attrs, pool, BA_ORIGINATOR_ID, 0, src->remote_id);
|
bgp_set_attr_u32(&attrs, pool, BA_ORIGINATOR_ID, 0, src->remote_id);
|
||||||
|
|
||||||
/* CLUSTER_LIST attribute - prepend cluster ID */
|
/* CLUSTER_LIST attribute - prepend cluster ID */
|
||||||
if (src->rr_cluster_id)
|
a = bgp_find_attr(attrs0, BA_CLUSTER_LIST);
|
||||||
bgp_cluster_list_prepend(&attrs, pool, src->rr_cluster_id);
|
ad = a ? a->u.ptr : NULL;
|
||||||
|
|
||||||
/* Handle different src and dst cluster ID - prepend both ones */
|
/* Prepend src cluster ID */
|
||||||
|
if (src->rr_cluster_id)
|
||||||
|
ad = int_set_add(pool, ad, src->rr_cluster_id);
|
||||||
|
|
||||||
|
/* Prepend dst cluster ID if src and dst clusters are different */
|
||||||
if (p->rr_cluster_id && (src->rr_cluster_id != p->rr_cluster_id))
|
if (p->rr_cluster_id && (src->rr_cluster_id != p->rr_cluster_id))
|
||||||
bgp_cluster_list_prepend(&attrs, pool, p->rr_cluster_id);
|
ad = int_set_add(pool, ad, p->rr_cluster_id);
|
||||||
|
|
||||||
|
/* Should be at least one prepended cluster ID */
|
||||||
|
bgp_set_attr_ptr(&attrs, pool, BA_CLUSTER_LIST, 0, ad);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AS4_* transition attributes, RFC 6793 4.2.2 */
|
/* AS4_* transition attributes, RFC 6793 4.2.2 */
|
||||||
|
@ -1421,6 +1422,12 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Presence of mandatory attributes ORIGIN and AS_PATH is ensured by above
|
||||||
|
* conditions. Presence and validity of quasi-mandatory NEXT_HOP attribute
|
||||||
|
* should be checked in AF-specific hooks.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Apply per-attribute export hooks for validatation and normalization */
|
/* Apply per-attribute export hooks for validatation and normalization */
|
||||||
return bgp_export_attrs(&s, attrs);
|
return bgp_export_attrs(&s, attrs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ struct bgp_config {
|
||||||
u16 local_port; /* Local listening port */
|
u16 local_port; /* Local listening port */
|
||||||
u16 remote_port; /* Neighbor destination port */
|
u16 remote_port; /* Neighbor destination port */
|
||||||
int multihop; /* Number of hops if multihop */
|
int multihop; /* Number of hops if multihop */
|
||||||
int strict_bind; /* Bind listening socket to local address XXXX */
|
int strict_bind; /* Bind listening socket to local address */
|
||||||
int ttl_security; /* Enable TTL security [RFC 5082] */
|
int ttl_security; /* Enable TTL security [RFC 5082] */
|
||||||
int compare_path_lengths; /* Use path lengths when selecting best route */
|
int compare_path_lengths; /* Use path lengths when selecting best route */
|
||||||
int med_metric; /* Compare MULTI_EXIT_DISC even between routes from differen ASes */
|
int med_metric; /* Compare MULTI_EXIT_DISC even between routes from differen ASes */
|
||||||
|
@ -509,22 +509,18 @@ void bgp_update_next_hop(struct bgp_export_state *s, eattr *a, ea_list **to);
|
||||||
#define BAF_PARTIAL 0x20
|
#define BAF_PARTIAL 0x20
|
||||||
#define BAF_EXT_LEN 0x10
|
#define BAF_EXT_LEN 0x10
|
||||||
|
|
||||||
#define BA_ORIGIN 0x01 /* [RFC1771] */ /* WM */
|
#define BA_ORIGIN 0x01 /* RFC 4271 */ /* WM */
|
||||||
#define BA_AS_PATH 0x02 /* WM */
|
#define BA_AS_PATH 0x02 /* WM */
|
||||||
#define BA_NEXT_HOP 0x03 /* WM */
|
#define BA_NEXT_HOP 0x03 /* WM */
|
||||||
#define BA_MULTI_EXIT_DISC 0x04 /* ON */
|
#define BA_MULTI_EXIT_DISC 0x04 /* ON */
|
||||||
#define BA_LOCAL_PREF 0x05 /* WD */
|
#define BA_LOCAL_PREF 0x05 /* WD */
|
||||||
#define BA_ATOMIC_AGGR 0x06 /* WD */
|
#define BA_ATOMIC_AGGR 0x06 /* WD */
|
||||||
#define BA_AGGREGATOR 0x07 /* OT */
|
#define BA_AGGREGATOR 0x07 /* OT */
|
||||||
#define BA_COMMUNITY 0x08 /* [RFC1997] */ /* OT */
|
#define BA_COMMUNITY 0x08 /* RFC 1997 */ /* OT */
|
||||||
#define BA_ORIGINATOR_ID 0x09 /* [RFC1966] */ /* ON */
|
#define BA_ORIGINATOR_ID 0x09 /* RFC 4456 */ /* ON */
|
||||||
#define BA_CLUSTER_LIST 0x0a /* ON */
|
#define BA_CLUSTER_LIST 0x0a /* RFC 4456 */ /* ON */
|
||||||
/* We don't support these: */
|
#define BA_MP_REACH_NLRI 0x0e /* RFC 4760 */
|
||||||
#define BA_DPA 0x0b /* ??? */
|
#define BA_MP_UNREACH_NLRI 0x0f /* RFC 4760 */
|
||||||
#define BA_ADVERTISER 0x0c /* [RFC1863] */
|
|
||||||
#define BA_RCID_PATH 0x0d
|
|
||||||
#define BA_MP_REACH_NLRI 0x0e /* [RFC2283] */
|
|
||||||
#define BA_MP_UNREACH_NLRI 0x0f
|
|
||||||
#define BA_EXT_COMMUNITY 0x10 /* RFC 4360 */
|
#define BA_EXT_COMMUNITY 0x10 /* RFC 4360 */
|
||||||
#define BA_AS4_PATH 0x11 /* RFC 6793 */
|
#define BA_AS4_PATH 0x11 /* RFC 6793 */
|
||||||
#define BA_AS4_AGGREGATOR 0x12 /* RFC 6793 */
|
#define BA_AS4_AGGREGATOR 0x12 /* RFC 6793 */
|
||||||
|
|
|
@ -713,9 +713,13 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, uint len)
|
||||||
#define REPORT(msg, args...) \
|
#define REPORT(msg, args...) \
|
||||||
({ log(L_REMOTE "%s: " msg, s->proto->p.name, ## args); })
|
({ log(L_REMOTE "%s: " msg, s->proto->p.name, ## args); })
|
||||||
|
|
||||||
|
#define DISCARD(msg, args...) \
|
||||||
|
({ REPORT(msg, ## args); return; })
|
||||||
|
|
||||||
#define WITHDRAW(msg, args...) \
|
#define WITHDRAW(msg, args...) \
|
||||||
({ REPORT(msg, ## args); s->err_withdraw = 1; return; })
|
({ REPORT(msg, ## args); s->err_withdraw = 1; return; })
|
||||||
|
|
||||||
|
#define BAD_AFI "Unexpected AF <%u/%u> in UPDATE"
|
||||||
#define BAD_NEXT_HOP "Invalid NEXT_HOP attribute"
|
#define BAD_NEXT_HOP "Invalid NEXT_HOP attribute"
|
||||||
#define NO_NEXT_HOP "Missing NEXT_HOP attribute"
|
#define NO_NEXT_HOP "Missing NEXT_HOP attribute"
|
||||||
|
|
||||||
|
@ -836,21 +840,27 @@ bgp_update_next_hop_ip(struct bgp_export_state *s, eattr *a, ea_list **to)
|
||||||
static uint
|
static uint
|
||||||
bgp_encode_next_hop_none(struct bgp_write_state *s UNUSED, eattr *a UNUSED, byte *buf UNUSED, uint size UNUSED)
|
bgp_encode_next_hop_none(struct bgp_write_state *s UNUSED, eattr *a UNUSED, byte *buf UNUSED, uint size UNUSED)
|
||||||
{
|
{
|
||||||
// FIXME
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bgp_decode_next_hop_none(struct bgp_parse_state *s UNUSED, byte *data UNUSED, uint len UNUSED, rta *a UNUSED)
|
bgp_decode_next_hop_none(struct bgp_parse_state *s UNUSED, byte *data UNUSED, uint len UNUSED, rta *a UNUSED)
|
||||||
{
|
{
|
||||||
// FIXME
|
/*
|
||||||
|
* Although we expect no next hop and RFC 7606 7.11 states that attribute
|
||||||
|
* MP_REACH_NLRI with unexpected next hop length is considered malformed,
|
||||||
|
* FlowSpec RFC 5575 4 states that next hop shall be ignored on receipt.
|
||||||
|
*/
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bgp_update_next_hop_none(struct bgp_export_state *s UNUSED, eattr *a UNUSED, ea_list **to UNUSED)
|
bgp_update_next_hop_none(struct bgp_export_state *s, eattr *a, ea_list **to)
|
||||||
{
|
{
|
||||||
// FIXME
|
/* NEXT_HOP shall not pass */
|
||||||
|
if (a)
|
||||||
|
bgp_unset_attr(to, s->pool, BA_NEXT_HOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1652,15 +1662,15 @@ bgp_create_end_mark(struct bgp_channel *c, byte *buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
bgp_rx_end_mark(struct bgp_proto *p, u32 afi)
|
bgp_rx_end_mark(struct bgp_parse_state *s, u32 afi)
|
||||||
{
|
{
|
||||||
|
struct bgp_proto *p = s->proto;
|
||||||
struct bgp_channel *c = bgp_get_channel(p, afi);
|
struct bgp_channel *c = bgp_get_channel(p, afi);
|
||||||
|
|
||||||
BGP_TRACE(D_PACKETS, "Got END-OF-RIB");
|
BGP_TRACE(D_PACKETS, "Got END-OF-RIB");
|
||||||
|
|
||||||
/* XXXX handle unknown AF in MP_*_NLRI */
|
|
||||||
if (!c)
|
if (!c)
|
||||||
return;
|
DISCARD(BAD_AFI, BGP_AFI(afi), BGP_SAFI(afi));
|
||||||
|
|
||||||
if (c->load_state == BFS_LOADING)
|
if (c->load_state == BFS_LOADING)
|
||||||
c->load_state = BFS_NONE;
|
c->load_state = BFS_NONE;
|
||||||
|
@ -1678,9 +1688,8 @@ bgp_decode_nlri(struct bgp_parse_state *s, u32 afi, byte *nlri, uint len, ea_lis
|
||||||
struct bgp_channel *c = bgp_get_channel(s->proto, afi);
|
struct bgp_channel *c = bgp_get_channel(s->proto, afi);
|
||||||
rta *a = NULL;
|
rta *a = NULL;
|
||||||
|
|
||||||
/* XXXX handle unknown AF in MP_*_NLRI */
|
|
||||||
if (!c)
|
if (!c)
|
||||||
return;
|
DISCARD(BAD_AFI, BGP_AFI(afi), BGP_SAFI(afi));
|
||||||
|
|
||||||
s->channel = c;
|
s->channel = c;
|
||||||
s->add_path = c->add_path_rx;
|
s->add_path = c->add_path_rx;
|
||||||
|
@ -1791,12 +1800,12 @@ bgp_rx_update(struct bgp_conn *conn, byte *pkt, uint len)
|
||||||
|
|
||||||
/* Check for End-of-RIB marker */
|
/* Check for End-of-RIB marker */
|
||||||
if (!s.attr_len && !s.ip_unreach_len && !s.ip_reach_len)
|
if (!s.attr_len && !s.ip_unreach_len && !s.ip_reach_len)
|
||||||
{ bgp_rx_end_mark(p, BGP_AF_IPV4); goto done; }
|
{ bgp_rx_end_mark(&s, BGP_AF_IPV4); goto done; }
|
||||||
|
|
||||||
/* Check for MP End-of-RIB marker */
|
/* Check for MP End-of-RIB marker */
|
||||||
if ((s.attr_len < 8) && !s.ip_unreach_len && !s.ip_reach_len &&
|
if ((s.attr_len < 8) && !s.ip_unreach_len && !s.ip_reach_len &&
|
||||||
!s.mp_reach_len && !s.mp_unreach_len && s.mp_unreach_af) /* XXXX See RFC 7606 5.2 */
|
!s.mp_reach_len && !s.mp_unreach_len && s.mp_unreach_af)
|
||||||
{ bgp_rx_end_mark(p, s.mp_unreach_af); goto done; }
|
{ bgp_rx_end_mark(&s, s.mp_unreach_af); goto done; }
|
||||||
|
|
||||||
if (s.ip_unreach_len)
|
if (s.ip_unreach_len)
|
||||||
bgp_decode_nlri(&s, BGP_AF_IPV4, s.ip_unreach_nlri, s.ip_unreach_len, NULL, NULL, 0);
|
bgp_decode_nlri(&s, BGP_AF_IPV4, s.ip_unreach_nlri, s.ip_unreach_len, NULL, NULL, 0);
|
||||||
|
|
Loading…
Reference in a new issue