urpf: add interface dump to API

Add an urpf_interface_dump() API call, with optional sw_if_index.
If either a mode or a table is specified in any given interface
address family and direction, return it in a list, otherwise omit
it.

TESTED:
create loopback interface instance 0
create loopback interface instance 1
create loopback interface instance 2
create loopback interface instance 3
ip6 table add 8298
set urpf ip4 rx loose loop1
set urpf ip6 tx off loop2 table 8298

API call urpf_interface_dump(sw_if_index=~1) returns:
[
urpf_interface_details(_0=658, context=2, sw_if_index=2, is_rx=True, mode=<vl_api_urpf_mode_t.URPF_API_MODE_LOOSE: 1>, af=<vl_api_address_family_t.ADDRESS_IP4: 0>, table_id=0),
urpf_interface_details(_0=658, context=2, sw_if_index=3, is_rx=False, mode=<vl_api_urpf_mode_t.URPF_API_MODE_OFF: 0>, af=<vl_api_address_family_t.ADDRESS_IP6: 1>, table_id=8298)
]

Type: improvement
Change-Id: I1ded5c445dc07dab73ea41b817b5827b72ca79d4
Signed-off-by: pim@ipng.nl
diff --git a/test/test_urpf.py b/test/test_urpf.py
index 0eb8b05..1e4a6c5 100644
--- a/test/test_urpf.py
+++ b/test/test_urpf.py
@@ -317,6 +317,61 @@
             sw_if_index=self.pg1.sw_if_index,
         )
 
+    def test_interface_dump(self):
+        """uRPF Interface Dump"""
+
+        self.create_loopback_interfaces(3)
+        e = VppEnum
+        self.vapi.urpf_update(
+            is_input=True,
+            mode=e.vl_api_urpf_mode_t.URPF_API_MODE_STRICT,
+            af=e.vl_api_address_family_t.ADDRESS_IP4,
+            sw_if_index=self.loop1.sw_if_index,
+        )
+        self.vapi.urpf_update(
+            is_input=False,
+            mode=e.vl_api_urpf_mode_t.URPF_API_MODE_LOOSE,
+            af=e.vl_api_address_family_t.ADDRESS_IP6,
+            sw_if_index=self.loop2.sw_if_index,
+        )
+
+        ret = self.vapi.urpf_interface_dump()
+        self.assertEqual(len(ret), 2)
+
+        dump_loop1 = ret[0]
+        dump_loop2 = ret[1]
+        self.assertEqual(dump_loop1.sw_if_index, self.loop1.sw_if_index)
+        self.assertTrue(dump_loop1.is_input)
+        self.assertEqual(dump_loop1.mode, e.vl_api_urpf_mode_t.URPF_API_MODE_STRICT)
+        self.assertEqual(dump_loop1.af, e.vl_api_address_family_t.ADDRESS_IP4)
+        self.assertEqual(dump_loop2.sw_if_index, self.loop2.sw_if_index)
+        self.assertFalse(dump_loop2.is_input)
+        self.assertEqual(dump_loop2.mode, e.vl_api_urpf_mode_t.URPF_API_MODE_LOOSE)
+        self.assertEqual(dump_loop2.af, e.vl_api_address_family_t.ADDRESS_IP6)
+
+        ret = self.vapi.urpf_interface_dump(sw_if_index=self.loop1.sw_if_index)
+        self.assertEqual(len(ret), 1)
+
+        dump_loop1 = ret[0]
+        self.assertEqual(dump_loop1.sw_if_index, self.loop1.sw_if_index)
+        self.assertTrue(dump_loop1.is_input)
+        self.assertEqual(dump_loop1.mode, e.vl_api_urpf_mode_t.URPF_API_MODE_STRICT)
+        self.assertEqual(dump_loop1.af, e.vl_api_address_family_t.ADDRESS_IP4)
+
+        # cleanup
+        self.vapi.urpf_update(
+            is_input=False,
+            mode=e.vl_api_urpf_mode_t.URPF_API_MODE_OFF,
+            af=e.vl_api_address_family_t.ADDRESS_IP4,
+            sw_if_index=self.loop1.sw_if_index,
+        )
+        self.vapi.urpf_update(
+            is_input=False,
+            mode=e.vl_api_urpf_mode_t.URPF_API_MODE_OFF,
+            af=e.vl_api_address_family_t.ADDRESS_IP6,
+            sw_if_index=self.loop2.sw_if_index,
+        )
+
 
 if __name__ == "__main__":
     unittest.main(testRunner=VppTestRunner)