+ tnl_cfg.in_key = parse_key(args, "in_key",
+ &tnl_cfg.in_key_present,
+ &tnl_cfg.in_key_flow);
+
+ tnl_cfg.out_key = parse_key(args, "out_key",
+ &tnl_cfg.out_key_present,
+ &tnl_cfg.out_key_flow);
+
+ ovs_mutex_lock(&dev->mutex);
+ if (memcmp(&dev->tnl_cfg, &tnl_cfg, sizeof tnl_cfg)) {
+ dev->tnl_cfg = tnl_cfg;
+ tunnel_check_status_change__(dev);
+ netdev_change_seq_changed(dev_);
+ }
+ ovs_mutex_unlock(&dev->mutex);
+
+ return 0;
+}
+
+static int
+get_tunnel_config(const struct netdev *dev, struct smap *args)
+{
+ struct netdev_vport *netdev = netdev_vport_cast(dev);
+ struct netdev_tunnel_config tnl_cfg;
+
+ ovs_mutex_lock(&netdev->mutex);
+ tnl_cfg = netdev->tnl_cfg;
+ ovs_mutex_unlock(&netdev->mutex);
+
+ if (ipv6_addr_is_set(&tnl_cfg.ipv6_dst)) {
+ smap_add_ipv6(args, "remote_ip", &tnl_cfg.ipv6_dst);
+ } else if (tnl_cfg.ip_dst_flow) {
+ smap_add(args, "remote_ip", "flow");
+ }
+
+ if (ipv6_addr_is_set(&tnl_cfg.ipv6_src)) {
+ smap_add_ipv6(args, "local_ip", &tnl_cfg.ipv6_src);
+ } else if (tnl_cfg.ip_src_flow) {
+ smap_add(args, "local_ip", "flow");
+ }
+
+ if (tnl_cfg.in_key_flow && tnl_cfg.out_key_flow) {
+ smap_add(args, "key", "flow");
+ } else if (tnl_cfg.in_key_present && tnl_cfg.out_key_present
+ && tnl_cfg.in_key == tnl_cfg.out_key) {
+ smap_add_format(args, "key", "%"PRIu64, ntohll(tnl_cfg.in_key));
+ } else {
+ if (tnl_cfg.in_key_flow) {
+ smap_add(args, "in_key", "flow");
+ } else if (tnl_cfg.in_key_present) {
+ smap_add_format(args, "in_key", "%"PRIu64,
+ ntohll(tnl_cfg.in_key));
+ }
+
+ if (tnl_cfg.out_key_flow) {
+ smap_add(args, "out_key", "flow");
+ } else if (tnl_cfg.out_key_present) {
+ smap_add_format(args, "out_key", "%"PRIu64,
+ ntohll(tnl_cfg.out_key));