|
Packit |
c5a612 |
#!/usr/bin/python
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
from __future__ import print_function
|
|
Packit |
c5a612 |
import sys
|
|
Packit |
c5a612 |
import os
|
|
Packit |
c5a612 |
import json
|
|
Packit Service |
defc1a |
import argparse
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
TESTS_PATH = os.path.dirname(os.path.abspath(__file__))
|
|
Packit |
c5a612 |
sys.path.insert(0, os.path.join(TESTS_PATH, '../../py/'))
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
from nftables import Nftables
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
# Change working directory to repository root
|
|
Packit |
c5a612 |
os.chdir(TESTS_PATH + "/../..")
|
|
Packit |
c5a612 |
|
|
Packit Service |
defc1a |
parser = argparse.ArgumentParser(description='Run JSON echo tests')
|
|
Packit Service |
defc1a |
parser.add_argument('-H', '--host', action='store_true',
|
|
Packit Service |
defc1a |
help='Run tests against installed libnftables.so.1')
|
|
Packit Service |
defc1a |
parser.add_argument('-l', '--library', default=None,
|
|
Packit Service |
defc1a |
help='Path to libntables.so, overrides --host')
|
|
Packit Service |
defc1a |
args = parser.parse_args()
|
|
Packit Service |
defc1a |
|
|
Packit Service |
defc1a |
check_lib_path = True
|
|
Packit Service |
defc1a |
if args.library is None:
|
|
Packit Service |
defc1a |
if args.host:
|
|
Packit Service |
defc1a |
args.library = 'libnftables.so.1'
|
|
Packit Service |
defc1a |
check_lib_path = False
|
|
Packit Service |
defc1a |
else:
|
|
Packit Service |
defc1a |
args.library = 'src/.libs/libnftables.so.1'
|
|
Packit Service |
defc1a |
|
|
Packit Service |
defc1a |
if check_lib_path and not os.path.exists(args.library):
|
|
Packit Service |
defc1a |
print("Library not found at '%s'." % args.library)
|
|
Packit |
c5a612 |
sys.exit(1)
|
|
Packit |
c5a612 |
|
|
Packit Service |
defc1a |
nftables = Nftables(sofile = args.library)
|
|
Packit |
c5a612 |
nftables.set_echo_output(True)
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
# various commands to work with
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
flush_ruleset = { "flush": { "ruleset": None } }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
list_ruleset = { "list": { "ruleset": None } }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
add_table = { "add": {
|
|
Packit |
c5a612 |
"table": {
|
|
Packit |
c5a612 |
"family": "inet",
|
|
Packit |
c5a612 |
"name": "t",
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
}}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
add_chain = { "add": {
|
|
Packit |
c5a612 |
"chain": {
|
|
Packit |
c5a612 |
"family": "inet",
|
|
Packit |
c5a612 |
"table": "t",
|
|
Packit |
c5a612 |
"name": "c"
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
}}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
add_set = { "add": {
|
|
Packit |
c5a612 |
"set": {
|
|
Packit |
c5a612 |
"family": "inet",
|
|
Packit |
c5a612 |
"table": "t",
|
|
Packit |
c5a612 |
"name": "s",
|
|
Packit |
c5a612 |
"type": "inet_service"
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
}}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
add_rule = { "add": {
|
|
Packit |
c5a612 |
"rule": {
|
|
Packit |
c5a612 |
"family": "inet",
|
|
Packit |
c5a612 |
"table": "t",
|
|
Packit |
c5a612 |
"chain": "c",
|
|
Packit |
c5a612 |
"expr": [ { "accept": None } ]
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
}}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
add_counter = { "add": {
|
|
Packit |
c5a612 |
"counter": {
|
|
Packit |
c5a612 |
"family": "inet",
|
|
Packit |
c5a612 |
"table": "t",
|
|
Packit |
c5a612 |
"name": "c"
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
}}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
add_quota = { "add": {
|
|
Packit |
c5a612 |
"quota": {
|
|
Packit |
c5a612 |
"family": "inet",
|
|
Packit |
c5a612 |
"table": "t",
|
|
Packit |
c5a612 |
"name": "q",
|
|
Packit |
c5a612 |
"bytes": 65536
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
}}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
# helper functions
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
def exit_err(msg):
|
|
Packit |
c5a612 |
print("Error: %s" %msg)
|
|
Packit |
c5a612 |
sys.exit(1)
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
def exit_dump(e, obj):
|
|
Packit |
c5a612 |
print("FAIL: {}".format(e))
|
|
Packit |
c5a612 |
print("Output was:")
|
|
Packit |
c5a612 |
json.dumps(out, sort_keys = True, indent = 4, separators = (',', ': '))
|
|
Packit |
c5a612 |
sys.exit(1)
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
def do_flush():
|
|
Packit |
c5a612 |
rc, out, err = nftables.json_cmd({ "nftables": [flush_ruleset] })
|
|
Packit |
c5a612 |
if not rc is 0:
|
|
Packit |
c5a612 |
exit_err("flush ruleset failed: {}".format(err))
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
def do_command(cmd):
|
|
Packit |
c5a612 |
if not type(cmd) is list:
|
|
Packit |
c5a612 |
cmd = [cmd]
|
|
Packit |
c5a612 |
rc, out, err = nftables.json_cmd({ "nftables": cmd })
|
|
Packit |
c5a612 |
if not rc is 0:
|
|
Packit |
c5a612 |
exit_err("command failed: {}".format(err))
|
|
Packit |
c5a612 |
return out
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
def do_list_ruleset():
|
|
Packit |
c5a612 |
echo = nftables.get_echo_output()
|
|
Packit |
c5a612 |
nftables.set_echo_output(False)
|
|
Packit |
c5a612 |
out = do_command(list_ruleset)
|
|
Packit |
c5a612 |
nftables.set_echo_output(echo)
|
|
Packit |
c5a612 |
return out
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
def get_handle(output, search):
|
|
Packit |
c5a612 |
try:
|
|
Packit |
c5a612 |
for item in output["nftables"]:
|
|
Packit |
c5a612 |
if "add" in item:
|
|
Packit |
c5a612 |
data = item["add"]
|
|
Packit |
c5a612 |
elif "insert" in item:
|
|
Packit |
c5a612 |
data = item["insert"]
|
|
Packit |
c5a612 |
else:
|
|
Packit |
c5a612 |
data = item
|
|
Packit |
c5a612 |
|
|
Packit Service |
b07ed0 |
k = list(search.keys())[0]
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
if not k in data:
|
|
Packit |
c5a612 |
continue
|
|
Packit |
c5a612 |
found = True
|
|
Packit |
c5a612 |
for key in list(search[k].keys()):
|
|
Packit |
c5a612 |
if key == "handle":
|
|
Packit |
c5a612 |
continue
|
|
Packit |
c5a612 |
if not key in data[k] or search[k][key] != data[k][key]:
|
|
Packit |
c5a612 |
found = False
|
|
Packit |
c5a612 |
break
|
|
Packit |
c5a612 |
if not found:
|
|
Packit |
c5a612 |
continue
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
return data[k]["handle"]
|
|
Packit |
c5a612 |
except Exception as e:
|
|
Packit |
c5a612 |
exit_dump(e, output)
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
# single commands first
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
do_flush()
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
print("Adding table t")
|
|
Packit |
c5a612 |
out = do_command(add_table)
|
|
Packit |
c5a612 |
handle = get_handle(out, add_table["add"])
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
out = do_list_ruleset()
|
|
Packit |
c5a612 |
handle_cmp = get_handle(out, add_table["add"])
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
if handle != handle_cmp:
|
|
Packit |
c5a612 |
exit_err("handle mismatch!")
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
add_table["add"]["table"]["handle"] = handle
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
print("Adding chain c")
|
|
Packit |
c5a612 |
out = do_command(add_chain)
|
|
Packit |
c5a612 |
handle = get_handle(out, add_chain["add"])
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
out = do_list_ruleset()
|
|
Packit |
c5a612 |
handle_cmp = get_handle(out, add_chain["add"])
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
if handle != handle_cmp:
|
|
Packit |
c5a612 |
exit_err("handle mismatch!")
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
add_chain["add"]["chain"]["handle"] = handle
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
print("Adding set s")
|
|
Packit |
c5a612 |
out = do_command(add_set)
|
|
Packit |
c5a612 |
handle = get_handle(out, add_set["add"])
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
out = do_list_ruleset()
|
|
Packit |
c5a612 |
handle_cmp = get_handle(out, add_set["add"])
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
if handle != handle_cmp:
|
|
Packit |
c5a612 |
exit_err("handle mismatch!")
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
add_set["add"]["set"]["handle"] = handle
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
print("Adding rule")
|
|
Packit |
c5a612 |
out = do_command(add_rule)
|
|
Packit |
c5a612 |
handle = get_handle(out, add_rule["add"])
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
out = do_list_ruleset()
|
|
Packit |
c5a612 |
handle_cmp = get_handle(out, add_rule["add"])
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
if handle != handle_cmp:
|
|
Packit |
c5a612 |
exit_err("handle mismatch!")
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
add_rule["add"]["rule"]["handle"] = handle
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
print("Adding counter")
|
|
Packit |
c5a612 |
out = do_command(add_counter)
|
|
Packit |
c5a612 |
handle = get_handle(out, add_counter["add"])
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
out = do_list_ruleset()
|
|
Packit |
c5a612 |
handle_cmp = get_handle(out, add_counter["add"])
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
if handle != handle_cmp:
|
|
Packit |
c5a612 |
exit_err("handle mismatch!")
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
add_counter["add"]["counter"]["handle"] = handle
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
print("Adding quota")
|
|
Packit |
c5a612 |
out = do_command(add_quota)
|
|
Packit |
c5a612 |
handle = get_handle(out, add_quota["add"])
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
out = do_list_ruleset()
|
|
Packit |
c5a612 |
handle_cmp = get_handle(out, add_quota["add"])
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
if handle != handle_cmp:
|
|
Packit |
c5a612 |
exit_err("handle mismatch!")
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
add_quota["add"]["quota"]["handle"] = handle
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
# adjust names and add items again
|
|
Packit |
c5a612 |
# Note: Handles are per-table, hence add renamed objects to first table
|
|
Packit |
c5a612 |
# to make sure assigned handle differs from first run.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
add_table["add"]["table"]["name"] = "t2"
|
|
Packit |
c5a612 |
add_chain["add"]["chain"]["name"] = "c2"
|
|
Packit |
c5a612 |
add_set["add"]["set"]["name"] = "s2"
|
|
Packit |
c5a612 |
add_counter["add"]["counter"]["name"] = "c2"
|
|
Packit |
c5a612 |
add_quota["add"]["quota"]["name"] = "q2"
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
print("Adding table t2")
|
|
Packit |
c5a612 |
out = do_command(add_table)
|
|
Packit |
c5a612 |
handle = get_handle(out, add_table["add"])
|
|
Packit |
c5a612 |
if handle == add_table["add"]["table"]["handle"]:
|
|
Packit |
c5a612 |
exit_err("handle not changed in re-added table!")
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
print("Adding chain c2")
|
|
Packit |
c5a612 |
out = do_command(add_chain)
|
|
Packit |
c5a612 |
handle = get_handle(out, add_chain["add"])
|
|
Packit |
c5a612 |
if handle == add_chain["add"]["chain"]["handle"]:
|
|
Packit |
c5a612 |
exit_err("handle not changed in re-added chain!")
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
print("Adding set s2")
|
|
Packit |
c5a612 |
out = do_command(add_set)
|
|
Packit |
c5a612 |
handle = get_handle(out, add_set["add"])
|
|
Packit |
c5a612 |
if handle == add_set["add"]["set"]["handle"]:
|
|
Packit |
c5a612 |
exit_err("handle not changed in re-added set!")
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
print("Adding rule again")
|
|
Packit |
c5a612 |
out = do_command(add_rule)
|
|
Packit |
c5a612 |
handle = get_handle(out, add_rule["add"])
|
|
Packit |
c5a612 |
if handle == add_rule["add"]["rule"]["handle"]:
|
|
Packit |
c5a612 |
exit_err("handle not changed in re-added rule!")
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
print("Adding counter c2")
|
|
Packit |
c5a612 |
out = do_command(add_counter)
|
|
Packit |
c5a612 |
handle = get_handle(out, add_counter["add"])
|
|
Packit |
c5a612 |
if handle == add_counter["add"]["counter"]["handle"]:
|
|
Packit |
c5a612 |
exit_err("handle not changed in re-added counter!")
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
print("Adding quota q2")
|
|
Packit |
c5a612 |
out = do_command(add_quota)
|
|
Packit |
c5a612 |
handle = get_handle(out, add_quota["add"])
|
|
Packit |
c5a612 |
if handle == add_quota["add"]["quota"]["handle"]:
|
|
Packit |
c5a612 |
exit_err("handle not changed in re-added quota!")
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
# now multiple commands
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
# reset name changes again
|
|
Packit |
c5a612 |
add_table["add"]["table"]["name"] = "t"
|
|
Packit |
c5a612 |
add_chain["add"]["chain"]["name"] = "c"
|
|
Packit |
c5a612 |
add_set["add"]["set"]["name"] = "s"
|
|
Packit |
c5a612 |
add_counter["add"]["counter"]["name"] = "c"
|
|
Packit |
c5a612 |
add_quota["add"]["quota"]["name"] = "q"
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
do_flush()
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
print("doing multi add")
|
|
Packit |
c5a612 |
add_multi = [ add_table, add_chain, add_set, add_rule ]
|
|
Packit |
c5a612 |
out = do_command(add_multi)
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
thandle = get_handle(out, add_table["add"])
|
|
Packit |
c5a612 |
chandle = get_handle(out, add_chain["add"])
|
|
Packit |
c5a612 |
shandle = get_handle(out, add_set["add"])
|
|
Packit |
c5a612 |
rhandle = get_handle(out, add_rule["add"])
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
out = do_list_ruleset()
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
if thandle != get_handle(out, add_table["add"]):
|
|
Packit |
c5a612 |
exit_err("table handle mismatch!")
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
if chandle != get_handle(out, add_chain["add"]):
|
|
Packit |
c5a612 |
exit_err("chain handle mismatch!")
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
if shandle != get_handle(out, add_set["add"]):
|
|
Packit |
c5a612 |
exit_err("set handle mismatch!")
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
if rhandle != get_handle(out, add_rule["add"]):
|
|
Packit |
c5a612 |
exit_err("rule handle mismatch!")
|