[DN42] 谈一谈如何配置 BGP community

[DN42] 谈一谈如何配置 BGP community

本文最后更新于 74 天前,其中的信息可能已经有所发展或是发生改变。

注意:
本人是BGP小白,本文章写的十分不严谨,缝合自多位大佬的著作,可能有任何的 错误 / 笔误 / 小白式理解 。请诸位大佬们手下留情。
本文蓝色字体可以点击跳转到对应的网页

如果您能接受的话,可以继续看下去,如果不能接受,建议现在就关闭此文章

前言

本文方案使用的是根据 BGP.community 更改 BGP.local_pref 来选择线路,因为 BGP.local_pref 会在AS内部传递,所以需要同时更改 eBGPiBGP
本文的 BGP.community 仅配置region+country,这俩个一般来说够用了。
本文的配置示例为了示例而生!并未做任何检查!请不要直接照搬!!
本文的配置示例为了示例而生!并未任何检查!请不要直接照搬!!
本文的配置示例为了示例而生!并未任何检查!请不要直接照搬!!
本文的配置示例为了示例而生!并未任何检查!请不要直接照搬!!
本文的配置示例为了示例而生!并未任何检查!请不要直接照搬!!
本文的配置示例为了示例而生!并未任何检查!请不要直接照搬!!
本文的配置示例为了示例而生!并未任何检查!请不要直接照搬!!
本文的配置示例为了示例而生!并未任何检查!请不要直接照搬!!
本文的配置示例为了示例而生!并未任何检查!请不要直接照搬!!

本文的配置示例并非Xeiu Network所用的,但是功能一致。
本文基于 Bird2 – DN42 的配置而作。请仔细斟酌

对路由添加 BGP community

此处的路由仅指你要往外播的,属于你ASN的ip段的路由。

加了 BGP community 可以让别人有更多条件可以判断走哪条线路是最优解。
这个最优解,每个人对其的理解大概都不同。

在eBGP配置的export 的 filter 里边加个判断这个路由是否属于自己的,然后在判断是属于自己的路由打上BGP community就可以了。

这个判断这个路由是否属于自己的,如果你是按照 Bird2 – DN42 里配的bird;或者其扩展,总体上与前者差不多的话:
那么判断函数是 is_self_net()is_self_net_v6() ,前者是判断 ipv4 的,后者是 判断 ipv6 的。

如何为属于自己的路由打上BGP community ?
就要用到 bgp_community.add(); 了。

配置示例

大洲代码和国家或地区的代码的定义指路: DN42 Wiki BGP Communities (自备翻译)

# head
define DN42_REGION  = 52;             # 改成机器所在大洲代码 参见 DN42 Wiki BGP Communities 的 Origin Region 一节
define DN42_COUNTRY = 1344;           # 改成机器所在国家或地区的代码 1000 + ISO 数字三位国家或地区的代码,840 是美国


#eBPG
template bgp dnpeers {
    local as OWNAS;
    path metric 1;

    ipv4 {
        import filter {
          if is_valid_network() && !is_self_net() then {
            if (roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID) then {
              # Reject when unknown or invalid according to ROA
              print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;
              reject;
            } else accept;
          } else reject;
        };

        export filter { if is_valid_network() && source ~ [RTS_STATIC, RTS_BGP] then 
                if (is_self_net()) then {
		            bgp_community.add((64511, DN42_REGION));    #往属于自己的路由打上节点所属区域的BGP community
                    bgp_community.add((64511, DN42_COUNTRY));   #往属于自己的路由打上节点所属国家或地区的BGP community
	            }
                accept;
            else reject; };
        import limit 9000 action block;
    };

    ipv6 {   
        import filter {
          if is_valid_network_v6() && !is_self_net_v6() then {
            if (roa_check(dn42_roa_v6, net, bgp_path.last) != ROA_VALID) then {
              # Reject when unknown or invalid according to ROA
              print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;
              reject;
            } else accept;
          } else reject;
        };
        export filter { if is_valid_network_v6() && source ~ [RTS_STATIC, RTS_BGP] then
                if (is_self_net_v6()) then {
		            bgp_community.add((64511, DN42_REGION));    #往属于自己的路由打上节点所属区域的BGP community
                    bgp_community.add((64511, DN42_COUNTRY));   #往属于自己的路由打上节点所属国家或地区的BGP community
	            } 
                accept;             
            else reject; };
        import limit 9000 action block; 
    };
}

根据BGP community优选线路

我使用的是根据 BGP.community 更改 BGP.local_pref 来选择线路,因为 BGP.local_pref 会在AS内部传递,所以需要同时更改 eBGPiBGP

bird会优先选择 BGP.local_pref 最大的线路。

我的优选方案如下:

  • BGP.local_pref 的基础值为 100
  • 同区域(同大洲代码)的 +10
  • 同国家或地区的 +5
  • 有直接peer的(邻居) +20
    (判断bgp_path.len为1)

我不怎么想让流量走iBGP,所以iBGP部分没有优选,就在iBGP的import中把BGP.local_pref重置为默认值了(默认值为100)

配置示例

按上一个示例配置扩展

# head
define DN42_REGION  = 52;             # 改成机器所在大洲代码 参见 DN42 Wiki BGP Communities 的 Origin Region 一节
define DN42_COUNTRY = 1344;           # 改成机器所在国家或地区的代码 1000 + ISO 数字三位国家或地区的代码,840 是美国

#定义计算函数 ebgp_calculate_priority()
function ebgp_calculate_priority() {
    int priority = 100;  # 基础优先级
    
    # 同区域检测(+10)
    if bgp_community ~ [(64511, DN42_REGION)] then 
        priority = priority + 10;
    
    # 同国家检测(+5)
    if bgp_community ~ [(64511, DN42_COUNTRY)] then 
        priority = priority + 5;
    
    # eBGP直接邻居检测(+20)
    if bgp_path.len = 1 then 
        priority = priority + 20;
    
    return priority;
}

#修改eBGP
template bgp dnpeers {
    local as OWNAS;
    path metric 1;

    ipv4 {
        import filter {
          if is_valid_network() && !is_self_net() then {
            if (roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID) then {
              # Reject when unknown or invalid according to ROA
              print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;
              reject;
            } else {
              bgp_local_pref = ebgp_calculate_priority(); #调用函数计算BGP.local_pref
              accept
            };
          } else reject;
        };

        export filter { if is_valid_network() && source ~ [RTS_STATIC, RTS_BGP] then 
                if (is_self_net()) then {
		            bgp_community.add((64511, DN42_REGION));    #往属于自己的路由打上节点所属区域的BGP community
                    bgp_community.add((64511, DN42_COUNTRY));   #往属于自己的路由打上节点所属国家或地区的BGP community
	            }
                accept;
            else reject; };
        import limit 9000 action block;
    };

    ipv6 {   
        import filter {
          if is_valid_network_v6() && !is_self_net_v6() then {
            if (roa_check(dn42_roa_v6, net, bgp_path.last) != ROA_VALID) then {
              # Reject when unknown or invalid according to ROA
              print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;
              reject;
            } else {
                bgp_local_pref = ebgp_calculate_priority(); #调用函数计算BGP.local_pref
                accept;
            };
          } else reject;
        };
        export filter { if is_valid_network_v6() && source ~ [RTS_STATIC, RTS_BGP] then
                if (is_self_net_v6()) then {
		            bgp_community.add((64511, DN42_REGION));    #往属于自己的路由打上节点所属区域的BGP community
                    bgp_community.add((64511, DN42_COUNTRY));   #往属于自己的路由打上节点所属国家或地区的BGP community
	            } 
                accept;             
            else reject; };
        import limit 9000 action block; 
    };
}

#别忘了改iBGP
template bgp ibgpeers {
    local as OWNAS;
    
    ipv4 {
        import filter {
            if source = RTS_BGP && is_valid_network() && !is_self_net() then {
                bgp_local_pref = 100; #重置BGP.local_pref为100
                accept;
            } else reject;
        };
        
        export filter {
            if source = RTS_BGP && is_valid_network() && !is_self_net() then {
                accept;
            } else reject;
        };
        
        next hop self;
    };
    
    ipv6 {
        import filter {
            if source = RTS_BGP && is_valid_network_v6() && !is_self_net_v6() then {
                bgp_local_pref = 100; #重置BGP.local_pref为100
                accept;
            } else reject;
        };
        
        export filter {
            if source = RTS_BGP && is_valid_network_v6() && !is_self_net_v6() then {
                accept;
            } else reject;
        };
        
        next hop self;
    }; 
}

对路由添加 BGP large community

看你自己的定义了,用到 bgp_large_community.add(); 往路由打上BGP large community。
可以是所有经过你AS的路由,也可以仅是属于自己的路由。

我的 large community 定义:Xeiu Network (DN42) Routing

配置示例

看看就得了,不要真全部抄啊
按上一个配置示例进行扩展
基于Xeiu Network的BGP large community定义所写
对全部路由添加 BGP large community

# head
define NODE_ID   = 4;                 # 改成节点ID AS内惟一
define OWNAS  = 4242421336;           # 改成自己的 AS 号
define DN42_REGION  = 52;             # 改成机器所在大洲代码 参见 DN42 Wiki BGP Communities 的 Origin Region 一节
define DN42_COUNTRY = 1344;           # 改成机器所在国家或地区的代码 1000 + ISO 数字三位国家或地区的代码,840 是美国


define LC_ORIGIN_NODE     = (OWNAS, 110, NODE_ID); 

define LC_LEARNT_NODE     = (OWNAS, 100, NODE_ID);
define LC_LEARNT_COST     = (OWNAS, 200, 0);

#定义计算函数 ebgp_calculate_priority()
function ebgp_calculate_priority() {
    int priority = 100;  # 基础优先级
    
    # 同区域检测(+10)
    if bgp_community ~ [(64511, DN42_REGION)] then 
        priority = priority + 10;
    
    # 同国家检测(+5)
    if bgp_community ~ [(64511, DN42_COUNTRY)] then 
        priority = priority + 5;
    
    # eBGP直接邻居检测(+20)
    if bgp_path.len = 1 then 
        priority = priority + 20;
    
    return priority;
}

#定义函数 increment_community_third()(力大砖飞)
#小朋友不要学我这样写哦(划去)
function increment_community_third() {
	if (bgp_large_community ~ [(OWNAS, 200, *)]) then {
		if (bgp_large_community ~ [(OWNAS, 200, 14)]) then {
			bgp_large_community.delete([(OWNAS, 200, 14)]);
			bgp_large_community.add((OWNAS, 200, 15));
		}
		if (bgp_large_community ~ [(OWNAS, 200, 13)]) then {
			bgp_large_community.delete([(OWNAS, 200, 13)]);
			bgp_large_community.add((OWNAS, 200, 14));
		}
		if (bgp_large_community ~ [(OWNAS, 200, 12)]) then {
			bgp_large_community.delete([(OWNAS, 200, 12)]);
			bgp_large_community.add((OWNAS, 200, 13));
		}
		 if (bgp_large_community ~ [(OWNAS, 200, 11)]) then {
			bgp_large_community.delete([(OWNAS, 200, 11)]);
			bgp_large_community.add((OWNAS, 200, 12));
		}
		if (bgp_large_community ~ [(OWNAS, 200, 10)]) then {
			bgp_large_community.delete([(OWNAS, 200, 10)]);
			bgp_large_community.add((OWNAS, 200, 11));
		}
		if (bgp_large_community ~ [(OWNAS, 200, 9)]) then {
			bgp_large_community.delete([(OWNAS, 200, 9)]);
			bgp_large_community.add((OWNAS, 200, 10));
		}
		if (bgp_large_community ~ [(OWNAS, 200, 8)]) then {
			bgp_large_community.delete([(OWNAS, 200, 8)]);
			bgp_large_community.add((OWNAS, 200, 9));
		}
		if (bgp_large_community ~ [(OWNAS, 200, 7)]) then {
			bgp_large_community.delete([(OWNAS, 200, 7)]);
			bgp_large_community.add((OWNAS, 200, 8));
		}
		if (bgp_large_community ~ [(OWNAS, 200, 6)]) then {
			bgp_large_community.delete([(OWNAS, 200, 6)]);
			bgp_large_community.add((OWNAS, 200, 7));
		}
		if (bgp_large_community ~ [(OWNAS, 200, 5)]) then {
			bgp_large_community.delete([(OWNAS, 200, 5)]);
			bgp_large_community.add((OWNAS, 200, 6));
		}
		if (bgp_large_community ~ [(OWNAS, 200, 4)]) then {
			bgp_large_community.delete([(OWNAS, 200, 4)]);
			bgp_large_community.add((OWNAS, 200, 5));
		}
		if (bgp_large_community ~ [(OWNAS, 200, 3)]) then {
			bgp_large_community.delete([(OWNAS, 200, 3)]);
			bgp_large_community.add((OWNAS, 200, 4));
		}
		if (bgp_large_community ~ [(OWNAS, 200, 2)]) then {
			bgp_large_community.delete([(OWNAS, 200, 2)]);
			bgp_large_community.add((OWNAS, 200, 3));
		}
		if (bgp_large_community ~ [(OWNAS, 200, 1)]) then {
			bgp_large_community.delete([(OWNAS, 200, 1)]);
			bgp_large_community.add((OWNAS, 200, 2));
		}
		if (bgp_large_community ~ [(OWNAS, 200, 0)]) then {
			bgp_large_community.delete([(OWNAS, 200, 0)]);
			bgp_large_community.add((OWNAS, 200,1));
		}
	}
}


#修改eBGP
template bgp dnpeers {
    local as OWNAS;
    path metric 1;

    ipv4 {
        import filter {
          if is_valid_network() && !is_self_net() then {
            if (roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID) then {
              # Reject when unknown or invalid according to ROA
              print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;
              reject;
            } else {
                bgp_large_community.add(LC_LEARNT_COST);  #打上bgp_large_community
	            bgp_large_community.add(LC_LEARNT_NODE);  #打上bgp_large_community
                bgp_local_pref = ebgp_calculate_priority(); #调用函数计算BGP.local_pref
              accept
            };
          } else reject;
        };

        export filter { if is_valid_network() && source ~ [RTS_STATIC, RTS_BGP] then 
                if (is_self_net()) then {
		            bgp_community.add((64511, DN42_REGION));    #往属于自己的路由打上节点所属区域的BGP community
                    bgp_community.add((64511, DN42_COUNTRY));   #往属于自己的路由打上节点所属国家或地区的BGP community
                    bgp_large_community.add(LC_LEARNT_COST);  #打上bgp_large_community
	                bgp_large_community.add(LC_LEARNT_NODE);  #打上bgp_large_community
	            } 
                bgp_large_community.add(LC_ORIGIN_NODE);    #打上bgp_large_community
                accept;
            else reject; };
        import limit 9000 action block;
    };

    ipv6 {   
        import filter {
          if is_valid_network_v6() && !is_self_net_v6() then {
            if (roa_check(dn42_roa_v6, net, bgp_path.last) != ROA_VALID) then {
              # Reject when unknown or invalid according to ROA
              print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;
              reject;
            } else {
                bgp_large_community.add(LC_LEARNT_COST);  #打上bgp_large_community
	            bgp_large_community.add(LC_LEARNT_NODE);  #打上bgp_large_community
                bgp_local_pref = ebgp_calculate_priority(); #调用函数计算BGP.local_pref
                accept;
            };
          } else reject;
        };
        export filter { if is_valid_network_v6() && source ~ [RTS_STATIC, RTS_BGP] then
                if (is_self_net_v6()) then {
		            bgp_community.add((64511, DN42_REGION));    #往属于自己的路由打上节点所属区域的BGP community
                    bgp_community.add((64511, DN42_COUNTRY));   #往属于自己的路由打上节点所属国家或地区的BGP community
                    bgp_large_community.add(LC_LEARNT_COST);  #打上bgp_large_community
	                bgp_large_community.add(LC_LEARNT_NODE);  #打上bgp_large_community
	            } 
                bgp_large_community.add(LC_ORIGIN_NODE);    #打上bgp_large_community
                accept;             
            else reject; };
        import limit 9000 action block; 
    };
}

#别忘了改iBGP
template bgp ibgpeers {
    local as OWNAS;
    
    ipv4 {
        import filter {
            if source = RTS_BGP && is_valid_network() && !is_self_net() then {
                if (bgp_large_community ~ [(OWNAS, 200, *)]) then {
	                increment_community_third(); #调用力大砖飞的函数
	            }
                bgp_local_pref = 100; #重置BGP.local_pref为100
                accept;
            } else reject;
        };
        
        export filter {
            if source = RTS_BGP && is_valid_network() && !is_self_net() then {
                accept;
            } else reject;
        };
        
        next hop self;
    };
    
    ipv6 {
        import filter {
            if source = RTS_BGP && is_valid_network_v6() && !is_self_net_v6() then {
                if (bgp_large_community ~ [(OWNAS, 200, *)]) then {
	                increment_community_third(); #调用力大砖飞的函数
	            }
                bgp_local_pref = 100; #重置BGP.local_pref为100
                accept;
            } else reject;
        };
        
        export filter {
            if source = RTS_BGP && is_valid_network_v6() && !is_self_net_v6() then {
                accept;
            } else reject;
        };
        
        next hop self;
    }; 
}

关于BGP large community的作用?
我不知道,我也没写依据 BGP large community 的过滤以及优选规则,但是还是加上吧,万一以后有用呢?

特别鸣谢

感谢 DN42 Group Chat (unofficial) | XJBCast 群内的各位大佬的指导。


(顺带提一嘴,如果你想与我peer,请点击 这里 阅读我的DN42信息。)

评论

  1. CharlieMoomoo
    Android Firefox
    台湾省 威达电讯(VeeTime)
    2 月前
    2025-8-05 19:12:49

    我是小白

    • Avatar photo
      博主
      CharlieMoomoo
      Android Chrome
      日本东京都 OCTOPUS WEB SOLUTION INC
      2 月前
      2025-8-05 19:16:22

      好的大佬

  2. owo
    Android Chrome
    英国
    2 月前
    2025-8-05 19:21:54

    我是大白,我要照抄

  3. iPhone Chrome
    日本 东京市KDDI通信公司
    2 月前
    2025-8-05 19:28:44

    加油

    • Avatar photo
      博主
      iEdon
      Windows Edge
      广东省惠州市 移动
      2 月前
      2025-8-05 19:48:33

      谢谢大佬

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!

提交评论即代表您已阅读并同意隐私条款

上一篇
下一篇