~ubuntu-branches/ubuntu/lucid/vde2/lucid-proposed

« back to all changes in this revision

Viewing changes to src/vde_switch/packetq.c

  • Committer: Bazaar Package Importer
  • Author(s): Filippo Giunchedi
  • Date: 2008-06-17 15:36:32 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20080617153632-5318x7iv0zwmu3zu
Tags: 2.2.1-1
* New upstream release
  - fix vlan commands on amd64 (Closes: #484295)
  - fix mac addresses switch between ports (Closes: #469098)
* Suggest: qemu and kvm as requested in #461514
* Expand and spell-check README.Debian, add manual method example
  (Closes: #466363)
* Do not assume MAKEDEV presence in postinst
* Remove /usr/bin/daemon usage from ifupdown scripts (and Recommends)
* Add manpage for vde_tunctl
* Upgrade to S-V 3.8.0 (add Homepage field) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * packetq - packet queue management. try to send packets several times before discarding.
 
3
 * Copyright 2005 Renzo Davoli
 
4
 * Licensed under the GPLv2
 
5
 */
 
6
 
 
7
#include <stdlib.h>
 
8
#include <stdio.h>
 
9
#include <string.h>
 
10
#include <sys/time.h>
 
11
#include <time.h>
 
12
#include <sys/types.h>
 
13
#include <unistd.h>
 
14
#include <errno.h>
 
15
#include <syslog.h>
 
16
 
 
17
#include <config.h>
 
18
#include <vde.h>
 
19
#include <vdecommon.h>
 
20
 
 
21
#include "consmgmt.h"
 
22
 
 
23
#ifdef VDE_PQ
 
24
#include "packetq.h"
 
25
 
 
26
int packetq_timeout= -1;
 
27
static int countq;
 
28
#define TIMEOUT 5
 
29
#define TIMES 10
 
30
#define MAXQLEN 4192
 
31
 
 
32
struct packetqq {
 
33
        int (*sender)(int fd, int fd_ctl, void *packet, int len, void *data, int port);
 
34
        int fd; 
 
35
        int fd_ctl; 
 
36
        void *packet; 
 
37
        int len; 
 
38
        void *data; 
 
39
        int port;
 
40
        int times;
 
41
        struct packetqq *next;
 
42
};
 
43
 
 
44
static struct packetqq *pqh=NULL;
 
45
static struct packetqq *pqt=NULL;
 
46
static struct timeval last_try;
 
47
 
 
48
void packetq_add(int (*sender)(int fd, int fd_ctl, void *packet, int len, void *data, int port),
 
49
                int fd, int fd_ctl, void *packet, int len, void *data, int port)
 
50
{
 
51
        if (countq < MAXQLEN) {
 
52
                struct packetqq *new=malloc(sizeof(struct packetqq));
 
53
                void *packetcopy=malloc(len);
 
54
                if (new != NULL && packetcopy != NULL && len > 0) {
 
55
                        countq++;
 
56
                        new->sender=sender;
 
57
                        new->fd=fd;
 
58
                        new->fd_ctl=fd_ctl;
 
59
                        memcpy(packetcopy,packet,len);
 
60
                        new->packet=packetcopy;
 
61
                        new->len=len;
 
62
                        new->data=data;
 
63
                        new->port=port;
 
64
                        new->times=TIMES;
 
65
                        new->next=NULL;
 
66
                        if (pqh==NULL) {
 
67
                                gettimeofday(&last_try,NULL);
 
68
                                packetq_timeout=TIMEOUT;
 
69
                                pqh=pqt=new;
 
70
                        } else {
 
71
                                pqt->next=new;
 
72
                                pqt=new;
 
73
                        }
 
74
                } else {
 
75
                        if (new != NULL) free(new);
 
76
                        if (packetcopy != NULL) free(packetcopy);
 
77
                }
 
78
        }
 
79
}
 
80
 
 
81
static struct packetqq *packetq_scantry(struct packetqq *h,struct packetqq **t,fd_set *fds)
 
82
{
 
83
        if (h != NULL) {
 
84
                int sendrv=!(FD_ISSET(h->fd,fds));
 
85
                h->times--;
 
86
                if ((sendrv && (sendrv=h->sender(h->fd,h->fd_ctl,h->packet,h->len,h->data,h->port)) == 0)   /*send OK*/
 
87
                                || h->times<=0) { /*or max number of attempts reached*/
 
88
                        struct packetqq *next;
 
89
#if 0
 
90
                        /* this error code is unreachable! (sendrv==0 here) */
 
91
                        if (sendrv != 0) {
 
92
                                if (sendrv < 0) 
 
93
                                        printlog(LOG_WARNING,"packetqueue port %d: %s",h->port,strerror(-sendrv));
 
94
                                else
 
95
                                        printlog(LOG_WARNING,"packetqueue port %d: partial send (%d bytes lost)",h->port,sendrv);
 
96
                        }
 
97
#endif
 
98
                        next=h->next;
 
99
                        countq--;
 
100
                        free(h->packet);
 
101
                        free(h);
 
102
                        return packetq_scantry(next,t,fds);
 
103
                } else {
 
104
                        FD_SET(h->fd,fds);
 
105
                        h->next=packetq_scantry(h->next,t,fds);
 
106
                        if (h->next == NULL) *t=h;
 
107
                        return h;
 
108
                }
 
109
        } else
 
110
                return NULL;
 
111
}
 
112
 
 
113
void packetq_try(void)
 
114
{
 
115
        if (pqh != NULL) {
 
116
                struct timeval this_try;
 
117
                gettimeofday(&this_try,NULL);
 
118
                packetq_timeout=TIMEOUT - ((this_try.tv_sec-last_try.tv_sec) * 1000 + 
 
119
                                (this_try.tv_usec-last_try.tv_usec) / 1000);
 
120
                if (packetq_timeout <= 0) {
 
121
                        fd_set fds;
 
122
                        FD_ZERO(&fds);
 
123
                        pqh=packetq_scantry(pqh,&pqt,&fds);     
 
124
                        if (pqh != NULL) {
 
125
                                gettimeofday(&last_try,NULL);
 
126
                                packetq_timeout=TIMEOUT;
 
127
                        } else
 
128
                                packetq_timeout = -1;
 
129
                }
 
130
        }
 
131
}
 
132
 
 
133
static struct packetqq *packetq_scandelfd(int fd,struct packetqq *h,struct packetqq **t)
 
134
{
 
135
        if (h != NULL) {
 
136
                if (fd == h->fd) {
 
137
                        struct packetqq *next=h->next;
 
138
                        countq--;
 
139
                        free(h->packet);
 
140
                        free(h);
 
141
                        return packetq_scandelfd(fd,next,t);
 
142
                } else {
 
143
                        h->next=packetq_scandelfd(fd,h->next,t);
 
144
                        if (h->next == NULL) *t=h;
 
145
                        return h;
 
146
                }
 
147
        } else
 
148
                return NULL;
 
149
}
 
150
 
 
151
void packetq_delfd(int fd)
 
152
{
 
153
        pqh=packetq_scandelfd(fd,pqh,&pqt);
 
154
        if (pqh == NULL)
 
155
                packetq_timeout = -1;
 
156
}
 
157
 
 
158
int packetq_count()
 
159
{
 
160
        return countq;
 
161
}
 
162
#endif