Implements option that controls IPv6 BGP next hops when lladdr is missing.
This commit is contained in:
parent
62aa96caa2
commit
3f9b7bfe9f
6 changed files with 69 additions and 23 deletions
|
@ -646,7 +646,7 @@ incompatible with each other (that is to prevent you from shooting in the foot).
|
|||
but <cf>1.0.0.0/16 ˜ [ 1.0.0.0/8- ]</cf> is false.
|
||||
|
||||
Cisco-style patterns like <cf>10.0.0.0/8 ge 16 le 24</cf> can be expressed
|
||||
in Bird as <cf>10.0.0.0/8{16,24}</cf>, <cf>192.168.0.0/16 le 24</cf> as
|
||||
in BIRD as <cf>10.0.0.0/8{16,24}</cf>, <cf>192.168.0.0/16 le 24</cf> as
|
||||
<cf>192.168.0.0/16{16,24}</cf> and <cf>192.168.0.0/16 ge 24</cf> as
|
||||
<cf>192.168.0.0/16{24,32}</cf>.
|
||||
|
||||
|
@ -887,12 +887,28 @@ for each neighbor using the following configuration parameters:
|
|||
we should route via our direct neighbor with address <m/ip/.
|
||||
Default: switched off.
|
||||
|
||||
<tag>next hop self</tag> Avoid calculation of the Next Hop attribute
|
||||
and always advertise our own source address (see below) as a next hop.
|
||||
This needs to be used only
|
||||
occasionally to circumvent misconfigurations of other routers.
|
||||
<tag>next hop self</tag> Avoid calculation of the Next Hop
|
||||
attribute and always advertise our own source address (see
|
||||
below) as a next hop. This needs to be used only occasionally
|
||||
to circumvent misconfigurations of other routers.
|
||||
Default: disabled.
|
||||
|
||||
<tag>missing lladdr self|drop|ignore</tag>Next Hop attribute
|
||||
in BGP-IPv6 sometimes contains just the global IPv6 address,
|
||||
but sometimes it has to contain both global and link-local
|
||||
IPv6 addresses. This option specifies what to do if BIRD have
|
||||
to send both addresses but does not know link-local address.
|
||||
This situation might happen when routes from other protocols
|
||||
are exported to BGP, or when improper updates are received
|
||||
from BGP peers. <tag/self/ means that BIRD advertises its own
|
||||
local address instead. <tag/drop/ means that BIRD skips that
|
||||
prefixes and logs error. <tag/ignore/ means that BIRD ignores
|
||||
the problem and sends just the global address (and therefore
|
||||
forms improper BGP update). Default: <tag/self/, unless BIRD
|
||||
is configured as a route server (option <tag/rs client/), in
|
||||
that case default is <tag/drop/, because route servers usually
|
||||
does not forward packets ifselves.
|
||||
|
||||
<tag>source address <m/ip/</tag> Define local address we should use
|
||||
for next hop calculation. Default: the address of the local end
|
||||
of the interface our neighbor is connected to.
|
||||
|
@ -920,7 +936,7 @@ for each neighbor using the following configuration parameters:
|
|||
as a route server client. A route server is used as a
|
||||
replacement for full mesh EBGP routing in Internet exchange
|
||||
points in a similar way to route reflectors used in IBGP routing.
|
||||
Bird does not implement obsoleted RFC 1863, but uses ad-hoc implementation,
|
||||
BIRD does not implement obsoleted RFC 1863, but uses ad-hoc implementation,
|
||||
which behaves like plain EBGP but reduces modifications to advertised route
|
||||
attributes to be transparent (for example does not prepend its AS number to
|
||||
AS PATH attribute and keep MED attribute). Default: disabled.
|
||||
|
|
|
@ -141,7 +141,7 @@ proto_item:
|
|||
| EXPORT imexport { this_proto->out_filter = $2; }
|
||||
| TABLE rtable { this_proto->table = $2; }
|
||||
| ROUTER ID idval { this_proto->router_id = $3; }
|
||||
| DESCRIPTION dsc { this_proto->dsc = $2; }
|
||||
| DESCRIPTION TEXT { this_proto->dsc = $2; }
|
||||
;
|
||||
|
||||
imexport:
|
||||
|
|
|
@ -886,6 +886,10 @@ bgp_check(struct bgp_config *c)
|
|||
|
||||
if ((c->local_as == c->remote_as) && (c->rs_client))
|
||||
cf_error("Only external neighbor can be RS client");
|
||||
|
||||
/* Different default based on rs_client */
|
||||
if (c->missing_lladdr == 0)
|
||||
c->missing_lladdr = c->rs_client ? MLL_DROP : MLL_SELF;
|
||||
}
|
||||
|
||||
static char *bgp_state_names[] = { "Idle", "Connect", "Active", "OpenSent", "OpenConfirm", "Established", "Close" };
|
||||
|
|
|
@ -23,6 +23,7 @@ struct bgp_config {
|
|||
ip_addr multihop_via; /* Multihop: address to route to */
|
||||
ip_addr source_addr; /* Source address to use */
|
||||
int next_hop_self; /* Always set next hop to local IP address */
|
||||
int missing_lladdr; /* What we will do when we don' know link-local addr, see MLL_* */
|
||||
int compare_path_lengths; /* Use path lengths when selecting best route */
|
||||
int prefer_older; /* Prefer older routes according to RFC 5004 */
|
||||
u32 default_local_pref; /* Default value for LOCAL_PREF attribute */
|
||||
|
@ -46,6 +47,10 @@ struct bgp_config {
|
|||
char *password; /* Password used for MD5 authentication */
|
||||
};
|
||||
|
||||
#define MLL_SELF 1
|
||||
#define MLL_DROP 2
|
||||
#define MLL_IGNORE 3
|
||||
|
||||
struct bgp_conn {
|
||||
struct bgp_proto *bgp;
|
||||
struct birdsock *sk;
|
||||
|
|
|
@ -22,7 +22,8 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE,
|
|||
BGP_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN, BGP_NEXT_HOP,
|
||||
BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY, SOURCE, ADDRESS,
|
||||
PASSWORD, RR, RS, CLIENT, CLUSTER, ID, AS4, ADVERTISE, IPV4,
|
||||
CAPABILITIES, LIMIT, PASSIVE, PREFER, OLDER)
|
||||
CAPABILITIES, LIMIT, PASSIVE, PREFER, OLDER, MISSING, LLADDR,
|
||||
DROP, IGNORE)
|
||||
|
||||
CF_GRAMMAR
|
||||
|
||||
|
@ -64,6 +65,9 @@ bgp_proto:
|
|||
| bgp_proto KEEPALIVE TIME expr ';' { BGP_CFG->keepalive_time = $4; }
|
||||
| bgp_proto MULTIHOP expr VIA ipa ';' { BGP_CFG->multihop = $3; BGP_CFG->multihop_via = $5; }
|
||||
| bgp_proto NEXT HOP SELF ';' { BGP_CFG->next_hop_self = 1; }
|
||||
| bgp_proto MISSING LLADDR SELF ';' { BGP_CFG->missing_lladdr = MLL_SELF; }
|
||||
| bgp_proto MISSING LLADDR DROP ';' { BGP_CFG->missing_lladdr = MLL_DROP; }
|
||||
| bgp_proto MISSING LLADDR IGNORE ';' { BGP_CFG->missing_lladdr = MLL_IGNORE; }
|
||||
| bgp_proto PATH METRIC bool ';' { BGP_CFG->compare_path_lengths = $4; }
|
||||
| bgp_proto PREFER OLDER bool ';' { BGP_CFG->prefer_older = $4; }
|
||||
| bgp_proto DEFAULT BGP_MED expr ';' { BGP_CFG->default_med = $4; }
|
||||
|
|
|
@ -199,7 +199,7 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
|
|||
|
||||
if (a_size < 0)
|
||||
{
|
||||
log(L_ERR "%s: Attribute list too long, skipping corresponding route group", p->p.name);
|
||||
log(L_ERR "%s: Attribute list too long, skipping corresponding routes", p->p.name);
|
||||
bgp_flush_prefixes(p, buck);
|
||||
rem_node(&buck->send_node);
|
||||
bgp_free_bucket(p, buck);
|
||||
|
@ -234,9 +234,9 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
|
|||
{
|
||||
struct bgp_proto *p = conn->bgp;
|
||||
struct bgp_bucket *buck;
|
||||
int size, second;
|
||||
int size, second, rem_stored;
|
||||
int remains = BGP_MAX_PACKET_LENGTH - BGP_HEADER_LENGTH - 4;
|
||||
byte *w, *tmp, *tstart;
|
||||
byte *w, *w_stored, *tmp, *tstart;
|
||||
ip_addr *ipp, ip, ip_ll;
|
||||
ea_list *ea;
|
||||
eattr *nh;
|
||||
|
@ -272,28 +272,25 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
|
|||
}
|
||||
|
||||
DBG("Processing bucket %p\n", buck);
|
||||
size = bgp_encode_attrs(p, w, buck->eattrs, 2048);
|
||||
rem_stored = remains;
|
||||
w_stored = w;
|
||||
|
||||
size = bgp_encode_attrs(p, w, buck->eattrs, 2048);
|
||||
if (size < 0)
|
||||
{
|
||||
log(L_ERR "%s: Attribute list too long, ignoring corresponding route group", p->p.name);
|
||||
log(L_ERR "%s: Attribute list too long, skipping corresponding routes", p->p.name);
|
||||
bgp_flush_prefixes(p, buck);
|
||||
rem_node(&buck->send_node);
|
||||
bgp_free_bucket(p, buck);
|
||||
continue;
|
||||
}
|
||||
|
||||
w += size;
|
||||
remains -= size;
|
||||
tstart = tmp = bgp_attach_attr_wa(&ea, bgp_linpool, BA_MP_REACH_NLRI, remains-8);
|
||||
*tmp++ = 0;
|
||||
*tmp++ = BGP_AF_IPV6;
|
||||
*tmp++ = 1;
|
||||
|
||||
/* We have two addresses here in NEXT_HOP eattr. Really.
|
||||
Unless NEXT_HOP was modified by filter */
|
||||
nh = ea_find(buck->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
|
||||
ASSERT(nh);
|
||||
|
||||
/* We have two addresses here in 'nh'. Really.
|
||||
Unless NEXT_HOP was modified by filter */
|
||||
second = (nh->u.ptr->length == NEXT_HOP_LENGTH);
|
||||
ipp = (ip_addr *) nh->u.ptr->data;
|
||||
ip = ipp[0];
|
||||
|
@ -322,12 +319,32 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
|
|||
ip_ll = ipp[1];
|
||||
else
|
||||
{
|
||||
ip = p->source_addr;
|
||||
ip_ll = p->local_link;
|
||||
switch (p->cf->missing_lladdr)
|
||||
{
|
||||
case MLL_SELF:
|
||||
ip = p->source_addr;
|
||||
ip_ll = p->local_link;
|
||||
break;
|
||||
case MLL_DROP:
|
||||
log(L_ERR "%s: Missing link-local next hop address, skipping corresponding routes", p->p.name);
|
||||
w = w_stored;
|
||||
remains = rem_stored;
|
||||
bgp_flush_prefixes(p, buck);
|
||||
rem_node(&buck->send_node);
|
||||
bgp_free_bucket(p, buck);
|
||||
continue;
|
||||
case MLL_IGNORE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tstart = tmp = bgp_attach_attr_wa(&ea, bgp_linpool, BA_MP_REACH_NLRI, remains-8);
|
||||
*tmp++ = 0;
|
||||
*tmp++ = BGP_AF_IPV6;
|
||||
*tmp++ = 1;
|
||||
|
||||
if (ipa_nonzero(ip_ll))
|
||||
{
|
||||
*tmp++ = 32;
|
||||
|
|
Loading…
Reference in a new issue