@@ -174,107 +174,100 @@ def _cross(r1,r2):
174
174
175
175
def __rshift__ (c1 , c2 ):
176
176
from pyretic .core .language import match , modify , drop , identity , Controller , CountBucket , DerivedPolicy
177
- def _sequence_actions_classifier (acts , c2 ):
178
- def _sequence_action_classifier (act , c2 ):
179
- # given a test b and an action p, return a test
180
- # b' such that p >> b == b' >> p.
181
- def _commute_test (act , pkts ):
182
- while isinstance (act , DerivedPolicy ):
183
- act = act .policy
184
- if act == identity :
185
- return pkts
186
- elif act == drop :
187
- return drop
188
- elif act == Controller or isinstance (act , CountBucket ):
189
- return identity
190
- elif isinstance (act , modify ):
191
- new_match_dict = {}
192
- if pkts == identity :
193
- return identity
194
- elif pkts == drop :
195
- return drop
196
- for f , v in pkts .map .iteritems ():
197
- if f in act .map and act .map [f ] == v :
198
- continue
199
- elif f in act .map and act .map [f ] != v :
200
- return drop
201
- else :
202
- new_match_dict [f ] = v
203
- if len (new_match_dict ) == 0 :
204
- return identity
205
- return match (** new_match_dict )
206
- else :
207
- # TODO (cole) use compile error.
208
- # TODO (cole) what actions are allowable?
209
- raise TypeError
210
-
211
- # sequentially compose actions. a1 must be a
212
- # single action. Returns a list of actions.
213
- def _sequence_actions (a1 , as2 ):
214
- while isinstance (a1 , DerivedPolicy ):
215
- a1 = a1 .policy
216
- # TODO: be uniform about returning copied or modified objects.
217
- new_actions = []
218
- if a1 == drop :
219
- return [drop ]
220
- elif a1 == identity :
221
- return as2
222
- elif a1 == Controller or isinstance (a1 , CountBucket ):
223
- return [a1 ]
224
- elif isinstance (a1 , modify ):
225
- for a2 in as2 :
226
- while isinstance (a2 , DerivedPolicy ):
227
- a2 = a2 .policy
228
- new_a1 = modify (** a1 .map .copy ())
229
- if a2 == drop :
230
- new_actions .append (drop )
231
- elif a2 == Controller or isinstance (a2 , CountBucket ):
232
- new_actions .append (a2 )
233
- elif a2 == identity :
234
- new_actions .append (new_a1 )
235
- elif isinstance (a2 , modify ):
236
- new_a1 .map .update (a2 .map )
237
- new_actions .append (new_a1 )
238
- else :
239
- raise TypeError
240
- return new_actions
241
- else :
242
- raise TypeError
243
- # END _commute_test and _sequence_actions
244
-
245
- c3 = Classifier ()
246
- for r2 in c2 .rules :
247
- pkts = _commute_test (act , r2 .match )
177
+ def _sequence_action_classifier (act , c2 ):
178
+ # given a test b and an action p, return a test
179
+ # b' such that p >> b == b' >> p.
180
+ def _commute_test (act , pkts ):
181
+ while isinstance (act , DerivedPolicy ):
182
+ act = act .policy
183
+ if act == identity :
184
+ return pkts
185
+ elif act == drop :
186
+ return drop
187
+ elif act == Controller or isinstance (act , CountBucket ):
188
+ return identity
189
+ elif isinstance (act , modify ):
190
+ new_match_dict = {}
248
191
if pkts == identity :
249
- acts = _sequence_actions (act , r2 .actions )
250
- c3 .append (Rule (identity , acts ))
251
- break
192
+ return identity
252
193
elif pkts == drop :
253
- continue
254
- else :
255
- acts = _sequence_actions (act , r2 .actions )
256
- c3 .append (Rule (pkts , acts ))
257
- if len (c3 ) == 0 :
258
- c3 .append (Rule (identity , [drop ]))
259
- return c3
260
-
261
- # END _sequence_action_classifier
262
-
263
- c3 = Classifier ([Rule (identity , [drop ])])
264
- for act in acts :
265
- c3 = c3 + _sequence_action_classifier (act , c2 )
194
+ return drop
195
+ for f , v in pkts .map .iteritems ():
196
+ if f in act .map and act .map [f ] == v :
197
+ continue
198
+ elif f in act .map and act .map [f ] != v :
199
+ return drop
200
+ else :
201
+ new_match_dict [f ] = v
202
+ if len (new_match_dict ) == 0 :
203
+ return identity
204
+ return match (** new_match_dict )
205
+ else :
206
+ # TODO (cole) use compile error.
207
+ # TODO (cole) what actions are allowable?
208
+ raise TypeError
209
+
210
+ # sequentially compose actions. a1 must be a
211
+ # single action. Returns a list of actions.
212
+ def _sequence_actions (a1 , as2 ):
213
+ while isinstance (a1 , DerivedPolicy ):
214
+ a1 = a1 .policy
215
+ # TODO: be uniform about returning copied or modified objects.
216
+ new_actions = []
217
+ if a1 == drop :
218
+ return [drop ]
219
+ elif a1 == identity :
220
+ return as2
221
+ elif a1 == Controller or isinstance (a1 , CountBucket ):
222
+ return [a1 ]
223
+ elif isinstance (a1 , modify ):
224
+ for a2 in as2 :
225
+ while isinstance (a2 , DerivedPolicy ):
226
+ a2 = a2 .policy
227
+ new_a1 = modify (** a1 .map .copy ())
228
+ if a2 == drop :
229
+ new_actions .append (drop )
230
+ elif a2 == Controller or isinstance (a2 , CountBucket ):
231
+ new_actions .append (a2 )
232
+ elif a2 == identity :
233
+ new_actions .append (new_a1 )
234
+ elif isinstance (a2 , modify ):
235
+ new_a1 .map .update (a2 .map )
236
+ new_actions .append (new_a1 )
237
+ else :
238
+ raise TypeError
239
+ return new_actions
240
+ else :
241
+ raise TypeError
242
+ # END _commute_test and _sequence_actions
243
+
244
+ c3 = Classifier ()
245
+ for r2 in c2 .rules :
246
+ pkts = _commute_test (act , r2 .match )
247
+ if pkts == identity :
248
+ acts = _sequence_actions (act , r2 .actions )
249
+ c3 .append (Rule (identity , acts ))
250
+ break
251
+ elif pkts == drop :
252
+ continue
253
+ else :
254
+ acts = _sequence_actions (act , r2 .actions )
255
+ c3 .append (Rule (pkts , acts ))
256
+ if len (c3 ) == 0 :
257
+ c3 .append (Rule (identity , [drop ]))
266
258
return c3
267
259
268
- # END _sequence_actions_classifier
269
-
260
+ # END _sequence_action_classifier
270
261
271
262
# core __rshift__ logic begins here.
272
263
# start with an empty set of rules for the output classifier
273
264
# then for each rule in the first classifier (self)
274
265
c3 = Classifier ()
275
266
for r1 in c1 .rules :
276
267
# sequence the actions in second classifier c2 w/ respect to r1
277
- c2_seqd = _sequence_actions_classifier (r1 .actions , c2 )
268
+ c2_seqd = Classifier ([Rule (identity , [drop ])])
269
+ for act in r1 .actions :
270
+ c2_seqd = c2_seqd + _sequence_action_classifier (act , c2 )
278
271
279
272
# for each rule in the sequenced c2,
280
273
# intersect the rule's match with r1's match
0 commit comments