]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
tests: shell: add maps dumps
authorFlorian Westphal <fw@strlen.de>
Sun, 29 Jun 2025 09:11:25 +0000 (11:11 +0200)
committerFlorian Westphal <fw@strlen.de>
Mon, 30 Jun 2025 12:36:58 +0000 (14:36 +0200)
Signed-off-by: Florian Westphal <fw@strlen.de>
tests/shell/testcases/maps/dumps/delete_element.json-nft [new file with mode: 0644]
tests/shell/testcases/maps/dumps/delete_element_catchall.json-nft [new file with mode: 0644]
tests/shell/testcases/maps/dumps/named_ct_objects.json-nft [new file with mode: 0644]
tests/shell/testcases/maps/dumps/nat_addr_port.json-nft [new file with mode: 0644]
tests/shell/testcases/maps/dumps/typeof_integer_0.json-nft [new file with mode: 0644]
tests/shell/testcases/maps/dumps/typeof_maps_concat.json-nft [new file with mode: 0644]
tests/shell/testcases/maps/dumps/typeof_maps_concat_update_0.json-nft [new file with mode: 0644]
tests/shell/testcases/maps/dumps/typeof_raw_0.json-nft [new file with mode: 0644]
tests/shell/testcases/maps/dumps/vmap_unary.json-nft [new file with mode: 0644]

diff --git a/tests/shell/testcases/maps/dumps/delete_element.json-nft b/tests/shell/testcases/maps/dumps/delete_element.json-nft
new file mode 100644 (file)
index 0000000..69a0d3a
--- /dev/null
@@ -0,0 +1,87 @@
+{
+  "nftables": [
+    {
+      "metainfo": {
+        "version": "VERSION",
+        "release_name": "RELEASE_NAME",
+        "json_schema_version": 1
+      }
+    },
+    {
+      "table": {
+        "family": "ip",
+        "name": "x",
+        "handle": 0
+      }
+    },
+    {
+      "chain": {
+        "family": "ip",
+        "table": "x",
+        "name": "y",
+        "handle": 0,
+        "type": "filter",
+        "hook": "output",
+        "prio": 0,
+        "policy": "accept"
+      }
+    },
+    {
+      "map": {
+        "family": "ip",
+        "name": "m",
+        "table": "x",
+        "type": {
+          "typeof": {
+            "ct": {
+              "key": "bytes"
+            }
+          }
+        },
+        "handle": 0,
+        "map": "classid",
+        "flags": "interval",
+        "elem": [
+          [
+            {
+              "range": [
+                2048001,
+                4000000
+              ]
+            },
+            "1:2"
+          ]
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip",
+        "table": "x",
+        "chain": "y",
+        "handle": 0,
+        "expr": [
+          {
+            "mangle": {
+              "key": {
+                "meta": {
+                  "key": "priority"
+                }
+              },
+              "value": {
+                "map": {
+                  "key": {
+                    "ct": {
+                      "key": "bytes"
+                    }
+                  },
+                  "data": "@m"
+                }
+              }
+            }
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/tests/shell/testcases/maps/dumps/delete_element_catchall.json-nft b/tests/shell/testcases/maps/dumps/delete_element_catchall.json-nft
new file mode 100644 (file)
index 0000000..65053f2
--- /dev/null
@@ -0,0 +1,82 @@
+{
+  "nftables": [
+    {
+      "metainfo": {
+        "version": "VERSION",
+        "release_name": "RELEASE_NAME",
+        "json_schema_version": 1
+      }
+    },
+    {
+      "table": {
+        "family": "ip",
+        "name": "x",
+        "handle": 0
+      }
+    },
+    {
+      "chain": {
+        "family": "ip",
+        "table": "x",
+        "name": "y",
+        "handle": 0,
+        "type": "filter",
+        "hook": "output",
+        "prio": 0,
+        "policy": "accept"
+      }
+    },
+    {
+      "map": {
+        "family": "ip",
+        "name": "m",
+        "table": "x",
+        "type": {
+          "typeof": {
+            "ct": {
+              "key": "bytes"
+            }
+          }
+        },
+        "handle": 0,
+        "map": "classid",
+        "flags": "interval",
+        "elem": [
+          [
+            "*",
+            "1:3"
+          ]
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip",
+        "table": "x",
+        "chain": "y",
+        "handle": 0,
+        "expr": [
+          {
+            "mangle": {
+              "key": {
+                "meta": {
+                  "key": "priority"
+                }
+              },
+              "value": {
+                "map": {
+                  "key": {
+                    "ct": {
+                      "key": "bytes"
+                    }
+                  },
+                  "data": "@m"
+                }
+              }
+            }
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/tests/shell/testcases/maps/dumps/named_ct_objects.json-nft b/tests/shell/testcases/maps/dumps/named_ct_objects.json-nft
new file mode 100644 (file)
index 0000000..5258d87
--- /dev/null
@@ -0,0 +1,587 @@
+{
+  "nftables": [
+    {
+      "metainfo": {
+        "version": "VERSION",
+        "release_name": "RELEASE_NAME",
+        "json_schema_version": 1
+      }
+    },
+    {
+      "table": {
+        "family": "inet",
+        "name": "t",
+        "handle": 0
+      }
+    },
+    {
+      "chain": {
+        "family": "inet",
+        "table": "t",
+        "name": "y",
+        "handle": 0
+      }
+    },
+    {
+      "ct expectation": {
+        "family": "inet",
+        "name": "exp1",
+        "table": "t",
+        "handle": 0,
+        "protocol": "tcp",
+        "dport": 9876,
+        "timeout": 60000,
+        "size": 12,
+        "l3proto": "ip"
+      }
+    },
+    {
+      "ct expectation": {
+        "family": "inet",
+        "name": "exp2",
+        "table": "t",
+        "handle": 0,
+        "protocol": "tcp",
+        "dport": 9876,
+        "timeout": 3000,
+        "size": 13,
+        "l3proto": "ip6"
+      }
+    },
+    {
+      "ct helper": {
+        "family": "inet",
+        "name": "myftp",
+        "table": "t",
+        "handle": 0,
+        "type": "ftp",
+        "protocol": "tcp",
+        "l3proto": "inet"
+      }
+    },
+    {
+      "ct timeout": {
+        "family": "inet",
+        "name": "dns",
+        "table": "t",
+        "handle": 0,
+        "protocol": "tcp",
+        "l3proto": "ip",
+        "policy": {
+          "established": 3,
+          "close": 1
+        }
+      }
+    },
+    {
+      "map": {
+        "family": "inet",
+        "name": "exp",
+        "table": "t",
+        "type": {
+          "typeof": {
+            "payload": {
+              "protocol": "ip",
+              "field": "saddr"
+            }
+          }
+        },
+        "handle": 0,
+        "map": "ct expectation",
+        "elem": [
+          [
+            "192.168.2.2",
+            "exp1"
+          ]
+        ]
+      }
+    },
+    {
+      "map": {
+        "family": "inet",
+        "name": "exp6",
+        "table": "t",
+        "type": {
+          "typeof": {
+            "payload": {
+              "protocol": "ip6",
+              "field": "saddr"
+            }
+          }
+        },
+        "handle": 0,
+        "map": "ct expectation",
+        "flags": "interval",
+        "elem": [
+          [
+            {
+              "prefix": {
+                "addr": "dead:beef::",
+                "len": 64
+              }
+            },
+            "exp2"
+          ]
+        ]
+      }
+    },
+    {
+      "map": {
+        "family": "inet",
+        "name": "helpobj",
+        "table": "t",
+        "type": {
+          "typeof": {
+            "payload": {
+              "protocol": "ip6",
+              "field": "saddr"
+            }
+          }
+        },
+        "handle": 0,
+        "map": "ct helper",
+        "flags": "interval",
+        "elem": [
+          [
+            {
+              "prefix": {
+                "addr": "dead:beef::",
+                "len": 64
+              }
+            },
+            "myftp"
+          ]
+        ]
+      }
+    },
+    {
+      "map": {
+        "family": "inet",
+        "name": "timeoutmap",
+        "table": "t",
+        "type": {
+          "typeof": {
+            "payload": {
+              "protocol": "ip",
+              "field": "daddr"
+            }
+          }
+        },
+        "handle": 0,
+        "map": "ct timeout",
+        "elem": [
+          [
+            "192.168.0.1",
+            "dns"
+          ]
+        ]
+      }
+    },
+    {
+      "set": {
+        "family": "inet",
+        "name": "helpname",
+        "table": "t",
+        "type": {
+          "typeof": {
+            "ct": {
+              "key": "helper"
+            }
+          }
+        },
+        "handle": 0,
+        "elem": [
+          "sip",
+          "ftp"
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "t",
+        "chain": "y",
+        "handle": 0,
+        "expr": [
+          {
+            "ct expectation": {
+              "map": {
+                "key": {
+                  "payload": {
+                    "protocol": "ip",
+                    "field": "saddr"
+                  }
+                },
+                "data": "@exp"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "t",
+        "chain": "y",
+        "handle": 0,
+        "expr": [
+          {
+            "ct expectation": {
+              "map": {
+                "key": {
+                  "payload": {
+                    "protocol": "ip6",
+                    "field": "saddr"
+                  }
+                },
+                "data": {
+                  "set": [
+                    [
+                      "dead::beef",
+                      "exp2"
+                    ]
+                  ]
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "t",
+        "chain": "y",
+        "handle": 0,
+        "expr": [
+          {
+            "ct expectation": {
+              "map": {
+                "key": {
+                  "payload": {
+                    "protocol": "ip6",
+                    "field": "daddr"
+                  }
+                },
+                "data": {
+                  "set": [
+                    [
+                      "dead::beef",
+                      "exp2"
+                    ],
+                    [
+                      "feed::17",
+                      "exp2"
+                    ]
+                  ]
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "t",
+        "chain": "y",
+        "handle": 0,
+        "expr": [
+          {
+            "ct expectation": {
+              "map": {
+                "key": {
+                  "concat": [
+                    {
+                      "payload": {
+                        "protocol": "ip6",
+                        "field": "daddr"
+                      }
+                    },
+                    {
+                      "payload": {
+                        "protocol": "tcp",
+                        "field": "dport"
+                      }
+                    }
+                  ]
+                },
+                "data": {
+                  "set": [
+                    [
+                      {
+                        "concat": [
+                          "feed::17",
+                          512
+                        ]
+                      },
+                      "exp2"
+                    ],
+                    [
+                      {
+                        "concat": [
+                          "dead::beef",
+                          123
+                        ]
+                      },
+                      "exp2"
+                    ]
+                  ]
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "t",
+        "chain": "y",
+        "handle": 0,
+        "expr": [
+          {
+            "ct helper": {
+              "map": {
+                "key": {
+                  "payload": {
+                    "protocol": "ip6",
+                    "field": "saddr"
+                  }
+                },
+                "data": {
+                  "set": [
+                    [
+                      "1c3::c01d",
+                      "myftp"
+                    ],
+                    [
+                      "dead::beef",
+                      "myftp"
+                    ]
+                  ]
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "t",
+        "chain": "y",
+        "handle": 0,
+        "expr": [
+          {
+            "ct helper": {
+              "map": {
+                "key": {
+                  "payload": {
+                    "protocol": "ip6",
+                    "field": "saddr"
+                  }
+                },
+                "data": "@helpobj"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "t",
+        "chain": "y",
+        "handle": 0,
+        "expr": [
+          {
+            "ct timeout": {
+              "map": {
+                "key": {
+                  "payload": {
+                    "protocol": "ip",
+                    "field": "daddr"
+                  }
+                },
+                "data": "@timeoutmap"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "t",
+        "chain": "y",
+        "handle": 0,
+        "expr": [
+          {
+            "ct timeout": {
+              "map": {
+                "key": {
+                  "payload": {
+                    "protocol": "ip",
+                    "field": "daddr"
+                  }
+                },
+                "data": {
+                  "set": [
+                    [
+                      "1.2.3.4",
+                      "dns"
+                    ],
+                    [
+                      "5.6.7.8",
+                      "dns"
+                    ],
+                    [
+                      {
+                        "prefix": {
+                          "addr": "192.168.8.0",
+                          "len": 24
+                        }
+                      },
+                      "dns"
+                    ]
+                  ]
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "t",
+        "chain": "y",
+        "handle": 0,
+        "expr": [
+          {
+            "ct timeout": {
+              "map": {
+                "key": {
+                  "payload": {
+                    "protocol": "ip",
+                    "field": "daddr"
+                  }
+                },
+                "data": {
+                  "set": [
+                    [
+                      {
+                        "range": [
+                          "1.2.3.4",
+                          "1.2.3.8"
+                        ]
+                      },
+                      "dns"
+                    ]
+                  ]
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "t",
+        "chain": "y",
+        "handle": 0,
+        "expr": [
+          {
+            "ct timeout": {
+              "map": {
+                "key": {
+                  "payload": {
+                    "protocol": "ip6",
+                    "field": "daddr"
+                  }
+                },
+                "data": {
+                  "set": [
+                    [
+                      {
+                        "prefix": {
+                          "addr": "1ce::",
+                          "len": 64
+                        }
+                      },
+                      "dns"
+                    ],
+                    [
+                      "dead::beef",
+                      "dns"
+                    ]
+                  ]
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "t",
+        "chain": "y",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "ct": {
+                  "key": "helper"
+                }
+              },
+              "right": "@helpname"
+            }
+          },
+          {
+            "accept": null
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "t",
+        "chain": "y",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "payload": {
+                  "protocol": "ip",
+                  "field": "saddr"
+                }
+              },
+              "right": "192.168.1.1"
+            }
+          },
+          {
+            "ct timeout": "dns"
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/tests/shell/testcases/maps/dumps/nat_addr_port.json-nft b/tests/shell/testcases/maps/dumps/nat_addr_port.json-nft
new file mode 100644 (file)
index 0000000..38b01e6
--- /dev/null
@@ -0,0 +1,1419 @@
+{
+  "nftables": [
+    {
+      "metainfo": {
+        "version": "VERSION",
+        "release_name": "RELEASE_NAME",
+        "json_schema_version": 1
+      }
+    },
+    {
+      "table": {
+        "family": "ip",
+        "name": "ipfoo",
+        "handle": 0
+      }
+    },
+    {
+      "chain": {
+        "family": "ip",
+        "table": "ipfoo",
+        "name": "c",
+        "handle": 0,
+        "type": "nat",
+        "hook": "prerouting",
+        "prio": -100,
+        "policy": "accept"
+      }
+    },
+    {
+      "map": {
+        "family": "ip",
+        "name": "t1",
+        "table": "ipfoo",
+        "type": {
+          "typeof": {
+            "numgen": {
+              "mode": "inc",
+              "mod": 2,
+              "offset": 0
+            }
+          }
+        },
+        "handle": 0,
+        "map": "ipv4_addr"
+      }
+    },
+    {
+      "map": {
+        "family": "ip",
+        "name": "t2",
+        "table": "ipfoo",
+        "type": {
+          "typeof": {
+            "numgen": {
+              "mode": "inc",
+              "mod": 2,
+              "offset": 0
+            }
+          }
+        },
+        "handle": 0,
+        "map": [
+          "ipv4_addr",
+          "inet_service"
+        ]
+      }
+    },
+    {
+      "map": {
+        "family": "ip",
+        "name": "x",
+        "table": "ipfoo",
+        "type": "ipv4_addr",
+        "handle": 0,
+        "map": "ipv4_addr"
+      }
+    },
+    {
+      "map": {
+        "family": "ip",
+        "name": "y",
+        "table": "ipfoo",
+        "type": "ipv4_addr",
+        "handle": 0,
+        "map": [
+          "ipv4_addr",
+          "inet_service"
+        ],
+        "elem": [
+          [
+            "192.168.7.2",
+            {
+              "concat": [
+                "10.1.1.1",
+                4242
+              ]
+            }
+          ]
+        ]
+      }
+    },
+    {
+      "map": {
+        "family": "ip",
+        "name": "z",
+        "table": "ipfoo",
+        "type": [
+          "ipv4_addr",
+          "inet_service"
+        ],
+        "handle": 0,
+        "map": [
+          "ipv4_addr",
+          "inet_service"
+        ],
+        "elem": [
+          [
+            {
+              "concat": [
+                "192.168.7.2",
+                42
+              ]
+            },
+            {
+              "concat": [
+                "10.1.1.1",
+                4242
+              ]
+            }
+          ]
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip",
+        "table": "ipfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "!=",
+              "left": {
+                "meta": {
+                  "key": "iifname"
+                }
+              },
+              "right": "foobar"
+            }
+          },
+          {
+            "accept": null
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip",
+        "table": "ipfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "dnat": {
+              "addr": {
+                "map": {
+                  "key": {
+                    "payload": {
+                      "protocol": "ip",
+                      "field": "daddr"
+                    }
+                  },
+                  "data": "@x"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip",
+        "table": "ipfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "payload": {
+                  "protocol": "ip",
+                  "field": "saddr"
+                }
+              },
+              "right": "10.1.1.1"
+            }
+          },
+          {
+            "dnat": {
+              "addr": "10.2.3.4"
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip",
+        "table": "ipfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "payload": {
+                  "protocol": "ip",
+                  "field": "saddr"
+                }
+              },
+              "right": "10.1.1.2"
+            }
+          },
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "payload": {
+                  "protocol": "tcp",
+                  "field": "dport"
+                }
+              },
+              "right": 42
+            }
+          },
+          {
+            "dnat": {
+              "addr": "10.2.3.4",
+              "port": 4242
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip",
+        "table": "ipfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "meta": {
+                  "key": "l4proto"
+                }
+              },
+              "right": "tcp"
+            }
+          },
+          {
+            "dnat": {
+              "family": "ip",
+              "addr": {
+                "map": {
+                  "key": {
+                    "payload": {
+                      "protocol": "ip",
+                      "field": "saddr"
+                    }
+                  },
+                  "data": "@y"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip",
+        "table": "ipfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "dnat": {
+              "family": "ip",
+              "addr": {
+                "map": {
+                  "key": {
+                    "concat": [
+                      {
+                        "payload": {
+                          "protocol": "ip",
+                          "field": "saddr"
+                        }
+                      },
+                      {
+                        "payload": {
+                          "protocol": "tcp",
+                          "field": "dport"
+                        }
+                      }
+                    ]
+                  },
+                  "data": "@z"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip",
+        "table": "ipfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "dnat": {
+              "addr": {
+                "map": {
+                  "key": {
+                    "numgen": {
+                      "mode": "inc",
+                      "mod": 2,
+                      "offset": 0
+                    }
+                  },
+                  "data": "@t1"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip",
+        "table": "ipfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "meta": {
+                  "key": "l4proto"
+                }
+              },
+              "right": "tcp"
+            }
+          },
+          {
+            "dnat": {
+              "family": "ip",
+              "addr": {
+                "map": {
+                  "key": {
+                    "numgen": {
+                      "mode": "inc",
+                      "mod": 2,
+                      "offset": 0
+                    }
+                  },
+                  "data": "@t2"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "table": {
+        "family": "ip6",
+        "name": "ip6foo",
+        "handle": 0
+      }
+    },
+    {
+      "chain": {
+        "family": "ip6",
+        "table": "ip6foo",
+        "name": "c",
+        "handle": 0,
+        "type": "nat",
+        "hook": "prerouting",
+        "prio": -100,
+        "policy": "accept"
+      }
+    },
+    {
+      "map": {
+        "family": "ip6",
+        "name": "t1",
+        "table": "ip6foo",
+        "type": {
+          "typeof": {
+            "numgen": {
+              "mode": "inc",
+              "mod": 2,
+              "offset": 0
+            }
+          }
+        },
+        "handle": 0,
+        "map": "ipv6_addr"
+      }
+    },
+    {
+      "map": {
+        "family": "ip6",
+        "name": "t2",
+        "table": "ip6foo",
+        "type": {
+          "typeof": {
+            "numgen": {
+              "mode": "inc",
+              "mod": 2,
+              "offset": 0
+            }
+          }
+        },
+        "handle": 0,
+        "map": [
+          "ipv6_addr",
+          "inet_service"
+        ]
+      }
+    },
+    {
+      "map": {
+        "family": "ip6",
+        "name": "x",
+        "table": "ip6foo",
+        "type": "ipv6_addr",
+        "handle": 0,
+        "map": "ipv6_addr"
+      }
+    },
+    {
+      "map": {
+        "family": "ip6",
+        "name": "y",
+        "table": "ip6foo",
+        "type": "ipv6_addr",
+        "handle": 0,
+        "map": [
+          "ipv6_addr",
+          "inet_service"
+        ]
+      }
+    },
+    {
+      "map": {
+        "family": "ip6",
+        "name": "z",
+        "table": "ip6foo",
+        "type": [
+          "ipv6_addr",
+          "inet_service"
+        ],
+        "handle": 0,
+        "map": [
+          "ipv6_addr",
+          "inet_service"
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip6",
+        "table": "ip6foo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "!=",
+              "left": {
+                "meta": {
+                  "key": "iifname"
+                }
+              },
+              "right": "foobar"
+            }
+          },
+          {
+            "accept": null
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip6",
+        "table": "ip6foo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "dnat": {
+              "addr": {
+                "map": {
+                  "key": {
+                    "payload": {
+                      "protocol": "ip6",
+                      "field": "daddr"
+                    }
+                  },
+                  "data": "@x"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip6",
+        "table": "ip6foo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "payload": {
+                  "protocol": "ip6",
+                  "field": "saddr"
+                }
+              },
+              "right": "dead::1"
+            }
+          },
+          {
+            "dnat": {
+              "addr": "feed::1"
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip6",
+        "table": "ip6foo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "payload": {
+                  "protocol": "ip6",
+                  "field": "saddr"
+                }
+              },
+              "right": "dead::2"
+            }
+          },
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "payload": {
+                  "protocol": "tcp",
+                  "field": "dport"
+                }
+              },
+              "right": 42
+            }
+          },
+          {
+            "dnat": {
+              "addr": "c0::1a",
+              "port": 4242
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip6",
+        "table": "ip6foo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "meta": {
+                  "key": "l4proto"
+                }
+              },
+              "right": "tcp"
+            }
+          },
+          {
+            "dnat": {
+              "family": "ip6",
+              "addr": {
+                "map": {
+                  "key": {
+                    "payload": {
+                      "protocol": "ip6",
+                      "field": "saddr"
+                    }
+                  },
+                  "data": "@y"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip6",
+        "table": "ip6foo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "dnat": {
+              "family": "ip6",
+              "addr": {
+                "map": {
+                  "key": {
+                    "concat": [
+                      {
+                        "payload": {
+                          "protocol": "ip6",
+                          "field": "saddr"
+                        }
+                      },
+                      {
+                        "payload": {
+                          "protocol": "tcp",
+                          "field": "dport"
+                        }
+                      }
+                    ]
+                  },
+                  "data": "@z"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip6",
+        "table": "ip6foo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "dnat": {
+              "addr": {
+                "map": {
+                  "key": {
+                    "numgen": {
+                      "mode": "inc",
+                      "mod": 2,
+                      "offset": 0
+                    }
+                  },
+                  "data": "@t1"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip6",
+        "table": "ip6foo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "meta": {
+                  "key": "l4proto"
+                }
+              },
+              "right": "tcp"
+            }
+          },
+          {
+            "dnat": {
+              "family": "ip6",
+              "addr": {
+                "map": {
+                  "key": {
+                    "numgen": {
+                      "mode": "inc",
+                      "mod": 2,
+                      "offset": 0
+                    }
+                  },
+                  "data": "@t2"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "table": {
+        "family": "inet",
+        "name": "inetfoo",
+        "handle": 0
+      }
+    },
+    {
+      "chain": {
+        "family": "inet",
+        "table": "inetfoo",
+        "name": "c",
+        "handle": 0,
+        "type": "nat",
+        "hook": "prerouting",
+        "prio": -100,
+        "policy": "accept"
+      }
+    },
+    {
+      "map": {
+        "family": "inet",
+        "name": "t1v4",
+        "table": "inetfoo",
+        "type": {
+          "typeof": {
+            "numgen": {
+              "mode": "inc",
+              "mod": 2,
+              "offset": 0
+            }
+          }
+        },
+        "handle": 0,
+        "map": "ipv4_addr"
+      }
+    },
+    {
+      "map": {
+        "family": "inet",
+        "name": "t2v4",
+        "table": "inetfoo",
+        "type": {
+          "typeof": {
+            "numgen": {
+              "mode": "inc",
+              "mod": 2,
+              "offset": 0
+            }
+          }
+        },
+        "handle": 0,
+        "map": [
+          "ipv4_addr",
+          "inet_service"
+        ]
+      }
+    },
+    {
+      "map": {
+        "family": "inet",
+        "name": "t1v6",
+        "table": "inetfoo",
+        "type": {
+          "typeof": {
+            "numgen": {
+              "mode": "inc",
+              "mod": 2,
+              "offset": 0
+            }
+          }
+        },
+        "handle": 0,
+        "map": "ipv6_addr"
+      }
+    },
+    {
+      "map": {
+        "family": "inet",
+        "name": "t2v6",
+        "table": "inetfoo",
+        "type": {
+          "typeof": {
+            "numgen": {
+              "mode": "inc",
+              "mod": 2,
+              "offset": 0
+            }
+          }
+        },
+        "handle": 0,
+        "map": [
+          "ipv6_addr",
+          "inet_service"
+        ]
+      }
+    },
+    {
+      "map": {
+        "family": "inet",
+        "name": "x4",
+        "table": "inetfoo",
+        "type": "ipv4_addr",
+        "handle": 0,
+        "map": "ipv4_addr"
+      }
+    },
+    {
+      "map": {
+        "family": "inet",
+        "name": "y4",
+        "table": "inetfoo",
+        "type": "ipv4_addr",
+        "handle": 0,
+        "map": [
+          "ipv4_addr",
+          "inet_service"
+        ]
+      }
+    },
+    {
+      "map": {
+        "family": "inet",
+        "name": "z4",
+        "table": "inetfoo",
+        "type": [
+          "ipv4_addr",
+          "inet_service"
+        ],
+        "handle": 0,
+        "map": [
+          "ipv4_addr",
+          "inet_service"
+        ],
+        "elem": [
+          [
+            {
+              "concat": [
+                "192.168.7.2",
+                42
+              ]
+            },
+            {
+              "concat": [
+                "10.1.1.1",
+                4242
+              ]
+            }
+          ]
+        ]
+      }
+    },
+    {
+      "map": {
+        "family": "inet",
+        "name": "x6",
+        "table": "inetfoo",
+        "type": "ipv6_addr",
+        "handle": 0,
+        "map": "ipv6_addr"
+      }
+    },
+    {
+      "map": {
+        "family": "inet",
+        "name": "y6",
+        "table": "inetfoo",
+        "type": "ipv6_addr",
+        "handle": 0,
+        "map": [
+          "ipv6_addr",
+          "inet_service"
+        ]
+      }
+    },
+    {
+      "map": {
+        "family": "inet",
+        "name": "z6",
+        "table": "inetfoo",
+        "type": [
+          "ipv6_addr",
+          "inet_service"
+        ],
+        "handle": 0,
+        "map": [
+          "ipv6_addr",
+          "inet_service"
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "inetfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "!=",
+              "left": {
+                "meta": {
+                  "key": "iifname"
+                }
+              },
+              "right": "foobar"
+            }
+          },
+          {
+            "accept": null
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "inetfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "dnat": {
+              "family": "ip",
+              "addr": {
+                "map": {
+                  "key": {
+                    "payload": {
+                      "protocol": "ip",
+                      "field": "daddr"
+                    }
+                  },
+                  "data": "@x4"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "inetfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "payload": {
+                  "protocol": "ip",
+                  "field": "saddr"
+                }
+              },
+              "right": "10.1.1.1"
+            }
+          },
+          {
+            "dnat": {
+              "family": "ip",
+              "addr": "10.2.3.4"
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "inetfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "payload": {
+                  "protocol": "ip",
+                  "field": "saddr"
+                }
+              },
+              "right": "10.1.1.2"
+            }
+          },
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "payload": {
+                  "protocol": "tcp",
+                  "field": "dport"
+                }
+              },
+              "right": 42
+            }
+          },
+          {
+            "dnat": {
+              "family": "ip",
+              "addr": "10.2.3.4",
+              "port": 4242
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "inetfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "meta": {
+                  "key": "l4proto"
+                }
+              },
+              "right": "tcp"
+            }
+          },
+          {
+            "dnat": {
+              "family": "ip",
+              "addr": {
+                "map": {
+                  "key": {
+                    "payload": {
+                      "protocol": "ip",
+                      "field": "saddr"
+                    }
+                  },
+                  "data": "@y4"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "inetfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "dnat": {
+              "family": "ip",
+              "addr": {
+                "map": {
+                  "key": {
+                    "concat": [
+                      {
+                        "payload": {
+                          "protocol": "ip",
+                          "field": "saddr"
+                        }
+                      },
+                      {
+                        "payload": {
+                          "protocol": "tcp",
+                          "field": "dport"
+                        }
+                      }
+                    ]
+                  },
+                  "data": "@z4"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "inetfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "dnat": {
+              "family": "ip",
+              "addr": {
+                "map": {
+                  "key": {
+                    "numgen": {
+                      "mode": "inc",
+                      "mod": 2,
+                      "offset": 0
+                    }
+                  },
+                  "data": "@t1v4"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "inetfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "meta": {
+                  "key": "l4proto"
+                }
+              },
+              "right": "tcp"
+            }
+          },
+          {
+            "dnat": {
+              "family": "ip",
+              "addr": {
+                "map": {
+                  "key": {
+                    "numgen": {
+                      "mode": "inc",
+                      "mod": 2,
+                      "offset": 0
+                    }
+                  },
+                  "data": "@t2v4"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "inetfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "dnat": {
+              "family": "ip6",
+              "addr": {
+                "map": {
+                  "key": {
+                    "payload": {
+                      "protocol": "ip6",
+                      "field": "daddr"
+                    }
+                  },
+                  "data": "@x6"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "inetfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "payload": {
+                  "protocol": "ip6",
+                  "field": "saddr"
+                }
+              },
+              "right": "dead::1"
+            }
+          },
+          {
+            "dnat": {
+              "family": "ip6",
+              "addr": "feed::1"
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "inetfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "payload": {
+                  "protocol": "ip6",
+                  "field": "saddr"
+                }
+              },
+              "right": "dead::2"
+            }
+          },
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "payload": {
+                  "protocol": "tcp",
+                  "field": "dport"
+                }
+              },
+              "right": 42
+            }
+          },
+          {
+            "dnat": {
+              "family": "ip6",
+              "addr": "c0::1a",
+              "port": 4242
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "inetfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "meta": {
+                  "key": "l4proto"
+                }
+              },
+              "right": "tcp"
+            }
+          },
+          {
+            "dnat": {
+              "family": "ip6",
+              "addr": {
+                "map": {
+                  "key": {
+                    "payload": {
+                      "protocol": "ip6",
+                      "field": "saddr"
+                    }
+                  },
+                  "data": "@y6"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "inetfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "dnat": {
+              "family": "ip6",
+              "addr": {
+                "map": {
+                  "key": {
+                    "concat": [
+                      {
+                        "payload": {
+                          "protocol": "ip6",
+                          "field": "saddr"
+                        }
+                      },
+                      {
+                        "payload": {
+                          "protocol": "tcp",
+                          "field": "dport"
+                        }
+                      }
+                    ]
+                  },
+                  "data": "@z6"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "inetfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "dnat": {
+              "family": "ip6",
+              "addr": {
+                "map": {
+                  "key": {
+                    "numgen": {
+                      "mode": "inc",
+                      "mod": 2,
+                      "offset": 0
+                    }
+                  },
+                  "data": "@t1v6"
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "inetfoo",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "==",
+              "left": {
+                "meta": {
+                  "key": "l4proto"
+                }
+              },
+              "right": "tcp"
+            }
+          },
+          {
+            "dnat": {
+              "family": "ip6",
+              "addr": {
+                "map": {
+                  "key": {
+                    "numgen": {
+                      "mode": "inc",
+                      "mod": 2,
+                      "offset": 0
+                    }
+                  },
+                  "data": "@t2v6"
+                }
+              }
+            }
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/tests/shell/testcases/maps/dumps/typeof_integer_0.json-nft b/tests/shell/testcases/maps/dumps/typeof_integer_0.json-nft
new file mode 100644 (file)
index 0000000..8dea5c1
--- /dev/null
@@ -0,0 +1,256 @@
+{
+  "nftables": [
+    {
+      "metainfo": {
+        "version": "VERSION",
+        "release_name": "RELEASE_NAME",
+        "json_schema_version": 1
+      }
+    },
+    {
+      "table": {
+        "family": "inet",
+        "name": "t",
+        "handle": 0
+      }
+    },
+    {
+      "chain": {
+        "family": "inet",
+        "table": "t",
+        "name": "c",
+        "handle": 0
+      }
+    },
+    {
+      "map": {
+        "family": "inet",
+        "name": "m1",
+        "table": "t",
+        "type": {
+          "typeof": {
+            "concat": [
+              {
+                "payload": {
+                  "protocol": "udp",
+                  "field": "length"
+                }
+              },
+              {
+                "payload": {
+                  "base": "ih",
+                  "offset": 32,
+                  "len": 32
+                }
+              }
+            ]
+          }
+        },
+        "handle": 0,
+        "map": "verdict",
+        "flags": "interval",
+        "elem": [
+          [
+            {
+              "concat": [
+                {
+                  "range": [
+                    20,
+                    80
+                  ]
+                },
+                20
+              ]
+            },
+            {
+              "accept": null
+            }
+          ],
+          [
+            {
+              "concat": [
+                {
+                  "range": [
+                    1,
+                    10
+                  ]
+                },
+                10
+              ]
+            },
+            {
+              "drop": null
+            }
+          ]
+        ]
+      }
+    },
+    {
+      "map": {
+        "family": "inet",
+        "name": "m2",
+        "table": "t",
+        "type": {
+          "typeof": {
+            "concat": [
+              {
+                "payload": {
+                  "protocol": "udp",
+                  "field": "length"
+                }
+              },
+              {
+                "payload": {
+                  "base": "ih",
+                  "offset": 32,
+                  "len": 32
+                }
+              }
+            ]
+          }
+        },
+        "handle": 0,
+        "map": "verdict",
+        "elem": [
+          [
+            {
+              "concat": [
+                30,
+                30
+              ]
+            },
+            {
+              "drop": null
+            }
+          ],
+          [
+            {
+              "concat": [
+                20,
+                36
+              ]
+            },
+            {
+              "accept": null
+            }
+          ]
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "t",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "vmap": {
+              "key": {
+                "concat": [
+                  {
+                    "payload": {
+                      "protocol": "udp",
+                      "field": "length"
+                    }
+                  },
+                  {
+                    "payload": {
+                      "base": "nh",
+                      "offset": 32,
+                      "len": 32
+                    }
+                  }
+                ]
+              },
+              "data": "@m1"
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "t",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "vmap": {
+              "key": {
+                "concat": [
+                  {
+                    "payload": {
+                      "protocol": "udp",
+                      "field": "length"
+                    }
+                  },
+                  {
+                    "payload": {
+                      "base": "nh",
+                      "offset": 32,
+                      "len": 32
+                    }
+                  }
+                ]
+              },
+              "data": "@m2"
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "inet",
+        "table": "t",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "vmap": {
+              "key": {
+                "concat": [
+                  {
+                    "payload": {
+                      "protocol": "udp",
+                      "field": "length"
+                    }
+                  },
+                  {
+                    "payload": {
+                      "base": "th",
+                      "offset": 160,
+                      "len": 128
+                    }
+                  }
+                ]
+              },
+              "data": {
+                "set": [
+                  [
+                    {
+                      "concat": [
+                        {
+                          "range": [
+                            47,
+                            63
+                          ]
+                        },
+                        "0xe373135363130333131303735353203"
+                      ]
+                    },
+                    {
+                      "accept": null
+                    }
+                  ]
+                ]
+              }
+            }
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/tests/shell/testcases/maps/dumps/typeof_maps_concat.json-nft b/tests/shell/testcases/maps/dumps/typeof_maps_concat.json-nft
new file mode 100644 (file)
index 0000000..c9b27a7
--- /dev/null
@@ -0,0 +1,112 @@
+{
+  "nftables": [
+    {
+      "metainfo": {
+        "version": "VERSION",
+        "release_name": "RELEASE_NAME",
+        "json_schema_version": 1
+      }
+    },
+    {
+      "table": {
+        "family": "netdev",
+        "name": "t",
+        "handle": 0
+      }
+    },
+    {
+      "chain": {
+        "family": "netdev",
+        "table": "t",
+        "name": "c",
+        "handle": 0
+      }
+    },
+    {
+      "map": {
+        "family": "netdev",
+        "name": "m",
+        "table": "t",
+        "type": {
+          "typeof": {
+            "concat": [
+              {
+                "payload": {
+                  "protocol": "ether",
+                  "field": "saddr"
+                }
+              },
+              {
+                "payload": {
+                  "protocol": "vlan",
+                  "field": "id"
+                }
+              }
+            ]
+          }
+        },
+        "handle": 0,
+        "map": "mark",
+        "size": 1234,
+        "flags": [
+          "timeout",
+          "dynamic"
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "netdev",
+        "table": "t",
+        "chain": "c",
+        "handle": 0,
+        "expr": [
+          {
+            "match": {
+              "op": "!=",
+              "left": {
+                "payload": {
+                  "protocol": "ether",
+                  "field": "type"
+                }
+              },
+              "right": "8021q"
+            }
+          },
+          {
+            "map": {
+              "op": "update",
+              "elem": {
+                "elem": {
+                  "val": {
+                    "concat": [
+                      {
+                        "payload": {
+                          "protocol": "ether",
+                          "field": "daddr"
+                        }
+                      },
+                      123
+                    ]
+                  },
+                  "timeout": 60
+                }
+              },
+              "data": 42,
+              "map": "@m"
+            }
+          },
+          {
+            "counter": {
+              "packets": 0,
+              "bytes": 0
+            }
+          },
+          {
+            "return": null
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/tests/shell/testcases/maps/dumps/typeof_maps_concat_update_0.json-nft b/tests/shell/testcases/maps/dumps/typeof_maps_concat_update_0.json-nft
new file mode 100644 (file)
index 0000000..a21ff18
--- /dev/null
@@ -0,0 +1,168 @@
+{
+  "nftables": [
+    {
+      "metainfo": {
+        "version": "VERSION",
+        "release_name": "RELEASE_NAME",
+        "json_schema_version": 1
+      }
+    },
+    {
+      "table": {
+        "family": "ip",
+        "name": "foo",
+        "handle": 0
+      }
+    },
+    {
+      "chain": {
+        "family": "ip",
+        "table": "foo",
+        "name": "pr",
+        "handle": 0
+      }
+    },
+    {
+      "map": {
+        "family": "ip",
+        "name": "pinned",
+        "table": "foo",
+        "type": {
+          "typeof": {
+            "concat": [
+              {
+                "payload": {
+                  "protocol": "ip",
+                  "field": "saddr"
+                }
+              },
+              {
+                "ct": {
+                  "key": "proto-dst",
+                  "dir": "original"
+                }
+              }
+            ]
+          }
+        },
+        "handle": 0,
+        "map": [
+          "ipv4_addr",
+          "inet_service"
+        ],
+        "size": 65535,
+        "flags": [
+          "timeout",
+          "dynamic"
+        ],
+        "timeout": 360
+      }
+    },
+    {
+      "rule": {
+        "family": "ip",
+        "table": "foo",
+        "chain": "pr",
+        "handle": 0,
+        "expr": [
+          {
+            "map": {
+              "op": "update",
+              "elem": {
+                "elem": {
+                  "val": {
+                    "concat": [
+                      {
+                        "payload": {
+                          "protocol": "ip",
+                          "field": "saddr"
+                        }
+                      },
+                      {
+                        "ct": {
+                          "key": "proto-dst",
+                          "dir": "original"
+                        }
+                      }
+                    ]
+                  },
+                  "timeout": 90
+                }
+              },
+              "data": {
+                "concat": [
+                  {
+                    "payload": {
+                      "protocol": "ip",
+                      "field": "daddr"
+                    }
+                  },
+                  {
+                    "payload": {
+                      "protocol": "tcp",
+                      "field": "dport"
+                    }
+                  }
+                ]
+              },
+              "map": "@pinned"
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip",
+        "table": "foo",
+        "chain": "pr",
+        "handle": 0,
+        "expr": [
+          {
+            "map": {
+              "op": "update",
+              "elem": {
+                "elem": {
+                  "val": {
+                    "concat": [
+                      {
+                        "payload": {
+                          "protocol": "ip",
+                          "field": "saddr"
+                        }
+                      },
+                      {
+                        "ct": {
+                          "key": "proto-dst",
+                          "dir": "original"
+                        }
+                      }
+                    ]
+                  },
+                  "timeout": 90
+                }
+              },
+              "data": {
+                "concat": [
+                  {
+                    "payload": {
+                      "protocol": "ip",
+                      "field": "daddr"
+                    }
+                  },
+                  {
+                    "payload": {
+                      "protocol": "tcp",
+                      "field": "dport"
+                    }
+                  }
+                ]
+              },
+              "map": "@pinned"
+            }
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/tests/shell/testcases/maps/dumps/typeof_raw_0.json-nft b/tests/shell/testcases/maps/dumps/typeof_raw_0.json-nft
new file mode 100644 (file)
index 0000000..273f675
--- /dev/null
@@ -0,0 +1,178 @@
+{
+  "nftables": [
+    {
+      "metainfo": {
+        "version": "VERSION",
+        "release_name": "RELEASE_NAME",
+        "json_schema_version": 1
+      }
+    },
+    {
+      "table": {
+        "family": "ip",
+        "name": "x",
+        "handle": 0
+      }
+    },
+    {
+      "chain": {
+        "family": "ip",
+        "table": "x",
+        "name": "y",
+        "handle": 0
+      }
+    },
+    {
+      "map": {
+        "family": "ip",
+        "name": "y",
+        "table": "x",
+        "type": {
+          "typeof": {
+            "concat": [
+              {
+                "payload": {
+                  "protocol": "ip",
+                  "field": "saddr"
+                }
+              },
+              {
+                "payload": {
+                  "base": "ih",
+                  "offset": 32,
+                  "len": 32
+                }
+              }
+            ]
+          }
+        },
+        "handle": 0,
+        "map": "verdict",
+        "elem": [
+          [
+            {
+              "concat": [
+                "1.1.1.1",
+                20
+              ]
+            },
+            {
+              "accept": null
+            }
+          ],
+          [
+            {
+              "concat": [
+                "7.7.7.7",
+                134
+              ]
+            },
+            {
+              "accept": null
+            }
+          ],
+          [
+            {
+              "concat": [
+                "7.7.7.8",
+                151
+              ]
+            },
+            {
+              "drop": null
+            }
+          ]
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip",
+        "table": "x",
+        "chain": "y",
+        "handle": 0,
+        "expr": [
+          {
+            "vmap": {
+              "key": {
+                "concat": [
+                  {
+                    "payload": {
+                      "protocol": "ip",
+                      "field": "saddr"
+                    }
+                  },
+                  {
+                    "payload": {
+                      "base": "nh",
+                      "offset": 32,
+                      "len": 32
+                    }
+                  }
+                ]
+              },
+              "data": "@y"
+            }
+          }
+        ]
+      }
+    },
+    {
+      "rule": {
+        "family": "ip",
+        "table": "x",
+        "chain": "y",
+        "handle": 0,
+        "expr": [
+          {
+            "vmap": {
+              "key": {
+                "concat": [
+                  {
+                    "payload": {
+                      "protocol": "ip",
+                      "field": "saddr"
+                    }
+                  },
+                  {
+                    "payload": {
+                      "base": "nh",
+                      "offset": 32,
+                      "len": 32
+                    }
+                  }
+                ]
+              },
+              "data": {
+                "set": [
+                  [
+                    {
+                      "concat": [
+                        "4.4.4.4",
+                        52
+                      ]
+                    },
+                    {
+                      "accept": null
+                    }
+                  ],
+                  [
+                    {
+                      "concat": [
+                        "5.5.5.5",
+                        69
+                      ]
+                    },
+                    {
+                      "drop": null
+                    }
+                  ]
+                ]
+              }
+            }
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/tests/shell/testcases/maps/dumps/vmap_unary.json-nft b/tests/shell/testcases/maps/dumps/vmap_unary.json-nft
new file mode 100644 (file)
index 0000000..08583f9
--- /dev/null
@@ -0,0 +1,89 @@
+{
+  "nftables": [
+    {
+      "metainfo": {
+        "version": "VERSION",
+        "release_name": "RELEASE_NAME",
+        "json_schema_version": 1
+      }
+    },
+    {
+      "table": {
+        "family": "ip",
+        "name": "filter",
+        "handle": 0
+      }
+    },
+    {
+      "chain": {
+        "family": "ip",
+        "table": "filter",
+        "name": "INPUT",
+        "handle": 0,
+        "type": "filter",
+        "hook": "input",
+        "prio": 0,
+        "policy": "drop"
+      }
+    },
+    {
+      "map": {
+        "family": "ip",
+        "name": "ipsec_in",
+        "table": "filter",
+        "type": {
+          "typeof": {
+            "concat": [
+              {
+                "ipsec": {
+                  "key": "reqid",
+                  "dir": "in",
+                  "spnum": 0
+                }
+              },
+              {
+                "meta": {
+                  "key": "iif"
+                }
+              }
+            ]
+          }
+        },
+        "handle": 0,
+        "map": "verdict",
+        "flags": "interval"
+      }
+    },
+    {
+      "rule": {
+        "family": "ip",
+        "table": "filter",
+        "chain": "INPUT",
+        "handle": 0,
+        "expr": [
+          {
+            "vmap": {
+              "key": {
+                "concat": [
+                  {
+                    "ipsec": {
+                      "key": "reqid",
+                      "dir": "in",
+                      "spnum": 0
+                    }
+                  },
+                  {
+                    "meta": {
+                      "key": "iif"
+                    }
+                  }
+                ]
+              },
+              "data": "@ipsec_in"
+            }
+          }
+        ]
+      }
+    }
+  ]
+}