BCM56445流量统计功能开发总结

来源:互联网 发布:雅思大作文 知乎 编辑:程序博客网 时间:2024/05/29 16:53

文章说明:文章部分内容引自网上资料

==========================================================

1.交换芯片的架构

       交换芯片由GE/XE接口(MAC/PHY)模块、CPU接口模块、输入输出匹配/修改模块、MMU模块、L2转发模块、L3转发模块、安全模块、流分类模块等模块组成,其结构如图1所示: 

                                                          

2.交换芯片的内部结构

以网上的BCM5690为例:

                                                                            

a.GPIC控制器负责GE接口和内部交换逻辑之间的连接;

b.IPIC控制器负责HIGI接口和内部交换逻辑之间的连接;

c.CMIC控制器负责交换芯片和外部CPU之间的连接;

d.ARL为地址解析单元,主要负责数据包的转发策略;

e.MMU为内存管理单元,主要负责数据的缓冲和调度;

f.CBP为缓冲单元,主要负责数据包的缓冲;


3.交换芯片内部数据包的流程:

                                                            

        a.包由端口进入交换芯片之后,首先进行包头字段匹配,为流分类做准备;

        b.然后经过一个安全引擎进行包过滤;符合安全的包进行L2交换或者L3路由,并经过流分类处理器对匹配的包做相关动作(比如丢弃、限速、修改VLAN等);

       c. 对于可以转发的包根据802.1P或DSCP放到不同队列的buffer中,调度器根据优先级或者WRR等算法进行队列调度,在端口发出该包之前执行流分类修改动作,最终从相应端口发送出去。

4.BCM56445与应用程序之间的数据通信方案

     在BCM提供的SDK编译可以生成一个bcm.user.proxy的代理应用程序,由于BCM的SDK对外没有提供API,因此对于其他应用程序需要使用进程间通信和bcm.user.proxy交互;

     根据BCM56445提供的编程说明,可以查找到eg: d EPC_BMAP_LINK(查看GE端口的link状态的命令)、getreg GTPKT(读取端口发送包数)、getreg GRPKT(读取端口接收的包数)、getreg GRBYT(读取端口接收的字节数)、getreg GTBYT(读取端口发送的字节数)等;

   上述的这些命令本质上就是执行bcm.user.proxy时输入的命令,在设计两个程序的通信时,使用套接字socket通信,将bcm.user.proxy作为后台server程序,监听双方约定的端口,应用程序作为客户端程序在建立的socket中以字符串的形式发送上述的这些命令;

5.设计实现细节

a.在bcm.user.proxy运行时需要加载BCM56445运行时需要的ko文件,以及将bcm.user.proxy后台运行,这些动作需要编写配置脚本实现;

b.客户端应用程序中创建用于和BCM56445通信的子线程,代码实现:

STATUS Polling_BCM56445_Status(){int i=0;int sock_fd;   int ret=0;  int cmd_len;static UINT32 cnt=0;char *buf=NULL;char *cmd_ring[20]={"d EPC_LINK_BMAP\r\n","getreg GRPKT\r\n","d EPC_LINK_BMAP\r\n","getreg GTPKT\r\n","d EPC_LINK_BMAP\r\n","getreg GRBYT\r\n","d EPC_LINK_BMAP\r\n","getreg GTBYT\r\n"};//char *cmd_ring[2]={"d EPC_LINK_BMAP\r\n"};pthread_detach(pthread_self());    struct sockaddr_in svr_addr;   svr_addr.sin_family = AF_INET;  svr_addr.sin_port = htons(BCM56445_SVR_PORT);svr_addr.sin_addr.s_addr = htonl(INADDR_ANY);  //svr_addr.sin_addr.s_addr = inet_addr(BCM56445_SVR_IP);  sock_fd = socket(AF_INET, SOCK_STREAM, 0); if(sock_fd < 0) {   TME_TRCMSG(1,"BCM56445 client created socket failed\r\n"); goto BCM56445_FAIL; }ret = connect(sock_fd, (const struct sockaddr *)&svr_addr, sizeof(struct sockaddr));    if(ret < 0)  {     TME_TRCMSG(1,"BCM56445 client connected failed\r\n"); goto BCM56445_FAIL;}buf = (char*)malloc(BCM56445_BUFFER_SIZE);  while(1){for(i=0;i<8;i++){    memset(buf,0,BCM56445_BUFFER_SIZE);ret=send(sock_fd,cmd_ring[i],strlen(cmd_ring[i])+1,0);if(ret<0){TME_TRCMSG(1,"BCM56445 client send failed\r\n"); goto BCM56445_FAIL;}usleep(50000);ret=recv(sock_fd,buf,BCM56445_BUFFER_SIZE,0);cnt++;if(cnt>20){if((strstr(buf,"BCM.0>")==NULL)||(strstr(buf,"ge0")==NULL)){if((strstr(buf,"EPC_LINK_BMAP")!=NULL)&&(strstr(buf,"PORT_BITMAP=")!=NULL)){Recv_Msg_Deal(buf);}}else{Recv_Msg_Deal(buf);}    }usleep(50000);}}return OK;BCM56445_FAIL:free(buf);buf=NULL;pthread_exit(NULL);return ERROR;}
c.客户端以Socket的形式发送字符串,bcm.user.proxy代理程序收到之后,发送字符串,以客户端发送d EPC_LINK_BMAP为例,服务器回复的字符串为: 

d.客户端线程收到这些字符串之后需要解析,对于计算流量bps、pps时需要对累计值做溢出处理和时间戳设置

5.程序健壮性设计

在多进程套接字通信时,如果服务器端挂掉,客户端也就挂掉,因此编写了bcm.user.proxy的守护脚本:

#!/bin/bashwhile truedo        prco_exist=` ps -ef|grep "bcm.user.proxy"|grep -v grep|wc -l`        if [ $proc_exist -eq 0]; then        cd /home/bcm-sdk        ./bcm.user.proxy -d 9000        sleep 2        fidone
每隔2秒查看bcm.user.proxy是否存在,如果不存在立即启动;


客户端的重连机制没想到好的方法,暂未实现;


0 0
原创粉丝点击