kexec-tools does build fine on mips with 2.6.27 kernels, until we update the kexec...
[openwrt.git] / package / swconfig / src / cli.c
1 /*
2  * swconfig.c: Switch configuration utility
3  *
4  * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * version 2 as published by the Free Software Foundatio.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  */
15
16 #include <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <inttypes.h>
20 #include <errno.h>
21 #include <stdint.h>
22 #include <getopt.h>
23 #include <sys/types.h>
24 #include <sys/socket.h>
25
26 #include <linux/types.h>
27 #include <linux/netlink.h>
28 #include <linux/genetlink.h>
29 #include <netlink/netlink.h>
30 #include <netlink/genl/genl.h>
31 #include <netlink/genl/ctrl.h>
32 #include <linux/switch.h>
33 #include "swlib.h"
34
35 #define GET             1
36 #define SET             2
37
38 void print_attrs(struct switch_attr *attr)
39 {
40         int i = 0;
41         while (attr) {
42                 const char *type;
43                 switch(attr->type) {
44                         case SWITCH_TYPE_INT:
45                                 type = "int";
46                                 break;
47                         case SWITCH_TYPE_STRING:
48                                 type = "string";
49                                 break;
50                         case SWITCH_TYPE_PORTS:
51                                 type = "ports";
52                                 break;
53                         case SWITCH_TYPE_NOVAL:
54                                 type = "none";
55                                 break;
56                         default:
57                                 type = "unknown";
58                                 break;
59                 }
60                 printf("\tAttribute %d (%s): %s (%s)\n", ++i, type, attr->name, attr->description);
61                 attr = attr->next;
62         }
63 }
64
65 void list_attributes(struct switch_dev *dev)
66 {
67         printf("Switch %d: %s(%s), ports: %d, vlans: %d\n", dev->id, dev->dev_name, dev->name, dev->ports, dev->vlans);
68         printf("     --switch\n");
69         print_attrs(dev->ops);
70         printf("     --vlan\n");
71         print_attrs(dev->vlan_ops);
72         printf("     --port\n");
73         print_attrs(dev->port_ops);
74 }
75
76 void print_usage(void)
77 {
78         printf("swconfig dev <dev> [port <port>|vlan <vlan>] (help|set <key> <value>|get <key>)\n");
79         exit(0);
80 }
81
82 int main(int argc, char **argv)
83 {
84         int retval = 0;
85         struct switch_dev *dev;
86         struct switch_attr *a;
87         struct switch_val val;
88         int err;
89         int i;
90
91         struct switch_port *ports;
92
93         int cmd = 0;
94         char *cdev = NULL;
95         int cport = -1;
96         int cvlan = -1;
97         char *ckey = NULL;
98         char *cvalue = NULL;
99         int chelp = 0;
100
101         if(argc < 4)
102                 print_usage();
103
104         if(strcmp(argv[1], "dev"))
105                 print_usage();
106
107         cdev = argv[2];
108
109         for(i = 3; i < argc; i++)
110         {
111                 int p;
112                 if(!strcmp(argv[i], "help"))
113                 {
114                         chelp = 1;
115                         continue;
116                 }
117                 if(i + 1 >= argc)
118                         print_usage();
119                 p = atoi(argv[i + 1]);
120                 if(!strcmp(argv[i], "port"))
121                 {
122                         cport = p;
123                 } else if(!strcmp(argv[i], "vlan"))
124                 {
125                         cvlan = p;
126                 } else if(!strcmp(argv[i], "set"))
127                 {
128                         if(argc <= i + 1)
129                                 print_usage();
130                         cmd = SET;
131                         ckey = argv[i + 1];
132                         if (argc > i + 2)
133                                 cvalue = argv[i + 2];
134                         else
135                                 cvalue = NULL;
136                         i++;
137                 } else if(!strcmp(argv[i], "get"))
138                 {
139                         cmd = GET;
140                         ckey = argv[i + 1];
141                 } else{
142                         print_usage();
143                 }
144                 i++;
145         }
146
147         if(cport > -1 && cvlan > -1)
148                 print_usage();
149
150         dev = swlib_connect(cdev);
151         if (!dev) {
152                 fprintf(stderr, "Failed to connect to the switch\n");
153                 return 1;
154         }
155
156         ports = malloc(sizeof(struct switch_port) * dev->ports);
157         memset(ports, 0, sizeof(struct switch_port) * dev->ports);
158         swlib_scan(dev);
159
160         if(chelp)
161         {
162                 list_attributes(dev);
163                 goto out;
164         }
165
166         if(cport > -1)
167                 a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_PORT, ckey);
168         else if(cvlan > -1)
169                 a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_VLAN, ckey);
170         else
171                 a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_GLOBAL, ckey);
172
173         if(!a)
174         {
175                 fprintf(stderr, "Unknown attribute \"%s\"\n", ckey);
176                 goto out;
177         }
178
179         switch(cmd)
180         {
181         case SET:
182                 if ((a->type != SWITCH_TYPE_NOVAL) &&
183                                 (cvalue == NULL))
184                         print_usage();
185
186                 switch(a->type) {
187                 case SWITCH_TYPE_INT:
188                         val.value.i = atoi(cvalue);
189                         break;
190                 case SWITCH_TYPE_STRING:
191                         val.value.s = cvalue;
192                         break;
193                 case SWITCH_TYPE_PORTS:
194                         val.len = 0;
195                         while(cvalue && *cvalue)
196                         {
197                                 ports[val.len].flags = 0;
198                                 ports[val.len].id = strtol(cvalue, &cvalue, 10);
199                                 while(*cvalue && !isspace(*cvalue)) {
200                                         if (*cvalue == 't')
201                                                 ports[val.len].flags |= SWLIB_PORT_FLAG_TAGGED;
202                                         cvalue++;
203                                 }
204                                 if (*cvalue)
205                                         cvalue++;
206                                 val.len++;
207                         }
208                         val.value.ports = ports;
209                         break;
210                 default:
211                         break;
212                 }
213                 if(cvlan > -1)
214                         val.port_vlan = cvlan;
215                 if(cport > -1)
216                         val.port_vlan = cport;
217                 if(swlib_set_attr(dev, a, &val) < 0)
218                 {
219                         fprintf(stderr, "failed\n");
220                         retval = -1;
221                         goto out;
222                 }
223                 break;
224         case GET:
225                 if(cvlan > -1)
226                         val.port_vlan = cvlan;
227                 if(cport > -1)
228                         val.port_vlan = cport;
229                 if(swlib_get_attr(dev, a, &val) < 0)
230                 {
231                         fprintf(stderr, "failed\n");
232                         retval = -1;
233                         goto out;
234                 }
235                 switch(a->type) {
236                 case SWITCH_TYPE_INT:
237                         printf("%d\n", val.value.i);
238                         break;
239                 case SWITCH_TYPE_STRING:
240                         printf("%s\n", val.value.s);
241                         break;
242                 case SWITCH_TYPE_PORTS:
243                         for(i = 0; i < val.len; i++)
244                                 printf("%d ", val.value.ports[i]);
245                         printf("\n");
246                         break;
247                 }
248         }
249
250 out:
251         swlib_free_all(dev);
252         free(ports);
253
254         return 0;
255 }