]> git.sur5r.net Git - ngadmin/blob - lib/src/vlan.c
9bd14c69a21449b5bba3e5aea1bca139164c6cc9
[ngadmin] / lib / src / vlan.c
1
2 #include <ngadmin.h>
3
4 #include <attr.h>
5 #include <protocol.h>
6
7 #include "lib.h"
8 #include "network.h"
9
10
11 int ngadmin_getVLANType (struct ngadmin *nga, int *t)
12 {
13         List *attr;
14         struct attr *at;
15         int ret = ERR_OK;
16         
17         
18         if (nga == NULL || t == NULL)
19                 return ERR_INVARG;
20         else if (nga->current == NULL)
21                 return ERR_NOTLOG;
22         
23         
24         attr = createEmptyList();
25         pushBackList(attr, newEmptyAttr(ATTR_VLAN_TYPE));
26         ret=readRequest(nga, attr);
27         if (ret != ERR_OK)
28                 goto end;
29         
30         filterAttributes(attr, ATTR_VLAN_TYPE, ATTR_END);
31         
32         *t = VLAN_DISABLED;
33         
34         if (attr->first != NULL) {
35                 at = attr->first->data;
36                 *t =(int)*(char*)at->data;
37         }
38         
39         
40 end:
41         destroyList(attr, (void(*)(void*))freeAttr);
42         
43         
44         return ret;
45 }
46
47
48 int ngadmin_setVLANType (struct ngadmin *nga, int t)
49 {
50         List *attr;
51         
52         
53         if (nga == NULL || t < 1 || t > 4)
54                 return ERR_INVARG;
55         else if (nga->current == NULL)
56                 return ERR_NOTLOG;
57         
58         
59         attr = createEmptyList();
60         pushBackList(attr, newByteAttr(ATTR_VLAN_TYPE, t));
61         
62         
63         return writeRequest(nga, attr);
64 }
65
66
67 int ngadmin_getVLANPortConf (struct ngadmin *nga, unsigned char *ports)
68 {
69         List *attr;
70         ListNode *ln;
71         struct attr *at;
72         int ret = ERR_OK;
73         struct attr_vlan_conf *avc;
74         struct swi_attr *sa;
75         int port;
76         
77         
78         if (nga == NULL || ports== NULL)
79                 return ERR_INVARG;
80         
81         sa = nga->current;
82         if (sa == NULL)
83                 return ERR_NOTLOG;
84         
85         
86         attr = createEmptyList();
87         pushBackList(attr, newEmptyAttr(ATTR_VLAN_PORT_CONF));
88         ret = readRequest(nga, attr);
89         if (ret != ERR_OK)
90                 goto end;
91         
92         filterAttributes(attr, ATTR_VLAN_PORT_CONF, ATTR_END);
93         
94         memset(ports, 0, sa->ports);
95         
96         for (ln = attr->first; ln != NULL; ln = ln->next) {
97                 at = ln->data;
98                 avc = at->data;
99
100                 if (at->size != sizeof(struct attr_vlan_conf) + sa->ports)
101                         return ERR_INVARG;
102                 
103                 for (port = 0; port < sa->ports; port++) {
104                         if (avc->ports[port] == VLAN_UNTAGGED)
105                                 ports[port] = avc->vlan;
106                 }
107         }
108         
109         
110 end:
111         destroyList(attr, (void(*)(void*))freeAttr);
112         
113         
114         return ret;
115 }
116
117
118 int ngadmin_setVLANPortConf (struct ngadmin *nga, const unsigned char *ports)
119 {
120         List *attr = NULL;
121         ListNode *ln;
122         struct attr *at;
123         struct swi_attr *sa;
124         struct attr_vlan_conf *avc;
125         int ret = ERR_OK, port;
126         unsigned char vlan;
127         
128         
129         if (nga == NULL || ports == NULL)
130                 return ERR_INVARG;
131         
132         sa = nga->current;
133         if (sa == NULL)
134                 return ERR_NOTLOG;
135         
136         /* if nothing is to be changed, do nothing */
137         for (port = 0; port < sa->ports && ports[port] == 0; port++);
138         if (port == sa->ports )
139                 goto end;
140         
141         attr = createEmptyList();
142
143         if (memchr(ports, 0, sa->ports) != NULL) {
144                 /* if at least one port is unchanged, we need to read old config */
145                 pushBackList(attr, newEmptyAttr(ATTR_VLAN_PORT_CONF));
146                 ret = readRequest(nga, attr);
147                 if (ret != ERR_OK)
148                         goto end;
149                 
150                 filterAttributes(attr, ATTR_VLAN_PORT_CONF, ATTR_END);
151                 /* FIXME: check if the returned array effectively contains correct data */
152         } else {
153                 /* create an empty VLAN config */
154                 for (vlan = VLAN_MIN; vlan <= VLAN_PORT_MAX; vlan++) {
155                         avc = malloc(sizeof(struct attr_vlan_conf) + sa->ports);
156                         avc->vlan = vlan;
157                         memset(avc->ports, 0, sa->ports);
158                         pushBackList(attr, newAttr(ATTR_VLAN_PORT_CONF, sizeof(struct attr_vlan_conf) + sa->ports, avc));
159                 }
160         }
161         
162         for (ln = attr->first; ln != NULL; ln = ln->next) {
163                 at = ln->data;
164                 avc = at->data;
165                 for (port = 0; port < sa->ports; port++) {
166                         if (ports[port] == avc->vlan)
167                                 avc->ports[port] = VLAN_UNTAGGED;
168                         else
169                                 avc->ports[port] = VLAN_NO;
170                 }
171         }
172         
173         ret = writeRequest(nga, attr);
174         attr = NULL;
175         
176         
177 end:
178         destroyList(attr, (void(*)(void*))freeAttr);
179         
180         
181         return ret;
182 }
183
184
185 int ngadmin_getVLANDotAllConf (struct ngadmin *nga, unsigned short *vlans, unsigned char *ports, int *nb)
186 {
187         List *attr;
188         ListNode *ln;
189         struct attr *at;
190         int ret = ERR_OK, total;
191         struct attr_vlan_conf *avc;
192         struct swi_attr *sa;
193         
194         
195         if (nga == NULL || vlans == NULL || ports== NULL || nb == NULL || *nb <= 0)
196                 return ERR_INVARG;
197         
198         sa = nga->current;
199         if (sa == NULL)
200                 return ERR_NOTLOG;
201         
202         
203         total = *nb;
204         *nb = 0;
205         
206         attr = createEmptyList();
207         pushBackList(attr, newEmptyAttr(ATTR_VLAN_DOT_CONF));
208         ret = readRequest(nga, attr);
209         if (ret != ERR_OK)
210                 goto end;
211         
212         filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END);
213         
214         memset(vlans, 0, total * sizeof(unsigned short));
215         memset(ports, 0, total * sa->ports);
216         
217         for (ln = attr->first; ln != NULL; ln = ln->next) {
218                 at = ln->data;
219                 avc = at->data;
220                 
221                 if (at->size != sizeof(struct attr_vlan_conf) + sa->ports)
222                         return ERR_INVARG;
223                 
224                 *vlans = avc->vlan;
225                 memcpy(ports, avc->ports, sa->ports);
226                 
227                 vlans++;
228                 ports += sa->ports;
229                 (*nb)++;
230                 
231                 if (*nb > total)
232                         break; /* no more room */
233         }
234         
235         
236 end:
237         destroyList(attr, (void(*)(void*))freeAttr);
238         
239         
240         return ret;
241 }
242
243
244 int ngadmin_getVLANDotConf (struct ngadmin *nga, unsigned short vlan, unsigned char *ports)
245 {
246         List *attr;
247         ListNode *ln;
248         struct attr *at;
249         int ret = ERR_OK;
250         struct attr_vlan_conf *avc;
251         
252         
253         if (nga == NULL || vlan < VLAN_MIN || vlan > VLAN_DOT_MAX || ports == NULL)
254                 return ERR_INVARG;
255         else if (nga->current == NULL)
256                 return ERR_NOTLOG;
257         
258         
259         attr = createEmptyList();
260         pushBackList(attr, newShortAttr(ATTR_VLAN_DOT_CONF, vlan));
261         ret = readRequest(nga, attr);
262         if (ret != ERR_OK)
263                 goto end;
264         
265         filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END);
266         
267         memset(ports, 0, nga->current->ports);
268         
269         for (ln = attr->first; ln != NULL; ln = ln->next) {
270                 at = ln->data;
271                 avc = at->data;
272                 if (avc->vlan == vlan) {
273                         memcpy(ports, avc->ports, nga->current->ports);
274                         break;
275                 }
276         }
277         
278         
279 end:
280         destroyList(attr, (void(*)(void*))freeAttr);
281         
282         
283         return ret;
284 }
285
286
287 int ngadmin_setVLANDotConf (struct ngadmin *nga, unsigned short vlan, const unsigned char *ports)
288 {
289         List *attr = NULL;
290         struct attr *at;
291         struct swi_attr *sa;
292         struct attr_vlan_conf *avc;
293         int ret = ERR_OK, port;
294         
295         
296         if (nga == NULL || vlan < VLAN_MIN || vlan > VLAN_DOT_MAX || ports == NULL)
297                 return ERR_INVARG;
298         
299         sa = nga->current;
300         if (sa == NULL)
301                 return ERR_NOTLOG;
302         
303         
304         /* if nothing is to be changed, do nothing */
305         for (port = 0; port < sa->ports && ports[port] == VLAN_UNSPEC; port++);
306         if (port == sa->ports )
307                 goto end;
308         
309         
310         attr = createEmptyList();
311         avc = malloc(sizeof(struct attr_vlan_conf) + sa->ports);
312         if (avc == NULL)
313                 return ERR_MEM;
314         
315         avc->vlan = vlan;
316         
317         /* if all is to be changed, we do not need to read old config */
318         if (memchr(ports, VLAN_UNSPEC, sa->ports) != NULL) {
319                 
320                 pushBackList(attr, newShortAttr(ATTR_VLAN_DOT_CONF, vlan));
321                 ret = readRequest(nga, attr);
322                 if (ret != ERR_OK)
323                         goto end;
324                 
325                 filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END);
326                 
327                 if (attr->first != NULL) {
328                         at = attr->first->data;
329                         memcpy(avc, at->data, sizeof(struct attr_vlan_conf) + sa->ports);
330                 }
331                 
332                 clearList(attr, (void(*)(void*))freeAttr);
333         }
334         
335         
336         /* apply changes */
337         for (port = 0; port < sa->ports; port++) {
338                 if (ports[port] != VLAN_UNSPEC)
339                         avc->ports[port] = ports[port];
340         }
341         
342         
343         pushBackList(attr, newAttr(ATTR_VLAN_DOT_CONF, sizeof(struct attr_vlan_conf) + sa->ports, avc));
344         ret = writeRequest(nga, attr);
345         attr = NULL;
346         
347         
348 end:
349         destroyList(attr, (void(*)(void*))freeAttr);
350         
351         
352         return ret;
353 }
354
355
356 int ngadmin_VLANDestroy (struct ngadmin *nga, unsigned short vlan)
357 {
358         List *attr;
359         
360         
361         if (nga == NULL || vlan < VLAN_MIN || vlan > VLAN_DOT_MAX)
362                 return ERR_INVARG;
363         else if (nga->current == NULL)
364                 return ERR_NOTLOG;
365         
366         
367         attr = createEmptyList();
368         pushBackList(attr, newShortAttr(ATTR_VLAN_DESTROY, vlan));
369         
370         
371         return writeRequest(nga, attr);
372 }
373
374
375 int ngadmin_getAllPVID (struct ngadmin *nga, unsigned short *ports)
376 {
377         List *attr;
378         ListNode *ln;
379         struct attr *at;
380         int ret = ERR_OK;
381         struct attr_pvid *ap;
382         
383         
384         if (nga == NULL || ports == NULL)
385                 return ERR_INVARG;
386         else if (nga->current == NULL)
387                 return ERR_NOTLOG;
388         
389         
390         attr = createEmptyList();
391         pushBackList(attr, newEmptyAttr(ATTR_VLAN_PVID));
392         ret = readRequest(nga, attr);
393         if (ret != ERR_OK)
394                 goto end;
395         
396         filterAttributes(attr, ATTR_VLAN_PVID, ATTR_END);
397         
398         memset(ports, 0, nga->current->ports * sizeof(unsigned short));
399         
400         for (ln = attr->first; ln != NULL; ln = ln->next) {
401                 at = ln->data;
402                 ap = at->data;
403                 ports[ap->port - 1] = ap->vlan;
404         }
405         
406         
407 end:
408         destroyList(attr, (void(*)(void*))freeAttr);
409         
410         
411         return ret;
412 }
413
414
415 int ngadmin_setPVID (struct ngadmin *nga, unsigned char port, unsigned short vlan)
416 {
417         List *attr;
418         struct attr_pvid *ap;
419         
420         
421         if (nga == NULL || port < 1 || vlan < VLAN_MIN || vlan > VLAN_DOT_MAX)
422                 return ERR_INVARG;
423         else if (nga->current == NULL)
424                 return ERR_NOTLOG;
425         else if (port > nga->current->ports)
426                 return ERR_INVARG;
427         
428         
429         attr = createEmptyList();
430         ap = malloc(sizeof(struct attr_pvid));
431         if (ap == NULL)
432                 return ERR_MEM;
433         ap->port = port;
434         ap->vlan = vlan;
435         
436         pushBackList(attr, newAttr(ATTR_VLAN_PVID, sizeof(struct attr_pvid), ap));
437         
438         
439         return writeRequest(nga, attr);
440 }
441
442