iptables和tc的使用及开发实例总结

AP处理专线CPE的实例及实现的逻辑算法:

1、CPE桥接关联AP,它们在同一个桥上面;

2、初始化tc规则:

int tc_rule_init( void )
{
char filename[256] = {0};
char ifname[32] = {0};
char enable[10] = {0};
char uplink[10] = {0};
char downlink[10] = {0};
FILE *fp = NULL;


char *ifname_up = "eth0";


strcpy(filename, "/var/etc/wlan_tc_init.sh");
fp = fopen(filename, "w");
if (fp == NULL) 
{
log(LG_ERR, "can't create file \"%s\"", filename);
return -1;
}
fchmod(fileno(fp), 0755);
fprintf(fp, "#!/bin/sh\n");


nvramGetValue("wlan0/enable", enable, sizeof(enable));
//for downlink
if (atoi(enable) == 1)
{
strcpy(ifname, "wlan0");
nvramGetValue("wlan0/downlink_bandwidth", downlink, sizeof(downlink));
if (strlen(downlink) == 0)
strcpy(downlink, "500000");
fprintf(fp, "tc qdisc add dev %s root handle 1: htb default 100\n", ifname);
fprintf(fp, "tc class add dev %s parent 1: classid 1:1 htb rate %skbit ceil %skbit prio 1\n", ifname, downlink, downlink);


//default class
fprintf(fp, "tc class add dev %s parent 1:1 classid 1:100 htb rate 100kbit ceil %skbit prio 1\n", ifname, downlink);
}
nvramGetValue("ath0/enable", enable, sizeof(enable));
if (atoi(enable) == 1)
{
strcpy(ifname, "ath0");
memset(downlink, 0, sizeof(downlink));
nvramGetValue("ath0/downlink_bandwidth", downlink, sizeof(downlink));
if (strlen(downlink) == 0)
strcpy(downlink, "500000");
fprintf(fp, "tc qdisc add dev %s root handle 1: htb default 100\n", ifname);
fprintf(fp, "tc class add dev %s parent 1: classid 1:1 htb rate %skbit ceil %skbit prio 1\n", ifname, downlink, downlink);
fprintf(fp, "tc qdisc add dev %s parent 1:1 handle 11: sfq perturb 10\n", ifname);


//default class
fprintf(fp, "tc class add dev %s parent 1:1 classid 1:100 htb rate 100kbit ceil %skbit prio 1\n", ifname, downlink);
}
//for uplink
nvramGetValue("wlan0/uplink_bandwidth", uplink, sizeof(uplink));//for 2.4G classid 1:11
if (strlen(uplink) == 0)
strcpy(uplink, "500000");
fprintf(fp, "tc qdisc add dev %s root handle 1: htb default 100\n", ifname_up);
fprintf(fp, "tc class add dev %s parent 1: classid 1:1 htb rate 10000kbit ceil 10000kbit prio 1\n", ifname_up);


fprintf(fp, "tc class add dev %s parent 1:1 classid 1:11 htb rate %skbit ceil %skbit prio 1\n", ifname_up, uplink, uplink);




//default class
fprintf(fp, "tc class add dev %s parent 1:1 classid 1:100 htb rate 100kbit ceil %skbit prio 1\n", ifname_up, uplink);


memset(uplink, 0, sizeof(uplink));
nvramGetValue("ath0/uplink_bandwidth", uplink, sizeof(uplink));//for 5.8G classid 1:12
if (strlen(uplink) == 0)
strcpy(uplink, "500000");
fprintf(fp, "tc class add dev %s parent 1:1 classid 1:12 htb rate %skbit ceil %skbit prio 1\n", ifname_up, uplink, uplink);
//fprintf(fp, "tc qdisc add dev %s parent 1:12 handle 112: sfq perturb 10\n", ifname_up);


fclose(fp);

eval(filename);


return 1;
}

前两步实现基本流量控制操作,针对普通CPE的流量做的限制,对于专线CPE的流量配置,如下:

3、web端设置指定的CPE后,通过netlink发送mac到无线驱动端,无线驱动再netlink发送消息到上面处理流量控制的应用程序;


4、从无线接口端获取所有关联的cpe的mac地址;

typedef struct sta_buf
{
unsigned char sta_mac[32];
char ifname[32];
unsigned int max_uplink;
unsigned int min_uplink;
unsigned int max_downlink;
unsigned int min_downlink;
int parent_tag;
int tag;
int prio;
int online;
}*_p_sta_buf;将该Mac地址在存储于sta_buf结构体中的mac做查找;

若能找到,则设置这些mac地址的状态为在线;

若不能找到,则做如下处理;

判断是否在专线cpe列表中,如果在,则在 sta_buf结构体中标记为专线CPE,如果不在,则加入到sta_buf中;

设置mac为上线,并添加tc规则做流量控制;

5、当netlink将mac地址发送过来时,就会对mac的类型做判断,是上线,还是离线,还是加入网络,还是离开网络,并做好标记;然后对Mac添加tc规则做流量控制;


逻辑+标记

你可能感兴趣的:(router通信产品)