enum ovs_action_attr { /* ... */ /* * after #ifndef __KERNEL__ ... #endif. * the equals is thus ABSOLUTELY NECESSARY */ OVS_ACTION_ATTR_RMDUPQUEUE = 23, /* struct ovs_action_rmdupqueue. */ __OVS_ACTION_ATTR_MAX, /* Nothing past this will be accepted * from userspace. */ /* ... */ }
/* * struct ovs_action_rmdupqueue - %OVS_ACTION_ATTR_RMDUPQUEUE action argument. * @queue_id: Algorithm used to choose queue number. * @max_len: basis used for setting queue[queue_id] size. */ struct ovs_action_rmdupqueue{ uint32_t queue_id; uint32_t max_len; };
int nsh_hdr_from_nlattr(const struct nlattr *attr, struct nshhdr *nh, size_t size); //-------------------queue start--------------------- #define MAX_QUEUE_SIZE 1000 //最多可以为1000个流提供服务 #define MAX_QUEUE_LEN 1000 //----改进:动态自适应算法,自动选择队列大小 或者 滑动窗口协议PRP typedef struct { int *queue; //队列指针(动态分配队列空间) int NUM; //队列大小 int TOP, REAR; //队首队尾标识 int EmpFlag; //队列判空标识 }Queue; void InitQueue(Queue* q, int n); //初始化队列 int EmptyOrFullQueue(Queue q); //队列判空以及判断满 int QueueLength(Queue q); //获取队列大小 int PushQueue(Queue* q,int ele); //入队操作 int PopQueue(Queue* q); //出队操作 int RePushQueue(Queue* q, int ele); //当一个数据第二次到达时对数据进行匹配出队操作 int FindElePos(Queue q, int ele,int* n); //查找元素位置 void ShowData(Queue q); //显示队列数据 extern Queue Que[]; //-----------------queue end---------------------------- #endif /* flow_netlink.h */
//-------------------queue start--------------------- void InitQueue(Queue* q,int n) { q->NUM = n; //空间回收 if (q->queue != NULL) { kfree(q->queue); //改进:设置一个新的action(---del-flows指令,不是action) 实现队列的释放,清除上一个action q->queue = NULL; } if (q->NUM != 0) { q->queue = (int *)kmalloc(sizeof(int)*n,GFP_KERNEL); memset(q->queue, 0, sizeof(int)*n); } q->TOP = q->REAR = 0; q->EmpFlag = 1; //空队列 } int EmptyOrFullQueue(Queue q) { return q.EmpFlag; } int QueueLength(Queue q) { if (EmptyOrFullQueue(q) == 1) return 0; if (EmptyOrFullQueue(q) == 2) return q.NUM; if (q.TOP > q.REAR) return q.REAR + q.NUM - q.TOP; else return q.REAR - q.TOP; } int PushQueue(Queue* q, int ele) { if (q->NUM <= 0) return 0; //队列空间已经释放 设置常量 if (RePushQueue(q, ele) == 1) //重复插入,冗余数据---重点 改进:定义网络新协议,替换ip标识 return 1; if (q->EmpFlag == 2) //队列满的情况入队 PopQueue(q); //先出队队首,再入队 q->queue[q->REAR] = ele; q->REAR = (q->REAR + 1) % q->NUM; if (q->TOP == q->REAR) q->EmpFlag = 2; //为满队列 else q->EmpFlag = 3; return 0; } int PopQueue(Queue* q) { if (q->NUM <= 0) return -2; //队列空间已经释放 改进:可以队列动态空间划分 int temp = q->queue[q->TOP]; if (q->EmpFlag == 1) //队列为空时,不允许出队 return -1; q->TOP++; if (q->TOP == q->NUM) q->TOP = 0; if (q->TOP == q->REAR) q->EmpFlag = 1; //为空队列 else q->EmpFlag = 3; return temp; } int RePushQueue(Queue* q, int ele) { int n; //用于记录元素个数 int pos = FindElePos(*q, ele, &n); if (pos == -1) return 0; //可以直接插入 q->TOP = pos; if (QueueLength(*q) == 0) q->EmpFlag = 1; else q->EmpFlag = 3; return 1; //队列有重复 } int FindElePos(Queue q, int ele,int* n) { int i; for (i = 0; i < QueueLength