• 限速模块相关函数


    注意:

    1: userInfo表的isActive值并不是即时更新的而是在userInfo表满的情况下, 新进skb没有找到1==isActive且mac地址相同条目时才会去更新表的isActive值。

    一: int UserMgmt_init(void)

        调用: 系统初始化时调用。

        作用:

            (1) 分配8条BwLimitRule空间, 初始地址为bwLimitRule;

                     BwLimitRule bwLimitRule[USER_MGMT_MAX_BW_LIMIT_RULE];

            (2) 分配100条UserInfo的空间, 初始地址为userInfo;

                    UserInfo userInfo[USER_MGMT_MAX_USER_NUM];

            (3)限速模块户口函数hook地址赋值:

                    usermgmt_isallowforward_hook = userMgmt_isAllowForward;

            (4) setmark_hook地址赋值:

                    usermgmt_setmark_hook = userMgmt_setMark;

    二:  int userMgmt_enable( int isBandwidthLimitEnable);

        调用: board_ioctl在设置限速功能开启关闭时调用;

        作用:

            (1) 当限速功能开启时: usermgmt_isallowforward_hook = userMgmt_isAllowForward;

            (2) 当限速功能关闭时: usermgmt_isallowforward_hook = NULL;

    三: int userMgmt_isAllowForward(struct sk_buff *skb; int direction; unsigned long pktJiffies);

        参数说明: (1) skb;

                       (2) direction; 包方向, 1-uplink, 0-downlink;

                       (3) unsigned long pktJiffies; 包进来的时间, ptkJiffies.

        调用: 限速功能开启时, 在kernel, dev.c中调用。

        作用: 

    isFound = 0;

    firstUnusedEntry = -1;

    (1)

    for (遍历100条UserInfo entry)

    {

        if (1 ==userInfo[i].isActive)

        {                   

            if  (skbMac与userInfo[i].mac相同) 

            {                      

                isFound = 1;

                break;

                表明在当前活跃的userInfo entry中找到对应的entry.

            }

        } 

        else ( 即0 == userInfo[i].isActive)

        {             

            firstUnusedEntry = i;

          (此处可优化?break)

        }

    }

                        

    (2)

    if ( 0 == isFound, 表明没有找到1 == isActive且mac地址相同的条目)

    {

        if ( -1 == firstUnusedEntry) 表明(1)的遍历没有找到0 == isActive的条目

        {

            更新UserInfo表的状态将长时间不用entry(5S)的isActive置为0, 并且将更新表后

            第一条0==isActive的entry的下标值返回给firstUnusedentry, 如没有 0 == isActive

            的条目, 则返回-1。

            firstUnusedEntry = userMgmt_refreshUserStatus(); 

        }

        if ( -1 != firstUnusedEntry) 表明在userInfo表中, 在没有0 != isActive且mac地址相同的条目时, 找到了

                                                               0 == isActive的userInfo entry.

        {

              因为是新entry的的第一个包所以在更新userInfo[firstUnusedEntry]状态后转发skb, return 0;

              userInfoPtr = &userInfo[firstUnusedEntry];

              userInfoPtr->isActive = 1;

                             

              此处更新userInfo[firstUnusedEntry]的bwLimit, 只有此处更新, 不是实时更新。

               userMgmt_getBwLimitByIfName(&(userInfoPtr->upBwLimit),

                                                             &(userInfoPtr->downBwLimit),
                                                             skb->dev->name);

               userInfo[firstUnusedEntry]的条目更新结束, 下面是限速和流量统计。

                           

                当 0 == bwLimit时, 只统计流量, 而不进行限速。

                 if (bwLimit == 0)

                 {

                      (*totalBtis) += ((skb->len + SKB_LEN_DELTA))  ??

                 }

                 else

                 {              

                    userMgmt_preForwardhandler((direction?(&userInfoPtr->upLink):(&userInfoPtr->downLink)),

                                                                       (skb->len + SKB_LEN_DELTA),

                                                                       pktJiffies);                       

                  }

            return 0;

        }

        此处的else即为-1 == firstUnusedEntry, 即更新过用户表后仍然没有0 == isActive的条目, drop

        else     

        {

            return -1;

         }

    }

                    

    此处的else对应 1 == isFound, 流量统计和限速功能可参照上面

    else

    {

        获取用户条目, 流量统计, 限速的前期准备工作

        userInfoPtr = &userInfo[i];

        ...

        流量统计

        if ( 0 == bwLimit)

        {

            (*totalBits) += ((skb->len + SKB_LEN_DELTA)*8);

            return 0;

        }

        else

        {

            带宽计算

            if ( (usedMgmt_calUsedBw(pktListHead, pktJiffies) + (skb->len + SKB_LEN_DELTA)*8)))

            {

                forward, 更新条目

                userMgmt_preForwardhandler(pktListHead, (skb->len + SKB_LEN_DELTA), pktJiffies);

                (*totalBits) += ((skb->len + SKB_LEN_DELTA) * 8)

                return 0;

            }     

            else

            {    calUsedBw计算带宽超出, drop;

                return -1;

            }

        }

    }

            

  • 相关阅读:
    mybatis多参数传递(包括数组)
    mysql查询树状目录所有子节点
    Kettle ETL调用 java代码来进行数据库的增删改查
    java dom4j解析器使用
    Linux查看系统位数
    Linux查看系统是32位还是64位命令(getconf WORD_BIT和getconf LONG_BIT)
    Centos7下Redis缓存清理_FZlion
    springboot+vue项目实战(代码可运行)
    SpringBoot控制台打印SQL语句
    Error running ‘Application‘: Command line is too long
  • 原文地址:https://www.cnblogs.com/gavinwu/p/4021948.html
Copyright © 2020-2023  润新知