From ea763e0e2828c35660310f8b7791781b17b30cbd Mon Sep 17 00:00:00 2001 From: Ethan Jackson Date: Wed, 5 Jan 2011 11:51:15 -0800 Subject: [PATCH] bridge: Move tunnel_egress_iface to status column. This commit removes the tunnel_egress_iface column from the interface table and moves it's data to the status column. In the process it reverts the database to version 1.0.0. --- lib/netdev-dummy.c | 2 +- lib/netdev-linux.c | 2 +- lib/netdev-provider.h | 23 ++++++++------- lib/netdev-vport.c | 23 +++++++++++---- lib/netdev.c | 15 ++++++---- lib/netdev.h | 2 +- vswitchd/bridge.c | 58 +++++++++++++++++++++++++++++++++++--- vswitchd/vswitch.ovsschema | 8 ++---- vswitchd/vswitch.xml | 18 ++++++------ 9 files changed, 109 insertions(+), 42 deletions(-) diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c index 218a0228..4569f974 100644 --- a/lib/netdev-dummy.c +++ b/lib/netdev-dummy.c @@ -320,7 +320,7 @@ static const struct netdev_class dummy_class = { NULL, /* get_in6 */ NULL, /* add_router */ NULL, /* get_next_hop */ - NULL, /* get_tnl_iface */ + NULL, /* get_status */ NULL, /* arp_lookup */ netdev_dummy_update_flags, diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 5654dd46..97f9a647 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -2176,7 +2176,7 @@ netdev_linux_poll_remove(struct netdev_notifier *notifier_) netdev_linux_get_in6, \ netdev_linux_add_router, \ netdev_linux_get_next_hop, \ - NULL, /* get_tnl_iface */ \ + NULL, /* get_status */ \ netdev_linux_arp_lookup, \ \ netdev_linux_update_flags, \ diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h index 038f277f..da0ad45f 100644 --- a/lib/netdev-provider.h +++ b/lib/netdev-provider.h @@ -518,16 +518,19 @@ struct netdev_class { int (*get_next_hop)(const struct in_addr *host, struct in_addr *next_hop, char **netdev_name); - /* Looks up the name of the interface out of which traffic will egress if - * 'netdev' is a tunnel. If unsuccessful, or 'netdev' is not a tunnel, - * will return null. This function does not necessarily return the - * physical interface out which traffic will egress. Instead it returns - * the interface which is assigned 'netdev's remote_ip. This may be an - * internal interface such as a bridge port. - * - * This function may be set to null if 'netdev' is not a tunnel or it is - * not supported. */ - const char *(*get_tnl_iface)(const struct netdev *netdev); + /* Retrieves the status of the device. + * + * Populates 'sh' with key-value pairs representing the status of the + * device. A device's status is a set of key-value string pairs + * representing netdev type specific information. For more information see + * ovs-vswitchd.conf.db(5). + * + * The data of 'sh' are heap allocated strings which the caller is + * responsible for deallocating. + * + * This function may be set to null if it would always return EOPNOTSUPP + * anyhow. */ + int (*get_status)(const struct netdev *netdev, struct shash *sh); /* Looks up the ARP table entry for 'ip' on 'netdev' and stores the * corresponding MAC address in 'mac'. A return value of ENXIO, in diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c index f3985e9d..cf717cc7 100644 --- a/lib/netdev-vport.c +++ b/lib/netdev-vport.c @@ -100,6 +100,7 @@ static void netdev_vport_route_change(const struct rtnetlink_route_change *, void *); static void netdev_vport_link_change(const struct rtnetlink_link_change *, void *); +static const char *netdev_vport_get_tnl_iface(const struct netdev *netdev); static bool is_vport_class(const struct netdev_class *class) @@ -364,6 +365,18 @@ netdev_vport_set_stats(struct netdev *netdev, const struct netdev_stats *stats) return err; } +static int +netdev_vport_get_status(const struct netdev *netdev, struct shash *sh) +{ + const char *iface = netdev_vport_get_tnl_iface(netdev); + + if (iface) { + shash_add(sh, "tunnel_egress_iface", xstrdup(iface)); + } + + return 0; +} + static int netdev_vport_update_flags(struct netdev *netdev OVS_UNUSED, enum netdev_flags off, enum netdev_flags on OVS_UNUSED, @@ -924,7 +937,7 @@ parse_patch_config(const struct netdev_dev *dev, const struct shash *args, return 0; } -#define VPORT_FUNCTIONS(TNL_IFACE) \ +#define VPORT_FUNCTIONS(GET_STATUS) \ netdev_vport_init, \ netdev_vport_run, \ netdev_vport_wait, \ @@ -974,7 +987,7 @@ parse_patch_config(const struct netdev_dev *dev, const struct shash *args, NULL, /* get_in6 */ \ NULL, /* add_router */ \ NULL, /* get_next_hop */ \ - TNL_IFACE, \ + GET_STATUS, \ NULL, /* arp_lookup */ \ \ netdev_vport_update_flags, \ @@ -986,11 +999,11 @@ void netdev_vport_register(void) { static const struct vport_class vport_classes[] = { - { { "gre", VPORT_FUNCTIONS(netdev_vport_get_tnl_iface) }, + { { "gre", VPORT_FUNCTIONS(netdev_vport_get_status) }, parse_tunnel_config }, - { { "ipsec_gre", VPORT_FUNCTIONS(netdev_vport_get_tnl_iface) }, + { { "ipsec_gre", VPORT_FUNCTIONS(netdev_vport_get_status) }, parse_tunnel_config }, - { { "capwap", VPORT_FUNCTIONS(netdev_vport_get_tnl_iface) }, + { { "capwap", VPORT_FUNCTIONS(netdev_vport_get_status) }, parse_tunnel_config }, { { "patch", VPORT_FUNCTIONS(NULL) }, parse_patch_config } }; diff --git a/lib/netdev.c b/lib/netdev.c index 4b2e59e2..0f223271 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -769,14 +769,19 @@ netdev_get_next_hop(const struct netdev *netdev, return error; } -const char * -netdev_get_tnl_iface(const struct netdev *netdev) +/* Populates 'sh' with status information. + * + * Populates 'sh' with 'netdev' specific status information. This information + * may be used to populate the status column of the Interface table as defined + * in ovs-vswitchd.conf.db(5). */ +int +netdev_get_status(const struct netdev *netdev, struct shash *sh) { struct netdev_dev *dev = netdev_get_dev(netdev); - return (dev->netdev_class->get_tnl_iface - ? dev->netdev_class->get_tnl_iface(netdev) - : NULL); + return (dev->netdev_class->get_status + ? dev->netdev_class->get_status(netdev, sh) + : EOPNOTSUPP); } /* If 'netdev' has an assigned IPv6 address, sets '*in6' to that address and diff --git a/lib/netdev.h b/lib/netdev.h index d7d7097b..50ad5a3b 100644 --- a/lib/netdev.h +++ b/lib/netdev.h @@ -141,7 +141,7 @@ int netdev_get_in6(const struct netdev *, struct in6_addr *); int netdev_add_router(struct netdev *, struct in_addr router); int netdev_get_next_hop(const struct netdev *, const struct in_addr *host, struct in_addr *next_hop, char **); -const char *netdev_get_tnl_iface(const struct netdev *); +int netdev_get_status(const struct netdev *, struct shash *sh); int netdev_arp_lookup(const struct netdev *, uint32_t ip, uint8_t mac[6]); int netdev_get_flags(const struct netdev *, enum netdev_flags *); diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 8b07b3e0..20cbee5c 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -288,6 +288,9 @@ static void iface_send_packet(struct iface *, struct ofpbuf *packet); static void shash_from_ovs_idl_map(char **keys, char **values, size_t n, struct shash *); +static void shash_to_ovs_idl_map(struct shash *, + char ***keys, char ***values, size_t *n); + /* Hooks into ofproto processing. */ static struct ofhooks bridge_ofhooks; @@ -1110,11 +1113,26 @@ dpid_from_hash(const void *data, size_t n) } static void -iface_refresh_tunnel_egress(struct iface *iface) +iface_refresh_status(struct iface *iface) { - const char *name = netdev_get_tnl_iface(iface->netdev); + struct shash sh; + + shash_init(&sh); + + if (!netdev_get_status(iface->netdev, &sh)) { + size_t n; + char **keys, **values; - ovsrec_interface_set_tunnel_egress_iface(iface->cfg, name); + shash_to_ovs_idl_map(&sh, &keys, &values, &n); + ovsrec_interface_set_status(iface->cfg, keys, values, n); + + free(keys); + free(values); + } else { + ovsrec_interface_set_status(iface->cfg, NULL, NULL, 0); + } + + shash_destroy_free_data(&sh); } static void @@ -1326,7 +1344,7 @@ bridge_run(void) struct iface *iface = port->ifaces[j]; iface_refresh_stats(iface); iface_refresh_cfm_stats(iface); - iface_refresh_tunnel_egress(iface); + iface_refresh_status(iface); } } } @@ -4152,6 +4170,38 @@ shash_from_ovs_idl_map(char **keys, char **values, size_t n, } } +/* Creates 'keys' and 'values' arrays from 'shash'. + * + * Sets 'keys' and 'values' to heap allocated arrays representing the key-value + * pairs in 'shash'. The caller takes ownership of 'keys' and 'values'. They + * are populated with with strings taken directly from 'shash' and thus have + * the same ownership of the key-value pairs in shash. + */ +static void +shash_to_ovs_idl_map(struct shash *shash, + char ***keys, char ***values, size_t *n) +{ + size_t i, count; + char **k, **v; + struct shash_node *sn; + + count = shash_count(shash); + + k = xmalloc(count * sizeof *k); + v = xmalloc(count * sizeof *v); + + i = 0; + SHASH_FOR_EACH(sn, shash) { + k[i] = sn->name; + v[i] = sn->data; + i++; + } + + *n = count; + *keys = k; + *values = v; +} + struct iface_delete_queues_cbdata { struct netdev *netdev; const struct ovsdb_datum *queues; diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema index a8140b8a..f975851d 100644 --- a/vswitchd/vswitch.ovsschema +++ b/vswitchd/vswitch.ovsschema @@ -1,6 +1,6 @@ {"name": "Open_vSwitch", - "version": "1.0.2", - "cksum": "3196651018 14282", + "version": "1.0.3", + "cksum": "2654345387 14137", "tables": { "Open_vSwitch": { "columns": { @@ -151,10 +151,6 @@ "ingress_policing_burst": { "type": {"key": {"type": "integer", "minInteger": 0}}}, - "tunnel_egress_iface": { - "type": {"key": {"type": "string"}, - "min": 0, "max": 1}, - "ephemeral": true}, "mac": { "type": {"key": {"type": "string"}, "min": 0, "max": 1}}, diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index 7a70909e..5a3abb04 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -978,13 +978,21 @@ Key-value pairs that report port status. Supported status values are type-dependent.

-

The only currently defined key-value pair is:

+

The currently defined key-value pairs are:

source_ip
The source IP address used for an IPv4 tunnel end-point, such as gre or capwap. Not supported by all implementations.
+
+
tunnel_egress_iface
+
Egress interface for tunnels. Currently only relevant for GRE + and CAPWAP tunnels. On Linux systems, this column will show + the name of the interface which is responsible for routing + traffic destined for the configured remote_ip. + This could be an internal interface such as a bridge port.
+
@@ -1110,14 +1118,6 @@ - - Egress interface for tunnels. Currently only relevant for GRE and - CAPWAP tunnels. On Linux systems, this column will show the name of - the interface which is responsible for routing traffic destined for the - configured remote_ip. This could be an internal interface - such as a bridge port. - - Key-value pairs for rarely used interface features. Currently, there are none defined. -- 2.30.2