diff mbox series

[nft] py: Adjust Nftables class to output flags changes

Message ID 20181031125316.2275-1-phil@nwl.cc
State Accepted
Delegated to: Pablo Neira
Headers show
Series [nft] py: Adjust Nftables class to output flags changes | expand

Commit Message

Phil Sutter Oct. 31, 2018, 12:53 p.m. UTC
Introduce setter/getter methods for each introduced output flag. Ignore
NFT_CTX_OUTPUT_NUMERIC_ALL for now since it's main purpose is for
internal use.

Adjust the script in tests/py accordingly: Due to the good defaults,
only numeric proto output has to be selected - this is not a must, but
allows for the test cases to remain unchanged.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 py/nftables.py       | 220 ++++++++++++++++++++++++++++---------------
 tests/py/nft-test.py |  29 +++---
 2 files changed, 153 insertions(+), 96 deletions(-)

Comments

Pablo Neira Ayuso Oct. 31, 2018, 2:54 p.m. UTC | #1
On Wed, Oct 31, 2018 at 01:53:16PM +0100, Phil Sutter wrote:
> Introduce setter/getter methods for each introduced output flag. Ignore
> NFT_CTX_OUTPUT_NUMERIC_ALL for now since it's main purpose is for
> internal use.
> 
> Adjust the script in tests/py accordingly: Due to the good defaults,
> only numeric proto output has to be selected - this is not a must, but
> allows for the test cases to remain unchanged.

Applied, thanks Phil.
diff mbox series

Patch

diff --git a/py/nftables.py b/py/nftables.py
index d85bbb2ffeeda..6891cb1ce177b 100644
--- a/py/nftables.py
+++ b/py/nftables.py
@@ -33,11 +33,17 @@  class Nftables:
         "segtree":   0x40,
     }
 
-    numeric_levels = {
-        "none": 0,
-        "addr": 1,
-        "port": 2,
-        "all":  3,
+    output_flags = {
+        "reversedns":     (1 << 0),
+        "service":        (1 << 1),
+        "stateless":      (1 << 2),
+        "handle":         (1 << 3),
+        "json":           (1 << 4),
+        "echo":           (1 << 5),
+        "guid":           (1 << 6),
+        "numeric_proto":  (1 << 7),
+        "numeric_prio":   (1 << 8),
+        "numeric_symbol": (1 << 9),
     }
 
     def __init__(self, sofile="libnftables.so"):
@@ -58,40 +64,12 @@  class Nftables:
         self.nft_ctx_new.restype = c_void_p
         self.nft_ctx_new.argtypes = [c_int]
 
-        self.nft_ctx_output_get_handle = lib.nft_ctx_output_get_handle
-        self.nft_ctx_output_get_handle.restype = c_bool
-        self.nft_ctx_output_get_handle.argtypes = [c_void_p]
+        self.nft_ctx_output_get_flags = lib.nft_ctx_output_get_flags
+        self.nft_ctx_output_get_flags.restype = c_uint
+        self.nft_ctx_output_get_flags.argtypes = [c_void_p]
 
-        self.nft_ctx_output_set_handle = lib.nft_ctx_output_set_handle
-        self.nft_ctx_output_set_handle.argtypes = [c_void_p, c_bool]
-
-        self.nft_ctx_output_get_echo = lib.nft_ctx_output_get_echo
-        self.nft_ctx_output_get_echo.restype = c_bool
-        self.nft_ctx_output_get_echo.argtypes = [c_void_p]
-
-        self.nft_ctx_output_set_echo = lib.nft_ctx_output_set_echo
-        self.nft_ctx_output_set_echo.argtypes = [c_void_p, c_bool]
-
-        self.nft_ctx_output_get_numeric = lib.nft_ctx_output_get_numeric
-        self.nft_ctx_output_get_numeric.restype = c_int
-        self.nft_ctx_output_get_numeric.argtypes = [c_void_p]
-
-        self.nft_ctx_output_set_numeric = lib.nft_ctx_output_set_numeric
-        self.nft_ctx_output_set_numeric.argtypes = [c_void_p, c_int]
-
-        self.nft_ctx_output_get_stateless = lib.nft_ctx_output_get_stateless
-        self.nft_ctx_output_get_stateless.restype = c_bool
-        self.nft_ctx_output_get_stateless.argtypes = [c_void_p]
-
-        self.nft_ctx_output_set_stateless = lib.nft_ctx_output_set_stateless
-        self.nft_ctx_output_set_stateless.argtypes = [c_void_p, c_bool]
-
-        self.nft_ctx_output_get_json = lib.nft_ctx_output_get_json
-        self.nft_ctx_output_get_json.restype = c_bool
-        self.nft_ctx_output_get_json.argtypes = [c_void_p]
-
-        self.nft_ctx_output_set_json = lib.nft_ctx_output_set_json
-        self.nft_ctx_output_set_json.argtypes = [c_void_p, c_bool]
+        self.nft_ctx_output_set_flags = lib.nft_ctx_output_set_flags
+        self.nft_ctx_output_set_flags.argtypes = [c_void_p, c_uint]
 
         self.nft_ctx_output_get_debug = lib.nft_ctx_output_get_debug
         self.nft_ctx_output_get_debug.restype = c_int
@@ -128,12 +106,77 @@  class Nftables:
         self.nft_ctx_buffer_output(self.__ctx)
         self.nft_ctx_buffer_error(self.__ctx)
 
+    def __get_output_flag(self, name):
+        flag = self.output_flags[name]
+        return self.nft_ctx_output_get_flags(self.__ctx) & flag
+
+    def __set_output_flag(self, name, val):
+        flag = self.output_flags[name]
+        flags = self.nft_ctx_output_get_flags(self.__ctx)
+        if val:
+            new_flags = flags | flag
+        else:
+            new_flags = flags & ~flag
+        self.nft_ctx_output_set_flags(self.__ctx, new_flags)
+        return flags & flag
+
+    def get_reversedns_output(self):
+        """Get the current state of reverse DNS output.
+
+        Returns a boolean indicating whether reverse DNS lookups are performed
+        for IP addresses in output.
+        """
+        return self.__get_output_flag("reversedns")
+
+    def set_reversedns_output(self, val):
+        """Enable or disable reverse DNS output.
+
+        Accepts a boolean turning reverse DNS lookups in output on or off.
+
+        Returns the previous value.
+        """
+        return self.__set_output_flag("reversedns", val)
+
+    def get_service_output(self):
+        """Get the current state of service name output.
+
+        Returns a boolean indicating whether service names are used for port
+        numbers in output or not.
+        """
+        return self.__get_output_flag("service")
+
+    def set_service_output(self, val):
+        """Enable or disable service name output.
+
+        Accepts a boolean turning service names for port numbers in output on
+        or off.
+
+        Returns the previous value.
+        """
+        return self.__set_output_flag("service", val)
+
+    def get_stateless_output(self):
+        """Get the current state of stateless output.
+
+        Returns a boolean indicating whether stateless output is active or not.
+        """
+        return self.__get_output_flag("stateless")
+
+    def set_stateless_output(self, val):
+        """Enable or disable stateless output.
+
+        Accepts a boolean turning stateless output either on or off.
+
+        Returns the previous value.
+        """
+        return self.__set_output_flag("stateless", val)
+
     def get_handle_output(self):
         """Get the current state of handle output.
 
         Returns a boolean indicating whether handle output is active or not.
         """
-        return self.nft_ctx_output_get_handle(self.__ctx)
+        return self.__get_output_flag("handle")
 
     def set_handle_output(self, val):
         """Enable or disable handle output.
@@ -142,16 +185,30 @@  class Nftables:
 
         Returns the previous value.
         """
-        old = self.get_handle_output()
-        self.nft_ctx_output_set_handle(self.__ctx, val)
-        return old
+        return self.__set_output_flag("handle", val)
+
+    def get_json_output(self):
+        """Get the current state of JSON output.
+
+        Returns a boolean indicating whether JSON output is active or not.
+        """
+        return self.__get_output_flag("json")
+
+    def set_json_output(self, val):
+        """Enable or disable JSON output.
+
+        Accepts a boolean turning JSON output either on or off.
+
+        Returns the previous value.
+        """
+        return self.__set_output_flag("json", val)
 
     def get_echo_output(self):
         """Get the current state of echo output.
 
         Returns a boolean indicating whether echo output is active or not.
         """
-        return self.nft_ctx_output_get_echo(self.__ctx)
+        return self.__get_output_flag("echo")
 
     def set_echo_output(self, val):
         """Enable or disable echo output.
@@ -160,67 +217,74 @@  class Nftables:
 
         Returns the previous value.
         """
-        old = self.get_echo_output()
-        self.nft_ctx_output_set_echo(self.__ctx, val)
-        return old
+        return self.__set_output_flag("echo", val)
 
-    def get_numeric_output(self):
-        """Get the current state of numeric output.
+    def get_guid_output(self):
+        """Get the current state of GID/UID output.
 
-        Returns a boolean indicating whether boolean output is active or not.
+        Returns a boolean indicating whether names for group/user IDs are used
+        in output or not.
         """
-        return self.nft_ctx_output_get_numeric(self.__ctx)
+        return self.__get_output_flag("guid")
 
-    def set_numeric_output(self, val):
-        """Enable or disable numeric output.
+    def set_guid_output(self, val):
+        """Enable or disable GID/UID output.
 
-        Accepts a boolean turning numeric output on or off.
+        Accepts a boolean turning names for group/user IDs on or off.
 
         Returns the previous value.
         """
-        old = self.get_numeric_output()
+        return self.__set_output_flag("guid", val)
 
-        if type(val) is str:
-            val = self.numeric_levels[val]
-        self.nft_ctx_output_set_numeric(self.__ctx, val)
+    def get_numeric_proto_output(self):
+        """Get current status of numeric protocol output flag.
 
-        return old
+        Returns a boolean value indicating the status.
+        """
+        return self.__get_output_flag("numeric_proto")
 
-    def get_stateless_output(self):
-        """Get the current state of stateless output.
+    def set_numeric_proto_output(self, val):
+        """Set numeric protocol output flag.
 
-        Returns a boolean indicating whether stateless output is active or not.
+        Accepts a boolean turning numeric protocol output either on or off.
+
+        Returns the previous value.
         """
-        return self.nft_ctx_output_get_stateless(self.__ctx)
+        return self.__set_output_flag("numeric_proto", val)
 
-    def set_stateless_output(self, val):
-        """Enable or disable stateless output.
+    def get_numeric_prio_output(self):
+        """Get current status of numeric chain priority output flag.
 
-        Accepts a boolean turning stateless output either on or off.
+        Returns a boolean value indicating the status.
+        """
+        return self.__get_output_flag("numeric_prio")
+
+    def set_numeric_prio_output(self, val):
+        """Set numeric chain priority output flag.
+
+        Accepts a boolean turning numeric chain priority output either on or
+        off.
 
         Returns the previous value.
         """
-        old = self.get_stateless_output()
-        self.nft_ctx_output_set_stateless(self.__ctx, val)
-        return old
+        return self.__set_output_flag("numeric_prio", val)
 
-    def get_json_output(self):
-        """Get the current state of JSON output.
+    def get_numeric_symbol_output(self):
+        """Get current status of numeric symbols output flag.
 
-        Returns a boolean indicating whether JSON output is active or not.
+        Returns a boolean value indicating the status.
         """
-        return self.nft_ctx_output_get_json(self.__ctx)
+        return self.__get_output_flag("numeric_symbol")
 
-    def set_json_output(self, val):
-        """Enable or disable JSON output.
+    def set_numeric_symbol_output(self, val):
+        """Set numeric symbols output flag.
 
-        Accepts a boolean turning JSON output either on or off.
+        Accepts a boolean turning numeric representation of symbolic constants
+        in output either on or off.
 
         Returns the previous value.
         """
-        old = self.get_json_output()
-        self.nft_ctx_output_set_json(self.__ctx, val)
-        return old
+        return self.__set_output_flag("numeric_symbol", val)
 
     def get_debug(self):
         """Get currently active debug flags.
diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py
index 1837c9c935307..5c7e28a070204 100755
--- a/tests/py/nft-test.py
+++ b/tests/py/nft-test.py
@@ -176,7 +176,7 @@  def table_exist(table, filename, lineno):
     Exists a table.
     '''
     cmd = "list table %s" % table
-    ret = execute_cmd(cmd, filename, lineno, numeric="all")
+    ret = execute_cmd(cmd, filename, lineno)
 
     return True if (ret == 0) else False
 
@@ -263,7 +263,7 @@  def chain_exist(chain, table, filename):
     Checks a chain
     '''
     cmd = "list chain %s %s" % (table, chain)
-    ret = execute_cmd(cmd, filename, chain.lineno, numeric="all")
+    ret = execute_cmd(cmd, filename, chain.lineno)
 
     return True if (ret == 0) else False
 
@@ -466,7 +466,7 @@  def set_exist(set_name, table, filename, lineno):
     Check if the set exists.
     '''
     cmd = "list set %s %s" % (table, set_name)
-    ret = execute_cmd(cmd, filename, lineno, numeric="all")
+    ret = execute_cmd(cmd, filename, lineno)
 
     return True if (ret == 0) else False
 
@@ -476,7 +476,7 @@  def _set_exist(s, filename, lineno):
     Check if the set exists.
     '''
     cmd = "list set %s %s %s" % (s.family, s.table, s.name)
-    ret = execute_cmd(cmd, filename, lineno, numeric="all")
+    ret = execute_cmd(cmd, filename, lineno)
 
     return True if (ret == 0) else False
 
@@ -584,7 +584,7 @@  def obj_exist(o, table, filename, lineno):
     Check if the object exists.
     '''
     cmd = "list %s %s %s" % (o.type, table, o.name)
-    ret = execute_cmd(cmd, filename, lineno, numeric="all")
+    ret = execute_cmd(cmd, filename, lineno)
 
     return True if (ret == 0) else False
 
@@ -594,7 +594,7 @@  def _obj_exist(o, filename, lineno):
     Check if the object exists.
     '''
     cmd = "list %s %s %s %s" % (o.type, o.family, o.table, o.name)
-    ret = execute_cmd(cmd, filename, lineno, numeric="all")
+    ret = execute_cmd(cmd, filename, lineno)
 
     return True if (ret == 0) else False
 
@@ -805,11 +805,11 @@  def rule_add(rule, filename, lineno, force_all_family_option, filename_path):
                               gotf.name, 1)
 
             # Check for matching ruleset listing
-            numeric_old = nftables.set_numeric_output("all")
+            numeric_proto_old = nftables.set_numeric_proto_output(True)
             stateless_old = nftables.set_stateless_output(True)
             list_cmd = 'list table %s' % table
             rc, pre_output, err = nftables.cmd(list_cmd)
-            nftables.set_numeric_output(numeric_old)
+            nftables.set_numeric_proto_output(numeric_proto_old)
             nftables.set_stateless_output(stateless_old)
 
             output = pre_output.split(";")
@@ -937,12 +937,12 @@  def rule_add(rule, filename, lineno, force_all_family_option, filename_path):
                               gotf.name, 1)
 
             # Check for matching ruleset listing
-            numeric_old = nftables.set_numeric_output("all")
+            numeric_proto_old = nftables.set_numeric_proto_output(True)
             stateless_old = nftables.set_stateless_output(True)
             json_old = nftables.set_json_output(True)
             rc, json_output, err = nftables.cmd(list_cmd)
             nftables.set_json_output(json_old)
-            nftables.set_numeric_output(numeric_old)
+            nftables.set_numeric_proto_output(numeric_proto_old)
             nftables.set_stateless_output(stateless_old)
 
             json_output = json.loads(json_output)
@@ -990,8 +990,7 @@  def signal_handler(signal, frame):
     signal_received = 1
 
 
-def execute_cmd(cmd, filename, lineno,
-                stdout_log=False, numeric=False, debug=False):
+def execute_cmd(cmd, filename, lineno, stdout_log=False, debug=False):
     '''
     Executes a command, checks for segfaults and returns the command exit
     code.
@@ -1000,7 +999,6 @@  def execute_cmd(cmd, filename, lineno,
     :param filename: name of the file tested (used for print_error purposes)
     :param lineno: line number being tested (used for print_error purposes)
     :param stdout_log: redirect stdout to this file instead of global log_file
-    :param numeric: turn numeric output temporarily on
     :param debug: temporarily set these debug flags
     '''
     global log_file
@@ -1008,9 +1006,6 @@  def execute_cmd(cmd, filename, lineno,
     if debug_option:
         print cmd
 
-    if numeric:
-        numeric_old = nftables.get_numeric_output()
-        nftables.set_numeric_output(numeric)
     if debug:
         debug_old = nftables.get_debug()
         nftables.set_debug(debug)
@@ -1025,8 +1020,6 @@  def execute_cmd(cmd, filename, lineno,
     log_file.write(err)
     log_file.flush()
 
-    if numeric:
-        nftables.set_numeric_output(numeric_old)
     if debug:
         nftables.set_debug(debug_old)