Add tunnel tundevs for tunnel realdevs as needed. In general the notion is that realdevs may be configured by users and from an end-user point of view are compatible with the existing port-based tunneling code. And that tundevs exist in the datapath arnd are actually used to send and recieve packets, based on flows.
Cc: Kyle Mestery <kmest...@cisco.com> Signed-off-by: Simon Horman <ho...@verge.net.au> --- vswitchd/bridge.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 1d2f76b..512bf59 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -268,6 +268,7 @@ static void configure_splinter_port(struct port *); static void add_vlan_splinter_ports(struct bridge *, const unsigned long int *splinter_vlans, struct shash *ports); +static void add_tunnel_ports(struct bridge *, struct shash *ports); /* Public functions. */ @@ -2739,6 +2740,8 @@ bridge_add_del_ports(struct bridge *br, add_vlan_splinter_ports(br, splinter_vlans, &new_ports); } + add_tunnel_ports(br, &new_ports); + /* Get rid of deleted ports. * Get rid of deleted interfaces on ports that still exist. */ HMAP_FOR_EACH_SAFE (port, next, hmap_node, &br->ports) { @@ -4140,6 +4143,70 @@ add_vlan_splinter_ports(struct bridge *br, } } +static struct ovsrec_port * +synthesize_tunnel_port(const char *name, const char *type) +{ + struct ovsrec_interface *iface; + struct ovsrec_port *port; + + iface = xzalloc(sizeof *iface); + iface->name = xstrdup(name); + iface->type = type; + + port = xzalloc(sizeof *port); + port->interfaces = xmemdup(&iface, sizeof iface); + port->n_interfaces = 1; + port->name = xstrdup(name); + + register_block(iface); + register_block(iface->name); + register_block(port); + register_block(port->interfaces); + register_block(port->name); + + return port; +} + +/* For each interface with 'br' is a tunnel, adds the corresponding + * ovsrec_port to 'ports' if it is not already present */ +static void +add_tunnel_ports(struct bridge *br, struct shash *ports) +{ + size_t i; + + /* We iterate through 'br->cfg->ports' instead of 'ports' here because + * we're modifying 'ports'. */ + for (i = 0; i < br->cfg->n_ports; i++) { + const char *name = br->cfg->ports[i]->name; + struct ovsrec_port *port_cfg = shash_find_data(ports, name); + size_t j; + + for (j = 0; j < port_cfg->n_interfaces; j++) { + struct ovsrec_interface *iface_cfg = port_cfg->interfaces[j]; + const char *type = iface_get_type(iface_cfg, br->cfg); + const char *tundev_name; + const char *tundev_type; + + if (!is_tunnel_realdev(type)) { + continue; + } + + tundev_name = strcmp(type, "ipsec_gre") ? type : "gre"; + if (!strcmp(tundev_name, "gre")) { + tundev_type = "gre-tundev"; + } else { + tundev_type = "capwap-tundev"; + } + + if (!shash_find(ports, tundev_name)) { + shash_add(ports, tundev_name, + synthesize_tunnel_port(tundev_name, + tundev_type)); + } + } + } +} + static void mirror_refresh_stats(struct mirror *m) { -- 1.7.10 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev