
Hello, I've also come to think that there should be global communities for the basic purposes that most autonomous systems have built their own communities for. My approach is probably a little different to those of the other contributers to this discussion. Here is a sketch of the new well-known communities I have come up with: 0xFFFn:arg where n designates a function and arg designates a parameter to the function. These could be the functions: n=0 Never announce to AS <arg>. n=1 May announce to AS <arg>. n=2 If you announce to AS <arg>, prepend your own AS once. n=3 If you announce to AS <arg>, prepend your own AS twice. : : n=7 If you announce to AS <arg>, prepend your own AS six times. n=8 When announcing to AS <arg>, change this community to "local-AS" n=9 When announcing to AS <arg>, change this community to "no-advertise" n=10 When announcing to AS <arg>, change this community to "no-export" n=11 Reserved for brainstorming. n=12 Reserved for brainstorming. n=13 Reserved for brainstorming. n=14 Reserved for brainstorming. n=15 This contains the old well-known communities. Perhaps this could also double as "set local preference to <arg>?" 0xFFF0 is 65520, so 0xFFFn is 65520+n. Now I'm not saying these are all useful. I for one don't like to see anyone prepend more than three times and setting "no-advertise" at a distant location can also have quite nasty consequences. They may still have use in some special circumstances. Further brainstorming: an arg of 0 could be interpreted as "all transits" and 65535 as "all peers." If these special cases were to be hard coded into the BGP implementation, then there should be a way to mark sessions as transit/peering/other. If on the other hand support for these communities would be simply via auto-generated route-maps, you would only have to tell the generator the type of the session, and since the data for the generator would most probably come from a database of some kind the generator would get the type from there automagically. These communities should be able to travel through multiple autonomous systems. They should be usable to influence not only your transits' transits' routing decisions, but your transits' peers', your transits' transits' peers', your transits' transits' transits' peers' and so on. Getting all involved parties to turn on send-community on all involved BGP sessions is of course a challenge, but a one that has already been overcome with the existing "transit provider proprietary" communities where needed. Randy Bush pointed out an underlying problem with trusting preference hints from distant autonomous systems. I would like to argue the case against him and for letting everyone influence one's routing decisions. Suppose I have a transit T, a peer P, a customer C and a distant third party D. Suppose also that D has contractual agreements that result in me hearing D's routes from all of T, P and C. By default I would prefer D's routes heard from C. However, if D wishes me to use T or P to reach D instead, D can do so without the use of any communities. D can lower the preference of a path through P or C by arranging it so that I don't hear D from P or C, and D can increase the preference of a path by making me hear D's routes as more specifics from there. Both of these practises I frown upon. I would therefore see that it would be in my best interest to let D influence my routing decisions directly instead of littering my routing table or eating at the redundancy between my customers and D. Furthermore it should be in D's best interest not to give hints to use a bad path between D and me. If D would choose to maliciously abuse my trust (whether via the kludges or via the preference hints presented) I can always work to override or filter the bad routes and try to contact D's upstreams or D directly to resolve the issue. Alex Bligh noted that main stream IOS has insufficient means of manipulating communities. The bleeding edge versions have had methods for removing only some communities while preserving others for a good time now. I do agree though that routing policies can often be much more complicated than what is implementable with route-maps no matter how modern. -- Aleksi Suhonen Here is a sample shell script that does simple automagic. If anyone would use it, it would need to be modified to implement one's own routing policy too. It is included only as an example and proof of concept. I have not tested that what it produces actually works. #!/bin/sh # Usage: this-program my-as their-as their-ip comm-list session-type # comm-list: index of first available "ip community-list" # session-type: (T)ransit (P)eer (C)ustomer my_as=$1 their_as=$2 their_ip=$3 comm_deny=$4 comm_pre1=`echo 1+$4|bc` comm_pre2=`echo 2+$4|bc` comm_pre3=`echo 3+$4|bc` comm_pre4=`echo 4+$4|bc` comm_pre5=`echo 5+$4|bc` comm_pre6=`echo 6+$4|bc` comm_loas=`echo 7+$4|bc` comm_noad=`echo 8+$4|bc` comm_noex=`echo 9+$4|bc` # these can be reused for all sessions comm_local_pref_80=1 comm_local_pref_90=2 comm_local_pref_110=3 comm_remove=4 # set these to your values transit_route_tag=${my_as}:666 peer_route_tag=${my_as}:555 customer_route_tag=${my_as}:777 route_map_name_prefix=axu-${their_as} case $5 in T*) announce_community=$customer_route_tag denounce_community="$transit_route_tag $peer_route_tag" tag_community=$transit_route_tag default_preference=90 their_class=0 ;; P*) announce_community=$customer_route_tag denounce_community="$transit_route_tag $peer_route_tag" tag_community=$peer_route_tag default_preference=100 their_class=65535 ;; *) announce_community="$transit_route_tag $peer_route_tag $customer_route_t ag" denounce_community="" tag_community=$customer_route_tag default_preference=101 their_class=65534 ;; esac denounce_community="$denounce_community 65520:${their_as} 65520:${their_class}" cat <<EOF ! reused community-lists ip community-list $comm_local_pref_80 deny 65535:100 ip community-list $comm_local_pref_80 permit 65535:80 ip community-list $comm_local_pref_90 deny 65535:100 ip community-list $comm_local_pref_90 permit 65535:90 ip community-list $comm_local_pref_110 deny 65535:100 ip community-list $comm_local_pref_110 permit 65535:110 ip community-list $comm_remove permit 65535:80 65535:90 65535:100 65535:110 ip community-list $comm_remove permit $transit_route_tag $peer_route_tag ip community-list $comm_remove permit $customer_route_tag ! new community-lists ip community-list $comm_deny permit $denounce_community ip community-list $comm_pre1 permit 65522:${their_as} ip community-list $comm_pre1 permit 65522:${their_class} ip community-list $comm_pre2 permit 65523:${their_as} ip community-list $comm_pre2 permit 65523:${their_class} ip community-list $comm_pre3 permit 65524:${their_as} ip community-list $comm_pre3 permit 65524:${their_class} ip community-list $comm_pre4 permit 65525:${their_as} ip community-list $comm_pre4 permit 65525:${their_class} ip community-list $comm_pre5 permit 65526:${their_as} ip community-list $comm_pre5 permit 65526:${their_class} ip community-list $comm_pre6 permit 65527:${their_as} ip community-list $comm_pre6 permit 65527:${their_class} ip community-list $comm_loas permit 65528:${their_as} ip community-list $comm_loas permit 65528:${their_class} ip community-list $comm_noad permit 65529:${their_as} ip community-list $comm_noad permit 65529:${their_class} ip community-list $comm_noex permit 65530:${their_as} ip community-list $comm_noex permit 65530:${their_class} route-map ${route_map_name_prefix}-in permit 10 match community $comm_local_pref_80 set local-preference 80 set comm-list $comm_remove delete set community $tag_community additive ! route-map ${route_map_name_prefix}-in permit 20 match community $comm_local_pref_90 set local-preference 90 set comm-list $comm_remove delete set community $tag_community additive ! route-map ${route_map_name_prefix}-in permit 30 match community $comm_local_pref_110 set local-preference 110 set comm-list $comm_remove delete set community $tag_community additive ! route-map ${route_map_name_prefix}-in permit 40 set local-preference $default_preference set comm-list $comm_remove delete set community $tag_community additive ! route-map ${route_map_name_prefix}-out deny 10 match community $comm_deny ! route-map ${route_map_name_prefix}-out permit 20 match community $comm_pre1 set as-path prepend ${my_as} ! route-map ${route_map_name_prefix}-out permit 30 match community $comm_pre2 set as-path prepend ${my_as} ${my_as} ! route-map ${route_map_name_prefix}-out permit 40 match community $comm_pre3 set as-path prepend ${my_as} ${my_as} ${my_as} ! route-map ${route_map_name_prefix}-out permit 50 match community $comm_pre4 set as-path prepend ${my_as} ${my_as} ${my_as} ${my_as} ! route-map ${route_map_name_prefix}-out permit 60 match community $comm_pre5 set as-path prepend ${my_as} ${my_as} ${my_as} ${my_as} ${my_as} ! route-map ${route_map_name_prefix}-out permit 70 match community $comm_pre6 set as-path prepend ${my_as} ${my_as} ${my_as} ${my_as} ${my_as} ${my_as} ! route-map ${route_map_name_prefix}-out permit 80 match community $comm_loas set comm-list $comm_loas delete set community local-AS additive ! route-map ${route_map_name_prefix}-out permit 90 match community $comm_noad set comm-list $comm_noad delete set community no-advertise additive ! route-map ${route_map_name_prefix}-out permit 100 match community $comm_noex set comm-list $comm_noex delete set community no-export additive ! route-map ${route_map_name_prefix}-out permit 110 router bgp ${my_as} neighbor ${their_ip} remote-as ${their_as} neighbor ${their_ip} next-hop-self neighbor ${their_ip} send-community neighbor ${their_ip} remove-private-AS neighbor ${their_ip} route-map ${route_map_name_prefix}-in in neighbor ${their_ip} route-map ${route_map_name_prefix}-out out EOF