注意:
本人是BGP小白,本文章写的十分不严谨,缝合自多位大佬的著作,可能有任何的 错误 / 笔误 / 小白式理解 。请诸位大佬们手下留情。
本文蓝色字体可以点击跳转到对应的网页
如果您能接受的话,可以继续看下去,如果不能接受,建议现在就关闭此文章
前言
本文方案使用的是根据 BGP.community
更改 BGP.local_pref
来选择线路,因为 BGP.local_pref
会在AS内部传递,所以需要同时更改 eBGP
和 iBGP
。
本文的 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内部传递,所以需要同时更改 eBGP
和 iBGP
。
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信息。)
我是小白
好的大佬
我是大白,我要照抄
加油
谢谢大佬