Browse Source

OSP-246: Add src_tenant_id and src_segment_id in reachability tests.

When unicode is enabled:
src_tenant_id/src_segment_id is used for src_tenant_name/src_segment in bcf
test path.

When unicode is disabled:
src_tenant_name/src_segment_name is used for src_tenant/src_segment in bcf
test path.

Change-Id: I418fb81cfb6d3d8c691c816dac387d9f1fd2cea2
Weifan Fu 6 months ago
parent
commit
65fe6b3ab1

+ 4
- 2
networking_bigswitch/plugins/bigswitch/bsn_service_plugin.py View File

@@ -182,7 +182,8 @@ class BSNServicePlugin(service_base.ServicePluginBase,
182 182
                 reachabilitytest_data['run_test']:
183 183
             # run test on the controller and get results
184 184
             # update fields in reachabilitytest_data dict
185
-            src = reachabilitytest.get_connection_source()
185
+            src = reachabilitytest.get_connection_source(
186
+                unicode_mode=self.servers.is_unicode_enabled())
186 187
             dst = reachabilitytest.get_connection_destination()
187 188
             response = self.servers.rest_get_testpath(src, dst)
188 189
             test_result, detail, logical_path = self.parse_result(
@@ -244,7 +245,8 @@ class BSNServicePlugin(service_base.ServicePluginBase,
244 245
                 reachabilityquicktest_data['run_test']:
245 246
             # run test on the controller and get results
246 247
             # update fields in reachabilityquicktest_data dict
247
-            src = reachabilityquicktest.get_connection_source()
248
+            src = reachabilityquicktest.get_connection_source(
249
+                unicode_mode=self.servers.is_unicode_enabled())
248 250
             dst = reachabilityquicktest.get_connection_destination()
249 251
             response = self.servers.rest_get_testpath(src, dst)
250 252
             test_result, detail, logical_path = self.parse_result(

+ 69
- 0
networking_bigswitch/plugins/bigswitch/db/migration/alembic_migrations/versions/938c3e0e2029_add_tenant_segment_id_for_reachability_.py View File

@@ -0,0 +1,69 @@
1
+# Copyright 2017, Big Switch Networks
2
+# All Rights Reserved.
3
+#
4
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
5
+#    not use this file except in compliance with the License. You may obtain
6
+#    a copy of the License at
7
+#
8
+#         http://www.apache.org/licenses/LICENSE-2.0
9
+#
10
+#    Unless required by applicable law or agreed to in writing, software
11
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+#    License for the specific language governing permissions and limitations
14
+#    under the License.
15
+
16
+"""add tenant/segment id for reachability tests
17
+
18
+Revision ID: 938c3e0e2029
19
+Revises:
20
+Create Date: 2018-10-15 11:04:57.644914
21
+
22
+"""
23
+from alembic import op
24
+import sqlalchemy as sa
25
+
26
+
27
+# revision identifiers, used by Alembic.
28
+revision = '938c3e0e2029'
29
+down_revision = '7db8cd315b95'
30
+branch_labels = None
31
+depends_on = None
32
+
33
+
34
+def upgrade():
35
+    # reachability test
36
+    # segment name can be empty for uuid based schema (supported queens/5.0)
37
+    op.alter_column(
38
+        table_name='reachabilitytest',
39
+        column_name='src_segment_name',
40
+        existing_type=sa.String(255, convert_unicode=True),
41
+        nullable=True)
42
+
43
+    # If unicode is off, tenant id can be empty
44
+    op.add_column('reachabilitytest',
45
+                  sa.Column('src_tenant_id', sa.String(36), nullable=True))
46
+
47
+    # If unicode is off, segment id can be empty
48
+    op.add_column('reachabilitytest',
49
+                  sa.Column('src_segment_id', sa.String(36), nullable=True))
50
+
51
+    # reachability quick test
52
+    # segment name can be empty for uuid based schema (supported queens/5.0)
53
+    op.alter_column(
54
+        table_name='reachabilityquicktest',
55
+        column_name='src_segment_name',
56
+        existing_type=sa.String(255),
57
+        nullable=True)
58
+
59
+    # If unicode is off, tenant id can be empty
60
+    op.add_column('reachabilityquicktest',
61
+                  sa.Column('src_tenant_id', sa.String(36), nullable=True))
62
+
63
+    # If unicode is off, segment id can be empty
64
+    op.add_column('reachabilityquicktest',
65
+                  sa.Column('src_segment_id', sa.String(36), nullable=True))
66
+
67
+
68
+def downgrade():
69
+    pass

+ 1
- 1
networking_bigswitch/plugins/bigswitch/db/migration/alembic_migrations/versions/HEAD View File

@@ -1 +1 @@
1
-7db8cd315b95
1
+938c3e0e2029

+ 65
- 13
networking_bigswitch/plugins/bigswitch/db/reachability_test_db.py View File

@@ -55,8 +55,10 @@ class ReachabilityTest(model_base.BASEV2,
55 55
     """
56 56
     __tablename__ = 'reachabilitytest'
57 57
     name = sa.Column(sa.String(64), nullable=False, unique=True)
58
+    src_tenant_id = sa.Column(sa.String(length=36), nullable=True)
58 59
     src_tenant_name = sa.Column(sa.String(255), nullable=False)
59
-    src_segment_name = sa.Column(sa.String(255), nullable=False)
60
+    src_segment_id = sa.Column(sa.String(length=36), nullable=True)
61
+    src_segment_name = sa.Column(sa.String(255), nullable=True)
60 62
     src_ip = sa.Column(sa.String(16), nullable=False)
61 63
     dst_ip = sa.Column(sa.String(16), nullable=False)
62 64
     expected_result = sa.Column(Enum("dropped by route",
@@ -80,10 +82,23 @@ class ReachabilityTest(model_base.BASEV2,
80 82
     logical_path = sa.Column(JSONEncodedDict(8192), nullable=True)
81 83
     run_test = sa.Column(sa.Boolean, nullable=False, default=False)
82 84
 
83
-    def get_connection_source(self):
85
+    def get_connection_source(self, unicode_mode=False):
84 86
         source = {}
85
-        source['tenant'] = Util.format_resource_name(self.src_tenant_name)
86
-        source['segment'] = Util.format_resource_name(self.src_segment_name)
87
+        if unicode_mode:
88
+            if not self.src_tenant_id:
89
+                raise ReachabilityTestUnicodeTenantIdMissing(
90
+                    test_name=self.name)
91
+            source['tenant'] = self.src_tenant_id
92
+            if not self.src_segment_id:
93
+                raise ReachabilityTestUnicodeSegmentIdMissing(
94
+                    test_name=self.name)
95
+            source['segment'] = self.src_segment_id
96
+        else:
97
+            source['tenant'] = Util.format_resource_name(self.src_tenant_name)
98
+            if not self.src_segment_name:
99
+                raise ReachabilityTestSegmentNameMissing(test_name=self.name)
100
+            source['segment'] = Util.format_resource_name(
101
+                self.src_segment_name)
87 102
         source['ip'] = self.src_ip
88 103
         return source
89 104
 
@@ -97,6 +112,21 @@ class ReachabilityTestNotFound(exceptions.NotFound):
97 112
     message = _("Reachability Test %(id)s could not be found")
98 113
 
99 114
 
115
+class ReachabilityTestUnicodeTenantIdMissing(exceptions.NeutronException):
116
+    message = _("Source Tenant ID is required when Unicode is ENABLED. "
117
+                "Please update Test %(test_name)s.")
118
+
119
+
120
+class ReachabilityTestUnicodeSegmentIdMissing(exceptions.NeutronException):
121
+    message = _("Source Segment ID is required when Unicode is ENABLED. "
122
+                "Please update Test %(test_name)s.")
123
+
124
+
125
+class ReachabilityTestSegmentNameMissing(exceptions.NeutronException):
126
+    message = _("Source Segment Name is required when Unicode is DISABLED. "
127
+                "Please recreate the network and update Test %(test_name)s.")
128
+
129
+
100 130
 class ReachabilityTestDbMixin(common_db_mixin.CommonDbMixin):
101 131
     # internal methods
102 132
     def _make_reachabilitytest_dict(self, reachabilitytest, fields=None):
@@ -104,7 +134,9 @@ class ReachabilityTestDbMixin(common_db_mixin.CommonDbMixin):
104 134
             'id': reachabilitytest.id,
105 135
             'tenant_id': reachabilitytest.tenant_id,
106 136
             'name': reachabilitytest.name,
137
+            'src_tenant_id': reachabilitytest.src_tenant_id,
107 138
             'src_tenant_name': reachabilitytest.src_tenant_name,
139
+            'src_segment_id': reachabilitytest.src_segment_id,
108 140
             'src_segment_name': reachabilitytest.src_segment_name,
109 141
             'src_ip': reachabilitytest.src_ip,
110 142
             'dst_ip': reachabilitytest.dst_ip,
@@ -143,7 +175,9 @@ class ReachabilityTestDbMixin(common_db_mixin.CommonDbMixin):
143 175
             reachabilitytest = ReachabilityTest(
144 176
                 tenant_id=reachabilitytest_data['tenant_id'],
145 177
                 name=reachabilitytest_data['name'],
178
+                src_tenant_id=reachabilitytest_data.get('src_tenant_id'),
146 179
                 src_tenant_name=reachabilitytest_data['src_tenant_name'],
180
+                src_segment_id=reachabilitytest_data.get('src_segment_id'),
147 181
                 src_segment_name=reachabilitytest_data['src_segment_name'],
148 182
                 src_ip=reachabilitytest_data['src_ip'],
149 183
                 dst_ip=reachabilitytest_data['dst_ip'],
@@ -157,7 +191,9 @@ class ReachabilityTestDbMixin(common_db_mixin.CommonDbMixin):
157 191
             reachabilitytest = ReachabilityTest(
158 192
                 tenant_id=reachabilitytest_data['tenant_id'],
159 193
                 name=reachabilitytest_data['name'],
194
+                src_tenant_id=reachabilitytest_data.get('src_tenant_id'),
160 195
                 src_tenant_name=reachabilitytest_data['src_tenant_name'],
196
+                src_segment_id=reachabilitytest_data.get('src_segment_id'),
161 197
                 src_segment_name=reachabilitytest_data['src_segment_name'],
162 198
                 src_ip=reachabilitytest_data['src_ip'],
163 199
                 dst_ip=reachabilitytest_data['dst_ip'],
@@ -190,8 +226,10 @@ class ReachabilityQuickTest(model_base.BASEV2,
190 226
     """
191 227
     __tablename__ = 'reachabilityquicktest'
192 228
     name = sa.Column(sa.String(64), nullable=False, unique=True)
229
+    src_tenant_id = sa.Column(sa.String(length=36), nullable=True)
193 230
     src_tenant_name = sa.Column(sa.String(255), nullable=False)
194
-    src_segment_name = sa.Column(sa.String(255), nullable=False)
231
+    src_segment_id = sa.Column(sa.String(length=36), nullable=True)
232
+    src_segment_name = sa.Column(sa.String(255), nullable=True)
195 233
     src_ip = sa.Column(sa.String(16), nullable=False)
196 234
     dst_ip = sa.Column(sa.String(16), nullable=False)
197 235
     expected_result = sa.Column(Enum("dropped by route",
@@ -216,10 +254,24 @@ class ReachabilityQuickTest(model_base.BASEV2,
216 254
     run_test = sa.Column(sa.Boolean, nullable=False, default=False)
217 255
     save_test = sa.Column(sa.Boolean, nullable=False, default=False)
218 256
 
219
-    def get_connection_source(self):
257
+    def get_connection_source(self, unicode_mode=False):
220 258
         source = {}
221
-        source['tenant'] = Util.format_resource_name(self.src_tenant_name)
222
-        source['segment'] = Util.format_resource_name(self.src_segment_name)
259
+        if unicode_mode:
260
+            if not self.src_tenant_id:
261
+                raise ReachabilityTestUnicodeTenantIdMissing(
262
+                    test_name=self.name)
263
+            source['tenant'] = self.src_tenant_id
264
+            if not self.src_segment_id:
265
+                raise ReachabilityTestUnicodeSegmentIdMissing(
266
+                    test_name=self.name)
267
+            source['segment'] = self.src_segment_id
268
+        else:
269
+            source['tenant'] = Util.format_resource_name(self.src_tenant_name)
270
+            if not self.src_segment_name:
271
+                raise ReachabilityTestSegmentNameMissing(
272
+                    test_name=self.name)
273
+            source['segment'] = Util.format_resource_name(
274
+                self.src_segment_name)
223 275
         source['ip'] = self.src_ip
224 276
         return source
225 277
 
@@ -229,10 +281,6 @@ class ReachabilityQuickTest(model_base.BASEV2,
229 281
         return destination
230 282
 
231 283
 
232
-class ReachabilityQuickTestNotFound(exceptions.NotFound):
233
-    message = _("Reachability Quick Test %(id)s could not be found")
234
-
235
-
236 284
 class ReachabilityQuickTestDbMixin(common_db_mixin.CommonDbMixin):
237 285
     # internal methods
238 286
     def _make_reachabilityquicktest_dict(self, reachabilityquicktest,
@@ -241,7 +289,9 @@ class ReachabilityQuickTestDbMixin(common_db_mixin.CommonDbMixin):
241 289
             'id': reachabilityquicktest.id,
242 290
             'tenant_id': reachabilityquicktest.tenant_id,
243 291
             'name': reachabilityquicktest.name,
292
+            'src_tenant_id': reachabilityquicktest.src_tenant_id,
244 293
             'src_tenant_name': reachabilityquicktest.src_tenant_name,
294
+            'src_segment_id': reachabilityquicktest.src_segment_id,
245 295
             'src_segment_name': reachabilityquicktest.src_segment_name,
246 296
             'src_ip': reachabilityquicktest.src_ip,
247 297
             'dst_ip': reachabilityquicktest.dst_ip,
@@ -257,7 +307,7 @@ class ReachabilityQuickTestDbMixin(common_db_mixin.CommonDbMixin):
257 307
             reachabilityquicktest = self._get_by_id(
258 308
                 context, ReachabilityQuickTest, id)
259 309
         except exc.NoResultFound:
260
-            raise ReachabilityQuickTestNotFound(id=id)
310
+            raise ReachabilityTestNotFound(id=id)
261 311
         return reachabilityquicktest
262 312
 
263 313
     # public CRUD methods for Reachability Quick Test
@@ -283,7 +333,9 @@ class ReachabilityQuickTestDbMixin(common_db_mixin.CommonDbMixin):
283 333
                 id=quicktest_data['tenant_id'],
284 334
                 tenant_id=quicktest_data['tenant_id'],
285 335
                 name=quicktest_data['name'],
336
+                src_tenant_id=quicktest_data.get('src_tenant_id'),
286 337
                 src_tenant_name=quicktest_data['src_tenant_name'],
338
+                src_segment_id=quicktest_data.get('src_segment_id'),
287 339
                 src_segment_name=quicktest_data['src_segment_name'],
288 340
                 src_ip=quicktest_data['src_ip'],
289 341
                 dst_ip=quicktest_data['dst_ip'],

+ 12
- 0
networking_bigswitch/plugins/bigswitch/extensions/bsnserviceextension.py View File

@@ -66,9 +66,15 @@ RESOURCE_ATTRIBUTE_MAP = {
66 66
         'name': {'allow_post': True, 'allow_put': True,
67 67
                  'validate': {'type:string': None},
68 68
                  'is_visible': True},
69
+        'src_tenant_id': {'allow_post': True, 'allow_put': True,
70
+                          'validate': {'type:string': None},
71
+                          'is_visible': True},
69 72
         'src_tenant_name': {'allow_post': True, 'allow_put': True,
70 73
                             'validate': {'type:string': None},
71 74
                             'is_visible': True},
75
+        'src_segment_id': {'allow_post': True, 'allow_put': True,
76
+                           'validate': {'type:string': None},
77
+                           'is_visible': True},
72 78
         'src_segment_name': {'allow_post': True, 'allow_put': True,
73 79
                              'validate': {'type:string': None},
74 80
                              'is_visible': True},
@@ -99,9 +105,15 @@ RESOURCE_ATTRIBUTE_MAP = {
99 105
         'name': {'allow_post': True, 'allow_put': True,
100 106
                  'validate': {'type:string': None},
101 107
                  'is_visible': True},
108
+        'src_tenant_id': {'allow_post': True, 'allow_put': True,
109
+                          'validate': {'type:string': None},
110
+                          'is_visible': True},
102 111
         'src_tenant_name': {'allow_post': True, 'allow_put': True,
103 112
                             'validate': {'type:string': None},
104 113
                             'is_visible': True},
114
+        'src_segment_id': {'allow_post': True, 'allow_put': True,
115
+                           'validate': {'type:string': None},
116
+                           'is_visible': True},
105 117
         'src_segment_name': {'allow_post': True, 'allow_put': True,
106 118
                              'validate': {'type:string': None},
107 119
                              'is_visible': True},

+ 26
- 8
networking_bigswitch/plugins/bigswitch/neutronclient/v2_0/_bsn_plugin_client.py View File

@@ -183,9 +183,15 @@ def _reachabilitytest_updatable_args(parser):
183 183
     parser.add_argument(
184 184
         'name',
185 185
         help=_('Name of this reachability test.'))
186
+    parser.add_argument(
187
+        'src_tenant_id', metavar='src-tenant-id',
188
+        help=_('Tenant ID of the src-ip.'))
186 189
     parser.add_argument(
187 190
         'src_tenant_name', metavar='src-tenant-name',
188 191
         help=_('Tenant name of the src-ip.'))
192
+    parser.add_argument(
193
+        'src_segment_id', metavar='src-segment-id',
194
+        help=_('Network id of the src-ip.'))
189 195
     parser.add_argument(
190 196
         'src_segment_name', metavar='src-segment-name',
191 197
         help=_('Network name of the src-ip.'))
@@ -209,8 +215,12 @@ def _reachabilitytest_updatable_args2body(parsed_args, body, client):
209 215
     if parsed_args.name:
210 216
         body['name'] = parsed_args.name
211 217
     if parsed_args.src_tenant_id:
218
+        body['src_tenant_id'] = parsed_args.src_tenant_id
219
+    if parsed_args.src_tenant_name:
212 220
         body['src_tenant_name'] = parsed_args.src_tenant_name
213 221
     if parsed_args.src_segment_id:
222
+        body['src_segment_id'] = parsed_args.src_segment_id
223
+    if parsed_args.src_segment_name:
214 224
         body['src_segment_name'] = parsed_args.src_segment_name
215 225
     if parsed_args.src_ip:
216 226
         body['src_ip'] = parsed_args.src_ip
@@ -232,7 +242,8 @@ class ReachabilityTestsList(extension.ClientExtensionList, ReachabilityTest):
232 242
     """List Reachability Tests."""
233 243
 
234 244
     shell_command = 'reachability-tests-list'
235
-    list_columns = ['id', 'name', 'src_tenant_id', 'src_segment_id',
245
+    list_columns = ['id', 'name', 'src_tenant_id', 'src_tenant_name',
246
+                    'src_segment_id', 'src_segment_name',
236 247
                     'src_ip', 'dst_ip', 'expected_result']
237 248
 
238 249
 
@@ -241,7 +252,8 @@ class ReachabilityTestsCreate(extension.ClientExtensionCreate,
241 252
     """Create a Reachability Test."""
242 253
 
243 254
     shell_command = 'reachability-tests-create'
244
-    list_columns = ['id', 'name', 'src_tenant_id', 'src_segment_id',
255
+    list_columns = ['id', 'name', 'src_tenant_id', 'src_tenant_name',
256
+                    'src_segment_id', 'src_segment_name',
245 257
                     'src_ip', 'dst_ip', 'expected_result']
246 258
 
247 259
     def add_known_arguments(self, parser):
@@ -259,7 +271,8 @@ class ReachabilityTestsUpdate(extension.ClientExtensionUpdate,
259 271
     """Update a Reachability Test."""
260 272
 
261 273
     shell_command = 'reachability-tests-update'
262
-    list_columns = ['id', 'name', 'src_tenant_name', 'src_segment_name',
274
+    list_columns = ['id', 'name', 'src_tenant_id', 'src_tenant_name',
275
+                    'src_segment_id', 'src_segment_name',
263 276
                     'src_ip', 'dst_ip', 'expected_result']
264 277
 
265 278
     def add_known_arguments(self, parser):
@@ -277,7 +290,8 @@ class ReachabilityTestsRun(extension.ClientExtensionUpdate,
277 290
     """Run a Reachability Test."""
278 291
 
279 292
     shell_command = 'reachability-tests-run'
280
-    list_columns = ['id', 'name', 'src_tenant_name', 'src_segment_name',
293
+    list_columns = ['id', 'name', 'src_tenant_id', 'src_tenant_name',
294
+                    'src_segment_id', 'src_segment_name',
281 295
                     'src_ip', 'dst_ip', 'expected_result', 'test_result',
282 296
                     'detail', 'logical_path', 'test_time']
283 297
 
@@ -314,7 +328,8 @@ class ReachabilityQuickTestsList(extension.ClientExtensionList,
314 328
     """List Reachability Quick Tests."""
315 329
 
316 330
     shell_command = 'reachability-quick-tests-list'
317
-    list_columns = ['id', 'name', 'src_tenant_name', 'src_segment_name',
331
+    list_columns = ['id', 'name', 'src_tenant_id', 'src_tenant_name',
332
+                    'src_segment_id', 'src_segment_name',
318 333
                     'src_ip', 'dst_ip', 'expected_result']
319 334
 
320 335
 
@@ -323,7 +338,8 @@ class ReachabilityQuickTestsCreate(extension.ClientExtensionCreate,
323 338
     """Create a Reachability Quick Test."""
324 339
 
325 340
     shell_command = 'reachability-quick-tests-create'
326
-    list_columns = ['id', 'name', 'src_tenant_name', 'src_segment_name',
341
+    list_columns = ['id', 'name', 'src_tenant_id', 'src_tenant_name',
342
+                    'src_segment_id', 'src_segment_name',
327 343
                     'src_ip', 'dst_ip', 'expected_result']
328 344
 
329 345
     def add_known_arguments(self, parser):
@@ -341,7 +357,8 @@ class ReachabilityQuickTestsUpdate(extension.ClientExtensionUpdate,
341 357
     """Update a Reachability Quick Test."""
342 358
 
343 359
     shell_command = 'reachability-quick-tests-update'
344
-    list_columns = ['id', 'name', 'src_tenant_name', 'src_segment_name',
360
+    list_columns = ['id', 'name', 'src_tenant_id', 'src_tenant_name',
361
+                    'src_segment_id', 'src_segment_name',
345 362
                     'src_ip', 'dst_ip', 'expected_result']
346 363
 
347 364
     def add_known_arguments(self, parser):
@@ -359,7 +376,8 @@ class ReachabilityQuickTestsRun(extension.ClientExtensionUpdate,
359 376
     """Run a Reachability Quick Test."""
360 377
 
361 378
     shell_command = 'reachability-quick-tests-run'
362
-    list_columns = ['id', 'name', 'src_tenant_name', 'src_segment_name',
379
+    list_columns = ['id', 'name', 'src_tenant_id', 'src_tenant_name',
380
+                    'src_segment_id', 'src_segment_name',
363 381
                     'src_ip', 'dst_ip', 'expected_result', 'test_result',
364 382
                     'detail', 'logical_path', 'test_time']
365 383
 

+ 2
- 0
networking_bigswitch/tests/unit/bigswitch/test_reachabilityquicktest_db.py View File

@@ -39,7 +39,9 @@ class TestReachabilityQuickTestDbMixin(testlib_api.SqlTestCase):
39 39
             'reachabilityquicktest': {
40 40
                 'tenant_id': 'admin_tenant_id',
41 41
                 'name': 'quicktest',
42
+                'src_tenant_id': 'src_admin_tenant_id',
42 43
                 'src_tenant_name': 'admin',
44
+                'src_segment_id': 'web_segment_id',
43 45
                 'src_segment_name': 'web',
44 46
                 'src_ip': '10.1.1.2',
45 47
                 'dst_ip': '10.2.1.2',

+ 2
- 0
networking_bigswitch/tests/unit/bigswitch/test_reachabilitytest_db.py View File

@@ -39,7 +39,9 @@ class TestReachabilityTestDbMixin(testlib_api.SqlTestCase):
39 39
             'reachabilitytest': {
40 40
                 'tenant_id': 'admin_tenant_id',
41 41
                 'name': 'test1',
42
+                'src_tenant_id': 'admin_tenant_id',
42 43
                 'src_tenant_name': 'admin',
44
+                'src_segment_id': 'web_segment_id',
43 45
                 'src_segment_name': 'web',
44 46
                 'src_ip': '10.1.1.2',
45 47
                 'dst_ip': '10.2.1.2',

Loading…
Cancel
Save