+unparse_tunnel_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED,
+ const struct nlattr *options, size_t options_len,
+ struct shash *args)
+{
+ struct nlattr *a[ODP_TUNNEL_ATTR_MAX + 1];
+ ovs_be32 daddr;
+ uint32_t flags;
+ int error;
+
+ error = tnl_port_config_from_nlattr(options, options_len, a);
+ if (error) {
+ return error;
+ }
+
+ flags = nl_attr_get_u32(a[ODP_TUNNEL_ATTR_FLAGS]);
+ if (!(flags & TNL_F_HDR_CACHE) == !(flags & TNL_F_IPSEC)) {
+ smap_add(args, "header_cache",
+ flags & TNL_F_HDR_CACHE ? "true" : "false");
+ }
+
+ daddr = nl_attr_get_be32(a[ODP_TUNNEL_ATTR_DST_IPV4]);
+ shash_add(args, "remote_ip", xasprintf(IP_FMT, IP_ARGS(&daddr)));
+
+ if (a[ODP_TUNNEL_ATTR_SRC_IPV4]) {
+ ovs_be32 saddr = nl_attr_get_be32(a[ODP_TUNNEL_ATTR_SRC_IPV4]);
+ shash_add(args, "local_ip", xasprintf(IP_FMT, IP_ARGS(&saddr)));
+ }
+
+ if (!a[ODP_TUNNEL_ATTR_IN_KEY] && !a[ODP_TUNNEL_ATTR_OUT_KEY]) {
+ smap_add(args, "key", "flow");
+ } else {
+ uint64_t in_key = get_be64_or_zero(a[ODP_TUNNEL_ATTR_IN_KEY]);
+ uint64_t out_key = get_be64_or_zero(a[ODP_TUNNEL_ATTR_OUT_KEY]);
+
+ if (in_key && in_key == out_key) {
+ shash_add(args, "key", xasprintf("%"PRIu64, in_key));
+ } else {
+ if (!a[ODP_TUNNEL_ATTR_IN_KEY]) {
+ smap_add(args, "in_key", "flow");
+ } else if (in_key) {
+ shash_add(args, "in_key", xasprintf("%"PRIu64, in_key));
+ }
+
+ if (!a[ODP_TUNNEL_ATTR_OUT_KEY]) {
+ smap_add(args, "out_key", "flow");
+ } else if (out_key) {
+ shash_add(args, "out_key", xasprintf("%"PRIu64, out_key));
+ }
+ }
+ }
+
+ if (flags & TNL_F_TTL_INHERIT) {
+ smap_add(args, "tos", "inherit");
+ } else if (a[ODP_TUNNEL_ATTR_TTL]) {
+ int ttl = nl_attr_get_u8(a[ODP_TUNNEL_ATTR_TTL]);
+ shash_add(args, "tos", xasprintf("%d", ttl));
+ }
+
+ if (flags & TNL_F_TOS_INHERIT) {
+ smap_add(args, "tos", "inherit");
+ } else if (a[ODP_TUNNEL_ATTR_TOS]) {
+ int tos = nl_attr_get_u8(a[ODP_TUNNEL_ATTR_TOS]);
+ shash_add(args, "tos", xasprintf("%d", tos));
+ }
+
+ if (flags & TNL_F_CSUM) {
+ smap_add(args, "csum", "true");
+ }
+ if (!(flags & TNL_F_PMTUD)) {
+ smap_add(args, "pmtud", "false");
+ }
+
+ return 0;
+}
+
+static int
+parse_patch_config(const char *name, const char *type OVS_UNUSED,
+ const struct shash *args, struct ofpbuf *options)