├── .github └── workflows │ └── on-push.yml ├── .obs └── workflows.yml ├── LICENSE ├── README.md ├── docs ├── images │ ├── bmv2_setup.png │ ├── image_custom.png │ ├── image_storage.png │ ├── image_write.png │ ├── l2switch_setupA.png │ ├── l2switch_setupB.png │ ├── logo.png │ ├── results.png │ └── switch_interface.png └── pdf │ └── ccr21p4pi.pdf ├── exercises ├── bmv2 │ ├── calc │ │ ├── cal.py │ │ ├── calc.p4 │ │ └── solution │ │ │ ├── cal.py │ │ │ └── calc.p4 │ └── l3forwarding │ │ ├── basic.p4 │ │ └── solution │ │ └── basic.p4 └── internet-router │ ├── control-plane │ ├── p4runtime_lib │ │ ├── __init__.py │ │ ├── bmv2.py │ │ ├── convert.py │ │ ├── error_utils.py │ │ ├── helper.py │ │ ├── simple_controller.py │ │ └── switch.py │ └── pwospf.py │ └── data-plane │ └── router.p4 ├── p4app ├── LICENSE ├── README.md ├── basic.p4app │ ├── cleanup │ ├── commands1.txt │ ├── commands2.txt │ ├── commands3.txt │ ├── install_scripts.sh │ ├── p4app.json │ ├── p4src │ │ ├── basic.p4 │ │ └── solution │ │ │ ├── basic.p4 │ │ │ ├── commands1.txt │ │ │ ├── commands2.txt │ │ │ └── commands3.txt │ ├── receive.py │ ├── send.py │ ├── topo.py │ ├── topo.txt │ ├── xterm_h1.sh │ ├── xterm_h2.sh │ └── xterm_h3.sh ├── calc.p4app │ ├── README.md │ ├── cal.py │ ├── cleanup │ ├── commands1.txt │ ├── commands2.txt │ ├── commands3.txt │ ├── install_scripts.sh │ ├── p4app.json │ ├── p4src │ │ ├── calc.p4 │ │ └── solution │ │ │ └── calc.p4 │ ├── topo.py │ ├── topo.txt │ ├── xterm_h1.sh │ ├── xterm_h2.sh │ └── xterm_h3.sh ├── p4app └── topo.png ├── packages ├── obs │ ├── stable │ │ ├── libbpf │ │ │ ├── changelog │ │ │ ├── control │ │ │ ├── copyright │ │ │ ├── libbpf-dev.install │ │ │ ├── libbpf0.install │ │ │ ├── libbpf0.symbols │ │ │ ├── rules │ │ │ ├── source │ │ │ │ └── format │ │ │ ├── upstream │ │ │ │ └── metadata │ │ │ └── watch │ │ ├── p4lang-bmv2 │ │ │ ├── changelog │ │ │ ├── compat │ │ │ ├── control │ │ │ ├── copyright │ │ │ ├── rules │ │ │ └── source │ │ │ │ └── format │ │ ├── p4lang-p4c │ │ │ ├── changelog │ │ │ ├── compat │ │ │ ├── control │ │ │ ├── copyright │ │ │ ├── rules │ │ │ └── source │ │ │ │ └── format │ │ ├── p4lang-pi │ │ │ ├── changelog │ │ │ ├── compat │ │ │ ├── control │ │ │ ├── copyright │ │ │ ├── rules │ │ │ ├── source │ │ │ │ └── format │ │ │ └── watch │ │ ├── p4pi-examples │ │ │ └── _service │ │ ├── p4pi-kernel │ │ │ ├── 0001-Add-package-prefix.patch │ │ │ ├── README.md │ │ │ ├── config_p4pi.patch │ │ │ └── pack.sh │ │ └── p4pi-web │ │ │ └── _service │ └── unstable │ │ ├── p4pi-examples │ │ └── _service │ │ └── p4pi-web │ │ └── _service ├── p4pi-examples │ ├── apu-examples.cfg │ ├── bmv2 │ │ ├── arp_icmp │ │ │ └── arp_icmp.p4 │ │ ├── basic_mirror │ │ │ └── basic_mirror.p4 │ │ ├── calc │ │ │ ├── calc.p4 │ │ │ ├── receive.py │ │ │ └── send.py │ │ ├── l2switch │ │ │ └── l2switch.p4 │ │ ├── reflector │ │ │ └── reflector.p4 │ │ ├── stateful_firewall │ │ │ └── stateful_firewall.p4 │ │ └── traffic_filter │ │ │ └── traffic_filter.p4 │ ├── dpdk │ │ └── basic_mirror │ │ │ ├── Makefile │ │ │ ├── main.c │ │ │ └── meson.build │ ├── packaging │ │ └── p4pi-examples.spec │ ├── pi-examples.cfg │ └── t4p4s │ │ ├── arp_icmp │ │ ├── README.md │ │ └── arp_icmp.p4 │ │ ├── basic_mirror │ │ └── basic_mirror.p4 │ │ ├── calc │ │ ├── README.md │ │ ├── calc.p4 │ │ ├── receive.py │ │ └── send.py │ │ ├── l2switch │ │ ├── README.md │ │ └── l2switch.p4 │ │ ├── reflector │ │ └── reflector.p4 │ │ ├── stateful_firewall │ │ ├── README.md │ │ └── stateful_firewall.p4 │ │ └── traffic_filter │ │ ├── README.md │ │ └── traffic_filter.p4 └── p4pi-web │ ├── .editorconfig │ ├── .gitignore │ ├── .obs │ └── workflows.yml │ ├── LICENSE │ ├── README.md │ ├── config │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ ├── dashboard │ ├── __init__.py │ ├── admin.py │ ├── config.py │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── static │ │ ├── assets │ │ │ ├── css │ │ │ │ └── style.css │ │ │ ├── fonts │ │ │ │ ├── datta │ │ │ │ │ ├── fonts │ │ │ │ │ │ ├── pct.eot │ │ │ │ │ │ ├── pct.svg │ │ │ │ │ │ ├── pct.ttf │ │ │ │ │ │ └── pct.woff │ │ │ │ │ └── icon.css │ │ │ │ ├── feather │ │ │ │ │ ├── css │ │ │ │ │ │ └── feather.css │ │ │ │ │ └── fonts │ │ │ │ │ │ ├── feather.eot │ │ │ │ │ │ ├── feather.svg │ │ │ │ │ │ ├── feather.ttf │ │ │ │ │ │ └── feather.woff │ │ │ │ ├── fontawesome │ │ │ │ │ ├── css │ │ │ │ │ │ └── fontawesome-all.min.css │ │ │ │ │ └── webfonts │ │ │ │ │ │ ├── fa-brands-400.eot │ │ │ │ │ │ ├── fa-brands-400.svg │ │ │ │ │ │ ├── fa-brands-400.ttf │ │ │ │ │ │ ├── fa-brands-400.woff │ │ │ │ │ │ ├── fa-brands-400.woff2 │ │ │ │ │ │ ├── fa-regular-400.eot │ │ │ │ │ │ ├── fa-regular-400.svg │ │ │ │ │ │ ├── fa-regular-400.ttf │ │ │ │ │ │ ├── fa-regular-400.woff │ │ │ │ │ │ ├── fa-regular-400.woff2 │ │ │ │ │ │ ├── fa-solid-900.eot │ │ │ │ │ │ ├── fa-solid-900.svg │ │ │ │ │ │ ├── fa-solid-900.ttf │ │ │ │ │ │ ├── fa-solid-900.woff │ │ │ │ │ │ └── fa-solid-900.woff2 │ │ │ │ ├── material │ │ │ │ │ └── material_icons_w400.woff2 │ │ │ │ └── opensans │ │ │ │ │ ├── opensans.css │ │ │ │ │ ├── opensans_w300.ttf │ │ │ │ │ ├── opensans_w400.ttf │ │ │ │ │ └── opensans_w600.ttf │ │ │ ├── images │ │ │ │ ├── favicon.ico │ │ │ │ └── logo.png │ │ │ ├── js │ │ │ │ ├── chart.js │ │ │ │ ├── jquery.min.js │ │ │ │ ├── main.js │ │ │ │ ├── pages │ │ │ │ │ └── chart-morris-custom.js │ │ │ │ ├── pcoded.min.js │ │ │ │ └── vendor-all.min.js │ │ │ └── plugins │ │ │ │ ├── amchart │ │ │ │ └── js │ │ │ │ │ ├── amcharts.js │ │ │ │ │ ├── ammap.min.js │ │ │ │ │ ├── gauge.js │ │ │ │ │ ├── images │ │ │ │ │ ├── dragIconRoundBig.svg │ │ │ │ │ └── lens.svg │ │ │ │ │ ├── light.js │ │ │ │ │ ├── pie.min.js │ │ │ │ │ ├── radar.js │ │ │ │ │ ├── serial.js │ │ │ │ │ ├── usaLow.js │ │ │ │ │ └── worldLow.js │ │ │ │ ├── animation │ │ │ │ └── css │ │ │ │ │ └── animate.min.css │ │ │ │ ├── bootstrap │ │ │ │ ├── css │ │ │ │ │ ├── bootstrap.css │ │ │ │ │ └── bootstrap.min.css │ │ │ │ └── js │ │ │ │ │ ├── bootstrap.js │ │ │ │ │ ├── bootstrap.min.js │ │ │ │ │ └── popover.js │ │ │ │ ├── chart-morris │ │ │ │ ├── css │ │ │ │ │ └── morris.css │ │ │ │ └── js │ │ │ │ │ ├── morris.min.js │ │ │ │ │ └── raphael.min.js │ │ │ │ ├── jquery-scrollbar │ │ │ │ ├── css │ │ │ │ │ └── jquery.scrollbar.min.css │ │ │ │ └── js │ │ │ │ │ └── jquery.scrollbar.min.js │ │ │ │ ├── jquery-ui │ │ │ │ └── js │ │ │ │ │ └── jquery-ui.js │ │ │ │ └── jquery │ │ │ │ └── js │ │ │ │ └── jquery.min.js │ │ └── favicon.ico │ ├── templates │ │ ├── access-point.html │ │ ├── accounts │ │ │ ├── login.html │ │ │ ├── password_change.html │ │ │ └── register.html │ │ ├── entries.html │ │ ├── includes │ │ │ ├── navigation.html │ │ │ └── scripts.html │ │ ├── index.html │ │ ├── layouts │ │ │ ├── base-fullscreen.html │ │ │ └── base.html │ │ ├── page-403.html │ │ ├── page-404.html │ │ ├── page-500.html │ │ └── statistics.html │ ├── tests.py │ ├── urls.py │ ├── utils.py │ └── views.py │ ├── dummy_ctrl_plane_connection.py │ ├── fixtures │ └── users.json │ ├── generate-statistics.py │ ├── gunicorn-cfg.py │ ├── manage.py │ ├── packaging │ ├── bmv2-p4rtshell │ ├── bmv2-start │ ├── bmv2.service │ ├── p4pi-web-dummy-ctrl-plane.service │ ├── p4pi-web-genstat.service │ ├── p4pi-web.service │ └── p4pi-web.spec │ ├── poetry.lock │ ├── pyproject.toml │ ├── requirements.txt │ └── terminal │ ├── __init__.py │ ├── static │ ├── fit.js │ ├── fullscreen.js │ ├── socket.io.js │ ├── xterm.css │ └── xterm.js │ ├── templates │ └── terminal.html │ ├── urls.py │ └── views.py ├── pi-gen ├── .dockerignore ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── build-docker.sh ├── build.sh ├── config ├── depends ├── docker-compose.yml ├── export-image │ ├── 00-allow-rerun │ │ └── 00-run.sh │ ├── 01-user-rename │ │ ├── 00-packages │ │ └── 01-run.sh │ ├── 02-set-sources │ │ └── 01-run.sh │ ├── 03-network │ │ ├── 01-run.sh │ │ └── files │ │ │ └── resolv.conf │ ├── 04-set-partuuid │ │ └── 00-run.sh │ ├── 05-finalise │ │ └── 01-run.sh │ └── prerun.sh ├── imagetool.sh ├── scripts │ ├── common │ ├── dependencies_check │ ├── qcow2_handling │ └── remove-comments.sed ├── stage0 │ ├── 00-configure-apt │ │ ├── 00-run.sh │ │ ├── 01-packages │ │ └── files │ │ │ ├── 51cache │ │ │ ├── raspberrypi.gpg.key │ │ │ ├── raspi.list │ │ │ └── sources.list │ ├── 01-locale │ │ ├── 00-debconf │ │ └── 00-packages │ ├── 02-firmware │ │ └── 01-packages │ ├── files │ │ └── raspberrypi.gpg │ └── prerun.sh ├── stage1 │ ├── 00-boot-files │ │ ├── 00-run.sh │ │ └── files │ │ │ ├── cmdline.txt │ │ │ └── config.txt │ ├── 01-sys-tweaks │ │ ├── 00-packages │ │ ├── 00-patches │ │ │ ├── 01-bashrc.diff │ │ │ └── series │ │ ├── 00-run.sh │ │ └── files │ │ │ ├── fstab │ │ │ └── noclear.conf │ ├── 02-net-tweaks │ │ ├── 00-packages │ │ └── 00-run.sh │ ├── 03-install-packages │ │ └── 00-packages │ └── prerun.sh ├── stage2 │ ├── 01-sys-tweaks │ │ ├── 00-debconf │ │ ├── 00-packages │ │ ├── 00-packages-nr │ │ ├── 00-patches │ │ │ ├── 01-useradd.diff │ │ │ ├── 02-swap.diff │ │ │ ├── 04-inputrc.diff │ │ │ ├── 05-path.diff │ │ │ ├── 07-resize-init.diff │ │ │ └── series │ │ ├── 01-run.sh │ │ └── files │ │ │ ├── 50raspi │ │ │ ├── 90-qemu.rules │ │ │ ├── console-setup │ │ │ ├── rc.local │ │ │ ├── resize2fs_once │ │ │ └── ttyoutput.conf │ ├── 02-net-tweaks │ │ ├── 00-packages │ │ ├── 01-run.sh │ │ └── files │ │ │ └── wpa_supplicant.conf │ ├── 03-set-timezone │ │ └── 02-run.sh │ └── prerun.sh └── stage3 │ ├── 01-p4pi │ ├── 00-run.sh │ ├── 01-packages │ ├── 02-run.sh │ └── files │ │ └── motd │ ├── 02-enable-access-point │ ├── 00-packages │ ├── 00-run.sh │ └── files │ │ ├── dhcpcd.conf │ │ ├── dnsmasq.conf │ │ ├── hostapd.conf │ │ ├── p4pi-setup │ │ ├── p4pi-setup-eth-wlan-bridge │ │ ├── p4pi-setup-eth-wlan-bridge.service │ │ ├── p4pi-setup.service │ │ ├── p4pi.conf │ │ └── resolved.conf │ ├── EXPORT_IMAGE │ └── prerun.sh └── vm ├── .gitignore ├── README.md ├── Vagrantfile ├── bootstrap.sh └── files ├── bash.bashrc ├── dhcpcd.conf ├── dnsmasq.conf ├── jupyter.service ├── p4pi-setup ├── p4pi-setup.service ├── p4pi.conf ├── t4p4s-p4rtshell ├── t4p4s-start └── t4p4s.service /.github/workflows/on-push.yml: -------------------------------------------------------------------------------- 1 | name: Build image on push or PR 2 | on: 3 | push: 4 | branches: 5 | - master 6 | paths: 7 | - 'pi-gen/**' 8 | - 'packages/**' 9 | - '.github/workflows/on-push.yml' 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | defaults: 15 | run: 16 | shell: bash 17 | working-directory: pi-gen 18 | 19 | steps: 20 | - uses: actions/checkout@v4 21 | 22 | - name: Register binfmt_misc entries 23 | run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes 24 | 25 | - name: Run build script 26 | run: sudo PIGEN_DOCKER_OPTS="-e DEPLOY_XZ=1" ./build-docker.sh 27 | 28 | - name: List deploy directory 29 | run: ls -al deploy/ 30 | 31 | - name: Set image name 32 | run: | 33 | IMAGE_NAME="p4pi-$(date +'%Y-%m-%d')-$(git rev-parse --short=8 HEAD)" 34 | echo "IMAGE_NAME=$IMAGE_NAME" >> $GITHUB_ENV 35 | 36 | - name: Upload artifact 37 | uses: actions/upload-artifact@v4 38 | with: 39 | name: ${{ env.IMAGE_NAME }} 40 | path: pi-gen/deploy/*.zip 41 | if-no-files-found: error 42 | retention-days: 90 43 | -------------------------------------------------------------------------------- /.obs/workflows.yml: -------------------------------------------------------------------------------- 1 | build_tag: 2 | steps: 3 | - trigger_services: 4 | project: "home:p4pi:unstable" 5 | package: "p4pi-examples" 6 | - trigger_services: 7 | project: "home:p4pi:unstable" 8 | package: "p4pi-web" 9 | - trigger_services: 10 | project: "home:p4pi" 11 | package: "p4pi-examples" 12 | - trigger_services: 13 | project: "home:p4pi" 14 | package: "p4pi-web" 15 | filters: 16 | event: tag_push 17 | 18 | build_unstable: 19 | steps: 20 | - trigger_services: 21 | project: "home:p4pi:unstable" 22 | package: "p4pi-examples" 23 | - trigger_services: 24 | project: "home:p4pi:unstable" 25 | package: "p4pi-web" 26 | filters: 27 | event: push 28 | branches: 29 | only: 30 | - main 31 | -------------------------------------------------------------------------------- /docs/images/bmv2_setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/docs/images/bmv2_setup.png -------------------------------------------------------------------------------- /docs/images/image_custom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/docs/images/image_custom.png -------------------------------------------------------------------------------- /docs/images/image_storage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/docs/images/image_storage.png -------------------------------------------------------------------------------- /docs/images/image_write.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/docs/images/image_write.png -------------------------------------------------------------------------------- /docs/images/l2switch_setupA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/docs/images/l2switch_setupA.png -------------------------------------------------------------------------------- /docs/images/l2switch_setupB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/docs/images/l2switch_setupB.png -------------------------------------------------------------------------------- /docs/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/docs/images/logo.png -------------------------------------------------------------------------------- /docs/images/results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/docs/images/results.png -------------------------------------------------------------------------------- /docs/images/switch_interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/docs/images/switch_interface.png -------------------------------------------------------------------------------- /docs/pdf/ccr21p4pi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/docs/pdf/ccr21p4pi.pdf -------------------------------------------------------------------------------- /exercises/bmv2/calc/cal.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import re 4 | 5 | from scapy.all import ( 6 | Ether, 7 | IntField, 8 | Packet, 9 | StrFixedLenField, 10 | XByteField, 11 | bind_layers, 12 | srp1, 13 | get_if_list 14 | ) 15 | 16 | 17 | class P4calc(Packet): 18 | name = "P4calc" 19 | fields_desc = [ StrFixedLenField("P", "P", length=1), 20 | StrFixedLenField("Four", "4", length=1), 21 | XByteField("version", 0x01), 22 | StrFixedLenField("op", "+", length=1), 23 | IntField("operand_a", 0), 24 | IntField("operand_b", 0), 25 | IntField("result", 0xDEADBABE)] 26 | 27 | bind_layers(Ether, P4calc, type=0x1234) 28 | 29 | class NumParseError(Exception): 30 | pass 31 | 32 | class OpParseError(Exception): 33 | pass 34 | 35 | class Token: 36 | def __init__(self,type,value = None): 37 | self.type = type 38 | self.value = value 39 | 40 | def num_parser(s, i, ts): 41 | pattern = "^\s*([0-9]+)\s*" 42 | match = re.match(pattern,s[i:]) 43 | if match: 44 | ts.append(Token('num', match.group(1))) 45 | return i + match.end(), ts 46 | raise NumParseError('Expected number literal.') 47 | 48 | 49 | def op_parser(s, i, ts): 50 | pattern = "^\s*([-+&|^])\s*" 51 | match = re.match(pattern,s[i:]) 52 | if match: 53 | ts.append(Token('num', match.group(1))) 54 | return i + match.end(), ts 55 | raise NumParseError("Expected binary operator '-', '+', '&', '|', or '^'.") 56 | 57 | 58 | def make_seq(p1, p2): 59 | def parse(s, i, ts): 60 | i,ts2 = p1(s,i,ts) 61 | return p2(s,i,ts2) 62 | return parse 63 | 64 | def get_if(): 65 | ifs=get_if_list() 66 | iface= "veth0-1" 67 | for i in get_if_list(): 68 | if "eth0" in i: 69 | iface=i 70 | break; 71 | if not iface: 72 | print("Cannot find eth0 interface") 73 | exit(1) 74 | return iface 75 | 76 | def main(): 77 | 78 | p = make_seq(num_parser, make_seq(op_parser,num_parser)) 79 | s = '' 80 | iface = get_if() 81 | 82 | while True: 83 | s = input('> ') 84 | if s == "quit": 85 | break 86 | try: 87 | i,ts = p(s,0,[]) 88 | pkt = Ether(dst='00:04:00:00:00:00', type=0x1234) / P4calc(op=ts[1].value, 89 | operand_a=int(ts[0].value), 90 | operand_b=int(ts[2].value)) 91 | pkt = pkt/' ' 92 | 93 | # pkt.show() 94 | resp = srp1(pkt, iface=iface, timeout=1, verbose=False) 95 | if resp: 96 | p4calc=resp[P4calc] 97 | if p4calc: 98 | print(p4calc.result) 99 | else: 100 | print("cannot find P4calc header in the packet") 101 | else: 102 | print("Didn't receive response") 103 | except Exception as error: 104 | print(error) 105 | 106 | 107 | if __name__ == '__main__': 108 | main() 109 | -------------------------------------------------------------------------------- /exercises/bmv2/calc/solution/cal.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import re 4 | 5 | from scapy.all import ( 6 | Ether, 7 | IntField, 8 | Packet, 9 | StrFixedLenField, 10 | XByteField, 11 | bind_layers, 12 | srp1, 13 | get_if_list 14 | ) 15 | 16 | 17 | class P4calc(Packet): 18 | name = "P4calc" 19 | fields_desc = [ StrFixedLenField("P", "P", length=1), 20 | StrFixedLenField("Four", "4", length=1), 21 | XByteField("version", 0x01), 22 | StrFixedLenField("op", "+", length=1), 23 | IntField("operand_a", 0), 24 | IntField("operand_b", 0), 25 | IntField("result", 0xDEADBABE)] 26 | 27 | bind_layers(Ether, P4calc, type=0x1234) 28 | 29 | class NumParseError(Exception): 30 | pass 31 | 32 | class OpParseError(Exception): 33 | pass 34 | 35 | class Token: 36 | def __init__(self,type,value = None): 37 | self.type = type 38 | self.value = value 39 | 40 | def num_parser(s, i, ts): 41 | pattern = "^\s*([0-9]+)\s*" 42 | match = re.match(pattern,s[i:]) 43 | if match: 44 | ts.append(Token('num', match.group(1))) 45 | return i + match.end(), ts 46 | raise NumParseError('Expected number literal.') 47 | 48 | 49 | def op_parser(s, i, ts): 50 | pattern = "^\s*([-+&|^])\s*" 51 | match = re.match(pattern,s[i:]) 52 | if match: 53 | ts.append(Token('num', match.group(1))) 54 | return i + match.end(), ts 55 | raise NumParseError("Expected binary operator '-', '+', '&', '|', or '^'.") 56 | 57 | 58 | def make_seq(p1, p2): 59 | def parse(s, i, ts): 60 | i,ts2 = p1(s,i,ts) 61 | return p2(s,i,ts2) 62 | return parse 63 | 64 | def get_if(): 65 | ifs=get_if_list() 66 | iface= "veth0-1" 67 | return iface 68 | 69 | def main(): 70 | 71 | p = make_seq(num_parser, make_seq(op_parser,num_parser)) 72 | s = '' 73 | iface = get_if() 74 | 75 | while True: 76 | s = input('> ') 77 | if s == "quit": 78 | break 79 | try: 80 | i,ts = p(s,0,[]) 81 | pkt = Ether(dst='00:04:00:00:00:00', type=0x1234) / P4calc(op=ts[1].value, 82 | operand_a=int(ts[0].value), 83 | operand_b=int(ts[2].value)) 84 | pkt = pkt/' ' 85 | 86 | # pkt.show() 87 | resp = srp1(pkt, iface=iface, timeout=1, verbose=False) 88 | if resp: 89 | p4calc=resp[P4calc] 90 | if p4calc: 91 | print(p4calc.result) 92 | else: 93 | print("cannot find P4calc header in the packet") 94 | else: 95 | print("Didn't receive response") 96 | except Exception as error: 97 | print(error) 98 | 99 | 100 | if __name__ == '__main__': 101 | main() 102 | -------------------------------------------------------------------------------- /exercises/internet-router/control-plane/p4runtime_lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/exercises/internet-router/control-plane/p4runtime_lib/__init__.py -------------------------------------------------------------------------------- /exercises/internet-router/control-plane/p4runtime_lib/bmv2.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017-present Open Networking Foundation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | from .switch import SwitchConnection 16 | from p4.tmp import p4config_pb2 17 | 18 | 19 | def buildDeviceConfig(bmv2_json_file_path=None): 20 | "Builds the device config for BMv2" 21 | device_config = p4config_pb2.P4DeviceConfig() 22 | device_config.reassign = True 23 | with open(bmv2_json_file_path) as f: 24 | device_config.device_data = f.read().encode('utf-8') 25 | return device_config 26 | 27 | 28 | class Bmv2SwitchConnection(SwitchConnection): 29 | def buildDeviceConfig(self, **kwargs): 30 | return buildDeviceConfig(**kwargs) 31 | -------------------------------------------------------------------------------- /p4app/basic.p4app/cleanup: -------------------------------------------------------------------------------- 1 | sudo mn -c 2 | sudo killall lt-simple_switch 3 | sudo rm -f *.pcap 4 | sudo rm -f *.json 5 | -------------------------------------------------------------------------------- /p4app/basic.p4app/commands1.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/p4app/basic.p4app/commands1.txt -------------------------------------------------------------------------------- /p4app/basic.p4app/commands2.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/p4app/basic.p4app/commands2.txt -------------------------------------------------------------------------------- /p4app/basic.p4app/commands3.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/p4app/basic.p4app/commands3.txt -------------------------------------------------------------------------------- /p4app/basic.p4app/install_scripts.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | CAL=$(docker ps|grep -m1 p4app_|awk '{print $1}') 4 | docker cp send.py $CAL:/scripts 5 | docker cp receive.py $CAL:/scripts 6 | echo "Done" 7 | -------------------------------------------------------------------------------- /p4app/basic.p4app/p4app.json: -------------------------------------------------------------------------------- 1 | { 2 | "program": "p4src/basic.p4", 3 | "language": "p4-16", 4 | "targets": { 5 | "custom": { 6 | "program": "topo.py" 7 | }, 8 | "after": { 9 | "cmd": [ 10 | "sudo mn -c", 11 | " killall lt-simple_switch" 12 | ] 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /p4app/basic.p4app/p4src/solution/commands1.txt: -------------------------------------------------------------------------------- 1 | table_add ipv4_lpm ipv4_forward 10.0.1.1/32 => 00:00:00:00:01:01 1 2 | table_add ipv4_lpm ipv4_forward 10.0.2.2/32 => 00:00:00:00:02:02 3 3 | table_add ipv4_lpm ipv4_forward 10.0.3.3/32 => 00:00:00:00:03:03 2 4 | -------------------------------------------------------------------------------- /p4app/basic.p4app/p4src/solution/commands2.txt: -------------------------------------------------------------------------------- 1 | table_add ipv4_lpm ipv4_forward 10.0.1.1/32 => 00:00:00:00:01:01 2 2 | table_add ipv4_lpm ipv4_forward 10.0.2.2/32 => 00:00:00:00:02:02 1 3 | table_add ipv4_lpm ipv4_forward 10.0.3.3/32 => 00:00:00:00:03:03 3 4 | -------------------------------------------------------------------------------- /p4app/basic.p4app/p4src/solution/commands3.txt: -------------------------------------------------------------------------------- 1 | table_add ipv4_lpm ipv4_forward 10.0.1.1/32 => 00:00:00:00:01:01 2 2 | table_add ipv4_lpm ipv4_forward 10.0.2.2/32 => 00:00:00:00:02:02 3 3 | table_add ipv4_lpm ipv4_forward 10.0.3.3/32 => 00:00:00:00:03:03 1 4 | -------------------------------------------------------------------------------- /p4app/basic.p4app/receive.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | import struct 4 | import os 5 | 6 | from scapy.all import sniff, sendp, hexdump, get_if_list, get_if_hwaddr 7 | from scapy.all import Packet, IPOption 8 | from scapy.all import ShortField, IntField, LongField, BitField, FieldListField, FieldLenField 9 | from scapy.all import IP, TCP, UDP, Raw 10 | from scapy.layers.inet import _IPOption_HDR 11 | 12 | def get_if(): 13 | ifs=get_if_list() 14 | iface=None 15 | for i in get_if_list(): 16 | if "eth0" in i: 17 | iface=i 18 | break; 19 | if not iface: 20 | print("Cannot find eth0 interface") 21 | exit(1) 22 | return iface 23 | 24 | class IPOption_MRI(IPOption): 25 | name = "MRI" 26 | option = 31 27 | fields_desc = [ _IPOption_HDR, 28 | FieldLenField("length", None, fmt="B", 29 | length_of="swids", 30 | adjust=lambda pkt,l:l+4), 31 | ShortField("count", 0), 32 | FieldListField("swids", 33 | [], 34 | IntField("", 0), 35 | length_from=lambda pkt:pkt.count*4) ] 36 | def handle_pkt(pkt): 37 | if TCP in pkt and pkt[TCP].dport == 1234: 38 | print("got a packet") 39 | pkt.show2() 40 | # hexdump(pkt) 41 | sys.stdout.flush() 42 | 43 | 44 | def main(): 45 | ifaces = [i for i in os.listdir('/sys/class/net/') if 'eth' in i] 46 | iface = ifaces[0] 47 | print(("sniffing on %s" % iface)) 48 | sys.stdout.flush() 49 | sniff(iface = iface, 50 | prn = lambda x: handle_pkt(x)) 51 | 52 | if __name__ == '__main__': 53 | main() 54 | -------------------------------------------------------------------------------- /p4app/basic.p4app/send.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import argparse 3 | import sys 4 | import socket 5 | import random 6 | import struct 7 | 8 | from scapy.all import sendp, send, get_if_list, get_if_hwaddr 9 | from scapy.all import Packet 10 | from scapy.all import Ether, IP, UDP, TCP 11 | 12 | def get_if(): 13 | ifs=get_if_list() 14 | iface=None # "h1-eth0" 15 | for i in get_if_list(): 16 | if "eth0" in i: 17 | iface=i 18 | break; 19 | if not iface: 20 | print("Cannot find eth0 interface") 21 | exit(1) 22 | return iface 23 | 24 | def main(): 25 | 26 | if len(sys.argv)<3: 27 | print('pass 2 arguments: ""') 28 | exit(1) 29 | 30 | addr = sys.argv[1] 31 | iface = get_if() 32 | 33 | if addr == "h1": 34 | addr = "10.0.1.1" 35 | elif addr == "h2": 36 | addr = "10.0.2.2" 37 | elif addr == "h3": 38 | addr = "10.0.3.3" 39 | else: 40 | addr = socket.gethostbyname(sys.argv[1]) 41 | 42 | 43 | print(("sending on interface %s to %s" % (iface, str(addr)))) 44 | pkt = Ether(src=get_if_hwaddr(iface), dst='ff:ff:ff:ff:ff:ff') 45 | pkt = pkt /IP(dst=addr) / TCP(dport=1234, sport=random.randint(49152,65535)) / sys.argv[2] 46 | pkt.show2() 47 | sendp(pkt, iface=iface, verbose=False) 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | 53 | -------------------------------------------------------------------------------- /p4app/basic.p4app/topo.txt: -------------------------------------------------------------------------------- 1 | switches 3 2 | hosts 3 3 | h1 s1 4 | h2 s2 5 | h3 s3 6 | s1 s3 7 | s1 s2 8 | s2 s3 9 | -------------------------------------------------------------------------------- /p4app/basic.p4app/xterm_h1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2013-present Barefoot Networks, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | #THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 18 | 19 | #source $THIS_DIR/../../env.sh 20 | 21 | #CLI_PATH=$BMV2_PATH/targets/simple_switch/sswitch_CLI 22 | 23 | echo "Switch 10.0.1.1" 24 | 25 | 26 | echo "Entering host xterm h1" 27 | p4app exec m h1 bash 28 | echo 29 | 30 | -------------------------------------------------------------------------------- /p4app/basic.p4app/xterm_h2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2013-present Barefoot Networks, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | #THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 18 | 19 | #source $THIS_DIR/../../env.sh 20 | 21 | #CLI_PATH=$BMV2_PATH/targets/simple_switch/sswitch_CLI 22 | 23 | echo "Switch 10.0.2.2" 24 | 25 | 26 | echo "Entering host xterm h2" 27 | p4app exec m h2 bash 28 | echo 29 | 30 | -------------------------------------------------------------------------------- /p4app/basic.p4app/xterm_h3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2013-present Barefoot Networks, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | #THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 18 | 19 | #source $THIS_DIR/../../env.sh 20 | 21 | #CLI_PATH=$BMV2_PATH/targets/simple_switch/sswitch_CLI 22 | 23 | echo "Switch 10.0.3.3" 24 | 25 | 26 | echo "Entering host xterm h3" 27 | p4app exec m h3 bash 28 | echo 29 | 30 | -------------------------------------------------------------------------------- /p4app/calc.p4app/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/p4app/calc.p4app/README.md -------------------------------------------------------------------------------- /p4app/calc.p4app/cal.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import re 4 | 5 | from scapy.all import ( 6 | Ether, 7 | IntField, 8 | Packet, 9 | StrFixedLenField, 10 | XByteField, 11 | bind_layers, 12 | srp1, 13 | get_if_list 14 | ) 15 | 16 | 17 | class P4calc(Packet): 18 | name = "P4calc" 19 | fields_desc = [ StrFixedLenField("P", "P", length=1), 20 | StrFixedLenField("Four", "4", length=1), 21 | XByteField("version", 0x01), 22 | StrFixedLenField("op", "+", length=1), 23 | IntField("operand_a", 0), 24 | IntField("operand_b", 0), 25 | IntField("result", 0xDEADBABE)] 26 | 27 | bind_layers(Ether, P4calc, type=0x1234) 28 | 29 | class NumParseError(Exception): 30 | pass 31 | 32 | class OpParseError(Exception): 33 | pass 34 | 35 | class Token: 36 | def __init__(self,type,value = None): 37 | self.type = type 38 | self.value = value 39 | 40 | def num_parser(s, i, ts): 41 | pattern = "^\s*([0-9]+)\s*" 42 | match = re.match(pattern,s[i:]) 43 | if match: 44 | ts.append(Token('num', match.group(1))) 45 | return i + match.end(), ts 46 | raise NumParseError('Expected number literal.') 47 | 48 | 49 | def op_parser(s, i, ts): 50 | pattern = "^\s*([-+&|^])\s*" 51 | match = re.match(pattern,s[i:]) 52 | if match: 53 | ts.append(Token('num', match.group(1))) 54 | return i + match.end(), ts 55 | raise NumParseError("Expected binary operator '-', '+', '&', '|', or '^'.") 56 | 57 | 58 | def make_seq(p1, p2): 59 | def parse(s, i, ts): 60 | i,ts2 = p1(s,i,ts) 61 | return p2(s,i,ts2) 62 | return parse 63 | 64 | def get_if(): 65 | ifs=get_if_list() 66 | iface=None # "h1-eth0" 67 | for i in get_if_list(): 68 | if "eth0" in i: 69 | iface=i 70 | break; 71 | if not iface: 72 | print("Cannot find eth0 interface") 73 | exit(1) 74 | return iface 75 | 76 | def main(): 77 | 78 | p = make_seq(num_parser, make_seq(op_parser,num_parser)) 79 | s = '' 80 | iface = get_if() 81 | 82 | while True: 83 | s = input('> ') 84 | if s == "quit": 85 | break 86 | try: 87 | i,ts = p(s,0,[]) 88 | pkt = Ether(dst='00:04:00:00:00:00', type=0x1234) / P4calc(op=ts[1].value, 89 | operand_a=int(ts[0].value), 90 | operand_b=int(ts[2].value)) 91 | pkt = pkt/' ' 92 | 93 | # pkt.show() 94 | resp = srp1(pkt, iface=iface, timeout=1, verbose=False) 95 | if resp: 96 | p4calc=resp[P4calc] 97 | if p4calc: 98 | print(p4calc.result) 99 | else: 100 | print("cannot find P4calc header in the packet") 101 | else: 102 | print("Didn't receive response") 103 | except Exception as error: 104 | print(error) 105 | 106 | 107 | if __name__ == '__main__': 108 | main() 109 | -------------------------------------------------------------------------------- /p4app/calc.p4app/cleanup: -------------------------------------------------------------------------------- 1 | sudo mn -c 2 | sudo killall lt-simple_switch 3 | sudo rm -f *.pcap 4 | sudo rm -f *.json 5 | -------------------------------------------------------------------------------- /p4app/calc.p4app/commands1.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /p4app/calc.p4app/commands2.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/p4app/calc.p4app/commands2.txt -------------------------------------------------------------------------------- /p4app/calc.p4app/commands3.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/p4app/calc.p4app/commands3.txt -------------------------------------------------------------------------------- /p4app/calc.p4app/install_scripts.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | CAL=$(docker ps|grep -m1 p4app_|awk '{print $1}') 4 | 5 | docker cp cal.py $CAL:/scripts 6 | -------------------------------------------------------------------------------- /p4app/calc.p4app/p4app.json: -------------------------------------------------------------------------------- 1 | { 2 | "program": "p4src/calc.p4", 3 | "language": "p4-16", 4 | "targets": { 5 | "custom": { 6 | "program": "topo.py" 7 | }, 8 | "after": { 9 | "cmd": [ 10 | "sudo mn -c", 11 | " killall lt-simple_switch" 12 | ] 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /p4app/calc.p4app/topo.txt: -------------------------------------------------------------------------------- 1 | switches 3 2 | hosts 3 3 | h1 s1 4 | h2 s2 5 | h3 s3 6 | s1 s3 7 | s1 s2 8 | s2 s3 9 | -------------------------------------------------------------------------------- /p4app/calc.p4app/xterm_h1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2013-present Barefoot Networks, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | #THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 18 | 19 | #source $THIS_DIR/../../env.sh 20 | 21 | #CLI_PATH=$BMV2_PATH/targets/simple_switch/sswitch_CLI 22 | 23 | echo "Switch 10.0.1.1" 24 | 25 | 26 | echo "Entering host xterm h1" 27 | p4app exec m h1 bash 28 | echo 29 | 30 | -------------------------------------------------------------------------------- /p4app/calc.p4app/xterm_h2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2013-present Barefoot Networks, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | #THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 18 | 19 | #source $THIS_DIR/../../env.sh 20 | 21 | #CLI_PATH=$BMV2_PATH/targets/simple_switch/sswitch_CLI 22 | 23 | echo "Switch 10.0.2.2" 24 | 25 | 26 | echo "Entering host xterm h2" 27 | p4app exec m h2 bash 28 | echo 29 | 30 | -------------------------------------------------------------------------------- /p4app/calc.p4app/xterm_h3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2013-present Barefoot Networks, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | #THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 18 | 19 | #source $THIS_DIR/../../env.sh 20 | 21 | #CLI_PATH=$BMV2_PATH/targets/simple_switch/sswitch_CLI 22 | 23 | echo "Switch 10.0.3.3" 24 | 25 | 26 | echo "Entering host xterm h3" 27 | p4app exec m h3 bash 28 | echo 29 | 30 | -------------------------------------------------------------------------------- /p4app/topo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/p4app/topo.png -------------------------------------------------------------------------------- /packages/obs/stable/libbpf/changelog: -------------------------------------------------------------------------------- 1 | libbpf (0.5.0-1) focal; urgency=medium 2 | 3 | * Ubuntu 20.04 package 4 | 5 | -- Radostin Stoyanov Thu, 04 Nov 2021 03:56:20 +0000 6 | 7 | libbpf (0.5.0-1) unstable; urgency=medium 8 | 9 | * New upstream version 0.5.0 10 | - Update copyright. 11 | - Update symbols. 12 | * Update Standards-Version to 4.6.0.1 13 | 14 | -- Sudip Mukherjee Fri, 17 Sep 2021 22:32:53 +0100 15 | 16 | libbpf (0.4.0-2) unstable; urgency=medium 17 | 18 | * Upload to unstable. 19 | 20 | -- Sudip Mukherjee Tue, 17 Aug 2021 22:12:29 +0100 21 | 22 | libbpf (0.4.0-1) experimental; urgency=medium 23 | 24 | * New upstream version 0.4.0 25 | - Update symbols. 26 | 27 | -- Sudip Mukherjee Tue, 25 May 2021 22:05:09 +0100 28 | 29 | libbpf (0.3-2) unstable; urgency=medium 30 | 31 | [ Luca Boccassi ] 32 | * Add build-dependency on zlib1g-dev 33 | * Use pkg-config to get build flags 34 | * Enable verbose builds unless 'terse' DEB_BUILD_OPTIONS is set 35 | * Have libbpf-dev depend on libelf-dev and zlib1g-dev 36 | 37 | -- Sudip Mukherjee Sun, 10 Jan 2021 17:43:30 +0000 38 | 39 | libbpf (0.3-1) unstable; urgency=medium 40 | 41 | * New upstream version 0.3 (Closes: #979166) 42 | - Update symbols file. 43 | * Update Standards-Version to 4.5.1 44 | 45 | -- Sudip Mukherjee Sun, 03 Jan 2021 23:27:11 +0000 46 | 47 | libbpf (0.2-1) unstable; urgency=medium 48 | 49 | * New upstream version 0.2 50 | - Update symbols file. 51 | - Update copyright for removed file. 52 | 53 | -- Sudip Mukherjee Thu, 29 Oct 2020 23:07:35 +0000 54 | 55 | libbpf (0.1.1-1) unstable; urgency=medium 56 | 57 | * Update from upstream v0.1.1 58 | 59 | -- Sudip Mukherjee Sat, 26 Sep 2020 23:17:58 +0100 60 | 61 | libbpf (0.1.0-1) unstable; urgency=medium 62 | 63 | * Update from upstream v0.1.0 64 | - Update symbols file. 65 | 66 | -- Sudip Mukherjee Wed, 26 Aug 2020 22:40:21 +0100 67 | 68 | libbpf (0.0.9-1) unstable; urgency=medium 69 | 70 | [ Debian Janitor ] 71 | * Set upstream metadata fields: Bug-Database, Bug-Submit, Repository, 72 | Repository-Browse. 73 | 74 | [ Sudip Mukherjee ] 75 | * Update from upstream v0.0.9 76 | - Update symbols file. 77 | 78 | -- Sudip Mukherjee Thu, 23 Jul 2020 18:35:16 +0100 79 | 80 | libbpf (0.0.8-1) unstable; urgency=medium 81 | 82 | * Update from upstream v0.0.8 83 | * Update symbols file. 84 | * Update compat level to 13. 85 | 86 | -- Sudip Mukherjee Fri, 01 May 2020 09:44:49 +0100 87 | 88 | libbpf (0.0.6-1) unstable; urgency=medium 89 | 90 | * Package from github. (Closes: #948041) 91 | 92 | -- Sudip Mukherjee Sat, 11 Apr 2020 16:12:37 +0100 93 | -------------------------------------------------------------------------------- /packages/obs/stable/libbpf/control: -------------------------------------------------------------------------------- 1 | Source: libbpf 2 | Priority: optional 3 | Maintainer: Sudip Mukherjee 4 | Build-Depends: debhelper-compat (= 12), libelf-dev, zlib1g-dev, pkg-config 5 | Standards-Version: 4.6.0.1 6 | Section: libs 7 | Vcs-Browser: https://github.com/sudipm-mukherjee/libbpf 8 | Vcs-Git: https://github.com/sudipm-mukherjee/libbpf.git 9 | 10 | Package: libbpf-dev 11 | Section: libdevel 12 | Architecture: linux-any 13 | Multi-Arch: same 14 | Depends: ${misc:Depends}, libbpf0 (= ${binary:Version}), libelf-dev, zlib1g-dev 15 | Description: eBPF helper library (development files) 16 | libbpf is a library for loading eBPF programs and reading and 17 | manipulating eBPF objects from user-space. 18 | . 19 | This package is needed to compile programs against libbpf. 20 | 21 | Package: libbpf0 22 | Architecture: linux-any 23 | Multi-Arch: same 24 | Depends: ${shlibs:Depends}, ${misc:Depends} 25 | Description: eBPF helper library (shared library) 26 | libbpf is a library for loading eBPF programs and reading and 27 | manipulating eBPF objects from user-space. 28 | . 29 | This package contains the shared library. 30 | -------------------------------------------------------------------------------- /packages/obs/stable/libbpf/libbpf-dev.install: -------------------------------------------------------------------------------- 1 | usr/include/* 2 | usr/lib/*/lib*.a 3 | usr/lib/*/lib*.so 4 | usr/lib/*/pkgconfig/* 5 | -------------------------------------------------------------------------------- /packages/obs/stable/libbpf/libbpf0.install: -------------------------------------------------------------------------------- 1 | usr/lib/*/lib*.so.* 2 | -------------------------------------------------------------------------------- /packages/obs/stable/libbpf/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | export DEB_BUILD_MAINT_OPTIONS = hardening=+all 4 | export DEB_CFLAGS_MAINT_APPEND = -Werror=implicit-function-declaration 5 | include /usr/share/dpkg/pkg-info.mk 6 | include /usr/share/dpkg/architecture.mk 7 | 8 | ifeq (,$(findstring terse,$(DEB_BUILD_OPTIONS))) 9 | VERBOSE=1 10 | endif 11 | 12 | %: 13 | dh $@ --sourcedirectory=src 14 | 15 | override_dh_gencontrol: 16 | dh_gencontrol -- -v1:$(DEB_VERSION) 17 | 18 | override_dh_makeshlibs: 19 | dh_makeshlibs -- -v1:$(DEB_VERSION) 20 | 21 | override_dh_auto_build: 22 | dh_auto_build -- LIBSUBDIR=lib/$(DEB_HOST_MULTIARCH) V=$(VERBOSE) 23 | 24 | override_dh_auto_install: 25 | dh_auto_install -- LIBSUBDIR=lib/$(DEB_HOST_MULTIARCH) V=$(VERBOSE) 26 | -------------------------------------------------------------------------------- /packages/obs/stable/libbpf/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /packages/obs/stable/libbpf/upstream/metadata: -------------------------------------------------------------------------------- 1 | --- 2 | Bug-Database: https://github.com/libbpf/libbpf/issues 3 | Bug-Submit: https://github.com/libbpf/libbpf/issues/new 4 | Repository: https://github.com/libbpf/libbpf.git 5 | Repository-Browse: https://github.com/libbpf/libbpf 6 | -------------------------------------------------------------------------------- /packages/obs/stable/libbpf/watch: -------------------------------------------------------------------------------- 1 | version=4 2 | 3 | opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%libbpf-$1.tar.gz%" \ 4 | https://github.com/libbpf/libbpf/tags \ 5 | (?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate 6 | -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-bmv2/changelog: -------------------------------------------------------------------------------- 1 | p4lang-bmv2 (1.14.0-6) bullseye; urgency=medium 2 | 3 | * Enable logger and logging macros 4 | 5 | -- Radostin Stoyanov Sun, 07 Nov 2021 19:59:20 +0000 6 | 7 | p4lang-bmv2 (1.14.0-5) bullseye; urgency=medium 8 | 9 | * Add python3 dependencies 10 | * Set standards version to 4.5.0 11 | * Enable compile-time performance optimizations 12 | 13 | -- Radostin Stoyanov Sat, 06 Nov 2021 21:41:05 +0000 14 | 15 | p4lang-bmv2 (1.14.0-4) bullseye; urgency=medium 16 | 17 | * Fix uninitialized build warning 18 | 19 | -- Radostin Stoyanov Thu, 04 Nov 2021 08:09:03 +0000 20 | 21 | p4lang-bmv2 (1.14.0-3) bullseye; urgency=medium 22 | 23 | * Update to commit 98d6075 24 | 25 | -- Radostin Stoyanov Thu, 04 Nov 2021 06:05:49 +0000 26 | 27 | p4lang-bmv2 (1.14.0-2) bullseye; urgency=medium 28 | 29 | * Update to commit fc54206 30 | * Drop libJudy dependency 31 | 32 | -- Radostin Stoyanov Fri, 22 Oct 2021 20:22:41 +0100 33 | 34 | p4lang-bmv2 (1.14.0-1) bullseye; urgency=medium 35 | 36 | * Self-made package 37 | 38 | -- Radostin Stoyanov Thu, 07 Oct 2021 00:19:20 +0100 39 | -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-bmv2/compat: -------------------------------------------------------------------------------- 1 | 11 -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-bmv2/control: -------------------------------------------------------------------------------- 1 | Source: p4lang-bmv2 2 | Section: net 3 | Priority: optional 4 | Maintainer: Radostin Stoyanov 5 | Build-Depends: 6 | automake, 7 | build-essential, 8 | cmake, 9 | curl, 10 | debhelper (>= 12), 11 | dh-python, 12 | git, 13 | g++, 14 | gfortran | gfortran-10, 15 | libboost-dev, 16 | libboost-filesystem-dev, 17 | libboost-program-options-dev, 18 | libboost-system-dev, 19 | libboost-thread-dev, 20 | libgmp-dev, 21 | libgrpc++-dev, 22 | libgrpc-dev, 23 | libopenmpi-dev, 24 | libnanomsg-dev, 25 | libpcap-dev, 26 | libprotobuf-dev, 27 | libprotoc-dev, 28 | libssl-dev, 29 | libthrift | libthrift-0.11.0 | libthrift-0.13.0, 30 | libthrift-dev, 31 | libtool, 32 | pkg-config, 33 | protobuf-compiler, 34 | protobuf-compiler-grpc, 35 | python3-all, 36 | python3-six, 37 | python-thrift | python3-thrift | python3-thriftpy, 38 | thrift-compiler, 39 | libreadline-dev, 40 | p4lang-pi 41 | Standards-Version: 4.5.0 42 | Rules-Requires-Root: no 43 | Homepage: https://github.com/p4lang/behavioral-model 44 | Vcs-Git: https://github.com/p4lang/behavioral-model 45 | Vcs-Browser: https://github.com/p4lang/behavioral-model 46 | 47 | Package: p4lang-bmv2 48 | Architecture: amd64 arm64 49 | Depends: 50 | ${shlibs:Depends}, 51 | ${misc:Depends}, 52 | ${python3:Depends}, 53 | libboost-dev, 54 | libboost-filesystem-dev, 55 | libboost-program-options-dev, 56 | libboost-system-dev, 57 | libboost-thread-dev, 58 | libgmp-dev, 59 | libgrpc++-dev, 60 | libgrpc-dev, 61 | libnanomsg-dev, 62 | libpcap-dev, 63 | libprotobuf-dev, 64 | libprotoc-dev, 65 | libssl-dev, 66 | libthrift | libthrift-0.11.0 | libthrift-0.13.0, 67 | libthrift-dev, 68 | libtool, 69 | pkg-config, 70 | protobuf-compiler, 71 | protobuf-compiler-grpc, 72 | python-thrift | python3-thrift | python3-thriftpy, 73 | thrift-compiler, 74 | p4lang-pi 75 | Description: P4 behavioral-model 76 | The reference P4 software switch. 77 | -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-bmv2/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Source: https://github.com/p4lang/behavioral-model 3 | Upstream-Name: behavioral-model 4 | 5 | Files: * 6 | Copyright: behavioral-model authors 7 | License: Apache-2.0 8 | Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | . 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | . 14 | Unless required by applicable law or agreed to in writing, software 15 | distributed under the License is distributed on an "AS IS" BASIS, 16 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | See the License for the specific language governing permissions and 18 | limitations under the License. 19 | . 20 | On Debian systems, the complete text of the Apache version 2.0 license 21 | can be found in "/usr/share/common-licenses/Apache-2.0". 22 | -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-bmv2/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # https://www.debian.org/doc/debian-policy/ch-source.html#s-debianrules 4 | # https://manpages.debian.org/stretch/debhelper/debhelper.7.en.html 5 | 6 | # Uncomment this to turn on verbose mode. 7 | #export DH_VERBOSE=1 8 | 9 | export DEB_BUILD_MAINT_OPTIONS = hardening=+all 10 | 11 | export DEB_CFLAGS_MAINT_APPEND=-g -O3 12 | export DEB_CXXFLAGS_MAINT_APPEND=-g -O3 13 | 14 | version := $(shell dpkg-parsechangelog -S Version | sed -rne 's,([^-\+]+)+(\+dfsg)*.*,\1,p'i) 15 | source := $(shell dpkg-parsechangelog -S Source) 16 | upstreampck := $(source)_$(version).orig.tar.gz 17 | 18 | %: 19 | dh $@ --with python3 20 | 21 | clean: 22 | @ echo CLEAN 23 | rm -f ../$(upstreampck) 24 | tar czf ../$(upstreampck) --exclude=debian --exclude=.pc . 25 | dh_testdir 26 | dh_auto_clean 27 | dh_clean 28 | 29 | override_dh_auto_configure: 30 | dh_auto_configure -- --with-pdfixed --with-thrift --with-nanomsg --with-pi 31 | 32 | override_dh_auto_install: 33 | make DESTDIR=$(CURDIR)/debian/p4lang-bmv2 install 34 | autoreconf -fi targets/simple_switch_grpc/ 35 | cd targets/simple_switch_grpc/ && ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --disable-silent-rules --disable-maintainer-mode --disable-dependency-tracking --with-thrift 36 | make -C targets/simple_switch_grpc/ -j$(nproc) 37 | make -C targets/simple_switch_grpc/ DESTDIR=$(CURDIR)/debian/p4lang-bmv2 install 38 | find $(CURDIR)/debian/p4lang-bmv2 -name __pycache__ -type d | xargs rm -rf 39 | -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-bmv2/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-p4c/changelog: -------------------------------------------------------------------------------- 1 | p4lang-p4c (1.2.2-6) bullseye; urgency=medium 2 | 3 | * Update to commit 6c23bf3e6 4 | * Add python3 dependencies 5 | * Set standards version to 4.5.0 6 | 7 | -- Radostin Stoyanov Sat, 06 Nov 2021 22:02:45 +0000 8 | 9 | p4lang-p4c (1.2.2-5) bullseye; urgency=medium 10 | 11 | * Add libbpf-dev dependency 12 | 13 | -- Radostin Stoyanov Thu, 04 Nov 2021 04:26:53 +0000 14 | 15 | p4lang-p4c (1.2.2-4) bullseye; urgency=medium 16 | 17 | * Update to commit 61d1bb737 18 | 19 | -- Radostin Stoyanov Tue, 02 Nov 2021 19:19:42 +0000 20 | 21 | p4lang-p4c (1.2.2-3) bullseye; urgency=medium 22 | 23 | * Update to commit 063bf646b 24 | * Add gfortran-10 dependency needed by libopenmpi-dev 25 | 26 | -- Radostin Stoyanov Mon, 01 Nov 2021 03:09:38 +0000 27 | 28 | p4lang-p4c (1.2.2-2) bullseye; urgency=medium 29 | 30 | * Update to commit 7169708 31 | 32 | -- Radostin Stoyanov Fri, 08 Oct 2021 19:52:28 +0100 33 | 34 | p4lang-p4c (1.2.2-1) bullseye; urgency=low 35 | 36 | * Self-made package 37 | 38 | -- Radostin Stoyanov Thu, 22 Jul 2021 00:45:06 +0100 39 | -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-p4c/compat: -------------------------------------------------------------------------------- 1 | 11 2 | -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-p4c/control: -------------------------------------------------------------------------------- 1 | Source: p4lang-p4c 2 | Section: devel 3 | Priority: optional 4 | Maintainer: Radostin Stoyanov 5 | Build-Depends: 6 | debhelper (>= 12), 7 | dh-python, 8 | bison, 9 | cmake, 10 | flex, 11 | gfortran | gfortran-10, 12 | libboost-dev, 13 | libboost-all-dev, 14 | libboost-graph-dev, 15 | libboost-iostreams-dev, 16 | libfl-dev, 17 | libgc-dev, 18 | libgmp-dev, 19 | libbpf-dev, 20 | pkg-config, 21 | tcpdump, 22 | libelf-dev, 23 | llvm, 24 | clang, 25 | iproute2, 26 | net-tools, 27 | python3-all, 28 | python3-grpcio, 29 | python3-ipaddr, 30 | python3-pyroute2, 31 | python3-ply, 32 | python3-protobuf, 33 | python3-scapy, 34 | python3-setuptools, 35 | python3-thrift, 36 | libprotobuf-dev, 37 | libprotoc-dev, 38 | protobuf-compiler, 39 | libgrpc-dev, 40 | libgrpc++-dev, 41 | protobuf-compiler-grpc, 42 | libthrift | libthrift-0.11.0 | libthrift-0.13.0, 43 | libthrift-dev, 44 | thrift-compiler, 45 | p4lang-bmv2 46 | Standards-Version: 4.5.0 47 | Rules-Requires-Root: no 48 | Homepage: https://github.com/p4lang/p4c 49 | Vcs-Git: https://github.com/p4lang/p4c 50 | Vcs-Browser: https://github.com/p4lang/p4c 51 | 52 | Package: p4lang-p4c 53 | Architecture: amd64 arm64 54 | Depends: 55 | ${shlibs:Depends}, 56 | ${misc:Depends}, 57 | ${python3:Depends}, 58 | cpp, 59 | libboost-dev, 60 | libboost-all-dev, 61 | libboost-graph-dev, 62 | libboost-iostreams-dev, 63 | libfl-dev, 64 | libgc-dev, 65 | libgmp-dev, 66 | libbpf-dev, 67 | pkg-config, 68 | tcpdump, 69 | libelf-dev, 70 | llvm, 71 | clang, 72 | iproute2, 73 | net-tools, 74 | python3-grpcio, 75 | python3-pyroute2, 76 | python3-ipaddr, 77 | python3-ply, 78 | python3-scapy, 79 | python3-setuptools, 80 | python3-thrift, 81 | python3-protobuf, 82 | libprotobuf-dev, 83 | libprotoc-dev, 84 | protobuf-compiler, 85 | libgrpc-dev, 86 | libgrpc++-dev, 87 | protobuf-compiler-grpc, 88 | libthrift | libthrift-0.11.0 | libthrift-0.13.0, 89 | libthrift-dev, 90 | thrift-compiler, 91 | p4lang-bmv2 92 | Description: P4 language compiler 93 | A reference compiler for the P4 programming language. 94 | -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-p4c/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Source: https://github.com/p4lang/p4c 3 | Upstream-Name: p4c 4 | 5 | Files: * 6 | Copyright: p4c authors 7 | License: Apache-2.0 8 | Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | . 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | . 14 | Unless required by applicable law or agreed to in writing, software 15 | distributed under the License is distributed on an "AS IS" BASIS, 16 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | See the License for the specific language governing permissions and 18 | limitations under the License. 19 | . 20 | On Debian systems, the complete text of the Apache version 2.0 license 21 | can be found in "/usr/share/common-licenses/Apache-2.0". 22 | -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-p4c/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # https://www.debian.org/doc/debian-policy/ch-source.html#s-debianrules 4 | # https://manpages.debian.org/stretch/debhelper/debhelper.7.en.html 5 | 6 | # Uncomment this to turn on verbose mode. 7 | #export DH_VERBOSE=1 8 | 9 | export DEB_BUILD_MAINT_OPTIONS = hardening=+all 10 | 11 | version := $(shell dpkg-parsechangelog -S Version | sed -rne 's,([^-\+]+)+(\+dfsg)*.*,\1,p'i) 12 | source := $(shell dpkg-parsechangelog -S Source) 13 | upstreampck := $(source)_$(version).orig.tar.gz 14 | 15 | %: 16 | dh $@ --with python3 17 | 18 | clean: 19 | @ echo CLEAN 20 | rm -f ../$(upstreampck) 21 | tar czf ../$(upstreampck) --exclude=debian --exclude=.pc . 22 | dh_testdir 23 | dh_auto_clean 24 | dh_clean 25 | 26 | override_dh_auto_configure: 27 | dh_auto_configure --builddirectory=build/ -- \ 28 | -DCMAKE_BUILD_TYPE=RELEASE \ 29 | -DCMAKE_INSTALL_PREFIX=/usr \ 30 | -DENABLE_BMV2=ON \ 31 | -DENABLE_EBPF=ON \ 32 | -DENABLE_UBPF=ON \ 33 | -DENABLE_DPDK=ON \ 34 | -DENABLE_P4C_GRAPHS=ON \ 35 | -DENABLE_P4TEST=ON \ 36 | -DENABLE_DOCS=OFF \ 37 | -DENABLE_GC=ON \ 38 | -DENABLE_GTESTS=OFF \ 39 | -DENABLE_PROTOBUF_STATIC=ON \ 40 | -DENABLE_MULTITHREAD=OFF \ 41 | -DENABLE_GMP=ON 42 | 43 | 44 | override_dh_auto_install: 45 | dh_auto_install --builddirectory=build/ -- DESTDIR=$(CURDIR)/debian/p4lang-p4c install 46 | -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-p4c/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-pi/changelog: -------------------------------------------------------------------------------- 1 | p4lang-pi (0.1.0-8) bullseye; urgency=medium 2 | 3 | * Add python3 dependencies 4 | * Set standards version to 4.5.0 5 | 6 | -- Radostin Stoyanov Sat, 06 Nov 2021 21:12:21 +0000 7 | 8 | p4lang-pi (0.1.0-7) bullseye; urgency=medium 9 | 10 | * Update package format 11 | 12 | -- Radostin Stoyanov Thu, 04 Nov 2021 04:44:11 +0000 13 | 14 | p4lang-pi (0.1.0-6) bullseye; urgency=medium 15 | 16 | * Update to commit 66da143 17 | * Remove libJudy dependency 18 | 19 | -- Radostin Stoyanov Sat, 09 Oct 2021 10:44:16 +0100 20 | 21 | p4lang-pi (0.1.0-5) bullseye; urgency=medium 22 | 23 | * Update to commit a5fd855 24 | 25 | -- Radostin Stoyanov Sun, 03 Oct 2021 00:35:59 +0100 26 | 27 | p4lang-pi (0.1.0-4) bullseye; urgency=low 28 | 29 | * Self-made package 30 | 31 | -- Radostin Stoyanov Sun, 20 Jun 2021 22:54:44 +0100 32 | -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-pi/compat: -------------------------------------------------------------------------------- 1 | 12 2 | -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-pi/control: -------------------------------------------------------------------------------- 1 | Source: p4lang-pi 2 | Section: net 3 | Priority: optional 4 | Maintainer: Radostin Stoyanov 5 | Build-Depends: 6 | autoconf, 7 | automake, 8 | debhelper (>= 12), 9 | gnupg, 10 | dh-python, 11 | libboost-dev, 12 | libboost-system-dev, 13 | libboost-thread-dev, 14 | libgrpc++-dev, 15 | libgrpc-dev, 16 | libnanomsg-dev, 17 | libprotobuf-dev, 18 | libprotoc-dev, 19 | libreadline-dev, 20 | libtool, 21 | libtool-bin, 22 | pkg-config, 23 | protobuf-compiler, 24 | protobuf-compiler-grpc, 25 | python3-all, 26 | valgrind 27 | Standards-Version: 4.5.0 28 | Rules-Requires-Root: no 29 | Homepage: https://github.com/p4lang/PI 30 | Vcs-Git: https://github.com/p4lang/PI 31 | Vcs-Browser: https://github.com/p4lang/PI 32 | 33 | Package: p4lang-pi 34 | Architecture: amd64 arm64 35 | Depends: 36 | ${shlibs:Depends}, 37 | ${misc:Depends}, 38 | ${python3:Depends}, 39 | libboost-dev, 40 | libboost-system-dev, 41 | libboost-thread-dev, 42 | libprotobuf-dev, 43 | libprotoc-dev, 44 | protobuf-compiler, 45 | python3-protobuf, 46 | libgrpc++-dev, 47 | libgrpc-dev, 48 | protobuf-compiler-grpc, 49 | python3-grpcio 50 | Description: Implementation framework of a P4Runtime server 51 | Protocol Independent API (PI or P4 Runtime) defines a set of APIs that allow 52 | interacting with entities defined in a P4 program. 53 | These include: tables, counters, meters. 54 | . 55 | PI APIs are defined at the level of properties that can be effected. 56 | Examples include adding and deleting table entries. They are 57 | independent from the actual 58 | instance of the controlled object (and thus the name) which is passed 59 | as a parameter to the API. 60 | . 61 | This is the p4lang pi software 62 | -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-pi/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Source: https://github.com/p4lang/PI 3 | Upstream-Name: PI 4 | 5 | Files: * 6 | Copyright: PI authors 7 | License: Apache-2.0 8 | Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | . 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | . 14 | Unless required by applicable law or agreed to in writing, software 15 | distributed under the License is distributed on an "AS IS" BASIS, 16 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | See the License for the specific language governing permissions and 18 | limitations under the License. 19 | . 20 | On Debian systems, the complete text of the Apache version 2.0 license 21 | can be found in "/usr/share/common-licenses/Apache-2.0". 22 | -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-pi/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # https://www.debian.org/doc/debian-policy/ch-source.html#s-debianrules 4 | # https://manpages.debian.org/stretch/debhelper/debhelper.7.en.html 5 | 6 | # Uncomment this to turn on verbose mode. 7 | #export DH_VERBOSE=1 8 | 9 | export DEB_BUILD_MAINT_OPTIONS = hardening=+all 10 | 11 | version := $(shell dpkg-parsechangelog -S Version | sed -rne 's,([^-\+]+)+(\+dfsg)*.*,\1,p'i) 12 | source := $(shell dpkg-parsechangelog -S Source) 13 | upstreampck := $(source)_$(version).orig.tar.gz 14 | 15 | %: 16 | dh $@ --with python3 17 | 18 | clean: 19 | @ echo CLEAN 20 | rm -f ../$(upstreampck) 21 | tar czf ../$(upstreampck) --exclude=debian --exclude=.pc . 22 | dh_testdir 23 | dh_auto_clean 24 | dh_clean 25 | 26 | override_dh_auto_configure: 27 | dh_auto_configure -- --with-proto --with-cli 28 | 29 | override_dh_auto_build: 30 | $(MAKE) all 31 | 32 | override_dh_auto_install: 33 | dh_auto_install -- DESTDIR=$(CURDIR)/debian/p4lang-pi install 34 | find $(CURDIR)/debian/p4lang-pi -name "*.pyc" | xargs rm -f 35 | find $(CURDIR)/debian/p4lang-pi -name "*.pyo" | xargs rm -f 36 | -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-pi/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /packages/obs/stable/p4lang-pi/watch: -------------------------------------------------------------------------------- 1 | version=4 2 | opts="mode=git, pgpmode=none" https://github.com/p4lang/PI/ HEAD 3 | -------------------------------------------------------------------------------- /packages/obs/stable/p4pi-examples/_service: -------------------------------------------------------------------------------- 1 | 2 | 3 | git 4 | https://github.com/IcePhoenX/p4pi 5 | p4pi-examples 6 | p4pi_examples_v* 7 | @PARENT_TAG@ 8 | @PARENT_TAG@ 9 | p4pi_examples_v(.*) 10 | packages/p4pi-examples 11 | packaging/p4pi-examples.spec 12 | 13 | 14 | 15 | gz 16 | *.tar 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /packages/obs/stable/p4pi-kernel/0001-Add-package-prefix.patch: -------------------------------------------------------------------------------- 1 | From 446a73d993a4436ed5b629f9183ab96c53032ab7 Mon Sep 17 00:00:00 2001 2 | From: Radostin Stoyanov 3 | Date: Sat, 31 Jul 2021 21:01:45 +0000 4 | Subject: [PATCH] Add package prefix 5 | 6 | Signed-off-by: Radostin Stoyanov 7 | --- 8 | scripts/package/builddeb | 14 +++++++------- 9 | scripts/package/mkdebian | 10 +++++----- 10 | 2 files changed, 12 insertions(+), 12 deletions(-) 11 | 12 | diff --git a/scripts/package/builddeb b/scripts/package/builddeb 13 | index 91a502bb97e8..227fbf99f920 100755 14 | --- a/scripts/package/builddeb 15 | +++ b/scripts/package/builddeb 16 | @@ -107,9 +107,9 @@ deploy_libc_headers () { 17 | } 18 | 19 | version=$KERNELRELEASE 20 | -tmpdir=debian/linux-image 21 | -dbg_dir=debian/linux-image-dbg 22 | -packagename=linux-image-$version 23 | +tmpdir=debian/p4pi-linux-image 24 | +dbg_dir=debian/p4pi-linux-image-dbg 25 | +packagename=p4pi-linux-image-$version 26 | dbg_packagename=$packagename-dbg 27 | 28 | if [ "$ARCH" = "um" ] ; then 29 | @@ -210,12 +210,12 @@ done 30 | 31 | if [ "$ARCH" != "um" ]; then 32 | if is_enabled CONFIG_MODULES; then 33 | - deploy_kernel_headers debian/linux-headers 34 | - create_package linux-headers-$version debian/linux-headers 35 | + deploy_kernel_headers debian/p4pi-linux-headers 36 | + create_package p4pi-linux-headers-$version debian/p4pi-linux-headers 37 | fi 38 | 39 | - deploy_libc_headers debian/linux-libc-dev 40 | - create_package linux-libc-dev debian/linux-libc-dev 41 | + deploy_libc_headers debian/p4pi-linux-libc-dev 42 | + create_package p4pi-linux-libc-dev debian/p4pi-linux-libc-dev 43 | fi 44 | 45 | create_package "$packagename" "$tmpdir" 46 | diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian 47 | index 60a2a63a5e90..5920aaa6dfd8 100755 48 | --- a/scripts/package/mkdebian 49 | +++ b/scripts/package/mkdebian 50 | @@ -98,7 +98,7 @@ sourcename=$KDEB_SOURCENAME 51 | if [ "$ARCH" = "um" ] ; then 52 | packagename=user-mode-linux 53 | else 54 | - packagename=linux-image 55 | + packagename=p4pi-linux-image 56 | fi 57 | 58 | debarch= 59 | @@ -184,9 +184,9 @@ Description: Linux kernel, version $version 60 | This package contains the Linux kernel, modules and corresponding other 61 | files, version: $version. 62 | 63 | -Package: linux-libc-dev 64 | +Package: p4pi-linux-libc-dev 65 | Section: devel 66 | -Provides: linux-kernel-headers 67 | +Provides: p4pi-linux-kernel-headers 68 | Architecture: $debarch 69 | Description: Linux support headers for userspace development 70 | This package provides userspaces headers from the Linux kernel. These headers 71 | @@ -197,7 +197,7 @@ EOF 72 | if is_enabled CONFIG_MODULES; then 73 | cat <> debian/control 74 | 75 | -Package: linux-headers-$version 76 | +Package: p4pi-linux-headers-$version 77 | Architecture: $debarch 78 | Description: Linux kernel headers for $version on $debarch 79 | This package provides kernel header files for $version on $debarch 80 | @@ -209,7 +209,7 @@ fi 81 | if is_enabled CONFIG_DEBUG_INFO; then 82 | cat <> debian/control 83 | 84 | -Package: linux-image-$version-dbg 85 | +Package: p4pi-linux-image-$version-dbg 86 | Section: debug 87 | Architecture: $debarch 88 | Description: Linux kernel debugging symbols for $version 89 | -- 90 | 2.31.1 91 | 92 | -------------------------------------------------------------------------------- /packages/obs/stable/p4pi-kernel/config_p4pi.patch: -------------------------------------------------------------------------------- 1 | diff --git a/scripts/Makefile.package b/scripts/Makefile.package 2 | index b74c65284..e6aaa9fe5 100644 3 | --- a/scripts/Makefile.package 4 | +++ b/scripts/Makefile.package 5 | @@ -75,7 +75,7 @@ deb-pkg: 6 | $(call cmd,src_tar,$(KDEB_SOURCENAME)) 7 | origversion=$$(dpkg-parsechangelog -SVersion |sed 's/-[^-]*$$//');\ 8 | mv $(KDEB_SOURCENAME).tar.gz ../$(KDEB_SOURCENAME)_$${origversion}.orig.tar.gz 9 | - +dpkg-buildpackage -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch) $(DPKG_FLAGS) -i.git -us -uc 10 | + +dpkg-buildpackage -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch) $(DPKG_FLAGS) -i.git -us -uc -S 11 | 12 | PHONY += bindeb-pkg 13 | bindeb-pkg: 14 | diff --git a/scripts/package/builddeb b/scripts/package/builddeb 15 | index 91a502bb9..227fbf99f 100755 16 | --- a/scripts/package/builddeb 17 | +++ b/scripts/package/builddeb 18 | @@ -107,9 +107,9 @@ deploy_libc_headers () { 19 | } 20 | 21 | version=$KERNELRELEASE 22 | -tmpdir=debian/linux-image 23 | -dbg_dir=debian/linux-image-dbg 24 | -packagename=linux-image-$version 25 | +tmpdir=debian/p4pi-linux-image 26 | +dbg_dir=debian/p4pi-linux-image-dbg 27 | +packagename=p4pi-linux-image-$version 28 | dbg_packagename=$packagename-dbg 29 | 30 | if [ "$ARCH" = "um" ] ; then 31 | @@ -210,12 +210,12 @@ done 32 | 33 | if [ "$ARCH" != "um" ]; then 34 | if is_enabled CONFIG_MODULES; then 35 | - deploy_kernel_headers debian/linux-headers 36 | - create_package linux-headers-$version debian/linux-headers 37 | + deploy_kernel_headers debian/p4pi-linux-headers 38 | + create_package p4pi-linux-headers-$version debian/p4pi-linux-headers 39 | fi 40 | 41 | - deploy_libc_headers debian/linux-libc-dev 42 | - create_package linux-libc-dev debian/linux-libc-dev 43 | + deploy_libc_headers debian/p4pi-linux-libc-dev 44 | + create_package p4pi-linux-libc-dev debian/p4pi-linux-libc-dev 45 | fi 46 | 47 | create_package "$packagename" "$tmpdir" 48 | diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian 49 | index 60a2a63a5..5920aaa6d 100755 50 | --- a/scripts/package/mkdebian 51 | +++ b/scripts/package/mkdebian 52 | @@ -98,7 +98,7 @@ sourcename=$KDEB_SOURCENAME 53 | if [ "$ARCH" = "um" ] ; then 54 | packagename=user-mode-linux 55 | else 56 | - packagename=linux-image 57 | + packagename=p4pi-linux-image 58 | fi 59 | 60 | debarch= 61 | @@ -184,9 +184,9 @@ Description: Linux kernel, version $version 62 | This package contains the Linux kernel, modules and corresponding other 63 | files, version: $version. 64 | 65 | -Package: linux-libc-dev 66 | +Package: p4pi-linux-libc-dev 67 | Section: devel 68 | -Provides: linux-kernel-headers 69 | +Provides: p4pi-linux-kernel-headers 70 | Architecture: $debarch 71 | Description: Linux support headers for userspace development 72 | This package provides userspaces headers from the Linux kernel. These headers 73 | @@ -197,7 +197,7 @@ EOF 74 | if is_enabled CONFIG_MODULES; then 75 | cat <> debian/control 76 | 77 | -Package: linux-headers-$version 78 | +Package: p4pi-linux-headers-$version 79 | Architecture: $debarch 80 | Description: Linux kernel headers for $version on $debarch 81 | This package provides kernel header files for $version on $debarch 82 | @@ -209,7 +209,7 @@ fi 83 | if is_enabled CONFIG_DEBUG_INFO; then 84 | cat <> debian/control 85 | 86 | -Package: linux-image-$version-dbg 87 | +Package: p4pi-linux-image-$version-dbg 88 | Section: debug 89 | Architecture: $debarch 90 | Description: Linux kernel debugging symbols for $version 91 | -------------------------------------------------------------------------------- /packages/obs/stable/p4pi-kernel/pack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | TAG=1.20230106 4 | 5 | sudo apt-get install \ 6 | git bc bison flex libssl-dev make 7 | 8 | git clone -b "${TAG}" --depth=1 https://github.com/raspberrypi/linux 9 | git apply --directory=linux config_p4pi.patch 10 | 11 | cd linux 12 | KERNEL=kernel8 make bcm2711_defconfig 13 | 14 | sed -i 's/# CONFIG_HUGETLBFS.*/CONFIG_HUGETLBFS=y/' .config 15 | sed -i 's/# CONFIG_CHECKPOINT_RESTORE.*/CONFIG_CHECKPOINT_RESTORE=y/' .config 16 | sed -i 's/# CONFIG_NAMESPACES.*/CONFIG_NAMESPACES=y/' .config 17 | sed -i 's/# CONFIG_UTS_NS.*/CONFIG_UTS_NS=y/' .config 18 | sed -i 's/# CONFIG_IPC_NS.*/CONFIG_IPC_NS=y/' .config 19 | sed -i 's/# CONFIG_SYSVIPC_SYSCTL.*/CONFIG_SYSVIPC_SYSCTL=y/' .config 20 | sed -i 's/# CONFIG_PID_NS.*/CONFIG_PID_NS=y/' .config 21 | sed -i 's/# CONFIG_NET_NS.*/CONFIG_NET_NS=y/' .config 22 | sed -i 's/# CONFIG_FHANDLE.*/CONFIG_FHANDLE=y/' .config 23 | sed -i 's/# CONFIG_EVENTFD.*/CONFIG_EVENTFD=y/' .config 24 | sed -i 's/# CONFIG_EPOLL.*/CONFIG_EPOLL=y/' .config 25 | sed -i 's/# CONFIG_UNIX_DIAG.*/CONFIG_UNIX_DIAG=y/' .config 26 | sed -i 's/# CONFIG_INET_DIAG.*/CONFIG_INET_DIAG=y/' .config 27 | sed -i 's/# CONFIG_INET_UDP_DIAG.*/CONFIG_INET_UDP_DIAG=y/' .config 28 | sed -i 's/# CONFIG_PACKET_DIAG.*/CONFIG_PACKET_DIAG=y/' .config 29 | sed -i 's/# CONFIG_NETLINK_DIAG.*/CONFIG_NETLINK_DIAG=y/' .config 30 | sed -i 's/# CONFIG_NETFILTER_XT_MARK.*/CONFIG_NETFILTER_XT_MARK=y/' .config 31 | sed -i 's/# CONFIG_TUN.*/CONFIG_TUN=y/' .config 32 | sed -i 's/# CONFIG_INOTIFY_USER.*/CONFIG_INOTIFY_USER=y/' .config 33 | sed -i 's/# CONFIG_FANOTIFY.*/CONFIG_FANOTIFY=y/' .config 34 | sed -i 's/# CONFIG_MEMCG.*/CONFIG_MEMCG=y/' .config 35 | sed -i 's/# CONFIG_CGROUP_DEVICE.*/CONFIG_CGROUP_DEVICE=y/' .config 36 | sed -i 's/# CONFIG_MACVLAN.*/CONFIG_MACVLAN=y/' .config 37 | sed -i 's/# CONFIG_BRIDGE.*/CONFIG_BRIDGE=y/' .config 38 | sed -i 's/# CONFIG_BINFMT_MISC.*/CONFIG_BINFMT_MISC=y/' .config 39 | sed -i 's/# CONFIG_IA32_EMULATION.*/CONFIG_IA32_EMULATION=y/' .config 40 | sed -i 's/# CONFIG_USERFAULTFD.*/CONFIG_USERFAULTFD=y/' .config 41 | sed -i 's/# CONFIG_MEM_SOFT_DIRTY.*/CONFIG_MEM_SOFT_DIRTY=y/' .config 42 | sed -i 's/# CONFIG_NET_CLS_BPF.*/CONFIG_NET_CLS_BPF=m/' .config 43 | 44 | yes | make -j`nproc` \ 45 | KERNEL=kernel8 \ 46 | KBUILD_BUILD_USER="" \ 47 | KBUILD_DEBARCH=arm64 \ 48 | DEBEMAIL="" \ 49 | KDEB_CHANGELOG_DIST=bullseye \ 50 | KDEB_SOURCENAME=p4pi-kernel \ 51 | ARCH=arm64 \ 52 | LOCALVERSION=-p4pi \ 53 | deb-pkg 54 | -------------------------------------------------------------------------------- /packages/obs/stable/p4pi-web/_service: -------------------------------------------------------------------------------- 1 | 2 | 3 | git 4 | https://github.com/IcePhoenX/p4pi 5 | p4pi-web 6 | p4pi_web_v* 7 | @PARENT_TAG@ 8 | @PARENT_TAG@ 9 | p4pi_web_v(.*) 10 | packages/p4pi-web 11 | packaging/p4pi-web.spec 12 | 13 | 14 | 15 | gz 16 | *.tar 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /packages/obs/unstable/p4pi-examples/_service: -------------------------------------------------------------------------------- 1 | 2 | 3 | git 4 | https://github.com/IcePhoenX/p4pi 5 | p4pi-examples 6 | p4pi_examples_v* 7 | main 8 | @PARENT_TAG@.@TAG_OFFSET@+%cd~%h 9 | p4pi_examples_v(.*) 10 | packages/p4pi-examples 11 | packaging/p4pi-examples.spec 12 | 13 | 14 | 15 | gz 16 | *.tar 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /packages/obs/unstable/p4pi-web/_service: -------------------------------------------------------------------------------- 1 | 2 | 3 | git 4 | https://github.com/IcePhoenX/p4pi 5 | p4pi-web 6 | p4pi_web_v* 7 | main 8 | @PARENT_TAG@.@TAG_OFFSET@+%cd~%h 9 | p4pi_web_v(.*) 10 | packages/p4pi-web 11 | packaging/p4pi-web.spec 12 | 13 | 14 | 15 | gz 16 | *.tar 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /packages/p4pi-examples/apu-examples.cfg: -------------------------------------------------------------------------------- 1 | reflector arch=dpdk hugepages=1024 model=v1model smem vethmode apueal apuports 2 | l2switch arch=dpdk hugepages=1024 model=v1model smem vethmode apueal apuports 3 | traffic_filter arch=dpdk hugepages=1024 model=v1model smem vethmode apueal apuports 4 | stateful_firewall arch=dpdk hugepages=1024 model=v1model smem vethmode apueal apuports x_hash 5 | basic_mirror arch=dpdk hugepages=1024 model=v1model smem vethmode apueal apuports 6 | arp_icmp arch=dpdk hugepages=1024 model=v1model smem vethmode apueal apuports 7 | calc arch=dpdk hugepages=1024 model=v1model smem vethmode apueal apuports 8 | -------------------------------------------------------------------------------- /packages/p4pi-examples/bmv2/calc/receive.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import sys 5 | import platform 6 | 7 | from scapy.all import sniff, Packet, Ether, StrFixedLenField, XByteField, IntField, bind_layers 8 | 9 | 10 | class P4calc(Packet): 11 | name = "P4calc" 12 | fields_desc = [ 13 | StrFixedLenField("P", "P", length=1), 14 | StrFixedLenField("Four", "4", length=1), 15 | XByteField("version", 0x01), 16 | StrFixedLenField("op", "+", length=1), 17 | IntField("operand_a", 0), 18 | IntField("operand_b", 0), 19 | IntField("result", 0xDEADBABE) 20 | ] 21 | 22 | 23 | def get_wireless_interface(): 24 | """ 25 | Get defult wireless interface 26 | """ 27 | for device_name in os.listdir('/sys/class/net'): 28 | if os.path.exists(f'/sys/class/net/{device_name}/wireless'): 29 | return device_name 30 | print("Can't find WiFi interface") 31 | sys.exit(1) 32 | 33 | 34 | def packet_filter(packet): 35 | return packet[Ether].type == 0x1234 36 | 37 | 38 | def PacketHandler(packet): 39 | if packet_filter(packet): 40 | packet.show() 41 | 42 | 43 | def main(): 44 | bind_layers(Ether, P4calc, type=0x1234) 45 | if platform.system() == 'Linux': 46 | iface_name = get_wireless_interface() 47 | else: 48 | iface_name = input("Please enter wireless interface name: ") 49 | print(f"Monitoring P4calc packets on interface: {iface_name}") 50 | sniff(iface=iface_name, prn=PacketHandler) 51 | 52 | 53 | if __name__ == '__main__': 54 | main() 55 | -------------------------------------------------------------------------------- /packages/p4pi-examples/bmv2/calc/send.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import sys 5 | import platform 6 | import re 7 | 8 | from scapy.all import sendp, Packet, Ether, StrFixedLenField, XByteField, IntField, bind_layers 9 | 10 | DST_ADDR = "10:04:00:00:10:10" 11 | 12 | 13 | class P4calc(Packet): 14 | name = "P4calc" 15 | fields_desc = [ 16 | StrFixedLenField("P", "P", length=1), 17 | StrFixedLenField("Four", "4", length=1), 18 | XByteField("version", 0x01), 19 | StrFixedLenField("op", "+", length=1), 20 | IntField("operand_a", 0), 21 | IntField("operand_b", 0), 22 | IntField("result", 0xDEADBABE) 23 | ] 24 | 25 | 26 | class NumParseError(Exception): 27 | pass 28 | 29 | 30 | class Token: 31 | def __init__(self, token_type, value=None): 32 | self.type = token_type 33 | self.value = value 34 | 35 | 36 | def get_wireless_interface(): 37 | """ 38 | Get defult wireless interface 39 | """ 40 | for device_name in os.listdir('/sys/class/net'): 41 | if os.path.exists(f'/sys/class/net/{device_name}/wireless'): 42 | return device_name 43 | print("Can't find WiFi interface") 44 | sys.exit(1) 45 | 46 | 47 | def input_parser_numeric(s, i, ts): 48 | pattern = "^\\s*([0-9]+)\\s*" 49 | match = re.match(pattern, s[i:]) 50 | if match: 51 | ts.append(Token('num', match.group(1))) 52 | return i + match.end(), ts 53 | raise NumParseError('Expected number literal.') 54 | 55 | 56 | def input_parser_operator(s, i, ts): 57 | pattern = "^\\s*([-+&|^])\\s*" 58 | match = re.match(pattern, s[i:]) 59 | if match: 60 | ts.append(Token('num', match.group(1))) 61 | return i + match.end(), ts 62 | raise NumParseError("Expected binary operator '-', '+', '&', '|', or '^'.") 63 | 64 | 65 | def make_seq(p1, p2): 66 | def parse(s, i, ts): 67 | i, ts2 = p1(s, i, ts) 68 | return p2(s, i, ts2) 69 | return parse 70 | 71 | 72 | def main(): 73 | bind_layers(Ether, P4calc, type=0x1234) 74 | 75 | user_input_parser = make_seq( 76 | input_parser_numeric, 77 | make_seq(input_parser_operator, input_parser_numeric) 78 | ) 79 | 80 | if platform.system() == 'Linux': 81 | iface_name = get_wireless_interface() 82 | else: 83 | iface_name = input("Please enter wireless interface name: ") 84 | print(f"Using interface: {iface_name}") 85 | 86 | while True: 87 | user_command = input('Expression [1 + 2]: ') 88 | if user_command == '': 89 | user_command = '1 + 2' 90 | if user_command in ["quit", "q"]: 91 | break 92 | try: 93 | _, user_input = user_input_parser(user_command, 0, []) 94 | 95 | operator = user_input[1].value 96 | operand_a = int(user_input[0].value) 97 | operand_b = int(user_input[2].value) 98 | 99 | packet = Ether(dst=DST_ADDR, type=0x1234) 100 | packet /= P4calc(op=operator, operand_a=operand_a, 101 | operand_b=operand_b) 102 | 103 | print("Sending packet with payload: ") 104 | print(f"\t{operand_a} {operator} {operand_b}") 105 | sendp(packet, iface=iface_name) 106 | except Exception as error: 107 | print(error) 108 | 109 | 110 | if __name__ == '__main__': 111 | main() 112 | -------------------------------------------------------------------------------- /packages/p4pi-examples/bmv2/l2switch/l2switch.p4: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | header ethernet_t { 5 | bit<48> dstAddr; 6 | bit<48> srcAddr; 7 | bit<16> etherType; 8 | } 9 | 10 | struct metadata { 11 | } 12 | 13 | struct headers { 14 | ethernet_t ethernet; 15 | } 16 | 17 | parser ParserImpl(packet_in packet, out headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { 18 | 19 | state start { 20 | transition parse_ethernet; 21 | } 22 | 23 | state parse_ethernet { 24 | packet.extract(hdr.ethernet); 25 | transition accept; 26 | } 27 | 28 | } 29 | 30 | control egress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { 31 | apply { 32 | } 33 | } 34 | 35 | struct mac_learn_digest { 36 | bit<48> srcAddr; 37 | bit<9> ingress_port; 38 | } 39 | 40 | control ingress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { 41 | action forward(bit<9> port) { 42 | standard_metadata.egress_spec = port; 43 | } 44 | 45 | action bcast() { 46 | standard_metadata.mcast_grp = 1; 47 | } 48 | 49 | action mac_learn() { 50 | digest((bit<32>)1024, { hdr.ethernet.srcAddr, standard_metadata.ingress_port }); 51 | } 52 | 53 | action drop() { 54 | mark_to_drop( standard_metadata ); 55 | exit; 56 | } 57 | 58 | action _nop() { 59 | } 60 | 61 | table dmac { 62 | actions = { 63 | forward; 64 | bcast; 65 | drop; 66 | } 67 | key = { 68 | hdr.ethernet.dstAddr: exact; 69 | } 70 | default_action = bcast(); 71 | size = 512; 72 | } 73 | 74 | table smac { 75 | actions = { 76 | mac_learn; 77 | _nop; 78 | drop; 79 | } 80 | key = { 81 | hdr.ethernet.srcAddr: exact; 82 | } 83 | default_action = mac_learn(); 84 | size = 512; 85 | } 86 | 87 | apply { 88 | smac.apply(); 89 | dmac.apply(); 90 | } 91 | 92 | } 93 | 94 | control DeparserImpl(packet_out packet, in headers hdr) { 95 | apply { 96 | packet.emit(hdr.ethernet); 97 | } 98 | } 99 | 100 | control verifyChecksum(inout headers hdr, inout metadata meta) { 101 | apply { 102 | } 103 | } 104 | 105 | control computeChecksum(inout headers hdr, inout metadata meta) { 106 | apply { 107 | } 108 | } 109 | 110 | V1Switch(ParserImpl(), verifyChecksum(), ingress(), egress(), computeChecksum(), DeparserImpl()) main; 111 | 112 | -------------------------------------------------------------------------------- /packages/p4pi-examples/dpdk/basic_mirror/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # Copyright(c) 2010-2014 Intel Corporation 3 | 4 | # binary name 5 | APP = basic_mirror 6 | 7 | # all source are stored in SRCS-y 8 | SRCS-y := main.c 9 | 10 | # Build using pkg-config variables if possible 11 | ifeq ($(shell pkg-config --exists libdpdk && echo 0),0) 12 | 13 | all: shared 14 | .PHONY: shared static 15 | shared: build/$(APP)-shared 16 | ln -sf $(APP)-shared build/$(APP) 17 | static: build/$(APP)-static 18 | ln -sf $(APP)-static build/$(APP) 19 | 20 | PKGCONF ?= pkg-config 21 | 22 | PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) 23 | CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) 24 | # Add flag to allow experimental API as l2fwd uses rte_ethdev_set_ptype API 25 | CFLAGS += -DALLOW_EXPERIMENTAL_API 26 | LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) 27 | LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) 28 | 29 | build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build 30 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) 31 | 32 | build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build 33 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC) 34 | 35 | build: 36 | @mkdir -p $@ 37 | 38 | .PHONY: clean 39 | clean: 40 | rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared 41 | test -d build && rmdir -p build || true 42 | 43 | else # Build using legacy build system 44 | 45 | ifeq ($(RTE_SDK),) 46 | $(error "Please define RTE_SDK environment variable") 47 | endif 48 | 49 | # Default target, detect a build directory, by looking for a path with a .config 50 | RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config))))) 51 | 52 | include $(RTE_SDK)/mk/rte.vars.mk 53 | 54 | CFLAGS += -O3 55 | CFLAGS += $(WERROR_FLAGS) 56 | # Add flag to allow experimental API as l2fwd uses rte_ethdev_set_ptype API 57 | CFLAGS += -DALLOW_EXPERIMENTAL_API 58 | 59 | include $(RTE_SDK)/mk/rte.extapp.mk 60 | endif 61 | -------------------------------------------------------------------------------- /packages/p4pi-examples/dpdk/basic_mirror/meson.build: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # Copyright(c) 2017 Intel Corporation 3 | 4 | # meson file, for building this example as part of a main DPDK build. 5 | # 6 | # To build this example as a standalone application with an already-installed 7 | # DPDK instance, use 'make' 8 | 9 | # Enable experimental API flag as l2fwd uses rte_ethdev_set_ptype API 10 | allow_experimental_apis = true 11 | sources = files( 12 | 'main.c' 13 | ) 14 | -------------------------------------------------------------------------------- /packages/p4pi-examples/packaging/p4pi-examples.spec: -------------------------------------------------------------------------------- 1 | %{!?examplesroot: %global examplesroot /usr/share/p4pi/t4p4s} 2 | %{!?t4p4sroot: %global t4p4sroot /root/t4p4s} 3 | %{!?bmv2root: %global bmv2root /root/bmv2} 4 | Name: p4pi-examples 5 | Version: 0.0.0 6 | Release: 0%{?dist} 7 | Summary: P4Pi examples 8 | License: Apache 2.0 9 | URL: https://github.com/p4lang/p4pi 10 | Source0: %{name}-%{version}.tar.gz 11 | Requires: p4edge-t4p4s 12 | Packager: Dávid Kis 13 | 14 | %description 15 | P4Pi examples 16 | 17 | %prep 18 | %autosetup 19 | 20 | %build 21 | 22 | %install 23 | 24 | rm -rf %{buildroot} 25 | 26 | mkdir -p %{buildroot}%{examplesroot} 27 | cp -r t4p4s/arp_icmp/ %{buildroot}%{examplesroot} 28 | cp -r t4p4s/calc/ %{buildroot}%{examplesroot} 29 | cp -r t4p4s/l2switch/ %{buildroot}%{examplesroot} 30 | cp -r t4p4s/stateful_firewall/ %{buildroot}%{examplesroot} 31 | cp -r t4p4s/traffic_filter/ %{buildroot}%{examplesroot} 32 | cp -r t4p4s/basic_mirror/ %{buildroot}%{examplesroot} 33 | cp -r t4p4s/reflector/ %{buildroot}%{examplesroot} 34 | %ifarch arm64 35 | cp pi-examples.cfg %{buildroot}%{examplesroot} 36 | %else 37 | cp apu-examples.cfg %{buildroot}%{examplesroot} 38 | %endif 39 | 40 | mkdir -p %{buildroot}%{bmv2root}/bin 41 | mkdir -p %{buildroot}%{bmv2root}/examples/uploaded_switch 42 | 43 | cp -r bmv2/arp_icmp/ %{buildroot}%{bmv2root}/examples 44 | cp -r bmv2/calc/ %{buildroot}%{bmv2root}/examples 45 | cp -r bmv2/l2switch/ %{buildroot}%{bmv2root}/examples 46 | cp -r bmv2/stateful_firewall/ %{buildroot}%{bmv2root}/examples 47 | cp -r bmv2/traffic_filter/ %{buildroot}%{bmv2root}/examples 48 | cp -r bmv2/basic_mirror/ %{buildroot}%{bmv2root}/examples 49 | cp -r bmv2/reflector/ %{buildroot}%{bmv2root}/examples 50 | 51 | %post 52 | ln -s %{examplesroot} %{t4p4sroot}/examples/p4pi 53 | 54 | %files 55 | %{examplesroot}/arp_icmp/* 56 | %{examplesroot}/calc/* 57 | %{examplesroot}/l2switch/* 58 | %{examplesroot}/stateful_firewall/* 59 | %{examplesroot}/traffic_filter/* 60 | %{examplesroot}/basic_mirror/* 61 | %{examplesroot}/reflector/* 62 | %{examplesroot}/*.cfg 63 | %{bmv2root}/* 64 | -------------------------------------------------------------------------------- /packages/p4pi-examples/pi-examples.cfg: -------------------------------------------------------------------------------- 1 | @piveth arch=dpdk hugepages=2048 model=v1model smem pieal piports 2 | 3 | reflector arch=dpdk hugepages=1024 model=v1model smem vethmode pieal piports 4 | l2switch arch=dpdk hugepages=1024 model=v1model smem vethmode pieal piports 5 | traffic_filter arch=dpdk hugepages=1024 model=v1model smem vethmode pieal piports 6 | stateful_firewall arch=dpdk hugepages=1024 model=v1model smem vethmode pieal piports x_hash 7 | basic_mirror arch=dpdk hugepages=1024 model=v1model smem vethmode pieal piports 8 | arp_icmp arch=dpdk hugepages=1024 model=v1model smem vethmode pieal piports 9 | calc arch=dpdk hugepages=1024 model=v1model smem vethmode pieal piports 10 | -------------------------------------------------------------------------------- /packages/p4pi-examples/t4p4s/calc/receive.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import sys 5 | import platform 6 | 7 | from scapy.all import sniff, Packet, Ether, StrFixedLenField, XByteField, IntField, bind_layers 8 | 9 | 10 | class P4calc(Packet): 11 | name = "P4calc" 12 | fields_desc = [ 13 | StrFixedLenField("P", "P", length=1), 14 | StrFixedLenField("Four", "4", length=1), 15 | XByteField("version", 0x01), 16 | StrFixedLenField("op", "+", length=1), 17 | IntField("operand_a", 0), 18 | IntField("operand_b", 0), 19 | IntField("result", 0xDEADBABE) 20 | ] 21 | 22 | 23 | def get_wireless_interface(): 24 | """ 25 | Get defult wireless interface 26 | """ 27 | for device_name in os.listdir('/sys/class/net'): 28 | if os.path.exists(f'/sys/class/net/{device_name}/wireless'): 29 | return device_name 30 | print("Can't find WiFi interface") 31 | sys.exit(1) 32 | 33 | 34 | def packet_filter(packet): 35 | return packet[Ether].type == 0x1234 36 | 37 | 38 | def PacketHandler(packet): 39 | if packet_filter(packet): 40 | packet.show() 41 | 42 | 43 | def main(): 44 | bind_layers(Ether, P4calc, type=0x1234) 45 | if platform.system() == 'Linux': 46 | iface_name = get_wireless_interface() 47 | else: 48 | iface_name = input("Please enter wireless interface name: ") 49 | print(f"Monitoring P4calc packets on interface: {iface_name}") 50 | sniff(iface=iface_name, prn=PacketHandler) 51 | 52 | 53 | if __name__ == '__main__': 54 | main() 55 | -------------------------------------------------------------------------------- /packages/p4pi-examples/t4p4s/calc/send.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import sys 5 | import platform 6 | import re 7 | 8 | from scapy.all import sendp, Packet, Ether, StrFixedLenField, XByteField, IntField, bind_layers 9 | 10 | DST_ADDR = "10:04:00:00:10:10" 11 | 12 | 13 | class P4calc(Packet): 14 | name = "P4calc" 15 | fields_desc = [ 16 | StrFixedLenField("P", "P", length=1), 17 | StrFixedLenField("Four", "4", length=1), 18 | XByteField("version", 0x01), 19 | StrFixedLenField("op", "+", length=1), 20 | IntField("operand_a", 0), 21 | IntField("operand_b", 0), 22 | IntField("result", 0xDEADBABE) 23 | ] 24 | 25 | 26 | class NumParseError(Exception): 27 | pass 28 | 29 | 30 | class Token: 31 | def __init__(self, token_type, value=None): 32 | self.type = token_type 33 | self.value = value 34 | 35 | 36 | def get_wireless_interface(): 37 | """ 38 | Get defult wireless interface 39 | """ 40 | for device_name in os.listdir('/sys/class/net'): 41 | if os.path.exists(f'/sys/class/net/{device_name}/wireless'): 42 | return device_name 43 | print("Can't find WiFi interface") 44 | sys.exit(1) 45 | 46 | 47 | def input_parser_numeric(s, i, ts): 48 | pattern = "^\\s*([0-9]+)\\s*" 49 | match = re.match(pattern, s[i:]) 50 | if match: 51 | ts.append(Token('num', match.group(1))) 52 | return i + match.end(), ts 53 | raise NumParseError('Expected number literal.') 54 | 55 | 56 | def input_parser_operator(s, i, ts): 57 | pattern = "^\\s*([-+&|^])\\s*" 58 | match = re.match(pattern, s[i:]) 59 | if match: 60 | ts.append(Token('num', match.group(1))) 61 | return i + match.end(), ts 62 | raise NumParseError("Expected binary operator '-', '+', '&', '|', or '^'.") 63 | 64 | 65 | def make_seq(p1, p2): 66 | def parse(s, i, ts): 67 | i, ts2 = p1(s, i, ts) 68 | return p2(s, i, ts2) 69 | return parse 70 | 71 | 72 | def main(): 73 | bind_layers(Ether, P4calc, type=0x1234) 74 | 75 | user_input_parser = make_seq( 76 | input_parser_numeric, 77 | make_seq(input_parser_operator, input_parser_numeric) 78 | ) 79 | 80 | if platform.system() == 'Linux': 81 | iface_name = get_wireless_interface() 82 | else: 83 | iface_name = input("Please enter wireless interface name: ") 84 | print(f"Using interface: {iface_name}") 85 | 86 | while True: 87 | user_command = input('Expression [1 + 2]: ') 88 | if user_command == '': 89 | user_command = '1 + 2' 90 | if user_command in ["quit", "q"]: 91 | break 92 | try: 93 | _, user_input = user_input_parser(user_command, 0, []) 94 | 95 | operator = user_input[1].value 96 | operand_a = int(user_input[0].value) 97 | operand_b = int(user_input[2].value) 98 | 99 | packet = Ether(dst=DST_ADDR, type=0x1234) 100 | packet /= P4calc(op=operator, operand_a=operand_a, 101 | operand_b=operand_b) 102 | 103 | print("Sending packet with payload: ") 104 | print(f"\t{operand_a} {operator} {operand_b}") 105 | sendp(packet, iface=iface_name) 106 | except Exception as error: 107 | print(error) 108 | 109 | 110 | if __name__ == '__main__': 111 | main() 112 | -------------------------------------------------------------------------------- /packages/p4pi-examples/t4p4s/l2switch/l2switch.p4: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | header ethernet_t { 5 | bit<48> dstAddr; 6 | bit<48> srcAddr; 7 | bit<16> etherType; 8 | } 9 | 10 | struct metadata { 11 | } 12 | 13 | struct headers { 14 | ethernet_t ethernet; 15 | } 16 | 17 | parser ParserImpl(packet_in packet, out headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { 18 | 19 | state start { 20 | transition parse_ethernet; 21 | } 22 | 23 | state parse_ethernet { 24 | packet.extract(hdr.ethernet); 25 | transition accept; 26 | } 27 | 28 | } 29 | 30 | control egress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { 31 | apply { 32 | } 33 | } 34 | 35 | struct mac_learn_digest { 36 | bit<48> srcAddr; 37 | bit<9> ingress_port; 38 | } 39 | 40 | control ingress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { 41 | action forward(bit<9> port) { 42 | standard_metadata.egress_port = port; 43 | } 44 | 45 | action bcast() { 46 | standard_metadata.egress_port = 9w100; // Broadcast port 47 | } 48 | 49 | action mac_learn() { 50 | digest((bit<32>)1024, { hdr.ethernet.srcAddr, standard_metadata.ingress_port }); 51 | } 52 | 53 | action drop() { 54 | mark_to_drop( standard_metadata ); 55 | exit; 56 | } 57 | 58 | action _nop() { 59 | } 60 | 61 | table dmac { 62 | actions = { 63 | forward; 64 | bcast; 65 | drop; 66 | } 67 | key = { 68 | hdr.ethernet.dstAddr: exact; 69 | } 70 | default_action = bcast(); 71 | size = 512; 72 | } 73 | 74 | table smac { 75 | actions = { 76 | mac_learn; 77 | _nop; 78 | drop; 79 | } 80 | key = { 81 | hdr.ethernet.srcAddr: exact; 82 | } 83 | default_action = mac_learn(); 84 | size = 512; 85 | } 86 | 87 | apply { 88 | smac.apply(); 89 | dmac.apply(); 90 | } 91 | 92 | } 93 | 94 | control DeparserImpl(packet_out packet, in headers hdr) { 95 | apply { 96 | packet.emit(hdr.ethernet); 97 | } 98 | } 99 | 100 | control verifyChecksum(inout headers hdr, inout metadata meta) { 101 | apply { 102 | } 103 | } 104 | 105 | control computeChecksum(inout headers hdr, inout metadata meta) { 106 | apply { 107 | } 108 | } 109 | 110 | V1Switch(ParserImpl(), verifyChecksum(), ingress(), egress(), computeChecksum(), DeparserImpl()) main; 111 | 112 | -------------------------------------------------------------------------------- /packages/p4pi-web/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | trim_trailing_whitespace = true 7 | charset = utf-8 8 | 9 | [*.py] 10 | indent_style = space 11 | indent_size = 4 12 | -------------------------------------------------------------------------------- /packages/p4pi-web/.obs/workflows.yml: -------------------------------------------------------------------------------- 1 | build_stable: 2 | steps: 3 | - trigger_services: 4 | project: "home:p4edge" 5 | package: "p4edge-web" 6 | filters: 7 | event: tag_push 8 | branches: 9 | only: 10 | - main 11 | 12 | build_testing: 13 | steps: 14 | - trigger_services: 15 | project: "home:p4edge:testing" 16 | package: "p4edge-web" 17 | filters: 18 | event: push 19 | branches: 20 | only: 21 | - main 22 | -------------------------------------------------------------------------------- /packages/p4pi-web/README.md: -------------------------------------------------------------------------------- 1 | # Getting started 2 | 3 | The default user is `pi` with password `raspberry`. 4 | -------------------------------------------------------------------------------- /packages/p4pi-web/config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/config/__init__.py -------------------------------------------------------------------------------- /packages/p4pi-web/config/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for api project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /packages/p4pi-web/config/urls.py: -------------------------------------------------------------------------------- 1 | """api URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/3.2/topics/http/urls/ 5 | """ 6 | from django.urls import path, include 7 | from django.contrib.staticfiles.urls import staticfiles_urlpatterns 8 | 9 | urlpatterns = staticfiles_urlpatterns() 10 | urlpatterns += [ 11 | path("terminal", include("terminal.urls")), 12 | path("", include("dashboard.urls")), 13 | ] 14 | -------------------------------------------------------------------------------- /packages/p4pi-web/config/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for api project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | import socketio 14 | import eventlet.wsgi 15 | from terminal.views import sio 16 | 17 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 18 | 19 | django_app = get_wsgi_application() 20 | application = socketio.WSGIApp(sio, django_app) 21 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/__init__.py -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/config.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | class MyConfig(AppConfig): 4 | name = 'cfg' 5 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.12 on 2022-03-28 10:30 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | initial = True 9 | 10 | dependencies = [ 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='Statistics', 16 | fields=[ 17 | ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('name', models.CharField(max_length=25)), 19 | ('time', models.CharField(max_length=25)), 20 | ('value', models.FloatField()), 21 | ], 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/migrations/__init__.py -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | class Statistics(models.Model): 4 | name = models.CharField(max_length=25) 5 | time = models.CharField(max_length=25) 6 | value = models.FloatField() 7 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/datta/fonts/pct.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/datta/fonts/pct.eot -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/datta/fonts/pct.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by Fontastic.me 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/datta/fonts/pct.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/datta/fonts/pct.ttf -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/datta/fonts/pct.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/datta/fonts/pct.woff -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/datta/icon.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @font-face { 4 | font-family: "pct"; 5 | src:url("fonts/pct.eot"); 6 | src:url("fonts/pct.eot?#iefix") format("embedded-opentype"), 7 | url("fonts/pct.woff") format("woff"), 8 | url("fonts/pct.ttf") format("truetype"), 9 | url("fonts/pct.svg#pct") format("svg"); 10 | font-weight: normal; 11 | font-style: normal; 12 | 13 | } 14 | 15 | [data-icon]:before { 16 | font-family: "pct" !important; 17 | content: attr(data-icon); 18 | font-style: normal !important; 19 | font-weight: normal !important; 20 | font-variant: normal !important; 21 | text-transform: none !important; 22 | speak: none; 23 | line-height: 1; 24 | -webkit-font-smoothing: antialiased; 25 | -moz-osx-font-smoothing: grayscale; 26 | } 27 | 28 | [class^="pct-"]:before, 29 | [class*=" pct-"]:before { 30 | font-family: "pct" !important; 31 | font-style: normal !important; 32 | font-weight: normal !important; 33 | font-variant: normal !important; 34 | text-transform: none !important; 35 | speak: none; 36 | line-height: 1; 37 | -webkit-font-smoothing: antialiased; 38 | -moz-osx-font-smoothing: grayscale; 39 | } 40 | 41 | .pct-arrow1:before { 42 | content: "\61"; 43 | } 44 | .pct-arrow2:before { 45 | content: "\62"; 46 | } 47 | .pct-arrow3:before { 48 | content: "\63"; 49 | } 50 | .pct-arrow4:before { 51 | content: "\64"; 52 | } 53 | .pct-chat1:before { 54 | content: "\65"; 55 | } 56 | .pct-chat2:before { 57 | content: "\66"; 58 | } 59 | .pct-chat3:before { 60 | content: "\67"; 61 | } 62 | .pct-chat4:before { 63 | content: "\68"; 64 | } 65 | .pct-loader1:before { 66 | content: "\69"; 67 | } 68 | .pct-arrow-sharp1:before { 69 | content: "\6a"; 70 | } 71 | .pct-arrow-sharp2:before { 72 | content: "\6b"; 73 | } 74 | .pct-arrow-sharp3:before { 75 | content: "\6c"; 76 | } 77 | .pct-arrow-sharp4:before { 78 | content: "\6d"; 79 | } 80 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/feather/fonts/feather.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/feather/fonts/feather.eot -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/feather/fonts/feather.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/feather/fonts/feather.ttf -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/feather/fonts/feather.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/feather/fonts/feather.woff -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/fontawesome/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/material/material_icons_w400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/material/material_icons_w400.woff2 -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/opensans/opensans.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Open Sans'; 3 | font-style: normal; 4 | font-weight: 300; 5 | src: url(opensans_w300.ttf) format('truetype'); 6 | } 7 | @font-face { 8 | font-family: 'Open Sans'; 9 | font-style: normal; 10 | font-weight: 400; 11 | src: url(opensans_w400.ttf) format('truetype'); 12 | } 13 | @font-face { 14 | font-family: 'Open Sans'; 15 | font-style: normal; 16 | font-weight: 600; 17 | src: url(opensans_w600.ttf) format('truetype'); 18 | } 19 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/opensans/opensans_w300.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/opensans/opensans_w300.ttf -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/opensans/opensans_w400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/opensans/opensans_w400.ttf -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/fonts/opensans/opensans_w600.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/fonts/opensans/opensans_w600.ttf -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/images/favicon.ico -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/assets/images/logo.png -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/js/main.js: -------------------------------------------------------------------------------- 1 | function getCookie(name) { 2 | var cookieValue = null; 3 | if (document.cookie && document.cookie !== '') { 4 | var cookies = document.cookie.split(';'); 5 | for (var i = 0; i < cookies.length; i++) { 6 | var cookie = cookies[i].trim(); 7 | // Does this cookie string begin with the name we want? 8 | if (cookie.substring(0, name.length + 1) === (name + '=')) { 9 | cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 10 | break; 11 | } 12 | } 13 | } 14 | return cookieValue; 15 | } 16 | 17 | const setUpCsrfToken = () => { 18 | const csrftoken = getCookie('csrftoken'); 19 | return (url, data) => { 20 | return fetch(url, { 21 | method: 'POST', 22 | credentials: 'include', 23 | cache: 'no-cache', 24 | referrerPolicy: 'no-referrer', 25 | headers: new Headers({ 26 | 'X-CSRFToken': csrftoken, 27 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 28 | 'X-Requested-With': 'XMLHttpRequest' 29 | }), 30 | body: JSON.stringify(data) 31 | }) 32 | } 33 | } 34 | 35 | const sendPostRequest = setUpCsrfToken(); -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/plugins/amchart/js/images/dragIconRoundBig.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/plugins/amchart/js/images/lens.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/plugins/amchart/js/light.js: -------------------------------------------------------------------------------- 1 | AmCharts.themes.light={themeName:"light",AmChart:{color:"#000000",backgroundColor:"#FFFFFF"},AmCoordinateChart:{colors:["#67b7dc","#fdd400","#84b761","#cc4748","#cd82ad","#2f4074","#448e4d","#b7b83f","#b9783f","#b93e3d","#913167"]},AmStockChart:{colors:["#67b7dc","#fdd400","#84b761","#cc4748","#cd82ad","#2f4074","#448e4d","#b7b83f","#b9783f","#b93e3d","#913167"]},AmSlicedChart:{colors:["#67b7dc","#fdd400","#84b761","#cc4748","#cd82ad","#2f4074","#448e4d","#b7b83f","#b9783f","#b93e3d","#913167"],outlineAlpha:1,outlineThickness:2,labelTickColor:"#000000",labelTickAlpha:0.3},AmRectangularChart:{zoomOutButtonColor:'#000000',zoomOutButtonRollOverAlpha:0.15,zoomOutButtonImage:"lens"},AxisBase:{axisColor:"#000000",axisAlpha:0.3,gridAlpha:0.1,gridColor:"#000000"},ChartScrollbar:{backgroundColor:"#000000",backgroundAlpha:0.12,graphFillAlpha:0.5,graphLineAlpha:0,selectedBackgroundColor:"#FFFFFF",selectedBackgroundAlpha:0.4,gridAlpha:0.15},ChartCursor:{cursorColor:"#000000",color:"#FFFFFF",cursorAlpha:0.5},AmLegend:{color:"#000000"},AmGraph:{lineAlpha:0.9},GaugeArrow:{color:"#000000",alpha:0.8,nailAlpha:0,innerRadius:"40%",nailRadius:15,startWidth:15,borderAlpha:0.8,nailBorderAlpha:0},GaugeAxis:{tickColor:"#000000",tickAlpha:1,tickLength:15,minorTickLength:8,axisThickness:3,axisColor:'#000000',axisAlpha:1,bandAlpha:0.8},TrendLine:{lineColor:"#c03246",lineAlpha:0.8},AreasSettings:{alpha:0.8,color:"#67b7dc",colorSolid:"#003767",unlistedAreasAlpha:0.4,unlistedAreasColor:"#000000",outlineColor:"#FFFFFF",outlineAlpha:0.5,outlineThickness:0.5,rollOverColor:"#3c5bdc",rollOverOutlineColor:"#FFFFFF",selectedOutlineColor:"#FFFFFF",selectedColor:"#f15135",unlistedAreasOutlineColor:"#FFFFFF",unlistedAreasOutlineAlpha:0.5},LinesSettings:{color:"#000000",alpha:0.8},ImagesSettings:{alpha:0.8,labelColor:"#000000",color:"#000000",labelRollOverColor:"#3c5bdc"},ZoomControl:{buttonFillAlpha:0.7,buttonIconColor:"#a7a7a7"},SmallMap:{mapColor:"#000000",rectangleColor:"#f15135",backgroundColor:"#FFFFFF",backgroundAlpha:0.7,borderThickness:1,borderAlpha:0.8},PeriodSelector:{color:"#000000"},PeriodButton:{color:"#000000",background:"transparent",opacity:0.7,border:"1px solid rgba(0, 0, 0, .3)",MozBorderRadius:"5px",borderRadius:"5px",margin:"1px",outline:"none",boxSizing:"border-box"},PeriodButtonSelected:{color:"#000000",backgroundColor:"#b9cdf5",border:"1px solid rgba(0, 0, 0, .3)",MozBorderRadius:"5px",borderRadius:"5px",margin:"1px",outline:"none",opacity:1,boxSizing:"border-box"},PeriodInputField:{color:"#000000",background:"transparent",border:"1px solid rgba(0, 0, 0, .3)",outline:"none"},DataSetSelector:{color:"#000000",selectedBackgroundColor:"#b9cdf5",rollOverBackgroundColor:"#a8b0e4"},DataSetCompareList:{color:"#000000",lineHeight:"100%",boxSizing:"initial",webkitBoxSizing:"initial",border:"1px solid rgba(0, 0, 0, .3)"},DataSetSelect:{border:"1px solid rgba(0, 0, 0, .3)",outline:"none"}}; 2 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/plugins/chart-morris/css/morris.css: -------------------------------------------------------------------------------- 1 | .morris-hover{position:absolute;z-index:1000}.morris-hover.morris-default-style{border-radius:10px;padding:6px;color:#666;background:rgba(255,255,255,0.8);border:solid 2px rgba(230,230,230,0.8);font-family:sans-serif;font-size:12px;text-align:center}.morris-hover.morris-default-style .morris-hover-row-label{font-weight:bold;margin:0.25em 0} 2 | .morris-hover.morris-default-style .morris-hover-point{white-space:nowrap;margin:0.1em 0} 3 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/assets/plugins/jquery-scrollbar/css/jquery.scrollbar.min.css: -------------------------------------------------------------------------------- 1 | .scroll-wrapper{overflow:hidden!important;padding:0!important;position:relative}.scroll-wrapper>.scroll-content{border:none!important;box-sizing:content-box!important;height:auto;left:0;margin:0;max-height:none;max-width:none!important;overflow:scroll!important;padding:0;position:relative!important;top:0;width:auto!important}.scroll-wrapper>.scroll-content::-webkit-scrollbar{height:0;width:0}.scroll-element{display:none}.scroll-element,.scroll-element div{box-sizing:content-box}.scroll-element.scroll-x.scroll-scrollx_visible,.scroll-element.scroll-y.scroll-scrolly_visible{display:block}.scroll-element .scroll-arrow,.scroll-element .scroll-bar{cursor:default}.scroll-textarea{border:1px solid #ccc;border-top-color:#999}.scroll-textarea>.scroll-content{overflow:hidden!important}.scroll-textarea>.scroll-content>textarea{border:none!important;box-sizing:border-box;height:100%!important;margin:0;max-height:none!important;max-width:none!important;overflow:scroll!important;outline:0;padding:2px;position:relative!important;top:0;width:100%!important}.scroll-textarea>.scroll-content>textarea::-webkit-scrollbar{height:0;width:0}.scroll-div>.scroll-element,.scroll-div>.scroll-element div{background:0 0;border:none;margin:0;padding:0;position:absolute;z-index:1026}.scroll-div>.scroll-element div{display:block;height:100%;left:0;top:0;width:100%}.scroll-div>.scroll-element .scroll-element_track{display:none}.scroll-div>.scroll-element .scroll-bar{background-color:#a7a7a7;display:block;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:alpha(opacity=0);opacity:0;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px;-webkit-transition:opacity .2s linear;-moz-transition:opacity .2s linear;-o-transition:opacity .2s linear;-ms-transition:opacity .2s linear;transition:opacity .2s linear}.scroll-div:hover>.scroll-element .scroll-bar,.scroll-div>.scroll-element.scroll-draggable .scroll-bar{-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";filter:alpha(opacity=70);opacity:.7}.scroll-div>.scroll-element.scroll-x{bottom:0;height:0;left:0;min-width:100%;overflow:visible;width:100%}.scroll-div>.scroll-element.scroll-y{height:100%;min-height:100%;right:0;top:0;width:0}.scroll-div>.scroll-element.scroll-x .scroll-element_outer{left:2px}.scroll-div>.scroll-element.scroll-x .scroll-element_size{left:-4px}.scroll-div>.scroll-element.scroll-y .scroll-element_outer{top:2px}.scroll-div>.scroll-element.scroll-y .scroll-element_size{top:-4px}.scroll-div>.scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size{left:-11px}.scroll-div>.scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size{top:-11px}.scroll-div>.scroll-element.scroll-y .scroll-bar{left:-4px;min-height:10px;width:3px}.scroll-div>.scroll-element.scroll-x .scroll-bar{top:-3px;min-width:10px;height:3px} 2 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/static/favicon.ico -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/templates/accounts/login.html: -------------------------------------------------------------------------------- 1 | {% extends "layouts/base-fullscreen.html" %} 2 | 3 | {% block title %} Login {% endblock %} 4 | 5 | {% block content %} 6 | 7 |
8 |
9 |
10 | 11 | 12 | 13 | 14 |
15 |
16 |
17 |
18 | P4Pi Logo 19 |
20 |

Login

21 | 22 | 23 | {% if msg %} 24 | {{ msg | safe }} 25 | {% else %} 26 | Add your credentials 27 | {% endif %} 28 | 29 | 30 |
31 |
32 | 33 |
34 | 35 | {% csrf_token %} 36 | 37 |
38 | {{ form.username }} 39 |
40 | 41 |
42 | {{ form.password }} 43 |
44 | 45 |
46 |
47 | 48 | 49 |
50 |
51 | 52 | 53 |
54 |
55 |
56 |
57 |
58 | 59 | {% endblock content %} 60 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/templates/accounts/password_change.html: -------------------------------------------------------------------------------- 1 | {% extends "layouts/base-fullscreen.html" %} 2 | 3 | {% load crispy_forms_tags %} 4 | 5 | {% block title %} Change Password {% endblock %} 6 | 7 | 8 | {% block stylesheets %}{% endblock stylesheets %} 9 | 10 | {% block content %} 11 | 12 |
13 |
14 |
15 | 16 | 17 | 18 | 19 |
20 |
21 |
22 |
23 | 24 |
25 |

Change Password

26 | 27 | {% crispy form %} 28 | 29 |
30 |
31 |
32 |
33 | 34 | {% endblock content %} 35 | 36 | 37 | {% block javascripts %}{% endblock javascripts %} 38 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/templates/accounts/register.html: -------------------------------------------------------------------------------- 1 | {% extends "layouts/base-fullscreen.html" %} 2 | 3 | {% block title %} Login {% endblock %} 4 | 5 | {% block content %} 6 | 7 |
8 |
9 |
10 | 11 | 12 | 13 | 14 |
15 |
16 |
17 |
18 | 19 |
20 |

Create User

21 | 22 | 23 | {% if msg %} 24 | {{ msg | safe }} 25 | {% else %} 26 | Add user credentials 27 | {% endif %} 28 | 29 | 30 |
31 |
32 | 33 | 34 | {% if not success %} 35 |
36 | 37 | {% csrf_token %} 38 | 39 |
40 | {{ form.username }} 41 |
42 | {{ form.username.errors }} 43 | 44 |
45 | {{ form.email }} 46 |
47 | {{ form.email.errors }} 48 | 49 |
50 | {{ form.password1 }} 51 |
52 | {{ form.password1.errors }} 53 | 54 |
55 | {{ form.password2 }} 56 |
57 | {{ form.password2.errors }} 58 | 59 | 60 | 61 |
62 | {% endif %} 63 | 64 |

Already have an account? Login

65 |
66 |
67 |
68 |
69 | 70 | {% endblock content %} 71 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/templates/includes/scripts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/templates/layouts/base-fullscreen.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | P4Pi - {% block title %}{% endblock %} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | {% block stylesheets %}{% endblock stylesheets %} 19 | 20 | 21 | 22 | 23 | 24 | {% block content %}{% endblock content %} 25 | 26 | {% include 'includes/scripts.html' %} 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/templates/layouts/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | P4Pi - {% block title %}{% endblock %} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | {% block stylesheets %}{% endblock stylesheets %} 19 | 20 | 21 | 22 | 23 | 24 |
25 |
26 |
27 |
28 |
29 | 30 | {% include 'includes/navigation.html' %} 31 | 32 |
33 |
34 | 35 | {% for message in messages %} 36 |
37 | 43 |
44 | {% endfor %} 45 | 46 | {% block content %}{% endblock content %} 47 | 48 |
49 |
50 | 51 | {% include 'includes/scripts.html' %}{% block javascripts %} 52 | 53 | {% endblock javascripts %} 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/templates/page-403.html: -------------------------------------------------------------------------------- 1 | {% extends "layouts/base-fullscreen.html" %} 2 | 3 | {% block title %} 403 Page {% endblock %} 4 | 5 | {% block content %} 6 | 7 |
8 |
9 |
10 | 11 | 12 | 13 | 14 |
15 |
16 |
17 |
18 | 19 |
20 |

Error 403

21 | 22 |
23 | 24 | 25 | Access denied - Please authenticate 26 | 27 | 28 |
29 |
30 |
31 |
32 | 33 | {% endblock content %} 34 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/templates/page-404.html: -------------------------------------------------------------------------------- 1 | {% extends "layouts/base-fullscreen.html" %} 2 | 3 | {% block title %} 403 Page {% endblock %} 4 | 5 | {% block content %} 6 | 7 |
8 |
9 |
10 | 11 | 12 | 13 | 14 |
15 |
16 |
17 |
18 | 19 |
20 |

Error 404

21 | 22 |
23 | 24 | 25 | Page not found - Home 26 | 27 | 28 |
29 |
30 |
31 |
32 | 33 | {% endblock content %} 34 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/templates/page-500.html: -------------------------------------------------------------------------------- 1 | {% extends "layouts/base-fullscreen.html" %} 2 | 3 | {% block title %} 403 Page {% endblock %} 4 | 5 | {% block content %} 6 | 7 |
8 |
9 |
10 | 11 | 12 | 13 | 14 |
15 |
16 |
17 |
18 | 19 |
20 |

Error 500

21 | 22 |
23 | 24 | 25 | Server Error - Home 26 | 27 | 28 |
29 |
30 |
31 |
32 | 33 | {% endblock content %} 34 | -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/tests.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/dashboard/tests.py -------------------------------------------------------------------------------- /packages/p4pi-web/dashboard/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path, re_path 2 | from django.contrib.auth.views import LogoutView 3 | 4 | from . import views 5 | 6 | urlpatterns = [ 7 | path('', views.switch, name='switch'), 8 | 9 | path('login', views.login_view, name='login'), 10 | path('register', views.register_user, name='register'), 11 | path('password_change', views.password_change, name='password_change'), 12 | path('logout', LogoutView.as_view(), name='logout'), 13 | 14 | path('ap', views.access_point_settings, name='access_point_settings'), 15 | path('stats', views.statistics, name='statistics'), 16 | path('entries', views.entries, name='entries'), 17 | 18 | # Matches any html file 19 | re_path(r'^.*\.*', views.pages, name='pages'), 20 | ] 21 | -------------------------------------------------------------------------------- /packages/p4pi-web/dummy_ctrl_plane_connection.py: -------------------------------------------------------------------------------- 1 | entry1 = [{'match':'0xffeeddcc', 'action':'nop', 'params':''}, {'match':'0x11002233','action':'fwd', 'params':'1'}] 2 | entry2 = [{'match':'127.0.0.0', 'mask':'8', 'action':'nop', 'params':''}, {'match':'192.0.0.0', 'mask':'16', 'action':'fwd', 'params':'1'}] 3 | entry3 = [{'match':'127.0.0.0', 'mask':'8', 'action':'nop', 'params':''}, {'match':'192.0.0.0', 'mask':'16', 'action':'fwd', 'params':'1'}] 4 | 5 | entries = [entry1, entry2, entry3] 6 | 7 | tab = {'name':'l2tab', 'type':'exact', 'editable':True} 8 | tab2 = {'name':'l3tab', 'type':'lpm', 'editable':False} 9 | tab3 = {'name':'l3tabedit', 'type':'lpm', 'editable':True} 10 | tables = [tab, tab2, tab3] 11 | 12 | import socket 13 | import pickle 14 | 15 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 16 | sock.bind(('localhost',12345)) 17 | sock.listen() 18 | while True: 19 | cli, addr = sock.accept(); 20 | request = pickle.loads(cli.recv(1024)) 21 | print(request) 22 | if request['mode'] == 'add': 23 | i=-1 24 | for table in tables: 25 | print(table) 26 | i=i+1 27 | if table['name'] == request['name']: 28 | request.pop('mode') 29 | request.pop('name') 30 | entries[i].append(request) 31 | break 32 | elif request['mode'] == 'delete': 33 | i=-1 34 | for table in tables: 35 | print(table) 36 | i=i+1 37 | if table['name'] == request['name']: 38 | request.pop('mode') 39 | request.pop('name') 40 | try: 41 | entries[i].remove(request) 42 | except: 43 | pass 44 | break 45 | 46 | cli.send(pickle.dumps(tables)); 47 | import time 48 | time.sleep(0.05) 49 | cli.send(pickle.dumps(entries[0])); 50 | time.sleep(0.05) 51 | cli.send(pickle.dumps(entries[1])); 52 | time.sleep(0.05) 53 | cli.send(pickle.dumps(entries[2])); 54 | cli.close(); 55 | 56 | -------------------------------------------------------------------------------- /packages/p4pi-web/fixtures/users.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "model": "auth.user", 4 | "pk": 1, 5 | "fields": { 6 | "password": "pbkdf2_sha256$260000$Fp3x685Jc0poXaahZtNw73$L9JHOtaFO16A38ruvgtF8rM4rDaqeh13Il569K4A1NI=", 7 | "last_login": null, 8 | "is_superuser": true, 9 | "username": "pi", 10 | "first_name": "", 11 | "last_name": "", 12 | "email": "", 13 | "is_staff": true, 14 | "is_active": true, 15 | "date_joined": "2021-07-31T21:23:15.713Z", 16 | "groups": [], 17 | "user_permissions": [] 18 | } 19 | } 20 | ] 21 | -------------------------------------------------------------------------------- /packages/p4pi-web/gunicorn-cfg.py: -------------------------------------------------------------------------------- 1 | bind = '0.0.0.0:80' 2 | workers = 1 3 | worker_class = 'eventlet' 4 | accesslog = '-' 5 | loglevel = 'warning' 6 | capture_output = True 7 | enable_stdio_inheritance = True 8 | -------------------------------------------------------------------------------- /packages/p4pi-web/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | import subprocess 23 | subprocess.Popen(["python", "generate-statistics.py"]) 24 | main() 25 | -------------------------------------------------------------------------------- /packages/p4pi-web/packaging/bmv2-p4rtshell: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z $1 ] 4 | then 5 | echo "Missing commandline argument!" 6 | echo "Usage: $(basename $0) " 7 | echo "Example: $(basename $0) l2switch" 8 | exit -1 9 | fi 10 | 11 | DEFAULT_PROG=$1 12 | P4RTDIR="/root/bmv2/bin" 13 | 14 | echo "Launching P4Runtime-shell..." 15 | 16 | PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python python3 -m p4runtime_sh --grpc-addr localhost:50051 --device-id 0 --election-id 0,1 --config "${P4RTDIR}/${DEFAULT_PROG}.p4info.txt,${P4RTDIR}/${DEFAULT_PROG}.json" 17 | 18 | -------------------------------------------------------------------------------- /packages/p4pi-web/packaging/bmv2-start: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export P4PI=/root/t4p4s/third_party/PI 4 | export GRPCPP=/root/t4p4s/third_party/P4Runtime_GRPCPP 5 | export GRPC=/root/t4p4s/third_party/grpc 6 | 7 | BM2_WDIR=/root/bmv2 8 | P4_PROG=l2switch 9 | T4P4S_PROG_FILE=/root/t4p4s-switch 10 | if [ -f "${T4P4S_PROG_FILE}" ]; then 11 | P4_PROG=$(cat "${T4P4S_PROG_FILE}") 12 | else 13 | echo "${P4_PROG}" > "${T4P4S_PROG_FILE}" 14 | fi 15 | 16 | rm -rf ${BM2_WDIR}/bin 17 | mkdir ${BM2_WDIR}/bin 18 | echo "Compiling P4 code" 19 | p4c-bm2-ss -I /usr/share/p4c/p4include --std p4-16 --p4runtime-files ${BM2_WDIR}/bin/${P4_PROG}.p4info.txt -o ${BM2_WDIR}/bin/${P4_PROG}.json ${BM2_WDIR}/examples/${P4_PROG}/${P4_PROG}.p4 20 | 21 | echo "Launching BMv2 switch" 22 | sudo simple_switch_grpc -i 0@veth0 -i 1@veth1 ${BM2_WDIR}/bin/${P4_PROG}.json -- --grpc-server-addr 127.0.0.1:50051 23 | 24 | -------------------------------------------------------------------------------- /packages/p4pi-web/packaging/bmv2.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=BMv2 Switch 3 | After=p4pi-setup.service 4 | 5 | [Service] 6 | Type=simple 7 | ExecStart=/usr/bin/bmv2-start 8 | WorkingDirectory=/root/bmv2 9 | Restart=on-failure 10 | RestartSec=5s 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | 15 | -------------------------------------------------------------------------------- /packages/p4pi-web/packaging/p4pi-web-dummy-ctrl-plane.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Collect statistics for p4pi-web 3 | After=network.target 4 | 5 | [Service] 6 | Type=simple 7 | User=root 8 | Group=www-data 9 | WorkingDirectory=/srv/p4pi 10 | ExecStart=/usr/bin/python3 dummy_ctrl_plane_connection.py 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /packages/p4pi-web/packaging/p4pi-web-genstat.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Collect statistics for p4pi-web 3 | After=network.target 4 | 5 | [Service] 6 | Type=simple 7 | User=root 8 | Group=www-data 9 | WorkingDirectory=/srv/p4pi 10 | ExecStart=/usr/bin/python3 generate-statistics.py 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /packages/p4pi-web/packaging/p4pi-web.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Web UI for P4pi 3 | After=network.target 4 | 5 | [Service] 6 | Type=notify 7 | User=root 8 | Group=www-data 9 | WorkingDirectory=/srv/p4pi 10 | ExecStart=gunicorn --config gunicorn-cfg.py config.wsgi 11 | ExecReload=/bin/kill -s HUP $MAINPID 12 | KillMode=mixed 13 | TimeoutStopSec=5 14 | PrivateTmp=true 15 | 16 | [Install] 17 | WantedBy=multi-user.target 18 | -------------------------------------------------------------------------------- /packages/p4pi-web/packaging/p4pi-web.spec: -------------------------------------------------------------------------------- 1 | %{!?srvdir: %global srvdir /srv/p4pi} 2 | Name: p4pi-web 3 | Version: 0.0.0 4 | Release: 0%{?dist} 5 | Summary: Web UI for P4Pi 6 | License: Apache 2.0 7 | URL: https://github.com/p4lang/p4pi 8 | Source0: %{name}-%{version}.tar.gz 9 | BuildArch: noarch 10 | Requires: python3, python3-pip, lm-sensors, ifstat 11 | Requires: p4lang-bmv2, p4edge-t4p4s, p4pi-examples 12 | BuildRequires: debbuild-macros-systemd 13 | Packager: Dávid Kis 14 | 15 | %description 16 | Web UI for P4Pi 17 | 18 | %prep 19 | %autosetup 20 | 21 | %build 22 | 23 | %install 24 | rm -rf %{buildroot} 25 | 26 | mkdir -p %{buildroot}%{srvdir} 27 | cp -r config/ %{buildroot}%{srvdir} 28 | cp -r dashboard/ %{buildroot}%{srvdir} 29 | cp -r terminal/ %{buildroot}%{srvdir} 30 | cp -r fixtures/ %{buildroot}%{srvdir} 31 | cp gunicorn-cfg.py %{buildroot}%{srvdir} 32 | cp manage.py %{buildroot}%{srvdir} 33 | cp poetry.lock %{buildroot}%{srvdir} 34 | cp pyproject.toml %{buildroot}%{srvdir} 35 | cp requirements.txt %{buildroot}%{srvdir} 36 | cp .editorconfig %{buildroot}%{srvdir} 37 | cp dummy_ctrl_plane_connection.py %{buildroot}%{srvdir} 38 | cp generate-statistics.py %{buildroot}%{srvdir} 39 | 40 | mkdir -p %{buildroot}%{_bindir} 41 | mkdir -p %{buildroot}%{_unitdir} 42 | 43 | install -m 755 packaging/bmv2-start %{buildroot}%{_bindir} 44 | install -m 755 packaging/bmv2-p4rtshell %{buildroot}%{_bindir} 45 | install -m 644 packaging/bmv2.service %{buildroot}%{_unitdir} 46 | install -m 644 packaging/%{name}.service %{buildroot}%{_unitdir} 47 | install -m 644 packaging/%{name}-genstat.service %{buildroot}%{_unitdir} 48 | install -m 644 packaging/%{name}-dummy-ctrl-plane.service %{buildroot}%{_unitdir} 49 | 50 | %post 51 | cat > %{srvdir}/.env << EOF 52 | DEBUG=TRUE 53 | ALLOWED_HOSTS=["*"] 54 | SECRET_KEY=`python3 -c "import secrets; print(secrets.token_urlsafe())"` 55 | SQLITE_PATH=%{srvdir}/db.sqlite3 56 | EOF 57 | 58 | python3 -m pip install -r %{srvdir}/requirements.txt 59 | python3 -m pip install p4runtime-shell 60 | 61 | cd %{srvdir} 62 | python3 -m django migrate --settings=config.settings 63 | python3 -m django loaddata fixtures/users.json --settings=config.settings 64 | 65 | %systemd_post %{name}.service 66 | %systemd_post %{name}-genstat.service 67 | %systemd_post %{name}-dummy-ctrl-plane.service 68 | %systemd_post bmv2.service 69 | 70 | %preun 71 | %systemd_preun %{name}.service 72 | %systemd_preun %{name}-genstat.service 73 | %systemd_preun %{name}-dummy-ctrl-plane.service 74 | %systemd_preun bmv2.service 75 | 76 | %postun 77 | %systemd_postun %{name}.service 78 | %systemd_postun %{name}-genstat.service 79 | %systemd_postun %{name}-dummy-ctrl-plane.service 80 | %systemd_postun bmv2.service 81 | 82 | %files 83 | %{srvdir}/* 84 | %{srvdir}/.editorconfig 85 | %{_unitdir}/%{name}.service 86 | %{_unitdir}/%{name}-genstat.service 87 | %{_unitdir}/%{name}-dummy-ctrl-plane.service 88 | %{_unitdir}/bmv2.service 89 | %{_bindir}/bmv2-start 90 | %{_bindir}/bmv2-p4rtshell 91 | -------------------------------------------------------------------------------- /packages/p4pi-web/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "p4pi-web" 3 | version = "0.1.0" 4 | description = "Web interface for p4pi" 5 | authors = ["Dávid Kis "] 6 | maintainers = ["Dávid Kis "] 7 | repository="https://github.com/p4edge/ui" 8 | license = "MIT" 9 | packages = [ 10 | { include = "dashboard" }, 11 | { include = "config" }, 12 | ] 13 | include = [ 14 | "requirements.txt", 15 | ] 16 | 17 | [tool.poetry.dependencies] 18 | python = "~3.9" 19 | Django = "~=3.2.25" 20 | django-environ = "~=0.4.5" 21 | gunicorn = "^22.0.0" 22 | uvicorn = "^0.14.0" 23 | wsproto = "^1.0.0" 24 | channels = "^3.0.4" 25 | python-decouple = "^3.4" 26 | pycountry = "^20.7.3" 27 | django-crispy-forms = "^1.12.0" 28 | python-socketio = "^4.6.1" 29 | python-engineio = "^3.13.0" 30 | eventlet = "0.35.2" 31 | psutil = "^5.9.0" 32 | 33 | [build-system] 34 | requires = ["poetry-core>=1.0.0"] 35 | build-backend = "poetry.core.masonry.api" 36 | -------------------------------------------------------------------------------- /packages/p4pi-web/requirements.txt: -------------------------------------------------------------------------------- 1 | asgiref==3.4.1; python_version >= "3.6" 2 | attrs==21.2.0; python_full_version >= "3.6.7" and python_version >= "3.6" 3 | autobahn==21.3.1; python_version >= "3.7" 4 | automat==20.2.0; python_full_version >= "3.6.7" and python_version >= "3.6" 5 | cffi==1.14.6; python_version >= "3.7" 6 | channels==3.0.4; python_version >= "3.6" 7 | click==8.0.1; python_version >= "3.6" 8 | colorama==0.4.4; python_version >= "3.6" and python_full_version < "3.0.0" and platform_system == "Windows" or platform_system == "Windows" and python_version >= "3.6" and python_full_version >= "3.5.0" 9 | constantly==15.1.0; python_full_version >= "3.6.7" and python_version >= "3.6" 10 | cryptography==42.0.4; python_full_version >= "3.6.7" and python_version >= "3.7" 11 | daphne==3.0.2; python_version >= "3.6" 12 | django-crispy-forms==1.12.0; python_version >= "3.6" 13 | django-environ==0.4.5 14 | django==3.2.25; python_version >= "3.6" 15 | dnspython==1.16.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" 16 | eventlet==0.31.0 17 | greenlet==1.1.2; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" 18 | gunicorn==22.0.0; python_version >= "3.5" 19 | h11==0.12.0; python_version >= "3.6" and python_full_version >= "3.6.1" 20 | hyperlink==21.0.0; python_full_version >= "3.6.7" and python_version >= "3.7" 21 | idna==3.7; python_full_version >= "3.6.7" and python_version >= "3.7" 22 | incremental==21.3.0; python_full_version >= "3.6.7" and python_version >= "3.6" 23 | psutil==5.9.0; (python_version >= "2.6" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") 24 | pyasn1-modules==0.2.8; python_full_version >= "3.6.7" and python_version >= "3.6" 25 | pyasn1==0.4.8; python_full_version >= "3.6.7" and python_version >= "3.6" 26 | pycountry==20.7.3 27 | pycparser==2.20; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7" 28 | pyopenssl==20.0.1; python_full_version >= "3.6.7" and python_version >= "3.6" 29 | python-decouple==3.4 30 | python-engineio==3.14.2 31 | python-socketio==4.6.1 32 | pytz==2021.1; python_version >= "3.6" 33 | service-identity==21.1.0; python_full_version >= "3.6.7" and python_version >= "3.6" 34 | six==1.16.0; python_full_version >= "3.6.7" and python_version >= "3.6" 35 | sqlparse==0.5.0; python_version >= "3.6" 36 | twisted-iocpsupport==1.0.2; python_full_version >= "3.6.7" and python_version >= "3.6" and platform_system == "Windows" 37 | twisted==23.10.0rc1; python_full_version >= "3.6.7" and python_version >= "3.6" 38 | txaio==21.2.1; python_version >= "3.7" 39 | typing-extensions==3.10.0.2; python_full_version >= "3.6.7" and python_version >= "3.6" 40 | uvicorn==0.14.0 41 | wsproto==1.0.0; python_full_version >= "3.6.1" 42 | zope.interface==5.4.0; python_full_version >= "3.6.7" and python_version >= "3.6" 43 | -------------------------------------------------------------------------------- /packages/p4pi-web/terminal/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/packages/p4pi-web/terminal/__init__.py -------------------------------------------------------------------------------- /packages/p4pi-web/terminal/static/fit.js: -------------------------------------------------------------------------------- 1 | (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.fit = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i 6 | {% block stylesheets %} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 19 | {% endblock stylesheets %} 20 | 21 | {% block content %} 22 |
23 | Status: connecting... 24 | 25 |
26 | 27 |
28 | {% endblock content %} 29 | 30 | 31 | {% block javascripts %} 32 | 87 | {% endblock javascripts %} 88 | -------------------------------------------------------------------------------- /packages/p4pi-web/terminal/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path, re_path 2 | 3 | from . import views 4 | 5 | urlpatterns = [ 6 | path('', views.terminal, name='terminal'), 7 | ] 8 | -------------------------------------------------------------------------------- /packages/p4pi-web/terminal/views.py: -------------------------------------------------------------------------------- 1 | import os 2 | import socketio 3 | import pty 4 | import select 5 | import subprocess 6 | import struct 7 | import fcntl 8 | import termios 9 | import signal 10 | import eventlet 11 | 12 | from django.shortcuts import render 13 | from django.template import loader 14 | from django.http import HttpResponse 15 | from django.contrib.auth.decorators import login_required 16 | 17 | 18 | sio = socketio.Server(async_mode="eventlet") 19 | 20 | # will be used as global variables 21 | fd = None 22 | child_pid = None 23 | 24 | @login_required(login_url="/login") 25 | def terminal(request): 26 | html_template = loader.get_template('terminal.html') 27 | context = {'segment': 'terminal', 'errors': []} 28 | 29 | if request.method == 'GET': 30 | return HttpResponse(html_template.render(context, request)) 31 | 32 | # changes the size reported to TTY-aware applications like vim 33 | def set_winsize(fd, row, col, xpix=0, ypix=0): 34 | winsize = struct.pack("HHHH", row, col, xpix, ypix) 35 | fcntl.ioctl(fd, termios.TIOCSWINSZ, winsize) 36 | 37 | 38 | def read_and_forward_pty_output(): 39 | global fd 40 | max_read_bytes = 1024 * 20 41 | while True: 42 | sio.sleep(0.01) 43 | if fd: 44 | timeout_sec = 0 45 | (data_ready, _, _) = select.select([fd], [], [], timeout_sec) 46 | if data_ready: 47 | output = os.read(fd, max_read_bytes).decode() 48 | sio.emit("pty_output", {"output": output}) 49 | else: 50 | print("process killed") 51 | return 52 | 53 | @sio.event 54 | def resize(sid, message): 55 | if fd: 56 | set_winsize(fd, message["rows"], message["cols"]) 57 | 58 | @sio.event 59 | def pty_input(sid, message): 60 | if fd: 61 | os.write(fd, message["input"].encode()) 62 | 63 | @sio.event 64 | def disconnect_request(sid): 65 | sio.disconnect(sid) 66 | 67 | @sio.event 68 | def connect(sid, environ): 69 | global fd 70 | global child_pid 71 | 72 | if child_pid: 73 | # already started child process, don't start another 74 | # write a new line so that when a client refresh the shell prompt is printed 75 | os.write(fd, "\n".encode()) 76 | return 77 | 78 | # create child process attached to a pty we can read from and write to 79 | (child_pid, fd) = pty.fork() 80 | 81 | if child_pid == 0: 82 | # this is the child process fork. 83 | # anything printed here will show up in the pty, including the output 84 | # of this subprocess 85 | subprocess.run('bash') 86 | 87 | else: 88 | # this is the parent process fork. 89 | sio.start_background_task(target=read_and_forward_pty_output) 90 | 91 | @sio.event 92 | def disconnect(sid): 93 | 94 | global fd 95 | global child_pid 96 | 97 | # kill pty process 98 | os.kill(child_pid,signal.SIGKILL) 99 | os.waitpid(child_pid, 0) 100 | 101 | # reset the variables 102 | fd = None 103 | child_pid = None 104 | print('Client disconnected') 105 | -------------------------------------------------------------------------------- /pi-gen/.dockerignore: -------------------------------------------------------------------------------- 1 | output/ 2 | work/ 3 | deploy/ 4 | apt-cacher-ng/ 5 | .git/objects/* 6 | -------------------------------------------------------------------------------- /pi-gen/.gitignore: -------------------------------------------------------------------------------- 1 | deploy/* 2 | work/* 3 | postrun.sh 4 | SKIP 5 | SKIP_IMAGES 6 | .pc 7 | *-pc 8 | apt-cacher-ng/ 9 | -------------------------------------------------------------------------------- /pi-gen/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BASE_IMAGE=debian:bullseye 2 | FROM ${BASE_IMAGE} 3 | 4 | ENV DEBIAN_FRONTEND noninteractive 5 | 6 | RUN apt-get -y update && \ 7 | apt-get -y install --no-install-recommends \ 8 | git vim parted \ 9 | quilt coreutils qemu-user-static debootstrap zerofree zip dosfstools \ 10 | libarchive-tools libcap2-bin rsync grep udev xz-utils curl xxd file kmod bc\ 11 | binfmt-support ca-certificates qemu-utils kpartx fdisk gpg pigz\ 12 | && rm -rf /var/lib/apt/lists/* 13 | 14 | COPY . /pi-gen/ 15 | 16 | VOLUME [ "/pi-gen/work", "/pi-gen/deploy"] 17 | -------------------------------------------------------------------------------- /pi-gen/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Raspberry Pi (Trading) Ltd. 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 10 | 11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 | -------------------------------------------------------------------------------- /pi-gen/config: -------------------------------------------------------------------------------- 1 | IMG_NAME=p4pi 2 | RELEASE=bullseye 3 | TARGET_HOSTNAME="p4pi" 4 | FIRST_USER_NAME="pi" 5 | FIRST_USER_PASS="raspberry" 6 | DISABLE_FIRST_BOOT_USER_RENAME=1 7 | ENABLE_SSH=1 8 | DEPLOY_COMPRESSION=zip 9 | WPA_COUNTRY=HU 10 | #APT_PROXY=http://172.17.0.1:3142 11 | -------------------------------------------------------------------------------- /pi-gen/depends: -------------------------------------------------------------------------------- 1 | quilt 2 | parted 3 | realpath:coreutils 4 | qemu-arm-static:qemu-user-static 5 | debootstrap 6 | zerofree 7 | zip 8 | mkdosfs:dosfstools 9 | capsh:libcap2-bin 10 | bsdtar:libarchive-tools 11 | grep 12 | rsync 13 | xz:xz-utils 14 | curl 15 | xxd 16 | file 17 | git 18 | lsmod:kmod 19 | bc 20 | qemu-nbd:qemu-utils 21 | kpartx 22 | gpg 23 | pigz 24 | -------------------------------------------------------------------------------- /pi-gen/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | apt-cacher-ng: 5 | restart: unless-stopped 6 | image: sameersbn/apt-cacher-ng:latest 7 | ports: 8 | - "3142:3142" 9 | volumes: 10 | - ./apt-cacher-ng:/var/cache/apt-cacher-ng 11 | -------------------------------------------------------------------------------- /pi-gen/export-image/00-allow-rerun/00-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | if [ ! -x "${ROOTFS_DIR}/usr/bin/qemu-arm-static" ]; then 4 | cp /usr/bin/qemu-arm-static "${ROOTFS_DIR}/usr/bin/" 5 | fi 6 | 7 | if [ -e "${ROOTFS_DIR}/etc/ld.so.preload" ]; then 8 | mv "${ROOTFS_DIR}/etc/ld.so.preload" "${ROOTFS_DIR}/etc/ld.so.preload.disabled" 9 | fi 10 | -------------------------------------------------------------------------------- /pi-gen/export-image/01-user-rename/00-packages: -------------------------------------------------------------------------------- 1 | userconf-pi 2 | -------------------------------------------------------------------------------- /pi-gen/export-image/01-user-rename/01-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | if [[ "${DISABLE_FIRST_BOOT_USER_RENAME}" == "0" ]]; then 4 | on_chroot <<- EOF 5 | SUDO_USER="${FIRST_USER_NAME}" rename-user -f -s 6 | EOF 7 | else 8 | rm -f "${ROOTFS_DIR}/etc/xdg/autostart/piwiz.desktop" 9 | fi 10 | -------------------------------------------------------------------------------- /pi-gen/export-image/02-set-sources/01-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | rm -f "${ROOTFS_DIR}/etc/apt/apt.conf.d/51cache" 4 | find "${ROOTFS_DIR}/var/lib/apt/lists/" -type f -delete 5 | on_chroot << EOF 6 | apt-get update 7 | apt-get -y dist-upgrade 8 | apt-get clean 9 | EOF 10 | -------------------------------------------------------------------------------- /pi-gen/export-image/03-network/01-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | install -m 644 files/resolv.conf "${ROOTFS_DIR}/etc/" 4 | -------------------------------------------------------------------------------- /pi-gen/export-image/03-network/files/resolv.conf: -------------------------------------------------------------------------------- 1 | nameserver 8.8.8.8 2 | -------------------------------------------------------------------------------- /pi-gen/export-image/04-set-partuuid/00-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | if [ "${NO_PRERUN_QCOW2}" = "0" ]; then 4 | 5 | IMG_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img" 6 | 7 | IMGID="$(dd if="${IMG_FILE}" skip=440 bs=1 count=4 2>/dev/null | xxd -e | cut -f 2 -d' ')" 8 | 9 | BOOT_PARTUUID="${IMGID}-01" 10 | ROOT_PARTUUID="${IMGID}-02" 11 | 12 | sed -i "s/BOOTDEV/PARTUUID=${BOOT_PARTUUID}/" "${ROOTFS_DIR}/etc/fstab" 13 | sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${ROOTFS_DIR}/etc/fstab" 14 | 15 | sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${ROOTFS_DIR}/boot/cmdline.txt" 16 | 17 | fi 18 | 19 | -------------------------------------------------------------------------------- /pi-gen/export-image/prerun.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | if [ "${NO_PRERUN_QCOW2}" = "0" ]; then 4 | IMG_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img" 5 | 6 | unmount_image "${IMG_FILE}" 7 | 8 | rm -f "${IMG_FILE}" 9 | 10 | rm -rf "${ROOTFS_DIR}" 11 | mkdir -p "${ROOTFS_DIR}" 12 | 13 | BOOT_SIZE="$((256 * 1024 * 1024))" 14 | ROOT_SIZE=$(du --apparent-size -s "${EXPORT_ROOTFS_DIR}" --exclude var/cache/apt/archives --exclude boot --block-size=1 | cut -f 1) 15 | 16 | # All partition sizes and starts will be aligned to this size 17 | ALIGN="$((4 * 1024 * 1024))" 18 | # Add this much space to the calculated file size. This allows for 19 | # some overhead (since actual space usage is usually rounded up to the 20 | # filesystem block size) and gives some free space on the resulting 21 | # image. 22 | ROOT_MARGIN="$(echo "($ROOT_SIZE * 0.2 + 200 * 1024 * 1024) / 1" | bc)" 23 | 24 | BOOT_PART_START=$((ALIGN)) 25 | BOOT_PART_SIZE=$(((BOOT_SIZE + ALIGN - 1) / ALIGN * ALIGN)) 26 | ROOT_PART_START=$((BOOT_PART_START + BOOT_PART_SIZE)) 27 | ROOT_PART_SIZE=$(((ROOT_SIZE + ROOT_MARGIN + ALIGN - 1) / ALIGN * ALIGN)) 28 | IMG_SIZE=$((BOOT_PART_START + BOOT_PART_SIZE + ROOT_PART_SIZE)) 29 | 30 | truncate -s "${IMG_SIZE}" "${IMG_FILE}" 31 | 32 | parted --script "${IMG_FILE}" mklabel msdos 33 | parted --script "${IMG_FILE}" unit B mkpart primary fat32 "${BOOT_PART_START}" "$((BOOT_PART_START + BOOT_PART_SIZE - 1))" 34 | parted --script "${IMG_FILE}" unit B mkpart primary ext4 "${ROOT_PART_START}" "$((ROOT_PART_START + ROOT_PART_SIZE - 1))" 35 | 36 | echo "Creating loop device..." 37 | cnt=0 38 | until LOOP_DEV="$(losetup --show --find --partscan "$IMG_FILE")"; do 39 | if [ $cnt -lt 5 ]; then 40 | cnt=$((cnt + 1)) 41 | echo "Error in losetup. Retrying..." 42 | sleep 5 43 | else 44 | echo "ERROR: losetup failed; exiting" 45 | exit 1 46 | fi 47 | done 48 | 49 | BOOT_DEV="${LOOP_DEV}p1" 50 | ROOT_DEV="${LOOP_DEV}p2" 51 | 52 | ROOT_FEATURES="^huge_file" 53 | for FEATURE in 64bit; do 54 | if grep -q "$FEATURE" /etc/mke2fs.conf; then 55 | ROOT_FEATURES="^$FEATURE,$ROOT_FEATURES" 56 | fi 57 | done 58 | mkdosfs -n boot -F 32 -s 4 -v "$BOOT_DEV" > /dev/null 59 | mkfs.ext4 -L rootfs -O "$ROOT_FEATURES" "$ROOT_DEV" > /dev/null 60 | 61 | mount -v "$ROOT_DEV" "${ROOTFS_DIR}" -t ext4 62 | mkdir -p "${ROOTFS_DIR}/boot" 63 | mount -v "$BOOT_DEV" "${ROOTFS_DIR}/boot" -t vfat 64 | 65 | rsync -aHAXx --exclude /var/cache/apt/archives --exclude /boot "${EXPORT_ROOTFS_DIR}/" "${ROOTFS_DIR}/" 66 | rsync -rtx "${EXPORT_ROOTFS_DIR}/boot/" "${ROOTFS_DIR}/boot/" 67 | fi 68 | -------------------------------------------------------------------------------- /pi-gen/imagetool.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$(id -u)" != "0" ]; then 4 | echo "Please run as root" 1>&2 5 | exit 1 6 | fi 7 | 8 | progname=$(basename $0) 9 | 10 | function usage() 11 | { 12 | cat << HEREDOC 13 | 14 | Usage: 15 | Mount Image : $progname [--mount] [--image-name ] [--mount-point ] 16 | Umount Image: $progname [--umount] [--mount-point ] 17 | Cleanup NBD : $progname [--cleanup] 18 | 19 | arguments: 20 | -h, --help show this help message and exit 21 | -c, --cleanup cleanup orphaned device mappings 22 | -m, --mount mount image 23 | -u, --umount umount image 24 | -i, --image-name path to qcow2 image 25 | -p, --mount-point mount point for image 26 | 27 | This tool will use /dev/nbd1 as default for mounting an image. If you want to use another device, execute like this: 28 | NBD_DEV=/dev/nbd2 ./$progname --mount --image-name --mount-point 29 | 30 | HEREDOC 31 | } 32 | 33 | MOUNT=0 34 | UMOUNT=0 35 | IMAGE="" 36 | MOUNTPOINT="" 37 | 38 | nbd_cleanup() { 39 | DEVS="$(lsblk | grep nbd | grep disk | cut -d" " -f1)" 40 | if [ ! -z "${DEVS}" ]; then 41 | for d in $DEVS; do 42 | if [ ! -z "${d}" ]; then 43 | QDEV="$(ps xa | grep $d | grep -v grep)" 44 | if [ -z "${QDEV}" ]; then 45 | kpartx -d /dev/$d && echo "Unconnected device map removed: /dev/$d" 46 | fi 47 | fi 48 | done 49 | fi 50 | } 51 | 52 | # As long as there is at least one more argument, keep looping 53 | while [[ $# -gt 0 ]]; do 54 | key="$1" 55 | case "$key" in 56 | -h|--help) 57 | usage 58 | exit 59 | ;; 60 | -c|--cleanup) 61 | nbd_cleanup 62 | ;; 63 | -m|--mount) 64 | MOUNT=1 65 | ;; 66 | -u|--umount) 67 | UMOUNT=1 68 | ;; 69 | -i|--image-name) 70 | shift 71 | IMAGE="$1" 72 | ;; 73 | -p|--mount-point) 74 | shift 75 | MOUNTPOINT="$1" 76 | ;; 77 | *) 78 | echo "Unknown option '$key'" 79 | usage 80 | exit 81 | ;; 82 | esac 83 | # Shift after checking all the cases to get the next option 84 | shift 85 | done 86 | 87 | if [ "${MOUNT}" = "1" ] && [ "${UMOUNT}" = "1" ]; then 88 | usage 89 | echo "Concurrent mount options not possible." 90 | exit 91 | fi 92 | 93 | if [ "${MOUNT}" = "1" ] && ([ -z "${IMAGE}" ] || [ -z "${MOUNTPOINT}" ]); then 94 | usage 95 | echo "Can not mount image. Image path and/or mount point missing." 96 | exit 97 | fi 98 | 99 | if [ "${UMOUNT}" = "1" ] && [ -z "${MOUNTPOINT}" ]; then 100 | usage 101 | echo "Can not umount. Mount point parameter missing." 102 | exit 103 | fi 104 | 105 | export NBD_DEV="${NBD_DEV:-/dev/nbd1}" 106 | export MAP_BOOT_DEV=/dev/mapper/nbd1p1 107 | export MAP_ROOT_DEV=/dev/mapper/nbd1p2 108 | source scripts/qcow2_handling 109 | 110 | if [ "${MOUNT}" = "1" ]; then 111 | mount_qimage "${IMAGE}" "${MOUNTPOINT}" 112 | elif [ "${UMOUNT}" = "1" ]; then 113 | umount_qimage "${MOUNTPOINT}" 114 | fi 115 | -------------------------------------------------------------------------------- /pi-gen/scripts/common: -------------------------------------------------------------------------------- 1 | log (){ 2 | date +"[%T] $*" | tee -a "${LOG_FILE}" 3 | } 4 | export -f log 5 | 6 | bootstrap(){ 7 | local BOOTSTRAP_CMD=debootstrap 8 | local BOOTSTRAP_ARGS=() 9 | 10 | export http_proxy=${APT_PROXY} 11 | 12 | BOOTSTRAP_ARGS+=(--arch arm64) 13 | BOOTSTRAP_ARGS+=(--include gnupg) 14 | BOOTSTRAP_ARGS+=(--components "main,contrib,non-free") 15 | #BOOTSTRAP_ARGS+=(--keyring "${STAGE_DIR}/files/raspberrypi.gpg") 16 | BOOTSTRAP_ARGS+=(--exclude=info) 17 | BOOTSTRAP_ARGS+=(--include=ca-certificates) 18 | BOOTSTRAP_ARGS+=("$@") 19 | printf -v BOOTSTRAP_STR '%q ' "${BOOTSTRAP_ARGS[@]}" 20 | 21 | capsh $CAPSH_ARG -- -c "'${BOOTSTRAP_CMD}' $BOOTSTRAP_STR" || true 22 | 23 | if [ -d "$2/debootstrap" ] && ! rmdir "$2/debootstrap"; then 24 | cp "$2/debootstrap/debootstrap.log" "${STAGE_WORK_DIR}" 25 | log "bootstrap failed: please check ${STAGE_WORK_DIR}/debootstrap.log" 26 | return 1 27 | fi 28 | } 29 | export -f bootstrap 30 | 31 | copy_previous(){ 32 | if [ ! -d "${PREV_ROOTFS_DIR}" ]; then 33 | echo "Previous stage rootfs not found" 34 | false 35 | fi 36 | mkdir -p "${ROOTFS_DIR}" 37 | rsync -aHAXx --exclude var/cache/apt/archives "${PREV_ROOTFS_DIR}/" "${ROOTFS_DIR}/" 38 | } 39 | export -f copy_previous 40 | 41 | unmount(){ 42 | if [ -z "$1" ]; then 43 | DIR=$PWD 44 | else 45 | DIR=$1 46 | fi 47 | 48 | while mount | grep -q "$DIR"; do 49 | local LOCS 50 | LOCS=$(mount | grep "$DIR" | cut -f 3 -d ' ' | sort -r) 51 | for loc in $LOCS; do 52 | umount "$loc" 53 | done 54 | done 55 | } 56 | export -f unmount 57 | 58 | unmount_image(){ 59 | sync 60 | sleep 1 61 | LOOP_DEVICE=$(losetup --list | grep "$1" | cut -f1 -d' ') 62 | if [ -n "$LOOP_DEVICE" ]; then 63 | for part in "$LOOP_DEVICE"p*; do 64 | if DIR=$(findmnt -n -o target -S "$part"); then 65 | unmount "$DIR" 66 | fi 67 | done 68 | losetup -d "$LOOP_DEVICE" 69 | fi 70 | } 71 | export -f unmount_image 72 | 73 | on_chroot() { 74 | if ! mount | grep -q "$(realpath "${ROOTFS_DIR}"/proc)"; then 75 | mount -t proc proc "${ROOTFS_DIR}/proc" 76 | fi 77 | 78 | if ! mount | grep -q "$(realpath "${ROOTFS_DIR}"/dev)"; then 79 | mount --bind /dev "${ROOTFS_DIR}/dev" 80 | fi 81 | 82 | if ! mount | grep -q "$(realpath "${ROOTFS_DIR}"/dev/pts)"; then 83 | mount --bind /dev/pts "${ROOTFS_DIR}/dev/pts" 84 | fi 85 | 86 | if ! mount | grep -q "$(realpath "${ROOTFS_DIR}"/sys)"; then 87 | mount --bind /sys "${ROOTFS_DIR}/sys" 88 | fi 89 | 90 | capsh $CAPSH_ARG "--chroot=${ROOTFS_DIR}/" -- -e "$@" 91 | } 92 | export -f on_chroot 93 | 94 | update_issue() { 95 | echo -e "Raspberry Pi reference ${IMG_DATE}\nGenerated using ${PI_GEN}, ${PI_GEN_REPO}, ${GIT_HASH}, ${1}" > "${ROOTFS_DIR}/etc/rpi-issue" 96 | } 97 | export -f update_issue 98 | -------------------------------------------------------------------------------- /pi-gen/scripts/dependencies_check: -------------------------------------------------------------------------------- 1 | # dependencies_check 2 | # $@ Dependency files to check 3 | # 4 | # Each dependency is in the form of a tool to test for, optionally followed by 5 | # a : and the name of a package if the package on a Debian-ish system is not 6 | # named for the tool (i.e., qemu-user-static). 7 | dependencies_check() 8 | { 9 | local depfile deps missing 10 | 11 | for depfile in "$@"; do 12 | if [[ -e "$depfile" ]]; then 13 | deps="$(sed -f "${SCRIPT_DIR}/remove-comments.sed" < "${BASE_DIR}/depends")" 14 | 15 | fi 16 | for dep in $deps; do 17 | if ! hash "${dep%:*}" 2>/dev/null; then 18 | missing="${missing:+$missing }${dep#*:}" 19 | fi 20 | done 21 | done 22 | 23 | if [[ "$missing" ]]; then 24 | echo "Required dependencies not installed" 25 | echo 26 | echo "This can be resolved on Debian/Raspbian systems by installing:" 27 | echo "$missing" 28 | false 29 | fi 30 | 31 | # If we're building on a native arm platform, we don't need to check for 32 | # binfmt_misc or require it to be loaded. 33 | 34 | binfmt_misc_required=1 35 | 36 | case $(uname -m) in 37 | aarch64) 38 | binfmt_misc_required=0 39 | ;; 40 | arm*) 41 | binfmt_misc_required=0 42 | ;; 43 | esac 44 | 45 | if [[ "${binfmt_misc_required}" == "1" ]]; then 46 | if ! grep -q "/proc/sys/fs/binfmt_misc" /proc/mounts; then 47 | echo "Module binfmt_misc not loaded in host" 48 | echo "Please run:" 49 | echo " sudo modprobe binfmt_misc" 50 | exit 1 51 | fi 52 | fi 53 | } 54 | -------------------------------------------------------------------------------- /pi-gen/scripts/remove-comments.sed: -------------------------------------------------------------------------------- 1 | # Deletes comments and collapses whitespace in ##-packages files 2 | 3 | # Append (N)ext line to buffer 4 | # if (!)not ($)buffer is EOF, (b)ranch to (:)label loop 5 | :loop 6 | N 7 | $ !b loop 8 | 9 | # Buffer is "line1\nline2\n...lineN", del comments and collapse whitespace 10 | s/#[^\n]*//g 11 | s/[[:space:]]\{1,\}/ /g 12 | -------------------------------------------------------------------------------- /pi-gen/stage0/00-configure-apt/00-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | install -m 644 files/sources.list "${ROOTFS_DIR}/etc/apt/" 4 | install -m 644 files/raspi.list "${ROOTFS_DIR}/etc/apt/sources.list.d/" 5 | sed -i "s/RELEASE/${RELEASE}/g" "${ROOTFS_DIR}/etc/apt/sources.list" 6 | sed -i "s/RELEASE/${RELEASE}/g" "${ROOTFS_DIR}/etc/apt/sources.list.d/raspi.list" 7 | 8 | if [ -n "$APT_PROXY" ]; then 9 | install -m 644 files/51cache "${ROOTFS_DIR}/etc/apt/apt.conf.d/51cache" 10 | sed "${ROOTFS_DIR}/etc/apt/apt.conf.d/51cache" -i -e "s|APT_PROXY|${APT_PROXY}|" 11 | else 12 | rm -f "${ROOTFS_DIR}/etc/apt/apt.conf.d/51cache" 13 | fi 14 | 15 | cat files/raspberrypi.gpg.key | gpg --dearmor > "${ROOTFS_DIR}/etc/apt/trusted.gpg.d/raspberrypi-archive-stable.gpg" 16 | on_chroot << EOF 17 | dpkg --add-architecture armhf 18 | apt-get update 19 | apt-get dist-upgrade -y 20 | EOF 21 | -------------------------------------------------------------------------------- /pi-gen/stage0/00-configure-apt/01-packages: -------------------------------------------------------------------------------- 1 | raspberrypi-archive-keyring 2 | -------------------------------------------------------------------------------- /pi-gen/stage0/00-configure-apt/files/51cache: -------------------------------------------------------------------------------- 1 | Acquire::http { Proxy "APT_PROXY"; }; 2 | -------------------------------------------------------------------------------- /pi-gen/stage0/00-configure-apt/files/raspberrypi.gpg.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | Version: GnuPG v1.4.12 (GNU/Linux) 3 | 4 | mQENBE/d7o8BCACrwqQacGJfn3tnMzGui6mv2lLxYbsOuy/+U4rqMmGEuo3h9m92 5 | 30E2EtypsoWczkBretzLUCFv+VUOxaA6sV9+puTqYGhhQZFuKUWcG7orf7QbZRuu 6 | TxsEUepW5lg7MExmAu1JJzqM0kMQX8fVyWVDkjchZ/is4q3BPOUCJbUJOsE+kK/6 7 | 8kW6nWdhwSAjfDh06bA5wvoXNjYoDdnSZyVdcYCPEJXEg5jfF/+nmiFKMZBraHwn 8 | eQsepr7rBXxNcEvDlSOPal11fg90KXpy7Umre1UcAZYJdQeWcHu7X5uoJx/MG5J8 9 | ic6CwYmDaShIFa92f8qmFcna05+lppk76fsnABEBAAG0IFJhc3BiZXJyeSBQaSBB 10 | cmNoaXZlIFNpZ25pbmcgS2V5iQE4BBMBAgAiBQJP3e6PAhsDBgsJCAcDAgYVCAIJ 11 | CgsEFgIDAQIeAQIXgAAKCRCCsSmSf6MwPk6vB/9pePB3IukU9WC9Bammh3mpQTvL 12 | OifbkzHkmAYxzjfK6D2I8pT0xMxy949+ThzJ7uL60p6T/32ED9DR3LHIMXZvKtuc 13 | mQnSiNDX03E2p7lIP/htoxW2hDP2n8cdlNdt0M9IjaWBppsbO7IrDppG2B1aRLni 14 | uD7v8bHRL2mKTtIDLX42Enl8aLAkJYgNWpZyPkDyOqamjijarIWjGEPCkaURF7g4 15 | d44HvYhpbLMOrz1m6N5Bzoa5+nq3lmifeiWKxioFXU+Hy5bhtAM6ljVb59hbD2ra 16 | X4+3LXC9oox2flmQnyqwoyfZqVgSQa0B41qEQo8t1bz6Q1Ti7fbMLThmbRHiuQEN 17 | BE/d7o8BCADNlVtBZU63fm79SjHh5AEKFs0C3kwa0mOhp9oas/haDggmhiXdzeD3 18 | 49JWz9ZTx+vlTq0s+I+nIR1a+q+GL+hxYt4HhxoA6vlDMegVfvZKzqTX9Nr2VqQa 19 | S4Kz3W5ULv81tw3WowK6i0L7pqDmvDqgm73mMbbxfHD0SyTt8+fk7qX6Ag2pZ4a9 20 | ZdJGxvASkh0McGpbYJhk1WYD+eh4fqH3IaeJi6xtNoRdc5YXuzILnp+KaJyPE5CR 21 | qUY5JibOD3qR7zDjP0ueP93jLqmoKltCdN5+yYEExtSwz5lXniiYOJp8LWFCgv5h 22 | m8aYXkcJS1xVV9Ltno23YvX5edw9QY4hABEBAAGJAR8EGAECAAkFAk/d7o8CGwwA 23 | CgkQgrEpkn+jMD5Figf/dIC1qtDMTbu5IsI5uZPX63xydaExQNYf98cq5H2fWF6O 24 | yVR7ERzA2w33hI0yZQrqO6pU9SRnHRxCFvGv6y+mXXXMRcmjZG7GiD6tQWeN/3wb 25 | EbAn5cg6CJ/Lk/BI4iRRfBX07LbYULCohlGkwBOkRo10T+Ld4vCCnBftCh5x2OtZ 26 | TOWRULxP36y2PLGVNF+q9pho98qx+RIxvpofQM/842ZycjPJvzgVQsW4LT91KYAE 27 | 4TVf6JjwUM6HZDoiNcX6d7zOhNfQihXTsniZZ6rky287htsWVDNkqOi5T3oTxWUo 28 | m++/7s3K3L0zWopdhMVcgg6Nt9gcjzqN1c0gy55L/g== 29 | =mNSj 30 | -----END PGP PUBLIC KEY BLOCK----- 31 | -------------------------------------------------------------------------------- /pi-gen/stage0/00-configure-apt/files/raspi.list: -------------------------------------------------------------------------------- 1 | deb http://archive.raspberrypi.org/debian/ RELEASE main 2 | # Uncomment line below then 'apt-get update' to enable 'apt-get source' 3 | #deb-src http://archive.raspberrypi.org/debian/ RELEASE main 4 | -------------------------------------------------------------------------------- /pi-gen/stage0/00-configure-apt/files/sources.list: -------------------------------------------------------------------------------- 1 | deb http://deb.debian.org/debian RELEASE main contrib non-free 2 | deb http://security.debian.org/debian-security RELEASE-security main contrib non-free 3 | deb http://deb.debian.org/debian RELEASE-updates main contrib non-free 4 | # Uncomment deb-src lines below then 'apt-get update' to enable 'apt-get source' 5 | #deb-src http://deb.debian.org/debian RELEASE main contrib non-free 6 | #deb-src http://security.debian.org/debian-security RELEASE-security main contrib non-free 7 | #deb-src http://deb.debian.org/debian RELEASE-updates main contrib non-free 8 | -------------------------------------------------------------------------------- /pi-gen/stage0/01-locale/00-packages: -------------------------------------------------------------------------------- 1 | locales 2 | -------------------------------------------------------------------------------- /pi-gen/stage0/02-firmware/01-packages: -------------------------------------------------------------------------------- 1 | raspberrypi-bootloader 2 | raspberrypi-kernel 3 | -------------------------------------------------------------------------------- /pi-gen/stage0/files/raspberrypi.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/p4lang/p4pi/2a6e90f30e5346ecab543d0fdd5a2fb006ee4e07/pi-gen/stage0/files/raspberrypi.gpg -------------------------------------------------------------------------------- /pi-gen/stage0/prerun.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | if [ "$RELEASE" != "bullseye" ]; then 4 | echo "WARNING: RELEASE does not match the intended option for this branch." 5 | echo " Please check the relevant README.md section." 6 | fi 7 | 8 | if [ ! -d "${ROOTFS_DIR}" ] || [ "${USE_QCOW2}" = "1" ]; then 9 | bootstrap ${RELEASE} "${ROOTFS_DIR}" http://deb.debian.org/debian/ 10 | fi 11 | -------------------------------------------------------------------------------- /pi-gen/stage1/00-boot-files/00-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | install -m 644 files/cmdline.txt "${ROOTFS_DIR}/boot/" 4 | install -m 644 files/config.txt "${ROOTFS_DIR}/boot/" 5 | -------------------------------------------------------------------------------- /pi-gen/stage1/00-boot-files/files/cmdline.txt: -------------------------------------------------------------------------------- 1 | console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 fsck.repair=yes rootwait 2 | -------------------------------------------------------------------------------- /pi-gen/stage1/00-boot-files/files/config.txt: -------------------------------------------------------------------------------- 1 | # For more options and information see 2 | # http://rpf.io/configtxt 3 | # Some settings may impact device functionality. See link above for details 4 | 5 | # uncomment if you get no picture on HDMI for a default "safe" mode 6 | #hdmi_safe=1 7 | 8 | # uncomment the following to adjust overscan. Use positive numbers if console 9 | # goes off screen, and negative if there is too much border 10 | #overscan_left=16 11 | #overscan_right=16 12 | #overscan_top=16 13 | #overscan_bottom=16 14 | 15 | # uncomment to force a console size. By default it will be display's size minus 16 | # overscan. 17 | #framebuffer_width=1280 18 | #framebuffer_height=720 19 | 20 | # uncomment if hdmi display is not detected and composite is being output 21 | #hdmi_force_hotplug=1 22 | 23 | # uncomment to force a specific HDMI mode (this will force VGA) 24 | #hdmi_group=1 25 | #hdmi_mode=1 26 | 27 | # uncomment to force a HDMI mode rather than DVI. This can make audio work in 28 | # DMT (computer monitor) modes 29 | #hdmi_drive=2 30 | 31 | # uncomment to increase signal to HDMI, if you have interference, blanking, or 32 | # no display 33 | #config_hdmi_boost=4 34 | 35 | # uncomment for composite PAL 36 | #sdtv_mode=2 37 | 38 | #uncomment to overclock the arm. 700 MHz is the default. 39 | #arm_freq=800 40 | 41 | # Uncomment some or all of these to enable the optional hardware interfaces 42 | #dtparam=i2c_arm=on 43 | #dtparam=i2s=on 44 | #dtparam=spi=on 45 | 46 | # Uncomment this to enable infrared communication. 47 | #dtoverlay=gpio-ir,gpio_pin=17 48 | #dtoverlay=gpio-ir-tx,gpio_pin=18 49 | 50 | # Additional overlays and parameters are documented /boot/overlays/README 51 | 52 | # Enable audio (loads snd_bcm2835) 53 | dtparam=audio=on 54 | 55 | # Automatically load overlays for detected cameras 56 | camera_auto_detect=1 57 | 58 | # Automatically load overlays for detected DSI displays 59 | display_auto_detect=1 60 | 61 | # Enable DRM VC4 V3D driver 62 | dtoverlay=vc4-kms-v3d 63 | max_framebuffers=2 64 | 65 | # Run in 64-bit mode 66 | arm_64bit=1 67 | 68 | # Disable compensation for displays with overscan 69 | disable_overscan=1 70 | 71 | [cm4] 72 | # Enable host mode on the 2711 built-in XHCI USB controller. 73 | # This line should be removed if the legacy DWC2 controller is required 74 | # (e.g. for USB device mode) or if USB support is not required. 75 | otg_mode=1 76 | 77 | [all] 78 | 79 | [pi4] 80 | # Run as fast as firmware / board allows 81 | arm_boost=1 82 | 83 | [all] 84 | -------------------------------------------------------------------------------- /pi-gen/stage1/01-sys-tweaks/00-packages: -------------------------------------------------------------------------------- 1 | raspi-config 2 | -------------------------------------------------------------------------------- /pi-gen/stage1/01-sys-tweaks/00-patches/01-bashrc.diff: -------------------------------------------------------------------------------- 1 | --- a/rootfs/etc/skel/.bashrc 2 | +++ b/rootfs/etc/skel/.bashrc 3 | @@ -43,7 +43,7 @@ 4 | # uncomment for a colored prompt, if the terminal has the capability; turned 5 | # off by default to not distract the user: the focus in a terminal window 6 | # should be on the output of commands, not on the prompt 7 | -#force_color_prompt=yes 8 | +force_color_prompt=yes 9 | 10 | if [ -n "$force_color_prompt" ]; then 11 | if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then 12 | @@ -57,7 +57,7 @@ 13 | fi 14 | 15 | if [ "$color_prompt" = yes ]; then 16 | - PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' 17 | + PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w \$\[\033[00m\] ' 18 | else 19 | PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' 20 | fi 21 | @@ -79,9 +79,9 @@ 22 | #alias dir='dir --color=auto' 23 | #alias vdir='vdir --color=auto' 24 | 25 | - #alias grep='grep --color=auto' 26 | - #alias fgrep='fgrep --color=auto' 27 | - #alias egrep='egrep --color=auto' 28 | + alias grep='grep --color=auto' 29 | + alias fgrep='fgrep --color=auto' 30 | + alias egrep='egrep --color=auto' 31 | fi 32 | 33 | # colored GCC warnings and errors 34 | -------------------------------------------------------------------------------- /pi-gen/stage1/01-sys-tweaks/00-patches/series: -------------------------------------------------------------------------------- 1 | 01-bashrc.diff 2 | -------------------------------------------------------------------------------- /pi-gen/stage1/01-sys-tweaks/00-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | install -d "${ROOTFS_DIR}/etc/systemd/system/getty@tty1.service.d" 4 | install -m 644 files/noclear.conf "${ROOTFS_DIR}/etc/systemd/system/getty@tty1.service.d/noclear.conf" 5 | install -v -m 644 files/fstab "${ROOTFS_DIR}/etc/fstab" 6 | 7 | on_chroot << EOF 8 | if ! id -u ${FIRST_USER_NAME} >/dev/null 2>&1; then 9 | adduser --disabled-password --gecos "" ${FIRST_USER_NAME} 10 | fi 11 | 12 | if [ -n "${FIRST_USER_PASS}" ]; then 13 | echo "${FIRST_USER_NAME}:${FIRST_USER_PASS}" | chpasswd 14 | fi 15 | echo "root:root" | chpasswd 16 | EOF 17 | 18 | 19 | -------------------------------------------------------------------------------- /pi-gen/stage1/01-sys-tweaks/files/fstab: -------------------------------------------------------------------------------- 1 | proc /proc proc defaults 0 0 2 | BOOTDEV /boot vfat defaults 0 2 3 | ROOTDEV / ext4 defaults,noatime 0 1 4 | -------------------------------------------------------------------------------- /pi-gen/stage1/01-sys-tweaks/files/noclear.conf: -------------------------------------------------------------------------------- 1 | [Service] 2 | TTYVTDisallocate=no 3 | -------------------------------------------------------------------------------- /pi-gen/stage1/02-net-tweaks/00-packages: -------------------------------------------------------------------------------- 1 | netbase 2 | -------------------------------------------------------------------------------- /pi-gen/stage1/02-net-tweaks/00-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | echo "${TARGET_HOSTNAME}" > "${ROOTFS_DIR}/etc/hostname" 4 | echo "127.0.1.1 ${TARGET_HOSTNAME}" >> "${ROOTFS_DIR}/etc/hosts" 5 | 6 | on_chroot << EOF 7 | SUDO_USER="${FIRST_USER_NAME}" raspi-config nonint do_net_names 1 8 | EOF 9 | -------------------------------------------------------------------------------- /pi-gen/stage1/03-install-packages/00-packages: -------------------------------------------------------------------------------- 1 | libraspberrypi-bin libraspberrypi0 2 | systemd-timesyncd 3 | -------------------------------------------------------------------------------- /pi-gen/stage1/prerun.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | if [ ! -d "${ROOTFS_DIR}" ]; then 4 | copy_previous 5 | fi 6 | -------------------------------------------------------------------------------- /pi-gen/stage2/01-sys-tweaks/00-packages: -------------------------------------------------------------------------------- 1 | ssh less fbset sudo psmisc strace ed ncdu crda 2 | console-setup keyboard-configuration debconf-utils parted 3 | build-essential manpages-dev bash-completion gdb pkg-config 4 | python-is-python3 5 | python3-rpi.gpio v4l-utils 6 | python3-gpiozero 7 | avahi-daemon 8 | lua5.1 9 | luajit 10 | hardlink ca-certificates curl 11 | fake-hwclock nfs-common usbutils 12 | libraspberrypi-dev libraspberrypi-doc libfreetype6-dev 13 | dosfstools 14 | dphys-swapfile 15 | raspberrypi-sys-mods 16 | pi-bluetooth 17 | apt-listchanges 18 | usb-modeswitch 19 | libpam-chksshpwd 20 | rpi-update 21 | libmtp-runtime 22 | rsync 23 | htop 24 | man-db 25 | policykit-1 26 | ssh-import-id 27 | rng-tools 28 | ethtool 29 | ntfs-3g 30 | pciutils 31 | rpi-eeprom 32 | raspinfo 33 | udisks2 34 | unzip zip p7zip-full 35 | file 36 | kms++-utils 37 | -------------------------------------------------------------------------------- /pi-gen/stage2/01-sys-tweaks/00-packages-nr: -------------------------------------------------------------------------------- 1 | cifs-utils 2 | libcamera-apps-lite 3 | mkvtoolnix 4 | python3-picamera2 5 | -------------------------------------------------------------------------------- /pi-gen/stage2/01-sys-tweaks/00-patches/01-useradd.diff: -------------------------------------------------------------------------------- 1 | Index: jessie-stage2/rootfs/etc/default/useradd 2 | =================================================================== 3 | --- jessie-stage2.orig/rootfs/etc/default/useradd 4 | +++ jessie-stage2/rootfs/etc/default/useradd 5 | @@ -5,7 +5,7 @@ 6 | # Similar to DHSELL in adduser. However, we use "sh" here because 7 | # useradd is a low level utility and should be as general 8 | # as possible 9 | -SHELL=/bin/sh 10 | +SHELL=/bin/bash 11 | # 12 | # The default group for users 13 | # 100=users on Debian systems 14 | @@ -29,7 +29,7 @@ SHELL=/bin/sh 15 | # The SKEL variable specifies the directory containing "skeletal" user 16 | # files; in other words, files such as a sample .profile that will be 17 | # copied to the new user's home directory when it is created. 18 | -# SKEL=/etc/skel 19 | +SKEL=/etc/skel 20 | # 21 | # Defines whether the mail spool should be created while 22 | # creating the account 23 | -------------------------------------------------------------------------------- /pi-gen/stage2/01-sys-tweaks/00-patches/02-swap.diff: -------------------------------------------------------------------------------- 1 | Index: jessie-stage2/rootfs/etc/dphys-swapfile 2 | =================================================================== 3 | --- jessie-stage2.orig/rootfs/etc/dphys-swapfile 4 | +++ jessie-stage2/rootfs/etc/dphys-swapfile 5 | @@ -13,7 +13,7 @@ 6 | 7 | # set size to absolute value, leaving empty (default) then uses computed value 8 | # you most likely don't want this, unless you have an special disk situation 9 | -#CONF_SWAPSIZE= 10 | +CONF_SWAPSIZE=100 11 | 12 | # set size to computed value, this times RAM size, dynamically adapts, 13 | # guarantees that there is enough swap without wasting disk space on excess 14 | -------------------------------------------------------------------------------- /pi-gen/stage2/01-sys-tweaks/00-patches/04-inputrc.diff: -------------------------------------------------------------------------------- 1 | Index: jessie-stage2/rootfs/etc/inputrc 2 | =================================================================== 3 | --- jessie-stage2.orig/rootfs/etc/inputrc 4 | +++ jessie-stage2/rootfs/etc/inputrc 5 | @@ -65,3 +65,7 @@ $endif 6 | # "\e[F": end-of-line 7 | 8 | $endif 9 | + 10 | +# mappings for up and down arrows search history 11 | +# "\e[B": history-search-forward 12 | +# "\e[A": history-search-backward 13 | -------------------------------------------------------------------------------- /pi-gen/stage2/01-sys-tweaks/00-patches/05-path.diff: -------------------------------------------------------------------------------- 1 | Index: jessie-stage2/rootfs/etc/login.defs 2 | =================================================================== 3 | --- jessie-stage2.orig/rootfs/etc/login.defs 4 | +++ jessie-stage2/rootfs/etc/login.defs 5 | @@ -100,7 +100,7 @@ HUSHLOGIN_FILE .hushlogin 6 | # 7 | # (they are minimal, add the rest in the shell startup files) 8 | ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 9 | -ENV_PATH PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games 10 | +ENV_PATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games 11 | 12 | # 13 | # Terminal permissions 14 | Index: jessie-stage2/rootfs/etc/profile 15 | =================================================================== 16 | --- jessie-stage2.orig/rootfs/etc/profile 17 | +++ jessie-stage2/rootfs/etc/profile 18 | @@ -4,7 +4,7 @@ 19 | if [ "`id -u`" -eq 0 ]; then 20 | PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 21 | else 22 | - PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games" 23 | + PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games" 24 | fi 25 | export PATH 26 | 27 | -------------------------------------------------------------------------------- /pi-gen/stage2/01-sys-tweaks/00-patches/07-resize-init.diff: -------------------------------------------------------------------------------- 1 | --- stage2.orig/rootfs/boot/cmdline.txt 2 | +++ stage2/rootfs/boot/cmdline.txt 3 | @@ -1 +1 @@ 4 | -console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 fsck.repair=yes rootwait 5 | +console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 fsck.repair=yes rootwait quiet init=/usr/lib/raspberrypi-sys-mods/firstboot 6 | -------------------------------------------------------------------------------- /pi-gen/stage2/01-sys-tweaks/00-patches/series: -------------------------------------------------------------------------------- 1 | 01-useradd.diff 2 | 02-swap.diff 3 | 04-inputrc.diff 4 | 05-path.diff 5 | 07-resize-init.diff 6 | -------------------------------------------------------------------------------- /pi-gen/stage2/01-sys-tweaks/01-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | install -m 755 files/resize2fs_once "${ROOTFS_DIR}/etc/init.d/" 4 | 5 | install -d "${ROOTFS_DIR}/etc/systemd/system/rc-local.service.d" 6 | install -m 644 files/ttyoutput.conf "${ROOTFS_DIR}/etc/systemd/system/rc-local.service.d/" 7 | 8 | install -m 644 files/50raspi "${ROOTFS_DIR}/etc/apt/apt.conf.d/" 9 | 10 | install -m 644 files/console-setup "${ROOTFS_DIR}/etc/default/" 11 | 12 | install -m 755 files/rc.local "${ROOTFS_DIR}/etc/" 13 | 14 | if [ -n "${PUBKEY_SSH_FIRST_USER}" ]; then 15 | install -v -m 0700 -o 1000 -g 1000 -d "${ROOTFS_DIR}"/home/"${FIRST_USER_NAME}"/.ssh 16 | echo "${PUBKEY_SSH_FIRST_USER}" >"${ROOTFS_DIR}"/home/"${FIRST_USER_NAME}"/.ssh/authorized_keys 17 | chown 1000:1000 "${ROOTFS_DIR}"/home/"${FIRST_USER_NAME}"/.ssh/authorized_keys 18 | chmod 0600 "${ROOTFS_DIR}"/home/"${FIRST_USER_NAME}"/.ssh/authorized_keys 19 | fi 20 | 21 | if [ "${PUBKEY_ONLY_SSH}" = "1" ]; then 22 | sed -i -Ee 's/^#?[[:blank:]]*PubkeyAuthentication[[:blank:]]*no[[:blank:]]*$/PubkeyAuthentication yes/ 23 | s/^#?[[:blank:]]*PasswordAuthentication[[:blank:]]*yes[[:blank:]]*$/PasswordAuthentication no/' "${ROOTFS_DIR}"/etc/ssh/sshd_config 24 | fi 25 | 26 | on_chroot << EOF 27 | systemctl disable hwclock.sh 28 | systemctl disable nfs-common 29 | systemctl disable rpcbind 30 | if [ "${ENABLE_SSH}" == "1" ]; then 31 | systemctl enable ssh 32 | else 33 | systemctl disable ssh 34 | fi 35 | systemctl enable regenerate_ssh_host_keys 36 | EOF 37 | 38 | if [ "${USE_QEMU}" = "1" ]; then 39 | echo "enter QEMU mode" 40 | install -m 644 files/90-qemu.rules "${ROOTFS_DIR}/etc/udev/rules.d/" 41 | on_chroot << EOF 42 | systemctl disable resize2fs_once 43 | EOF 44 | echo "leaving QEMU mode" 45 | else 46 | on_chroot << EOF 47 | systemctl enable resize2fs_once 48 | EOF 49 | fi 50 | 51 | on_chroot <&2 23 | exit 3 24 | ;; 25 | esac 26 | -------------------------------------------------------------------------------- /pi-gen/stage2/01-sys-tweaks/files/ttyoutput.conf: -------------------------------------------------------------------------------- 1 | [Service] 2 | StandardOutput=tty 3 | -------------------------------------------------------------------------------- /pi-gen/stage2/02-net-tweaks/00-packages: -------------------------------------------------------------------------------- 1 | wpasupplicant wireless-tools firmware-atheros firmware-brcm80211 firmware-libertas firmware-misc-nonfree firmware-realtek 2 | raspberrypi-net-mods 3 | dhcpcd5 4 | network-manager 5 | net-tools 6 | -------------------------------------------------------------------------------- /pi-gen/stage2/02-net-tweaks/01-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | install -v -d "${ROOTFS_DIR}/etc/wpa_supplicant" 4 | install -v -m 600 files/wpa_supplicant.conf "${ROOTFS_DIR}/etc/wpa_supplicant/" 5 | 6 | on_chroot << EOF 7 | SUDO_USER="${FIRST_USER_NAME}" raspi-config nonint do_boot_wait 0 8 | SUDO_USER="${FIRST_USER_NAME}" raspi-config nonint do_netconf 1 9 | EOF 10 | 11 | if [ -v WPA_COUNTRY ]; then 12 | on_chroot <<- EOF 13 | SUDO_USER="${FIRST_USER_NAME}" raspi-config nonint do_wifi_country "${WPA_COUNTRY}" 14 | EOF 15 | fi 16 | 17 | if [ -v WPA_ESSID ] && [ -v WPA_PASSWORD ]; then 18 | on_chroot <> "${ROOTFS_DIR}/etc/wpa_supplicant/wpa_supplicant.conf" << EOL 24 | 25 | network={ 26 | ssid="${WPA_ESSID}" 27 | key_mgmt=NONE 28 | } 29 | EOL 30 | fi 31 | 32 | # Disable wifi on 5GHz models if WPA_COUNTRY is not set 33 | mkdir -p "${ROOTFS_DIR}/var/lib/systemd/rfkill/" 34 | if [ -n "$WPA_COUNTRY" ]; then 35 | echo 0 > "${ROOTFS_DIR}/var/lib/systemd/rfkill/platform-3f300000.mmcnr:wlan" 36 | echo 0 > "${ROOTFS_DIR}/var/lib/systemd/rfkill/platform-fe300000.mmcnr:wlan" 37 | else 38 | echo 1 > "${ROOTFS_DIR}/var/lib/systemd/rfkill/platform-3f300000.mmcnr:wlan" 39 | echo 1 > "${ROOTFS_DIR}/var/lib/systemd/rfkill/platform-fe300000.mmcnr:wlan" 40 | fi 41 | -------------------------------------------------------------------------------- /pi-gen/stage2/02-net-tweaks/files/wpa_supplicant.conf: -------------------------------------------------------------------------------- 1 | ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev 2 | update_config=1 3 | -------------------------------------------------------------------------------- /pi-gen/stage2/03-set-timezone/02-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | echo "${TIMEZONE_DEFAULT}" > "${ROOTFS_DIR}/etc/timezone" 4 | rm "${ROOTFS_DIR}/etc/localtime" 5 | 6 | on_chroot << EOF 7 | dpkg-reconfigure -f noninteractive tzdata 8 | EOF 9 | -------------------------------------------------------------------------------- /pi-gen/stage2/prerun.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | if [ ! -d "${ROOTFS_DIR}" ]; then 4 | copy_previous 5 | fi 6 | -------------------------------------------------------------------------------- /pi-gen/stage3/01-p4pi/00-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | # Display logo on TTY login 4 | install -m 644 files/motd "${ROOTFS_DIR}/etc/" 5 | 6 | on_chroot << EOF 7 | echo 'deb [signed-by=/usr/share/keyrings/p4pi-kernel-archive-keyring.gpg] http://download.opensuse.org/repositories/home:/p4pi:/kernel/Raspbian_11/ /' | tee /etc/apt/sources.list.d/p4pi-kernel.list 8 | curl -fsSL https://download.opensuse.org/repositories/home:p4pi:/kernel/Raspbian_11/Release.key | gpg --dearmor > /usr/share/keyrings/p4pi-kernel-archive-keyring.gpg 9 | 10 | echo 'deb [signed-by=/usr/share/keyrings/p4edge-p4lang-testing-archive-keyring.gpg] http://download.opensuse.org/repositories/home:/p4edge:/p4lang-testing/Raspbian_11/ /' | tee /etc/apt/sources.list.d/p4edge-p4lang-testing.list 11 | curl -fsSL https://download.opensuse.org/repositories/home:/p4edge:/p4lang-testing/Raspbian_11/Release.key | gpg --dearmor > /usr/share/keyrings/p4edge-p4lang-testing-archive-keyring.gpg 12 | 13 | echo 'deb [signed-by=/usr/share/keyrings/p4edge-archive-keyring.gpg] http://download.opensuse.org/repositories/home:/p4edge/Raspbian_11/ /' | tee /etc/apt/sources.list.d/p4edge.list 14 | curl -fsSL https://download.opensuse.org/repositories/home:/p4edge/Raspbian_11/Release.key | gpg --dearmor > /usr/share/keyrings/p4edge-archive-keyring.gpg 15 | 16 | echo 'deb [signed-by=/usr/share/keyrings/p4pi-archive-keyring.gpg] http://download.opensuse.org/repositories/home:/p4pi/Raspbian_11/ /' | tee /etc/apt/sources.list.d/p4pi.list 17 | curl -fsSL https://download.opensuse.org/repositories/home:/p4pi/Raspbian_11/Release.key | gpg --dearmor > /usr/share/keyrings/p4pi-archive-keyring.gpg 18 | 19 | # echo 'deb [signed-by=/usr/share/keyrings/p4pi-unstable-archive-keyring.gpg] http://download.opensuse.org/repositories/home:/p4pi:/unstable/Raspbian_11/ /' | tee /etc/apt/sources.list.d/p4pi-unstable.list 20 | # curl -fsSL https://download.opensuse.org/repositories/home:/p4pi:/unstable/Raspbian_11/Release.key | gpg --dearmor > /usr/share/keyrings/p4pi-unstable-archive-keyring.gpg 21 | 22 | apt-get -y update 23 | 24 | wget https://raw.githubusercontent.com/p4lang/behavioral-model/main/tools/p4dbg.py 25 | mv p4dbg.py /usr/lib/python3/dist-packages/ 26 | EOF 27 | -------------------------------------------------------------------------------- /pi-gen/stage3/01-p4pi/01-packages: -------------------------------------------------------------------------------- 1 | p4lang-pi 2 | p4lang-p4c 3 | p4lang-bmv2 4 | p4edge-t4p4s 5 | p4pi-linux-headers-5.15.84-v8-p4pi 6 | p4pi-linux-image-5.15.84-v8-p4pi 7 | p4pi-examples 8 | p4pi-web 9 | git 10 | vim 11 | tmux 12 | bridge-utils 13 | iperf 14 | dpdk-kmods-dkms 15 | -------------------------------------------------------------------------------- /pi-gen/stage3/01-p4pi/02-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | on_chroot << EOF 4 | mv /boot/vmlinuz-5.15.84-v8-p4pi /boot/p4pi-kernel8.img 5 | echo "kernel=p4pi-kernel8.img" >> /boot/config.txt 6 | EOF 7 | -------------------------------------------------------------------------------- /pi-gen/stage3/02-enable-access-point/00-packages: -------------------------------------------------------------------------------- 1 | hostapd 2 | dnsmasq 3 | netfilter-persistent 4 | iptables-persistent -------------------------------------------------------------------------------- /pi-gen/stage3/02-enable-access-point/00-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | install -m 644 files/dhcpcd.conf "${ROOTFS_DIR}/etc/" 4 | install -m 644 files/dnsmasq.conf "${ROOTFS_DIR}/etc/" 5 | install -m 644 files/p4pi.conf "${ROOTFS_DIR}/etc/dnsmasq.d/" 6 | install -m 644 files/hostapd.conf "${ROOTFS_DIR}/etc/hostapd/" 7 | 8 | install -m 755 files/p4pi-setup-eth-wlan-bridge "${ROOTFS_DIR}/usr/sbin/" 9 | install -m 644 files/p4pi-setup-eth-wlan-bridge.service "${ROOTFS_DIR}/lib/systemd/system/" 10 | 11 | install -m 755 files/p4pi-setup "${ROOTFS_DIR}/usr/sbin/" 12 | install -m 644 files/p4pi-setup.service "${ROOTFS_DIR}/lib/systemd/system/" 13 | 14 | # Switch off binding to port 53 to avoid conflict with dnsmasq 15 | install -m 644 files/resolved.conf "${ROOTFS_DIR}/etc/systemd/" 16 | 17 | on_chroot << EOF 18 | 19 | # Enable IPv4 routing 20 | echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.d/routed-ap.conf 21 | 22 | # Enable access point 23 | systemctl unmask hostapd 24 | systemctl enable hostapd 25 | 26 | # Setup DNS if available 27 | systemctl enable systemd-resolved.service 28 | 29 | # Create and setup interfaces on startup 30 | systemctl enable systemd-networkd.service 31 | systemctl enable p4pi-setup.service 32 | systemctl enable t4p4s.service 33 | 34 | # Enable web UI 35 | systemctl enable p4pi-web 36 | 37 | EOF 38 | -------------------------------------------------------------------------------- /pi-gen/stage3/02-enable-access-point/files/dhcpcd.conf: -------------------------------------------------------------------------------- 1 | # A sample configuration for dhcpcd. 2 | # See dhcpcd.conf(5) for details. 3 | 4 | # denyinterfaces wlan0 eth0 5 | 6 | # Inform the DHCP server of our hostname for DDNS. 7 | #hostname 8 | 9 | # To share the DHCP lease across OSX and Windows a ClientID is needed. 10 | # Enabling this may get a different lease than the kernel DHCP client. 11 | # Some upstream DHCP servers may also require a ClientID, such as FRITZ!Box. 12 | #clientid 13 | 14 | # A list of options to request from the DHCP server. 15 | #option domain_name_servers, domain_name, domain_search, host_name 16 | #option classless_static_routes 17 | 18 | # Most distributions have NTP support. 19 | #option ntp_servers 20 | 21 | # Respect the network MTU. 22 | #option interface_mtu 23 | 24 | # A ServerID is required by RFC2131. 25 | #require dhcp_server_identifier 26 | 27 | # A hook script is provided to lookup the hostname if not set by the DHCP 28 | # server, but it should not be run by default. 29 | #nohook lookup-hostname 30 | 31 | # Staic IP address for WiFi Access Point 32 | interface br0 33 | static ip_address=192.168.4.1/24 34 | nohook wpa_supplicant 35 | -------------------------------------------------------------------------------- /pi-gen/stage3/02-enable-access-point/files/p4pi-setup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # brctl addbr br0 4 | ip netns add gigport 5 | 6 | ip netns exec gigport brctl addbr br1 7 | ip netns exec gigport brctl setageing br1 0 8 | 9 | brctl setageing br0 0 10 | 11 | ip link add dev veth0 type veth peer name veth0-1 12 | ip link add dev veth1 type veth peer name veth1-1 13 | 14 | ip link set dev veth0 address 10:04:00:00:00:00 15 | ip link set dev veth0-1 address 10:04:00:00:00:10 16 | ip link set dev veth1 address 10:04:00:00:10:00 17 | ip link set dev veth1-1 address 10:04:00:00:10:10 18 | 19 | ip link set dev veth0 up 20 | ip link set dev veth1 up 21 | 22 | ip link set dev veth0-1 up 23 | ip link set veth1-1 netns gigport 24 | ip netns exec gigport ip link set dev veth1-1 up 25 | ip netns exec gigport ethtool -K veth1-1 tx off 26 | 27 | ethtool -K veth0 tx off 28 | ethtool -K veth1 tx off 29 | 30 | ethtool -K veth0-1 tx off 31 | 32 | brctl addif br0 veth0-1 33 | ip netns exec gigport brctl addif br1 veth1-1 34 | ip netns exec gigport ip addr add 192.168.4.150/24 dev br1 35 | ip netns exec gigport ip link set dev br1 up 36 | -------------------------------------------------------------------------------- /pi-gen/stage3/02-enable-access-point/files/p4pi-setup-eth-wlan-bridge: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Bridging eth0 and wlan0 through the T4P4S switch." 4 | 5 | myip=`ip addr show eth0 | grep 'inet ' | awk '{print($2);}'` 6 | 7 | if [ "$myip" == "" ] 8 | then 9 | echo "eth0 is connected to a network without DHCP server." 10 | echo "Reconfiguration stopped." 11 | exit -1 12 | fi 13 | 14 | #echo "YOUR NEW MANAGEMENT IP IS $myip" 15 | 16 | echo "Stopping DHCP service" 17 | service dnsmasq stop 18 | 19 | echo "Redirecting veth1 end-point" 20 | ip netns exec gigport ip link set veth1-1 netns 1 21 | ip link set dev veth1-1 up 22 | brctl addbr br2 23 | brctl setageing br2 0 24 | ip link set dev br2 up 25 | 26 | echo "Connecting eth0 to br2" 27 | ip link set eth0 promisc on 28 | brctl addif br2 eth0 29 | brctl addif br2 veth1-1 30 | 31 | echo "Requesting IP for br2 from the external DHCP server" 32 | dhclient br2 33 | 34 | myip=`ip addr show br2 | grep 'inet ' | awk '{print($2);}'` 35 | 36 | echo "Requesting IP for br0 from the external DHCP server" 37 | dhclient br0 38 | ip addr add 192.168.4.101/24 dev br0 39 | 40 | echo "+-------------------------------------------------------------" 41 | echo "| Management IP on the wired interface: $myip" 42 | ip addr show br0 | grep 'inet ' | awk '{printf("| Management IP on the wireless interface: %s\n",$2);}' 43 | echo "+-------------------------------------------------------------" 44 | ifconfig eth0 0.0.0.0 up 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /pi-gen/stage3/02-enable-access-point/files/p4pi-setup-eth-wlan-bridge.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Setup eth wlan bridge for p4pi l2switch example 3 | 4 | [Service] 5 | Type=oneshot 6 | ExecStart=/usr/sbin/p4pi-setup-eth-wlan-bridge 7 | ExecStop= 8 | RemainAfterExit=yes 9 | 10 | [Install] 11 | WantedBy=multi-user.target 12 | -------------------------------------------------------------------------------- /pi-gen/stage3/02-enable-access-point/files/p4pi-setup.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Setup veth and bridge interfaces for packet processing 3 | Requires=systemd-networkd.service 4 | After=network.target dhcpcd.service 5 | 6 | [Service] 7 | ExecStart=/usr/sbin/p4pi-setup 8 | 9 | [Install] 10 | WantedBy=multi-user.target 11 | -------------------------------------------------------------------------------- /pi-gen/stage3/02-enable-access-point/files/p4pi.conf: -------------------------------------------------------------------------------- 1 | resolv-file=/etc/resolv.conf 2 | interface=br0 3 | dhcp-range=set:br0,192.168.4.2,192.168.4.20,255.255.255.0,24h 4 | dhcp-lease-max=160 5 | domain=p4pi 6 | address=/gw.p4pi/192.168.4.1 7 | server=1.1.1.1 8 | -------------------------------------------------------------------------------- /pi-gen/stage3/02-enable-access-point/files/resolved.conf: -------------------------------------------------------------------------------- 1 | # This file is part of systemd. 2 | # 3 | # systemd is free software; you can redistribute it and/or modify it 4 | # under the terms of the GNU Lesser General Public License as published by 5 | # the Free Software Foundation; either version 2.1 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # Entries in this file show the compile time defaults. 9 | # You can change settings by editing this file. 10 | # Defaults can be restored by simply deleting this file. 11 | # 12 | # See resolved.conf(5) for details 13 | 14 | [Resolve] 15 | # Some examples of DNS servers which may be used for DNS= and FallbackDNS=: 16 | # Cloudflare: 1.1.1.1 1.0.0.1 2606:4700:4700::1111 2606:4700:4700::1001 17 | # Google: 8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844 18 | # Quad9: 9.9.9.9 2620:fe::fe 19 | #DNS= 20 | #FallbackDNS= 21 | #Domains= 22 | #DNSSEC=no 23 | #DNSOverTLS=no 24 | #MulticastDNS=yes 25 | #LLMNR=yes 26 | #Cache=yes 27 | DNSStubListener=no 28 | #DNSStubListenerExtra= 29 | #ReadEtcHosts=yes 30 | #ResolveUnicastSingleLabel=no -------------------------------------------------------------------------------- /pi-gen/stage3/EXPORT_IMAGE: -------------------------------------------------------------------------------- 1 | IMG_SUFFIX="-lite" 2 | if [ "${USE_QEMU}" = "1" ]; then 3 | export IMG_SUFFIX="${IMG_SUFFIX}-qemu" 4 | fi 5 | -------------------------------------------------------------------------------- /pi-gen/stage3/prerun.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | if [ ! -d "${ROOTFS_DIR}" ]; then 4 | copy_previous 5 | fi 6 | -------------------------------------------------------------------------------- /vm/.gitignore: -------------------------------------------------------------------------------- 1 | .vagrant/ 2 | -------------------------------------------------------------------------------- /vm/README.md: -------------------------------------------------------------------------------- 1 | # Virtual Machine image for P4Pi 2 | 3 | To build the virtual machine: 4 | 5 | - Install Vagrant and VirtualBox 6 | - Clone the repository 7 | - `cd vm && vagrant up` 8 | -------------------------------------------------------------------------------- /vm/files/dhcpcd.conf: -------------------------------------------------------------------------------- 1 | # A sample configuration for dhcpcd. 2 | # See dhcpcd.conf(5) for details. 3 | 4 | # Inform the DHCP server of our hostname for DDNS. 5 | hostname 6 | 7 | # To share the DHCP lease across OSX and Windows a ClientID is needed. 8 | # Enabling this may get a different lease than the kernel DHCP client. 9 | # Some upstream DHCP servers may also require a ClientID, such as FRITZ!Box. 10 | clientid 11 | 12 | # A list of options to request from the DHCP server. 13 | option domain_name_servers, domain_name, domain_search, host_name 14 | option classless_static_routes 15 | 16 | # Most distributions have NTP support. 17 | option ntp_servers 18 | 19 | # Respect the network MTU. 20 | option interface_mtu 21 | 22 | # A ServerID is required by RFC2131. 23 | require dhcp_server_identifier 24 | 25 | # A hook script is provided to lookup the hostname if not set by the DHCP 26 | # server, but it should not be run by default. 27 | nohook lookup-hostname 28 | 29 | interface br0 30 | static ip_address=192.168.4.1/24 31 | -------------------------------------------------------------------------------- /vm/files/jupyter.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Jupyter Lab Server 3 | 4 | [Service] 5 | Type=simple 6 | ExecStart=/usr/bin/env jupyter lab --ip=0.0.0.0 --port 8888 --LabApp.token='' 7 | WorkingDirectory=/home/pi/jupyter 8 | User=pi 9 | Group=pi 10 | Restart=on-failure 11 | RestartSec=5s 12 | 13 | [Install] 14 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /vm/files/p4pi-setup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | brctl addbr br0 4 | ip netns add gigport 5 | 6 | ip netns exec gigport brctl addbr br1 7 | ip netns exec gigport brctl setageing br1 0 8 | 9 | brctl setageing br0 0 10 | 11 | ip link add dev veth0 type veth peer name veth0-1 12 | ip link add dev veth1 type veth peer name veth1-1 13 | 14 | ip link set dev veth0 up 15 | ip link set dev veth1 up 16 | 17 | ip link set dev veth0-1 up 18 | ip link set veth1-1 netns gigport 19 | ip netns exec gigport ip link set dev veth1-1 up 20 | ip netns exec gigport ethtool -K veth1-1 tx off 21 | 22 | ethtool -K veth0 tx off 23 | ethtool -K veth1 tx off 24 | 25 | ethtool -K veth0-1 tx off 26 | 27 | brctl addif br0 veth0-1 28 | ip netns exec gigport brctl addif br1 veth1-1 29 | ip netns exec gigport ip addr add 192.168.4.150/24 dev br1 30 | ip netns exec gigport ip link set dev br1 up 31 | -------------------------------------------------------------------------------- /vm/files/p4pi-setup.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Setup veth and bridge interfaces for packet processing 3 | Requires=systemd-networkd.target 4 | After=systemd-networkd.target 5 | After=network.target 6 | 7 | [Service] 8 | ExecStart=/usr/sbin/p4pi-setup 9 | 10 | [Install] 11 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /vm/files/p4pi.conf: -------------------------------------------------------------------------------- 1 | resolv-file=/etc/resolv.conf 2 | interface=br0 3 | dhcp-range=set:br0,192.168.4.2,192.168.4.20,255.255.255.0,24h 4 | dhcp-lease-max=160 5 | domain=p4pi 6 | address=/gw.p4pi/192.168.4.1 7 | server=1.1.1.1 -------------------------------------------------------------------------------- /vm/files/t4p4s-p4rtshell: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z $1 ] 4 | then 5 | echo "Missing commandline argument!" 6 | echo "Usage: ./$0 " 7 | echo "Example: ./$0 l2switch" 8 | exit 1 9 | fi 10 | 11 | DEFAULT_PROG=$1 12 | T4P4SDIR="/root/t4p4s" 13 | P4RTDIR="${T4P4SDIR}/examples/p4rt_files" 14 | 15 | 16 | if [ ! -f "${T4P4SDIR}/examples/${DEFAULT_PROG}.p4" ] 17 | then 18 | echo "P4 source file does not exist." 19 | echo "Missing file: ${T4P4SDIR}/examples/${DEFAULT_PROG}.p4" 20 | exit 1 21 | fi 22 | 23 | echo "Generating P4Runtime files..." 24 | 25 | if [ ! -d "$P4RTDIR" ] 26 | then 27 | echo "Creating the directory for P4Runtime files: $P4RTDIR" 28 | mkdir $P4RTDIR 29 | fi 30 | 31 | pushd ${P4RTDIR} 32 | p4c-bm2-ss --p4runtime-files "${DEFAULT_PROG}.p4runtime.txt" --toJSON "${DEFAULT_PROG}.json" "${T4P4SDIR}/examples/${DEFAULT_PROG}.p4" 33 | popd 34 | 35 | echo "Launching P4Runtime-shell..." 36 | python3.9 -m p4runtime_sh --grpc-addr localhost:50051 --device-id 1 --election-id 0,1 --config "${P4RTDIR}/${DEFAULT_PROG}.p4runtime.txt,${P4RTDIR}/${DEFAULT_PROG}.json" 37 | 38 | -------------------------------------------------------------------------------- /vm/files/t4p4s-start: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export P4PI=/root/PI 4 | export GRPCPP=/root/P4Runtime_GRPCPP 5 | export GRPC=/root/grpc 6 | 7 | P4_PROG=l2switch 8 | T4P4S_PROG_FILE=/root/t4p4s-switch 9 | if [ -f "${T4P4S_PROG_FILE}" ]; then 10 | P4_PROG=$(cat "${T4P4S_PROG_FILE}") 11 | else 12 | echo "${P4_PROG}" > "${T4P4S_PROG_FILE}" 13 | fi 14 | 15 | /root/t4p4s/t4p4s.sh :"${P4_PROG}" p4rt -------------------------------------------------------------------------------- /vm/files/t4p4s.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=T4P4S Switch 3 | 4 | [Service] 5 | Type=simple 6 | ExecStart=/usr/sbin/t4p4s-start 7 | WorkingDirectory=/root/t4p4s 8 | Restart=on-failure 9 | RestartSec=5s 10 | 11 | [Install] 12 | WantedBy=multi-user.target --------------------------------------------------------------------------------