forked from sonoble/sonic-buildimage
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtranslate_acl
More file actions
executable file
·172 lines (152 loc) · 6.86 KB
/
Copy pathtranslate_acl
File metadata and controls
executable file
·172 lines (152 loc) · 6.86 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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/usr/bin/env python
import sys
import os.path
import json
import argparse
import openconfig_acl
import pyangbind.lib.pybindJSON as pybindJSON
from minigraph import parse_xml
def dump_json(filename, data):
with open(filename, 'w') as outfile:
json.dump(data, outfile, indent=4, sort_keys=True, separators=(',', ':'))
def default_deny_rule(table_name):
rule_props = {}
rule_data = {}
rule_data["ACL_RULE_TABLE:"+table_name+":default_rule"] = rule_props
rule_data["OP"] = "SET"
rule_props["priority"] = 1
rule_props["PACKET_ACTION"] = "DROP"
return rule_data
def generate_rule_json(table_name, rule, max_priority, mirror):
rule_idx = rule.config.sequence_id
rule_props = {}
rule_data = {}
rule_data["ACL_RULE_TABLE:"+table_name+":Rule_"+str(rule_idx)] = rule_props
rule_data["OP"] = "SET"
rule_props["priority"] = max_priority - rule_idx
if rule.actions.config.forwarding_action == "ACCEPT":
if mirror:
rule_props["MIRROR_ACTION"] = "everflow"
else:
rule_props["PACKET_ACTION"] = "FORWARD"
elif rule.actions.config.forwarding_action == "DROP":
rule_props["PACKET_ACTION"] = "DROP"
elif rule.actions.config.forwarding_action == "REJECT":
rule_props["PACKET_ACTION"] = "DROP"
else:
print "Unknown rule action %s in table %s, rule %d!" % (rule.actions.config.forwarding_action, table_name, rule_idx)
return {}
ip_protocol_map = {
"IP_TCP" : 6,
"IP_ICMP" : 1,
"IP_UDP" : 17,
"IP_IGMP" : 2,
"IP_PIM" : 103,
"IP_RSVP" : 46,
"IP_GRE" : 47,
"IP_AUTH" : 51,
"IP_L2TP" : 115
}
if not rule.ip.config.protocol:
pass
elif ip_protocol_map.has_key(rule.ip.config.protocol):
rule_props["IP_PROTOCOL"] = ip_protocol_map[rule.ip.config.protocol]
else:
try:
int(rule.ip.config.protocol)
except:
print "Unknown rule protocol %s in table %s, rule %d!" % (rule.ip.config.protocol, table_name, rule_idx)
return {}
else:
rule_props["IP_PROTOCOL"] = rule.ip.config.protocol
if rule.ip.config.source_ip_address != "":
rule_props["SRC_IP"] = rule.ip.config.source_ip_address
if rule.ip.config.destination_ip_address != "":
rule_props["DST_IP"] = rule.ip.config.destination_ip_address
if rule.transport.config.source_port == "":
pass
elif str(rule.transport.config.source_port).find("..") < 0:
rule_props["L4_SRC_PORT"] = rule.transport.config.source_port
else:
rule_props["L4_SRC_PORT_RANGE"] = str(rule.transport.config.source_port).replace("..", "-")
if rule.transport.config.destination_port == "":
pass
elif str(rule.transport.config.destination_port).find("..") < 0:
rule_props["L4_DST_PORT"] = rule.transport.config.destination_port
else:
rule_props["L4_DST_PORT_RANGE"] = str(rule.transport.config.destination_port).replace("..", "-")
tcp_flags = 0x00;
for flag in rule.transport.config.tcp_flags:
if flag == "TCP_FIN":
tcp_flags = tcp_flags | 0x01
if flag == "TCP_SYN":
tcp_flags = tcp_flags | 0x02
if flag == "TCP_RST":
tcp_flags = tcp_flags | 0x04
if flag == "TCP_PSH":
tcp_flags = tcp_flags | 0x08
if flag == "TCP_ACK":
tcp_flags = tcp_flags | 0x10
if flag == "TCP_URG":
tcp_flags = tcp_flags | 0x20
if flag == "TCP_ECE":
tcp_flags = tcp_flags | 0x40
if flag == "TCP_CWR":
tcp_flags = tcp_flags | 0x80
if tcp_flags != 0x00:
rule_props["TCP_FLAGS"] = '0x{:02x}/0x{:02x}'.format(tcp_flags, tcp_flags)
return rule_data
def generate_table_json(aclset, aclname, ports, mirror, max_priority, output_path='.'):
table_name = aclname.replace(" ", "_").replace("-", "_")
#table_name = generate_random_table_name()
table_props = {}
table_props["policy_desc"] = table_name
table_props["type"] = "mirror" if mirror else "L3"
table_props["ports"] = ports
table_data = [{}]
table_data[0]["ACL_TABLE:"+table_name] = table_props
table_data[0]["OP"] = "SET"
dump_json(os.path.join(output_path, "table_"+table_name+".json"), table_data)
rule_data = []
for aclentryname in aclset.acl_entries.acl_entry:
aclentry = aclset.acl_entries.acl_entry[aclentryname]
rule_props = generate_rule_json(table_name, aclentry, max_priority, mirror)
if rule_props:
rule_data.append(rule_props)
if not mirror:
rule_data.append(default_deny_rule(table_name))
dump_json(os.path.join(output_path, "rules_for_"+table_name+".json"), rule_data)
def translate_acl_fixed_port(filename, output_path, port, max_priority):
yang_acl = pybindJSON.load(filename, openconfig_acl, "openconfig_acl")
for aclsetname in yang_acl.acl.acl_sets.acl_set:
aclset = yang_acl.acl.acl_sets.acl_set[aclsetname]
generate_table_json(aclset, aclsetname, port, max_priority, output_path)
return
def translate_acl(filename, output_path, mini_acl, max_priority):
yang_acl = pybindJSON.load(filename, openconfig_acl, "openconfig_acl")
for aclsetname in yang_acl.acl.acl_sets.acl_set:
tablename = aclsetname.replace(" ", "_").replace("-", "_")
if mini_acl.has_key(tablename):
is_mirror = mini_acl[tablename]['IsMirror']
ports = ','.join(mini_acl[tablename]['AttachTo'])
aclset = yang_acl.acl.acl_sets.acl_set[aclsetname]
generate_table_json(aclset, aclsetname, ports, is_mirror, max_priority, output_path)
return
def main():
parser = argparse.ArgumentParser(description="Translate openconfig ACL json into SONiC ACL jsons")
parser.add_argument('input', metavar='INPUT', help='input json file in openconfig format')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-a', '--attach-to', help='the port(s) that this ACL is attached to')
group.add_argument('-m', '--minigraph', help='read ACL attaching information from minigraph')
parser.add_argument("-p", "--port-config", help="port config file, used with -m")
parser.add_argument('-n', '--max-priority', type=int, default=10000, help='the priority number of the first rule in ACL entries')
parser.add_argument('-o', '--output-path', default='.', help='output directory where SONiC ACL jsons will be generated')
args = parser.parse_args()
if args.attach_to:
translate_acl_fixed_port(args.input, args.output_path, args.port, args.max_priority)
elif args.minigraph:
mini_data = parse_xml(args.minigraph, port_config_file=args.port_config)
if mini_data['minigraph_acls']:
translate_acl(args.input, args.output_path, mini_data['minigraph_acls'], args.max_priority)
if __name__ == "__main__":
main()