/* * swlib.h: Switch configuration API (user space part) * * Copyright (C) 2008-2009 Felix Fietkau * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * Usage of the library functions: The main datastructure for a switch is the struct switch_device To get started, you first need to use switch_connect() to probe for switches and allocate an instance of this struct. There are two possible usage modes: dev = switch_connect("eth0"); - this call will look for a switch registered for the linux device "eth0" and only allocate a switch_device for this particular switch. dev = switch_connect(NULL) - this will return one switch_device struct for each available switch. The switch_device structs are chained with by ->next pointer Then to query a switch for all available attributes, use: swlib_scan(dev); All allocated datastructures for the switch_device struct can be freed with swlib_free(dev); or swlib_free_all(dev); The latter traverses a whole chain of switch_device structs and frees them all Switch attributes (struct switch_attr) are divided into three groups: dev->ops: - global settings dev->port_ops: - per-port settings dev->vlan_ops: - per-vlan settings switch_lookup_attr() is a small helper function to locate attributes by name. switch_set_attr() and switch_get_attr() can alter or request the values of attributes. Usage of the switch_attr struct: ->atype: attribute group, one of: - SWLIB_ATTR_GROUP_GLOBAL - SWLIB_ATTR_GROUP_VLAN - SWLIB_ATTR_GROUP_PORT ->id: identifier for the attribute ->type: data type, one of: - SWITCH_TYPE_INT - SWITCH_TYPE_STRING - SWITCH_TYPE_PORT ->name: short name of the attribute ->description: longer description ->next: pointer to the next attribute of the current group Usage of the switch_val struct: When setting attributes, following members of the struct switch_val need to be set up: ->len (for attr->type == SWITCH_TYPE_PORT) ->port_vlan: - port number (for attr->atype == SWLIB_ATTR_GROUP_PORT), or: - vlan number (for attr->atype == SWLIB_ATTR_GROUP_VLAN) ->value.i (for attr->type == SWITCH_TYPE_INT) ->value.s (for attr->type == SWITCH_TYPE_STRING) - owned by the caller, not stored in the library internally ->value.ports (for attr->type == SWITCH_TYPE_PORT) - must point to an array of at lest val->len * sizeof(struct switch_port) When getting string attributes, val->value.s must be freed by the caller When getting port list attributes, an internal static buffer is used, which changes from call to call. */ #ifndef __SWLIB_H #define __SWLIB_H enum swlib_attr_group { SWLIB_ATTR_GROUP_GLOBAL, SWLIB_ATTR_GROUP_VLAN, SWLIB_ATTR_GROUP_PORT, }; enum swlib_port_flags { SWLIB_PORT_FLAG_TAGGED = (1 << 0), }; struct switch_dev; struct switch_attr; struct switch_port; struct switch_val; struct uci_package; struct switch_dev { int id; const char *name; const char *dev_name; int ports; int vlans; struct switch_attr *ops; struct switch_attr *port_ops; struct switch_attr *vlan_ops; struct switch_dev *next; void *priv; }; struct switch_val { struct switch_attr *attr; int len; int err; int port_vlan; union { const char *s; int i; struct switch_port *ports; } value; }; struct switch_attr { struct switch_dev *dev; int atype; int id; int type; const char *name; const char *description; struct switch_attr *next; }; struct switch_port { unsigned int id; unsigned int flags; }; /** * swlib_connect: connect to the switch through netlink * @name: name of the ethernet interface, * * if name is NULL, it connect and builds a chain of all switches */ struct switch_dev *swlib_connect(const char *name); /** * swlib_free: free all dynamically allocated data for the switch connection * @dev: switch device struct * * all members of a switch device chain (generated by swlib_connect(NULL)) * must be freed individually */ void swlib_free(struct switch_dev *dev); /** * swlib_free_all: run swlib_free on all devices in the chain * @dev: switch device struct */ void swlib_free_all(struct switch_dev *dev); /** * swlib_scan: probe the switch driver for available commands/attributes * @dev: switch device struct */ int swlib_scan(struct switch_dev *dev); /** * swlib_lookup_attr: look up a switch attribute * @dev: switch device struct * @type: global, port or vlan * @name: name of the attribute */ struct switch_attr *swlib_lookup_attr(struct switch_dev *dev, enum swlib_attr_group atype, const char *name); /** * swlib_set_attr: set the value for an attribute * @dev: switch device struct * @attr: switch attribute struct * @val: attribute value pointer * returns 0 on success */ int swlib_set_attr(struct switch_dev *dev, struct switch_attr *attr, struct switch_val *val); /** * swlib_set_attr_string: set the value for an attribute with type conversion * @dev: switch device struct * @attr: switch attribute struct * @port_vlan: port or vlan (if applicable) * @str: string value * returns 0 on success */ int swlib_set_attr_string(struct switch_dev *dev, struct switch_attr *attr, int port_vlan, const char *str); /** * swlib_get_attr: get the value for an attribute * @dev: switch device struct * @attr: switch attribute struct * @val: attribute value pointer * returns 0 on success * for string attributes, the result string must be freed by the caller */ int swlib_get_attr(struct switch_dev *dev, struct switch_attr *attr, struct switch_val *val); /** * swlib_apply_from_uci: set up the switch from a uci configuration * @dev: switch device struct * @p: uci package which contains the desired global config */ int swlib_apply_from_uci(struct switch_dev *dev, struct uci_package *p); #endif