├── .gitignore ├── LICENSE ├── README.md ├── Vagrantfile ├── netasm ├── __init__.py ├── back_ends │ ├── __init__.py │ └── soft_switch │ │ ├── __init__.py │ │ ├── api.py │ │ ├── datapath.py │ │ └── mininet │ │ ├── __init__.py │ │ ├── bash.py │ │ └── node.py ├── examples │ ├── __init__.py │ ├── back_ends │ │ ├── __init__.py │ │ └── soft_switch │ │ │ ├── __init__.py │ │ │ └── mininet │ │ │ ├── __init__.py │ │ │ ├── linear_switch.py │ │ │ ├── single_switch.py │ │ │ └── standalone_single_switch.py │ ├── controllers │ │ ├── __init__.py │ │ └── pox │ │ │ ├── __init__.py │ │ │ ├── hub.py │ │ │ ├── learning_switch.py │ │ │ ├── pass_through_2ports.py │ │ │ ├── send_to_controller_hub.py │ │ │ ├── statistics.py │ │ │ ├── table_based_learning.py │ │ │ └── table_based_pass_through.py │ └── netasm │ │ ├── __init__.py │ │ ├── controller_assisted │ │ ├── __init__.py │ │ ├── send_to_controller.py │ │ └── table_based_simple.py │ │ ├── hybrid │ │ └── __init__.py │ │ └── standalone │ │ ├── __init__.py │ │ ├── decrement_loop.py │ │ ├── hub.py │ │ ├── learning_switch.py │ │ └── pass_through_2ports.py └── netasm │ ├── __init__.py │ ├── core │ ├── __init__.py │ ├── analyses │ │ ├── __init__.py │ │ ├── field_reachability.py │ │ ├── field_usability.py │ │ ├── liveness.py │ │ └── reaching_definitions.py │ ├── common.py │ ├── cost.py │ ├── execute │ │ ├── __init__.py │ │ ├── multi_process.py │ │ └── single_process.py │ ├── graphs │ │ ├── __init__.py │ │ ├── basic_blocks.py │ │ └── control_flow_graph.py │ ├── optimize.py │ ├── parse.py │ ├── syntax.py │ ├── transformations │ │ ├── __init__.py │ │ ├── add_code_motion.py │ │ ├── dead_code_elimination.py │ │ ├── redundant_code_elimination.py │ │ ├── rmv_code_insertion.py │ │ └── rmv_code_motion.py │ ├── type_check.py │ └── utilities │ │ ├── __init__.py │ │ ├── algorithms.py │ │ └── profile.py │ ├── cost.py │ ├── execute.py │ ├── optimize.py │ ├── parse.py │ └── validate.py ├── setup ├── basic.sh ├── last.sh ├── mininet.sh ├── netasm.sh └── pox-patch.sh └── tools ├── veth_setup.sh └── veth_teardown.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | 53 | # Sphinx documentation 54 | docs/_build/ 55 | 56 | # PyBuilder 57 | target/ 58 | 59 | # Others 60 | *.idea/ 61 | *.vagrant/ 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Welcome to NetASM-python! 2 | 3 | Visit our [Wiki homepage](https://github.com/NetASM/NetASM-python/wiki). 4 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ## 3 | ## https://github.com/NetASM/NetASM-python 4 | ## 5 | ## File: 6 | ## Vagrantfile 7 | ## 8 | ## Project: 9 | ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | ## 11 | ## Author: 12 | ## Muhammad Shahbaz 13 | ## 14 | ## Copyright notice: 15 | ## Copyright (C) 2014 Princeton University 16 | ## Network Operations and Internet Security Lab 17 | ## 18 | ## Licence: 19 | ## This file is a part of the NetASM development base package. 20 | ## 21 | ## This file is free code: you can redistribute it and/or modify it under 22 | ## the terms of the GNU Lesser General Public License version 2.1 as 23 | ## published by the Free Software Foundation. 24 | ## 25 | ## This package is distributed in the hope that it will be useful, but 26 | ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | ## Lesser General Public License for more details. 29 | ## 30 | ## You should have received a copy of the GNU Lesser General Public 31 | ## License along with the NetASM source package. If not, see 32 | ## http://www.gnu.org/licenses/. 33 | 34 | VAGRANTFILE_API_VERSION = "2" 35 | 36 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 37 | config.vm.box = "ubuntu/trusty64" 38 | 39 | config.vm.provider "virtualbox" do |v| 40 | v.customize ["modifyvm", :id, "--cpuexecutioncap", "50"] 41 | v.customize ["modifyvm", :id, "--memory", "1024"] 42 | end 43 | 44 | config.vm.provision "shell", privileged: false, path: "./setup/basic.sh" 45 | config.vm.provision "shell", privileged: false, path: "./setup/mininet.sh" 46 | config.vm.provision "shell", privileged: false, path: "./setup/pox-patch.sh" 47 | config.vm.provision "shell", privileged: false, path: "./setup/netasm.sh" 48 | config.vm.provision "shell", privileged: false, path: "./setup/last.sh" 49 | end 50 | -------------------------------------------------------------------------------- /netasm/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## # Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | -------------------------------------------------------------------------------- /netasm/back_ends/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | -------------------------------------------------------------------------------- /netasm/back_ends/soft_switch/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' -------------------------------------------------------------------------------- /netasm/back_ends/soft_switch/api.py: -------------------------------------------------------------------------------- 1 | # ############################################################################### 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## api.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from ast import literal_eval 37 | 38 | from pox.openflow import libopenflow_01 as of 39 | 40 | 41 | class InMessage: 42 | def __init__(self, vendor): 43 | self.vendor = vendor 44 | self.message = literal_eval(vendor.data) 45 | 46 | if not self.message['type'] == 'in': 47 | raise TypeError() 48 | 49 | self.is_packet_in = self.message['operation'] == 'packet-in' 50 | self.is_query_table_entry = self.message['operation'] == 'query-table-entry' 51 | self.is_query_table_list = self.message['operation'] == 'query-table-list' 52 | 53 | if self.is_packet_in: 54 | self.port = self.message['data'][0] 55 | self.packet_data = self.message['data'][1] 56 | self.reason = self.message['data'][2][0] 57 | self.description = self.message['data'][2][1] 58 | elif self.is_query_table_entry: 59 | self.table_name = self.message['data'][0] 60 | self.table_index = self.message['data'][1] 61 | self.table_entry = self.message['data'][2] 62 | elif self.is_query_table_list: 63 | self.table_list = self.message['data'] 64 | else: 65 | raise TypeError() 66 | 67 | 68 | class OutMessage(of.ofp_vendor_generic): 69 | def __init__(self): 70 | super(OutMessage, self).__init__() 71 | self.message = {'type': 'out'} 72 | 73 | def set_policy(self, policy): 74 | self.message['operation'] = 'set-policy' 75 | self.message['data'] = policy 76 | self.data = str(self.message) 77 | 78 | def clr_policy(self): 79 | self.message['operation'] = 'clr-policy' 80 | self.message['data'] = None 81 | self.data = str(self.message) 82 | 83 | def add_table_entry(self, name, index, entry): 84 | self.message['operation'] = 'add-table-entry' 85 | self.message['data'] = (name, index, entry) 86 | self.data = str(self.message) 87 | 88 | def del_table_entry(self, name, index): 89 | self.message['operation'] = 'del-table-entry' 90 | self.message['data'] = (name, index) 91 | self.data = str(self.message) 92 | 93 | def packet_out(self, ports, packet=None): 94 | self.message['operation'] = 'packet-out' 95 | self.message['data'] = (ports, packet) 96 | self.data = str(self.message) 97 | 98 | 99 | class QueryMessage(of.ofp_vendor_generic): 100 | def __init__(self): 101 | super(QueryMessage, self).__init__() 102 | self.message = {'type': 'query'} 103 | 104 | def table_entry(self, name, index): 105 | self.message['operation'] = 'query-table-entry' 106 | self.message['data'] = (name, index) 107 | self.data = str(self.message) 108 | 109 | def table_list(self): 110 | self.message['operation'] = 'query-table-list' 111 | self.message['data'] = None 112 | self.data = str(self.message) -------------------------------------------------------------------------------- /netasm/back_ends/soft_switch/mininet/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' -------------------------------------------------------------------------------- /netasm/back_ends/soft_switch/mininet/bash.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## bash.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | import os 37 | import sys 38 | import subprocess 39 | import re 40 | 41 | import psutil 42 | 43 | 44 | def get_path(filename): 45 | try: 46 | output = os.environ['PYTHONPATH'] 47 | except: 48 | print 'Error: Unable to obtain PYTHONPATH' 49 | sys.exit(1) 50 | 51 | path = None 52 | 53 | for p in output.split(':'): 54 | if re.match('.*' + filename + '.*/?$', p): 55 | path = os.path.abspath(p) 56 | break 57 | 58 | if path is None: 59 | print 'Error: ' + filename + ' not found in PYTHONPATH' 60 | print output 61 | sys.exit(1) 62 | 63 | return path 64 | 65 | 66 | def set_path(filename): 67 | try: 68 | output = os.environ['PYTHONPATH'] 69 | except: 70 | print 'Error: Unable to obtain PYTHONPATH' 71 | sys.exit(1) 72 | 73 | os.environ['PYTHONPATH'] += ':' + filename 74 | 75 | 76 | def run_silent_command(command): 77 | devnull = open(os.devnull, 'w') 78 | 79 | return subprocess.Popen(command, stdout=devnull, stderr=devnull, preexec_fn=os.setpgrp) 80 | 81 | 82 | run_command = run_silent_command 83 | 84 | 85 | def kill_command(process, signal): 86 | try: 87 | process = psutil.Process(process.pid) 88 | except: 89 | return 90 | 91 | child_processes_pid = process.get_children(recursive=True) 92 | for pid in child_processes_pid: 93 | os.kill(pid.pid, signal) 94 | 95 | os.kill(process.pid, signal) 96 | 97 | 98 | -------------------------------------------------------------------------------- /netasm/back_ends/soft_switch/mininet/node.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## node.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from mininet.node import Switch 37 | from mininet.log import error 38 | from netasm.back_ends.soft_switch.mininet.bash import get_path, run_command, kill_command 39 | 40 | 41 | path = get_path("pox") 42 | 43 | 44 | class NetASMSwitch(Switch): 45 | CTL_ADDRESS = "127.0.0.1" 46 | CTL_PORT = 7791 47 | CTL_ENABLE = False 48 | 49 | def __init__(self, name, **kwargs): 50 | Switch.__init__(self, name, **kwargs) 51 | self.policy = '' 52 | 53 | def start(self, controllers): 54 | pass 55 | 56 | def stop(self): 57 | pass 58 | 59 | @staticmethod 60 | def start_datapath(switches, address="127.0.0.1", port=6633, standalone=False): 61 | global _process 62 | 63 | args = [] 64 | for switch in switches: 65 | args += ['netasm.back_ends.soft_switch.datapath'] + \ 66 | (['--standalone'] if standalone else []) + \ 67 | ['--address=' + address] + ['--port=' + str(port)] + \ 68 | ['--dpid=' + switch.dpid] 69 | 70 | args += ['--policy=' + switch.policy] 71 | 72 | intfs = '' 73 | for intf in switch.intfList(): 74 | if switch.name in intf.name: 75 | intfs += intf.name + ',' 76 | 77 | args += ['--ports=' + intfs[:-1]] 78 | 79 | _process = None 80 | 81 | if args: 82 | command = ['python', path + '/pox.py', '--no-openflow'] + args + \ 83 | ['--ctl_port=' + str(NetASMSwitch.CTL_PORT)] 84 | raw_input("*** Run this command in a separate terminal then press Enter!\n" + 'sudopy ' + ' '.join(command)) 85 | # _process = run_command(command) 86 | NetASMSwitch.CTL_ENABLE = True 87 | else: 88 | NetASMSwitch.CTL_ENABLE = False 89 | 90 | @staticmethod 91 | def stop_datapath(): 92 | global _process 93 | 94 | if _process: 95 | import signal 96 | 97 | kill_command(_process, signal.SIGINT) 98 | _process = None 99 | 100 | NetASMSwitch.CTL_ENABLE = False 101 | -------------------------------------------------------------------------------- /netasm/examples/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | -------------------------------------------------------------------------------- /netasm/examples/back_ends/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | -------------------------------------------------------------------------------- /netasm/examples/back_ends/soft_switch/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | -------------------------------------------------------------------------------- /netasm/examples/back_ends/soft_switch/mininet/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | -------------------------------------------------------------------------------- /netasm/examples/back_ends/soft_switch/mininet/linear_switch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # ################################################################################ 4 | # ## 5 | # ## https://github.com/NetASM/NetASM-python 6 | # ## 7 | # ## File: 8 | # ## linear_switch.py 9 | # ## 10 | # ## Project: 11 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 12 | # ## 13 | # ## Author: 14 | # ## Muhammad Shahbaz 15 | # ## 16 | # ## Copyright notice: 17 | # ## Copyright (C) 2014 Princeton University 18 | # ## Network Operations and Internet Security Lab 19 | # ## 20 | # ## Licence: 21 | # ## This file is a part of the NetASM development base package. 22 | # ## 23 | # ## This file is free code: you can redistribute it and/or modify it under 24 | # ## the terms of the GNU Lesser General Public License version 2.1 as 25 | # ## published by the Free Software Foundation. 26 | # ## 27 | # ## This package is distributed in the hope that it will be useful, but 28 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 29 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 30 | # ## Lesser General Public License for more details. 31 | # ## 32 | # ## You should have received a copy of the GNU Lesser General Public 33 | # ## License along with the NetASM source package. If not, see 34 | # ## http://www.gnu.org/licenses/. 35 | 36 | __author__ = 'shahbaz' 37 | 38 | from optparse import OptionParser 39 | 40 | from mininet.node import RemoteController 41 | from mininet.net import Mininet, CLI 42 | from mininet.topo import SingleSwitchTopo, LinearTopo 43 | from mininet.log import setLogLevel 44 | from netasm.back_ends.soft_switch.mininet.node import NetASMSwitch 45 | 46 | 47 | def test(): 48 | op = OptionParser() 49 | op.add_option('--cli', action="store_true", dest="cli") 50 | op.add_option('--ports', action="store", dest="ports") 51 | 52 | op.set_defaults(cli=False, ports=2) 53 | options, args = op.parse_args() 54 | 55 | topo = LinearTopo(int(options.ports)) 56 | 57 | NetASMSwitch.CTL_ADDRESS = "127.0.0.1" 58 | NetASMSwitch.CTL_PORT = 7791 59 | 60 | net = Mininet(topo, switch=NetASMSwitch, autoSetMacs=True, controller=lambda name: RemoteController(name)) 61 | 62 | NetASMSwitch.start_datapath(net.switches, address="127.0.0.1", port=6633) 63 | net.start() 64 | 65 | if options.cli: 66 | CLI(net) 67 | else: 68 | net.pingAll() 69 | 70 | net.stop() 71 | NetASMSwitch.stop_datapath() 72 | 73 | 74 | if __name__ == '__main__': 75 | # Tell mininet to print useful information 76 | setLogLevel('info') 77 | test() -------------------------------------------------------------------------------- /netasm/examples/back_ends/soft_switch/mininet/single_switch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # ################################################################################ 4 | # ## 5 | # ## https://github.com/NetASM/NetASM-python 6 | # ## 7 | # ## File: 8 | # ## single_switch.py 9 | # ## 10 | # ## Project: 11 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 12 | # ## 13 | # ## Author: 14 | # ## Muhammad Shahbaz 15 | # ## 16 | # ## Copyright notice: 17 | # ## Copyright (C) 2014 Princeton University 18 | # ## Network Operations and Internet Security Lab 19 | # ## 20 | # ## Licence: 21 | # ## This file is a part of the NetASM development base package. 22 | # ## 23 | # ## This file is free code: you can redistribute it and/or modify it under 24 | # ## the terms of the GNU Lesser General Public License version 2.1 as 25 | # ## published by the Free Software Foundation. 26 | # ## 27 | # ## This package is distributed in the hope that it will be useful, but 28 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 29 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 30 | # ## Lesser General Public License for more details. 31 | # ## 32 | # ## You should have received a copy of the GNU Lesser General Public 33 | # ## License along with the NetASM source package. If not, see 34 | # ## http://www.gnu.org/licenses/. 35 | 36 | __author__ = 'shahbaz' 37 | 38 | from optparse import OptionParser 39 | 40 | from mininet.node import RemoteController 41 | from mininet.net import Mininet, CLI 42 | from mininet.topo import SingleSwitchTopo 43 | from mininet.log import setLogLevel 44 | from netasm.back_ends.soft_switch.mininet.node import NetASMSwitch 45 | 46 | 47 | def test(): 48 | op = OptionParser() 49 | op.add_option('--cli', action="store_true", dest="cli") 50 | op.add_option('--ports', action="store", dest="ports") 51 | 52 | op.set_defaults(cli=False, ports=2) 53 | options, args = op.parse_args() 54 | 55 | topo = SingleSwitchTopo(int(options.ports)) 56 | 57 | NetASMSwitch.CTL_ADDRESS = "127.0.0.1" 58 | NetASMSwitch.CTL_PORT = 7791 59 | 60 | net = Mininet(topo, switch=NetASMSwitch, autoSetMacs=True, controller=lambda name: RemoteController(name)) 61 | 62 | NetASMSwitch.start_datapath(net.switches, address="127.0.0.1", port=6633) 63 | net.start() 64 | 65 | if options.cli: 66 | CLI(net) 67 | else: 68 | net.pingAll() 69 | 70 | net.stop() 71 | NetASMSwitch.stop_datapath() 72 | 73 | 74 | if __name__ == '__main__': 75 | # Tell mininet to print useful information 76 | setLogLevel('info') 77 | test() -------------------------------------------------------------------------------- /netasm/examples/back_ends/soft_switch/mininet/standalone_single_switch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # ################################################################################ 4 | # ## 5 | # ## https://github.com/NetASM/NetASM-python 6 | # ## 7 | # ## File: 8 | # ## single_switch.py 9 | # ## 10 | # ## Project: 11 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 12 | # ## 13 | # ## Author: 14 | # ## Muhammad Shahbaz 15 | # ## 16 | # ## Copyright notice: 17 | # ## Copyright (C) 2014 Princeton University 18 | # ## Network Operations and Internet Security Lab 19 | # ## 20 | # ## Licence: 21 | # ## This file is a part of the NetASM development base package. 22 | # ## 23 | # ## This file is free code: you can redistribute it and/or modify it under 24 | # ## the terms of the GNU Lesser General Public License version 2.1 as 25 | # ## published by the Free Software Foundation. 26 | # ## 27 | # ## This package is distributed in the hope that it will be useful, but 28 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 29 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 30 | # ## Lesser General Public License for more details. 31 | # ## 32 | # ## You should have received a copy of the GNU Lesser General Public 33 | # ## License along with the NetASM source package. If not, see 34 | # ## http://www.gnu.org/licenses/. 35 | 36 | __author__ = 'shahbaz' 37 | 38 | from mininet.node import RemoteController 39 | from mininet.net import Mininet, CLI 40 | from mininet.topo import SingleSwitchTopo 41 | from mininet.log import setLogLevel 42 | from netasm.back_ends.soft_switch.mininet.node import NetASMSwitch 43 | 44 | 45 | def test(): 46 | topo = SingleSwitchTopo(2) 47 | 48 | NetASMSwitch.CTL_ADDRESS = "127.0.0.1" 49 | NetASMSwitch.CTL_PORT = 7791 50 | 51 | net = Mininet(topo, switch=NetASMSwitch, autoSetMacs=True, controller=lambda name: RemoteController(name)) 52 | 53 | for switch in net.switches: 54 | switch.policy = 'netasm.examples.netasm.standalone.hub' 55 | 56 | NetASMSwitch.start_datapath(net.switches, address="127.0.0.1", port=6633, standalone=True) 57 | net.start() 58 | 59 | net.pingAll() 60 | 61 | net.stop() 62 | NetASMSwitch.stop_datapath() 63 | 64 | 65 | if __name__ == '__main__': 66 | # Tell mininet to print useful information 67 | setLogLevel('info') 68 | test() -------------------------------------------------------------------------------- /netasm/examples/controllers/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | -------------------------------------------------------------------------------- /netasm/examples/controllers/pox/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' -------------------------------------------------------------------------------- /netasm/examples/controllers/pox/hub.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## hub.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | from pox.core import core 35 | from pox.lib.util import dpidToStr 36 | 37 | from netasm.back_ends.soft_switch.api import OutMessage 38 | 39 | 40 | log = core.getLogger() 41 | 42 | 43 | def _handle_ConnectionUp(event): 44 | msg = OutMessage() 45 | 46 | msg.set_policy("netasm.examples.netasm.standalone.hub") 47 | event.connection.send(msg) 48 | 49 | log.info("netasm.examples.netasm.standalone.hub for %s", dpidToStr(event.dpid)) 50 | 51 | 52 | def launch(): 53 | core.openflow.addListenerByName("ConnectionUp", _handle_ConnectionUp) 54 | 55 | log.info("netasm.examples.netasm.standalone.hub running.") -------------------------------------------------------------------------------- /netasm/examples/controllers/pox/learning_switch.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## learning_switch.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | from pox.core import core 35 | from pox.lib.util import dpidToStr 36 | 37 | from netasm.back_ends.soft_switch.api import OutMessage 38 | 39 | 40 | log = core.getLogger() 41 | 42 | 43 | def _handle_ConnectionUp(event): 44 | msg = OutMessage() 45 | 46 | msg.set_policy("netasm.examples.netasm.standalone.learning_switch") 47 | event.connection.send(msg) 48 | 49 | log.info("netasm.examples.netasm.standalone.learning_switch for %s", dpidToStr(event.dpid)) 50 | 51 | 52 | def launch(): 53 | core.openflow.addListenerByName("ConnectionUp", _handle_ConnectionUp) 54 | 55 | log.info("netasm.examples.netasm.standalone.learning_switch running.") -------------------------------------------------------------------------------- /netasm/examples/controllers/pox/pass_through_2ports.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## pass_through_2ports.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | from pox.core import core 35 | from pox.lib.util import dpidToStr 36 | 37 | from netasm.back_ends.soft_switch.api import OutMessage 38 | 39 | 40 | log = core.getLogger() 41 | 42 | 43 | def _handle_ConnectionUp(event): 44 | msg = OutMessage() 45 | 46 | msg.set_policy("netasm.examples.netasm.standalone.pass_through_2ports") 47 | event.connection.send(msg) 48 | 49 | log.info("netasm.examples.netasm.standalone.pass_through_2ports for %s", dpidToStr(event.dpid)) 50 | 51 | 52 | def launch(): 53 | core.openflow.addListenerByName("ConnectionUp", _handle_ConnectionUp) 54 | 55 | log.info("netasm.examples.netasm.standalone.pass_through_2ports running.") -------------------------------------------------------------------------------- /netasm/examples/controllers/pox/send_to_controller_hub.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## send_to_controller_hub.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | from pox.core import core 35 | from pox.lib.util import dpidToStr 36 | 37 | from netasm.back_ends.soft_switch.api import OutMessage, InMessage 38 | 39 | 40 | log = core.getLogger() 41 | PORT_COUNT = 16 42 | 43 | 44 | def _handle_VendorIn(event): 45 | in_msg = InMessage(event.ofp) 46 | 47 | if in_msg.is_packet_in: 48 | 49 | if in_msg.reason == 'SEND_TO_CONTROLLER': 50 | out_msg = OutMessage() 51 | 52 | ports = [] 53 | for i in range(1, PORT_COUNT + 1): 54 | if i != in_msg.port: 55 | ports.append(i) 56 | 57 | out_msg.packet_out(ports, in_msg.packet_data) 58 | 59 | event.connection.send(out_msg) 60 | 61 | 62 | def _handle_ConnectionUp(event): 63 | msg = OutMessage() 64 | 65 | msg.set_policy("netasm.examples.netasm.controller_assisted.send_to_controller") 66 | event.connection.send(msg) 67 | 68 | log.info("netasm.examples.netasm.controller_assisted.send_to_controller (hub) for %s", dpidToStr(event.dpid)) 69 | 70 | 71 | def launch(): 72 | core.openflow.addListenerByName("ConnectionUp", _handle_ConnectionUp) 73 | core.openflow.addListenerByName("VendorIn", _handle_VendorIn) 74 | 75 | log.info("netasm.examples.netasm.controller_assisted.send_to_controller (hub) running.") -------------------------------------------------------------------------------- /netasm/examples/controllers/pox/statistics.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## statistics.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | from pox.core import core 35 | from pox.lib.util import dpidToStr 36 | 37 | from netasm.back_ends.soft_switch.api import * 38 | 39 | 40 | log = core.getLogger() 41 | 42 | 43 | def _handle_VendorIn(event): 44 | in_msg = InMessage(event.ofp) 45 | 46 | if in_msg.is_query_table_entry: 47 | print in_msg.table_name, in_msg.table_index, in_msg.table_entry 48 | elif in_msg.is_query_table_list: 49 | print in_msg.table_list 50 | 51 | 52 | def _handle_ConnectionUp(event): 53 | msg = OutMessage() 54 | 55 | msg.set_policy("netasm.examples.netasm.controller_assisted.table_based_simple") 56 | event.connection.send(msg) 57 | 58 | msg = QueryMessage() 59 | 60 | msg.table_entry('match_table', 0) 61 | event.connection.send(msg) 62 | 63 | msg.table_list() 64 | event.connection.send(msg) 65 | 66 | log.info("netasm.examples.netasm.controller_assisted.table_based_simple (statistics) for %s", dpidToStr(event.dpid)) 67 | 68 | 69 | def launch(): 70 | core.openflow.addListenerByName("ConnectionUp", _handle_ConnectionUp) 71 | core.openflow.addListenerByName("VendorIn", _handle_VendorIn) 72 | 73 | log.info("netasm.examples.netasm.controller_assisted.table_based_simple (statistics) running.") -------------------------------------------------------------------------------- /netasm/examples/controllers/pox/table_based_learning.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## table_based_learning.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | from pox.core import core 35 | from pox.lib.util import dpidToStr 36 | 37 | from netasm.back_ends.soft_switch.api import OutMessage, InMessage 38 | 39 | 40 | log = core.getLogger() 41 | 42 | 43 | def _handle_VendorIn(event): 44 | in_msg = InMessage(event.ofp) 45 | 46 | if in_msg.is_packet_in: 47 | 48 | if in_msg.reason == 'MATCH_TABLE_MISS': 49 | 50 | out_msg = OutMessage() 51 | 52 | if in_msg.port == 1: 53 | out_msg.packet_out([2], in_msg.packet_data) 54 | elif in_msg.port == 2: 55 | out_msg.packet_out([1], in_msg.packet_data) 56 | 57 | event.connection.send(out_msg) 58 | 59 | # TODO: on learning, install a rule in the switch ... Missing 60 | 61 | 62 | def _handle_ConnectionUp(event): 63 | msg = OutMessage() 64 | 65 | msg.set_policy("netasm.examples.netasm.controller_assisted.table_based_simple") 66 | event.connection.send(msg) 67 | 68 | log.info("netasm.examples.netasm.controller_assisted.table_based_simple (learning) for %s", dpidToStr(event.dpid)) 69 | 70 | 71 | def launch(): 72 | core.openflow.addListenerByName("ConnectionUp", _handle_ConnectionUp) 73 | core.openflow.addListenerByName("VendorIn", _handle_VendorIn) 74 | 75 | log.info("netasm.examples.netasm.controller_assisted.table_based_simple (learning) running.") -------------------------------------------------------------------------------- /netasm/examples/controllers/pox/table_based_pass_through.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## table_based_pass_through.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | from pox.core import core 35 | from pox.lib.util import dpidToStr 36 | 37 | from netasm.netasm.core.common import ports_to_bitmap 38 | from netasm.back_ends.soft_switch.api import OutMessage, InMessage, QueryMessage 39 | 40 | 41 | log = core.getLogger() 42 | 43 | 44 | def _handle_VendorIn(event): 45 | in_msg = InMessage(event.ofp) 46 | 47 | if in_msg.is_query_table_entry: 48 | print "Query Table Entry: %s %s %s" % (in_msg.table_name, in_msg.table_index, in_msg.table_entry) 49 | elif in_msg.is_query_table_list: 50 | print "Query Table List: %s" % (in_msg.table_list, ) 51 | 52 | 53 | def _handle_ConnectionUp(event): 54 | msg = OutMessage() 55 | 56 | msg.set_policy("netasm.examples.netasm.controller_assisted.table_based_simple") 57 | event.connection.send(msg) 58 | 59 | msg.add_table_entry('match_table', 0, 60 | {'eth_src': (0x000000000001, 0xFFFFFFFFFFFF)}) 61 | event.connection.send(msg) 62 | msg.add_table_entry('params_table', 0, 63 | {'outport_bitmap': ports_to_bitmap(2)}) 64 | event.connection.send(msg) 65 | 66 | msg.add_table_entry('match_table', 1, 67 | {'eth_src': (0x000000000002, 0xFFFFFFFFFFFF)}) 68 | event.connection.send(msg) 69 | msg.add_table_entry('params_table', 1, 70 | {'outport_bitmap': ports_to_bitmap(1)}) 71 | event.connection.send(msg) 72 | 73 | msg = QueryMessage() 74 | 75 | msg.table_entry('match_table', 0) 76 | event.connection.send(msg) 77 | msg.table_entry('params_table', 0) 78 | event.connection.send(msg) 79 | 80 | msg.table_entry('match_table', 1) 81 | event.connection.send(msg) 82 | msg.table_entry('params_table', 1) 83 | event.connection.send(msg) 84 | 85 | msg.table_list() 86 | event.connection.send(msg) 87 | 88 | log.info("netasm.examples.netasm.controller_assisted.table_based_simple (pass through) for %s", 89 | dpidToStr(event.dpid)) 90 | 91 | 92 | def launch(): 93 | core.openflow.addListenerByName("ConnectionUp", _handle_ConnectionUp) 94 | core.openflow.addListenerByName("VendorIn", _handle_VendorIn) 95 | 96 | log.info("netasm.examples.netasm.controller_assisted.table_based_simple (pass through) running.") -------------------------------------------------------------------------------- /netasm/examples/netasm/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | -------------------------------------------------------------------------------- /netasm/examples/netasm/controller_assisted/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | -------------------------------------------------------------------------------- /netasm/examples/netasm/controller_assisted/send_to_controller.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## send_to_controller.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from netasm.netasm.core import * 37 | 38 | 39 | def main(): 40 | ### Declarations ### 41 | decls = Decls(TableDecls()) 42 | 43 | ### Code ### 44 | code = I.Code( 45 | ################## 46 | ### Arguments #### 47 | ################## 48 | Fields(), 49 | 50 | ################## 51 | ## Instructions ## 52 | ################## 53 | I.Instructions( 54 | I.CTR(Reason('SEND_TO_CONTROLLER', 'Sending all traffic to controller.')), 55 | I.HLT() 56 | ) 57 | ) 58 | 59 | return Policy(decls, code) -------------------------------------------------------------------------------- /netasm/examples/netasm/controller_assisted/table_based_simple.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## table_based_simple.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from netasm.netasm.core import * 37 | 38 | 39 | def main(): 40 | ### Declarations ### 41 | decls = Decls(TableDecls()) 42 | 43 | ## Tables ## 44 | TABLE_SIZE = Size(2) 45 | decls.table_decls[TableId('match_table')] = \ 46 | Table(TableFieldsCollection.MatchFields(), 47 | TABLE_SIZE, 48 | TableTypeCollection.CAM) 49 | match_table = decls.table_decls[TableId('match_table')] 50 | match_table.table_fields[Field('eth_src')] = Size(48), MatchTypeCollection.Binary 51 | 52 | decls.table_decls[TableId('params_table')] = \ 53 | Table(TableFieldsCollection.SimpleFields(), 54 | TABLE_SIZE, 55 | TableTypeCollection.RAM) 56 | params_table = decls.table_decls[TableId('params_table')] 57 | params_table.table_fields[Field('outport_bitmap')] = Size(2) 58 | # Note: outport_bitmap is a bitmap 59 | 60 | ### Code ### 61 | code = I.Code( 62 | ################## 63 | ### Arguments #### 64 | ################## 65 | Fields(), 66 | 67 | ################## 68 | ## Instructions ## 69 | ################## 70 | I.Instructions( 71 | ################## 72 | ## Parse packet ## 73 | ################## 74 | 75 | # Add ethernet header fields in the header set 76 | I.ADD(O.Field(Field('eth_dst')), 77 | Size(48)), 78 | I.ADD(O.Field(Field('eth_src')), 79 | Size(48)), 80 | I.ADD(O.Field(Field('eth_type')), 81 | Size(16)), 82 | 83 | # Load fields with default values 84 | I.LD(O.Field(Field('eth_dst')), 85 | O.Value(Value(0, Size(48)))), 86 | I.LD(O.Field(Field('eth_src')), 87 | O.Value(Value(0, Size(48)))), 88 | I.LD(O.Field(Field('eth_type')), 89 | O.Value(Value(0, Size(16)))), 90 | 91 | # Parse ethernet 92 | # load ethernet header fields from the packet 93 | I.LD(O.Field(Field('eth_dst')), 94 | O.Location( 95 | Location( 96 | O.Value(Value(0, Size(16)))))), 97 | I.LD(O.Field(Field('eth_src')), 98 | O.Location( 99 | Location( 100 | O.Value(Value(48, Size(16)))))), 101 | I.LD(O.Field(Field('eth_type')), 102 | O.Location( 103 | Location( 104 | O.Value(Value(96, Size(16)))))), 105 | 106 | ################## 107 | ## Pass through ## 108 | ################## 109 | 110 | # Add the following header fields in the header set 111 | I.ADD(O.Field(Field('index')), 112 | Size(16)), 113 | 114 | # Lookup in the match table and store the matched index 115 | I.LKt(O.Field(Field('index')), 116 | TableId('match_table'), 117 | O.Operands_( 118 | O.Field(Field('eth_src')))), 119 | I.BR(O.Field(Field('index')), 120 | Op.Neq, 121 | O.Value(Value(-1, Size(16))), 122 | Label('LBL_PT_0')), 123 | 124 | # Case: there is not match in the match table 125 | # send to controller 126 | I.CTR(Reason('MATCH_TABLE_MISS', '')), 127 | I.JMP(Label('LBL_HLT')), 128 | 129 | # Case: there is a match in the l2 match table 130 | I.LBL(Label('LBL_PT_0')), 131 | 132 | # Load output port and others from the l2 parameters table 133 | I.LDt( 134 | O.Operands__( 135 | O.Field(Field('outport_bitmap'))), 136 | TableId('params_table'), 137 | O.Field(Field('index'))), 138 | 139 | ########## 140 | ## Halt ## 141 | ########## 142 | I.LBL(Label('LBL_HLT')), 143 | I.HLT() 144 | ) 145 | ) 146 | 147 | return Policy(decls, code) -------------------------------------------------------------------------------- /netasm/examples/netasm/hybrid/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'mshahbaz' 2 | -------------------------------------------------------------------------------- /netasm/examples/netasm/standalone/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | -------------------------------------------------------------------------------- /netasm/examples/netasm/standalone/decrement_loop.py: -------------------------------------------------------------------------------- 1 | __author__ = 'mshahbaz' 2 | 3 | # ################################################################################- 4 | # ## 5 | # ## https://github.com/NetASM/NetASM-python 6 | # ## 7 | # ## File: 8 | # ## hub.py 9 | # ## 10 | # ## Project: 11 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 12 | # ## 13 | # ## Author: 14 | # ## Muhammad Shahbaz 15 | # ## 16 | # ## Copyright notice: 17 | # ## Copyright (C) 2014 Princeton University 18 | # ## Network Operations and Internet Security Lab 19 | # ## 20 | # ## Licence: 21 | # ## This file is a part of the NetASM development base package. 22 | # ## 23 | # ## This file is free code: you can redistribute it and/or modify it under 24 | # ## the terms of the GNU Lesser General Public License version 2.1 as 25 | # ## published by the Free Software Foundation. 26 | # ## 27 | # ## This package is distributed in the hope that it will be useful, but 28 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 29 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 30 | # ## Lesser General Public License for more details. 31 | # ## 32 | # ## You should have received a copy of the GNU Lesser General Public 33 | # ## License along with the NetASM source package. If not, see 34 | # ## http://www.gnu.org/licenses/. 35 | 36 | __author__ = 'shahbaz' 37 | 38 | from netasm.netasm.core import * 39 | 40 | 41 | def main(): 42 | decls = Decls(TableDecls()) 43 | 44 | PORT_COUNT_BITMAP = 0xFFFF # mean [... bit(1): port_2, bit(0): port_1] 45 | 46 | code = I.Code( 47 | Fields(), 48 | I.Instructions( 49 | I.ADD( 50 | O.Field(Field('reg0')), 51 | Size(16) 52 | ), 53 | I.LD( 54 | O.Field(Field('reg0')), 55 | O.Value(Value(4, Size(16))) 56 | ), 57 | I.LBL(Label('LBL_0')), 58 | I.BR( 59 | O.Field(Field('reg0')), 60 | Op.Eq, 61 | O.Value(Value(0, Size(16))), 62 | Label('LBL_HLT') 63 | ), 64 | I.OP( 65 | O.Field(Field('reg0')), 66 | O.Field(Field('reg0')), 67 | Op.Sub, 68 | O.Value(Value(1, Size(16))), 69 | ), 70 | I.JMP(Label('LBL_0')), 71 | I.LBL(Label('LBL_HLT')), 72 | I.LD( 73 | O.Field(Field('outport_bitmap')), 74 | O.Field(Field('reg0')) 75 | ), 76 | I.HLT() 77 | ) 78 | ) 79 | 80 | return Policy(decls, code) 81 | 82 | # Testing 83 | if __name__ == "__main__": 84 | policy = main() 85 | 86 | # CFG 87 | if False: 88 | import netasm.netasm.core.graphs.control_flow_graph as cfg 89 | graph = cfg.generate(policy.code.instructions) 90 | print graph 91 | 92 | # Cost 93 | if False: 94 | from netasm.netasm import cost 95 | area, latency = cost.cost_Policy(policy) 96 | print area, latency 97 | 98 | # Execute 99 | if True: 100 | from netasm.netasm import execute 101 | 102 | policy = execute.Execute(policy) 103 | 104 | state = execute.State(execute.Header(), execute.Packet(1000)) 105 | # Add special fields (see netasm/core/common.py) 106 | state.header[Field('inport_bitmap')] = Value(0, Size(64)) 107 | state.header[Field('outport_bitmap')] = Value(0xFFFF, Size(64)) 108 | state.header[Field('bit_length')] = Value(len(state.packet), Size(64)) 109 | state.header[Field('DRP')] = Value(0, Size(1)) 110 | state.header[Field('CTR')] = Value(0, Size(1)) 111 | 112 | policy.start() 113 | 114 | from netasm.netasm.core.utilities.profile import time_usage 115 | 116 | @time_usage 117 | def run(): 118 | iterations = 1 119 | 120 | for i in range(iterations): 121 | policy.put(state) 122 | 123 | for i in range(iterations): 124 | _state = policy.get() 125 | print _state.header[Field('outport_bitmap')].value 126 | 127 | run() 128 | 129 | policy.stop() -------------------------------------------------------------------------------- /netasm/examples/netasm/standalone/hub.py: -------------------------------------------------------------------------------- 1 | # ################################################################################- 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## hub.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from netasm.netasm.core import * 37 | 38 | 39 | def main(): 40 | decls = Decls(TableDecls()) 41 | 42 | PORT_COUNT_BITMAP = 0xFFFF # mean [... bit(1): port_2, bit(0): port_1] 43 | 44 | code = I.Code( 45 | Fields(), 46 | I.Instructions( 47 | I.OP( 48 | O.Field(Field('outport_bitmap')), 49 | O.Field(Field('inport_bitmap')), 50 | Op.Xor, 51 | O.Value(Value(PORT_COUNT_BITMAP, Size(16))), 52 | ), 53 | I.HLT() 54 | ) 55 | ) 56 | 57 | return Policy(decls, code) 58 | 59 | -------------------------------------------------------------------------------- /netasm/examples/netasm/standalone/learning_switch.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## learning_switch.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from netasm.netasm.core import * 37 | 38 | 39 | # NOTE: We are not considering loop avoidance but we do take into account host migration in this example 40 | 41 | 42 | def main(): 43 | # Constants 44 | PORT_COUNT_BITMAP = 0xFFFF # means [... bit(1): port_2, bit(0): port_1] 45 | 46 | # Declarations 47 | decls = Decls(TableDecls()) 48 | 49 | # Tables 50 | # Ethernet address table 51 | MAC_TABLE_SIZE = Size(16) 52 | decls.table_decls[TableId('eth_match_table')] = \ 53 | Table(TableFieldsCollection.MatchFields(), 54 | MAC_TABLE_SIZE, 55 | TableTypeCollection.CAM) 56 | match_table = decls.table_decls[TableId('eth_match_table')] 57 | match_table.table_fields[Field('eth_addr')] = Size(48), MatchTypeCollection.Binary 58 | 59 | decls.table_decls[TableId('eth_params_table')] = \ 60 | Table(TableFieldsCollection.SimpleFields(), 61 | MAC_TABLE_SIZE, 62 | TableTypeCollection.RAM) 63 | params_table = decls.table_decls[TableId('eth_params_table')] 64 | params_table.table_fields[Field('outport_bitmap')] = Size(3) 65 | 66 | # Index address table 67 | INDEX_TABLE_SIZE = Size(1) 68 | decls.table_decls[TableId('index_table')] = \ 69 | Table(TableFieldsCollection.SimpleFields(), 70 | INDEX_TABLE_SIZE, 71 | TableTypeCollection.RAM) 72 | index_table = decls.table_decls[TableId('index_table')] 73 | index_table.table_fields[Field('index')] = Size(16) 74 | 75 | # Code 76 | code = I.Code( 77 | ################## 78 | ### Arguments #### 79 | ################## 80 | Fields(), 81 | 82 | ################## 83 | ## Instructions ## 84 | ################## 85 | I.Instructions( 86 | ################## 87 | ## Parse packet ## 88 | ################## 89 | 90 | # Add ethernet header fields in the header set 91 | I.ADD(O.Field(Field('eth_dst')), 92 | Size(48)), 93 | I.ADD(O.Field(Field('eth_src')), 94 | Size(48)), 95 | I.ADD(O.Field(Field('eth_type')), 96 | Size(16)), 97 | 98 | # Load fields with default values 99 | I.LD(O.Field(Field('eth_dst')), 100 | O.Value(Value(0, Size(48)))), 101 | I.LD(O.Field(Field('eth_src')), 102 | O.Value(Value(0, Size(48)))), 103 | I.LD(O.Field(Field('eth_type')), 104 | O.Value(Value(0, Size(16)))), 105 | 106 | # Parse ethernet 107 | # load ethernet header fields from the packet 108 | I.LD(O.Field(Field('eth_dst')), 109 | O.Location( 110 | Location( 111 | O.Value(Value(0, Size(16)))))), 112 | I.LD(O.Field(Field('eth_src')), 113 | O.Location( 114 | Location( 115 | O.Value(Value(48, Size(16)))))), 116 | I.LD(O.Field(Field('eth_type')), 117 | O.Location( 118 | Location( 119 | O.Value(Value(96, Size(16)))))), 120 | 121 | ######################## 122 | ## Lookup MAC address ## 123 | ######################## 124 | 125 | # Add the following header fields in the header set 126 | I.ADD(O.Field(Field('index')), 127 | Size(16)), 128 | 129 | I.ATM( 130 | I.Code( 131 | Fields(Field('index'), Field('eth_dst'), Field('eth_src')), 132 | I.Instructions( 133 | # Lookup in the match table and store the matched index 134 | I.LKt(O.Field(Field('index')), 135 | TableId('eth_match_table'), 136 | O.Operands_( 137 | O.Field(Field('eth_dst')))), 138 | I.BR(O.Field(Field('index')), 139 | Op.Neq, 140 | O.Value(Value(-1, Size(16))), 141 | Label('LBL_LKP_0')), 142 | 143 | # Case: there is no match in the match table 144 | # Broadcast the packet 145 | I.OP( 146 | O.Field(Field('outport_bitmap')), 147 | O.Field(Field('inport_bitmap')), 148 | Op.Xor, 149 | O.Value(Value(PORT_COUNT_BITMAP, Size(16))), 150 | ), 151 | I.JMP(Label('LBL_LRN')), 152 | 153 | # Case: there is a match in the l2 match table 154 | I.LBL(Label('LBL_LKP_0')), 155 | 156 | # Load output port from the parameters table 157 | I.LDt( 158 | O.Operands__( 159 | O.Field(Field('outport_bitmap'))), 160 | TableId('eth_params_table'), 161 | O.Field(Field('index'))), 162 | 163 | ####################### 164 | ## Learn MAC address ## 165 | ####################### 166 | I.LBL(Label('LBL_LRN')), 167 | 168 | # Lookup in the match table and store the matched index 169 | I.LKt(O.Field(Field('index')), 170 | TableId('eth_match_table'), 171 | O.Operands_( 172 | O.Field(Field('eth_src')))), 173 | I.BR(O.Field(Field('index')), 174 | Op.Neq, 175 | O.Value(Value(-1, Size(16))), 176 | Label('LBL_LRN_0')), 177 | 178 | # Case: there is no match in the match table 179 | # Read the running index from the index table 180 | I.LDt( 181 | O.Operands__( 182 | O.Field(Field('index'))), 183 | TableId('index_table'), 184 | O.Value(Value(0, Size(1)))), 185 | 186 | # Store eth_src in the eth_match_table 187 | I.STt(TableId('eth_match_table'), 188 | O.Field(Field('index')), 189 | O.OperandsMasks_( 190 | (O.Field(Field('eth_src')), Mask(0xFFFFFFFFFFFF)))), 191 | 192 | # Store inport_bitmap in the eth_params_table 193 | I.STt(TableId('eth_params_table'), 194 | O.Field(Field('index')), 195 | O.Operands_( 196 | O.Field(Field('inport_bitmap')))), 197 | 198 | # Increment the running index 199 | I.OP( 200 | O.Field(Field('index')), 201 | O.Field(Field('index')), 202 | Op.Add, 203 | O.Value(Value(1, Size(16))), 204 | ), 205 | 206 | # Check if the index is less than the MAC_TABLE_SIZE 207 | I.BR(O.Field(Field('index')), 208 | Op.Lt, 209 | O.Value(Value(MAC_TABLE_SIZE, Size(16))), 210 | Label('LBL_LRN_1')), 211 | 212 | # Reset the running index 213 | I.LD(O.Field(Field('index')), 214 | O.Value(Value(0, Size(16)))), 215 | 216 | # Store the running index back in the table 217 | I.LBL(Label('LBL_LRN_1')), 218 | 219 | I.STt(TableId('index_table'), 220 | O.Value(Value(0, Size(1))), 221 | O.Operands_( 222 | O.Field(Field('index')))), 223 | I.JMP(Label('LBL_HLT')), 224 | 225 | # Store the current inport_bitmap in the eth_params_table 226 | I.LBL(Label('LBL_LRN_0')), 227 | 228 | I.STt(TableId('eth_params_table'), 229 | O.Field(Field('index')), 230 | O.Operands_( 231 | O.Field(Field('inport_bitmap')))), 232 | 233 | # Halt 234 | I.LBL(Label('LBL_HLT')), 235 | I.HLT() 236 | ) 237 | ) 238 | ), 239 | 240 | ########## 241 | ## Halt ## 242 | ########## 243 | I.LBL(Label('LBL_HLT')), 244 | I.HLT() 245 | ) 246 | ) 247 | 248 | return Policy(decls, code) 249 | 250 | # Testing 251 | if __name__ == "__main__": 252 | policy = main() 253 | 254 | # Cost 255 | if True: 256 | from netasm.netasm import cost 257 | area, latency = cost.cost_Policy(policy) 258 | print area, latency 259 | 260 | # Execute 261 | if False: 262 | from netasm.netasm import execute 263 | 264 | policy = execute.Execute(policy) 265 | 266 | state = execute.State(execute.Header(), execute.Packet(1000)) 267 | # Add special fields (see netasm/core/common.py) 268 | state.header[Field('inport_bitmap')] = Value(0, Size(64)) 269 | state.header[Field('outport_bitmap')] = Value(0, Size(64)) 270 | state.header[Field('bit_length')] = Value(len(state.packet), Size(64)) 271 | state.header[Field('DRP')] = Value(0, Size(1)) 272 | state.header[Field('CTR')] = Value(0, Size(1)) 273 | 274 | policy.start() 275 | 276 | from netasm.netasm.core.utilities.profile import time_usage 277 | 278 | @time_usage 279 | def run(): 280 | iterations = 100 281 | 282 | for i in range(iterations): 283 | policy.put(state) 284 | 285 | for i in range(iterations): 286 | policy.get() 287 | 288 | run() 289 | 290 | policy.stop() 291 | -------------------------------------------------------------------------------- /netasm/examples/netasm/standalone/pass_through_2ports.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## pass_through_2ports.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from netasm.netasm.core import * 37 | 38 | 39 | def main(): 40 | decls = Decls(TableDecls()) 41 | 42 | code = I.Code( 43 | Fields(), 44 | I.Instructions( 45 | I.BR( 46 | O.Field(Field('inport_bitmap')), 47 | Op.Eq, 48 | O.Value(Value(2, Size(2))), 49 | Label('LBL_1') 50 | ), 51 | I.LD( 52 | O.Field(Field('outport_bitmap')), 53 | O.Value(Value(2, Size(2))) 54 | ), 55 | I.JMP( 56 | Label('LBL_HLT') 57 | ), 58 | I.LBL( 59 | Label('LBL_1') 60 | ), 61 | I.LD( 62 | O.Field(Field('outport_bitmap')), 63 | O.Value(Value(1, Size(1))) 64 | ), 65 | I.LBL( 66 | Label('LBL_HLT') 67 | ), 68 | I.HLT() 69 | ) 70 | ) 71 | 72 | return Policy(decls, code) 73 | -------------------------------------------------------------------------------- /netasm/netasm/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | -------------------------------------------------------------------------------- /netasm/netasm/core/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from netasm.netasm.core.syntax import * 37 | from netasm.netasm.core.syntax import InstructionCollection as I, OperandCollection as O, OperatorCollection as Op -------------------------------------------------------------------------------- /netasm/netasm/core/analyses/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | -------------------------------------------------------------------------------- /netasm/netasm/core/analyses/field_reachability.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## field_reachability.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | # Note: reachability analysis just operates on fields 37 | 38 | from netasm.netasm.core.syntax import InstructionCollection as I, OperandCollection as O 39 | from netasm.netasm.core.graphs.control_flow_graph import Entry 40 | 41 | 42 | class Use: 43 | def __init__(self): 44 | raise NotImplementedError 45 | 46 | @staticmethod 47 | def field(instruction, argument_fields, exclude_list): 48 | operands = set() 49 | 50 | if any(map(lambda instruction_type: isinstance(instruction, instruction_type), exclude_list)): 51 | pass 52 | elif isinstance(instruction, Entry): 53 | # for field in argument_fields: 54 | # operands |= {field} 55 | # for field in get_reserved_fields(): 56 | # operands |= {field} 57 | pass 58 | elif isinstance(instruction, I.ADD): 59 | operands |= {instruction.field.field} 60 | elif isinstance(instruction, I.LD): 61 | if isinstance(instruction.source, O.Field): 62 | operands |= {instruction.source.field} 63 | if isinstance(instruction.destination, O.Field): 64 | operands |= {instruction.destination.field} 65 | elif isinstance(instruction, I.ST): 66 | if isinstance(instruction.source, O.Field): 67 | operands |= {instruction.source.field} 68 | if isinstance(instruction.location, O.Location): 69 | if isinstance(instruction.location.location.offset, O.Field): 70 | operands |= {instruction.location.location.offset.field} 71 | if isinstance(instruction.location.location.length, O.Field): 72 | operands |= {instruction.location.location.length.field} 73 | else: 74 | raise RuntimeError() 75 | elif isinstance(instruction, I.OP): 76 | if isinstance(instruction.left_source, O.Field): 77 | operands |= {instruction.left_source.field} 78 | if isinstance(instruction.right_source, O.Field): 79 | operands |= {instruction.right_source.field} 80 | if isinstance(instruction.destination, O.Field): 81 | operands |= {instruction.destination.field} 82 | elif isinstance(instruction, I.PUSH): 83 | if isinstance(instruction.location, O.Location): 84 | if isinstance(instruction.location.location.offset, O.Field): 85 | operands |= {instruction.location.location.offset.field} 86 | if isinstance(instruction.location.location.length, O.Field): 87 | operands |= {instruction.location.location.length.field} 88 | else: 89 | raise RuntimeError() 90 | elif isinstance(instruction, I.POP): 91 | if isinstance(instruction.location, O.Location): 92 | if isinstance(instruction.location.location.offset, O.Field): 93 | operands |= {instruction.location.location.offset.field} 94 | if isinstance(instruction.location.location.length, O.Field): 95 | operands |= {instruction.location.location.length.field} 96 | else: 97 | raise RuntimeError() 98 | elif isinstance(instruction, I.BR): 99 | if isinstance(instruction.left_source, O.Field): 100 | operands |= {instruction.left_source.field} 101 | if isinstance(instruction.right_source, O.Field): 102 | operands |= {instruction.right_source.field} 103 | elif isinstance(instruction, I.LDt): 104 | if isinstance(instruction.index, O.Field): 105 | operands |= {instruction.index.field} 106 | if isinstance(instruction.destinations, O.Operands__): 107 | for operand in instruction.destinations: 108 | if isinstance(operand, O.Field): 109 | operands |= {operand.field} 110 | else: 111 | raise RuntimeError() 112 | elif isinstance(instruction, I.STt): 113 | if isinstance(instruction.index, O.Field): 114 | operands |= {instruction.index.field} 115 | if isinstance(instruction.sources, O.Operands_): 116 | for operand in instruction.sources: 117 | if isinstance(operand, O.Field): 118 | operands |= {operand.field} 119 | elif isinstance(instruction.sources, O.OperandsMasks_): 120 | for operand, _ in instruction.sources: 121 | if isinstance(operand, O.Field): 122 | operands |= {operand.field} 123 | else: 124 | raise RuntimeError() 125 | elif isinstance(instruction, I.INCt): 126 | if isinstance(instruction.index, O.Field): 127 | operands |= {instruction.index.field} 128 | elif isinstance(instruction, I.LKt): 129 | if isinstance(instruction.sources, O.Operands_): 130 | for operand in instruction.sources: 131 | if isinstance(operand, O.Field): 132 | operands |= {operand.field} 133 | else: 134 | raise RuntimeError() 135 | if isinstance(instruction.index, O.Field): 136 | operands |= {instruction.index.field} 137 | elif isinstance(instruction, I.CRC): 138 | if isinstance(instruction.sources, O.Operands_): 139 | for operand in instruction.sources: 140 | if isinstance(operand, O.Field): 141 | operands |= {operand.field} 142 | else: 143 | raise RuntimeError() 144 | if isinstance(instruction.destination, O.Field): 145 | operands |= {instruction.destination.field} 146 | elif isinstance(instruction, I.HSH): 147 | if isinstance(instruction.sources, O.Operands_): 148 | for operand in instruction.sources: 149 | if isinstance(operand, O.Field): 150 | operands |= {operand.field} 151 | else: 152 | raise RuntimeError() 153 | if isinstance(instruction.destination, O.Field): 154 | operands |= {instruction.destination.field} 155 | elif isinstance(instruction, I.CNC): 156 | if isinstance(instruction.codes, I.Codes): 157 | for code in instruction.codes: 158 | for field in code.argument_fields: 159 | operands |= {field} 160 | else: 161 | raise RuntimeError() 162 | elif isinstance(instruction, I.ATM): 163 | if isinstance(instruction.code, I.Code): 164 | for field in instruction.code.argument_fields: 165 | operands |= {field} 166 | else: 167 | raise RuntimeError() 168 | elif isinstance(instruction, I.SEQ): 169 | if isinstance(instruction.code, I.Code): 170 | for field in instruction.code.argument_fields: 171 | operands |= {field} 172 | else: 173 | raise RuntimeError() 174 | elif isinstance(instruction, I.Instruction): 175 | pass 176 | else: 177 | raise RuntimeError() 178 | 179 | return operands 180 | 181 | 182 | class Kill: 183 | def __init__(self): 184 | raise NotImplementedError 185 | 186 | @staticmethod 187 | def field(instruction, argument_fields, exclude_list): 188 | operands = set() 189 | 190 | if any(map(lambda instruction_type: isinstance(instruction, instruction_type), exclude_list)): 191 | pass 192 | elif isinstance(instruction, I.RMV): 193 | operands |= {instruction.field.field} 194 | elif isinstance(instruction, I.Instruction): 195 | pass 196 | else: 197 | raise RuntimeError() 198 | 199 | return operands 200 | 201 | 202 | # Propagate reachability information once at every node in the flow graph 203 | def _step(flow_graph, ins, outs, argument_fields, exclude_list): 204 | use_ = Use.field 205 | kill_ = Kill.field 206 | 207 | for _, node in flow_graph.iteritems(): 208 | previous_instruction = None 209 | 210 | for instruction in node.basic_block: 211 | _out = [] 212 | if not previous_instruction: 213 | for n in node.predecessors: 214 | last_instruction = flow_graph[n].basic_block[-1] 215 | _out.append(outs[last_instruction]) 216 | else: 217 | _out.append(outs[previous_instruction]) 218 | previous_instruction = instruction 219 | 220 | _in = set.union(set(), *_out) 221 | _out = (use_(instruction, argument_fields, exclude_list) | 222 | (_in - kill_(instruction, argument_fields, exclude_list))) 223 | ins[instruction] = _in 224 | outs[instruction] = _out 225 | 226 | 227 | # Iterates until a fixed-point is reached 228 | def _solve(flow_graph, ins, outs, argument_fields, exclude_list): 229 | _outs = outs.copy() 230 | _step(flow_graph, ins, _outs, argument_fields, exclude_list) 231 | 232 | if all(map(lambda i: outs[i] == _outs[i], outs.keys())): 233 | return ins, outs 234 | else: 235 | return _solve(flow_graph, ins, _outs, argument_fields, exclude_list) 236 | 237 | 238 | # Compute field reachability in/out fields at every node in the control flow graph 239 | def analyse(flow_graph, argument_fields, exclude_list): 240 | ins = {} 241 | outs = {} 242 | for _, node in flow_graph.iteritems(): 243 | for instruction in node.basic_block: 244 | ins[instruction] = set() 245 | outs[instruction] = set() 246 | return _solve(flow_graph, ins, outs, argument_fields, exclude_list) -------------------------------------------------------------------------------- /netasm/netasm/core/analyses/field_usability.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## field_usability.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | # Note: usability analysis just operates on fields 37 | 38 | from netasm.netasm.core.syntax import InstructionCollection as I, OperandCollection as O 39 | from netasm.netasm.core.graphs.control_flow_graph import Exit 40 | 41 | 42 | class Gen: 43 | def __init__(self): 44 | raise NotImplementedError 45 | 46 | @staticmethod 47 | def field(instruction, argument_fields, exclude_list): 48 | operands = set() 49 | 50 | if any(map(lambda instruction_type: isinstance(instruction, instruction_type), exclude_list)): 51 | pass 52 | elif isinstance(instruction, I.ADD): 53 | operands |= {instruction.field.field} 54 | elif isinstance(instruction, I.Instruction): 55 | pass 56 | else: 57 | raise RuntimeError() 58 | 59 | return operands 60 | 61 | 62 | class Use: 63 | def __init__(self): 64 | raise NotImplementedError 65 | 66 | @staticmethod 67 | def field(instruction, argument_fields, exclude_list): 68 | operands = set() 69 | 70 | if any(map(lambda instruction_type: isinstance(instruction, instruction_type), exclude_list)): 71 | pass 72 | elif isinstance(instruction, I.RMV): 73 | operands |= {instruction.field.field} 74 | elif isinstance(instruction, I.LD): 75 | if isinstance(instruction.source, O.Field): 76 | operands |= {instruction.source.field} 77 | if isinstance(instruction.destination, O.Field): 78 | operands |= {instruction.destination.field} 79 | elif isinstance(instruction, I.ST): 80 | if isinstance(instruction.source, O.Field): 81 | operands |= {instruction.source.field} 82 | if isinstance(instruction.location, O.Location): 83 | if isinstance(instruction.location.location.offset, O.Field): 84 | operands |= {instruction.location.location.offset.field} 85 | if isinstance(instruction.location.location.length, O.Field): 86 | operands |= {instruction.location.location.length.field} 87 | else: 88 | raise RuntimeError() 89 | elif isinstance(instruction, I.OP): 90 | if isinstance(instruction.left_source, O.Field): 91 | operands |= {instruction.left_source.field} 92 | if isinstance(instruction.right_source, O.Field): 93 | operands |= {instruction.right_source.field} 94 | if isinstance(instruction.destination, O.Field): 95 | operands |= {instruction.destination.field} 96 | elif isinstance(instruction, I.PUSH): 97 | if isinstance(instruction.location, O.Location): 98 | if isinstance(instruction.location.location.offset, O.Field): 99 | operands |= {instruction.location.location.offset.field} 100 | if isinstance(instruction.location.location.length, O.Field): 101 | operands |= {instruction.location.location.length.field} 102 | else: 103 | raise RuntimeError() 104 | elif isinstance(instruction, I.POP): 105 | if isinstance(instruction.location, O.Location): 106 | if isinstance(instruction.location.location.offset, O.Field): 107 | operands |= {instruction.location.location.offset.field} 108 | if isinstance(instruction.location.location.length, O.Field): 109 | operands |= {instruction.location.location.length.field} 110 | else: 111 | raise RuntimeError() 112 | elif isinstance(instruction, I.BR): 113 | if isinstance(instruction.left_source, O.Field): 114 | operands |= {instruction.left_source.field} 115 | if isinstance(instruction.right_source, O.Field): 116 | operands |= {instruction.right_source.field} 117 | elif isinstance(instruction, I.LDt): 118 | if isinstance(instruction.index, O.Field): 119 | operands |= {instruction.index.field} 120 | if isinstance(instruction.destinations, O.Operands__): 121 | for operand in instruction.destinations: 122 | if isinstance(operand, O.Field): 123 | operands |= {operand.field} 124 | else: 125 | raise RuntimeError() 126 | elif isinstance(instruction, I.STt): 127 | if isinstance(instruction.index, O.Field): 128 | operands |= {instruction.index.field} 129 | if isinstance(instruction.sources, O.Operands_): 130 | for operand in instruction.sources: 131 | if isinstance(operand, O.Field): 132 | operands |= {operand.field} 133 | elif isinstance(instruction.sources, O.OperandsMasks_): 134 | for operand, _ in instruction.sources: 135 | if isinstance(operand, O.Field): 136 | operands |= {operand.field} 137 | else: 138 | raise RuntimeError() 139 | elif isinstance(instruction, I.INCt): 140 | if isinstance(instruction.index, O.Field): 141 | operands |= {instruction.index.field} 142 | elif isinstance(instruction, I.LKt): 143 | if isinstance(instruction.sources, O.Operands_): 144 | for operand in instruction.sources: 145 | if isinstance(operand, O.Field): 146 | operands |= {operand.field} 147 | else: 148 | raise RuntimeError() 149 | if isinstance(instruction.index, O.Field): 150 | operands |= {instruction.index.field} 151 | elif isinstance(instruction, I.CRC): 152 | if isinstance(instruction.sources, O.Operands_): 153 | for operand in instruction.sources: 154 | if isinstance(operand, O.Field): 155 | operands |= {operand.field} 156 | else: 157 | raise RuntimeError() 158 | if isinstance(instruction.destination, O.Field): 159 | operands |= {instruction.destination.field} 160 | elif isinstance(instruction, I.HSH): 161 | if isinstance(instruction.sources, O.Operands_): 162 | for operand in instruction.sources: 163 | if isinstance(operand, O.Field): 164 | operands |= {operand.field} 165 | else: 166 | raise RuntimeError() 167 | if isinstance(instruction.destination, O.Field): 168 | operands |= {instruction.destination.field} 169 | elif isinstance(instruction, I.CNC): 170 | if isinstance(instruction.codes, I.Codes): 171 | for code in instruction.codes: 172 | for field in code.argument_fields: 173 | operands |= {field} 174 | else: 175 | raise RuntimeError() 176 | elif isinstance(instruction, I.ATM): 177 | if isinstance(instruction.code, I.Code): 178 | for field in instruction.code.argument_fields: 179 | operands |= {field} 180 | else: 181 | raise RuntimeError() 182 | elif isinstance(instruction, I.SEQ): 183 | if isinstance(instruction.code, I.Code): 184 | for field in instruction.code.argument_fields: 185 | operands |= {field} 186 | else: 187 | raise RuntimeError() 188 | elif isinstance(instruction, Exit): 189 | # for field in argument_fields: 190 | # operands |= {field} 191 | # for field in get_reserved_fields(): 192 | # operands |= {field} 193 | pass 194 | elif isinstance(instruction, I.Instruction): 195 | pass 196 | else: 197 | raise RuntimeError() 198 | 199 | return operands 200 | 201 | 202 | # Propagate usability information once at every node in the flow graph 203 | def _step(flow_graph, ins, outs, argument_fields, exclude_list): 204 | gen_ = Gen.field 205 | use_ = Use.field 206 | 207 | for _, node in flow_graph.iteritems(): 208 | next_instruction = None 209 | 210 | for instruction in node.basic_block[::-1]: 211 | _in = [] 212 | if not next_instruction: 213 | for n in node.successors: 214 | first_instruction = flow_graph[n].basic_block[0] 215 | _in.append(ins[first_instruction]) 216 | else: 217 | _in.append(ins[next_instruction]) 218 | next_instruction = instruction 219 | 220 | _out = set.union(set(), *_in) 221 | _in = (use_(instruction, argument_fields, exclude_list) | 222 | (_out - gen_(instruction, argument_fields, exclude_list))) 223 | ins[instruction] = _in 224 | outs[instruction] = _out 225 | 226 | 227 | # Iterates until a fixed-point is reached 228 | def _solve(flow_graph, ins, outs, argument_fields, exclude_list): 229 | _ins = ins.copy() 230 | _step(flow_graph, _ins, outs, argument_fields, exclude_list) 231 | 232 | if all(map(lambda l: ins[l] == _ins[l], ins.keys())): 233 | return ins, outs 234 | else: 235 | return _solve(flow_graph, _ins, outs, argument_fields, exclude_list) 236 | 237 | 238 | # Compute the field usability in/out fields at every node in control flow graph 239 | def analyse(flow_graph, argument_fields, exclude_list): 240 | ins = {} 241 | outs = {} 242 | for _, node in flow_graph.iteritems(): 243 | for instruction in node.basic_block: 244 | ins[instruction] = set() 245 | outs[instruction] = set() 246 | return _solve(flow_graph, ins, outs, argument_fields, exclude_list) -------------------------------------------------------------------------------- /netasm/netasm/core/analyses/liveness.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## liveness.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from netasm.netasm.core.syntax import InstructionCollection as I, OperandCollection as O 37 | from netasm.netasm.core.common import is_reserved_field 38 | from netasm.netasm.core.graphs.control_flow_graph import Exit 39 | 40 | 41 | class Use: 42 | def __init__(self): 43 | raise NotImplementedError 44 | 45 | @staticmethod 46 | def field(instruction, argument_fields, exclude_list): 47 | operands = set() 48 | 49 | if any(map(lambda instruction_type: isinstance(instruction, instruction_type), exclude_list)): 50 | pass 51 | # I.ID 52 | # I.DRP 53 | # I.CTR 54 | # I.ADD 55 | elif isinstance(instruction, I.RMV): 56 | operands |= {instruction.field.field} 57 | elif isinstance(instruction, I.LD): 58 | if isinstance(instruction.source, O.Field): 59 | operands |= {instruction.source.field} 60 | elif isinstance(instruction, I.ST): 61 | if isinstance(instruction.source, O.Field): 62 | operands |= {instruction.source.field} 63 | if isinstance(instruction.location, O.Location): 64 | if isinstance(instruction.location.location.offset, O.Field): 65 | operands |= {instruction.location.location.offset.field} 66 | if isinstance(instruction.location.location.length, O.Field): 67 | operands |= {instruction.location.location.length.field} 68 | else: 69 | raise RuntimeError() 70 | elif isinstance(instruction, I.OP): 71 | if isinstance(instruction.left_source, O.Field): 72 | operands |= {instruction.left_source.field} 73 | if isinstance(instruction.right_source, O.Field): 74 | operands |= {instruction.right_source.field} 75 | elif isinstance(instruction, I.PUSH): 76 | if isinstance(instruction.location, O.Location): 77 | if isinstance(instruction.location.location.offset, O.Field): 78 | operands |= {instruction.location.location.offset.field} 79 | if isinstance(instruction.location.location.length, O.Field): 80 | operands |= {instruction.location.location.length.field} 81 | else: 82 | raise RuntimeError() 83 | elif isinstance(instruction, I.POP): 84 | if isinstance(instruction.location, O.Location): 85 | if isinstance(instruction.location.location.offset, O.Field): 86 | operands |= {instruction.location.location.offset.field} 87 | if isinstance(instruction.location.location.length, O.Field): 88 | operands |= {instruction.location.location.length.field} 89 | else: 90 | raise RuntimeError() 91 | elif isinstance(instruction, I.BR): 92 | if isinstance(instruction.left_source, O.Field): 93 | operands |= {instruction.left_source.field} 94 | if isinstance(instruction.right_source, O.Field): 95 | operands |= {instruction.right_source.field} 96 | # I.JMP 97 | # I.LBL 98 | elif isinstance(instruction, I.LDt): 99 | if isinstance(instruction.index, O.Field): 100 | operands |= {instruction.index.field} 101 | elif isinstance(instruction, I.STt): 102 | if isinstance(instruction.index, O.Field): 103 | operands |= {instruction.index.field} 104 | if isinstance(instruction.sources, O.Operands_): 105 | for operand in instruction.sources: 106 | if isinstance(operand, O.Field): 107 | operands |= {operand.field} 108 | elif isinstance(instruction.sources, O.OperandsMasks_): 109 | for operand, _ in instruction.sources: 110 | if isinstance(operand, O.Field): 111 | operands |= {operand.field} 112 | else: 113 | raise RuntimeError() 114 | elif isinstance(instruction, I.INCt): 115 | if isinstance(instruction.index, O.Field): 116 | operands |= {instruction.index.field} 117 | elif isinstance(instruction, I.LKt): 118 | if isinstance(instruction.sources, O.Operands_): 119 | for operand in instruction.sources: 120 | if isinstance(operand, O.Field): 121 | operands |= {operand.field} 122 | else: 123 | raise RuntimeError() 124 | elif isinstance(instruction, I.CRC): 125 | if isinstance(instruction.sources, O.Operands_): 126 | for operand in instruction.sources: 127 | if isinstance(operand, O.Field): 128 | operands |= {operand.field} 129 | else: 130 | raise RuntimeError() 131 | elif isinstance(instruction, I.HSH): 132 | if isinstance(instruction.sources, O.Operands_): 133 | for operand in instruction.sources: 134 | if isinstance(operand, O.Field): 135 | operands |= {operand.field} 136 | else: 137 | raise RuntimeError() 138 | # I.HLT 139 | elif isinstance(instruction, I.CNC): 140 | if isinstance(instruction.codes, I.Codes): 141 | for code in instruction.codes: 142 | for field in code.argument_fields: 143 | operands |= {field} 144 | else: 145 | raise RuntimeError() 146 | elif isinstance(instruction, I.ATM): 147 | if isinstance(instruction.code, I.Code): 148 | for field in instruction.code.argument_fields: 149 | operands |= {field} 150 | else: 151 | raise RuntimeError() 152 | elif isinstance(instruction, I.SEQ): 153 | if isinstance(instruction.code, I.Code): 154 | for field in instruction.code.argument_fields: 155 | operands |= {field} 156 | else: 157 | raise RuntimeError() 158 | elif isinstance(instruction, Exit): 159 | # for field in argument_fields: 160 | # operands |= {field} 161 | # for field in get_reserved_fields(): 162 | # operands |= {field} 163 | pass 164 | elif isinstance(instruction, I.Instruction): 165 | pass 166 | else: 167 | raise RuntimeError() 168 | 169 | return operands 170 | 171 | 172 | class Def(): 173 | def __init__(self): 174 | raise NotImplementedError 175 | 176 | @staticmethod 177 | def field(instruction, argument_fields, exclude_list): 178 | operands = set() 179 | 180 | if any(map(lambda instruction_type: isinstance(instruction, instruction_type), exclude_list)): 181 | pass 182 | # I.ID 183 | # I.DRP 184 | # I.CTR 185 | elif isinstance(instruction, I.ADD): 186 | operands |= {instruction.field.field} 187 | # I.RMV 188 | elif isinstance(instruction, I.LD): 189 | if isinstance(instruction.destination, O.Field): 190 | if not (is_reserved_field(instruction.destination.field) 191 | or instruction.destination.field in argument_fields): 192 | operands |= {instruction.destination.field} 193 | # I.ST 194 | elif isinstance(instruction, I.OP): 195 | if isinstance(instruction.destination, O.Field): 196 | if not (is_reserved_field(instruction.destination.field) 197 | or instruction.destination.field in argument_fields): 198 | operands |= {instruction.destination.field} 199 | # I.PUSH 200 | # I.POP 201 | # I.BR 202 | # I.JMP 203 | # I.LBL 204 | elif isinstance(instruction, I.LDt): 205 | if isinstance(instruction.destinations, O.Operands__): 206 | for operand in instruction.destinations: 207 | if isinstance(operand, O.Field): 208 | if not (is_reserved_field(operand.field) 209 | or operand.field in argument_fields): 210 | operands |= {operand.field} 211 | else: 212 | raise RuntimeError() 213 | # I.STt 214 | # I.INCt 215 | elif isinstance(instruction, I.LKt): 216 | if isinstance(instruction.index, O.Field): 217 | if not (is_reserved_field(instruction.index.field) 218 | or instruction.index.field in argument_fields): 219 | operands |= {instruction.index.field} 220 | elif isinstance(instruction, I.CRC): 221 | if isinstance(instruction.destination, O.Field): 222 | if not (is_reserved_field(instruction.destination.field) 223 | or instruction.destination.field in argument_fields): 224 | operands |= {instruction.destination.field} 225 | elif isinstance(instruction, I.HSH): 226 | if isinstance(instruction.destination, O.Field): 227 | if not (is_reserved_field(instruction.destination.field) 228 | or instruction.destination.field in argument_fields): 229 | operands |= {instruction.destination.field} 230 | # I.HLT 231 | elif isinstance(instruction, I.CNC): 232 | if isinstance(instruction.codes, I.Codes): 233 | for code in instruction.codes: 234 | for field in code.argument_fields: 235 | operands |= {field} 236 | else: 237 | raise RuntimeError() 238 | elif isinstance(instruction, I.ATM): 239 | if isinstance(instruction.code, I.Code): 240 | for field in instruction.code.argument_fields: 241 | operands |= {field} 242 | else: 243 | raise RuntimeError() 244 | elif isinstance(instruction, I.SEQ): 245 | if isinstance(instruction.code, I.Code): 246 | for field in instruction.code.argument_fields: 247 | operands |= {field} 248 | else: 249 | raise RuntimeError() 250 | elif isinstance(instruction, I.Instruction): 251 | pass 252 | else: 253 | raise RuntimeError() 254 | 255 | return operands 256 | 257 | 258 | # Propagate liveness information once at every node in the flow graph 259 | def _step(flow_graph, ins, outs, argument_fields, exclude_list): 260 | use_ = Use.field 261 | def_ = Def.field 262 | 263 | for _, node in flow_graph.iteritems(): 264 | next_instruction = None 265 | 266 | for instruction in node.basic_block[::-1]: 267 | _in = [] 268 | if not next_instruction: 269 | for n in node.successors: 270 | first_instruction = flow_graph[n].basic_block[0] 271 | _in.append(ins[first_instruction]) 272 | else: 273 | _in.append(ins[next_instruction]) 274 | next_instruction = instruction 275 | 276 | _out = set.union(set(), *_in) 277 | _in = (use_(instruction, argument_fields, exclude_list) | 278 | (_out - def_(instruction, argument_fields, exclude_list))) 279 | ins[instruction] = _in 280 | outs[instruction] = _out 281 | 282 | 283 | # Iterates until a fixed-point is reached 284 | def _solve(flow_graph, ins, outs, argument_fields, exclude_list): 285 | _ins = ins.copy() 286 | _step(flow_graph, _ins, outs, argument_fields, exclude_list) 287 | 288 | if all(map(lambda l: ins[l] == _ins[l], ins.keys())): 289 | return ins, outs 290 | else: 291 | return _solve(flow_graph, _ins, outs, argument_fields, exclude_list) 292 | 293 | 294 | # Compute the live-in/out fields/registers at every node in the flow graph 295 | def analyse(flow_graph, argument_fields, exclude_list): 296 | ins = {} 297 | outs = {} 298 | for _, node in flow_graph.iteritems(): 299 | for instruction in node.basic_block: 300 | ins[instruction] = set() 301 | outs[instruction] = set() 302 | return _solve(flow_graph, ins, outs, argument_fields, exclude_list) -------------------------------------------------------------------------------- /netasm/netasm/core/analyses/reaching_definitions.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## reaching_definitions.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from netasm.netasm.core.syntax import InstructionCollection as I, OperandCollection as O 37 | from netasm.netasm.core.common import is_reserved_field 38 | 39 | 40 | class Gen: 41 | def __init__(self): 42 | raise NotImplementedError 43 | 44 | @staticmethod 45 | def field(instruction, argument_fields, exclude_list): 46 | instructions = set() 47 | 48 | if any(map(lambda instruction_type: isinstance(instruction, instruction_type), exclude_list)): 49 | pass 50 | elif isinstance(instruction, I.ADD): 51 | instructions |= {instruction} 52 | elif isinstance(instruction, I.LD): 53 | if isinstance(instruction.destination, O.Field): 54 | instructions |= {instruction} 55 | elif isinstance(instruction, I.OP): 56 | if isinstance(instruction.destination, O.Field): 57 | instructions |= {instruction} 58 | elif isinstance(instruction, I.LDt): 59 | if isinstance(instruction.destinations, O.Operands_): 60 | for operand in instruction.destinations: 61 | if isinstance(operand, O.Field): 62 | instructions |= {instruction} 63 | break 64 | else: 65 | raise RuntimeError() 66 | elif isinstance(instruction, I.LKt): 67 | if isinstance(instruction.index, O.Field): 68 | instructions |= {instruction} 69 | elif isinstance(instruction, I.CRC): 70 | if isinstance(instruction.destination, O.Field): 71 | instructions |= {instruction} 72 | elif isinstance(instruction, I.HSH): 73 | if isinstance(instruction.destination, O.Field): 74 | instructions |= {instruction} 75 | elif isinstance(instruction, I.CNC): 76 | if isinstance(instruction.codes, I.Codes): 77 | for code in instruction.codes: 78 | for _ in code.argument_fields: 79 | instructions |= {instruction} 80 | break 81 | else: 82 | raise RuntimeError() 83 | elif isinstance(instruction, I.ATM): 84 | if isinstance(instruction.code, I.Code): 85 | for _ in instruction.code.argument_fields: 86 | instructions |= {instruction} 87 | break 88 | else: 89 | raise RuntimeError() 90 | elif isinstance(instruction, I.SEQ): 91 | if isinstance(instruction.code, I.Code): 92 | for _ in instruction.code.argument_fields: 93 | instructions |= {instruction} 94 | break 95 | else: 96 | raise RuntimeError() 97 | elif isinstance(instruction, I.Instruction): 98 | pass 99 | else: 100 | raise RuntimeError() 101 | 102 | return instructions 103 | 104 | 105 | class Kill: 106 | def __init__(self): 107 | raise NotImplementedError 108 | 109 | @staticmethod 110 | def field(flow_graph, instruction, argument_fields, exclude_list): 111 | 112 | def defines(flow_graph, field, argument_fields): 113 | instructions = set() 114 | 115 | for _, node in flow_graph.iteritems(): 116 | for instruction in node.basic_block: 117 | if isinstance(instruction, I.ADD): 118 | if instruction.field.field == field: 119 | instructions |= {instruction} 120 | elif isinstance(instruction, I.LD): 121 | if isinstance(instruction.destination, O.Field): 122 | if instruction.destination.field == field: 123 | if not (is_reserved_field(field) or field in argument_fields): 124 | instructions |= {instruction} 125 | elif isinstance(instruction, I.OP): 126 | if isinstance(instruction.destination, O.Field): 127 | if instruction.destination.field == field: 128 | if not (is_reserved_field(field) or field in argument_fields): 129 | instructions |= {instruction} 130 | elif isinstance(instruction, I.LDt): 131 | if isinstance(instruction.destinations, O.Operands__): 132 | for operand in instruction.destinations: 133 | if isinstance(operand, O.Field): 134 | if operand.field == field: 135 | if not (is_reserved_field(field) or field in argument_fields): 136 | instructions |= {instruction} 137 | break 138 | else: 139 | raise RuntimeError() 140 | elif isinstance(instruction, I.LKt): 141 | if isinstance(instruction.index, O.Field): 142 | if instruction.index.field == field: 143 | if not (is_reserved_field(field) or field in argument_fields): 144 | instructions |= {instruction} 145 | elif isinstance(instruction, I.CRC): 146 | if isinstance(instruction.destination, O.Field): 147 | if instruction.destination.field == field: 148 | if not (is_reserved_field(field) or field in argument_fields): 149 | instructions |= {instruction} 150 | elif isinstance(instruction, I.HSH): 151 | if isinstance(instruction.destination, O.Field): 152 | if instruction.destination.field == field: 153 | if not (is_reserved_field(field) or field in argument_fields): 154 | instructions |= {instruction} 155 | elif isinstance(instruction, I.CNC): 156 | if isinstance(instruction.codes, I.Codes): 157 | for code in instruction.codes: 158 | for _field in code.argument_fields: 159 | if _field == field: 160 | if not (is_reserved_field(field) or field in argument_fields): 161 | instructions |= {instruction} 162 | break 163 | else: 164 | raise RuntimeError() 165 | elif isinstance(instruction, I.ATM): 166 | if isinstance(instruction.code, I.Code): 167 | for _field in instruction.code.argument_fields: 168 | if _field == field: 169 | if not (is_reserved_field(field) or field in argument_fields): 170 | instructions |= {instruction} 171 | break 172 | else: 173 | raise RuntimeError() 174 | elif isinstance(instruction, I.SEQ): 175 | if isinstance(instruction.code, I.Code): 176 | for _field in instruction.code.argument_fields: 177 | if _field == field: 178 | if not (is_reserved_field(field) or field in argument_fields): 179 | instructions |= {instruction} 180 | break 181 | else: 182 | raise RuntimeError() 183 | elif isinstance(instruction, I.Instruction): 184 | pass 185 | else: 186 | raise RuntimeError() 187 | 188 | return instructions 189 | 190 | instructions = set() 191 | 192 | if any(map(lambda instruction_type: isinstance(instruction, instruction_type), exclude_list)): 193 | pass 194 | elif isinstance(instruction, I.ADD): 195 | instructions |= defines(flow_graph, instruction.field.field, argument_fields) - {instruction} 196 | elif isinstance(instruction, I.RMV): 197 | instructions |= defines(flow_graph, instruction.field.field, argument_fields) - {instruction} 198 | elif isinstance(instruction, I.LD): 199 | if isinstance(instruction.destination, O.Field): 200 | instructions |= defines(flow_graph, instruction.destination.field, argument_fields) - {instruction} 201 | elif isinstance(instruction, I.OP): 202 | if isinstance(instruction.destination, O.Field): 203 | instructions |= defines(flow_graph, instruction.destination.field, argument_fields) - {instruction} 204 | elif isinstance(instruction, I.LDt): 205 | if isinstance(instruction.destinations, O.Operands_): 206 | for operand in instruction.destinations: 207 | if isinstance(operand, O.Field): 208 | instructions |= defines(flow_graph, operand.field, argument_fields) - {instruction} 209 | # Note: a field can only be specified once in the destinations of LDt 210 | elif isinstance(instruction, I.LKt): 211 | if isinstance(instruction.index, O.Field): 212 | instructions |= defines(flow_graph, instruction.index.field, argument_fields) - {instruction} 213 | elif isinstance(instruction, I.CRC): 214 | if isinstance(instruction.destination, O.Field): 215 | instructions |= defines(flow_graph, instruction.destination.field, argument_fields) - {instruction} 216 | elif isinstance(instruction, I.HSH): 217 | if isinstance(instruction.destination, O.Field): 218 | instructions |= defines(flow_graph, instruction.destination.field, argument_fields) - {instruction} 219 | elif isinstance(instruction, I.CNC): 220 | if isinstance(instruction.codes, I.Codes): 221 | for code in instruction.codes: 222 | for field in code.argument_fields: 223 | instructions |= defines(flow_graph, field, argument_fields) - {instruction} 224 | else: 225 | raise RuntimeError() 226 | elif isinstance(instruction, I.ATM): 227 | if isinstance(instruction.code, I.Code): 228 | for field in instruction.code.argument_fields: 229 | instructions |= defines(flow_graph, field, argument_fields) - {instruction} 230 | else: 231 | raise RuntimeError() 232 | elif isinstance(instruction, I.SEQ): 233 | if isinstance(instruction.code, I.Code): 234 | for field in instruction.code.argument_fields: 235 | instructions |= defines(flow_graph, field, argument_fields) - {instruction} 236 | else: 237 | raise RuntimeError() 238 | elif isinstance(instruction, I.Instruction): 239 | pass 240 | else: 241 | raise RuntimeError() 242 | 243 | return instructions 244 | 245 | 246 | # Propagate reaching-definitions information once at every node in the flow graph 247 | def _step(flow_graph, ins, outs, argument_fields, exclude_list): 248 | gen_ = Gen.field 249 | kill_ = Kill.field 250 | 251 | for _, node in flow_graph.iteritems(): 252 | previous_instruction = None 253 | 254 | for instruction in node.basic_block: 255 | _out = [] 256 | if not previous_instruction: 257 | for n in node.predecessors: 258 | last_instruction = flow_graph[n].basic_block[-1] 259 | _out.append(outs[last_instruction]) 260 | else: 261 | _out.append(outs[previous_instruction]) 262 | previous_instruction = instruction 263 | 264 | _in = set.union(set(), *_out) 265 | _out = (gen_(instruction, argument_fields, exclude_list) | 266 | (_in - kill_(flow_graph, instruction, argument_fields, exclude_list))) 267 | ins[instruction] = _in 268 | outs[instruction] = _out 269 | 270 | 271 | # Iterates until a fixed-point is reached 272 | def _solve(flow_graph, ins, outs, argument_fields, exclude_list): 273 | _outs = outs.copy() 274 | _step(flow_graph, ins, _outs, argument_fields, exclude_list) 275 | 276 | if all(map(lambda i: outs[i] == _outs[i], outs.keys())): 277 | return ins, outs 278 | else: 279 | return _solve(flow_graph, ins, _outs, argument_fields, exclude_list) 280 | 281 | 282 | # Compute reach-in/out fields/registers at every node in the flow graph 283 | def analyse(flow_graph, argument_fields, exclude_list): 284 | ins = {} 285 | outs = {} 286 | for _, node in flow_graph.iteritems(): 287 | for instruction in node.basic_block: 288 | ins[instruction] = set() 289 | outs[instruction] = set() 290 | return _solve(flow_graph, ins, outs, argument_fields, exclude_list) -------------------------------------------------------------------------------- /netasm/netasm/core/common.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## common.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from netasm.netasm.core.syntax import * 37 | from netasm.netasm.core.syntax import InstructionCollection as I, OperandCollection as O 38 | 39 | 40 | SPECIAL_FIELDS = [Field('DRP'), 41 | Field('CTR')] 42 | 43 | 44 | RESERVED_FIELDS = [Field('inport_bitmap'), 45 | Field('outport_bitmap'), 46 | Field('bit_length')] + SPECIAL_FIELDS 47 | 48 | 49 | def get_modified_locations(instructions): 50 | modified_offsets = [] 51 | 52 | for instruction in instructions: 53 | if isinstance(instruction, I.ST): 54 | modified_offsets.append(instruction.location.location) 55 | elif isinstance(instruction, I.ATM): 56 | modified_offsets.extend(get_modified_locations(instruction.code.instructions)) 57 | elif isinstance(instruction, I.SEQ): 58 | modified_offsets.extend(get_modified_locations(instruction.code.instructions)) 59 | elif isinstance(instruction, I.CNC): 60 | for code in instruction.codes: 61 | modified_offsets.extend(get_modified_locations(code.instructions)) 62 | 63 | # TODO: optimize by finding overlapping offset/length pairs and eliminate them 64 | 65 | return modified_offsets 66 | 67 | 68 | def get_modified_reserved_fields(instructions): 69 | modified_reserved_fields = set() 70 | 71 | for instruction in instructions: 72 | if isinstance(instruction, I.DRP): 73 | modified_reserved_fields |= {Field('DRP')} 74 | elif isinstance(instruction, I.CTR): 75 | modified_reserved_fields |= {Field('CTR')} 76 | elif isinstance(instruction, I.LD): 77 | if isinstance(instruction.destination, O.Field): 78 | if is_reserved_field(instruction.destination.field): 79 | modified_reserved_fields |= {instruction.destination.field} 80 | elif isinstance(instruction, I.OP): 81 | if isinstance(instruction.destination, O.Field): 82 | if is_reserved_field(instruction.destination.field): 83 | modified_reserved_fields |= {instruction.destination.field} 84 | elif isinstance(instruction, I.LDt): 85 | if isinstance(instruction.destinations, O.Operands__): 86 | for operand in instruction.destinations: 87 | if isinstance(operand, O.Field): 88 | if is_reserved_field(operand.field): 89 | modified_reserved_fields |= {operand.field} 90 | else: 91 | raise TypeError("invalid %s of destinations (%s). Should be %s." 92 | % (type(instruction.destinations), instruction.destinations, O.Operands__)) 93 | elif isinstance(instruction, I.LKt): 94 | if isinstance(instruction.index, O.Field): 95 | if is_reserved_field(instruction.index.field): 96 | modified_reserved_fields |= {instruction.index.field} 97 | elif isinstance(instruction, I.CRC): 98 | if isinstance(instruction.destination, O.Field): 99 | if is_reserved_field(instruction.destination.field): 100 | modified_reserved_fields |= {instruction.destination.field} 101 | elif isinstance(instruction, I.HSH): 102 | if isinstance(instruction.destination, O.Field): 103 | if is_reserved_field(instruction.destination.field): 104 | modified_reserved_fields |= {instruction.destination.field} 105 | elif isinstance(instruction, I.ATM): 106 | modified_reserved_fields |= get_modified_reserved_fields(instruction.code.instructions) 107 | elif isinstance(instruction, I.SEQ): 108 | modified_reserved_fields |= get_modified_reserved_fields(instruction.code.instructions) 109 | elif isinstance(instruction, I.CNC): 110 | for code in instruction.codes: 111 | modified_reserved_fields |= get_modified_reserved_fields(code.instructions) 112 | 113 | return modified_reserved_fields 114 | 115 | 116 | def get_modified_fields(instructions, fields): 117 | modified_fields = set() 118 | 119 | for instruction in instructions: 120 | if isinstance(instruction, I.LD): 121 | if isinstance(instruction.destination, O.Field): 122 | if instruction.destination.field in fields: 123 | modified_fields |= {instruction.destination.field} 124 | elif isinstance(instruction, I.OP): 125 | if isinstance(instruction.destination, O.Field): 126 | if instruction.destination.field in fields: 127 | modified_fields |= {instruction.destination.field} 128 | elif isinstance(instruction, I.LDt): 129 | if isinstance(instruction.destinations, O.Operands__): 130 | for operand in instruction.destinations: 131 | if isinstance(operand, O.Field): 132 | if operand.field in fields: 133 | modified_fields |= {operand.field} 134 | else: 135 | raise TypeError("invalid %s of destinations (%s). Should be %s." 136 | % (type(instruction.destinations), instruction.destinations, O.Operands__)) 137 | elif isinstance(instruction, I.LKt): 138 | if isinstance(instruction.index, O.Field): 139 | if instruction.index.field in fields: 140 | modified_fields |= {instruction.index.field} 141 | elif isinstance(instruction, I.CRC): 142 | if isinstance(instruction.destination, O.Field): 143 | if instruction.destination.field in fields: 144 | modified_fields |= {instruction.destination.field} 145 | elif isinstance(instruction, I.HSH): 146 | if isinstance(instruction.destination, O.Field): 147 | if instruction.destination.field in fields: 148 | modified_fields |= {instruction.destination.field} 149 | elif isinstance(instruction, I.ATM): 150 | modified_fields |= get_modified_fields(instruction.code.instructions, fields) 151 | elif isinstance(instruction, I.SEQ): 152 | modified_fields |= get_modified_fields(instruction.code.instructions, fields) 153 | elif isinstance(instruction, I.CNC): 154 | for code in instruction.codes: 155 | modified_fields |= get_modified_fields(code.instructions, fields) 156 | 157 | return modified_fields 158 | 159 | 160 | def get_add_instruction_count(instructions, field): 161 | count = 0 162 | for instruction in instructions: 163 | if isinstance(instruction, I.ADD): 164 | if instruction.field.field == field: 165 | count += 1 166 | return count 167 | 168 | 169 | def get_rmv_instruction_count(instructions, field): 170 | count = 0 171 | for instruction in instructions: 172 | if isinstance(instruction, I.RMV): 173 | if instruction.field.field == field: 174 | count += 1 175 | return count 176 | 177 | 178 | def get_instruction_at_label(instructions, label): 179 | i = 0 180 | for instruction in instructions: 181 | if isinstance(instruction, I.LBL): 182 | if instruction.label == label: 183 | return i, instruction 184 | i += 1 185 | 186 | raise TypeError("invalid label (%s)." % label) 187 | 188 | 189 | def is_special_field(field): 190 | return True if field in SPECIAL_FIELDS else False 191 | 192 | 193 | def is_reserved_field(field): 194 | return True if field in RESERVED_FIELDS else False 195 | 196 | 197 | def get_reserved_fields(): 198 | return Fields(*RESERVED_FIELDS) 199 | 200 | 201 | # Note: port numbers start from 1 202 | def ports_to_bitmap(*args): 203 | bitmap = 0 204 | if isinstance(args[0], list): 205 | for port in args[0]: 206 | bitmap |= 1 << (port - 1) 207 | else: 208 | for port in args: 209 | bitmap |= 1 << (port - 1) 210 | return bitmap 211 | 212 | 213 | def bitmap_to_ports(bitmap): 214 | ports = [] 215 | bitmap_string = bin(bitmap)[2:][::-1] 216 | for i in range(0, len(bitmap_string)): 217 | if int(bitmap_string[i]) == 1: 218 | ports.append(i + 1) 219 | return ports -------------------------------------------------------------------------------- /netasm/netasm/core/execute/single_process.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## single_process.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from copy import deepcopy 37 | from Queue import Queue 38 | from threading import Thread, Lock 39 | 40 | from netasm.netasm.core.syntax import InstructionCollection as I, Policy 41 | from netasm.netasm.core.common import get_reserved_fields, get_instruction_at_label as get_label 42 | from netasm.netasm.core.utilities.profile import time_usage, do_cprofile 43 | from netasm.netasm.core.execute import * 44 | 45 | 46 | # TODO: add runtime errors' details. 47 | 48 | 49 | lock = Lock() 50 | 51 | 52 | class Table: 53 | def __init__(self, patterns): 54 | self.patterns = patterns 55 | 56 | 57 | class Tables(dict): 58 | def __setitem__(self, table_id, table): 59 | dict.__setitem__(self, table_id, table) 60 | 61 | 62 | class ExecuteDecls: 63 | def __init__(self, decls): 64 | # Declare tables 65 | self.tables = Tables() 66 | for table_id, table in decls.table_decls.iteritems(): 67 | # generate pattern 68 | if isinstance(table.table_fields, syntax.TableFieldsCollection.SimpleFields): 69 | pattern = SimplePattern() 70 | for field, size in table.table_fields.iteritems(): 71 | pattern[field] = syntax.Value(0, size) 72 | 73 | # generate list of patterns 74 | patterns = SimplePatterns() 75 | for i in range(0, table.size): 76 | patterns.insert(i, deepcopy(pattern)) 77 | elif isinstance(table.table_fields, syntax.TableFieldsCollection.MatchFields): 78 | pattern = MatchPattern() 79 | for field, (size, _) in table.table_fields.iteritems(): 80 | pattern[field] = (syntax.Value(0, size), syntax.Mask(-1)) 81 | 82 | # generate list of patterns 83 | patterns = MatchPatterns() 84 | for i in range(0, table.size): 85 | patterns.insert(i, deepcopy(pattern)) 86 | else: 87 | raise RuntimeError() 88 | 89 | self.tables[table_id] = Table(patterns) 90 | 91 | 92 | def execute_LDt(state, tables, destinations, table_id, index): 93 | index_value = None 94 | ''' Lookup index ''' 95 | if isinstance(index, O.Value): 96 | index_value = index.value 97 | elif isinstance(index, O.Field): 98 | index_value = state.header[index.field] 99 | else: 100 | raise RuntimeError() 101 | 102 | ''' Lookup table ''' 103 | patterns = tables[table_id].patterns 104 | 105 | ''' Lookup pattern ''' 106 | pattern = patterns[index_value.value] 107 | pattern_list = pattern.values() 108 | 109 | for i in range(0, len(destinations)): 110 | operand = destinations[i] 111 | 112 | if isinstance(operand, O.Field): 113 | state.header[operand.field].value = pattern_list[i].value 114 | else: 115 | raise RuntimeError() 116 | 117 | state.label = syntax.Label('') 118 | return state 119 | 120 | 121 | # TODO: type system to ensure destinations and patterns must have the same order 122 | 123 | 124 | def execute_STt(state, tables, table_id, index, sources): 125 | index_value = None 126 | ''' Lookup index ''' 127 | if isinstance(index, O.Value): 128 | index_value = index.value 129 | elif isinstance(index, O.Field): 130 | index_value = state.header[index.field] 131 | else: 132 | raise RuntimeError() 133 | 134 | ''' Lookup table ''' 135 | patterns = tables[table_id].patterns 136 | 137 | ''' Lookup pattern ''' 138 | pattern = patterns[index_value.value] 139 | pattern_list = pattern.keys() 140 | 141 | if isinstance(sources, O.Operands_): 142 | for i in range(0, len(sources)): 143 | field = pattern_list[i] 144 | operand = sources[i] 145 | 146 | if isinstance(operand, O.Value): 147 | pattern[field].value = operand.value.value 148 | elif isinstance(operand, O.Field): 149 | pattern[field].value = state.header[operand.field].value 150 | else: 151 | raise RuntimeError() 152 | elif isinstance(sources, O.OperandsMasks_): 153 | for i in range(0, len(sources)): 154 | field = pattern_list[i] 155 | operand, mask = sources[i] 156 | 157 | if isinstance(operand, O.Value): 158 | pattern[field][0].value = operand.value.value 159 | pattern[field] = (pattern[field][0], mask) 160 | elif isinstance(operand, O.Field): 161 | pattern[field][0].value = state.header[operand.field].value 162 | pattern[field] = (pattern[field][0], mask) 163 | else: 164 | raise RuntimeError() 165 | else: 166 | raise RuntimeError() 167 | 168 | state.label = syntax.Label('') 169 | return state 170 | 171 | 172 | # TODO: type system to ensure destinations and patterns must have the same order 173 | 174 | 175 | def execute_INCt(state, tables, table_id, index): 176 | index_value = None 177 | ''' Lookup index ''' 178 | if isinstance(index, O.Value): 179 | index_value = index.value 180 | elif isinstance(index, O.Field): 181 | index_value = state.header[index.field] 182 | else: 183 | raise RuntimeError() 184 | 185 | ''' Lookup table ''' 186 | patterns = tables[table_id].patterns 187 | 188 | ''' Lookup pattern ''' 189 | pattern = patterns[index_value.value] 190 | 191 | for field in pattern: 192 | pattern[field].value += 1 193 | 194 | state.label = syntax.Label('') 195 | return state 196 | 197 | 198 | def execute_LKt(state, tables, index, table_id, sources): 199 | values = [] 200 | ''' Read sources values ''' 201 | for source in sources: 202 | if isinstance(source, O.Value): 203 | values.append(source.value) 204 | elif isinstance(source, O.Field): 205 | values.append(state.header[source.field]) 206 | else: 207 | raise RuntimeError() 208 | 209 | ''' Lookup table ''' 210 | patterns = tables[table_id].patterns 211 | 212 | value = -1 213 | if isinstance(patterns, MatchPatterns): 214 | for i in range(0, len(patterns)): 215 | pattern_list = patterns[i].values() 216 | 217 | if len(pattern_list) != len(values): 218 | raise RuntimeError() 219 | 220 | if all(map((lambda (value, mask), source: value.value == (source.value & mask)), 221 | pattern_list, values)): 222 | value = i 223 | break 224 | elif isinstance(patterns, SimplePatterns): 225 | for i in range(0, len(patterns)): 226 | pattern_list = patterns[i].values() 227 | 228 | if all(map((lambda value, source: value.value == source.value), 229 | pattern_list, values)): 230 | value = i 231 | break 232 | else: 233 | raise RuntimeError() 234 | 235 | ''' Lookup index ''' 236 | if isinstance(index, O.Field): 237 | state.header[index.field].value = value 238 | else: 239 | raise RuntimeError() 240 | 241 | state.label = syntax.Label('') 242 | return state 243 | 244 | 245 | # TODO: 1) type system to ensure destinations and patterns must have the same order 246 | # TODO: 2) look into the -1 assignment issue 247 | 248 | 249 | def _execute_CNC(state, tables, codes): 250 | for code in codes: 251 | state = _execute_Code(code, tables, state) 252 | return state 253 | 254 | 255 | def _execute_ATM(state, tables, code): 256 | return _execute_Code(code, tables, state) 257 | 258 | 259 | def _execute_SEQ(state, tables, code): 260 | return _execute_Code(code, tables, state) 261 | 262 | 263 | def _next_Instruction(instructions, tables, state): 264 | # Read instruction at program counter 265 | instruction = instructions[state.pc] 266 | 267 | if isinstance(instruction, I.ID): 268 | state = execute_ID(state) 269 | elif isinstance(instruction, I.DRP): 270 | state = execute_DRP(state, instruction.reason) 271 | elif isinstance(instruction, I.CTR): 272 | state = execute_CTR(state, instruction.reason) 273 | elif isinstance(instruction, I.ADD): 274 | state = execute_ADD(state, instruction.field, instruction.size) 275 | elif isinstance(instruction, I.RMV): 276 | state = execute_RMV(state, instruction.field) 277 | elif isinstance(instruction, I.LD): 278 | state = execute_LD(state, instruction.destination, instruction.source) 279 | elif isinstance(instruction, I.ST): 280 | state = execute_ST(state, instruction.location, instruction.source) 281 | elif isinstance(instruction, I.OP): 282 | state = execute_OP(state, instruction.destination, instruction.left_source, 283 | instruction.operator, instruction.right_source) 284 | elif isinstance(instruction, I.PUSH): 285 | state = execute_PUSH(state, instruction.location) 286 | elif isinstance(instruction, I.POP): 287 | state = execute_POP(state, instruction.location) 288 | elif isinstance(instruction, I.BR): 289 | state = execute_BR(state, instruction.left_source, instruction.operator, 290 | instruction.right_source, instruction.label) 291 | elif isinstance(instruction, I.JMP): 292 | state = execute_JMP(state, instruction.label) 293 | elif isinstance(instruction, I.LBL): 294 | state = execute_LBL(state) 295 | elif isinstance(instruction, I.LDt): 296 | state = execute_LDt(state, tables, instruction.destinations, instruction.table_id, instruction.index) 297 | elif isinstance(instruction, I.STt): 298 | state = execute_STt(state, tables, instruction.table_id, instruction.index, instruction.sources) 299 | elif isinstance(instruction, I.INCt): 300 | state = execute_INCt(state, tables, instruction.table_id, instruction.index) 301 | elif isinstance(instruction, I.LKt): 302 | state = execute_LKt(state, tables, instruction.index, instruction.table_id, instruction.sources) 303 | elif isinstance(instruction, I.CRC): 304 | state = execute_CRC(state, instruction.destination, instruction.sources) 305 | elif isinstance(instruction, I.HSH): 306 | state = execute_HSH(state, instruction.destination, instruction.sources) 307 | elif isinstance(instruction, I.CNC): 308 | state = _execute_CNC(state, tables, instruction.codes) 309 | elif isinstance(instruction, I.ATM): 310 | state = _execute_ATM(state, tables, instruction.code) 311 | elif isinstance(instruction, I.SEQ): 312 | state = _execute_SEQ(state, tables, instruction.code) 313 | else: 314 | raise RuntimeError() 315 | 316 | if state.label == syntax.Label(''): 317 | state.pc += 1 318 | else: 319 | state.pc, _ = get_label(instructions, state.label) 320 | 321 | return state 322 | 323 | 324 | def _execute_Instructions(instructions, tables, state): 325 | # Read instruction at program counter 326 | instruction = instructions[state.pc] 327 | 328 | # Check if HLT instruction 329 | if isinstance(instruction, I.HLT): 330 | state = execute_HLT(state) 331 | else: 332 | state = _next_Instruction(instructions, tables, state) 333 | state = _execute_Instructions(instructions, tables, state) 334 | 335 | return state 336 | 337 | 338 | def _execute_Code(code, tables, state): 339 | # Save the current header and pc 340 | pc = state.pc 341 | header = state.header 342 | 343 | state.pc = 0 344 | state.header = Header() 345 | for field in code.argument_fields: 346 | state.header[field] = header[field] 347 | for field in get_reserved_fields(): 348 | state.header[field] = header[field] 349 | 350 | # Execute instructions 351 | state = _execute_Instructions(code.instructions, tables, state) 352 | 353 | # Commit changes to the current header 354 | for field in code.argument_fields: 355 | header[field] = state.header[field] 356 | for field in get_reserved_fields(): 357 | header[field] = state.header[field] 358 | 359 | state.pc = pc 360 | state.header = header 361 | 362 | return state 363 | 364 | 365 | # Execute code with timing usage 366 | @time_usage 367 | def _execute_Code__time_usage(code, tables, state): 368 | return _execute_Code(code, tables, state) 369 | 370 | 371 | # Execute code with profiling information 372 | @do_cprofile 373 | def _execute_Code__cprofile(code, tables, state): 374 | return _execute_Code(code, tables, state) 375 | 376 | 377 | execute = _execute_Code 378 | 379 | 380 | class Execute(Thread): 381 | def __init__(self, policy): 382 | super(Execute, self).__init__() 383 | 384 | self._execute_decls = ExecuteDecls(policy.decls) 385 | self._tables = self._execute_decls.tables 386 | self._code = policy.code 387 | self._input_interface = Queue() 388 | self._output_interface = Queue() 389 | 390 | def put(self, state): 391 | setattr(state, 'pc', 0) 392 | self._input_interface.put(state) 393 | 394 | def get(self): 395 | state = self._output_interface.get() 396 | del state.pc 397 | return state 398 | 399 | def stop(self): 400 | self._input_interface.put(None) 401 | self.join() 402 | 403 | def run(self): 404 | while True: 405 | try: 406 | state = self._input_interface.get() 407 | 408 | if state is None: 409 | return 410 | 411 | state = execute(self._code, self._tables, state) 412 | self._output_interface.put(state) 413 | except KeyboardInterrupt: 414 | break 415 | 416 | def add_table_entry(self, id, index, entry): 417 | lock.acquire() 418 | if id in self._tables: 419 | self._tables[id].patterns.add_entry(index, entry) 420 | else: 421 | raise RuntimeError("No such table") 422 | lock.release() 423 | 424 | def del_table_entry(self, id, index): 425 | lock.acquire() 426 | if id in self._tables: 427 | self._tables[id].patterns.del_entry(index) 428 | else: 429 | raise RuntimeError("No such table") 430 | lock.release() 431 | 432 | def query_table_entry(self, id, index): 433 | lock.acquire() 434 | if id in self._tables: 435 | entry = self._tables[id].patterns.query_entry(index) 436 | else: 437 | raise RuntimeError("No such table") 438 | lock.release() 439 | return entry 440 | 441 | def query_table_list(self): 442 | list = [] 443 | lock.acquire() 444 | for t in self._tables.keys(): 445 | list.append(str(t)) 446 | lock.release() 447 | return list 448 | -------------------------------------------------------------------------------- /netasm/netasm/core/graphs/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | -------------------------------------------------------------------------------- /netasm/netasm/core/graphs/basic_blocks.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## basic_blocks.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from netasm.netasm.core.syntax import InstructionCollection as I 37 | from netasm.netasm.core.common import get_instruction_at_label 38 | 39 | 40 | def _find_leaders(instructions): 41 | leaders_set = set() 42 | 43 | for i in range(0, len(instructions)): 44 | instruction = instructions[i] 45 | 46 | ''' The first instruction is always a leader ''' 47 | if not leaders_set: 48 | leaders_set |= {instruction} 49 | 50 | if (isinstance(instruction, I.BR) or 51 | isinstance(instruction, I.JMP)): 52 | ''' The instruction following BR/JMP is a leader ''' 53 | if (i + 1) < len(instructions): 54 | leaders_set |= {instructions[i + 1]} 55 | else: 56 | raise RuntimeError 57 | 58 | ''' The target instruction of BR/JMP is a leader ''' 59 | j, _ = get_instruction_at_label(instructions, instruction.label) 60 | if (j + 1) < len(instructions): 61 | leaders_set |= {instructions[j + 1]} 62 | else: 63 | raise RuntimeError 64 | 65 | return leaders_set 66 | 67 | 68 | def generate(instructions): 69 | leaders = _find_leaders(instructions) 70 | 71 | basic_block_list = None 72 | basic_blocks_list = [] 73 | 74 | for instruction in instructions: 75 | if instruction in leaders: 76 | basic_block_list = [instruction] 77 | basic_blocks_list.append(basic_block_list) 78 | else: 79 | basic_block_list.append(instruction) 80 | 81 | return basic_blocks_list -------------------------------------------------------------------------------- /netasm/netasm/core/graphs/control_flow_graph.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## control_flow_graph.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | import uuid 37 | 38 | from netasm.netasm.core import syntax as syntax 39 | from netasm.netasm.core.syntax import InstructionCollection as I 40 | from netasm.netasm.core.graphs import basic_blocks as bb 41 | 42 | 43 | class Node: 44 | def __init__(self, basic_block, predecessors, successors): 45 | self.basic_block = basic_block 46 | self.predecessors = predecessors 47 | self.successors = successors 48 | 49 | 50 | def _next_label(instruction): 51 | if isinstance(instruction, I.LBL): 52 | return instruction.label 53 | elif isinstance(instruction, I.Instruction): 54 | return syntax.Label('$' + str(uuid.uuid1().hex)) 55 | else: 56 | raise RuntimeError 57 | 58 | 59 | def _successors(instruction, next_label): 60 | if isinstance(instruction, I.BR): 61 | return [next_label, instruction.label] 62 | elif isinstance(instruction, I.JMP): 63 | return [instruction.label] 64 | elif isinstance(instruction, I.HLT): 65 | return [] 66 | elif isinstance(instruction, I.Instruction): 67 | return [next_label] 68 | else: 69 | raise RuntimeError 70 | 71 | 72 | class Entry(I.Instruction): 73 | pass 74 | 75 | 76 | class Exit(I.Instruction): 77 | pass 78 | 79 | 80 | def generate(instructions): 81 | flow_graph = {} 82 | 83 | basic_blocks = bb.generate(instructions) 84 | 85 | entry_label = syntax.Label('$entry') 86 | first_label = current_label = syntax.Label('$' + str(uuid.uuid1().hex)) 87 | exit_label = syntax.Label('$exit') 88 | last_label = None 89 | 90 | flow_graph[entry_label] = Node([Entry()], [], [first_label]) 91 | flow_graph[exit_label] = Node([Exit()], [], []) 92 | 93 | for basic_block in basic_blocks: 94 | instruction = basic_block[-1] 95 | next_label = _next_label(instruction) 96 | flow_graph[current_label] = Node(basic_block, [], _successors(instruction, next_label)) 97 | if isinstance(instruction, I.HLT): 98 | last_label = current_label 99 | current_label = next_label 100 | 101 | flow_graph[last_label].successors.append(exit_label) 102 | 103 | # Remove redundant label instructions 104 | label_list = [] 105 | for label, node in flow_graph.iteritems(): 106 | instruction_list = [] 107 | for instruction in node.basic_block: 108 | if isinstance(instruction, I.LBL): 109 | instruction_list.append(instruction) 110 | for instruction in instruction_list: 111 | node.basic_block.remove(instruction) 112 | if len(node.basic_block) == 0: 113 | label_list.append(label) 114 | for label in label_list: 115 | del flow_graph[label] 116 | 117 | for label, node in flow_graph.iteritems(): 118 | for successor_label in node.successors: 119 | flow_graph[successor_label].predecessors.append(label) 120 | 121 | return flow_graph 122 | 123 | # TODO: work on the graph traversals (reverse-post-order and vice versa) -------------------------------------------------------------------------------- /netasm/netasm/core/optimize.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## optimize.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from netasm.netasm.core.utilities.profile import time_usage 37 | from netasm.netasm.core.syntax import InstructionCollection as I 38 | from netasm.netasm.core.transformations import dead_code_elimination as dce 39 | from netasm.netasm.core.transformations import redundant_code_elimination as rce 40 | from netasm.netasm.core.transformations import add_code_motion as acm 41 | from netasm.netasm.core.transformations import rmv_code_motion as rcm 42 | # from netasm.netasm.core.transformations import rmv_code_insertion as rci 43 | 44 | 45 | def _optimize_Code(code): 46 | code = acm.transform(code) 47 | code = rcm.transform(code) 48 | code = dce.transform(code) 49 | code = rce.transform(code) 50 | # code = rci.transform(code) 51 | 52 | return code 53 | 54 | 55 | def optimize_Code(code): 56 | for instruction in code.instructions: 57 | if isinstance(instruction, I.CNC): 58 | codes = I.Codes() 59 | for _code in instruction.codes: 60 | codes.append(optimize_Code(_code)) 61 | instruction.codes = codes 62 | elif isinstance(instruction, I.ATM): 63 | instruction.code = optimize_Code(instruction.code) 64 | elif isinstance(instruction, I.SEQ): 65 | instruction.code = optimize_Code(instruction.code) 66 | 67 | return _optimize_Code(code) 68 | 69 | 70 | def optimize_Policy(policy): 71 | policy.code = optimize_Code(policy.code) 72 | return policy 73 | 74 | 75 | @time_usage 76 | def optimize_Policy__time_usage(policy): 77 | return optimize_Policy(policy) -------------------------------------------------------------------------------- /netasm/netasm/core/parse.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## parse.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | raise NotImplementedError() -------------------------------------------------------------------------------- /netasm/netasm/core/transformations/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | -------------------------------------------------------------------------------- /netasm/netasm/core/transformations/dead_code_elimination.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## dead_code_elimination.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from copy import copy 37 | 38 | from netasm.netasm.core.syntax import InstructionCollection as I, OperandCollection as O 39 | from netasm.netasm.core.common import is_reserved_field 40 | from netasm.netasm.core.graphs import control_flow_graph as cfg 41 | from netasm.netasm.core.analyses import liveness as li 42 | from netasm.netasm.core.analyses import field_usability as fu 43 | from netasm.netasm.core.analyses import field_reachability as fr 44 | 45 | 46 | def is_reserved_or_argument_field(field, argument_fields): 47 | return is_reserved_field(field) or (field in argument_fields) 48 | 49 | 50 | # Transform using liveness analysis 51 | def _phase_0(code): 52 | instructions = code.instructions 53 | 54 | ''' Generate flow graph ''' 55 | flow_graph = cfg.generate(instructions) 56 | 57 | ''' Get liveness information ''' 58 | live_ins, live_outs = li.analyse(flow_graph, code.argument_fields, [I.ADD, I.RMV]) 59 | 60 | ''' Cherry-pick dead instructions ''' 61 | instruction_list = [] 62 | for _, node in flow_graph.iteritems(): 63 | for instruction in node.basic_block: 64 | # I.ID 65 | # I.DRP 66 | # I.CTR 67 | # I.ADD 68 | # I.RMV 69 | if isinstance(instruction, I.LD): 70 | if isinstance(instruction.destination, O.Field): 71 | if is_reserved_or_argument_field(instruction.destination.field, code.argument_fields): 72 | pass 73 | elif not (instruction.destination.field in live_outs[instruction]): 74 | instruction_list.append(instruction) 75 | # I.ST 76 | elif isinstance(instruction, I.OP): 77 | if isinstance(instruction.destination, O.Field): 78 | if is_reserved_or_argument_field(instruction.destination.field, code.argument_fields): 79 | pass 80 | elif not (instruction.destination.field in live_outs[instruction]): 81 | instruction_list.append(instruction) 82 | # I.PUSH 83 | # I.POP 84 | # I.BR 85 | # I.JMP 86 | # I.LBL 87 | elif isinstance(instruction, I.LDt): 88 | check_list = [] 89 | for destination in instruction.destinations: 90 | if isinstance(destination, O.Field): 91 | if is_reserved_or_argument_field(destination.field, code.argument_fields): 92 | check_list.append(False) 93 | else: 94 | check_list.append(True if not (destination.field in live_outs[instruction]) else False) 95 | if check_list and all(check_list): 96 | instruction_list.append(instruction) 97 | # I.STt 98 | # I.INCt 99 | elif isinstance(instruction, I.LKt): 100 | if isinstance(instruction.index, O.Field): 101 | if is_reserved_or_argument_field(instruction.index.field, code.argument_fields): 102 | pass 103 | elif not (instruction.index.field in live_outs[instruction]): 104 | instruction_list.append(instruction) 105 | elif isinstance(instruction, I.CRC): 106 | if isinstance(instruction.destination, O.Field): 107 | if is_reserved_or_argument_field(instruction.destination.field, code.argument_fields): 108 | pass 109 | elif not (instruction.destination.field in live_outs[instruction]): 110 | instruction_list.append(instruction) 111 | elif isinstance(instruction, I.HSH): 112 | if isinstance(instruction.destination, O.Field): 113 | if is_reserved_or_argument_field(instruction.destination.field, code.argument_fields): 114 | pass 115 | elif not (instruction.destination.field in live_outs[instruction]): 116 | instruction_list.append(instruction) 117 | # I.HLT 118 | # I.CNC 119 | # I.ATM 120 | # I.SEQ 121 | 122 | # TODO: add support for group instructions, above. 123 | 124 | ''' Remove dead instructions from the code ''' 125 | for instruction in instruction_list: 126 | instructions.remove(instruction) 127 | 128 | 129 | # Transform using field usability analysis for removing dead ADD instructions 130 | def _phase_1(code): 131 | instructions = code.instructions 132 | 133 | ''' Generate flow graph ''' 134 | flow_graph = cfg.generate(instructions) 135 | 136 | ''' Get usability information ''' 137 | use_ins, use_outs = fu.analyse(flow_graph, code.argument_fields, [I.RMV]) 138 | 139 | ''' Cherry-pick dead instructions ''' 140 | instruction_list = [] 141 | for _, node in flow_graph.iteritems(): 142 | for instruction in node.basic_block: 143 | if isinstance(instruction, I.ADD): 144 | if is_reserved_or_argument_field(instruction.field.field, code.argument_fields): 145 | pass 146 | elif not (instruction.field.field in use_outs[instruction]): 147 | instruction_list.append(instruction) 148 | 149 | ''' Remove dead instructions from the code ''' 150 | for instruction in instruction_list: 151 | instructions.remove(instruction) 152 | 153 | 154 | # Transform using field reachability analysis for removing dead RMV instructions 155 | def _phase_2(code): 156 | instructions = code.instructions 157 | 158 | ''' Generate flow graph ''' 159 | flow_graph = cfg.generate(instructions) 160 | 161 | ''' Get reachability information ''' 162 | reach_ins, reach_outs = fr.analyse(flow_graph, code.argument_fields, [I.ADD]) 163 | 164 | ''' Cherry-pick dead instructions ''' 165 | instruction_list = [] 166 | for _, node in flow_graph.iteritems(): 167 | for instruction in node.basic_block: 168 | if isinstance(instruction, I.RMV): 169 | if is_reserved_or_argument_field(instruction.field.field, code.argument_fields): 170 | pass 171 | elif not (instruction.field.field in reach_ins[instruction]): 172 | instruction_list.append(instruction) 173 | 174 | ''' Remove dead instructions from the code ''' 175 | for instruction in instruction_list: 176 | instructions.remove(instruction) 177 | 178 | 179 | def transform(code): 180 | while True: 181 | ''' Iterate till fixed-point is reached ''' 182 | instructions = copy(code.instructions) 183 | 184 | _phase_0(code) 185 | _phase_1(code) 186 | _phase_2(code) 187 | 188 | if set(instructions) == set(code.instructions): 189 | return code -------------------------------------------------------------------------------- /netasm/netasm/core/transformations/redundant_code_elimination.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## redundant_code_elimination.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from copy import copy 37 | 38 | from netasm.netasm.core.syntax import InstructionCollection as I 39 | from netasm.netasm.core.common import is_reserved_field, get_add_instruction_count, get_rmv_instruction_count 40 | from netasm.netasm.core.graphs import control_flow_graph as cfg 41 | from netasm.netasm.core.analyses import field_usability as fu 42 | from netasm.netasm.core.analyses import field_reachability as fr 43 | 44 | 45 | def is_reserved_or_argument_field(field, argument_fields): 46 | return is_reserved_field(field) or (field in argument_fields) 47 | 48 | 49 | # Transform using field reachability analysis for removing redundant ADD instructions 50 | def _phase_0(code): 51 | instructions = code.instructions 52 | 53 | ''' Generate flow graph ''' 54 | flow_graph = cfg.generate(instructions) 55 | 56 | ''' Get reachability information ''' 57 | reach_ins, reach_outs = fr.analyse(flow_graph, code.argument_fields, []) 58 | 59 | ''' Cherry-pick dead instructions ''' 60 | instruction_list = [] 61 | for _, node in flow_graph.iteritems(): 62 | for instruction in node.basic_block: 63 | if isinstance(instruction, I.ADD): 64 | if is_reserved_or_argument_field(instruction.field.field, code.argument_fields): 65 | pass 66 | else: 67 | if get_add_instruction_count(code.instructions, instruction.field.field) < 2: 68 | pass 69 | elif not (instruction.field.field in reach_ins[instruction]): 70 | instruction_list.append(instruction) 71 | 72 | ''' Remove dead instructions from the code ''' 73 | for instruction in instruction_list: 74 | instructions.remove(instruction) 75 | 76 | 77 | # Transform using field usability analysis for removing redundant RMV instructions 78 | def _phase_1(code): 79 | instructions = code.instructions 80 | 81 | ''' Generate flow graph ''' 82 | flow_graph = cfg.generate(instructions) 83 | 84 | ''' Get usability information ''' 85 | use_ins, use_outs = fu.analyse(flow_graph, code.argument_fields, []) 86 | 87 | ''' Cherry-pick dead instructions ''' 88 | instruction_list = [] 89 | for _, node in flow_graph.iteritems(): 90 | for instruction in node.basic_block: 91 | if isinstance(instruction, I.RMV): 92 | if is_reserved_or_argument_field(instruction.field.field, code.argument_fields): 93 | pass 94 | else: 95 | if get_rmv_instruction_count(code.instructions, instruction.field.field) < 2: 96 | pass 97 | elif not (instruction.field.field in use_outs[instruction]): 98 | instruction_list.append(instruction) 99 | 100 | ''' Remove dead instructions from the code ''' 101 | for instruction in instruction_list: 102 | instructions.remove(instruction) 103 | 104 | 105 | def transform(code): 106 | while True: 107 | ''' Iterate till fixed-point is reached ''' 108 | instructions = copy(code.instructions) 109 | 110 | _phase_0(code) 111 | _phase_1(code) 112 | 113 | if set(instructions) == set(code.instructions): 114 | return code -------------------------------------------------------------------------------- /netasm/netasm/core/transformations/rmv_code_motion.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## rmv_code_motion.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from netasm.netasm.core.syntax import InstructionCollection as I 37 | from netasm.netasm.core.transformations.rmv_code_insertion import _transform 38 | 39 | 40 | def transform(code): 41 | _transform(code, [I.RMV]) 42 | 43 | return code -------------------------------------------------------------------------------- /netasm/netasm/core/utilities/__init__.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## __init__.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | -------------------------------------------------------------------------------- /netasm/netasm/core/utilities/algorithms.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## algorithms.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | import struct 37 | import array 38 | 39 | 40 | if struct.pack("H", 1) == "\x00\x01": 41 | ''' big endian ''' 42 | 43 | def crc16(ba): 44 | if len(ba) % 2 == 1: 45 | ba += "\0" 46 | s = sum(array.array("H", ba)) 47 | s = (s >> 16) + (s & 0xffff) 48 | s += s >> 16 49 | s = ~s 50 | return s & 0xffff 51 | else: 52 | def crc16(ba): 53 | if len(ba) % 2 == 1: 54 | ba += "\0" 55 | s = sum(array.array("H", ba)) 56 | s = (s >> 16) + (s & 0xffff) 57 | s += s >> 16 58 | s = ~s 59 | return (((s >> 8) & 0xff) | s << 8) & 0xffff -------------------------------------------------------------------------------- /netasm/netasm/core/utilities/profile.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## profile.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | 37 | def do_cprofile(func): 38 | import cProfile 39 | 40 | def profiled_func(*args, **kwargs): 41 | profile = cProfile.Profile() 42 | try: 43 | profile.enable() 44 | result = func(*args, **kwargs) 45 | profile.disable() 46 | return result 47 | finally: 48 | profile.print_stats() 49 | 50 | return profiled_func 51 | 52 | 53 | def time_usage(func): 54 | import time 55 | 56 | def wrapper(*args, **kwargs): 57 | beg_ts = time.time() 58 | result = func(*args, **kwargs) 59 | end_ts = time.time() 60 | print("Elapsed time: %f" % (end_ts - beg_ts)) 61 | return result 62 | 63 | return wrapper -------------------------------------------------------------------------------- /netasm/netasm/cost.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## cost.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from netasm.netasm.core.cost import * -------------------------------------------------------------------------------- /netasm/netasm/execute.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## execute.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | # from netasm.netasm.core.execute.single_process import * 37 | from netasm.netasm.core.execute.multi_process import * 38 | -------------------------------------------------------------------------------- /netasm/netasm/optimize.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## optimize.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from netasm.netasm.core.optimize import * -------------------------------------------------------------------------------- /netasm/netasm/parse.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## parse.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | from netasm.netasm.core.parse import * -------------------------------------------------------------------------------- /netasm/netasm/validate.py: -------------------------------------------------------------------------------- 1 | # ################################################################################ 2 | # ## 3 | # ## https://github.com/NetASM/NetASM-python 4 | # ## 5 | # ## File: 6 | # ## validate.py 7 | # ## 8 | # ## Project: 9 | # ## NetASM: A Network Assembly Language for Programmable Dataplanes 10 | # ## 11 | # ## Author: 12 | # ## Muhammad Shahbaz 13 | # ## 14 | # ## Copyright notice: 15 | # ## Copyright (C) 2014 Princeton University 16 | # ## Network Operations and Internet Security Lab 17 | # ## 18 | # ## Licence: 19 | # ## This file is a part of the NetASM development base package. 20 | # ## 21 | # ## This file is free code: you can redistribute it and/or modify it under 22 | # ## the terms of the GNU Lesser General Public License version 2.1 as 23 | # ## published by the Free Software Foundation. 24 | # ## 25 | # ## This package is distributed in the hope that it will be useful, but 26 | # ## WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | # ## Lesser General Public License for more details. 29 | # ## 30 | # ## You should have received a copy of the GNU Lesser General Public 31 | # ## License along with the NetASM source package. If not, see 32 | # ## http://www.gnu.org/licenses/. 33 | 34 | __author__ = 'shahbaz' 35 | 36 | import netasm.netasm.core.type_check as type_check -------------------------------------------------------------------------------- /setup/basic.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ################################################################################ 4 | ## 5 | ## https://github.com/NetASM/NetASM-python 6 | ## 7 | ## File: 8 | ## basic.sh 9 | ## 10 | ## Project: 11 | ## NetASM: A Network Assembly Language for Programmable Dataplanes 12 | ## 13 | ## Author: 14 | ## Muhammad Shahbaz 15 | ## 16 | ## Copyright notice: 17 | ## Copyright (C) 2014 Princeton University 18 | ## Network Operations and Internet Security Lab 19 | ## 20 | ## Licence: 21 | ## This file is a part of the NetASM development base package. 22 | ## 23 | ## This file is free code: you can redistribute it and/or modify it under 24 | ## the terms of the GNU Lesser General Public License version 2.1 as 25 | ## published by the Free Software Foundation. 26 | ## 27 | ## This package is distributed in the hope that it will be useful, but 28 | ## WITHOUT ANY WARRANTY; without even the implied warranty of 29 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 30 | ## Lesser General Public License for more details. 31 | ## 32 | ## You should have received a copy of the GNU Lesser General Public 33 | ## License along with the NetASM source package. If not, see 34 | ## http://www.gnu.org/licenses/. 35 | 36 | # Update virtualbox 37 | sudo apt-get update 38 | 39 | # Install essentials 40 | sudo apt-get install -y ssh git 41 | 42 | sudo apt-get install -y build-essential autoconf automake graphviz libtool vim 43 | sudo apt-get install -y python-all python-qt4 python-dev python-twisted-conch python-pip python-sphinx 44 | sudo apt-get install -y libpcap-dev 45 | 46 | sudo pip install alabaster psutil bitstring 47 | -------------------------------------------------------------------------------- /setup/last.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ################################################################################ 4 | ## 5 | ## https://github.com/NetASM/NetASM-python 6 | ## 7 | ## File: 8 | ## last.sh 9 | ## 10 | ## Project: 11 | ## NetASM: A Network Assembly Language for Programmable Dataplanes 12 | ## 13 | ## Author: 14 | ## Muhammad Shahbaz 15 | ## 16 | ## Copyright notice: 17 | ## Copyright (C) 2014 Princeton University 18 | ## Network Operations and Internet Security Lab 19 | ## 20 | ## Licence: 21 | ## This file is a part of the NetASM development base package. 22 | ## 23 | ## This file is free code: you can redistribute it and/or modify it under 24 | ## the terms of the GNU Lesser General Public License version 2.1 as 25 | ## published by the Free Software Foundation. 26 | ## 27 | ## This package is distributed in the hope that it will be useful, but 28 | ## WITHOUT ANY WARRANTY; without even the implied warranty of 29 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 30 | ## Lesser General Public License for more details. 31 | ## 32 | ## You should have received a copy of the GNU Lesser General Public 33 | ## License along with the NetASM source package. If not, see 34 | ## http://www.gnu.org/licenses/. 35 | 36 | echo 'alias sudopy="sudo PYTHONPATH=$PYTHONPATH"' >> ~/.profile -------------------------------------------------------------------------------- /setup/mininet.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ################################################################################ 4 | ## 5 | ## https://github.com/NetASM/NetASM-python 6 | ## 7 | ## File: 8 | ## mininet.sh 9 | ## 10 | ## Project: 11 | ## NetASM: A Network Assembly Language for Programmable Dataplanes 12 | ## 13 | ## Author: 14 | ## Muhammad Shahbaz 15 | ## 16 | ## Copyright notice: 17 | ## Copyright (C) 2014 Princeton University 18 | ## Network Operations and Internet Security Lab 19 | ## 20 | ## Licence: 21 | ## This file is a part of the NetASM development base package. 22 | ## 23 | ## This file is free code: you can redistribute it and/or modify it under 24 | ## the terms of the GNU Lesser General Public License version 2.1 as 25 | ## published by the Free Software Foundation. 26 | ## 27 | ## This package is distributed in the hope that it will be useful, but 28 | ## WITHOUT ANY WARRANTY; without even the implied warranty of 29 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 30 | ## Lesser General Public License for more details. 31 | ## 32 | ## You should have received a copy of the GNU Lesser General Public 33 | ## License along with the NetASM source package. If not, see 34 | ## http://www.gnu.org/licenses/. 35 | 36 | cd ~/ 37 | 38 | # Clone Mininet 39 | git clone git://github.com/mininet/mininet 40 | 41 | # Install Mininet 42 | sudo ~/mininet/util/install.sh -a 43 | 44 | # Add Mininet to PATH and PYTHONPATH environment variables 45 | echo 'export PATH=$PATH:$HOME/mininet' >> ~/.profile 46 | echo 'export PYTHONPATH=$PYTHONPATH:$HOME/mininet' >> ~/.profile 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /setup/netasm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ################################################################################ 4 | ## 5 | ## https://github.com/NetASM/NetASM-python 6 | ## 7 | ## File: 8 | ## netasm.sh 9 | ## 10 | ## Project: 11 | ## NetASM: A Network Assembly Language for Programmable Dataplanes 12 | ## 13 | ## Author: 14 | ## Muhammad Shahbaz 15 | ## 16 | ## Copyright notice: 17 | ## Copyright (C) 2014 Princeton University 18 | ## Network Operations and Internet Security Lab 19 | ## 20 | ## Licence: 21 | ## This file is a part of the NetASM development base package. 22 | ## 23 | ## This file is free code: you can redistribute it and/or modify it under 24 | ## the terms of the GNU Lesser General Public License version 2.1 as 25 | ## published by the Free Software Foundation. 26 | ## 27 | ## This package is distributed in the hope that it will be useful, but 28 | ## WITHOUT ANY WARRANTY; without even the implied warranty of 29 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 30 | ## Lesser General Public License for more details. 31 | ## 32 | ## You should have received a copy of the GNU Lesser General Public 33 | ## License along with the NetASM source package. If not, see 34 | ## http://www.gnu.org/licenses/. 35 | 36 | cd ~/ 37 | 38 | # Link netasm to ~/netasm 39 | ln -s /vagrant/ ~/netasm 40 | 41 | # Add NetASM to PATH and PYTHONPATH environment variables 42 | echo 'export PATH=$PATH:$HOME/netasm' >> ~/.profile 43 | echo 'export PYTHONPATH=$PYTHONPATH:$HOME/netasm' >> ~/.profile 44 | -------------------------------------------------------------------------------- /setup/pox-patch.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ################################################################################ 4 | ## 5 | ## https://github.com/NetASM/NetASM-python 6 | ## 7 | ## File: 8 | ## pox-patch.sh 9 | ## 10 | ## Project: 11 | ## NetASM: A Network Assembly Language for Programmable Dataplanes 12 | ## 13 | ## Author: 14 | ## Muhammad Shahbaz 15 | ## 16 | ## Copyright notice: 17 | ## Copyright (C) 2014 Princeton University 18 | ## Network Operations and Internet Security Lab 19 | ## 20 | ## Licence: 21 | ## This file is a part of the NetASM development base package. 22 | ## 23 | ## This file is free code: you can redistribute it and/or modify it under 24 | ## the terms of the GNU Lesser General Public License version 2.1 as 25 | ## published by the Free Software Foundation. 26 | ## 27 | ## This package is distributed in the hope that it will be useful, but 28 | ## WITHOUT ANY WARRANTY; without even the implied warranty of 29 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 30 | ## Lesser General Public License for more details. 31 | ## 32 | ## You should have received a copy of the GNU Lesser General Public 33 | ## License along with the NetASM source package. If not, see 34 | ## http://www.gnu.org/licenses/. 35 | 36 | # Apply patch for POX 37 | cd ~/pox 38 | sudo git remote add netasm-patch https://github.com/PrincetonUniversity/pox 39 | sudo git pull netasm-patch carp 40 | 41 | # Install pxpcap 42 | cd ~/pox/pox/lib/pxpcap/pxpcap_c/ 43 | sudo ./build_linux 44 | 45 | # Add POX to PATH and PYTHONPATH environment variables 46 | echo 'export PATH=$PATH:$HOME/pox' >> ~/.profile 47 | echo 'export PYTHONPATH=$PYTHONPATH:$HOME/pox' >> ~/.profile -------------------------------------------------------------------------------- /tools/veth_setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | vethpairs=48 4 | 5 | if [ $# -eq 1 ]; then 6 | vethpairs=$1 7 | fi 8 | 9 | if [ $vethpairs -gt 48 ]; then 10 | echo "No of veth pairs should be less than or equal to 48" 11 | exit 12 | fi 13 | 14 | echo "No of veth pairs is $vethpairs" 15 | 16 | idx=0 17 | 18 | while [ $idx -lt $vethpairs ] 19 | do 20 | intf0="veth$(($idx*2))" 21 | intf1="veth$(($idx*2+1))" 22 | idx=$((idx + 1)) 23 | if ! ip link show $intf0 &> /dev/null; then 24 | ip link add name $intf0 type veth peer name $intf1 25 | ip link set dev $intf0 up 26 | ip link set dev $intf1 up 27 | TOE_OPTIONS="rx tx sg tso ufo gso gro lro rxvlan txvlan rxhash" 28 | for TOE_OPTION in $TOE_OPTIONS; do 29 | /sbin/ethtool --offload $intf0 "$TOE_OPTION" off 30 | /sbin/ethtool --offload $intf1 "$TOE_OPTION" off 31 | done 32 | else 33 | ip link set dev $intf0 up 34 | ip link set dev $intf1 up 35 | fi 36 | done 37 | -------------------------------------------------------------------------------- /tools/veth_teardown.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | vethpairs=48 4 | 5 | if [ $# -eq 1 ]; then 6 | vethpairs=$1 7 | fi 8 | 9 | echo "No of veth pairs is $vethpairs" 10 | 11 | idx=0 12 | 13 | while [ $idx -lt $vethpairs ] 14 | do 15 | intf="veth$(($idx*2))" 16 | if ip link show $intf &> /dev/null; then 17 | ip link delete $intf type veth 18 | fi 19 | idx=$((idx + 1)) 20 | done --------------------------------------------------------------------------------