forked from iovisor/bcc
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathebpfConditional.py
More file actions
118 lines (102 loc) · 4.08 KB
/
Copy pathebpfConditional.py
File metadata and controls
118 lines (102 loc) · 4.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# Copyright (c) Barefoot Networks, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")
from p4_hlir.hlir import p4_conditional_node, p4_expression
from p4_hlir.hlir import p4_header_instance, p4_field
from programSerializer import ProgramSerializer
from compilationException import CompilationException
import ebpfProgram
import ebpfInstance
class EbpfConditional(object):
@staticmethod
def translate(op):
if op == "not":
return "!"
elif op == "or":
return "||"
elif op == "and":
return "&&"
return op
def __init__(self, p4conditional, program):
assert isinstance(p4conditional, p4_conditional_node)
assert isinstance(program, ebpfProgram.EbpfProgram)
self.hlirconditional = p4conditional
self.name = p4conditional.name
def emitNode(self, node, serializer, program):
if isinstance(node, p4_expression):
self.emitExpression(node, serializer, program, False)
elif node is None:
pass
elif isinstance(node, int):
serializer.append(node)
elif isinstance(node, p4_header_instance):
header = program.getInstance(node.name)
assert isinstance(header, ebpfInstance.EbpfHeader)
# TODO: stacks?
serializer.appendFormat(
"{0}.{1}", program.headerStructName, header.name)
elif isinstance(node, p4_field):
instance = node.instance
einstance = program.getInstance(instance.name)
if isinstance(einstance, ebpfInstance.EbpfHeader):
base = program.headerStructName
else:
base = program.metadataStructName
serializer.appendFormat(
"{0}.{1}.{2}", base, einstance.name, node.name)
else:
raise CompilationException(True, "{0} Unexpected expression ", node)
def emitExpression(self, expression, serializer, program, toplevel):
assert isinstance(serializer, ProgramSerializer)
assert isinstance(program, ebpfProgram.EbpfProgram)
assert isinstance(expression, p4_expression)
assert isinstance(toplevel, bool)
left = expression.left
op = expression.op
right = expression.right
assert isinstance(op, str)
if op == "valid":
self.emitNode(right, serializer, program)
serializer.append(".valid")
return
if not toplevel:
serializer.append("(")
self.emitNode(left, serializer, program)
op = EbpfConditional.translate(op)
serializer.append(op)
self.emitNode(right, serializer, program)
if not toplevel:
serializer.append(")")
def generateCode(self, serializer, program, nextNode):
assert isinstance(serializer, ProgramSerializer)
assert isinstance(program, ebpfProgram.EbpfProgram)
serializer.emitIndent()
serializer.blockStart()
trueBranch = self.hlirconditional.next_[True]
if trueBranch is None:
trueBranch = nextNode
falseBranch = self.hlirconditional.next_[False]
if falseBranch is None:
falseBranch = nextNode
serializer.emitIndent()
serializer.appendFormat("{0}:", program.getLabel(self.hlirconditional))
serializer.newline()
serializer.emitIndent()
serializer.append("if (")
self.emitExpression(
self.hlirconditional.condition, serializer, program, True)
serializer.appendLine(")")
serializer.increaseIndent()
label = program.getLabel(trueBranch)
serializer.emitIndent()
serializer.appendFormat("goto {0};", label)
serializer.newline()
serializer.decreaseIndent()
serializer.emitIndent()
serializer.appendLine("else")
serializer.increaseIndent()
label = program.getLabel(falseBranch)
serializer.emitIndent()
serializer.appendFormat("goto {0};", label)
serializer.newline()
serializer.decreaseIndent()
serializer.blockEnd(True)