IPv4路由下一跳合法性检测
函数fib_check_nh检测下一跳的合法性。
int fib_check_nh(struct net *net, struct fib_nh *nh, u32 table, u8 scope, struct netlink_ext_ack *extack)
{int err;if (nh->fib_nh_gw_family == AF_INET)err = fib_check_nh_v4_gw(net, nh, table, scope, extack);else if (nh->fib_nh_gw_family == AF_INET6)err = fib_check_nh_v6_gw(net, nh, table, extack);elseerr = fib_check_nh_nongw(net, nh, extack);
IPv4下一跳检查
内核代码中注释内容显示了下一跳网关检查的4种情况:
* a) gateway can be actually local interface address, so that gatewayed route is direct.网关可以是本地接口上的地址,所以目的网络是直连的。
* b) gateway must be on-link address, possibly described not by an ifaddr, but also by a direct route.网关必须是链路可达地址,可以不是和接口地址同网段,或是直连路由可达。
* c) If both gateway and interface are specified, they should not contradict.如果同时指定了网关和出接口,两者不能冲突。
* d) If we use tunnel routes, gateway could be not on-link.如果使用隧道路由,网关可以不是链路可达地址(需指定onlink命令字)。
如下路由配置:
# /a/
# ip address
4: ens35: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether 00:0c:29:ea:2e:3b brd ff:ff:ff:ff:ff:ffinet 192.168.10.2/32 scope global ens35valid_lft forever preferred_lft forever
#
# ip route add 192.168.10.0/24 via 192.168.10.2
# ip route add 192.168.5.0/24 via 192.168.10.2
#
# ip route list
192.168.5.0/24 via 192.168.10.2 dev ens35
192.168.10.0/24 via 192.168.10.2 dev ens35
#
# /c/
# ip route add 192.168.7.0/24 via 192.168.10.2 dev ens35
#
# /d/
# ip route add 10.10.1.0/24 via 192.168.10.1 dev ens35 onlink
先看一下onlink路由的配置,由于指定了错误scope值,IP命令配置路由时返回以下错误:
# ip route add 10.10.1.0/24 via 192.168.10.1 scope 255 onlink
Error: Invalid scope.
#
# ip route add 10.10.1.0/24 via 192.168.10.1 scope host onlink
Error: Route with host scope can not have a gateway.
如下在fib_create_info中的代码,如果scope值大于RT_SCOPE_HOST(254),就认为是不合法的scope值,即到达目的网络最近的就是RT_SCOPE_HOST。另外,如果scope值等于RT_SCOPE_HOST,不能指定路由网关。
struct fib_info *fib_create_info(struct fib_config *cfg, struct netlink_ext_ack *extack)
{if (cfg->fc_scope > RT_SCOPE_HOST) { /* RT_SCOPE_HOST */NL_SET_ERR_MSG(extack, "Invalid scope");goto err_inval;}if (fi->nh) {...} else if (cfg->fc_scope == RT_SCOPE_HOST) {struct fib_nh *nh = fi->fib_nh;/* Local address is added. */if (nhs != 1) {NL_SET_ERR_MSG(extack, "Route with host scope can not have multiple nexthops");goto err_inval;}if (nh->fib_nh_gw_family) {NL_SET_ERR_MSG(extack, "Route with host scope can not have a gateway");goto err_inval;}
以下IP命令将触发内核函数fib_check_nh_v4_gw中的错误检查,对于当前链路路由(RTNH_F_ONLINK),如下所示:
# ip addr add 192.168.10.2/32 dev ens35
#
# ip route add 10.10.1.0/24 via 192.168.10.1 scope 253 onlink
Error: Nexthop has invalid scope.
#
# ip route add 10.10.1.0/24 via 192.168.10.1 onlink
Error: Nexthop device required for onlink.
#
# ip route add 10.10.1.0/24 via 192.168.10.1 dev ens35 onlink
Error: Nexthop device is not up.
#
# ip route add 10.10.1.0/24 via 192.168.10.1 dev ens35
Error: Nexthop has invalid gateway.
IP命令的onlink关键字对于与内核代码中的标志位RTNH_F_ONLINK,那么scope值不应大于等于RT_SCOPE_LINK。如果scope值等于RT_SCOPE_LINK,或者更大的值RT_SCOPE_HOST,就没有必要指定onlink命令字。
static int fib_check_nh_v4_gw(struct net *net, struct fib_nh *nh, u32 table, u8 scope, struct netlink_ext_ack *extack)
{if (nh->fib_nh_flags & RTNH_F_ONLINK) {unsigned int addr_type;if (scope >= RT_SCOPE_LINK) {NL_SET_ERR_MSG(extack, "Nexthop has invalid scope");return -EINVAL;}dev = __dev_get_by_index(net, nh->fib_nh_oif);if (!dev) {NL_SET_ERR_MSG(extack, "Nexthop device required for onlink");return -ENODEV;}if (!(dev->flags & IFF_UP)) {NL_SET_ERR_MSG(extack, "Nexthop device is not up");return -ENETDOWN;}addr_type = inet_addr_type_dev_table(net, dev, nh->fib_nh_gw4);if (addr_type != RTN_UNICAST) {NL_SET_ERR_MSG(extack, "Nexthop has invalid gateway");return -EINVAL;}if (!netif_carrier_ok(dev))nh->fib_nh_flags |= RTNH_F_LINKDOWN;nh->fib_nh_dev = dev;dev_hold(dev);nh->fib_nh_scope = RT_SCOPE_LINK;return 0;}
以下为没有指定onlink关键字的情况(通常情况不指定),需要验证网关的可达性。对于可达网关,其scope应当等于RT_SCOPE_LINK或者RT_SCOPE_HOST,以下路由查询获取到达网关的路由,将scope的最小值限定在RT_SCOPE_LINK值。
如果指定了路由表(非主路由表),在其中进行路由查询;否则,未指定路由表,或者以上查询失败的情况下,在主路由表和本地路由表中(RT_TABLE_MAIN/RT_TABLE_LOCAL)进行查询。
{struct fib_table *tbl = NULL;struct flowi4 fl4 = {.daddr = nh->fib_nh_gw4,.flowi4_scope = scope + 1,.flowi4_oif = nh->fib_nh_oif,.flowi4_iif = LOOPBACK_IFINDEX,};/* It is not necessary, but requires a bit of thinking */if (fl4.flowi4_scope < RT_SCOPE_LINK)fl4.flowi4_scope = RT_SCOPE_LINK;if (table && table != RT_TABLE_MAIN)tbl = fib_get_table(net, table);if (tbl)err = fib_table_lookup(tbl, &fl4, &res, FIB_LOOKUP_IGNORE_LINKSTATE | FIB_LOOKUP_NOREF);/* on error or if no table given do full lookup. This* is needed for example when nexthops are in the local* table rather than the given table*/if (!tbl || err) {err = fib_lookup(net, &fl4, &res, FIB_LOOKUP_IGNORE_LINKSTATE);}if (err) {NL_SET_ERR_MSG(extack, "Nexthop has invalid gateway");goto out;}}
合法的网关路由类型需要是单播类型(RTN_UNICAST)或者本地类型(RTN_LOCAL),否则为无效网关。如果路由查询结果的出接口为空,返回错误。最后,根据出口设备的链路状态设置下一跳结构的状态位。
err = -EINVAL;if (res.type != RTN_UNICAST && res.type != RTN_LOCAL) {NL_SET_ERR_MSG(extack, "Nexthop has invalid gateway");goto out;}nh->fib_nh_scope = res.scope;nh->fib_nh_oif = FIB_RES_OIF(res);nh->fib_nh_dev = dev = FIB_RES_DEV(res);if (!dev) {NL_SET_ERR_MSG(extack, "No egress device for nexthop gateway");goto out;}dev_hold(dev);if (!netif_carrier_ok(dev))nh->fib_nh_flags |= RTNH_F_LINKDOWN;err = (dev->flags & IFF_UP) ? 0 : -ENETDOWN;
另外,fl4结构成员flowi4_scope的值等于参数scope+1,例如scope值为RT_SCOPE_LINK,增加1之后变成RT_SCOPE_HOST。即对于RT_SCOPE_LINK类型的路由网关,要求查询到的到网关的路由的scope值小于大于等于RT_SCOPE_HOST。参见在路由查询函数fib_table_lookup中,对flowi4_scope的判断。
对于scope为RT_SCOPE_HOST的情况,不需要网关。对于scope为RT_SCOPE_NOWHERE(255)的情况,增加1之后为0,对于小于RT_SCOPE_LINK的scope,都按照RT_SCOPE_NOWHERE进行路由查询。
int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, struct fib_result *res, int fib_flags)
{/* Step 3: Process the leaf, if that fails fall back to backtracing */hlist_for_each_entry_rcu(fa, &n->leaf, fa_list) {struct fib_info *fi = fa->fa_info;if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos)continue;if (fi->fib_dead)continue;if (fa->fa_info->fib_scope < flp->flowi4_scope)continue;
未设置网关下一跳检查
以下IP命令配置无网关的路由项:
# ip route add 192.168.30.0/24 dev ens35 onlink
Error: Invalid flags for nexthop - PERVASIVE and ONLINK can not be set.
#
# ip route add 192.168.30.0/24 dev ens35
Error: Device for nexthop is not up.
对于未配置网关的路由,不能设置RTNH_F_PERVASIVE或者RTNH_F_ONLINK标志,前者用于递归查找网关,或者用于指定网关在本地链路上。未配置网关的路由项需要指定出口设备,如果出口设备没有启用,返回错误。
static int fib_check_nh_nongw(struct net *net, struct fib_nh *nh, struct netlink_ext_ack *extack)
{struct in_device *in_dev;int err;if (nh->fib_nh_flags & (RTNH_F_PERVASIVE | RTNH_F_ONLINK)) {NL_SET_ERR_MSG(extack, "Invalid flags for nexthop - PERVASIVE and ONLINK can not be set");return -EINVAL;}rcu_read_lock();err = -ENODEV;in_dev = inetdev_by_index(net, nh->fib_nh_oif);if (!in_dev)goto out;err = -ENETDOWN;if (!(in_dev->dev->flags & IFF_UP)) {NL_SET_ERR_MSG(extack, "Device for nexthop is not up");goto out;}nh->fib_nh_dev = in_dev->dev;dev_hold(nh->fib_nh_dev);nh->fib_nh_scope = RT_SCOPE_HOST;if (!netif_carrier_ok(nh->fib_nh_dev))nh->fib_nh_flags |= RTNH_F_LINKDOWN;
内核版本 5.10
IPv4路由下一跳合法性检测相关推荐
- 配置静态路由下一跳为本地出战接口和IP地址的区别
配置静态路由下一跳为本地出战接口和IP地址的区别 在配置静态路由时,下一跳可以使用下一路由器的IP地址,也可以使用本路由器的出站接口.在点对点的网络中,两者可能没有什么差别,但在以太网中或者NBMA网 ...
- 【数通网络交换基础梳理2】三层设备、网关、ARP表、VLAN、路由表及跨网段路由下一跳转发原理
一.不同网段如何通讯 同网段可以依靠二层交换机通讯,网络中存在多个网段192.168.1.1/24 172.16.1.1/24 173.73.1.1/24情况下如何互相通讯?上节留一下的问题,这节继续 ...
- h3c 虚拟服务器 下一跳,H3CNE 312题和313题 直连路由静态路由的下一跳问题
321.在MSR 路由器上看到路由表里有如下显示: Destination/Mask Proto Pre Cost NextHop Interface 127.0.0.0/8 Direct 0 0 1 ...
- BGP邻居特性及下一跳如何建立 学习笔记
两台路由器运行bgp建立任何邻居之前,会先交互tcp的三个报文 ,三次握手做完之后建成一个基于tcp的 信道,基于信道就开始邻居关系建立,只用交互一个open报文 .主要包括路由信的身份标识 ,rou ...
- IPv4路由cache统计信息
内核定义如下的每处理器结构rt_cache_stat记录路由缓存信息. struct rt_cache_stat {unsigned int in_slow_tot;unsigned int in_s ...
- CCNP精粹系列之三十二--BGP下一跳问题,推荐
Bgp的下一跳 R1:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:off ...
- 路由器下一跳地址怎么判断_CCNP-路由器工作原理
好物要写,我们的文章也不能断更,赚钱重要,学习新知识更重要,今天就是进入NP阶段的内容了,我们会深入理解每个动态路由协议的工作原理,以及一些策略方面的配置,至此你就能随心所欲控制路由的走向,让他走你所 ...
- 路由nexthop下一跳blackhole属性
以下添加blackhole属性的nexthop及相关路由. # ip -6 nexthop add id 1 blackhole # # ip nexthop id 1 blackhole # # i ...
- 配置静态路由使用出站接口和下一跳IP的差别
在配置静态路由时,下一跳可以使用下一路由器的IP地址,也可以使用本路由器的出站接口.在点对点的网络中,两者可能没有什么差别,但在以太网中,两者有很大差别. 在以太网中,两个相邻接口之间 ...
最新文章
- HTML5中常见的列表标签包括,介绍几个常用的HTML5标签
- WordPress电子商务博客源码
- 2019 年最好用的 7 款数据库监控工具
- Maven学习总结(39)——Maven私服的搭建及使用deploy命令部署构建问题汇总
- Photoshop和WPF双剑配合,打造炫酷个性的进度条控件
- HDX RealTime 避免回音
- 解决从PDF复制到Word中的英文字母变成宋体格式的问题
- html+css+js实现小游戏flybird(完整版)
- m个苹果放在n个盘子里面有多少种放法?(动态规划)
- matlab怎么画函数线,请问matlab怎么画常数函数,比如同时画x=300和x=400这两条线...
- Arthas线上问题定位神器
- 西瓜中视频是如何赚钱的?教你提高视频收益的3个方法!
- 获取android模拟器的IP地址
- 三位数求最大公因数c语言,求最大公因数的三种算法
- 开关柜绝缘状态检测与故障诊断
- Julia实现GCC-PHAT算法
- MAC盗版软件下载网站黑名单
- 拨乱反正!关于LoRaWAN的7个常见误解
- 免费算力平台——九天毕昇
- 服务器npc修改,梦幻古龙服务端NPC对话修改工具与教程
热门文章
- 松柏先生·每日一例:卖的不止是面包,而是一种生活方式
- css自适应屏幕教程,WordPress主题css适配屏幕尺寸大小自适应教程
- 前端实现纯css文本显示省略号
- 查看linux时间和时区,Linux查看时区和时间
- 剑灵力士卡刀ahk_用AutoHotkey帮朋友写一份卡刀软件,不清楚力士卡刀数据,帮个忙....
- 中兴PON设备通过MEF认证
- 【python日用】for表达式[列表推导式]
- 国内券商转型迎来新风口——港股市场的火热「微观篇」
- 新理念计算机英语,《新理念英语》English For You
- 互联网时代即时通讯软件的利与弊