]> git.sur5r.net Git - ngadmin/blob - lib/src/vlan.c
Remove and ignore INSTALL
[ngadmin] / lib / src / vlan.c
1
2 #include <ngadmin.h>
3
4 #include <nsdp/attr.h>
5 #include <nsdp/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                 ret = ERR_BADREPLY;
36                 goto end;
37         }
38         at = attr->first->data;
39         if (at->size != 1) {
40                 ret = ERR_BADREPLY;
41                 goto end;
42         }
43         *t =(int)*(char*)at->data;
44         
45 end:
46         destroyList(attr, (void(*)(void*))freeAttr);
47         
48         
49         return ret;
50 }
51
52
53 int ngadmin_setVLANType (struct ngadmin *nga, int t)
54 {
55         List *attr;
56         
57         
58         if (nga == NULL || t < VLAN_DISABLED || t > VLAN_DOT_ADV)
59                 return ERR_INVARG;
60         else if (nga->current == NULL)
61                 return ERR_NOTLOG;
62         
63         
64         attr = createEmptyList();
65         pushBackList(attr, newByteAttr(ATTR_VLAN_TYPE, t));
66         
67         
68         return writeRequest(nga, attr);
69 }
70
71
72 int ngadmin_getVLANPortConf (struct ngadmin *nga, unsigned char *ports)
73 {
74         List *attr;
75         ListNode *ln;
76         struct attr *at;
77         int ret = ERR_OK;
78         struct attr_vlan_conf *avc;
79         struct swi_attr *sa;
80         int port;
81         
82         
83         if (nga == NULL || ports== NULL)
84                 return ERR_INVARG;
85         
86         sa = nga->current;
87         if (sa == NULL)
88                 return ERR_NOTLOG;
89         
90         
91         attr = createEmptyList();
92         pushBackList(attr, newEmptyAttr(ATTR_VLAN_PORT_CONF));
93         ret = readRequest(nga, attr);
94         if (ret != ERR_OK)
95                 goto end;
96         
97         filterAttributes(attr, ATTR_VLAN_PORT_CONF, ATTR_END);
98         
99         if (attr->first == NULL) {
100                 ret = ERR_BADREPLY;
101                 goto end;
102         }
103         
104         memset(ports, 0, sa->ports);
105         
106         for (ln = attr->first; ln != NULL; ln = ln->next) {
107                 at = ln->data;
108                 avc = at->data;
109
110                 if (at->size < sizeof(struct attr_vlan_conf) + sa->ports) {
111                         ret = ERR_BADREPLY;
112                         goto end;
113                 }
114                 
115                 for (port = 0; port < sa->ports; port++) {
116                         if (avc->ports[port] == VLAN_UNTAGGED)
117                                 ports[port] = avc->vlan;
118                 }
119         }
120         
121         
122 end:
123         destroyList(attr, (void(*)(void*))freeAttr);
124         
125         
126         return ret;
127 }
128
129
130 int ngadmin_setVLANPortConf (struct ngadmin *nga, const unsigned char *ports)
131 {
132         List *conf_old = NULL, *conf_new = NULL;
133         ListNode *ln;
134         struct attr *at;
135         struct swi_attr *sa;
136         struct attr_vlan_conf *avc_old, *avc_new;
137         int ret = ERR_OK, port;
138         
139         
140         if (nga == NULL || ports == NULL)
141                 return ERR_INVARG;
142         
143         sa = nga->current;
144         if (sa == NULL)
145                 return ERR_NOTLOG;
146         
147         /* if nothing is to be changed, do nothing */
148         for (port = 0; port < sa->ports && ports[port] == 0; port++);
149         if (port == sa->ports)
150                 goto end;
151         
152         /* read old config */
153         conf_old = createEmptyList();
154         pushBackList(conf_old, newEmptyAttr(ATTR_VLAN_PORT_CONF));
155         ret = readRequest(nga, conf_old);
156         if (ret != ERR_OK)
157                 goto end;
158         
159         filterAttributes(conf_old, ATTR_VLAN_PORT_CONF, ATTR_END);
160         
161         if (conf_old->first == NULL) {
162                 ret = ERR_BADREPLY;
163                 goto end;
164         }
165         
166         /* merge old config with requested config */
167         conf_new = createEmptyList();
168         avc_new = malloc(sizeof(struct attr_vlan_conf) + sa->ports);
169         
170         for (ln = conf_old->first; ln != NULL; ln = ln->next) {
171                 at = ln->data;
172                 avc_old = at->data;
173                 
174                 if (at->size < sizeof(struct attr_vlan_conf) + sa->ports) {
175                         ret = ERR_BADREPLY;
176                         free(avc_new);
177                         goto end;
178                 }
179                 
180                 /* compute new VLAN configuration */
181                 avc_new->vlan = avc_old->vlan;
182                 
183                 for (port = 0; port < sa->ports; port++) {
184                         if (ports[port] == 0)
185                                 avc_new->ports[port] = avc_old->ports[port];
186                         else if (ports[port] == avc_new->vlan)
187                                 avc_new->ports[port] = VLAN_UNTAGGED;
188                         else
189                                 avc_new->ports[port] = VLAN_NO;
190                 }
191                 
192                 /* only add it if it is different from old config */
193                 if (memcmp(avc_old->ports, avc_new->ports, sa->ports) != 0) {
194                         pushBackList(conf_new, newAttr(ATTR_VLAN_PORT_CONF, sizeof(struct attr_vlan_conf) + sa->ports, avc_new));
195                         avc_new = malloc(sizeof(struct attr_vlan_conf) + sa->ports);
196                 }
197         }
198         
199         free(avc_new);
200         
201         /* if no VLAN is changed, no need to send anything to the switch */
202         if (conf_new->first == NULL)
203                 goto end;
204         
205         /* send new configuration to the switch */
206         ret = writeRequest(nga, conf_new);
207         conf_new = NULL;
208         
209 end:
210         destroyList(conf_old, (void(*)(void*))freeAttr);
211         destroyList(conf_new, (void(*)(void*))freeAttr);
212         
213         
214         return ret;
215 }
216
217
218 int ngadmin_getVLANDotAllConf (struct ngadmin *nga, unsigned short *vlans, unsigned char *ports, int *nb)
219 {
220         List *attr;
221         ListNode *ln;
222         struct attr *at;
223         int ret = ERR_OK, total;
224         struct attr_vlan_conf *avc;
225         struct swi_attr *sa;
226         
227         
228         if (nga == NULL || vlans == NULL || ports== NULL || nb == NULL || *nb <= 0)
229                 return ERR_INVARG;
230         
231         sa = nga->current;
232         if (sa == NULL)
233                 return ERR_NOTLOG;
234         
235         
236         total = *nb;
237         *nb = 0;
238         
239         attr = createEmptyList();
240         pushBackList(attr, newEmptyAttr(ATTR_VLAN_DOT_CONF));
241         ret = readRequest(nga, attr);
242         if (ret != ERR_OK)
243                 goto end;
244         
245         filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END);
246         
247         if (attr->first == NULL) {
248                 ret = ERR_BADREPLY;
249                 goto end;
250         }
251         
252         memset(vlans, 0, total * sizeof(unsigned short));
253         memset(ports, 0, total * sa->ports);
254         
255         for (ln = attr->first; ln != NULL; ln = ln->next) {
256                 at = ln->data;
257                 avc = at->data;
258                 
259                 if (at->size < sizeof(struct attr_vlan_conf) + sa->ports) {
260                         ret = ERR_BADREPLY;
261                         goto end;
262                 }
263                 
264                 *vlans = avc->vlan;
265                 memcpy(ports, avc->ports, sa->ports);
266                 
267                 vlans++;
268                 ports += sa->ports;
269                 (*nb)++;
270                 
271                 if (*nb > total)
272                         break; /* no more room */
273         }
274         
275         
276 end:
277         destroyList(attr, (void(*)(void*))freeAttr);
278         
279         
280         return ret;
281 }
282
283
284 int ngadmin_getVLANDotConf (struct ngadmin *nga, unsigned short vlan, unsigned char *ports)
285 {
286         List *attr;
287         ListNode *ln;
288         struct attr *at;
289         int ret = ERR_OK;
290         struct swi_attr *sa;
291         struct attr_vlan_conf *avc;
292         
293         
294         if (nga == NULL || vlan < VLAN_MIN || vlan > VLAN_DOT_MAX || ports == NULL)
295                 return ERR_INVARG;
296         
297         sa = nga->current;
298         if (sa == NULL)
299                 return ERR_NOTLOG;
300         
301         attr = createEmptyList();
302         pushBackList(attr, newShortAttr(ATTR_VLAN_DOT_CONF, vlan));
303         ret = readRequest(nga, attr);
304         if (ret != ERR_OK)
305                 goto end;
306         
307         filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END);
308         
309         if (attr->first == NULL) {
310                 ret = ERR_BADREPLY;
311                 goto end;
312         }
313         
314         memset(ports, 0, sa->ports);
315         
316         for (ln = attr->first; ln != NULL; ln = ln->next) {
317                 at = ln->data;
318                 avc = at->data;
319                 
320                 if (at->size < sizeof(struct attr_vlan_conf) + sa->ports) {
321                         ret = ERR_BADREPLY;
322                         goto end;
323                 }
324                 
325                 if (avc->vlan == vlan) {
326                         memcpy(ports, avc->ports, sa->ports);
327                         break;
328                 }
329         }
330         
331         
332 end:
333         destroyList(attr, (void(*)(void*))freeAttr);
334         
335         
336         return ret;
337 }
338
339
340 int ngadmin_setVLANDotConf (struct ngadmin *nga, unsigned short vlan, const unsigned char *ports)
341 {
342         List *attr = NULL;
343         struct attr *at;
344         struct swi_attr *sa;
345         struct attr_vlan_conf *avc;
346         int ret = ERR_OK, port;
347         
348         
349         if (nga == NULL || vlan < VLAN_MIN || vlan > VLAN_DOT_MAX || ports == NULL)
350                 return ERR_INVARG;
351         
352         sa = nga->current;
353         if (sa == NULL)
354                 return ERR_NOTLOG;
355         
356         
357         /* if nothing is to be changed, do nothing */
358         for (port = 0; port < sa->ports && ports[port] == VLAN_UNSPEC; port++);
359         if (port == sa->ports )
360                 goto end;
361         
362         
363         attr = createEmptyList();
364         avc = malloc(sizeof(struct attr_vlan_conf) + sa->ports);
365         if (avc == NULL)
366                 return ERR_MEM;
367         
368         avc->vlan = vlan;
369         
370         /* if all is to be changed, we do not need to read old config */
371         if (memchr(ports, VLAN_UNSPEC, sa->ports) != NULL) {
372                 
373                 pushBackList(attr, newShortAttr(ATTR_VLAN_DOT_CONF, vlan));
374                 ret = readRequest(nga, attr);
375                 if (ret != ERR_OK)
376                         goto end;
377                 
378                 filterAttributes(attr, ATTR_VLAN_DOT_CONF, ATTR_END);
379                 
380                 /* check if the switch is in 802.1Q mode */
381                 if (attr->first == NULL) {
382                         ret = ERR_BADREPLY;
383                         goto end;
384                 } else {
385                         at = attr->first->data;
386                         if (at->size < sizeof(struct attr_vlan_conf) + sa->ports) {
387                                 ret = ERR_BADREPLY;
388                                 goto end;
389                         }
390                 }
391                 
392                 memcpy(avc, at->data, sizeof(struct attr_vlan_conf) + sa->ports);
393                 clearList(attr, (void(*)(void*))freeAttr);
394         }
395         
396         
397         /* apply changes */
398         for (port = 0; port < sa->ports; port++) {
399                 if (ports[port] != VLAN_UNSPEC)
400                         avc->ports[port] = ports[port];
401         }
402         
403         
404         pushBackList(attr, newAttr(ATTR_VLAN_DOT_CONF, sizeof(struct attr_vlan_conf) + sa->ports, avc));
405         ret = writeRequest(nga, attr);
406         attr = NULL;
407         
408         
409 end:
410         destroyList(attr, (void(*)(void*))freeAttr);
411         
412         
413         return ret;
414 }
415
416
417 int ngadmin_VLANDestroy (struct ngadmin *nga, unsigned short vlan)
418 {
419         List *attr;
420         
421         
422         if (nga == NULL || vlan < VLAN_MIN || vlan > VLAN_DOT_MAX)
423                 return ERR_INVARG;
424         else if (nga->current == NULL)
425                 return ERR_NOTLOG;
426         
427         
428         attr = createEmptyList();
429         pushBackList(attr, newShortAttr(ATTR_VLAN_DESTROY, vlan));
430         
431         
432         return writeRequest(nga, attr);
433 }
434
435
436 int ngadmin_getAllPVID (struct ngadmin *nga, unsigned short *ports)
437 {
438         List *attr;
439         ListNode *ln;
440         struct attr *at;
441         int ret = ERR_OK;
442         struct attr_pvid *ap;
443         struct swi_attr *sa;
444         
445         
446         if (nga == NULL || ports == NULL)
447                 return ERR_INVARG;
448         
449         sa = nga->current;
450         if (sa == NULL)
451                 return ERR_NOTLOG;
452         
453         
454         attr = createEmptyList();
455         pushBackList(attr, newEmptyAttr(ATTR_VLAN_PVID));
456         ret = readRequest(nga, attr);
457         if (ret != ERR_OK)
458                 goto end;
459         
460         filterAttributes(attr, ATTR_VLAN_PVID, ATTR_END);
461         
462         memset(ports, 0, sa->ports * sizeof(unsigned short));
463         
464         for (ln = attr->first; ln != NULL; ln = ln->next) {
465                 at = ln->data;
466                 ap = at->data;
467                 if (at->size == 0) {
468                         ret = ERR_BADREPLY;
469                         goto end;
470                 }
471                 if (ap->port <= sa->ports)
472                         ports[ap->port - 1] = ap->vlan;
473         }
474         
475         
476 end:
477         destroyList(attr, (void(*)(void*))freeAttr);
478         
479         
480         return ret;
481 }
482
483
484 int ngadmin_setPVID (struct ngadmin *nga, unsigned char port, unsigned short vlan)
485 {
486         List *attr;
487         struct attr_pvid *ap;
488         
489         
490         if (nga == NULL || port < 1 || vlan < VLAN_MIN || vlan > VLAN_DOT_MAX)
491                 return ERR_INVARG;
492         else if (nga->current == NULL)
493                 return ERR_NOTLOG;
494         else if (port > nga->current->ports)
495                 return ERR_INVARG;
496         
497         
498         attr = createEmptyList();
499         ap = malloc(sizeof(struct attr_pvid));
500         if (ap == NULL)
501                 return ERR_MEM;
502         ap->port = port;
503         ap->vlan = vlan;
504         
505         pushBackList(attr, newAttr(ATTR_VLAN_PVID, sizeof(struct attr_pvid), ap));
506         
507         
508         return writeRequest(nga, attr);
509 }
510
511