[ixpmanager] route server template/32bit ASNs

Andreas Polyrakis apolyr at noc.grnet.gr
Fri Aug 7 07:56:18 IST 2015


On 08/06/2015 08:52 PM, Stefan Kaltenbrunner wrote:
>> Attached you can find our implementation of route servers, including the
>> IXPmanager templates.
>>
>> We follow approach #2, with extended communities.  Although Nick's
>> concerns are valid, we have not encountered cases with members with
>> routers not supporting this feature yet.
>>
>> If you decide to follow our implementation, I can send you an improved
>> version of the function master_to_as() -- but this one also works fine.
> thanks a lot for those examples - would love to see the improved version
> of master_to_as() as well as getting those docs in a plain text format
> because it kinda looks like the PDF has some lines cut off :/
>
>

Hello Stefan,

I attach the header.cfg and neighbor.cfg that you can use to replace (or 
even better, skin) your IXPmanager installation.

The improved master_to_as() function:
(a) has an additional parameter for debugging. The bird configuration 
produced by IXPmanager always set this parameter to OFF (0), but when 
debugging a specific peer you can set this value manually to ON (1) so 
that debug messages will be printed in the log file for this specific peer
(b) augments the community-based policy so that extended communities can 
be used even for 16-bit ASNs. Some of our members found confusing that 
they had to use a mix of standard and extended communities, so now they 
have the option of using only extended communities for prefix 
advertisement control.

I also attach the html page that describes our policy to our members.

The initial pdf I sent you is from a documentation that we have uploaded 
to the euroix wiki
https://wiki.euro-ix.net/index.php/BCP/Technical/Routeserver/BIRD/Samples/GR-IX
If you are a euroix member you can access this directly.

I hope these help. I will be on vacation for the next two weeks, further 
replies may be a bit delayed.

If you have some comments on our implementation or documentation, or if 
you improve them, please share :-)

Regards






-- 
-----------------------------------------------------------------------
Andreas Polyrakis - apolyr at noc.grnet.gr
GRNET NOC Technical Manager
Greek Research & Technology Network - http://www.grnet.gr
56, Mesogion Av., Ampelokipi, 11527 Athens, Greece
Mobile: +30 6972832445    Office: +30 2107474249   Fax: +30 2107474490
-----------------------------------------------------------------------

-------------- next part --------------
### Customer ID: {$int.cid} - Full name: {$int.cname} - Shortname: {$int.cshortname}
### AS number: {$int.autsys} - IPv4/6 address: {$int.address} - ID in peering VLAN: {$int.vliid} ({$int.fvliid})
### Full location name: {$int.location_name} - Location shortname: {$int.location_shortname} - Location tag: {$int.location_tag}
### Peering macro: {$int.peeringmacro} - Maximum # of prefixes: {$int.maxprefixes} - BGP MD5 secret: {$int.bgpmd5secret}

table t_{$int.cshortname}{$int.vliid};

filter peer_{$int.cshortname}{$int.vliid}_to_master
prefix set {$int.cshortname}_prefixes;
int set {$int.cshortname}_ASNs;
{
	# Basic prefix validation. Do not propagate funny prefixes. 
	# Check first AS in AS-PATH, esp to prevent route servers peering to each other
        if !(avoid_martians()) then reject;
        if (bgp_path.first != {$int.autsys} ) then reject;
 
{* Only do filtering if this is enabled per client *}
{if $int['irrdbfilter'] }
	# Check AS-PATH against the appropriate IRRDB macro
        {$int.cshortname}_ASNs = [ {foreach $irrdbAsns as $a}{$a.asn}{if not $a at last},{/if} {if $a at iteration % 10 == 0} 		# {$int.cshortname}-{$int.vliid} - AS{$int.autsys} - {$int.address}
                  {/if}{/foreach} ];

        if !(bgp_path.last ~ {$int.cshortname}_ASNs ) then reject "REJECTING ",net.ip,"/",net.len," received by {$int.cshortname}-{$int.vliid}, AS{$int.autsys}: Origin AS",bgp_path.last," not in AS-SET: {$int.peeringmacro}";
               
{if count( $prefixes )}
	# Check each prefix against the route objects originating from the ASNs in the appropriate IRRDB macro
        {$int.cshortname}_prefixes = [ {foreach $prefixes as $p}{$p.prefix}{if not $p at last},{/if} {/foreach} ];

        if ! (net ~ {$int.cshortname}_prefixes ) then reject "REJECTING ",net.ip,"/",net.len," received by {$int.cshortname}-{$int.vliid}, AS{$int.autsys}: No route object with origin AS",bgp_path.last," for this prefix";
{else}
        # Deny everything because the IRRDB returned nothing
        reject;
{/if}
{else}
        # This ASN was configured not to use IRRDB filtering
{/if}

	# Prepend 1,2,3 times, if (RSasn,65001), (RSasn,65002), (RSasn,65003) have been set
	if (RSasn,65501) ~ bgp_community then bgp_path.prepend(RSasn);
	if (RSasn,65502) ~ bgp_community then { bgp_path.prepend(RSasn); bgp_path.prepend(RSasn); }
	if (RSasn,65503) ~ bgp_community then { bgp_path.prepend(RSasn); bgp_path.prepend(RSasn); bgp_path.prepend(RSasn); }

	# Mark prefixies with "site" community
{if $int.location_shortname eq "EIE"}
	bgp_community.add ((RSasn,65101));
{/if}
{if $int.location_shortname eq "LH"}
	bgp_community.add ((RSasn,65102));
{/if}
{if $int.location_shortname eq "MED"}
	bgp_community.add ((RSasn,65103));
{/if}

	# Done filtering & manipulation. Accept!
        accept;
}

protocol pipe p_{$int.cshortname}{$int.vliid} {
	description "Pipe for {$int.cshortname}{$int.vliid} (AS{$int.autsys} - {$int.address})";
	table master;
	mode transparent;
	peer table t_{$int.cshortname}{$int.vliid};
	import filter peer_{$int.cshortname}{$int.vliid}_to_master;
	export where master_to_as({$int.autsys},"{$int.location_shortname}",0);
}

protocol bgp b_{$int.cshortname}{$int.vliid} from grix_rs_client {
	description "BGP for {$int.cshortname}{$int.vliid} (AS{$int.autsys} - {$int.address})";
	neighbor {$int.address} as {$int.autsys};
	route limit {$int.maxprefixes};
	table t_{$int.cshortname}{$int.vliid};
	bfd on; # This should be configured for specific peers in the future.
{if $int.bgpmd5secret}	password "{$int.bgpmd5secret}";{/if}
}

-------------- next part --------------
#################################################################################
#
# Bird Route Server configuration for VLAN: {$vlan->getName()} (Tag: {$vlan->getNumber()})
#
# -------------------------------------------------------------------------------
# This configuration was generated automatically by IXP Manager
#      Generated: {$smarty.now|date_format:'Y-m-d H:i:s'}
#
# Attention: Do not edit manually, it will be overwritten automatically.
#
#################################################################################

#################################################################################
# BASIC DOCUMENTATION
#
#
# 1. Communities
# --------------
#
# ** Advertisement Control: **
# RSasn,PeerAS (1<=PeerAS<65000) or route origin extended community ro,RSasn,PeerAS, PeerAS>65536): Do not advertise to PeerAS
# RSasn,0 : Inverse advertising policy (do not advertise to any peers, except from those defined with RSasn:PeerASn)
#
# ** Prepending (communities can be combined)**
# RSasn,65501: prepend one time
# RSasn,65502: prepend two times
# RSasn,65503: prepend three times
#
# ** MED: **
# RSasn,65000: Do not alter incoming MED for IX switching optimisation
#
# ** Site-Marking: **
# RSasn,65101: Prefix received from a peering at EIE site
# RSasn,65102: Prefix received from a peering at LH site
# RSasn,65103: Prefix received from a peering at MED site
#
#
# 2. Route selection
# ------------------
# 1. Prefer route with the highest Local Preference attribute.
#	(no practical use, Local Pref is not used in our implementation)
# 2. Prefer route with the shortest AS path.
#	(in use)	
# 3. Prefer IGP origin over EGP and EGP origin over incomplete.
#	(in use)	
# 4. Prefer the lowest value of the Multiple Exit Discriminator.
#	(in use, BUT only MED from prefixes advertised by peerings of the SAME AS are compared (always-compare-med not enabled))	
# 5. Prefer routes received via eBGP over ones received via iBGP.
#	(no practical use, all peerings are eBGP)	
# 6. Prefer routes with lower internal distance to a boundary router.
#	(no practical use, all distances are the same)	
# 7. Prefer older routes
#	(this is not part of the route selection algorithm but it is a configurable option of the route server to avoid unstable toutes)
# 8. Prefer the route with the lowest value of router ID of the advertising router.
#	(in use)
#
#
#################################################################################


timeformat base     iso long;
timeformat log      iso long;
timeformat protocol iso long;
timeformat route    iso long;

log "{#rsconfLogfile#}" all;
log syslog all;
log stderr all;

# Turn on global debugging of all protocols
#debug protocols all;

define RSasn = {#rsconfASN#};
define RSaddress = {#rsconfListenAddr#};

router id {#rsconfRouterID#};
listen bgp address {#rsconfListenAddr#};

# ignore interface up/down events
protocol device { }
protocol direct { }

### Filter Martians Function
# This function excludes weird networks
#  rfc1918, class D, class E, too long and too short prefixes
function avoid_martians()
prefix set martians;
{
    {if $proto eq 6}

        martians = [
                ::/0,                   # Default (can be advertised as a route in BGP to peers if desired)
                ::/96,                  # IPv4-compatible IPv6 address <E2><80><93> deprecated by RFC4291
                ::/128,                 # Unspecified address
                ::1/128,                # Local host loopback address
                ::ffff:0.0.0.0/96+,     # IPv4-mapped addresses
                ::224.0.0.0/100+,       # Compatible address (IPv4 format)
                ::127.0.0.0/104+,       # Compatible address (IPv4 format)
                ::0.0.0.0/104+,         # Compatible address (IPv4 format)
                ::255.0.0.0/104+,       # Compatible address (IPv4 format)
                0000::/8+,              # Pool used for unspecified, loopback and embedded IPv4 addresses
                0200::/7+,              # OSI NSAP-mapped prefix set (RFC4548) <E2><80><93> deprecated by RFC4048
                3ffe::/16+,             # Former 6bone, now decommissioned
                2001:db8::/32+,         # Reserved by IANA for special purposes and documentation
                2002:e000::/20+,        # Invalid 6to4 packets (IPv4 multicast)
                2002:7f00::/24+,        # Invalid 6to4 packets (IPv4 loopback)
                2002:0000::/24+,        # Invalid 6to4 packets (IPv4 default)
                2002:ff00::/24+,        # Invalid 6to4 packets
                2002:0a00::/24+,        # Invalid 6to4 packets (IPv4 private 10.0.0.0/8 network)
                2002:ac10::/28+,        # Invalid 6to4 packets (IPv4 private 172.16.0.0/12 network)
                2002:c0a8::/32+,        # Invalid 6to4 packets (IPv4 private 192.168.0.0/16 network)
                fc00::/7+,              # Unicast Unique Local Addresses (ULA) <E2><80><93> RFC 4193
                fe80::/10+,             # Link-local Unicast
                fec0::/10+,             # Site-local Unicast <E2><80><93> deprecated by RFC 3879 (replaced by ULA)
                ff00::/8+               # Multicast
        ];

     {else}

        martians = [
                10.0.0.0/8+,
                169.254.0.0/16+,
                172.16.0.0/12+,
                192.0.0.0/24+,
                192.0.2.0/24+,
                192.168.0.0/16+,
                198.18.0.0/15+,
                198.51.100.0/24+,
                203.0.113.0/24+,
                224.0.0.0/4+,
                240.0.0.0/4+,
                0.0.0.0/32-,
                0.0.0.0/0{ldelim}28,32{rdelim},
                0.0.0.0/0{ldelim}0,7{rdelim}
        ];

     {/if}

        # Avoid RFC1918 and similar networks
        if net ~ martians then {
		print "REJECTING ",net.ip,"/",net.len," received by ",from,": Martian/too long/too short prefix";
		return false;
		}

        return true;
}

### Filtering between members Function
# Applied on the pipes between the master table and each members' table
# peeras: the AS of the peer towards which the prefixes are exported
# site: the GR-IX POP name where the peering is located
# dbg: set to 1 to print debug messages for this peer (check the log file)
function master_to_as(int peeras;string site;int dbg)
{

	# reject non-BGP routes
	if ! (source = RTS_BGP) then {
		if (dbg=1) then print "DEBUG ",peeras,": REJECT ",net.ip,"/",net.len," from ",from,", REASON: not a BGP prefix";
		return false;
	}

        if  ( ((RSasn,0) ~ bgp_community) || ((rt,RSasn,0) ~ bgp_ext_community) ) then {        # Default reject policy. Allow only (Rsasn,peeras) or (rt,Rsasn,peeras)
                if !( (peeras <= 65535 && ((RSasn,peeras) ~ bgp_community)) 
                      || ((rt,RSasn,peeras) ~ bgp_ext_community) 
                    ) then {
                        if (dbg=1) then print "DEBUG ",peeras,": REJECT ",net.ip,"/",net.len," from ",from,", REASON: Default reject and not implicitely allowed ",bgp_community," - ",bgp_ext_community;
                        return false;
                }
        } else  {                                     # Default accept policy. Deny (Rsasn,peeras) or (rt,Rsasn,peeras)
                if ( (peeras <= 65535 && ((RSasn,peeras) ~ bgp_community)) 
                     || ((rt,RSasn,peeras) ~ bgp_ext_community) 
                   ) then {
                        if (dbg=1) then print "DEBUG ",peeras,": REJECT ",net.ip,"/",net.len," from ",from,", REASON: Default announce, but explicitely forbidden ",bgp_community," - ",bgp_ext_community;
                        return false;
                }
        }

        if !((RSasn,65000) ~ bgp_community) then { # MED values are not used by the member; they can be used to optimised switching within the exchange
                bgp_med = 0;
                if ( site = "EIE" && (RSasn,65102) ~ bgp_community ) then bgp_med = 2;
                if ( site = "EIE" && (RSasn,65103) ~ bgp_community ) then bgp_med = 4;
                if ( site = "LH" && (RSasn,65101) ~ bgp_community ) then bgp_med = 2;
                if ( site = "LH" && (RSasn,65103) ~ bgp_community ) then bgp_med = 2;
                if ( site = "MED" && (RSasn,65101) ~ bgp_community ) then bgp_med = 4;
                if ( site = "MED" && (RSasn,65102) ~ bgp_community ) then bgp_med = 2;
        }

        if (dbg=1) then print "DEBUG ",peeras,": ACCEPT ",net.ip,"/",net.len," from ",from," ",bgp_community," - ",bgp_ext_community;

        return true;

}


### ETH0 BFD configuration
protocol bfd rs_bfd {
        interface "eth0" {
        interval 400ms;
        multiplier 5;
        passive on;
        };
}

### GR-IX Route Server Client Template
template bgp grix_rs_client {
        local as RSasn;
        source address RSaddress;
        rs client;			# Preserve AS-PATH, next-hop and MED
        passive on;			# Do not initiate bgp sessions
	prefer older on;		# Do not bread ties through IDs; keep the older (more stable) route
	interpret communities off;	# Do not respect NO-EXPORT and NO-ADVERTISE (and preserve them in the outgoing advertisements)
	graceful restart on;		# Participate in graceful restart recovery
	error wait time 60,43200;
        export all;
	{if $proto eq 4}
        import filter {
                ## Prevent BGP NEXT_HOP Hijacking
                if !( from = bgp_next_hop ) then
                    reject "REJECTING ",net.ip,"/",net.len,": BGP neighbor address [", from, "] does not match next hop address [", bgp_next_hop, "]";
                accept;
        };
	{else}
        import all;
	{/if}
}

############### END OF COMMON CONFIG, PER MEMBER CONFIGURATION FOLLOWS ###############

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.inex.ie/pipermail/ixpmanager/attachments/20150807/a94d201a/attachment.html>


More information about the ixpmanager mailing list