235 lines
6.2 KiB
C
235 lines
6.2 KiB
C
|
/*
|
||
|
* swlib.h: Switch configuration API (user space part)
|
||
|
*
|
||
|
* Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org>
|
||
|
*
|
||
|
* 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;
|
||
|
char dev_name[IFNAMSIZ];
|
||
|
const char *name;
|
||
|
const char *alias;
|
||
|
int ports;
|
||
|
int vlans;
|
||
|
int cpu_port;
|
||
|
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
|