Skip to content
This repository was archived by the owner on Jun 27, 2018. It is now read-only.

Commit 9408f83

Browse files
author
Joshua Reich
committed
change Rule actions from list to set
1 parent feb20a5 commit 9408f83

File tree

2 files changed

+28
-27
lines changed

2 files changed

+28
-27
lines changed

pyretic/core/classifier.py

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ class Rule(object):
1212
Pyretic actions.
1313
"""
1414

15-
# Matches m should be of the match class. Actions acts should be a list of
16-
# either modify, identity, or drop policies.
15+
# Matches m should be of the match class. Actions acts should be a set of
16+
# modify, identity, drop, and/or Controller/CountBucket/FwdBucket policies.
17+
# Actions is Rule are semantically meant to run in parallel
18+
# unlike OpenFlow rules.
1719
def __init__(self,m,acts):
1820
self.match = m
1921
self.actions = acts
@@ -127,11 +129,11 @@ def __invert__(self):
127129
from pyretic.core.language import drop, identity
128130
c = copy.copy(self)
129131
for r in c.rules:
130-
assert len(set(r.actions)) == 1
131-
if r.actions[0] == identity:
132-
r.actions = [drop]
133-
elif r.actions[0] == drop:
134-
r.actions = [identity]
132+
assert len(r.actions) == 1
133+
if r.actions == {identity}:
134+
r.actions = {drop}
135+
elif r.actions == {drop}:
136+
r.actions = {identity}
135137
else:
136138
raise TypeError # TODO MAKE A CompileError TYPE
137139
return c
@@ -146,10 +148,9 @@ def _cross(r1,r2):
146148
if intersection != drop:
147149
# TODO (josh) logic for detecting when sets of actions can't be combined
148150
# e.g., [modify(dstip='10.0.0.1'),fwd(1)] + [modify(srcip='10.0.0.2'),fwd(2)]
149-
actions = r1.actions + r2.actions
150-
actions = filter(lambda a: a != drop,actions)
151-
if len(actions) == 0:
152-
actions = [drop]
151+
actions = r1.actions | r2.actions
152+
if len(actions) > 1:
153+
actions.discard(drop)
153154
return Rule(intersection, actions)
154155
else:
155156
return None
@@ -165,7 +166,7 @@ def _cross(r1,r2):
165166
c3.append(crossed_r)
166167
# if the classifier is empty, add a drop-all rule
167168
if len(c3) == 0:
168-
c3.append(Rule(identity,[drop]))
169+
c3.append(Rule(identity,{drop}))
169170
# and optimize the classifier
170171
else:
171172
c3 = c3.optimize()
@@ -214,27 +215,27 @@ def _sequence_actions(a1, as2):
214215
while isinstance(a1, DerivedPolicy):
215216
a1 = a1.policy
216217
# TODO: be uniform about returning copied or modified objects.
217-
new_actions = []
218218
if a1 == drop:
219-
return [drop]
219+
return {drop}
220220
elif a1 == Controller or isinstance(a1, CountBucket):
221-
return [a1]
221+
return {a1}
222222
elif a1 == identity:
223223
return as2
224224
elif isinstance(a1, modify):
225+
new_actions = set()
225226
for a2 in as2:
226227
while isinstance(a2, DerivedPolicy):
227228
a2 = a2.policy
228229
if a2 == drop:
229-
new_actions.append(drop)
230+
new_actions.add(drop)
230231
elif a2 == Controller or isinstance(a2, CountBucket):
231-
new_actions.append(a2)
232+
new_actions.add(a2)
232233
elif a2 == identity:
233-
new_actions.append(a1)
234+
new_actions.add(a1)
234235
elif isinstance(a2, modify):
235236
new_a1 = modify(**a1.map.copy())
236237
new_a1.map.update(a2.map)
237-
new_actions.append(new_a1)
238+
new_actions.add(new_a1)
238239
else:
239240
raise TypeError
240241
return new_actions
@@ -246,7 +247,7 @@ def _sequence_actions(a1, as2):
246247
def _cross_act(r1,act,r2):
247248
m = r1.match.intersect(_commute_test(act, r2.match))
248249
actions = _sequence_actions(act,r2.actions)
249-
if actions == [drop]:
250+
if actions == {drop}:
250251
return Classifier([Rule(r1.match,actions)])
251252
elif m == drop:
252253
return None

pyretic/core/language.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ def compile(self):
218218
return self.__class__._classifier
219219

220220
def generate_classifier(self):
221-
return Classifier([Rule(identity, [self])])
221+
return Classifier([Rule(identity, {self})])
222222

223223

224224
@singleton
@@ -329,8 +329,8 @@ def eval(self, pkt):
329329
return {pkt}
330330

331331
def generate_classifier(self):
332-
r1 = Rule(self,[identity])
333-
r2 = Rule(identity,[drop])
332+
r1 = Rule(self,{identity})
333+
r2 = Rule(identity,{drop})
334334
return Classifier([r1, r2])
335335

336336
def __eq__(self, other):
@@ -446,9 +446,9 @@ def eval(self, pkt):
446446

447447
def generate_classifier(self):
448448
if self.has_virtual_headers:
449-
r = Rule(identity,[Controller])
449+
r = Rule(identity,{Controller})
450450
else:
451-
r = Rule(identity,[self])
451+
r = Rule(identity,{self})
452452
return Classifier([r])
453453

454454
def __repr__(self):
@@ -503,7 +503,7 @@ def __init__(self):
503503
super(FwdBucket,self).__init__()
504504

505505
def generate_classifier(self):
506-
return Classifier([Rule(identity,[Controller])])
506+
return Classifier([Rule(identity,{Controller})])
507507

508508
def apply(self):
509509
with self.bucket_lock:
@@ -553,7 +553,7 @@ def eval(self, pkt):
553553
return set()
554554

555555
def generate_classifier(self):
556-
return Classifier([Rule(identity,[self])])
556+
return Classifier([Rule(identity,{self})])
557557

558558
def apply(self):
559559
with self.bucket_lock:

0 commit comments

Comments
 (0)