限速模块相关函数
注意:
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;
}
}
}