日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

接口狀態與策略路由表

作者:redwingz 更新時間: 2022-08-15 編程語言

添加如下的路由策略:

# ip rule add from 10.0.1.3 oif ens33 lookup 10
# 
# ip rule
0:      from all lookup local
32760:  from 10.0.1.3 lookup 10
32766:  from all lookup main
32767:  from all lookup default

在策略路由表10中,添加默認網關192.168.0.40。查看可見出接口為ens33。

# ip route add default via 192.168.0.40 table 10
# 
# 
# ip route show table 10
default via 192.168.0.40 dev ens33 

如下刪除接口ens33接口上的IP地址,路由規則還在,但是路由表10中的ens33相關表項已經被清除,導致策略路由失效。

# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.4  netmask 255.255.255.0  broadcast 192.168.0.255

# 
# ip addr del 192.168.0.4/24 dev ens33
#
# ip rule
0:      from all lookup local
32760:  from 10.0.1.3 lookup 10
32766:  from all lookup main
32767:  from all lookup default
#
# ip route show table 10  
#

或者將出接口ens33設置為down狀態,也將清除路由表10中的路由表項。這導致在接口UP/DOWN,或者修改接口地址時,要重新下發策略路由表中的表項。

# ip link set ens33 down

路由項刪除

如下在地址刪除處理中,向inetaddr_chain鏈發送NETDEV_DOWN消息。

static void __inet_del_ifa(struct in_device *in_dev,
               struct in_ifaddr __rcu **ifap,
               int destroy, struct nlmsghdr *nlh, u32 portid)
{

    rtmsg_ifa(RTM_DELADDR, ifa1, nlh, portid);
    blocking_notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1);

路由子系統在inetaddr_chain上注冊了處理函數fib_inetaddr_event,由函數fib_del_ifaddr處理IP地址刪除事件。如果此接口上沒有IP地址,由函數fib_disable_ip處理。

static int fib_inetaddr_event(struct notifier_block *this, unsigned long event, void *ptr)
{
    struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;

    switch (event) {
    case NETDEV_DOWN:
        fib_del_ifaddr(ifa, NULL);
        atomic_inc(&net->ipv4.dev_addr_genid);
        if (!ifa->ifa_dev->ifa_list) {
            /* Last address was deleted from this interface.
             * Disable IP.
             */
            fib_disable_ip(dev, event, true);
        }

如下fib_disable_ip函數,處理路由表項及緩存的刪除。

static void fib_disable_ip(struct net_device *dev, unsigned long event,
               bool force)
{
    if (fib_sync_down_dev(dev, event, force))
        fib_flush(dev_net(dev));
    else
        rt_cache_flush(dev_net(dev));
    arp_ifdown(dev);

遍歷接口設備相關聯的路由表項,將下一跳設置為RTNH_F_DEAD。

int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force)
{    
    int scope = RT_SCOPE_NOWHERE;
    unsigned int hash = fib_devindex_hashfn(dev->ifindex);
    struct hlist_head *head = &fib_info_devhash[hash];

    hlist_for_each_entry(nh, head, nh_hash) {
        struct fib_info *fi = nh->nh_parent;

        if (nh->fib_nh_dev != dev || fi == prev_fi)
            continue;
        change_nexthops(fi) {
            if (nexthop_nh->fib_nh_flags & RTNH_F_DEAD)
                dead++;
            else if (nexthop_nh->fib_nh_dev == dev &&
                 nexthop_nh->fib_nh_scope != scope) {
                switch (event) {
                case NETDEV_DOWN:
                case NETDEV_UNREGISTER:
                    nexthop_nh->fib_nh_flags |= RTNH_F_DEAD;

最后,fib_flush遍歷命名空間中所有的路由表,已經每個表中的路由項,刪除設置了RTNH_F_DEAD標志的表項。

void fib_flush(struct net *net)
{
    for (h = 0; h < FIB_TABLE_HASHSZ; h++) {
        struct hlist_head *head = &net->ipv4.fib_table_hash[h];
        struct hlist_node *tmp;
        struct fib_table *tb;

        hlist_for_each_entry_safe(tb, tmp, head, tb_hlist)
            flushed += fib_table_flush(net, tb, false);
    }

    if (flushed)
        rt_cache_flush(net);

內核版本 5.10

原文鏈接:https://blog.csdn.net/sinat_20184565/article/details/126325194

欄目分類
最近更新