Commit 3f9b7bfe authored by Ondřej Zajíček's avatar Ondřej Zajíček

Implements option that controls IPv6 BGP next hops when lladdr is missing.

parent 62aa96ca
......@@ -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 &tilde; [ 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;
nh = ea_find(buck->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
ASSERT(nh);
/* We have two addresses here in 'nh'. Really.
/* 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);
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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment