mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-12 11:18:59 +00:00
bgpd: conditional default-originate using route-map
Incorporate a patch by Svetozar Mihailov which implements default-originate route-maps to behave as expected, i.e. allowing the default route to be advertised conditionally, depending on a criterion given by the route-map. I am aware that the performance attributes of the following implementation are far from optimal. However, this affects only code paths belonging to a feature that is broken without this patch, therefore, it seems reasonable to me to have this in the mainline for now. Cc: Svetozar Mihailov <quagga@j.zarhi.com> Reported-by: Sébastien Cramatte <scramatte@gmail.com> Signed-off-by: Christian Franke <chris@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
86998bc2bc
commit
dcab1bb822
5
NEWS
5
NEWS
@ -1,5 +1,10 @@
|
|||||||
Note: this file lists major user-visible changes only.
|
Note: this file lists major user-visible changes only.
|
||||||
|
|
||||||
|
- [bgpd] The semantics of default-originate route-map have changed.
|
||||||
|
The route-map is now used to advertise the default route conditionally.
|
||||||
|
The old behaviour which allowed to set attributes on the originated
|
||||||
|
default route is no longer supported.
|
||||||
|
|
||||||
* Changes in Quagga 0.99.21
|
* Changes in Quagga 0.99.21
|
||||||
|
|
||||||
- [bgpd] BGP multipath support has been merged
|
- [bgpd] BGP multipath support has been merged
|
||||||
|
@ -506,6 +506,16 @@ bgp_scan (afi_t afi, safi_t safi)
|
|||||||
else if (afi == AFI_IP6)
|
else if (afi == AFI_IP6)
|
||||||
zlog_debug ("scanning IPv6 Unicast routing tables");
|
zlog_debug ("scanning IPv6 Unicast routing tables");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reevaluate default-originate route-maps and announce/withdraw
|
||||||
|
* default route if neccesary. */
|
||||||
|
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
|
||||||
|
{
|
||||||
|
if (peer->status == Established
|
||||||
|
&& CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)
|
||||||
|
&& peer->default_rmap[afi][safi].name)
|
||||||
|
bgp_default_originate (peer, afi, safi, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BGP scan thread. This thread check nexthop reachability. */
|
/* BGP scan thread. This thread check nexthop reachability. */
|
||||||
|
@ -2462,8 +2462,9 @@ bgp_default_originate (struct peer *peer, afi_t afi, safi_t safi, int withdraw)
|
|||||||
struct attr attr;
|
struct attr attr;
|
||||||
struct aspath *aspath;
|
struct aspath *aspath;
|
||||||
struct prefix p;
|
struct prefix p;
|
||||||
struct bgp_info binfo;
|
|
||||||
struct peer *from;
|
struct peer *from;
|
||||||
|
struct bgp_node *rn;
|
||||||
|
struct bgp_info *ri;
|
||||||
int ret = RMAP_DENYMATCH;
|
int ret = RMAP_DENYMATCH;
|
||||||
|
|
||||||
if (!(afi == AFI_IP || afi == AFI_IP6))
|
if (!(afi == AFI_IP || afi == AFI_IP6))
|
||||||
@ -2505,22 +2506,38 @@ bgp_default_originate (struct peer *peer, afi_t afi, safi_t safi, int withdraw)
|
|||||||
|
|
||||||
if (peer->default_rmap[afi][safi].name)
|
if (peer->default_rmap[afi][safi].name)
|
||||||
{
|
{
|
||||||
binfo.peer = bgp->peer_self;
|
|
||||||
binfo.attr = &attr;
|
|
||||||
|
|
||||||
SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT);
|
SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT);
|
||||||
|
for (rn = bgp_table_top(bgp->rib[afi][safi]); rn; rn = bgp_route_next(rn))
|
||||||
|
{
|
||||||
|
for (ri = rn->info; ri; ri = ri->next)
|
||||||
|
{
|
||||||
|
struct attr dummy_attr;
|
||||||
|
struct attr_extra dummy_extra;
|
||||||
|
struct bgp_info info;
|
||||||
|
|
||||||
ret = route_map_apply (peer->default_rmap[afi][safi].map, &p,
|
/* Provide dummy so the route-map can't modify the attributes */
|
||||||
RMAP_BGP, &binfo);
|
dummy_attr.extra = &dummy_extra;
|
||||||
|
bgp_attr_dup(&dummy_attr, ri->attr);
|
||||||
|
info.peer = ri->peer;
|
||||||
|
info.attr = &dummy_attr;
|
||||||
|
|
||||||
|
ret = route_map_apply(peer->default_rmap[afi][safi].map, &rn->p,
|
||||||
|
RMAP_BGP, &info);
|
||||||
|
|
||||||
|
/* The route map might have set attributes. If we don't flush them
|
||||||
|
* here, they will be leaked. */
|
||||||
|
bgp_attr_flush(&dummy_attr);
|
||||||
|
if (ret != RMAP_DENYMATCH)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ret != RMAP_DENYMATCH)
|
||||||
|
break;
|
||||||
|
}
|
||||||
bgp->peer_self->rmap_type = 0;
|
bgp->peer_self->rmap_type = 0;
|
||||||
|
|
||||||
if (ret == RMAP_DENYMATCH)
|
if (ret == RMAP_DENYMATCH)
|
||||||
{
|
|
||||||
bgp_attr_flush (&attr);
|
|
||||||
withdraw = 1;
|
withdraw = 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (withdraw)
|
if (withdraw)
|
||||||
{
|
{
|
||||||
@ -2529,10 +2546,13 @@ bgp_default_originate (struct peer *peer, afi_t afi, safi_t safi, int withdraw)
|
|||||||
UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE);
|
UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE))
|
||||||
{
|
{
|
||||||
SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE);
|
SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE);
|
||||||
bgp_default_update_send (peer, &attr, afi, safi, from);
|
bgp_default_update_send (peer, &attr, afi, safi, from);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bgp_attr_extra_free (&attr);
|
bgp_attr_extra_free (&attr);
|
||||||
aspath_unintern (&aspath);
|
aspath_unintern (&aspath);
|
||||||
|
Loading…
Reference in New Issue
Block a user