source: trunk/package/swconfig/src/cli.c @ 20939

Last change on this file since 20939 was 20939, checked in by juhosg, 7 years ago

swconfig: Add cpu port index to help output.

Let swconfig provide the cpu port index in its help page. This is
needed as e.g. Atheros switches have their cpu port at port 0, not
port 5.

This could allow e.g. luci to get a rough overview of the layout of
the switch.

Signed-off-by: Jonas Gorski <jonas.gorski+openwrt@…>

File size: 6.5 KB
Line 
1/*
2 * swconfig.c: Switch configuration utility
3 *
4 * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
5 * Copyright (C) 2010 Martin Mares <mj@ucw.cz>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundatio.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 */
16
17#include <stdio.h>
18#include <string.h>
19#include <stdlib.h>
20#include <inttypes.h>
21#include <errno.h>
22#include <stdint.h>
23#include <getopt.h>
24#include <sys/types.h>
25#include <sys/socket.h>
26#include <uci.h>
27
28#include <linux/types.h>
29#include <linux/netlink.h>
30#include <linux/genetlink.h>
31#include <netlink/netlink.h>
32#include <netlink/genl/genl.h>
33#include <netlink/genl/ctrl.h>
34#include <linux/switch.h>
35#include "swlib.h"
36
37enum {
38        CMD_NONE,
39        CMD_GET,
40        CMD_SET,
41        CMD_LOAD,
42        CMD_HELP,
43        CMD_SHOW,
44};
45
46static void
47print_attrs(const struct switch_attr *attr)
48{
49        int i = 0;
50        while (attr) {
51                const char *type;
52                switch(attr->type) {
53                        case SWITCH_TYPE_INT:
54                                type = "int";
55                                break;
56                        case SWITCH_TYPE_STRING:
57                                type = "string";
58                                break;
59                        case SWITCH_TYPE_PORTS:
60                                type = "ports";
61                                break;
62                        case SWITCH_TYPE_NOVAL:
63                                type = "none";
64                                break;
65                        default:
66                                type = "unknown";
67                                break;
68                }
69                printf("\tAttribute %d (%s): %s (%s)\n", ++i, type, attr->name, attr->description);
70                attr = attr->next;
71        }
72}
73
74static void
75list_attributes(struct switch_dev *dev)
76{
77        printf("Switch %d: %s(%s), ports: %d (cpu @ %d), vlans: %d\n", dev->id, dev->dev_name, dev->name, dev->ports, dev->cpu_port, dev->vlans);
78        printf("     --switch\n");
79        print_attrs(dev->ops);
80        printf("     --vlan\n");
81        print_attrs(dev->vlan_ops);
82        printf("     --port\n");
83        print_attrs(dev->port_ops);
84}
85
86static void
87print_attr_val(const struct switch_attr *attr, const struct switch_val *val)
88{
89        int i;
90
91        switch (attr->type) {
92        case SWITCH_TYPE_INT:
93                printf("%d", val->value.i);
94                break;
95        case SWITCH_TYPE_STRING:
96                printf("%s", val->value.s);
97                break;
98        case SWITCH_TYPE_PORTS:
99                for(i = 0; i < val->len; i++) {
100                        printf("%d%s ",
101                                val->value.ports[i].id,
102                                (val->value.ports[i].flags &
103                                 SWLIB_PORT_FLAG_TAGGED) ? "t" : "");
104                }
105                break;
106        default:
107                printf("?unknown-type?");
108        }
109}
110
111static void
112show_attrs(struct switch_dev *dev, struct switch_attr *attr, struct switch_val *val)
113{
114        while (attr) {
115                if (attr->type != SWITCH_TYPE_NOVAL) {
116                        printf("\t%s: ", attr->name);
117                        if (swlib_get_attr(dev, attr, val) < 0)
118                                printf("???");
119                        else
120                                print_attr_val(attr, val);
121                        putchar('\n');
122                }
123                attr = attr->next;
124        }
125}
126
127static void
128show_global(struct switch_dev *dev)
129{
130        struct switch_val val;
131
132        printf("Global attributes:\n");
133        show_attrs(dev, dev->ops, &val);
134}
135
136static void
137show_port(struct switch_dev *dev, int port)
138{
139        struct switch_val val;
140
141        printf("Port %d:\n", port);
142        val.port_vlan = port;
143        show_attrs(dev, dev->port_ops, &val);
144}
145
146static void
147show_vlan(struct switch_dev *dev, int vlan)
148{
149        struct switch_val val;
150
151        printf("VLAN %d:\n", vlan);
152        val.port_vlan = vlan;
153        show_attrs(dev, dev->vlan_ops, &val);
154}
155
156static void
157print_usage(void)
158{
159        printf("swconfig dev <dev> [port <port>|vlan <vlan>] (help|set <key> <value>|get <key>|load <config>|show)\n");
160        exit(1);
161}
162
163static void
164swconfig_load_uci(struct switch_dev *dev, const char *name)
165{
166        struct uci_context *ctx;
167        struct uci_package *p = NULL;
168        struct uci_element *e;
169        int ret = -1;
170
171        ctx = uci_alloc_context();
172        if (!ctx)
173                return;
174
175        uci_load(ctx, name, &p);
176        if (!p) {
177                uci_perror(ctx, "Failed to load config file: ");
178                goto out;
179        }
180
181        ret = swlib_apply_from_uci(dev, p);
182        if (ret < 0)
183                fprintf(stderr, "Failed to apply configuration for switch '%s'\n", dev->dev_name);
184
185out:
186        uci_free_context(ctx);
187        exit(ret);
188}
189
190int main(int argc, char **argv)
191{
192        int retval = 0;
193        struct switch_dev *dev;
194        struct switch_attr *a;
195        struct switch_val val;
196        int err;
197        int i;
198
199        int cmd = CMD_NONE;
200        char *cdev = NULL;
201        int cport = -1;
202        int cvlan = -1;
203        char *ckey = NULL;
204        char *cvalue = NULL;
205
206        if(argc < 4)
207                print_usage();
208
209        if(strcmp(argv[1], "dev"))
210                print_usage();
211
212        cdev = argv[2];
213
214        for(i = 3; i < argc; i++)
215        {
216                char *arg = argv[i];
217                if (cmd != CMD_NONE) {
218                        print_usage();
219                } else if (!strcmp(arg, "port") && i+1 < argc) {
220                        cport = atoi(argv[++i]);
221                } else if (!strcmp(arg, "vlan") && i+1 < argc) {
222                        cvlan = atoi(argv[++i]);
223                } else if (!strcmp(arg, "help")) {
224                        cmd = CMD_HELP;
225                } else if (!strcmp(arg, "set") && i+1 < argc) {
226                        cmd = CMD_SET;
227                        ckey = argv[++i];
228                        if (i+1 < argc)
229                                cvalue = argv[++i];
230                } else if (!strcmp(arg, "get") && i+1 < argc) {
231                        cmd = CMD_GET;
232                        ckey = argv[++i];
233                } else if (!strcmp(arg, "load") && i+1 < argc) {
234                        if ((cport >= 0) || (cvlan >= 0))
235                                print_usage();
236                        cmd = CMD_LOAD;
237                        ckey = argv[++i];
238                } else if (!strcmp(arg, "show")) {
239                        cmd = CMD_SHOW;
240                } else {
241                        print_usage();
242                }
243        }
244
245        if (cmd == CMD_NONE)
246                print_usage();
247        if (cport > -1 && cvlan > -1)
248                print_usage();
249
250        dev = swlib_connect(cdev);
251        if (!dev) {
252                fprintf(stderr, "Failed to connect to the switch\n");
253                return 1;
254        }
255
256        swlib_scan(dev);
257
258        if (cmd == CMD_GET || cmd == CMD_SET) {
259                if(cport > -1)
260                        a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_PORT, ckey);
261                else if(cvlan > -1)
262                        a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_VLAN, ckey);
263                else
264                        a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_GLOBAL, ckey);
265
266                if(!a)
267                {
268                        fprintf(stderr, "Unknown attribute \"%s\"\n", ckey);
269                        goto out;
270                }
271        }
272
273        switch(cmd)
274        {
275        case CMD_SET:
276                if ((a->type != SWITCH_TYPE_NOVAL) &&
277                                (cvalue == NULL))
278                        print_usage();
279
280                if(cvlan > -1)
281                        cport = cvlan;
282
283                if(swlib_set_attr_string(dev, a, cport, cvalue) < 0)
284                {
285                        fprintf(stderr, "failed\n");
286                        retval = -1;
287                        goto out;
288                }
289                break;
290        case CMD_GET:
291                if(cvlan > -1)
292                        val.port_vlan = cvlan;
293                if(cport > -1)
294                        val.port_vlan = cport;
295                if(swlib_get_attr(dev, a, &val) < 0)
296                {
297                        fprintf(stderr, "failed\n");
298                        retval = -1;
299                        goto out;
300                }
301                print_attr_val(a, &val);
302                putchar('\n');
303                break;
304        case CMD_LOAD:
305                swconfig_load_uci(dev, ckey);
306                break;
307        case CMD_HELP:
308                list_attributes(dev);
309                break;
310        case CMD_SHOW:
311                if (cport >= 0 || cvlan >= 0) {
312                        if (cport >= 0)
313                                show_port(dev, cport);
314                        else
315                                show_vlan(dev, cvlan);
316                } else {
317                        show_global(dev);
318                        for (i=0; i < dev->ports; i++)
319                                show_port(dev, i);
320                        for (i=0; i < dev->vlans; i++)
321                                show_vlan(dev, i);
322                }
323                break;
324        }
325
326out:
327        swlib_free_all(dev);
328        return 0;
329}
Note: See TracBrowser for help on using the repository browser.