+static int print_fou_mapping(struct nlmsghdr *n, void *arg)
+{
+ struct genlmsghdr *ghdr;
+ struct rtattr *tb[FOU_ATTR_MAX + 1];
+ int len = n->nlmsg_len;
+
+ if (n->nlmsg_type != genl_family)
+ return 0;
+
+ len -= NLMSG_LENGTH(GENL_HDRLEN);
+ if (len < 0)
+ return -1;
+
+ ghdr = NLMSG_DATA(n);
+ parse_rtattr(tb, FOU_ATTR_MAX, (void *) ghdr + GENL_HDRLEN, len);
+
+ open_json_object(NULL);
+ if (tb[FOU_ATTR_PORT])
+ print_uint(PRINT_ANY, "port", "port %u",
+ ntohs(rta_getattr_u16(tb[FOU_ATTR_PORT])));
+
+ if (tb[FOU_ATTR_TYPE] &&
+ rta_getattr_u8(tb[FOU_ATTR_TYPE]) == FOU_ENCAP_GUE)
+ print_null(PRINT_ANY, "gue", " gue", NULL);
+ else if (tb[FOU_ATTR_IPPROTO])
+ print_uint(PRINT_ANY, "ipproto",
+ " ipproto %u", rta_getattr_u8(tb[FOU_ATTR_IPPROTO]));
+
+ if (tb[FOU_ATTR_AF]) {
+ __u8 family = rta_getattr_u8(tb[FOU_ATTR_AF]);
+
+ print_string(PRINT_JSON, "family", NULL,
+ family_name(family));
+
+ if (family == AF_INET6)
+ print_string(PRINT_FP, NULL,
+ " -6", NULL);
+ }
+ print_string(PRINT_FP, NULL, "\n", NULL);
+ close_json_object();
+
+ return 0;
+}
+
+static int do_show(int argc, char **argv)
+{
+ FOU_REQUEST(req, 4096, FOU_CMD_GET, NLM_F_REQUEST | NLM_F_DUMP);
+
+ if (argc > 0) {
+ fprintf(stderr,
+ "\"ip fou show\" does not take any arguments.\n");
+ return -1;
+ }
+
+ if (rtnl_send(&genl_rth, &req.n, req.n.nlmsg_len) < 0) {
+ perror("Cannot send show request");
+ exit(1);
+ }
+
+ new_json_obj(json);
+ if (rtnl_dump_filter(&genl_rth, print_fou_mapping, stdout) < 0) {
+ fprintf(stderr, "Dump terminated\n");
+ return 1;
+ }
+ delete_json_obj();
+ fflush(stdout);
+
+ return 0;
+}
+