1414class Firewall (OpenWrtConverter ):
1515 netjson_key = "firewall"
1616 intermediate_key = "firewall"
17- _uci_types = ["defaults" , "forwarding" , "zone" , "rule" ]
17+ _uci_types = ["defaults" , "forwarding" , "zone" , "rule" , "redirect" ]
1818 _schema = schema ["properties" ]["firewall" ]
1919
2020 def to_intermediate_loop (self , block , result , index = None ):
2121 forwardings = self .__intermediate_forwardings (block .pop ("forwardings" , {}))
2222 zones = self .__intermediate_zones (block .pop ("zones" , {}))
2323 rules = self .__intermediate_rules (block .pop ("rules" , {}))
24+ redirects = self .__intermediate_redirects (block .pop ("redirects" , {}))
2425 block .update ({".type" : "defaults" , ".name" : block .pop ("id" , "defaults" )})
2526 result .setdefault ("firewall" , [])
26- result ["firewall" ] = [self .sorted_dict (block )] + forwardings + zones + rules
27+ result ["firewall" ] = (
28+ [self .sorted_dict (block )] + forwardings + zones + rules + redirects
29+ )
2730 return result
2831
2932 def __intermediate_forwardings (self , forwardings ):
@@ -104,6 +107,37 @@ def __intermediate_rules(self, rules):
104107 def __get_auto_name_rule (self , rule ):
105108 return "rule_{0}" .format (self ._get_uci_name (rule ["name" ]))
106109
110+ def __intermediate_redirects (self , redirects ):
111+ """
112+ converts NetJSON redirect to
113+ UCI intermediate data structure
114+ """
115+ result = []
116+ for redirect in redirects :
117+ if "config_name" in redirect :
118+ del redirect ["config_name" ]
119+ resultdict = OrderedDict (
120+ (
121+ (".name" , self .__get_auto_name_redirect (redirect )),
122+ (".type" , "redirect" ),
123+ )
124+ )
125+ if "proto" in redirect :
126+ # If proto is a single value, then force it not to be in a list so that
127+ # the UCI uses "option" rather than "list". If proto is only "tcp"
128+ # and"udp", we can force it to the single special value of "tcpudp".
129+ proto = redirect ["proto" ]
130+ if len (proto ) == 1 :
131+ redirect ["proto" ] = proto [0 ]
132+ elif set (proto ) == {"tcp" , "udp" }:
133+ redirect ["proto" ] = "tcpudp"
134+ resultdict .update (redirect )
135+ result .append (resultdict )
136+ return result
137+
138+ def __get_auto_name_redirect (self , redirect ):
139+ return "redirect_{0}" .format (self ._get_uci_name (redirect ["name" ]))
140+
107141 def to_netjson_loop (self , block , result , index ):
108142 result .setdefault ("firewall" , {})
109143
@@ -122,6 +156,10 @@ def to_netjson_loop(self, block, result, index):
122156 forwarding = self .__netjson_forwarding (block )
123157 result ["firewall" ].setdefault ("forwardings" , [])
124158 result ["firewall" ]["forwardings" ].append (forwarding )
159+ if _type == "redirect" :
160+ redirect = self .__netjson_redirect (block )
161+ result ["firewall" ].setdefault ("redirects" , [])
162+ result ["firewall" ]["redirects" ].append (redirect )
125163
126164 return self .type_cast (result )
127165
@@ -156,3 +194,14 @@ def __netjson_zone(self, zone):
156194
157195 def __netjson_forwarding (self , forwarding ):
158196 return self .type_cast (forwarding )
197+
198+ def __netjson_redirect (self , redirect ):
199+ if "proto" in redirect :
200+ proto = redirect .pop ("proto" )
201+ if not isinstance (proto , list ):
202+ if proto == "tcpudp" :
203+ redirect ["proto" ] = ["tcp" , "udp" ]
204+ else :
205+ redirect ["proto" ] = [proto ]
206+
207+ return self .type_cast (redirect )
0 commit comments