@@ -288,6 +288,69 @@ def batch_delete_rules(table, batch_rules, ipv6=False, raise_exc=True):
288288 if raise_exc : raise
289289
290290
291+ def encode_iptc_rule (rule_d , ipv6 = False ):
292+ """ Return a Rule(6) object from the input dictionary """
293+ # Sanity check
294+ assert (isinstance (rule_d , dict ))
295+ # Basic rule attributes
296+ rule_attr = ('src' , 'dst' , 'protocol' , 'in-interface' , 'out-interface' , 'fragment' )
297+ iptc_rule = Rule6 () if ipv6 else Rule ()
298+ # Avoid issues with matches that require basic parameters to be configured first
299+ for name in rule_attr :
300+ if name in rule_d :
301+ _iptc_setrule (iptc_rule , name , rule_d [name ])
302+ for name , value in rule_d .items ():
303+ try :
304+ if name in rule_attr :
305+ continue
306+ elif name == 'target' :
307+ _iptc_settarget (iptc_rule , value )
308+ else :
309+ _iptc_setmatch (iptc_rule , name , value )
310+ except Exception as e :
311+ #print('Ignoring unsupported field <{}:{}>'.format(name, value))
312+ continue
313+ return iptc_rule
314+
315+ def decode_iptc_rule (iptc_rule , ipv6 = False ):
316+ """ Return a dictionary representation of the Rule(6) object
317+ Note: host IP addresses are appended their corresponding CIDR """
318+ d = {}
319+ if ipv6 == False and iptc_rule .src != '0.0.0.0/0.0.0.0' :
320+ _ip , _netmask = iptc_rule .src .split ('/' )
321+ _netmask = _netmask_v4_to_cidr (_netmask )
322+ d ['src' ] = '{}/{}' .format (_ip , _netmask )
323+ elif ipv6 == True and iptc_rule .src != '::/0' :
324+ d ['src' ] = iptc_rule .src
325+ if ipv6 == False and iptc_rule .dst != '0.0.0.0/0.0.0.0' :
326+ _ip , _netmask = iptc_rule .dst .split ('/' )
327+ _netmask = _netmask_v4_to_cidr (_netmask )
328+ d ['dst' ] = '{}/{}' .format (_ip , _netmask )
329+ elif ipv6 == True and iptc_rule .dst != '::/0' :
330+ d ['dst' ] = iptc_rule .dst
331+ if iptc_rule .protocol != 'ip' :
332+ d ['protocol' ] = iptc_rule .protocol
333+ if iptc_rule .in_interface is not None :
334+ d ['in-interface' ] = iptc_rule .in_interface
335+ if iptc_rule .out_interface is not None :
336+ d ['out-interface' ] = iptc_rule .out_interface
337+ if ipv6 == False and iptc_rule .fragment :
338+ d ['fragment' ] = iptc_rule .fragment
339+ for m in iptc_rule .matches :
340+ if m .name not in d :
341+ d [m .name ] = m .get_all_parameters ()
342+ elif isinstance (d [m .name ], list ):
343+ d [m .name ].append (m .get_all_parameters ())
344+ else :
345+ d [m .name ] = [d [m .name ], m .get_all_parameters ()]
346+ if iptc_rule .target and iptc_rule .target .name and len (iptc_rule .target .get_all_parameters ()):
347+ name = iptc_rule .target .name .replace ('-' , '_' )
348+ d ['target' ] = {name :iptc_rule .target .get_all_parameters ()}
349+ elif iptc_rule .target and iptc_rule .target .name :
350+ d ['target' ] = iptc_rule .target .name
351+ # Return a filtered dictionary
352+ return _filter_empty_field (d )
353+
291354### INTERNAL FUNCTIONS ###
292355def _iptc_table_available (table , ipv6 = False ):
293356 """ Return True if the table is available, False otherwise """
@@ -357,69 +420,6 @@ def _iptc_settarget(iptc_rule, value):
357420 else :
358421 iptc_target = iptc_rule .create_target (value )
359422
360- def encode_iptc_rule (rule_d , ipv6 = False ):
361- # Sanity check
362- assert (isinstance (rule_d , dict ))
363- # Basic rule attributes
364- rule_attr = ('src' , 'dst' , 'protocol' , 'in-interface' , 'out-interface' , 'fragment' )
365- iptc_rule = Rule6 () if ipv6 else Rule ()
366- # Avoid issues with matches that require basic parameters to be configured first
367- for name in rule_attr :
368- if name in rule_d :
369- _iptc_setrule (iptc_rule , name , rule_d [name ])
370- for name , value in rule_d .items ():
371- try :
372- if name in rule_attr :
373- #_iptc_setrule(iptc_rule, name, value)
374- continue
375- elif name == 'target' :
376- _iptc_settarget (iptc_rule , value )
377- else :
378- _iptc_setmatch (iptc_rule , name , value )
379- except Exception as e :
380- #print('Ignoring unsupported field <{}:{}>'.format(name, value))
381- continue
382- return iptc_rule
383-
384- def decode_iptc_rule (iptc_rule , ipv6 = False ):
385- """ Return a dictionary representation of an iptc_rule
386- Note: host IP addresses are appended their corresponding CIDR """
387- d = {}
388- if ipv6 == False and iptc_rule .src != '0.0.0.0/0.0.0.0' :
389- _ip , _netmask = iptc_rule .src .split ('/' )
390- _netmask = _netmask_v4_to_cidr (_netmask )
391- d ['src' ] = '{}/{}' .format (_ip , _netmask )
392- elif ipv6 == True and iptc_rule .src != '::/0' :
393- d ['src' ] = iptc_rule .src
394- if ipv6 == False and iptc_rule .dst != '0.0.0.0/0.0.0.0' :
395- _ip , _netmask = iptc_rule .dst .split ('/' )
396- _netmask = _netmask_v4_to_cidr (_netmask )
397- d ['dst' ] = '{}/{}' .format (_ip , _netmask )
398- elif ipv6 == True and iptc_rule .dst != '::/0' :
399- d ['dst' ] = iptc_rule .dst
400- if iptc_rule .protocol != 'ip' :
401- d ['protocol' ] = iptc_rule .protocol
402- if iptc_rule .in_interface is not None :
403- d ['in-interface' ] = iptc_rule .in_interface
404- if iptc_rule .out_interface is not None :
405- d ['out-interface' ] = iptc_rule .out_interface
406- if ipv6 == False and iptc_rule .fragment :
407- d ['fragment' ] = iptc_rule .fragment
408- for m in iptc_rule .matches :
409- if m .name not in d :
410- d [m .name ] = m .get_all_parameters ()
411- elif isinstance (d [m .name ], list ):
412- d [m .name ].append (m .get_all_parameters ())
413- else :
414- d [m .name ] = [d [m .name ], m .get_all_parameters ()]
415- if iptc_rule .target and iptc_rule .target .name and len (iptc_rule .target .get_all_parameters ()):
416- name = iptc_rule .target .name .replace ('-' , '_' )
417- d ['target' ] = {name :iptc_rule .target .get_all_parameters ()}
418- elif iptc_rule .target and iptc_rule .target .name :
419- d ['target' ] = iptc_rule .target .name
420- # Return a filtered dictionary
421- return _filter_empty_field (d )
422-
423423def _batch_begin_table (table , ipv6 = False ):
424424 """ Disable autocommit on a table """
425425 iptc_table = _iptc_gettable (table , ipv6 )
0 commit comments