mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-08 12:18:42 +00:00
Implements option that controls IPv6 BGP next hops when lladdr is missing.
This commit is contained in:
parent
62aa96caa2
commit
3f9b7bfe9f
@ -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.
|
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
|
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{16,24}</cf> and <cf>192.168.0.0/16 ge 24</cf> as
|
||||||
<cf>192.168.0.0/16{24,32}</cf>.
|
<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/.
|
we should route via our direct neighbor with address <m/ip/.
|
||||||
Default: switched off.
|
Default: switched off.
|
||||||
|
|
||||||
<tag>next hop self</tag> Avoid calculation of the Next Hop attribute
|
<tag>next hop self</tag> Avoid calculation of the Next Hop
|
||||||
and always advertise our own source address (see below) as a next hop.
|
attribute and always advertise our own source address (see
|
||||||
This needs to be used only
|
below) as a next hop. This needs to be used only occasionally
|
||||||
occasionally to circumvent misconfigurations of other routers.
|
to circumvent misconfigurations of other routers.
|
||||||
Default: disabled.
|
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
|
<tag>source address <m/ip/</tag> Define local address we should use
|
||||||
for next hop calculation. Default: the address of the local end
|
for next hop calculation. Default: the address of the local end
|
||||||
of the interface our neighbor is connected to.
|
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
|
as a route server client. A route server is used as a
|
||||||
replacement for full mesh EBGP routing in Internet exchange
|
replacement for full mesh EBGP routing in Internet exchange
|
||||||
points in a similar way to route reflectors used in IBGP routing.
|
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
|
which behaves like plain EBGP but reduces modifications to advertised route
|
||||||
attributes to be transparent (for example does not prepend its AS number to
|
attributes to be transparent (for example does not prepend its AS number to
|
||||||
AS PATH attribute and keep MED attribute). Default: disabled.
|
AS PATH attribute and keep MED attribute). Default: disabled.
|
||||||
|
@ -141,7 +141,7 @@ proto_item:
|
|||||||
| EXPORT imexport { this_proto->out_filter = $2; }
|
| EXPORT imexport { this_proto->out_filter = $2; }
|
||||||
| TABLE rtable { this_proto->table = $2; }
|
| TABLE rtable { this_proto->table = $2; }
|
||||||
| ROUTER ID idval { this_proto->router_id = $3; }
|
| ROUTER ID idval { this_proto->router_id = $3; }
|
||||||
| DESCRIPTION dsc { this_proto->dsc = $2; }
|
| DESCRIPTION TEXT { this_proto->dsc = $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
imexport:
|
imexport:
|
||||||
|
@ -886,6 +886,10 @@ bgp_check(struct bgp_config *c)
|
|||||||
|
|
||||||
if ((c->local_as == c->remote_as) && (c->rs_client))
|
if ((c->local_as == c->remote_as) && (c->rs_client))
|
||||||
cf_error("Only external neighbor can be 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" };
|
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 multihop_via; /* Multihop: address to route to */
|
||||||
ip_addr source_addr; /* Source address to use */
|
ip_addr source_addr; /* Source address to use */
|
||||||
int next_hop_self; /* Always set next hop to local IP address */
|
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 compare_path_lengths; /* Use path lengths when selecting best route */
|
||||||
int prefer_older; /* Prefer older routes according to RFC 5004 */
|
int prefer_older; /* Prefer older routes according to RFC 5004 */
|
||||||
u32 default_local_pref; /* Default value for LOCAL_PREF attribute */
|
u32 default_local_pref; /* Default value for LOCAL_PREF attribute */
|
||||||
@ -46,6 +47,10 @@ struct bgp_config {
|
|||||||
char *password; /* Password used for MD5 authentication */
|
char *password; /* Password used for MD5 authentication */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MLL_SELF 1
|
||||||
|
#define MLL_DROP 2
|
||||||
|
#define MLL_IGNORE 3
|
||||||
|
|
||||||
struct bgp_conn {
|
struct bgp_conn {
|
||||||
struct bgp_proto *bgp;
|
struct bgp_proto *bgp;
|
||||||
struct birdsock *sk;
|
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_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN, BGP_NEXT_HOP,
|
||||||
BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY, SOURCE, ADDRESS,
|
BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY, SOURCE, ADDRESS,
|
||||||
PASSWORD, RR, RS, CLIENT, CLUSTER, ID, AS4, ADVERTISE, IPV4,
|
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
|
CF_GRAMMAR
|
||||||
|
|
||||||
@ -64,6 +65,9 @@ bgp_proto:
|
|||||||
| bgp_proto KEEPALIVE TIME expr ';' { BGP_CFG->keepalive_time = $4; }
|
| 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 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 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 PATH METRIC bool ';' { BGP_CFG->compare_path_lengths = $4; }
|
||||||
| bgp_proto PREFER OLDER bool ';' { BGP_CFG->prefer_older = $4; }
|
| bgp_proto PREFER OLDER bool ';' { BGP_CFG->prefer_older = $4; }
|
||||||
| bgp_proto DEFAULT BGP_MED expr ';' { BGP_CFG->default_med = $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)
|
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);
|
bgp_flush_prefixes(p, buck);
|
||||||
rem_node(&buck->send_node);
|
rem_node(&buck->send_node);
|
||||||
bgp_free_bucket(p, buck);
|
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_proto *p = conn->bgp;
|
||||||
struct bgp_bucket *buck;
|
struct bgp_bucket *buck;
|
||||||
int size, second;
|
int size, second, rem_stored;
|
||||||
int remains = BGP_MAX_PACKET_LENGTH - BGP_HEADER_LENGTH - 4;
|
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;
|
ip_addr *ipp, ip, ip_ll;
|
||||||
ea_list *ea;
|
ea_list *ea;
|
||||||
eattr *nh;
|
eattr *nh;
|
||||||
@ -272,28 +272,25 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DBG("Processing bucket %p\n", buck);
|
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)
|
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);
|
bgp_flush_prefixes(p, buck);
|
||||||
rem_node(&buck->send_node);
|
rem_node(&buck->send_node);
|
||||||
bgp_free_bucket(p, buck);
|
bgp_free_bucket(p, buck);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
w += size;
|
w += size;
|
||||||
remains -= size;
|
remains -= size;
|
||||||
tstart = tmp = bgp_attach_attr_wa(&ea, bgp_linpool, BA_MP_REACH_NLRI, remains-8);
|
|
||||||
*tmp++ = 0;
|
/* We have two addresses here in NEXT_HOP eattr. Really.
|
||||||
*tmp++ = BGP_AF_IPV6;
|
Unless NEXT_HOP was modified by filter */
|
||||||
*tmp++ = 1;
|
|
||||||
nh = ea_find(buck->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
|
nh = ea_find(buck->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
|
||||||
ASSERT(nh);
|
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);
|
second = (nh->u.ptr->length == NEXT_HOP_LENGTH);
|
||||||
ipp = (ip_addr *) nh->u.ptr->data;
|
ipp = (ip_addr *) nh->u.ptr->data;
|
||||||
ip = ipp[0];
|
ip = ipp[0];
|
||||||
@ -322,12 +319,32 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
|
|||||||
ip_ll = ipp[1];
|
ip_ll = ipp[1];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ip = p->source_addr;
|
switch (p->cf->missing_lladdr)
|
||||||
ip_ll = p->local_link;
|
{
|
||||||
|
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))
|
if (ipa_nonzero(ip_ll))
|
||||||
{
|
{
|
||||||
*tmp++ = 32;
|
*tmp++ = 32;
|
||||||
|
Loading…
Reference in New Issue
Block a user