├── vpp-vxlan ├── stop.sh ├── routers │ ├── router1 │ │ ├── r1-2.vtysh │ │ ├── r1-vxlan.cmd │ │ ├── r1-1.vtysh │ │ ├── frr.conf │ │ └── daemons │ └── router2 │ │ ├── r2-2.vtysh │ │ ├── r2-vxlan.cmd │ │ ├── r2-1.vtysh │ │ ├── frr.conf │ │ └── daemons ├── .gitignore ├── scripts │ └── PC-interfaces.sh ├── frr01.clab.yml ├── README.md └── run.sh ├── sonic-vpp ├── sonic-vpp-L3 │ ├── stop.sh │ ├── .gitignore │ ├── sonic-vpp01.clab.yml │ ├── scripts │ │ └── PC-interfaces.sh │ ├── run.sh │ └── README.md └── sonic-vpp-L3-BGP │ ├── stop.sh │ ├── .gitignore │ ├── routers │ ├── router1 │ │ └── r1-1.vtysh │ └── router2 │ │ └── r2-1.vtysh │ ├── sonic-vpp01.clab.yml │ ├── README.md │ ├── scripts │ └── PC-interfaces.sh │ └── run.sh ├── .gitignore ├── nsm └── LFNWebinar │ ├── img │ ├── lfn-webinar-routing.png │ ├── lfn-webinar-networking.png │ └── lfn-webinar-routing.xml │ ├── network-service.yaml │ ├── client.yaml │ ├── webserver.yaml │ ├── cnf-nat44.yaml │ ├── cnf-crd.yaml │ └── README.md ├── vpp-bgp-ecmp ├── .gitignore ├── routers │ ├── router2 │ │ ├── r2.vtysh │ │ └── daemons │ ├── router3 │ │ └── r3.vtysh │ ├── router1 │ │ ├── r1.vtysh │ │ └── daemons │ └── router4 │ │ └── r4.vtysh ├── README.md ├── run.sh ├── frr01.clab.yml └── scripts │ └── interfaces.sh ├── ONAP-cdnf-integration ├── cba │ ├── TOSCA-Metadata │ │ └── TOSCA.meta │ ├── Templates │ │ ├── cnf-config-template.vtl │ │ └── cnf-config-mapping.json │ ├── pom.xml │ ├── Definitions │ │ └── cnf-configuration.json │ └── Scripts │ │ └── kotlin │ │ └── ConfigDeploy.kt ├── README.md ├── docker-compose.yml ├── run-demo.sh ├── firewall-cnf-helper.sh ├── cds-bp-application.properties └── CDS-CNF demo.postman_collection.json ├── README.md ├── vpp-traceability ├── README.md ├── vlib_error_counters.c ├── vnet_route_updates.c ├── vlib_simple_counters.c ├── vnet_arp_updates.c ├── vnet_neighbor_updates.c ├── vnet_ip_updates.c ├── vnet_nat_updates.c ├── vlib_combined_counters.c ├── vnet_interfaces.c ├── vlib_stats.c ├── vpp_bpftrace.py └── vpp-traceability.diff └── LICENSE /vpp-vxlan/stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo clab destroy --topo frr01.clab.yml 4 | -------------------------------------------------------------------------------- /sonic-vpp/sonic-vpp-L3/stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo clab destroy --topo sonic-vpp01.clab.yml 4 | -------------------------------------------------------------------------------- /sonic-vpp/sonic-vpp-L3-BGP/stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo clab destroy --topo sonic-vpp01.clab.yml 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .iml 3 | /ONAP-cdnf-integration/*.zip 4 | /ONAP-cdnf-integration/reports/ 5 | /ONAP-cdnf-integration/cba/target/ 6 | -------------------------------------------------------------------------------- /nsm/LFNWebinar/img/lfn-webinar-routing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PANTHEONtech/cnf-examples/HEAD/nsm/LFNWebinar/img/lfn-webinar-routing.png -------------------------------------------------------------------------------- /nsm/LFNWebinar/img/lfn-webinar-networking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PANTHEONtech/cnf-examples/HEAD/nsm/LFNWebinar/img/lfn-webinar-networking.png -------------------------------------------------------------------------------- /vpp-vxlan/routers/router1/r1-2.vtysh: -------------------------------------------------------------------------------- 1 | configure terminal 2 | router bgp 65100 3 | address-family l2vpn evpn 4 | neighbor 10.0.1.0 activate 5 | advertise-all-vni 6 | end 7 | write 8 | exit 9 | -------------------------------------------------------------------------------- /vpp-vxlan/routers/router2/r2-2.vtysh: -------------------------------------------------------------------------------- 1 | configure terminal 2 | router bgp 65100 3 | address-family l2vpn evpn 4 | neighbor 10.0.1.1 activate 5 | advertise-all-vni 6 | end 7 | write 8 | exit 9 | -------------------------------------------------------------------------------- /vpp-vxlan/routers/router1/r1-vxlan.cmd: -------------------------------------------------------------------------------- 1 | sudo config vlan add 100 2 | config vlan member add -u 100 Ethernet1 3 | sudo config vxlan add vtep 10.0.1.1 4 | sudo config vxlan evpn_nvo add nvo vtep 5 | sudo config vxlan map add vtep 100 1000 6 | -------------------------------------------------------------------------------- /vpp-vxlan/routers/router2/r2-vxlan.cmd: -------------------------------------------------------------------------------- 1 | sudo config vlan add 100 2 | config vlan member add -u 100 Ethernet1 3 | sudo config vxlan add vtep 10.0.1.0 4 | sudo config vxlan evpn_nvo add nvo vtep 5 | sudo config vxlan map add vtep 100 1000 6 | -------------------------------------------------------------------------------- /vpp-vxlan/.gitignore: -------------------------------------------------------------------------------- 1 | # IDE specific files # 2 | ###################### 3 | .idea/ 4 | 5 | # Sensitive files # 6 | ########## 7 | *.env 8 | *.key 9 | 10 | # Project Build Related # 11 | ############################ 12 | /clab-frr01 13 | *.bak 14 | -------------------------------------------------------------------------------- /vpp-bgp-ecmp/.gitignore: -------------------------------------------------------------------------------- 1 | # IDE specific files # 2 | ###################### 3 | .idea/ 4 | 5 | # Sensitive files # 6 | ########## 7 | *.env 8 | *.key 9 | 10 | # Project Build Related # 11 | ############################ 12 | /clab-frr01 13 | *.bak 14 | -------------------------------------------------------------------------------- /vpp-vxlan/routers/router1/r1-1.vtysh: -------------------------------------------------------------------------------- 1 | configure terminal 2 | router bgp 65100 3 | no bgp ebgp-requires-policy 4 | bgp router-id 10.0.1.1 5 | neighbor 10.0.1.0 remote-as 65100 6 | address-family ipv4 7 | network 10.0.1.1/31 8 | end 9 | write 10 | exit 11 | -------------------------------------------------------------------------------- /vpp-vxlan/routers/router2/r2-1.vtysh: -------------------------------------------------------------------------------- 1 | configure terminal 2 | router bgp 65100 3 | no bgp ebgp-requires-policy 4 | bgp router-id 10.0.1.0 5 | neighbor 10.0.1.1 remote-as 65100 6 | address-family ipv4 7 | network 10.0.1.0/31 8 | end 9 | write 10 | exit 11 | -------------------------------------------------------------------------------- /sonic-vpp/sonic-vpp-L3/.gitignore: -------------------------------------------------------------------------------- 1 | # IDE specific files # 2 | ###################### 3 | .idea/ 4 | 5 | # Sensitive files # 6 | ########## 7 | *.env 8 | *.key 9 | 10 | # Project Build Related # 11 | ############################ 12 | /clab-sonic-vpp01 13 | *.bak 14 | -------------------------------------------------------------------------------- /sonic-vpp/sonic-vpp-L3-BGP/.gitignore: -------------------------------------------------------------------------------- 1 | # IDE specific files # 2 | ###################### 3 | .idea/ 4 | 5 | # Sensitive files # 6 | ########## 7 | *.env 8 | *.key 9 | 10 | # Project Build Related # 11 | ############################ 12 | /clab-frr01 13 | clab-sonic-vpp01/ 14 | *.bak 15 | -------------------------------------------------------------------------------- /sonic-vpp/sonic-vpp-L3-BGP/routers/router1/r1-1.vtysh: -------------------------------------------------------------------------------- 1 | configure terminal 2 | router bgp 65100 3 | no bgp ebgp-requires-policy 4 | bgp router-id 10.0.1.1 5 | neighbor 10.0.1.2 remote-as 65100 6 | address-family ipv4 7 | neighbor 10.0.1.2 activate 8 | network 10.0.1.1/30 9 | network 10.20.1.0/24 10 | end 11 | write 12 | exit 13 | -------------------------------------------------------------------------------- /sonic-vpp/sonic-vpp-L3-BGP/routers/router2/r2-1.vtysh: -------------------------------------------------------------------------------- 1 | configure terminal 2 | router bgp 65100 3 | no bgp ebgp-requires-policy 4 | bgp router-id 10.0.1.2 5 | neighbor 10.0.1.1 remote-as 65100 6 | address-family ipv4 7 | neighbor 10.0.1.1 activate 8 | network 10.0.1.2/30 9 | network 10.20.2.0/24 10 | end 11 | write 12 | exit 13 | -------------------------------------------------------------------------------- /ONAP-cdnf-integration/cba/TOSCA-Metadata/TOSCA.meta: -------------------------------------------------------------------------------- 1 | TOSCA-Meta-File-Version: 1.0.0 2 | CSAR-Version: 1.0 3 | Created-By: Filip Gschwandtner 4 | Entry-Definitions: Definitions/cnf-configuration.json 5 | Template-Tags: CBA, Firewall, CNF, demo, Pantheon.tech 6 | Template-Name: Firewall-CNF-configuration-example 7 | Template-Version: 1.0.0 8 | Template-Type: DEFAULT -------------------------------------------------------------------------------- /vpp-bgp-ecmp/routers/router2/r2.vtysh: -------------------------------------------------------------------------------- 1 | configure terminal 2 | hostname router2 3 | no ipv6 forwarding 4 | ! 5 | router bgp 65100 6 | no bgp ebgp-requires-policy 7 | network 192.168.12.0 mask 255.255.255.0 8 | network 192.168.14.0 mask 255.255.255.0 9 | neighbor 192.168.12.1 remote-as 65000 10 | neighbor 192.168.14.2 remote-as 65300 11 | ! 12 | line vty 13 | ! 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /vpp-bgp-ecmp/routers/router3/r3.vtysh: -------------------------------------------------------------------------------- 1 | configure terminal 2 | hostname router3 3 | no ipv6 forwarding 4 | ! 5 | router bgp 65200 6 | no bgp ebgp-requires-policy 7 | network 192.168.13.0 mask 255.255.255.0 8 | network 192.168.15.0 mask 255.255.255.0 9 | neighbor 192.168.13.1 remote-as 65000 10 | neighbor 192.168.15.2 remote-as 65300 11 | ! 12 | line vty 13 | ! 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /vpp-bgp-ecmp/routers/router1/r1.vtysh: -------------------------------------------------------------------------------- 1 | configure terminal 2 | hostname router1 3 | no ipv6 forwarding 4 | ! 5 | router bgp 65000 6 | no bgp ebgp-requires-policy 7 | maximum-paths 2 8 | bgp bestpath as-path multipath-relax 9 | network 192.168.11.0 mask 255.255.255.0 10 | network 192.168.12.0 mask 255.255.255.0 11 | network 192.168.13.0 mask 255.255.255.0 12 | neighbor 192.168.12.2 remote-as 65100 13 | neighbor 192.168.13.2 remote-as 65200 14 | ! 15 | line vty 16 | ! 17 | -------------------------------------------------------------------------------- /vpp-bgp-ecmp/routers/router4/r4.vtysh: -------------------------------------------------------------------------------- 1 | configure terminal 2 | hostname router4 3 | no ipv6 forwarding 4 | ! 5 | router bgp 65300 6 | no bgp ebgp-requires-policy 7 | maximum-paths 2 8 | bgp bestpath as-path multipath-relax 9 | network 192.168.16.0 mask 255.255.255.0 10 | network 192.168.14.0 mask 255.255.255.0 11 | network 192.168.15.0 mask 255.255.255.0 12 | neighbor 192.168.14.1 remote-as 65100 13 | neighbor 192.168.15.1 remote-as 65200 14 | ! 15 | line vty 16 | ! 17 | -------------------------------------------------------------------------------- /ONAP-cdnf-integration/cba/Templates/cnf-config-template.vtl: -------------------------------------------------------------------------------- 1 | netallocConfig: {} 2 | linuxConfig: {} 3 | vppConfig: 4 | acls: 5 | - name: ICMPTrafficDemo 6 | rules: 7 | - action: ${firewall_action} 8 | ip_rule: 9 | ip: 10 | destinationNetwork: ${traffic_destination_network} 11 | sourceNetwork: 0.0.0.0/0 12 | interfaces: 13 | egress: 14 | - fromVPPAFPacket -------------------------------------------------------------------------------- /vpp-vxlan/routers/router1/frr.conf: -------------------------------------------------------------------------------- 1 | frr version 7.5.1_git 2 | frr defaults traditional 3 | hostname router1 4 | no ipv6 forwarding 5 | ! 6 | interface eth1 7 | ip address 192.0.2.1/24 8 | ! 9 | interface eth2 10 | ip address 198.51.100.1/30 11 | ! 12 | router bgp 64000 13 | bgp router-id 1.1.1.1 14 | neighbor 198.51.100.2 remote-as 65000 15 | ! 16 | address-family ipv4 unicast 17 | no bgp ebgp-requires-policy 18 | no bgp network import-check 19 | network 192.0.2.0/24 20 | exit-address-family 21 | ! 22 | line vty 23 | ! 24 | 25 | -------------------------------------------------------------------------------- /vpp-vxlan/routers/router2/frr.conf: -------------------------------------------------------------------------------- 1 | frr version 7.5.1_git 2 | frr defaults traditional 3 | hostname router2 4 | no ipv6 forwarding 5 | ! 6 | interface eth1 7 | ip address 203.0.113.1/24 8 | ! 9 | interface eth2 10 | ip address 198.51.100.2/30 11 | ! 12 | router bgp 65000 13 | bgp router-id 2.2.2.2 14 | neighbor 198.51.100.1 remote-as 64000 15 | ! 16 | address-family ipv4 unicast 17 | no bgp ebgp-requires-policy 18 | no bgp network import-check 19 | network 203.0.113.0/24 20 | exit-address-family 21 | ! 22 | line vty 23 | ! 24 | 25 | -------------------------------------------------------------------------------- /sonic-vpp/sonic-vpp-L3/sonic-vpp01.clab.yml: -------------------------------------------------------------------------------- 1 | name: sonic-vpp01 2 | 3 | topology: 4 | nodes: 5 | router1: 6 | kind: sonic-vm 7 | image: ghcr.io/pantheontech/sonic-vpp-vs:250619 8 | router2: 9 | kind: sonic-vm 10 | image: ghcr.io/pantheontech/sonic-vpp-vs:250619 11 | PC1: 12 | kind: linux 13 | image: wbitt/network-multitool:extra 14 | PC2: 15 | kind: linux 16 | image: wbitt/network-multitool:extra 17 | 18 | links: 19 | - endpoints: ["router1:eth1", "router2:eth1"] 20 | - endpoints: ["PC1:eth2", "router1:eth2"] 21 | - endpoints: ["PC2:eth2", "router2:eth2"] 22 | -------------------------------------------------------------------------------- /sonic-vpp/sonic-vpp-L3-BGP/sonic-vpp01.clab.yml: -------------------------------------------------------------------------------- 1 | name: sonic-vpp01 2 | 3 | topology: 4 | nodes: 5 | router1: 6 | kind: sonic-vm 7 | image: ghcr.io/pantheontech/sonic-vpp-vs:250619 8 | router2: 9 | kind: sonic-vm 10 | image: ghcr.io/pantheontech/sonic-vpp-vs:250619 11 | PC1: 12 | kind: linux 13 | image: wbitt/network-multitool:extra 14 | PC2: 15 | kind: linux 16 | image: wbitt/network-multitool:extra 17 | 18 | links: 19 | - endpoints: ["router1:eth1", "router2:eth1"] 20 | - endpoints: ["PC1:eth2", "router1:eth2"] 21 | - endpoints: ["PC2:eth2", "router2:eth2"] 22 | -------------------------------------------------------------------------------- /nsm/LFNWebinar/network-service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: networkservicemesh.io/v1alpha1 3 | kind: NetworkService 4 | metadata: 5 | name: cnf-nat-example 6 | spec: 7 | payload: IP 8 | matches: 9 | # connect client to the (local side of) cnf-nat44 10 | - match: 11 | sourceSelector: 12 | app: client 13 | route: 14 | - destination: 15 | destinationSelector: 16 | app: nat44 17 | # connect the (external side of) cnf-nat44 to the webserver 18 | - match: 19 | sourceSelector: 20 | app: nat44 21 | route: 22 | - destination: 23 | destinationSelector: 24 | app: webserver -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CNF Examples 2 | ------------ 3 | 4 | The repository provides reference code and test cases for running networking code on Kubernetes using 5 | the [Ligato framework][ligato] and emerging cloud native technologies such as [NSM][nsm], with primary focus 6 | on the Telecom domain. 7 | 8 | *Example presented in the LFN Webinar "Building CNFs with FD.io VPP and Network Service Mesh..." can be found inside 9 | the `nsm/LFNWebinar` sub-directory.* 10 | 11 | More information about cloud-native tools and network functions provided by PANTHEON.tech can be found on our website 12 | [cdnf.io][cdnf-io]. 13 | 14 | [ligato]: https://github.com/ligato 15 | [nsm]: https://networkservicemesh.io/ 16 | [cdnf-io]: https://cdnf.io/ 17 | -------------------------------------------------------------------------------- /vpp-vxlan/routers/router1/daemons: -------------------------------------------------------------------------------- 1 | zebra=yes 2 | bgpd=yes 3 | ospfd=no 4 | ospf6d=no 5 | ripd=no 6 | ripngd=no 7 | isisd=no 8 | pimd=no 9 | ldpd=yes 10 | nhrpd=no 11 | eigrpd=no 12 | babeld=no 13 | sharpd=no 14 | staticd=no 15 | pbrd=no 16 | bfdd=no 17 | fabricd=no 18 | 19 | vtysh_enable=yes 20 | zebra_options=" -s 90000000 --daemon -A 127.0.0.1" 21 | bgpd_options=" --daemon -A 127.0.0.1" 22 | ospfd_options=" --daemon -A 127.0.0.1" 23 | ospf6d_options=" --daemon -A ::1" 24 | ripd_options=" --daemon -A 127.0.0.1" 25 | ripngd_options=" --daemon -A ::1" 26 | isisd_options=" --daemon -A 127.0.0.1" 27 | pimd_options=" --daemon -A 127.0.0.1" 28 | ldpd_options=" --daemon -A 127.0.0.1" 29 | nhrpd_options=" --daemon -A 127.0.0.1" 30 | eigrpd_options=" --daemon -A 127.0.0.1" 31 | babeld_options=" --daemon -A 127.0.0.1" 32 | sharpd_options=" --daemon -A 127.0.0.1" 33 | staticd_options=" --daemon -A 127.0.0.1" 34 | pbrd_options=" --daemon -A 127.0.0.1" 35 | bfdd_options=" --daemon -A 127.0.0.1" 36 | fabricd_options=" --daemon -A 127.0.0.1" 37 | -------------------------------------------------------------------------------- /vpp-vxlan/routers/router2/daemons: -------------------------------------------------------------------------------- 1 | zebra=yes 2 | bgpd=yes 3 | ospfd=no 4 | ospf6d=no 5 | ripd=no 6 | ripngd=no 7 | isisd=no 8 | pimd=no 9 | ldpd=yes 10 | nhrpd=no 11 | eigrpd=no 12 | babeld=no 13 | sharpd=no 14 | staticd=no 15 | pbrd=no 16 | bfdd=no 17 | fabricd=no 18 | 19 | vtysh_enable=yes 20 | zebra_options=" -s 90000000 --daemon -A 127.0.0.1" 21 | bgpd_options=" --daemon -A 127.0.0.1" 22 | ospfd_options=" --daemon -A 127.0.0.1" 23 | ospf6d_options=" --daemon -A ::1" 24 | ripd_options=" --daemon -A 127.0.0.1" 25 | ripngd_options=" --daemon -A ::1" 26 | isisd_options=" --daemon -A 127.0.0.1" 27 | pimd_options=" --daemon -A 127.0.0.1" 28 | ldpd_options=" --daemon -A 127.0.0.1" 29 | nhrpd_options=" --daemon -A 127.0.0.1" 30 | eigrpd_options=" --daemon -A 127.0.0.1" 31 | babeld_options=" --daemon -A 127.0.0.1" 32 | sharpd_options=" --daemon -A 127.0.0.1" 33 | staticd_options=" --daemon -A 127.0.0.1" 34 | pbrd_options=" --daemon -A 127.0.0.1" 35 | bfdd_options=" --daemon -A 127.0.0.1" 36 | fabricd_options=" --daemon -A 127.0.0.1" 37 | -------------------------------------------------------------------------------- /vpp-bgp-ecmp/routers/router1/daemons: -------------------------------------------------------------------------------- 1 | zebra=yes 2 | bgpd=yes 3 | ospfd=no 4 | ospf6d=no 5 | ripd=no 6 | ripngd=no 7 | isisd=no 8 | pimd=no 9 | ldpd=yes 10 | nhrpd=no 11 | eigrpd=no 12 | babeld=no 13 | sharpd=no 14 | staticd=no 15 | pbrd=no 16 | bfdd=no 17 | fabricd=no 18 | 19 | vtysh_enable=yes 20 | zebra_options=" -s 90000000 --daemon -A 127.0.0.1" 21 | bgpd_options=" --daemon -A 127.0.0.1" 22 | ospfd_options=" --daemon -A 127.0.0.1" 23 | ospf6d_options=" --daemon -A ::1" 24 | ripd_options=" --daemon -A 127.0.0.1" 25 | ripngd_options=" --daemon -A ::1" 26 | isisd_options=" --daemon -A 127.0.0.1" 27 | pimd_options=" --daemon -A 127.0.0.1" 28 | ldpd_options=" --daemon -A 127.0.0.1" 29 | nhrpd_options=" --daemon -A 127.0.0.1" 30 | eigrpd_options=" --daemon -A 127.0.0.1" 31 | babeld_options=" --daemon -A 127.0.0.1" 32 | sharpd_options=" --daemon -A 127.0.0.1" 33 | staticd_options=" --daemon -A 127.0.0.1" 34 | pbrd_options=" --daemon -A 127.0.0.1" 35 | bfdd_options=" --daemon -A 127.0.0.1" 36 | fabricd_options=" --daemon -A 127.0.0.1" 37 | -------------------------------------------------------------------------------- /vpp-bgp-ecmp/routers/router2/daemons: -------------------------------------------------------------------------------- 1 | zebra=yes 2 | bgpd=yes 3 | ospfd=no 4 | ospf6d=no 5 | ripd=no 6 | ripngd=no 7 | isisd=no 8 | pimd=no 9 | ldpd=yes 10 | nhrpd=no 11 | eigrpd=no 12 | babeld=no 13 | sharpd=no 14 | staticd=no 15 | pbrd=no 16 | bfdd=no 17 | fabricd=no 18 | 19 | vtysh_enable=yes 20 | zebra_options=" -s 90000000 --daemon -A 127.0.0.1" 21 | bgpd_options=" --daemon -A 127.0.0.1" 22 | ospfd_options=" --daemon -A 127.0.0.1" 23 | ospf6d_options=" --daemon -A ::1" 24 | ripd_options=" --daemon -A 127.0.0.1" 25 | ripngd_options=" --daemon -A ::1" 26 | isisd_options=" --daemon -A 127.0.0.1" 27 | pimd_options=" --daemon -A 127.0.0.1" 28 | ldpd_options=" --daemon -A 127.0.0.1" 29 | nhrpd_options=" --daemon -A 127.0.0.1" 30 | eigrpd_options=" --daemon -A 127.0.0.1" 31 | babeld_options=" --daemon -A 127.0.0.1" 32 | sharpd_options=" --daemon -A 127.0.0.1" 33 | staticd_options=" --daemon -A 127.0.0.1" 34 | pbrd_options=" --daemon -A 127.0.0.1" 35 | bfdd_options=" --daemon -A 127.0.0.1" 36 | fabricd_options=" --daemon -A 127.0.0.1" 37 | -------------------------------------------------------------------------------- /vpp-vxlan/scripts/PC-interfaces.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | sudo docker exec -d clab-frr01-PC1 ip link set dev eth2 address aa:aa:aa:aa:aa:aa 3 | sudo docker exec -d clab-frr01-PC1 ip link set eth2 up 4 | sudo docker exec -d clab-frr01-PC1 ip addr add 168.95.10.2/16 dev eth2 5 | sudo docker exec -d clab-frr01-PC1 ip route add 0.0.0.0/0 dev eth2 6 | 7 | sudo docker exec -d clab-frr01-PC2 ip link set dev eth2 address be:ef:be:ef:be:ef 8 | sudo docker exec -d clab-frr01-PC2 ip link set eth2 up 9 | sudo docker exec -d clab-frr01-PC2 ip addr add 168.95.10.1/16 dev eth2 10 | 11 | sudo docker exec -d clab-frr01-router1 config interface ip add Ethernet0 10.0.1.1/31 12 | sudo docker exec -d clab-frr01-router1 config interface startup Ethernet0 13 | sudo docker exec -d clab-frr01-router1 config interface startup Ethernet1 14 | 15 | sudo docker exec -d clab-frr01-router2 config interface ip add Ethernet0 10.0.1.0/31 16 | sudo docker exec -d clab-frr01-router2 config interface startup Ethernet0 17 | sudo docker exec -d clab-frr01-router2 config interface startup Ethernet1 -------------------------------------------------------------------------------- /ONAP-cdnf-integration/cba/Templates/cnf-config-mapping.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "traffic_destination_network", 4 | "property": { 5 | "description": "Destination network (IP+mask) for firewall rule applied to firewall CNF", 6 | "required": true, 7 | "type": "string", 8 | "status": "", 9 | "constraints": [{}], 10 | "entry_schema": { 11 | "type": "" 12 | } 13 | }, 14 | "input-param": true, 15 | "dictionary-name": "address", 16 | "dictionary-source": "input", 17 | "dependencies": [], 18 | "version": 0 19 | }, 20 | { 21 | "name": "firewall_action", 22 | "property": { 23 | "description": "Action that will be applied by firewall to network traffic (possible values: DENY, PERMIT)", 24 | "required": true, 25 | "type": "string", 26 | "status": "", 27 | "constraints": [{}], 28 | "entry_schema": { 29 | "type": "" 30 | } 31 | }, 32 | "input-param": true, 33 | "dictionary-name": "address", 34 | "dictionary-source": "input", 35 | "dependencies": [], 36 | "version": 0 37 | } 38 | ] -------------------------------------------------------------------------------- /sonic-vpp/sonic-vpp-L3-BGP/README.md: -------------------------------------------------------------------------------- 1 | To launch the project, simply execute the run.sh script: 2 | 3 | ```bash 4 | ./run.sh 5 | ``` 6 | 7 | The run.sh script orchestrates the setup and configuration of the VXLAN environment. 8 | 9 | ## Verifying the Setup 10 | 11 | - Verify Container 12 | 13 | ```bash 14 | docker ps 15 | ``` 16 | Ensure that you see containers for Router 1, Router 2, PC1, and PC2. 17 | 18 | - Verify BGP Status 19 | 20 | ```bash 21 | sshpass -p admin ssh admin@clab-sonic-vpp01-router1 "vtysh -c 'show ip bgp summary'" 22 | sshpass -p admin ssh admin@clab-sonic-vpp01-router1 "vtysh -c 'show ip bgp'" 23 | 24 | sshpass -p admin ssh admin@clab-sonic-vpp01-router2 "vtysh -c 'show ip bgp summary'" 25 | sshpass -p admin ssh admin@clab-sonic-vpp01-router2 "vtysh -c 'show ip bgp'" 26 | ``` 27 | 28 | Verify connectivity between PC1 and PC2 29 | 30 | ```bash 31 | docker exec clab-sonic-vpp01-PC1 ping -c 5 10.20.2.1 32 | docker exec clab-sonic-vpp01-PC2 ping -c 5 10.20.1.1 33 | ``` 34 | 35 | - Test Connectivity 36 | 37 | ```bash 38 | docker exec -it clab-sonic-vpp01-PC1 iperf3 -s 39 | docker exec -it clab-sonic-vpp01-PC2 iperf3 -c 10.20.1.1 40 | ``` 41 | -------------------------------------------------------------------------------- /vpp-vxlan/frr01.clab.yml: -------------------------------------------------------------------------------- 1 | name: frr01 2 | 3 | topology: 4 | nodes: 5 | router1: 6 | kind: linux 7 | image: ghcr.io/pantheontech/sonic-vpp:vxlan-poc-24.04.0 8 | binds: 9 | - routers/router1/daemons:/etc/frr/daemons 10 | env: 11 | DPDK_DISABLE: "y" 12 | VPP_DPDK_PORTS: "eth1,eth2" 13 | SONIC_NUM_PORTS: 2 14 | VPP_CONF_DB: "n" 15 | NO_LINUX_NL: "y" 16 | ports: 17 | - 6379:6379 18 | - 8081:8081 19 | router2: 20 | kind: linux 21 | image: ghcr.io/pantheontech/sonic-vpp:vxlan-poc-24.04.0 22 | binds: 23 | - routers/router2/daemons:/etc/frr/daemons 24 | env: 25 | DPDK_DISABLE: "y" 26 | VPP_DPDK_PORTS: "eth1,eth2" 27 | SONIC_NUM_PORTS: 2 28 | VPP_CONF_DB: "n" 29 | NO_LINUX_NL: "y" 30 | ports: 31 | - 8082:8081 32 | 33 | PC1: 34 | kind: linux 35 | image: praqma/network-multitool:latest 36 | PC2: 37 | kind: linux 38 | image: praqma/network-multitool:latest 39 | 40 | links: 41 | - endpoints: ["router1:eth1", "router2:eth1"] 42 | - endpoints: ["PC1:eth2", "router1:eth2"] 43 | - endpoints: ["PC2:eth2", "router2:eth2"] 44 | -------------------------------------------------------------------------------- /sonic-vpp/sonic-vpp-L3-BGP/scripts/PC-interfaces.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -x 4 | 5 | ROUTER1="sshpass -p admin ssh admin@clab-sonic-vpp01-router1" 6 | ROUTER2="sshpass -p admin ssh admin@clab-sonic-vpp01-router2" 7 | 8 | 9 | sudo docker exec -d clab-sonic-vpp01-PC1 ip link set dev eth2 address aa:aa:aa:aa:aa:aa 10 | sudo docker exec -d clab-sonic-vpp01-PC1 ip link set eth2 up 11 | sudo docker exec -d clab-sonic-vpp01-PC1 ip addr add 10.20.1.1/24 dev eth2 12 | sudo docker exec -d clab-sonic-vpp01-PC1 ip route add 10.20.2.0/24 via 10.20.1.254 13 | 14 | sudo docker exec -d clab-sonic-vpp01-PC2 ip link set dev eth2 address be:ef:be:ef:be:ef 15 | sudo docker exec -d clab-sonic-vpp01-PC2 ip link set eth2 up 16 | sudo docker exec -d clab-sonic-vpp01-PC2 ip addr add 10.20.2.1/24 dev eth2 17 | sudo docker exec -d clab-sonic-vpp01-PC2 ip route add 10.20.1.0/24 via 10.20.2.254 18 | 19 | 20 | ${ROUTER1} sudo config interface ip add Ethernet0 10.0.1.1/30 21 | ${ROUTER1} sudo config interface startup Ethernet0 22 | ${ROUTER1} sudo config interface ip add Ethernet4 10.20.1.254/24 23 | ${ROUTER1} sudo config interface startup Ethernet4 24 | 25 | ${ROUTER2} sudo config interface ip add Ethernet0 10.0.1.2/30 26 | ${ROUTER2} sudo config interface startup Ethernet0 27 | ${ROUTER2} sudo config interface ip add Ethernet4 10.20.2.254/24 28 | ${ROUTER2} sudo config interface startup Ethernet4 29 | -------------------------------------------------------------------------------- /ONAP-cdnf-integration/cba/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | 7 | org.onap.ccsdk.cds.components.cba 8 | test-blueprint-kotlin-parent 9 | 1.1.1 10 | 11 | 12 | cnf-configuration-demo 13 | 1.1.1 14 | pom 15 | 16 | 17 | 18 | ccsdkapps 19 | ccsdkapps 20 | 24 | 8000 25 | 29 | 30 | 31 | 32 | 33 | org.onap.ccsdk.cds.blueprintsprocessor.functions 34 | restful-executor 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /sonic-vpp/sonic-vpp-L3/scripts/PC-interfaces.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -x 4 | 5 | ROUTER1="sshpass -p admin ssh admin@clab-sonic-vpp01-router1" 6 | ROUTER2="sshpass -p admin ssh admin@clab-sonic-vpp01-router2" 7 | 8 | 9 | sudo docker exec -d clab-sonic-vpp01-PC1 ip link set dev eth2 address aa:aa:aa:aa:aa:aa 10 | sudo docker exec -d clab-sonic-vpp01-PC1 ip link set eth2 up 11 | sudo docker exec -d clab-sonic-vpp01-PC1 ip addr add 10.20.1.1/24 dev eth2 12 | sudo docker exec -d clab-sonic-vpp01-PC1 ip route add 10.20.2.0/24 via 10.20.1.254 13 | 14 | sudo docker exec -d clab-sonic-vpp01-PC2 ip link set dev eth2 address be:ef:be:ef:be:ef 15 | sudo docker exec -d clab-sonic-vpp01-PC2 ip link set eth2 up 16 | sudo docker exec -d clab-sonic-vpp01-PC2 ip addr add 10.20.2.1/24 dev eth2 17 | sudo docker exec -d clab-sonic-vpp01-PC2 ip route add 10.20.1.0/24 via 10.20.2.254 18 | 19 | 20 | ${ROUTER1} sudo config interface ip add Ethernet0 10.0.1.1/30 21 | ${ROUTER1} sudo config interface startup Ethernet0 22 | ${ROUTER1} sudo config interface ip add Ethernet4 10.20.1.254/24 23 | ${ROUTER1} sudo config interface startup Ethernet4 24 | ${ROUTER1} sudo config route add prefix 10.20.2.0/24 nexthop 10.0.1.2 25 | 26 | ${ROUTER2} sudo config interface ip add Ethernet0 10.0.1.2/30 27 | ${ROUTER2} sudo config interface startup Ethernet0 28 | ${ROUTER2} sudo config interface ip add Ethernet4 10.20.2.254/24 29 | ${ROUTER2} sudo config interface startup Ethernet4 30 | ${ROUTER2} sudo config route add prefix 10.20.1.0/24 nexthop 10.0.1.1 31 | -------------------------------------------------------------------------------- /vpp-bgp-ecmp/README.md: -------------------------------------------------------------------------------- 1 | # BGP ECMP 2 | 3 | ## Overview 4 | This project sets up a BGP ECMP lab using Containerlab. The lab includes multiple routers and PCs configured to test the behavior of BGP and ECMP in a controlled environment. BGP (Border Gateway Protocol) is used to exchange routing information between different networks, while ECMP (Equal-Cost Multi-Path) allows for load balancing across multiple paths of equal cost. 5 | 6 | 7 | 8 | ## Requirements 9 | * Prerequisites: [Docker](https://docs.docker.com/engine/install/), [Containerlab](https://containerlab.dev/install/) 10 | * Linux distribution that can run both (Debian, CentOS, Ubuntu, Fedora) 11 | 12 | 13 | ## Setup Instructions 14 | 15 | Clone this repository and navigate to this directory: 16 | ```sh 17 | cd cnf-examples/vpp-bgp-ecmp 18 | ``` 19 | 20 | ### 1. Run the Setup Script 21 | Execute the `run.sh` script to deploy the topology and configure the network interfaces: 22 | 23 | ```sh 24 | ./run.sh 25 | ``` 26 | ### 2. Verify the Setup 27 | Open multiple terminal tabs and run the following commands to verify the setup. 28 | 29 | #### First Tab 30 | ```sh 31 | docker exec -it clab-frr01-PC2 iperf3 -s 32 | ``` 33 | #### Second Tab 34 | ```sh 35 | docker exec -it clab-frr01-PC1 iperf3 -c 192.168.16.2 -u -t 0 36 | ``` 37 | #### Third Tab 38 | ```sh 39 | docker exec -it clab-frr01-router1 bash 40 | ``` 41 | ```sh 42 | show ip route 43 | ``` 44 | ```sh 45 | show interfaces counter 46 | config interface shutdown Ethernet0 47 | show interfaces counter 48 | ``` -------------------------------------------------------------------------------- /vpp-traceability/README.md: -------------------------------------------------------------------------------- 1 | VPP Traceability with eBPF 2 | ========================== 3 | 4 | VPP-BPF tooling is Python script build on BCC [https://github.com/iovisor/bcc], a 5 | Berkeley Packet Filter Compiler Collection. 6 | 7 | It enables to trace running VPP and displays combines output from all USDT probes, 8 | inserted into VPP's code (see below) including data-plane (interface, error and node counters) 9 | and control-plane changes performed via CLI and/or API commands into one otput. 10 | 11 | Linux Kernel Requirements: 12 | -------------- 13 | 14 | It is recommended that you are running a Linux 4.9 kernel or higher. 15 | 16 | Requirements: 17 | -------------- 18 | ### Installed BCC and BPFtrace 19 | 20 | - [https://github.com/iovisor/bcc/blob/master/INSTALL.md] 21 | - [https://github.com/iovisor/bpftrace/blob/master/INSTALL.md] 22 | 23 | ### VPP [FD.io] 24 | 25 | - Clone VPP with eBPF tracing support 26 | ``` 27 | git clone "https://gerrit.fd.io/r/vpp" 28 | git review -d 27945 29 | ``` 30 | Build: 31 | -------------- 32 | ### build with USDT probes 33 | 34 | - Install SystemTap 35 | ``` 36 | apt-get install systemtap-sdt-dev 37 | ``` 38 | - Annotated code using SystemTap macros from patch 39 | ``` 40 | vpp-traceability.diff 41 | ``` 42 | - Rebuild vpp with annotated code 43 | 44 | ### start VPP 45 | 46 | ``` 47 | vpp -c startup.conf 48 | ``` 49 | 50 | ### start VPP-BPF tooling and attach it to running VPP 51 | 52 | ``` 53 | python vpp_bpftrace.py -r 1 -p `pgrep vpp` 54 | ``` 55 | -------------------------------------------------------------------------------- /nsm/LFNWebinar/client.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # DHCP configuration 3 | apiVersion: pantheon.tech/v1 4 | kind: CNFConfiguration 5 | metadata: 6 | name: client 7 | spec: 8 | microservice: client 9 | configItems: 10 | - module: cnf.nsm 11 | version: v1 12 | type: client 13 | data: |- 14 | name: access-to-cnf-network 15 | network_service: cnf-nat-example 16 | outgoing_labels: 17 | - key: app 18 | value: client 19 | interface_name: tap0 20 | interface_type: KERNEL_INTERFACE 21 | ipAddresses: 22 | - "192.168.100.10/24" 23 | - module: linux.l3 24 | type: route 25 | data: |- 26 | outgoing_interface: tap0 27 | scope: GLOBAL 28 | dst_network: 80.80.80.0/24 29 | gw_addr: 192.168.100.1 30 | 31 | --- 32 | apiVersion: v1 33 | kind: Pod 34 | metadata: 35 | name: client 36 | labels: 37 | cnf: client 38 | spec: 39 | containers: 40 | - name: client 41 | image: pantheontech/nsm-agent-linux:v3.1.0 42 | imagePullPolicy: IfNotPresent 43 | securityContext: 44 | privileged: true 45 | env: 46 | - name: ETCD_CONFIG 47 | value: "/etc/etcd/etcd.conf" 48 | - name: MICROSERVICE_LABEL 49 | value: "client" 50 | resources: 51 | limits: 52 | networkservicemesh.io/socket: 1 53 | volumeMounts: 54 | - name: etcd-cfg 55 | mountPath: /etc/etcd 56 | volumes: 57 | - name: etcd-cfg 58 | configMap: 59 | name: cnf-etcd-cfg 60 | -------------------------------------------------------------------------------- /vpp-traceability/vlib_error_counters.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Pantheon.tech and/or its affiliates. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | 18 | struct hash_key_t 19 | { 20 | char name[32]; 21 | u64 counter_index; 22 | }; 23 | 24 | struct hash_leaf_error_counter_t 25 | { 26 | u64 total; 27 | }; 28 | 29 | BPF_HASH(error_counters, struct hash_key_t, struct hash_leaf_error_counter_t); 30 | 31 | /** 32 | * @brief Reads VPP's error counters, and stores them in the error_counter hash. 33 | * @param ctx The BPF context. 34 | * 35 | */ 36 | int vpp_error_counters(struct pt_regs *ctx) { 37 | struct hash_key_t key = {}; 38 | bpf_usdt_readarg_p(1, ctx, &key.name, sizeof(key.name)); 39 | bpf_usdt_readarg(2, ctx, &key.counter_index); 40 | 41 | struct hash_leaf_error_counter_t counter = {}; 42 | bpf_usdt_readarg(3, ctx, &counter.total); 43 | 44 | bpf_trace_printk("%s[%d] : %d\n", key.name, key.counter_index, counter.total); 45 | 46 | error_counters.update(&key, &counter); 47 | return 0; 48 | }; -------------------------------------------------------------------------------- /vpp-traceability/vnet_route_updates.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Pantheon.tech and/or its affiliates. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | 18 | struct data_t 19 | { 20 | u32 is_del; 21 | u32 is_ipv6; 22 | u32 fib_index; 23 | u8 path[16]; 24 | u32 path_len; 25 | u8 route[16]; 26 | }; 27 | 28 | BPF_PERF_OUTPUT(route_events); 29 | 30 | /** 31 | * @brief Reads VPP's ROUTE updates, flush it using BPF perf event. 32 | * @param ctx The BPF context. 33 | * 34 | * DTRACE_PROBE ... 35 | */ 36 | int vpp_route_updates(struct pt_regs *ctx) { 37 | struct data_t data = { 0 }; 38 | 39 | bpf_usdt_readarg(1, ctx, &data.is_del); 40 | bpf_usdt_readarg(2, ctx, &data.is_ipv6); 41 | bpf_usdt_readarg(3, ctx, &data.fib_index); 42 | bpf_usdt_readarg_p(4, ctx, &data.path, sizeof(data.path)); 43 | bpf_usdt_readarg(5, ctx, &data.path_len); 44 | bpf_usdt_readarg_p(6, ctx, &data.route, sizeof(data.route)); 45 | 46 | route_events.perf_submit(ctx, &data, sizeof(data)); 47 | 48 | return 0; 49 | }; -------------------------------------------------------------------------------- /vpp-traceability/vlib_simple_counters.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Pantheon.tech and/or its affiliates. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | 18 | struct hash_key_t 19 | { 20 | char name[16]; 21 | u32 counter_index; 22 | }; 23 | 24 | struct hash_leaf_simple_counter_t 25 | { 26 | u64 total; 27 | }; 28 | 29 | BPF_HASH(simple_counters, struct hash_key_t, struct hash_leaf_simple_counter_t, 16); 30 | 31 | /** 32 | * @brief Reads VPP's simple counters, and stores them in the simple_counter hash. 33 | * @param ctx The BPF context. 34 | * 35 | */ 36 | int vpp_simple_counters(struct pt_regs *ctx) { 37 | struct hash_key_t key = {}; 38 | bpf_usdt_readarg_p(1, ctx, &key.name, sizeof(key.name)); 39 | bpf_usdt_readarg(2, ctx, &key.counter_index); 40 | 41 | struct hash_leaf_simple_counter_t counter = {}; 42 | bpf_usdt_readarg(3, ctx, &counter.total); 43 | 44 | bpf_trace_printk("%s[if_idx %d] : %d\n", key.name, key.counter_index, counter.total); 45 | 46 | simple_counters.update(&key, &counter); 47 | return 0; 48 | }; -------------------------------------------------------------------------------- /vpp-traceability/vnet_arp_updates.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Pantheon.tech and/or its affiliates. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | 18 | struct data_t 19 | { 20 | u32 is_del; 21 | u32 is_ipv6; 22 | u32 sw_if_index; 23 | u8 ip_address[16]; 24 | u8 mac_address[6]; 25 | u32 flags; 26 | }; 27 | 28 | BPF_PERF_OUTPUT(nbh_events); 29 | 30 | /** 31 | * @brief Reads VPP's neighbor updates (ARP / NS), flush it using BPF perf event. 32 | * @param ctx The BPF context. 33 | * 34 | * DTRACE_PROBE ... 35 | */ 36 | int vpp_nbh_updates(struct pt_regs *ctx) { 37 | struct data_t data = {}; 38 | 39 | bpf_usdt_readarg(1, ctx, &data.is_del); 40 | bpf_usdt_readarg(2, ctx, &data.is_ipv6); 41 | bpf_usdt_readarg(3, ctx, &data.sw_if_index); 42 | bpf_usdt_readarg_p(4, ctx,&data.ip_address, sizeof(data.ip_address)); 43 | bpf_usdt_readarg_p(5, ctx,&data.mac_address, sizeof(data.mac_address)); 44 | bpf_usdt_readarg(6, ctx, &data.flags); 45 | 46 | nbh_events.perf_submit(ctx, &data, sizeof(data)); 47 | 48 | return 0; 49 | }; -------------------------------------------------------------------------------- /vpp-traceability/vnet_neighbor_updates.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Pantheon.tech and/or its affiliates. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | 18 | struct data_t 19 | { 20 | u32 is_del; 21 | u32 is_ipv6; 22 | u32 sw_if_index; 23 | u8 ip_address[16]; 24 | u8 mac_address[6]; 25 | u32 flags; 26 | }; 27 | 28 | BPF_PERF_OUTPUT(nbh_events); 29 | 30 | /** 31 | * @brief Reads VPP's neighbor updates (ARP / NS), flush it using BPF perf event. 32 | * @param ctx The BPF context. 33 | * 34 | * DTRACE_PROBE ... 35 | */ 36 | int vpp_nbh_updates(struct pt_regs *ctx) { 37 | struct data_t data = {}; 38 | 39 | bpf_usdt_readarg(1, ctx, &data.is_del); 40 | bpf_usdt_readarg(2, ctx, &data.is_ipv6); 41 | bpf_usdt_readarg(3, ctx, &data.sw_if_index); 42 | bpf_usdt_readarg_p(4, ctx,&data.ip_address, sizeof(data.ip_address)); 43 | bpf_usdt_readarg_p(5, ctx,&data.mac_address, sizeof(data.mac_address)); 44 | bpf_usdt_readarg(6, ctx, &data.flags); 45 | 46 | nbh_events.perf_submit(ctx, &data, sizeof(data)); 47 | 48 | return 0; 49 | }; -------------------------------------------------------------------------------- /vpp-traceability/vnet_ip_updates.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Pantheon.tech and/or its affiliates. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | 18 | struct data_t 19 | { 20 | u32 is_del; 21 | u32 is_ipv6; 22 | u32 sw_if_index; 23 | u8 ip_address[16]; 24 | u32 address_length; 25 | }; 26 | 27 | BPF_PERF_OUTPUT(ip_events); 28 | 29 | /** 30 | * @brief Reads VPP's IP updates, flush it using BPF perf event. 31 | * @param ctx The BPF context. 32 | * 33 | * DTRACE_PROBE ... 34 | */ 35 | int vpp_ip_updates(struct pt_regs *ctx) { 36 | struct data_t data = { 0 }; 37 | 38 | bpf_usdt_readarg(1, ctx, &data.is_del); 39 | bpf_usdt_readarg(2, ctx, &data.is_ipv6); 40 | bpf_usdt_readarg(3, ctx, &data.sw_if_index); 41 | bpf_usdt_readarg_p(4, ctx, &data.ip_address, sizeof(data.ip_address)); 42 | bpf_usdt_readarg(5, ctx, &data.address_length); 43 | 44 | ip_events.perf_submit(ctx, &data, sizeof(data)); 45 | 46 | bpf_trace_printk("sw_if_index %d is_del = %d is_ipv6 = %d\n", data.sw_if_index, data.is_del, data.is_ipv6); 47 | 48 | return 0; 49 | }; -------------------------------------------------------------------------------- /vpp-vxlan/README.md: -------------------------------------------------------------------------------- 1 | To launch the project, simply execute the run.sh script: 2 | 3 | ```bash 4 | ./run.sh 5 | ``` 6 | 7 | The run.sh script orchestrates the setup and configuration of the VXLAN environment. 8 | 9 | ## Verifying the Setup 10 | 11 | - Verify Container 12 | 13 | ```bash 14 | docker ps 15 | ``` 16 | Ensure that you see containers for Router 1, Router 2, PC1, and PC2. 17 | 18 | - Verify BGP Status 19 | 20 | ```bash 21 | docker exec clab-frr01-router1 vtysh -c "show ip bgp summary" 22 | docker exec clab-frr01-router2 vtysh -c "show ip bgp summary" 23 | ``` 24 | 25 | - Verify VXLAN Interfaces 26 | 27 | ```bash 28 | docker exec clab-frr01-router1 ip -d link show type vxlan 29 | docker exec clab-frr01-router2 ip -d link show type vxlan 30 | ``` 31 | 32 | - Verify VXLAN Interfaces on VPP 33 | ```bash 34 | docker exec -it clab-frr01-router1 vppctl show vxlan tunnel 35 | docker exec -it clab-frr01-router2 vppctl show vxlan tunnel 36 | ``` 37 | 38 | - Verify EVPN Routes 39 | 40 | 41 | ```bash 42 | docker exec clab-frr01-router1 vtysh -c "show bgp l2vpn evpn" 43 | docker exec clab-frr01-router2 vtysh -c "show bgp l2vpn evpn" 44 | ``` 45 | 46 | - Test Connectivity 47 | 48 | ```bash 49 | docker exec clab-frr01-PC1 ping -c 5 168.95.10.1 50 | ``` 51 | 52 | 53 | - Packet Tracing 54 | 55 | - Enable Packet Tracing 56 | 57 | ```bash 58 | docker exec -it clab-frr01-router1 vppctl trace add af-packet-input 10 59 | ``` 60 | 61 | - Generate Traffic 62 | 63 | ```bash 64 | docker exec clab-frr01-PC1 ping -c 5 168.95.10.1 65 | ``` 66 | 67 | - View Trace Results 68 | 69 | ```bash 70 | docker exec clab-frr01-router1 vppctl show trace 71 | ``` 72 | -------------------------------------------------------------------------------- /vpp-traceability/vnet_nat_updates.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Pantheon.tech and/or its affiliates. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | 18 | struct data_t 19 | { 20 | u8 operation; 21 | u32 thread_index; 22 | u32 fib_index; 23 | u32 protocol; 24 | u32 in2out_addr; 25 | u32 in2out_port; 26 | u32 out2in_addr; 27 | u32 out2in_port; 28 | }; 29 | 30 | BPF_PERF_OUTPUT(nat_events); 31 | 32 | /** 33 | * @brief Reads VPP's NAT updates, flush it using BPF perf event. 34 | * @param ctx The BPF context. 35 | * 36 | * DTRACE_PROBE ... 37 | */ 38 | int vpp_nat_session_updates(struct pt_regs *ctx) { 39 | struct data_t data = { 0 }; 40 | 41 | bpf_usdt_readarg(1, ctx, &data.operation); 42 | bpf_usdt_readarg(2, ctx, &data.thread_index); 43 | bpf_usdt_readarg(3, ctx, &data.fib_index); 44 | bpf_usdt_readarg(4, ctx, &data.protocol); 45 | bpf_usdt_readarg(5, ctx, &data.in2out_addr); 46 | bpf_usdt_readarg(6, ctx, &data.in2out_port); 47 | bpf_usdt_readarg(7, ctx, &data.out2in_addr); 48 | bpf_usdt_readarg(8, ctx, &data.out2in_port); 49 | 50 | nat_events.perf_submit(ctx, &data, sizeof(data)); 51 | 52 | return 0; 53 | }; -------------------------------------------------------------------------------- /vpp-traceability/vlib_combined_counters.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Pantheon.tech and/or its affiliates. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | 18 | struct hash_key_t 19 | { 20 | // char name[16]; 21 | u32 counter_index; 22 | }; 23 | 24 | struct hash_leaf_combined_counter_t 25 | { 26 | u64 packets; 27 | u64 bytes; 28 | }; 29 | 30 | BPF_HASH(combined_counters, u32, struct hash_leaf_combined_counter_t, 16); 31 | 32 | /** 33 | * @brief Reads VPP's combined counters, and stores them in the combined_counter hash. 34 | * @param ctx The BPF context. 35 | * 36 | * DTRACE_PROBE ... 37 | */ 38 | int vpp_combined_counters(struct pt_regs *ctx) { 39 | struct hash_key_t key = {}; 40 | // bpf_usdt_readarg_p(1, ctx, &key.name, sizeof(key.name)); 41 | // bpf_usdt_readarg(2, ctx, &key.counter_index); 42 | 43 | bpf_usdt_readarg(1, ctx, &key.counter_index); 44 | 45 | struct hash_leaf_combined_counter_t counter = {}; 46 | // bpf_usdt_readarg(3, ctx, &counter.packets); 47 | // bpf_usdt_readarg(4, ctx, &counter.bytes); 48 | 49 | bpf_usdt_readarg(2, ctx, &counter.packets); 50 | 51 | // bpf_trace_printk("[%d] : %d\\n", key, counter.packets); 52 | bpf_trace_printk("%d : %d\\n", counter.packets, counter.bytes); 53 | 54 | // combined_counters.update(&key, &counter); 55 | return 0; 56 | }; -------------------------------------------------------------------------------- /vpp-bgp-ecmp/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check if Docker is installed 4 | if ! command -v docker &> /dev/null; then 5 | echo "Docker is not installed. Please install Docker (https://docs.docker.com/engine/install/) and try again." 6 | exit 1 7 | fi 8 | 9 | # Check if clab is installed 10 | if ! command -v clab &> /dev/null; then 11 | echo "Containerlab is not installed. Please install Containerlab (https://containerlab.dev/install/) and try again." 12 | exit 1 13 | fi 14 | 15 | # Check if the user is part of the docker group 16 | if ! groups $USER | grep -q '\bdocker\b'; then 17 | echo "You are not a member of the docker group. Please add yourself to the docker group using:" 18 | echo "sudo usermod -aG docker $USER" 19 | echo "Then log out and back in for the changes to take effect." 20 | exit 1 21 | fi 22 | 23 | set -x 24 | ROUTER1="docker exec clab-frr01-router1" 25 | ROUTER2="docker exec clab-frr01-router2" 26 | ROUTER3="docker exec clab-frr01-router3" 27 | ROUTER4="docker exec clab-frr01-router4" 28 | 29 | if ! sudo clab deploy --topo frr01.clab.yml; then 30 | { set +x; } > /dev/null 2>&1 31 | echo "Alternatively, you can manually destroy the existing containers using 'sudo clab destroy --topo frr01.clab.yml' and rerun this script." 32 | exit 1 33 | fi 34 | 35 | sleep 60 36 | 37 | set_swss_log_level() { 38 | $1 swssloglevel -l INFO -c syncd 39 | $1 swssloglevel -l INFO -c fdbsyncd 40 | $1 swssloglevel -l INFO -c orchagent 41 | $1 swssloglevel -l SAI_LOG_LEVEL_INFO -s -a 42 | } 43 | 44 | set_swss_log_level "$ROUTER1" 45 | set_swss_log_level "$ROUTER2" 46 | 47 | ./scripts/interfaces.sh 48 | 49 | sleep 10 50 | 51 | execute() { 52 | if [[ "$2" == *.vtysh ]]; then 53 | commands=$(cat $2) 54 | $1 vtysh -c "$commands" 55 | else 56 | mapfile -t commands < $2 57 | for cmd in "${commands[@]}"; do 58 | $1 $cmd 59 | done 60 | fi 61 | } 62 | 63 | execute "$ROUTER1" "routers/router1/r1.vtysh" 64 | execute "$ROUTER2" "routers/router2/r2.vtysh" 65 | execute "$ROUTER3" "routers/router3/r3.vtysh" 66 | execute "$ROUTER4" "routers/router4/r4.vtysh" 67 | 68 | # First sleep is intentional to load all services inside of the containers 69 | # The other is only for better visibility in syslog 70 | -------------------------------------------------------------------------------- /vpp-vxlan/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check if Docker is installed 4 | if ! command -v docker &> /dev/null; then 5 | echo "Docker is not installed. Please install Docker (https://docs.docker.com/engine/install/) and try again." 6 | exit 1 7 | fi 8 | 9 | # Check if clab is installed 10 | if ! command -v clab &> /dev/null; then 11 | echo "Containerlab is not installed. Please install Containerlab (https://containerlab.dev/install/) and try again." 12 | exit 1 13 | fi 14 | 15 | # Check if the user is part of the docker group 16 | if ! groups $USER | grep -q '\bdocker\b'; then 17 | echo "You are not a member of the docker group. Please add yourself to the docker group using:" 18 | echo "sudo usermod -aG docker $USER" 19 | echo "Then log out and back in for the changes to take effect." 20 | exit 1 21 | fi 22 | 23 | set -x 24 | 25 | ROUTER1="docker exec clab-frr01-router1" 26 | ROUTER2="docker exec clab-frr01-router2" 27 | 28 | if ! sudo clab deploy --topo frr01.clab.yml; then 29 | { set +x; } > /dev/null 2>&1 30 | echo "Alternatively, you can manually destroy the existing containers using 'sudo clab destroy --topo frr01.clab.yml' and rerun this script." 31 | exit 1 32 | fi 33 | 34 | sleep 50 35 | 36 | set_swss_log_level() { 37 | $1 swssloglevel -l INFO -c syncd 38 | $1 swssloglevel -l INFO -c fdbsyncd 39 | $1 swssloglevel -l INFO -c orchagent 40 | $1 swssloglevel -l SAI_LOG_LEVEL_INFO -s -a 41 | } 42 | 43 | set_swss_log_level "$ROUTER1" 44 | set_swss_log_level "$ROUTER2" 45 | 46 | ./scripts/PC-interfaces.sh 47 | 48 | execute() { 49 | if [[ "$2" == *.vtysh ]]; then 50 | commands=$(cat $2) 51 | $1 vtysh -c "$commands" 52 | else 53 | mapfile -t commands < $2 54 | 55 | for cmd in "${commands[@]}"; do 56 | $1 $cmd 57 | done 58 | fi 59 | } 60 | 61 | sleep 10 62 | 63 | execute "$ROUTER1" "routers/router1/r1-1.vtysh" 64 | execute "$ROUTER2" "routers/router2/r2-1.vtysh" 65 | 66 | sleep 10 67 | 68 | execute "$ROUTER1" "routers/router1/r1-vxlan.cmd" 69 | execute "$ROUTER2" "routers/router2/r2-vxlan.cmd" 70 | 71 | sleep 10 72 | 73 | execute "$ROUTER1" "routers/router1/r1-2.vtysh" 74 | execute "$ROUTER2" "routers/router2/r2-2.vtysh" 75 | 76 | # First sleep is intentional to load all services inside of the containers 77 | # The others are only for better visibility in syslog 78 | 79 | 80 | -------------------------------------------------------------------------------- /vpp-bgp-ecmp/frr01.clab.yml: -------------------------------------------------------------------------------- 1 | name: frr01 2 | 3 | topology: 4 | nodes: 5 | router1: 6 | kind: linux 7 | image: ghcr.io/pantheontech/sonic-vpp:24.04.0 8 | binds: 9 | - routers/router1/daemons:/etc/frr/daemons 10 | env: 11 | DPDK_DISABLE: "y" 12 | VPP_DPDK_PORTS: "eth1,eth2,eth3" 13 | SONIC_NUM_PORTS: 3 14 | VPP_CONF_DB: "n" 15 | NO_LINUX_NL: "y" 16 | entrypoint: /bin/sh -c "sleep 10; /usr/local/bin/start_sonic.sh" 17 | ports: 18 | - 6379:6379 19 | - 8081:8081 20 | router2: 21 | kind: linux 22 | image: ghcr.io/pantheontech/sonic-vpp:24.04.0 23 | binds: 24 | - routers/router2/daemons:/etc/frr/daemons 25 | env: 26 | DPDK_DISABLE: "y" 27 | VPP_DPDK_PORTS: "eth1,eth2" 28 | SONIC_NUM_PORTS: 2 29 | VPP_CONF_DB: "n" 30 | NO_LINUX_NL: "y" 31 | entrypoint: /bin/sh -c "sleep 10; /usr/local/bin/start_sonic.sh" 32 | ports: 33 | - 8082:8081 34 | router3: 35 | kind: linux 36 | image: ghcr.io/pantheontech/sonic-vpp:24.04.0 37 | binds: 38 | - routers/router1/daemons:/etc/frr/daemons 39 | env: 40 | DPDK_DISABLE: "y" 41 | VPP_DPDK_PORTS: "eth1,eth2" 42 | SONIC_NUM_PORTS: 2 43 | VPP_CONF_DB: "n" 44 | NO_LINUX_NL: "y" 45 | entrypoint: /bin/sh -c "sleep 10; /usr/local/bin/start_sonic.sh" 46 | router4: 47 | kind: linux 48 | image: ghcr.io/pantheontech/sonic-vpp:24.04.0 49 | binds: 50 | - routers/router1/daemons:/etc/frr/daemons 51 | env: 52 | DPDK_DISABLE: "y" 53 | VPP_DPDK_PORTS: "eth1,eth2,eth3" 54 | SONIC_NUM_PORTS: 3 55 | VPP_CONF_DB: "n" 56 | NO_LINUX_NL: "y" 57 | entrypoint: /bin/sh -c "sleep 10; /usr/local/bin/start_sonic.sh" 58 | 59 | PC1: 60 | kind: linux 61 | image: wbitt/network-multitool:extra 62 | PC2: 63 | kind: linux 64 | image: wbitt/network-multitool:extra 65 | links: 66 | - endpoints: ["router1:eth1", "router2:eth1"] 67 | - endpoints: ["router1:eth2", "router3:eth1"] 68 | - endpoints: ["router2:eth2", "router4:eth1"] 69 | - endpoints: ["router3:eth2", "router4:eth2"] 70 | - endpoints: ["PC1:eth1", "router1:eth3"] 71 | - endpoints: ["PC2:eth1", "router4:eth3"] 72 | -------------------------------------------------------------------------------- /nsm/LFNWebinar/webserver.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: pantheon.tech/v1 3 | kind: CNFConfiguration 4 | metadata: 5 | name: webserver 6 | spec: 7 | microservice: webserver 8 | configItems: 9 | - module: cnf.nsm 10 | version: v1 11 | type: endpoint 12 | data: |- 13 | network_service: cnf-nat-example 14 | advertised_labels: 15 | - key: app 16 | value: webserver 17 | interface_name_prefix: memif # full name: memif0 18 | interface_type: MEM_INTERFACE 19 | single_client: true 20 | ipAddresses: 21 | - "80.80.80.80/24" 22 | 23 | --- 24 | apiVersion: v1 25 | kind: ConfigMap 26 | metadata: 27 | name: vpp-startup-cfg 28 | data: 29 | vpp.conf: | 30 | unix { 31 | nodaemon 32 | cli-listen /run/vpp/cli.sock 33 | cli-no-pager 34 | log /tmp/vpp.log 35 | coredump-size unlimited 36 | full-coredump 37 | poll-sleep-usec 50 38 | startup-config /etc/vpp/cli-config.txt 39 | } 40 | plugins { 41 | plugin dpdk_plugin.so { 42 | disable 43 | } 44 | } 45 | api-trace { 46 | on 47 | } 48 | socksvr { 49 | default 50 | } 51 | statseg { 52 | default 53 | per-node-counters on 54 | } 55 | nat { 56 | endpoint-dependent 57 | translation hash buckets 1048576 58 | translation hash memory 268435456 59 | user hash buckets 1024 60 | max translations per user 10000 61 | } 62 | cli-config.txt: | 63 | comment { start HTTP server } 64 | test http server 65 | 66 | --- 67 | apiVersion: v1 68 | kind: Pod 69 | metadata: 70 | name: webserver 71 | labels: 72 | app: webserver 73 | spec: 74 | containers: 75 | - name: webserver 76 | image: pantheontech/nsm-agent-vpp:v3.1.0 77 | env: 78 | - name: ETCD_CONFIG 79 | value: "/etc/etcd/etcd.conf" 80 | - name: MICROSERVICE_LABEL 81 | value: "webserver" 82 | resources: 83 | limits: 84 | networkservicemesh.io/socket: 1 85 | volumeMounts: 86 | - name: etcd-cfg 87 | mountPath: /etc/etcd 88 | - name: vpp-startup-cfg 89 | mountPath: /etc/vpp 90 | volumes: 91 | - name: etcd-cfg 92 | configMap: 93 | name: cnf-etcd-cfg 94 | - name: vpp-startup-cfg 95 | configMap: 96 | name: vpp-startup-cfg 97 | -------------------------------------------------------------------------------- /nsm/LFNWebinar/cnf-nat44.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # NAT44 configuration 3 | apiVersion: pantheon.tech/v1 4 | kind: CNFConfiguration 5 | metadata: 6 | name: cnf-nat44 7 | spec: 8 | microservice: cnf-nat44 9 | configItems: 10 | - module: cnf.nsm 11 | version: v1 12 | type: endpoint 13 | data: |- 14 | network_service: cnf-nat-example 15 | advertised_labels: 16 | - key: app 17 | value: nat44 18 | interface_name_prefix: memif # full name: memif0 19 | interface_type: MEM_INTERFACE 20 | single_client: true 21 | ipAddresses: 22 | - "192.168.100.1/24" 23 | 24 | - module: cnf.nsm 25 | version: v1 26 | type: client 27 | data: |- 28 | name: access-to-external-network 29 | network_service: cnf-nat-example 30 | outgoing_labels: 31 | - key: app 32 | value: nat44 33 | interface_name: memif1 34 | interface_type: MEM_INTERFACE 35 | ipAddresses: 36 | - "80.80.80.100/24" 37 | 38 | - module: vpp.nat 39 | type: nat44-interface 40 | data: |- 41 | name: memif1 42 | nat_outside: true 43 | output_feature: true 44 | 45 | - module: vpp.nat 46 | type: nat44-interface 47 | data: |- 48 | name: memif0 49 | nat_inside: true 50 | 51 | - module: vpp.nat 52 | type: nat44-pool 53 | data: |- 54 | first_ip: 80.80.80.100 55 | last_ip: 80.80.80.105 56 | 57 | --- 58 | # CNF-NAT44 pod definition 59 | apiVersion: v1 60 | kind: Pod 61 | metadata: 62 | name: cnf-nat44 63 | labels: 64 | cnf: cnf-nat44 65 | spec: 66 | containers: 67 | - name: cnf-nat44 68 | image: pantheontech/nsm-agent-vpp:v3.1.0 69 | imagePullPolicy: IfNotPresent 70 | securityContext: 71 | privileged: true 72 | ports: 73 | - containerPort: 9191 74 | name: http 75 | env: 76 | - name: ETCD_CONFIG 77 | value: "/etc/etcd/etcd.conf" 78 | - name: MICROSERVICE_LABEL 79 | value: "cnf-nat44" 80 | - name: ETCD_EXPAND_ENV_VARS 81 | value: "true" 82 | resources: 83 | limits: 84 | networkservicemesh.io/socket: 1 85 | volumeMounts: 86 | - name: etcd-cfg 87 | mountPath: /etc/etcd 88 | volumes: 89 | - name: etcd-cfg 90 | configMap: 91 | name: cnf-etcd-cfg 92 | -------------------------------------------------------------------------------- /nsm/LFNWebinar/img/lfn-webinar-routing.xml: -------------------------------------------------------------------------------- 1 | 2 | 7Zxbc6M2FIB/jWfah3iQBNg8OhfvdqZ7mUmn7T7KIBs1GFGQE2d/fSUQBnGxHQN2kobsJNZB16NPR0cX7wjdrLefYhz5X5hHghE0vO0I3Y4gnAIofkvBcyawTJQJVjH1MhEoBPf0J1FCQ0k31COJFpEzFnAa6UKXhSFxuSbDccye9GhLFuilRnhFaoJ7Fwd16V/U475qlmUU8s+Ervy8ZGCoN2ucR1aCxMceeyqJ0N0I3cSM8ezTentDAqm7XC9ZunnL213FYhLyYxKgpQdm4eKz8+nnw+L226M1wfRqmuXyiIONavAI2oHI79qjj7LS/Flpwv53I2t6vWQhv0rSfpqJCABE2+Kl+LRSf4M88um5PJFFQuJHEufZicZlOeqlCHFa21wKtSKhUIOghcgMfcrJfYRd+eZJ8CpkPl8HIgTER5xEGUJLuiWequUNC1icZoSyR8gTHrMHUnpjp49MQYOgJL+z5c+uUqIpnGxb+w/sqBCjibA14fGziKISiB4cA+gUzyTLQQ0sR2H2VFA6USK/BGguw2pcrHblFOiID4qeF5AEwGtGSVqIgJKUncugpINB0qcJJWQjB3k9IoM0TEzj0pygulY9YXJVMGShVEvMNqEnFXdriBCLuc9WLMTB74xFSsX/EM6f1YSBN5zpHUBCbybNvwi6AU4S6mbCOQ12UbaU/y1LGFsq9EOVJz/fbsuB5zwQCh2UEsngj12RIlAkS0N5uqzNsqH7u1LohW1il+xRoK0UyHG8InxPRDhphiMmAeb0Ua9JUz+rpN8ZTYdeDpVljQ3DMvIHaHxBVAEna4/Kozw9VbO1DS0j4FQyytpbyyiFcNe6Dlxar4bLExk7heceuUTOkVwicyAuHd3SgVNJtJyxU360bNGZuYTwPFw2wgMOGMODLB/LV+80mFA3J6ZjnUbDwYyG7n/U6lcd7RIZuktkLLGrJ1izkCWpM1OO5u68kkKIpjemoYsyX2lqjLN/Ql1zaLb6WRWWhXPDdRJ1j0jxXXaflAgHdBVK9ARJYomArqWrRMXKbaZerKnnBW2+mj5gPJz4aQDUvf4ptGfguieHzJEO2W7qNGDzlFfyzcwG3wwO5ZtB822wBhw4BvZ0LBbbH7jtxU26asVjWvpUZl2at0ln3qYV3Jo5ynRa42hN1nR5LDpFF4LD67/Kcm9pyZ/9Owctew19YIDs8XRqFg6NrZsdy65jAMdWHQRgDQQC6m54qiB0sjsfvECdEWRYdUbQeHJWSJw3AQkXffv+ETGBMCnNC6MSIui8ZsRs8pUrOk98HGULJ37EPt4Cuw+rtJu+bXhApSeQyj0cP3wTqShPF0Njw9Im+cKxyA8NGnpwDudoPuunP9BUX6U09UXT1L5L139fdDfpzkmjVd/QXeQCHNE/SZxQFqaZ7wbookhhhIQ/sfhBHjpQl6xJ4o8pE3EeAQ4iH4NdpnFrMQ809NoL+JoVcJ8VcER2oi+whzluzbIhB7yWEIeLJMoKrWUa4jVpr6MbLq9CzK/IVmQUHFNJudfdawUj/BwwvEePv30/LeM15q4vjxOPr2yZ2MZ5QLjV6ehsILBSn0NhUV80Ko4yiyMLgzP5yxedYfwSMLHokMOHejLMlr8WnWa2L4QOq+uI6lXUeTVKzzldv6TQLiUcrEG2aXNPAqEf2RMnMzd4+CA2jiNXZE3Y1PWMoyiziE3NPepca1Bd6JWVe3dsw8mZmDjIjITUIwmnYnzo1v+igByqdqnKb4H3rs3tNmRaxku7rmrDpFMFXmx590XUzp/P6jAN0Wfts6M+1anJjWw5icPT57cjj/UvrekzOhUHe7HkW7zgws3xWn6d8NYnrdfjzFx0uuxiB2t2t4WSmjk+0VEa2uM9CE1Nex+ez9Cez2uu+rsaXCdPBqcdueXnawFZyugdTtd62E7b3ZLLj0gMVN9PA037adaemwrd9tPar+p2vRpZN2s9ZHvzdS43vGZ/HOOz1coecufcw2S6dGscyp1zd0oWy34QAs60evcSmvVDFAAbKLKH2pTND3z7O0LJ+ufr/ZemfYva1sSL+/kVntfLwHfM5TollYgBMKqdtSj/vR+SKjcj0XQybjiNO+fBvdXdGL2EIxJ6UXa/6oOkbiRVLoDkF5AuxZH9YY/eIkW6PYLw4vbIhh/26E2SpNsjYNXd7PNy1P2y7cc9pH7vIVmli/gVdzr/qskF7ySZTXeS+uoANd733RY1DNtu/krioB7oxGmw+MBqWhDbQ7mgTXdH373moWNeXvP/S+Zh3sqL6d1u+obtu9c7MK0BiRfB4hv42Vd2iv/GAN39Bw== -------------------------------------------------------------------------------- /vpp-bgp-ecmp/scripts/interfaces.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | sudo docker exec -d clab-frr01-PC1 ip link set eth1 up 4 | sudo docker exec -d clab-frr01-PC1 ip addr add 192.168.11.2/24 dev eth1 5 | sudo docker exec -d clab-frr01-PC1 ip route add 192.168.0.0/16 via 192.168.11.1 dev eth1 6 | sudo docker exec -d clab-frr01-PC1 ip route add 10.10.10.0/24 via 192.168.11.1 dev eth1 7 | #iperf3 has obviously problem with larger mtu and fragmentation, so for testing purpose mtu is set to 1500 8 | sudo docker exec -d clab-frr01-PC1 ip link set dev eth1 mtu 1500 9 | 10 | sudo docker exec -d clab-frr01-PC2 ip link set eth1 up 11 | sudo docker exec -d clab-frr01-PC2 ip addr add 192.168.16.2/24 dev eth1 12 | sudo docker exec -d clab-frr01-PC2 ip route add 192.168.0.0/16 via 192.168.16.1 dev eth1 13 | sudo docker exec -d clab-frr01-PC2 ip route add 10.10.10.0/24 via 192.168.16.1 dev eth1 14 | 15 | sudo docker exec -d clab-frr01-router1 config interface ip add Ethernet0 192.168.12.1/24 16 | sudo docker exec -d clab-frr01-router1 config interface ip add Ethernet1 192.168.13.1/24 17 | sudo docker exec -d clab-frr01-router1 config interface ip add Ethernet2 192.168.11.1/24 18 | sudo docker exec -d clab-frr01-router1 config interface startup Ethernet0 19 | sudo docker exec -d clab-frr01-router1 config interface startup Ethernet1 20 | sudo docker exec -d clab-frr01-router1 config interface startup Ethernet2 21 | 22 | 23 | sudo docker exec -d clab-frr01-router2 config interface ip add Ethernet0 192.168.12.2/24 24 | sudo docker exec -d clab-frr01-router2 config interface ip add Ethernet1 192.168.14.1/24 25 | sudo docker exec -d clab-frr01-router2 config interface startup Ethernet0 26 | sudo docker exec -d clab-frr01-router2 config interface startup Ethernet1 27 | 28 | sudo docker exec -d clab-frr01-router3 config interface ip add Ethernet0 192.168.13.2/24 29 | sudo docker exec -d clab-frr01-router3 config interface ip add Ethernet1 192.168.15.1/24 30 | sudo docker exec -d clab-frr01-router3 config interface startup Ethernet0 31 | sudo docker exec -d clab-frr01-router3 config interface startup Ethernet1 32 | 33 | sudo docker exec -d clab-frr01-router4 config interface ip add Ethernet0 192.168.14.2/24 34 | sudo docker exec -d clab-frr01-router4 config interface ip add Ethernet1 192.168.15.2/24 35 | sudo docker exec -d clab-frr01-router4 config interface ip add Ethernet2 192.168.16.1/24 36 | sudo docker exec -d clab-frr01-router4 config interface startup Ethernet0 37 | sudo docker exec -d clab-frr01-router4 config interface startup Ethernet1 38 | sudo docker exec -d clab-frr01-router4 config interface startup Ethernet2 39 | 40 | -------------------------------------------------------------------------------- /vpp-traceability/vnet_interfaces.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Pantheon.tech and/or its affiliates. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | 18 | struct hash_key_t 19 | { 20 | u32 if_index; 21 | }; 22 | 23 | struct hash_leaf_interface_info_t 24 | { 25 | char if_name[32]; 26 | u32 state; 27 | u32 thread_index; // rx_placement 28 | u32 queue_id; // rx_placement 29 | u32 queue_mode; 30 | }; 31 | 32 | BPF_HASH(intfs_info, struct hash_key_t, struct hash_leaf_interface_info_t); 33 | 34 | int vpp_intfs_state(struct pt_regs *ctx) { 35 | struct hash_key_t key = {}; 36 | bpf_usdt_readarg(1, ctx, &key.if_index); 37 | 38 | struct hash_leaf_interface_info_t zero = {}; 39 | struct hash_leaf_interface_info_t* info = intfs_info.lookup_or_try_init(&key, &zero); 40 | if (0 == info) { 41 | return 0; 42 | } 43 | bpf_usdt_readarg(2, ctx, &info->state); 44 | bpf_usdt_readarg_p(3, ctx, &info->if_name, sizeof(info->if_name)); 45 | 46 | return 0; 47 | } 48 | 49 | /** 50 | * @brief Reads VPP's stat counters, and stores them in the stats_counters hash. 51 | * @param ctx The BPF context. 52 | */ 53 | int vpp_intfs_rx_placement(struct pt_regs *ctx) { 54 | struct hash_key_t key = {}; 55 | bpf_usdt_readarg(1, ctx, &key.if_index); 56 | 57 | struct hash_leaf_interface_info_t zero = {}; 58 | struct hash_leaf_interface_info_t* info = intfs_info.lookup_or_try_init(&key, &zero); 59 | if (0 == info) { 60 | return 0; 61 | } 62 | bpf_usdt_readarg(2, ctx, &info->thread_index); 63 | bpf_usdt_readarg(3, ctx, &info->queue_id); 64 | 65 | return 0; 66 | }; 67 | 68 | /** 69 | * @brief Reads VPP's stat counters, and stores them in the stats_counters hash. 70 | * @param ctx The BPF context. 71 | */ 72 | int vpp_intfs_rx_mode(struct pt_regs *ctx) { 73 | struct hash_key_t key = {}; 74 | bpf_usdt_readarg(1, ctx, &key.if_index); 75 | 76 | struct hash_leaf_interface_info_t zero = {}; 77 | struct hash_leaf_interface_info_t* info = intfs_info.lookup_or_try_init(&key, &zero); 78 | if (0 == info) { 79 | return 0; 80 | } 81 | bpf_usdt_readarg(2, ctx, &info->queue_mode); 82 | 83 | return 0; 84 | }; 85 | -------------------------------------------------------------------------------- /sonic-vpp/sonic-vpp-L3-BGP/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check if Docker is installed 4 | if ! command -v docker &> /dev/null; then 5 | echo "Docker is not installed. Please install Docker (https://docs.docker.com/engine/install/) and try again." 6 | exit 1 7 | fi 8 | 9 | # Check if clab is installed 10 | if ! command -v clab &> /dev/null; then 11 | echo "Containerlab is not installed. Please install Containerlab (https://containerlab.dev/install/) and try again." 12 | exit 1 13 | fi 14 | 15 | # Check if the user is part of the docker group 16 | if ! groups $USER | grep -q '\bdocker\b'; then 17 | echo "You are not a member of the docker group. Please add yourself to the docker group using:" 18 | echo "sudo usermod -aG docker $USER" 19 | echo "Then log out and back in for the changes to take effect." 20 | exit 1 21 | fi 22 | 23 | set -x 24 | 25 | ROUTER1="sshpass -p admin ssh admin@clab-sonic-vpp01-router1" 26 | ROUTER2="sshpass -p admin ssh admin@clab-sonic-vpp01-router2" 27 | 28 | if ! sudo clab deploy --topo sonic-vpp01.clab.yml; then 29 | { set +x; } > /dev/null 2>&1 30 | echo "Alternatively, you can manually destroy the existing containers using 'sudo clab destroy --topo sonic-vpp01.clab.yml' and rerun this script." 31 | exit 1 32 | fi 33 | 34 | 35 | #Let's wait for the VMs to boot up 36 | 37 | RETRY_INTERVAL=10 # seconds 38 | MAX_RETRIES=20 39 | TARGET_HEALTHY_COUNT=2 40 | 41 | for ((i=1; i<=MAX_RETRIES; i++)); do 42 | echo "Attempt $i of $MAX_RETRIES..." 43 | 44 | # Run the containerlab inspect and count 'healthy' statuses 45 | HEALTHY_COUNT=$(clab inspect -f json | grep -o '"status": *"healthy"' | wc -l) 46 | 47 | if [ "$HEALTHY_COUNT" -ge "$TARGET_HEALTHY_COUNT" ]; then 48 | echo "Success: $HEALTHY_COUNT nodes are healthy. Continuing..." 49 | break 50 | else 51 | echo "Currently $HEALTHY_COUNT healthy nodes. Waiting for $TARGET_HEALTHY_COUNT..." 52 | if [ "$i" -eq "$MAX_RETRIES" ]; then 53 | echo "Error: Timeout reached. Not all containers are healthy." 54 | exit 1 55 | fi 56 | sleep $RETRY_INTERVAL 57 | fi 58 | done 59 | 60 | set_swss_log_level() { 61 | $1 swssloglevel -l ERROR -a 62 | $1 swssloglevel -l SAI_LOG_LEVEL_INFO -s -a 63 | } 64 | 65 | set_swss_log_level "$ROUTER1" 66 | set_swss_log_level "$ROUTER2" 67 | 68 | ./scripts/PC-interfaces.sh 69 | 70 | execute() { 71 | local host=$1 72 | local file=$2 73 | 74 | if [[ "$file" == *.vtysh ]]; then 75 | # Send all commands in the file to vtysh via heredoc inside ssh 76 | $1 bash < 17 | 18 | struct hash_key_t 19 | { 20 | u32 node_index; 21 | }; 22 | 23 | struct hash_leaf_stat_counter_t 24 | { 25 | char node_name[32]; 26 | u64 calls; // Calls 27 | u64 vectors; // Vectors 28 | u64 suspends; // Suspends 29 | u64 clocksperx; // Clocks 30 | u64 vectorspercall; // Vectors/Call 31 | u64 maxcn; // Max Node Clocks 32 | u32 maxn; // Vectors at Max 33 | u64 maxc; // Max Clocks 34 | }; 35 | 36 | BPF_HASH(stats_counters, struct hash_key_t, struct hash_leaf_stat_counter_t); 37 | 38 | #define MAX_CORES 8 39 | 40 | struct hash_key_vr_t 41 | { 42 | u32 node_index; 43 | }; 44 | 45 | struct hash_leaf_vr_counter_t 46 | { 47 | u64 vectors; 48 | u64 calls; 49 | }; 50 | 51 | BPF_HASH(vector_rate_counters, struct hash_key_vr_t, struct hash_leaf_vr_counter_t); 52 | 53 | /** 54 | * @brief Reads VPP's stat counters, and stores them in the stats_counters hash. 55 | * @param ctx The BPF context. 56 | * 57 | * DTRACE_PROBE ... 58 | */ 59 | int vpp_stats(struct pt_regs *ctx) { 60 | struct hash_key_t key = {}; 61 | bpf_usdt_readarg(2, ctx, &key.node_index); 62 | 63 | struct hash_leaf_stat_counter_t counter = {}; 64 | bpf_usdt_readarg_p(1, ctx, &counter.node_name, sizeof(counter.node_name)); 65 | bpf_usdt_readarg(3, ctx, &counter.calls); 66 | bpf_usdt_readarg(4, ctx, &counter.vectors); 67 | bpf_usdt_readarg(5, ctx, &counter.suspends); 68 | bpf_usdt_readarg(6, ctx, &counter.clocksperx); 69 | bpf_usdt_readarg(7, ctx, &counter.vectorspercall); 70 | bpf_usdt_readarg(8, ctx, &counter.maxcn); 71 | bpf_usdt_readarg(9, ctx, &counter.maxn); 72 | bpf_usdt_readarg(10, ctx, &counter.maxc); 73 | 74 | stats_counters.update(&key, &counter); 75 | return 0; 76 | }; 77 | 78 | /** 79 | * @brief Reads VPP's vector rates, and stores them in the vector_rate_counters hash. 80 | * @param ctx The BPF context. 81 | * 82 | * DTRACE_PROBE ... 83 | */ 84 | int vpp_vector_rate(struct pt_regs *ctx) { 85 | struct hash_key_vr_t key = {}; 86 | bpf_usdt_readarg(1, ctx, &key.node_index); 87 | 88 | struct hash_leaf_vr_counter_t counter = {}; 89 | bpf_usdt_readarg(2, ctx, &counter.vectors); 90 | bpf_usdt_readarg(3, ctx, &counter.calls); 91 | 92 | vector_rate_counters.update(&key, &counter); 93 | 94 | return 0; 95 | }; -------------------------------------------------------------------------------- /sonic-vpp/sonic-vpp-L3/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check if Docker is installed 4 | if ! command -v docker &> /dev/null; then 5 | echo "Docker is not installed. Please install Docker (https://docs.docker.com/engine/install/) and try again." 6 | exit 1 7 | fi 8 | 9 | # Check if clab is installed 10 | if ! command -v clab &> /dev/null; then 11 | echo "Containerlab is not installed. Please install Containerlab (https://containerlab.dev/install/) and try again." 12 | exit 1 13 | fi 14 | 15 | # Check if the user is part of the docker group 16 | if ! groups $USER | grep -q '\bdocker\b'; then 17 | echo "You are not a member of the docker group. Please add yourself to the docker group using:" 18 | echo "sudo usermod -aG docker $USER" 19 | echo "Then log out and back in for the changes to take effect." 20 | exit 1 21 | fi 22 | 23 | set -x 24 | 25 | ROUTER1="sshpass -p admin ssh admin@clab-sonic-vpp01-router1" 26 | ROUTER2="sshpass -p admin ssh admin@clab-sonic-vpp01-router2" 27 | 28 | if ! sudo clab deploy --topo sonic-vpp01.clab.yml; then 29 | { set +x; } > /dev/null 2>&1 30 | echo "Alternatively, you can manually destroy the existing containers using 'sudo clab destroy --topo sonic-vpp01.clab.yml' and rerun this script." 31 | exit 1 32 | fi 33 | 34 | 35 | #Let's wait for the VMs to boot up 36 | 37 | RETRY_INTERVAL=10 # seconds 38 | MAX_RETRIES=20 39 | TARGET_HEALTHY_COUNT=2 40 | 41 | for ((i=1; i<=MAX_RETRIES; i++)); do 42 | echo "Attempt $i of $MAX_RETRIES..." 43 | 44 | # Run the containerlab inspect and count 'healthy' statuses 45 | HEALTHY_COUNT=$(clab inspect -f json | grep -o '"status": *"healthy"' | wc -l) 46 | 47 | if [ "$HEALTHY_COUNT" -ge "$TARGET_HEALTHY_COUNT" ]; then 48 | echo "Success: $HEALTHY_COUNT nodes are healthy. Continuing..." 49 | break 50 | else 51 | echo "Currently $HEALTHY_COUNT healthy nodes. Waiting for $TARGET_HEALTHY_COUNT..." 52 | if [ "$i" -eq "$MAX_RETRIES" ]; then 53 | echo "Error: Timeout reached. Not all containers are healthy." 54 | exit 1 55 | fi 56 | sleep $RETRY_INTERVAL 57 | fi 58 | done 59 | 60 | set_swss_log_level() { 61 | $1 swssloglevel -l ERROR -a 62 | $1 swssloglevel -l SAI_LOG_LEVEL_INFO -s -a 63 | } 64 | 65 | set_swss_log_level "$ROUTER1" 66 | set_swss_log_level "$ROUTER2" 67 | 68 | ./scripts/PC-interfaces.sh 69 | 70 | execute() { 71 | local host=$1 72 | local file=$2 73 | 74 | if [[ "$file" == *.vtysh ]]; then 75 | # Send all commands in the file to vtysh via heredoc inside ssh 76 | $1 bash <TODO: start of blueprintprocessor container is not enough, need to wait for its REST API to be ready for usage) 41 | image: onap/ccsdk-cds-ui-server:1.1.1 42 | container_name: cds-ui 43 | ports: 44 | - "3000:3000" # port for UI 45 | - "9080:8080" 46 | - "9081:8081" 47 | environment: 48 | - HOST=0.0.0.0 # host for UI 49 | - API_BLUEPRINT_CONTROLLER_HTTP_BASE_URL=http://172.28.0.1:8000/api/v1 50 | - API_BLUEPRINT_CONTROLLER_HTTP_AUTH_TOKEN=Basic Y2NzZGthcHBzOmNjc2RrYXBwcw== 51 | - API_BLUEPRINT_PROCESSOR_HTTP_BASE_URL=http://172.28.0.1:8000/api/v1 52 | - API_BLUEPRINT_PROCESSOR_HTTP_AUTH_TOKEN=Basic Y2NzZGthcHBzOmNjc2RrYXBwcw== 53 | - API_BLUEPRINT_PROCESSOR_GRPC_HOST=172.28.0.1 54 | - API_BLUEPRINT_PROCESSOR_GRPC_PORT=9111 55 | - API_BLUEPRINT_PROCESSOR_GRPC_AUTH_TOKEN=Basic Y2NzZGthcHBzOmNjc2RrYXBwcw== 56 | 57 | firewall-cnf: 58 | container_name: firewall-cnf 59 | image: 'ghcr.io/pantheontech/stonework:21.01.04' 60 | privileged: true 61 | networks: 62 | - cds-network 63 | ports: 64 | - '9191:9191' # REST API 65 | - '9111:9111' # GRPC # TODO remove later 66 | volumes: 67 | - '/tmp/vpp/:/run/vpp/' 68 | - '/var/run/netns/:/var/run/netns/' 69 | environment: 70 | - ETCD_CONFIG=disabled # don't use ETCD (it is not needed in this case) 71 | pid: host # needed for connection between startpoint and endpoint 72 | cap_add: 73 | - NET_ADMIN # needed for connection between startpoint and endpoint 74 | 75 | startpoint: 76 | container_name: startpoint 77 | image: 'alpine-start-end-point:latest' 78 | privileged: true 79 | command: sh -c "sleep 100000s" 80 | cap_add: 81 | - NET_ADMIN # needed for connection between startpoint and endpoint 82 | 83 | endpoint: 84 | container_name: endpoint 85 | image: 'alpine-start-end-point:latest' 86 | privileged: true 87 | command: sh -c "sleep 100000s" 88 | cap_add: 89 | - NET_ADMIN # needed for connection between startpoint and endpoint 90 | 91 | networks: 92 | cds-network: 93 | driver: bridge 94 | ipam: 95 | driver: default 96 | config: 97 | - subnet: 172.28.0.0/16 -------------------------------------------------------------------------------- /nsm/LFNWebinar/cnf-crd.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # This cluster role defines a set of permissions required for cnf-crd. 3 | apiVersion: rbac.authorization.k8s.io/v1beta1 4 | kind: ClusterRole 5 | metadata: 6 | name: cnf-crd 7 | namespace: default 8 | rules: 9 | - apiGroups: 10 | - apiextensions.k8s.io 11 | - pantheon.tech 12 | resources: 13 | - customresourcedefinitions 14 | - cnfconfigurations 15 | verbs: 16 | - "*" 17 | 18 | --- 19 | # This defines a service account for cnf-crd. 20 | apiVersion: v1 21 | kind: ServiceAccount 22 | metadata: 23 | name: cnf-crd 24 | namespace: default 25 | 26 | --- 27 | # This binds the cnf-crd cluster role with cnf-crd service account. 28 | apiVersion: rbac.authorization.k8s.io/v1beta1 29 | kind: ClusterRoleBinding 30 | metadata: 31 | name: cnf-crd 32 | roleRef: 33 | apiGroup: rbac.authorization.k8s.io 34 | kind: ClusterRole 35 | name: cnf-crd 36 | subjects: 37 | - kind: ServiceAccount 38 | name: cnf-crd 39 | namespace: default 40 | 41 | --- 42 | apiVersion: v1 43 | kind: Pod 44 | metadata: 45 | name: cnf-crd 46 | namespace: default 47 | labels: 48 | app: cnf-crd 49 | spec: 50 | serviceAccountName: cnf-crd 51 | initContainers: 52 | # This init container waits until etcd is started 53 | - name: wait-foretcd 54 | image: busybox:1.29.3 55 | imagePullPolicy: IfNotPresent 56 | env: 57 | - name: HOST_IP 58 | valueFrom: 59 | fieldRef: 60 | fieldPath: status.hostIP 61 | command: 62 | - /bin/sh 63 | args: 64 | - -c 65 | - | 66 | until nc -w 2 $HOST_IP:31379; do echo waiting for etcd; sleep 2; done; 67 | containers: 68 | - name: cnf-crd 69 | image: pantheontech/cnf-crd:latest 70 | imagePullPolicy: IfNotPresent 71 | env: 72 | - name: ETCD_CONFIG 73 | value: "/etc/etcd/etcd.conf" 74 | volumeMounts: 75 | - name: etcd-cfg 76 | mountPath: /etc/etcd 77 | volumes: 78 | - name: etcd-cfg 79 | configMap: 80 | name: cnf-etcd-cfg 81 | 82 | --- 83 | # etcd config used by CNFs deployed in the host network namespace 84 | apiVersion: v1 85 | kind: ConfigMap 86 | metadata: 87 | name: cnf-etcd-cfg-for-nodeport 88 | data: 89 | etcd.conf: | 90 | dial-timeout: 10000000000 91 | allow-delayed-start: true 92 | insecure-transport: true 93 | endpoints: 94 | - "__HOST_IP__:31379" 95 | 96 | --- 97 | # etcd config used by CNF with their own network namespace 98 | apiVersion: v1 99 | kind: ConfigMap 100 | metadata: 101 | name: cnf-etcd-cfg 102 | data: 103 | etcd.conf: | 104 | dial-timeout: 10000000000 105 | allow-delayed-start: true 106 | insecure-transport: true 107 | endpoints: 108 | - "cnf-etcd.default.svc.cluster.local:12379" 109 | 110 | --- 111 | apiVersion: v1 112 | kind: Service 113 | metadata: 114 | name: cnf-etcd 115 | spec: 116 | type: NodePort 117 | selector: 118 | app: cnf-etcd 119 | ports: 120 | - port: 12379 121 | nodePort: 31379 # 32379 is used by contiv-etcd 122 | 123 | --- 124 | apiVersion: v1 125 | kind: Pod 126 | metadata: 127 | name: cnf-etcd 128 | labels: 129 | app: cnf-etcd 130 | spec: 131 | containers: 132 | - name: cnf-etcd 133 | image: quay.io/coreos/etcd:v3.3.11 134 | imagePullPolicy: IfNotPresent 135 | env: 136 | - name: ETCDCTL_API 137 | value: "3" 138 | command: 139 | - /bin/sh 140 | args: 141 | - -c 142 | - /usr/local/bin/etcd --name=cnf-etcd --data-dir=/var/cnf-etcd/data 143 | --advertise-client-urls=http://0.0.0.0:12379 --listen-client-urls=http://0.0.0.0:12379 --listen-peer-urls=http://0.0.0.0:12380 -------------------------------------------------------------------------------- /sonic-vpp/sonic-vpp-L3/README.md: -------------------------------------------------------------------------------- 1 | # [Demo] SONiC VPP L3 2 | 3 | This demo showcases L3 integration between [SONiC](https://sonicfoundation.dev/) and [FD.io VPP](fd.io), enabling high-performance routing in a containerized environment, using SONiC as control plane and FD.io VPP as the fast software data plane. 4 | 5 | ## Prerequisites 6 | - This example was successfully replicated on an Ubuntu (24.04.2 LTS) WSL instance in Windows. 7 | - [Docker](https://docs.docker.com/engine/install/) 8 | - [ContainerLab](https://containerlab.dev/install/) 9 | - [sshpass](https://www.cyberciti.biz/faq/noninteractive-shell-script-ssh-password-provider/) 10 | 11 | First, clone the repository so you have a local copy: 12 | 13 | ```bash 14 | git clone https://github.com/PANTHEONtech/cnf-examples.git 15 | ``` 16 | 17 | To launch the example, simply execute the *run.sh* script within the folder you downloaded the example to: 18 | 19 | ```bash 20 | ./run.sh 21 | ``` 22 | 23 | The run.sh script orchestrates the setup and configuration of the L3 network. 24 | 25 | ## Verifying the Setup 26 | 27 | 1. Verify instances 28 | 29 | ```bash 30 | clab inspect 31 | ``` 32 | - Ensure that you see containers for PC1, PC2, Router 1 and Router 2. 33 | - Take note of the IP address each container is given. Replace them in the commands below. The output of *inspect* should look like this: 34 | 35 | ```Example Output 36 | ╭──────────────────────────┬──────────────────────────────────────────┬───────────┬───────────────────╮ 37 | │ Name │ Kind/Image │ State │ IPv4/6 Address │ 38 | ├──────────────────────────┼──────────────────────────────────────────┼───────────┼───────────────────┤ 39 | │ clab-sonic-vpp01-PC1 │ linux │ running │ 192.xx.xx.x │ 40 | │ │ wbitt/network-multitool:extra │ │ 3fff:172:20:20::2 │ 41 | ├──────────────────────────┼──────────────────────────────────────────┼───────────┼───────────────────┤ 42 | │ clab-sonic-vpp01-PC2 │ linux │ running │ 192.xx.xx.x │ 43 | │ │ wbitt/network-multitool:extra │ │ 3fff:172:20:20::3 │ 44 | ├──────────────────────────┼──────────────────────────────────────────┼───────────┼───────────────────┤ 45 | │ clab-sonic-vpp01-router1 │ sonic-vm │ running │ 192.xx.xx.x │ 46 | │ │ ghcr.io/pantheontech/sonic-vpp-vs:250619 │ (healthy) │ 3fff:172:20:20::4 │ 47 | ├──────────────────────────┼──────────────────────────────────────────┼───────────┼───────────────────┤ 48 | │ clab-sonic-vpp01-router2 │ sonic-vm │ running │ 192.xx.xx.x │ 49 | │ │ ghcr.io/pantheontech/sonic-vpp-vs:250619 │ (healthy) │ 3fff:172:20:20::5 │ 50 | ╰──────────────────────────┴──────────────────────────────────────────┴───────────┴───────────────────╯ 51 | ``` 52 | 2. Verify connectivity between router1 and router2 53 | 54 | ```bash 55 | sshpass -p admin ssh admin@clab-sonic-vpp01-router1 ping -c5 10.0.1.2 56 | sshpass -p admin ssh admin@clab-sonic-vpp01-router2 ping -c5 10.0.1.1 57 | ``` 58 | 59 | 3. Verify connectivity between PC1 and PC2 60 | 61 | ```bash 62 | docker exec clab-sonic-vpp01-PC1 ping -c 5 10.20.2.1 63 | docker exec clab-sonic-vpp01-PC2 ping -c 5 10.20.1.1 64 | ``` 65 | 66 | 4. Test Connectivity 67 | 68 | ```bash 69 | docker exec -it clab-sonic-vpp01-PC1 iperf3 -s 70 | docker exec -it clab-sonic-vpp01-PC2 iperf3 -c 10.20.1.1 71 | ``` 72 | 73 | # About PANTHEON.tech 74 | 75 | Do you want to [deploy SONiC](https://pantheon.tech/services/expertise/sonic-nos/) in your infrastructure? Or [orchestrate SONiC with a unique solution](https://pantheon.tech/products/sandwork/)? 76 | 77 | We help enterprises take control of their network infrastructure – through software-driven automation, orchestration, and deep network technology expertise. 78 | -------------------------------------------------------------------------------- /nsm/LFNWebinar/README.md: -------------------------------------------------------------------------------- 1 | CNF chaining using Ligato and NSM (example for LFN Webinar) 2 | =========================================================== 3 | 4 | Overview 5 | -------- 6 | 7 | In this simple example we demonstrate the capabilities of the NSM agent - a control-plane for Cloud-native 8 | Network Functions deployed in Kubernetes cluster. The NSM agent seamlessly integrates [Ligato framework][ligato] 9 | for Linux and VPP network configuration management together with [Network Service Mesh (NSM)][nsm] for separation 10 | of data plane from control plane connectivity between containers and external endpoints. 11 | 12 | In the presented use-case we simulate scenario in which a client from a local network needs to access a web server 13 | with a public IP address. The necessary Network Address Translation (NAT) is performed in-between the client and 14 | the web server by the high-performance [VPP NAT plugin][vpp-nat-plugin], deployed as a true CNF (Cloud-Native Network 15 | Functions) inside a container. For simplicity the client is represented by a K8s Pod running image with [cURL][curl] 16 | installed (as opposed to being an external endpoint as it would be in a real-world scenario). For the server side 17 | the minimalistic [TestHTTPServer][vpp-test-http-server] implemented in VPP is utilized. 18 | 19 | In all the three Pods an instance of NSM Agent is run to communicate with the NSM manager via NSM SDK and negotiate 20 | additional network connections to connect the pods into a chain `client <-> NAT-CNF <-> web-server` (see diagrams below). 21 | The agents then use the features of Ligato framework to further configure Linux and VPP networking around the additional 22 | interfaces provided by NSM (e.g. routes, NAT). 23 | 24 | The configuration to apply is described declaratively and submitted to NSM agents in a Kubernetes native way through 25 | our own Custom Resource called `CNFConfiguration`. The controller for this CRD (installed by [cnf-crd.yaml][cnf-crd-yaml]) 26 | simply reflects the content of applied CRD instances into an `etcd` datastore from which it is read by NSM agents. 27 | For example, the configuration for the NSM agent managing the central NAT CNF can be found in [cnf-nat44.yaml][cnf-nat44-yaml]. 28 | 29 | More information about cloud-native tools and network functions provided by PANTHEON.tech can be found on our website 30 | [cdnf.io][cdnf-io]. 31 | 32 | ### Networking Diagram 33 | 34 | ![networking][networking] 35 | 36 | ### Routing Diagram 37 | 38 | ![routing][routing] 39 | 40 | Demo steps 41 | ---------- 42 | 43 | 1. Create Kubernetes cluster; deploy CNI (network plugin) of your preference 44 | 2. [Install Helm][install-helm] version 2 (latest NSM release v0.2.0 does not support Helm v3) 45 | 3. Run `helm init` to install Tiller and to set up local configuration for the Helm 46 | 4. Create service account for Tiller: 47 | ``` 48 | $ kubectl create serviceaccount --namespace kube-system tiller 49 | $ kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller 50 | $ kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}' 51 | ``` 52 | 5. Deploy NSM using Helm: 53 | ``` 54 | $ helm repo add nsm https://helm.nsm.dev/ 55 | $ helm install --set insecure=true nsm/nsm 56 | ``` 57 | 6. Deploy etcd + controller for CRD, both of which will be used together to pass configuration to NSM agents: 58 | ``` 59 | $ kubectl apply -f cnf-crd.yaml 60 | ``` 61 | 7. Submit definition of the network topology for this example to NSM: 62 | ``` 63 | $ kubectl apply -f network-service.yaml 64 | ``` 65 | 8. Deploy and start simple VPP-based webserver with NSM-Agent-VPP as control-plane: 66 | ``` 67 | $ kubectl apply -f webserver.yaml 68 | ``` 69 | 9. Deploy VPP-based NAT44 CNF with NSM-Agent-VPP as control-plane: 70 | ``` 71 | $ kubectl apply -f cnf-nat44.yaml 72 | ``` 73 | 10. Deploy Pod with NSM-Agent-Linux control-plane and curl for testing connection to the webserver through NAT44 CNF: 74 | ``` 75 | $ kubectl apply -f client.yaml 76 | ``` 77 | 11. Test connectivity between client and webserver: 78 | ``` 79 | $ kubectl exec -it client curl 80.80.80.80/show/version 80 | 81 | show version
vpp v20.01-rc2~11-gfce396738~b17 built by root on b81dced13911 at 2020-01-29T21:07:15
 82 |     
83 | ``` 84 | 12. To confirm that client's IP is indeed source NATed (from `192.168.100.10` to `80.80.80.102`) before reaching 85 | the webserver, one can use the VPP packet tracing: 86 | ``` 87 | $ kubectl exec -it webserver vppctl trace add memif-input 10 88 | $ kubectl exec -it client curl 80.80.80.80/show/version 89 | $ kubectl exec -it webserver vppctl show trace 90 | 91 | 00:01:04:655507: memif-input 92 | memif: hw_if_index 1 next-index 4 93 | slot: ring 0 94 | 00:01:04:655515: ethernet-input 95 | IP4: 02:fe:68:a6:6b:8c -> 02:fe:b8:e1:c8:ad 96 | 00:01:04:655519: ip4-input 97 | TCP: 80.80.80.100 -> 80.80.80.80 98 | ... 99 | ``` 100 | 101 | [ligato]: https://ligato.io/ 102 | [nsm]: https://networkservicemesh.io/ 103 | [install-helm]: https://helm.sh/docs/intro/install/ 104 | [networking]: img/lfn-webinar-networking.png 105 | [routing]: img/lfn-webinar-routing.png 106 | [cdnf-io]: https://cdnf.io/ 107 | [vpp-nat-plugin]: https://wiki.fd.io/view/VPP/NAT 108 | [curl]: https://curl.haxx.se/ 109 | [vpp-test-http-server]: https://wiki.fd.io/view/VPP/HostStack/TestHttpServer 110 | [crd]: https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/ 111 | [cnf-nat44-yaml]: ./cnf-nat44.yaml 112 | [cnf-crd-yaml]: ./cnf-crd.yaml 113 | -------------------------------------------------------------------------------- /ONAP-cdnf-integration/run-demo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # requirements: 4 | # 1. docker, docker-compose 5 | # 2. curl 6 | # 7 | #(Tested with: 8 | # Ubuntu 20.04 9 | # docker 20.10.5 10 | # docker-compose 1.27.4 11 | # curl 7.68.0 (x86_64-pc-linux-gnu) 12 | # ) 13 | 14 | set -eo pipefail 15 | 16 | source firewall-cnf-helper.sh 17 | 18 | 19 | CBA_FILE="cba.zip" 20 | ENRICHED_CBA_FILE="cba-enriched.zip" 21 | 22 | echo " -----------------------------------------------------------------------------" 23 | echo " Configuring Firewall CNF using ONAP (CDS) " 24 | echo " -----------------------------------------------------------------------------" 25 | 26 | ######################################## 27 | # Setup 28 | ######################################## 29 | 30 | echo 31 | echo "Cleaning up from previous runs and doing other preparations..." 32 | docker-compose down --volumes # removing also DB volumes 33 | rm ${CBA_FILE} > /dev/null 2>&1 || true 34 | rm ${ENRICHED_CBA_FILE} > /dev/null 2>&1 || true 35 | preDockerComposeCNFPreparations 36 | 37 | echo 38 | echo "Starting docker containers/networking..." 39 | docker-compose up -d 40 | 41 | echo 42 | echo "Waiting little bit longer to start CNF properly..." 43 | sleep 5s 44 | 45 | echo 46 | echo "Preparing Firewall CNF use case topology..." 47 | setupCNFTrafficTopology 48 | 49 | echo 50 | echo "Waiting little bit longer to start CDS-blueprintprocessor properly..." 51 | sleep 5s 52 | 53 | 54 | echo 55 | echo "CDS bootstraping (loading of default model types and resource dictionary-needed for proper CBA enrichment)..." 56 | curl --location --request POST 'http://localhost:8000/api/v1/blueprint-model/bootstrap' \ 57 | --header 'Content-Type: application/json' \ 58 | --header 'Authorization: Basic Y2NzZGthcHBzOmNjc2RrYXBwcw==' \ 59 | --data-raw '{ 60 | "loadModelType" : true, 61 | "loadResourceDictionary" : true, 62 | "loadCBA" : false 63 | }' 64 | 65 | echo 66 | echo "Packing CBA (making zip archive from cba folder content)..." 67 | cd cba;zip -r ../${CBA_FILE} * -x "pom.xml" "target/*";cd .. 68 | 69 | echo 70 | echo "Enriching CBA..." 71 | curl --location --request POST 'http://localhost:8000/api/v1/blueprint-model/enrich' \ 72 | --header 'Authorization: Basic Y2NzZGthcHBzOmNjc2RrYXBwcw==' \ 73 | --form 'file=@"./'${CBA_FILE}'"' \ 74 | --output ${ENRICHED_CBA_FILE} 75 | 76 | echo 77 | echo "Saving/Uploading enriched CBA to CDS..." 78 | curl --location --request POST 'http://localhost:8000/api/v1/blueprint-model' \ 79 | --header 'Authorization: Basic Y2NzZGthcHBzOmNjc2RrYXBwcw==' \ 80 | --form 'file=@"./'${ENRICHED_CBA_FILE}'"' 81 | 82 | ######################################## 83 | # Sending Traffic through Firewall CNF 84 | ######################################## 85 | 86 | echo;echo 87 | echo "Sending data through unconfigured firewall..." 88 | newVPPTrace 89 | sendPing "startpoint" ${TRAFFIC_DEST_IP} 90 | if [ ! $PASSED_THROUGHT ]; then 91 | echo "=> failed to transmit data properly (ERROR)" 92 | logVPPTrace "unconfigured-firewall" 93 | exit 1 94 | else 95 | echo "=> data transmission was successful (OK)" 96 | logVPPTrace "unconfigured-firewall" 97 | fi 98 | 99 | echo 100 | echo "Starting firewall configuration (Deny traffic) by using CDS..." 101 | curl --location --request POST 'http://localhost:8000/api/v1/execution-service/process' \ 102 | --header 'Authorization: Basic Y2NzZGthcHBzOmNjc2RrYXBwcw==' \ 103 | --header 'Content-Type: application/json' \ 104 | --data-raw '{ 105 | "actionIdentifiers": { 106 | "mode": "sync", 107 | "blueprintName": "Firewall-CNF-configuration-example", 108 | "blueprintVersion": "1.0.0", 109 | "actionName": "apply-firewall-rule" 110 | }, 111 | "payload": { 112 | "apply-firewall-rule-request": { 113 | "cnf-rest-url": "http://'${CNF_CONTAINER_NAME}':9191", 114 | "firewall_action": "DENY", 115 | "traffic_destination_network": "'${TRAFFIC_DEST_IP}'/32" 116 | } 117 | }, 118 | "commonHeader": { 119 | "subRequestId": "143748f9-3cd5-4910-81c9-a4601ff2ea58", 120 | "requestId": "e5eb1f1e-3386-435d-b290-d49d8af8db4c", 121 | "originatorId": "SDNC_DG" 122 | } 123 | }' 124 | 125 | echo;echo 126 | echo "Sending data through configured firewall (Deny traffic)..." 127 | newVPPTrace 128 | sendPing "startpoint" ${TRAFFIC_DEST_IP} 129 | if [ ! $PASSED_THROUGHT ]; then 130 | if [[ $(getVPPTrace) == *"ACL deny packets"* ]]; then 131 | echo "=> blocked by firewall as expected (OK)" 132 | logVPPTrace "deny-configured-firewall" 133 | else 134 | echo "=> didn't pass throught but not because of firewall => demo failure (ERROR)" 135 | logVPPTrace "deny-configured-firewall" 136 | exit 1 137 | fi 138 | else 139 | echo "=> passed through firewall but shouldn't(ERROR)" 140 | logVPPTrace "deny-configured-firewall" 141 | exit 1 142 | fi 143 | 144 | echo 145 | echo "Starting firewall configuration (Allow traffic) by using CDS..." 146 | curl --location --request POST 'http://localhost:8000/api/v1/execution-service/process' \ 147 | --header 'Authorization: Basic Y2NzZGthcHBzOmNjc2RrYXBwcw==' \ 148 | --header 'Content-Type: application/json' \ 149 | --data-raw '{ 150 | "actionIdentifiers": { 151 | "mode": "sync", 152 | "blueprintName": "Firewall-CNF-configuration-example", 153 | "blueprintVersion": "1.0.0", 154 | "actionName": "apply-firewall-rule" 155 | }, 156 | "payload": { 157 | "apply-firewall-rule-request": { 158 | "cnf-rest-url": "http://'${CNF_CONTAINER_NAME}':9191", 159 | "firewall_action": "PERMIT", 160 | "traffic_destination_network": "'${TRAFFIC_DEST_IP}'/32" 161 | } 162 | }, 163 | "commonHeader": { 164 | "subRequestId": "143748f9-3cd5-4910-81c9-a4601ff2ea58", 165 | "requestId": "e5eb1f1e-3386-435d-b290-d49d8af8db4c", 166 | "originatorId": "SDNC_DG" 167 | } 168 | }' 169 | 170 | echo;echo 171 | echo "Sending data through configured firewall (Allowed Traffic)..." 172 | newVPPTrace 173 | sendPing "startpoint" ${TRAFFIC_DEST_IP} 174 | if [ ! $PASSED_THROUGHT ]; then 175 | echo "=> failed to transmit data properly (ERROR)" 176 | logVPPTrace "allow-configured-firewall" 177 | exit 1 178 | else 179 | echo "=> data transmission was successful (OK)" 180 | logVPPTrace "allow-configured-firewall" 181 | fi 182 | 183 | echo 184 | echo "Logging CNF state..." 185 | reportCNFState 186 | 187 | 188 | ######################################## 189 | # Clean up 190 | ######################################## 191 | 192 | echo 193 | echo "Cleaning up..." 194 | rm ${CBA_FILE} > /dev/null 2>&1 || true 195 | rm ${ENRICHED_CBA_FILE} > /dev/null 2>&1 || true 196 | docker-compose down --volumes # removing also DB volumes 197 | cleanupCNFRelatedThings 198 | -------------------------------------------------------------------------------- /ONAP-cdnf-integration/cba/Scripts/kotlin/ConfigDeploy.kt: -------------------------------------------------------------------------------- 1 | package org.onap.ccsdk.cds.blueprintsprocessor.services.execution.scripts 2 | 3 | import org.apache.commons.io.IOUtils 4 | import org.apache.http.client.ClientProtocolException 5 | import org.apache.http.client.entity.EntityBuilder 6 | import org.apache.http.client.methods.HttpPut 7 | import org.apache.http.client.methods.HttpUriRequest 8 | import org.apache.http.message.BasicHeader 9 | import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput 10 | import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionComponent 11 | import org.onap.ccsdk.cds.blueprintsprocessor.rest.RestClientProperties 12 | import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService 13 | import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.RestLoggerService 14 | import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractScriptComponentFunction 15 | import org.onap.ccsdk.cds.controllerblueprints.core.BlueprintProcessorException 16 | import org.onap.ccsdk.cds.controllerblueprints.core.asJsonNode 17 | import org.onap.ccsdk.cds.controllerblueprints.core.rootFieldsToMap 18 | import org.slf4j.LoggerFactory 19 | import org.springframework.http.HttpHeaders 20 | import org.springframework.http.MediaType 21 | import java.io.IOException 22 | import java.nio.charset.Charset 23 | 24 | open class ConfigDeploy : AbstractScriptComponentFunction() { 25 | 26 | private val log = LoggerFactory.getLogger(ConfigDeploy::class.java)!! 27 | 28 | // workflow input parameter names 29 | private val workflowInputCNFURL = "cnf-rest-url" 30 | 31 | // template resolving (previous step in workflow) 32 | private val templateResolvingNodeName = "resolve-template" 33 | private val cnfConfigTemplate = "cnf-config" 34 | 35 | override fun getName(): String { 36 | return "PantheonCNFConfigDeploy" 37 | } 38 | 39 | // processNB is the main entry for this script (processing NB input = using NB input to deploy config to CNF) 40 | override suspend fun processNB(executionRequest: ExecutionServiceInput) { 41 | log.info("executing Pantheon CNF config deploy script") 42 | 43 | try { 44 | // get input (from workflow and previous step) 45 | val cnfRestURL = bluePrintRuntimeService.getInputValue(workflowInputCNFURL) 46 | val resolvedTemplates = bluePrintRuntimeService.getNodeTemplateOperationOutputValue( 47 | templateResolvingNodeName, 48 | "ResourceResolutionComponent", 49 | operationName, 50 | ResourceResolutionComponent.OUTPUT_RESOURCE_ASSIGNMENT_PARAMS 51 | ) 52 | val cnfConfig = resolvedTemplates.rootFieldsToMap()[cnfConfigTemplate]?.asText() 53 | ?: throw BlueprintProcessorException("Can't get resolved template(CNF configuration) from previous workflow step") 54 | 55 | // apply CNF config 56 | val api = CNFRestClient(cnfRestURL.asText()) 57 | writeScriptOutputs(api.ApplyConfig(cnfConfig)) 58 | } catch (bpe: BlueprintProcessorException) { 59 | addError("Failure in config-deployment script: $bpe") 60 | throw bpe 61 | } 62 | 63 | log.info("Pantheon CNF config deploy script completed") 64 | } 65 | 66 | // recoverNB is for recovering state of CNF after problems with executing config deployment (exceptions and problems 67 | // inside and outside of processNB call) 68 | override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) { 69 | log.info("Something went wrong -> Executing CNF Recovery (currently NO recovery implemented for CNF configuration)") 70 | } 71 | 72 | // writeScriptOutputs writes deployment result to node template attribute used as workflow output 73 | private fun writeScriptOutputs(result: BlueprintWebClientService.WebClientResponse) { 74 | if (result.status != 200) { 75 | addError("Failed to configure CNF due to error response code (${result.status}) from CNF REST API.") 76 | } 77 | setAttribute( 78 | "response-data", 79 | mutableMapOf( 80 | "CNF-response-code" to (result.status.toString()), 81 | "CNF-response-message" to (result.body ?: "") 82 | ).asJsonNode() 83 | ) 84 | } 85 | 86 | // CNFRestClient is REST client specialized for communication with CNF REST API. 87 | inner class CNFRestClient(private val restURL: String) { 88 | private val service: RestClientService // BasicAuthRestClientService 89 | 90 | init { 91 | // collect all info for REST client service to successfully operate 92 | var mapOfHeaders = hashMapOf() 93 | mapOfHeaders.put("Content-Type", "application/yaml") 94 | mapOfHeaders.put("cache-control", " no-cache") 95 | mapOfHeaders.put("Accept", "application/json") 96 | // NOTE: use BasicAuthRestClientProperties when basic authentification is needed 97 | var restClientProperties = RestClientProperties() 98 | restClientProperties.url = restURL 99 | restClientProperties.additionalHeaders = mapOfHeaders 100 | 101 | // create REST client service 102 | this.service = RestClientService(restClientProperties) 103 | } 104 | 105 | // ApplyConfig uses CNF REST API to configure given configuration for CNF 106 | fun ApplyConfig(config: String): BlueprintWebClientService.WebClientResponse { 107 | try { 108 | return service.put("/configuration", config) 109 | } catch (e: Exception) { 110 | throw BlueprintProcessorException("Caught exception trying to apply CNF configuration: ${e.message}", e) 111 | } 112 | } 113 | } 114 | } 115 | 116 | // RestClientService is implementation of BlueprintWebClientService that serves as properly configured 117 | // REST client for communicate with CNF. It has no knowledge about the REST API specification of CNF. 118 | class RestClientService( 119 | private val restClientProperties: RestClientProperties 120 | ) : BlueprintWebClientService { 121 | 122 | override fun defaultHeaders(): Map { 123 | return mapOf( 124 | HttpHeaders.CONTENT_TYPE to MediaType.APPLICATION_JSON_VALUE, 125 | HttpHeaders.ACCEPT to MediaType.APPLICATION_JSON_VALUE 126 | ) 127 | } 128 | 129 | override fun host(uri: String): String { 130 | return restClientProperties.url + uri 131 | } 132 | 133 | override fun convertToBasicHeaders(headers: Map): 134 | Array { 135 | val customHeaders: MutableMap = headers.toMutableMap() 136 | customHeaders.putAll(verifyAdditionalHeaders(restClientProperties)) 137 | return super.convertToBasicHeaders(customHeaders) 138 | } 139 | 140 | @Throws(IOException::class, ClientProtocolException::class) 141 | private fun performHttpCall(httpUriRequest: HttpUriRequest): BlueprintWebClientService.WebClientResponse { 142 | val httpResponse = httpClient().execute(httpUriRequest) 143 | val statusCode = httpResponse.statusLine.statusCode 144 | httpResponse.entity.content.use { 145 | val body = IOUtils.toString(it, Charset.defaultCharset()) 146 | return BlueprintWebClientService.WebClientResponse(statusCode, body) 147 | } 148 | } 149 | 150 | // put calls REST PUT operation for given (url+)path and given payload 151 | fun put(path: String, payload: String): BlueprintWebClientService.WebClientResponse { 152 | val convertedHeaders: Array = convertToBasicHeaders(defaultHeaders()) 153 | val httpPost = HttpPut(host(path)) 154 | val entity = EntityBuilder.create().setText(payload).build() 155 | httpPost.setEntity(entity) 156 | RestLoggerService.httpInvoking(convertedHeaders) 157 | httpPost.setHeaders(convertedHeaders) 158 | return performHttpCall(httpPost) 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /ONAP-cdnf-integration/firewall-cnf-helper.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | # Topology 6 | TEST_ALPINE_IMAGE_TAG="alpine-start-end-point" 7 | CNF_CONTAINER_NAME="firewall-cnf" # dependent on docker-compose.yml 8 | STARTPOINT_VETH_IP="10.11.1.1" 9 | STARTPOINT_VETH_MAC_ADDRESS="66:66:66:66:66:66" 10 | STARTPOINT_VETH_HOST_IP="10.11.1.2" 11 | ENDPOINT_VETH_HOST_IP="10.11.2.1" 12 | ENDPOINT_VETH_IP="10.11.2.2" 13 | NAME_OF_DEFAULT_NETWORK="onap-cdnf-integration_default" # dependent on parent directory name 14 | NAME_OF_CDS_NETWORK="onap-cdnf-integration_cds-network" # dependent on parent directory name and docker-compose.yml 15 | 16 | # Test traffic 17 | TRAFFIC_DEST_IP="10.12.0.1" 18 | TRAFFIC_DEST_NETWORK="10.12.0.0/24" 19 | PORT="9000" 20 | 21 | 22 | function preDockerComposeCNFPreparations() { 23 | # clean up reporting directory from previous reports 24 | refreshReportingDir 25 | 26 | # create (if not exists) docker image for startpoint and endpoint containers 27 | assertStartEndPointDockerImage 28 | 29 | # prepare directories for veth moving 30 | sudo mkdir -p /var/run/netns 31 | 32 | # clean up previous run if needed 33 | sudo rm -f /var/run/netns/startpoint 34 | sudo rm -f /var/run/netns/endpoint 35 | } 36 | 37 | function setupCNFTrafficTopology() { 38 | setupVPPPacketPath 39 | setupLoopForIPAddress "endpoint" ${TRAFFIC_DEST_IP} # used as ping destination 40 | } 41 | 42 | function refreshReportingDir() { 43 | rm -rf reports;mkdir -p reports; # for demo report output 44 | } 45 | 46 | function reportCNFState { 47 | docker logs ${CNF_CONTAINER_NAME} &> reports/cnf-log.txt 48 | logVPPACLConfig 49 | logVPPTrace "from-demo-exit" 50 | } 51 | 52 | function cleanupCNFRelatedThings { 53 | sudo rm -f /var/run/netns/startpoint 54 | sudo rm -f /var/run/netns/endpoint 55 | } 56 | 57 | function setupVPPPacketPath() { 58 | ENDPOINT_IP=$(docker inspect endpoint --format='{{ (index .NetworkSettings.Networks "'${NAME_OF_DEFAULT_NETWORK}'").IPAddress}}') 59 | STARTPOINT_IP=$(docker inspect startpoint --format='{{ (index .NetworkSettings.Networks "'${NAME_OF_DEFAULT_NETWORK}'").IPAddress}}') 60 | CNF_IP=$(docker inspect ${CNF_CONTAINER_NAME} --format='{{ (index .NetworkSettings.Networks "'${NAME_OF_CDS_NETWORK}'").IPAddress}}') 61 | 62 | echo "Running setup for packet path..." 63 | echo "--creating file reference of startpoint container namespace..." 64 | mkdir -p /tmp/netns 65 | startpoint_pid=`docker inspect -f '{{.State.Pid}}' startpoint` 66 | sudo ln -s /proc/$startpoint_pid/ns/net /var/run/netns/startpoint 67 | 68 | echo "--creating file reference of endpoint container namespace..." 69 | endpoint_pid=`docker inspect -f '{{.State.Pid}}' endpoint` 70 | sudo ln -s /proc/$endpoint_pid/ns/net /var/run/netns/endpoint 71 | 72 | echo "--creating veth tunnel from startpoint container to VPP in \"CNF\" container...(2 veth tunnels and routes needed in vpp)" 73 | curl --location --request PUT 'http://'${CNF_IP}':9191/configuration' \ 74 | --header 'Content-Type: text/plain' \ 75 | --data-raw 'netallocConfig: {} 76 | linuxConfig: 77 | interfaces: 78 | - name: vpptoLinuxVETH 79 | type: VETH 80 | hostIfName: veth3 81 | enabled: true 82 | veth: 83 | peerIfName: endpointVETH 84 | - name: startpointVETH 85 | type: VETH 86 | namespace: 87 | type: FD 88 | reference: /var/run/netns/startpoint 89 | hostIfName: veth1 90 | enabled: true 91 | ipAddresses: 92 | - '${STARTPOINT_VETH_IP}'/24 93 | physAddress: '${STARTPOINT_VETH_MAC_ADDRESS}' 94 | veth: 95 | peerIfName: startpointToLinuxVETH 96 | - name: endpointVETH 97 | type: VETH 98 | namespace: 99 | type: FD 100 | reference: /var/run/netns/endpoint 101 | hostIfName: veth4 102 | enabled: true 103 | ipAddresses: 104 | - '${ENDPOINT_VETH_IP}'/24 105 | physAddress: 66:66:66:66:66:65 106 | veth: 107 | peerIfName: vpptoLinuxVETH 108 | - name: startpointToLinuxVETH 109 | type: VETH 110 | hostIfName: veth2 111 | enabled: true 112 | veth: 113 | peerIfName: startpointVETH 114 | vppConfig: 115 | interfaces: 116 | - name: toVPPAFPacket 117 | type: AF_PACKET 118 | enabled: true 119 | physAddress: a7:35:45:55:65:75 120 | ipAddresses: 121 | - '${STARTPOINT_VETH_HOST_IP}'/24 122 | afpacket: 123 | hostIfName: veth2 124 | - name: fromVPPAFPacket 125 | type: AF_PACKET 126 | enabled: true 127 | physAddress: b7:35:45:55:65:75 128 | ipAddresses: 129 | - '${ENDPOINT_VETH_HOST_IP}'/24 130 | afpacket: 131 | hostIfName: veth3 132 | routes: 133 | - dstNetwork: '${TRAFFIC_DEST_IP}'/32 134 | nextHopAddr: '${ENDPOINT_VETH_IP}'/24 135 | outgoingInterface: fromVPPAFPacket 136 | - dstNetwork: '${STARTPOINT_IP}'/32 137 | nextHopAddr: '${STARTPOINT_VETH_IP}' 138 | outgoingInterface: toVPPAFPacket 139 | ' 140 | 141 | echo "--creating route in startpoint to veth tunnel..." 142 | docker exec -it startpoint ip route add ${TRAFFIC_DEST_NETWORK} via ${STARTPOINT_VETH_HOST_IP} 143 | 144 | echo "--disabling Linux kernel's reverse path filtering" #disabling to not filter out packets based on unknown/trash source address (source address is expected by this filtering to be reachable with interface from which the packet came) 145 | docker exec -it endpoint sysctl -w net.ipv4.conf.all.rp_filter=0 > /dev/null 146 | docker exec -it endpoint sysctl -w net.ipv4.conf.veth4.rp_filter=0 > /dev/null 147 | 148 | echo "--enabling Linux kernel's routing of packet from veth tunnel to localnet (127.0.0.1)" #external/"martian" source addressed packets are not allowed to localnet by default 149 | docker exec -it endpoint sysctl -w net.ipv4.conf.all.route_localnet=1 > /dev/null 150 | docker exec -it endpoint sysctl -w net.ipv4.conf.veth4.route_localnet=1 > /dev/null 151 | 152 | echo "--moving packets from tunnel (VPP->Endpoint) to Linux localhost" #(so that netcat/socat server listening to localhost can pick them 153 | docker exec -it endpoint iptables -t nat -A PREROUTING -i veth4 -p udp --dport ${PORT} -j DNAT --to-destination 127.0.0.1 154 | docker exec -it endpoint iptables -t nat -A PREROUTING -i veth4 -p tcp --dport ${PORT} -j DNAT --to-destination 127.0.0.1 155 | 156 | echo "--route back for TCP's confirmation packet" #TCP does confirmation using packet sending back to TCP client 157 | docker exec -it endpoint ip route add ${STARTPOINT_VETH_IP}/32 via ${ENDPOINT_VETH_HOST_IP} 158 | 159 | echo "--waiting for processing and applying the configuration inside CNF" #configuration items are dependent on each other and correct configuration may take time 160 | sleep 5s # TODO make pooling solution 161 | 162 | #TODO i should probably find out all things needed to setup and setup them manually 163 | echo "--sending one packet to trigger initialization of packet path(ARP learning and other stuff)" #otherwise first packet failure will break netcat connetion 164 | docker exec -it startpoint sh -c "timeout -t 1 ping ${TRAFFIC_DEST_IP} || true" > /dev/null 165 | echo 166 | } 167 | 168 | function setupLoopForIPAddress() { 169 | local containerName=$1 170 | local ipAddress=$2 171 | $(docker exec -it ${containerName} ip addr add ${ipAddress}/32 dev lo) 172 | } 173 | 174 | function newVPPTrace() { 175 | docker exec -it ${CNF_CONTAINER_NAME} vppctl clear trace 176 | docker exec -it ${CNF_CONTAINER_NAME} vppctl trace add af-packet-input 100 177 | } 178 | 179 | function sendPing() { 180 | local start_container_name=$1 181 | local dest_ip=$2 182 | 183 | pingOutput=$(docker exec -it ${start_container_name} ping -c 1 -W 3 ${dest_ip} || true) 184 | if [[ "$pingOutput" == *"100% packet loss"* ]]; then 185 | # empty string will be evaluated as false when used in if condition 186 | PASSED_THROUGHT= 187 | else 188 | PASSED_THROUGHT=yes 189 | fi 190 | } 191 | 192 | function logVPPTrace() { 193 | docker exec -it ${CNF_CONTAINER_NAME} vppctl sh trace > reports/vpp-trace-output-$1.txt 194 | } 195 | 196 | function logVPPACLConfig() { 197 | docker exec -it ${CNF_CONTAINER_NAME} vppctl show acl-plugin acl > reports/vpp-acl-config-output.txt 198 | docker exec -it ${CNF_CONTAINER_NAME} vppctl show int >> reports/vpp-acl-config-output.txt # needed due to interface referencing in ACL configuration 199 | } 200 | 201 | function getVPPTrace() { 202 | docker exec -it ${CNF_CONTAINER_NAME} vppctl sh trace 203 | } 204 | 205 | function assertStartEndPointDockerImage() { 206 | if ! docker images | grep $TEST_ALPINE_IMAGE_TAG > /dev/null; then 207 | echo "Creating docker image for startpoint/endpoint" 208 | printf "FROM alpine:3.9.5\n RUN apk add iproute2" | docker build - --tag $TEST_ALPINE_IMAGE_TAG 209 | echo 210 | fi 211 | } 212 | -------------------------------------------------------------------------------- /ONAP-cdnf-integration/cds-bp-application.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2017-2019 AT&T, IBM, Bell Canada, Nordix Foundation. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | # NOTE: this properties file is copied from onap/ccsdk-blueprintsprocessor:1.1.1 (/opt/app/onap/config/application.properties) 18 | # and modified for purpose of this demo (all changed values are marked as "CHANGED") 19 | 20 | # Web server config 21 | ### START -Controller Blueprints Properties 22 | # Load Resource Source Mappings 23 | resourceSourceMappings=processor-db=source-db,input=source-input,default=source-default,sdnc=source-rest,aai-data=source-rest,capability=source-capability,rest=source-rest,vault-data=source-rest,script=source-capability 24 | 25 | # Controller Blueprints Core Configuration 26 | blueprintsprocessor.blueprintDeployPath=/opt/app/onap/blueprints/deploy 27 | blueprintsprocessor.blueprintArchivePath=/opt/app/onap/blueprints/archive 28 | blueprintsprocessor.blueprintWorkingPath=/opt/app/onap/blueprints/working 29 | 30 | # Controller Blueprint Load Configurations 31 | blueprintsprocessor.loadBlueprintPaths=/opt/app/onap/model-catalog/blueprint-model 32 | # CHANGED to load properly the types in bootstrap REST API call - /opt/app/onap/model-catalog/definition-type -> /opt/app/onap/model-catalog/definition-type/starter-type 33 | blueprintsprocessor.loadModeTypePaths=/opt/app/onap/model-catalog/definition-type/starter-type 34 | # CHANGED to load properly the dictionary in bootstrap REST API call - /opt/app/onap/model-catalog/resource-dictionary -> /opt/app/onap/model-catalog/resource-dictionary/starter-dictionary 35 | blueprintsprocessor.loadResourceDictionaryPaths=/opt/app/onap/model-catalog/resource-dictionary/starter-dictionary 36 | 37 | # CBA file extension 38 | controllerblueprints.loadCbaExtension=zip 39 | 40 | ### END -Controller Blueprints Properties 41 | 42 | blueprintsprocessor.grpcEnable=true 43 | blueprintsprocessor.httpPort=8080 44 | blueprintsprocessor.grpcPort=9111 45 | 46 | # db 47 | # CHANGED - renamed db hostname to deployed db service name - db -> cds-db 48 | blueprintsprocessor.db.url=jdbc:mysql://cds-db:3306/sdnctl 49 | blueprintsprocessor.db.username=sdnctl 50 | blueprintsprocessor.db.password=sdnctl 51 | blueprintsprocessor.db.driverClassName=org.mariadb.jdbc.Driver 52 | blueprintsprocessor.db.hibernateHbm2ddlAuto=update 53 | blueprintsprocessor.db.hibernateDDLAuto=update 54 | blueprintsprocessor.db.hibernateNamingStrategy=org.hibernate.cfg.ImprovedNamingStrategy 55 | blueprintsprocessor.db.hibernateDialect=org.hibernate.dialect.MySQL5InnoDBDialect 56 | 57 | # processor-db endpoint 58 | blueprintsprocessor.db.processor-db.type=maria-db 59 | blueprintsprocessor.db.processor-db.url=jdbc:mysql://mariadb-galera:3306/sdnctl 60 | blueprintsprocessor.db.processor-db.username=root 61 | blueprintsprocessor.db.processor-db.password=secretpassword 62 | 63 | # Python executor 64 | blueprints.processor.functions.python.executor.executionPath=/opt/app/onap/scripts/jython/ccsdk_blueprints 65 | blueprints.processor.functions.python.executor.modulePaths=/opt/app/onap/scripts/jython/ccsdk_blueprints,/opt/app/onap/scripts/jython/ccsdk_netconf,/opt/app/onap/scripts/jython/ccsdk_restconf 66 | 67 | security.user.password: {bcrypt}$2a$10$duaUzVUVW0YPQCSIbGEkQOXwafZGwQ/b32/Ys4R1iwSSawFgz7QNu 68 | security.user.name: ccsdkapps 69 | 70 | # Error Managements 71 | error.catalog.applicationId=cds 72 | error.catalog.type=properties 73 | error.catalog.errorDefinitionDir=/opt/app/onap/config/ 74 | 75 | # Used in Health Check 76 | #endpoints.user.name=ccsdkapps 77 | #endpoints.user.password=ccsdkapps 78 | 79 | # Executor Options 80 | blueprintsprocessor.resourceResolution.enabled=true 81 | blueprintsprocessor.netconfExecutor.enabled=true 82 | blueprintsprocessor.restConfExecutor.enabled=true 83 | blueprintsprocessor.cliExecutor.enabled=true 84 | blueprintsprocessor.remoteScriptCommand.enabled=true 85 | 86 | # Command executor 87 | blueprintsprocessor.grpcclient.remote-python.type=token-auth 88 | blueprintsprocessor.grpcclient.remote-python.host=localhost 89 | blueprintsprocessor.grpcclient.remote-python.port=50051 90 | blueprintsprocessor.grpcclient.remote-python.token=Basic Y2NzZGthcHBzOmNjc2RrYXBwcw== 91 | 92 | # Py executor 93 | blueprintsprocessor.grpcclient.py-executor.type=tls-auth 94 | blueprintsprocessor.grpcclient.py-executor.host=py-executor-default:50052 95 | blueprintsprocessor.grpcclient.py-executor.trustCertCollection=/opt/app/onap/config/certs/py-executor/py-executor-chain.pem 96 | 97 | # Config Data REST client settings 98 | blueprintsprocessor.restconfEnabled=true 99 | blueprintsprocessor.restclient.sdnc.type=basic-auth 100 | blueprintsprocessor.restclient.sdnc.url=http://sdnc:8282 101 | blueprintsprocessor.restclient.sdnc.username=admin 102 | blueprintsprocessor.restclient.sdnc.password=Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U 103 | 104 | # Naming MS REST client settings 105 | blueprintsprocessor.restclient.naming-ms.type=basic-auth 106 | blueprintsprocessor.restclient.naming-ms.url=http://naming-ms:8282 107 | blueprintsprocessor.restclient.naming-ms.username=admin 108 | blueprintsprocessor.restclient.naming-ms.password=demo123456! 109 | 110 | # IPAssign MS REST client settings 111 | blueprintsprocessor.restclient.ipassign-ms.type=basic-auth 112 | blueprintsprocessor.restclient.ipassign-ms.url=http://naming-ms:8282 113 | blueprintsprocessor.restclient.ipassign-ms.username=admin 114 | blueprintsprocessor.restclient.ipassign-ms.password=demo123456! 115 | 116 | # Primary AAI Data REST Client settings 117 | blueprintsprocessor.restclient.aai-data.type=basic-auth 118 | blueprintsprocessor.restclient.aai-data.url=https://aai:8443 119 | blueprintsprocessor.restclient.aai-data.username=aai@aai.onap.org 120 | blueprintsprocessor.restclient.aai-data.password=demo123456! 121 | blueprintsprocessor.restclient.aai-data.additionalHeaders.X-TransactionId=cds-transaction-id 122 | blueprintsprocessor.restclient.aai-data.additionalHeaders.X-FromAppId=cds-app-id 123 | blueprintsprocessor.restclient.aai-data.additionalHeaders.Accept=application/json 124 | 125 | # Kafka audit service Configurations 126 | ## Audit request 127 | blueprintsprocessor.messageproducer.self-service-api.audit.kafkaEnable=false 128 | blueprintsprocessor.messageproducer.self-service-api.audit.request.type=kafka-basic-auth 129 | blueprintsprocessor.messageproducer.self-service-api.audit.request.bootstrapServers=127.0.0.1:9092 130 | blueprintsprocessor.messageproducer.self-service-api.audit.request.clientId=audit-request-producer-client-id 131 | blueprintsprocessor.messageproducer.self-service-api.audit.request.topic=audit-request-producer.t 132 | #### Security settings 133 | #### SSL 134 | #blueprintsprocessor.messageproducer.self-service-api.audit.request.truststore=/path/to/truststore.jks 135 | #blueprintsprocessor.messageproducer.self-service-api.audit.request.truststorePassword=truststorePassword 136 | #blueprintsprocessor.messageproducer.self-service-api.audit.request.keystore=/path/to/keystore.jks 137 | #blueprintsprocessor.messageproducer.self-service-api.audit.request.keystorePassword=keystorePassword 138 | #### SCRAM 139 | #blueprintsprocessor.messageproducer.self-service-api.audit.request.scramUsername=test-user 140 | #blueprintsprocessor.messageproducer.self-service-api.audit.request.scramPassword=testUserPassword 141 | 142 | ## Audit response 143 | blueprintsprocessor.messageproducer.self-service-api.audit.response.type=kafka-basic-auth 144 | blueprintsprocessor.messageproducer.self-service-api.audit.response.bootstrapServers=127.0.0.1:9092 145 | blueprintsprocessor.messageproducer.self-service-api.audit.response.clientId=audit-response-producer-client-id 146 | blueprintsprocessor.messageproducer.self-service-api.audit.response.topic=audit-response-producer.t 147 | 148 | # Message prioritization kakfa properties, Enable if Prioritization service is needed 149 | # Deploy message-prioritization function along with blueprintsprocessor application. 150 | #blueprintsprocessor.messageconsumer.prioritize-input.type=kafka-streams-basic-auth 151 | #blueprintsprocessor.messageconsumer.prioritize-input.bootstrapServers=127.0.0.1:9092 152 | #blueprintsprocessor.messageconsumer.prioritize-input.applicationId=cds-controller 153 | #blueprintsprocessor.messageconsumer.prioritize-input.topic=prioritize-input-topic 154 | 155 | blueprintprocessor.remoteScriptCommand.enabled=true 156 | 157 | #Encrypted username and password for health check service 158 | endpoints.user.name=eHbVUbJAj4AG2522cSbrOQ== 159 | endpoints.user.password=eHbVUbJAj4AG2522cSbrOQ== 160 | 161 | #BaseUrls for health check blueprint processor services 162 | blueprintprocessor.healthcheck.baseUrl=http://localhost:8080/ 163 | blueprintprocessor.healthcheck.mapping-service-name-with-service-link=[Execution service,/api/v1/execution-service/health-check],[Resources service,/api/v1/resources/health-check],[Template service,/api/v1/template/health-check] 164 | 165 | #BaseUrls for health check Cds Listener services 166 | cdslistener.healthcheck.baseUrl=http://cds-sdc-listener:8080/ 167 | cdslistener.healthcheck.mapping-service-name-with-service-link=[SDC Listener service,/api/v1/sdclistener/healthcheck] 168 | 169 | #Actuator properties 170 | management.endpoints.web.exposure.include=* 171 | management.endpoint.health.show-details=always 172 | management.info.git.mode=full 173 | 174 | #K8s Plugin properties 175 | blueprintprocessor.k8s.plugin.username=test 176 | blueprintprocessor.k8s.plugin.password=pass 177 | blueprintprocessor.k8s.plugin.url=http://multicloud-k8s:9015/ 178 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /vpp-traceability/vpp_bpftrace.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | # Trace VPP BPF tooling to display output from BPF probes. 4 | # 5 | # Copyright 2020 GitHub, Inc. 6 | # Copyright 2020 Pantheon.tech and/or its affiliates. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | 10 | from __future__ import print_function 11 | import argparse 12 | import curses 13 | import inspect 14 | import ipaddress 15 | import logging 16 | import os 17 | import sys 18 | import subprocess 19 | from bcc import BPF, USDT 20 | from decimal import Decimal 21 | from multiprocessing import Process 22 | from select import select 23 | from struct import * 24 | from time import sleep, strftime 25 | 26 | Config = {} 27 | VppBpfProbes = {} 28 | VppBpfPerfProbes = {} 29 | USDT_ctx = {} 30 | 31 | def bpf_tracing2curses(stdscr, vpp_bpf_probes): 32 | global Config 33 | 34 | def render_header(stdscr, line, header, col=0): 35 | stdscr.attron(curses.color_pair(2)) 36 | stdscr.attron(curses.A_BOLD) 37 | stdscr.addstr(line, col, header) 38 | stdscr.addstr(line+1, col, "=" * len(header)) 39 | stdscr.attroff(curses.color_pair(2)) 40 | stdscr.attroff(curses.A_BOLD) 41 | 42 | # Clear and refresh the screen for a blank canvas 43 | stdscr.clear() 44 | stdscr.refresh() 45 | 46 | auto_refresh = True 47 | key = 0 48 | 49 | # Start colors in curses 50 | curses.start_color() 51 | curses.init_pair(1, curses.COLOR_CYAN, curses.COLOR_BLACK) 52 | curses.init_pair(2, curses.COLOR_BLUE, curses.COLOR_BLACK) 53 | curses.init_pair(3, curses.COLOR_BLACK, curses.COLOR_WHITE) 54 | curses.init_pair(4, curses.COLOR_MAGENTA, curses.COLOR_BLACK) 55 | 56 | titlestr = "VPP BPFtrace tooling" 57 | header_simple_counters = "{:<11} | {:<32} | {:^15}".format("SW-if-index", "Counter name", "Count") 58 | header_error_counters = "{:<11} | {:<32} | {:^15}".format("Error-idx", "Counter name", "Count") 59 | header_stats = "{:^32} | {:^8}|{:^8}|{:^8}|{:^8}|{:^8}|{:^8}|{:^8}|{:^8}".format("Node name (with Calls > 0)", "Calls", "Vectors", "Suspends", "Clocks", "Vcts/Cls", "MxNodCls", "VctsAtMx", "MxClocks") 60 | header_intfs_info = "{:<46} | {:^5} | {:^7}".format("SW-if-index [if-name]", "State", "Core ID") 61 | header_vector_rates = "{:^9} | {:^7} | {:^7} | {:^32}".format("Core ID", "Calls", "Vectors", "Internal node vector rate") 62 | height, width = stdscr.getmaxyx() 63 | 64 | while (key != ord('q')): 65 | # Initialization 66 | stdscr.clear() 67 | line = 0 68 | 69 | simple_counters = vpp_bpf_probes["InterfaceCounters"].get_table("simple_counters") if (vpp_bpf_probes.get("InterfaceCounters") != None) else None 70 | error_counters = vpp_bpf_probes["ErrorCounters"].get_table("error_counters") if (vpp_bpf_probes.get("ErrorCounters") != None) else None 71 | stats_counters = vpp_bpf_probes["NodeStatistics"].get_table("stats_counters") if (vpp_bpf_probes.get("NodeStatistics") != None) else None 72 | intfs_info = vpp_bpf_probes["InterfacesInfo"].get_table("intfs_info") if (vpp_bpf_probes.get("InterfacesInfo") != None) else None 73 | vector_rate_counters = vpp_bpf_probes["NodeStatistics"].get_table("vector_rate_counters") if (vpp_bpf_probes.get("NodeStatistics") != None) else None 74 | 75 | # Render status bar 76 | refreshstr = "Auto {:2} s".format(Config["refresh_interval"]) if auto_refresh else "Manual" 77 | statusbarstr = " STATUS BAR | Attached to pid {} | Refresh : {:>9} | Press 'q' to exit, 'r' to refresh, 'a' for auto-refresh".format(Config["pid"], refreshstr) 78 | stdscr.attron(curses.color_pair(3)) 79 | stdscr.addstr(height-1, 0, statusbarstr) 80 | stdscr.addstr(height-1, len(statusbarstr), " " * (width - len(statusbarstr) - 1)) 81 | stdscr.attroff(curses.color_pair(3)) 82 | 83 | # Render title bar 84 | stdscr.attron(curses.color_pair(4)) 85 | stdscr.attron(curses.A_BOLD) 86 | col = int((width // 2) - (len(titlestr) // 2) - len(titlestr) % 2) 87 | stdscr.addstr(line, col, titlestr) 88 | stdscr.attroff(curses.color_pair(4)) 89 | stdscr.attroff(curses.A_BOLD) 90 | 91 | # Render splitters 92 | stdscr.attron(curses.color_pair(2)) 93 | stdscr.attron(curses.A_BOLD) 94 | for l in range(line+2, height-Config["log_height"]-3): stdscr.addstr(l, 68, "|") 95 | for c in range(0, width): stdscr.addstr(height-Config["log_height"]-4, c, "-") 96 | stdscr.attroff(curses.color_pair(2)) 97 | stdscr.attroff(curses.A_BOLD) 98 | 99 | if stats_counters != None: 100 | # Render stat header 101 | render_header(stdscr, line+2, header_stats, col=70) 102 | # Rendering stat probes output 103 | l = line+4 104 | for k, v in sorted(stats_counters.items(), key=lambda kv: kv[1].node_name): 105 | if l == height-Config["log_height"]-5: 106 | stdscr.addstr(l, 70, "...") 107 | break 108 | if v.calls > 0: 109 | item = "{:<32} | {:1.2E} {:1.2E} {:1.2E} {:1.2E} {:1.2E} {:1.2E} {:1.2E} {:1.2E}". \ 110 | format(v.node_name, v.calls, v.vectors, \ 111 | v.suspends, v.clocksperx, v.vectorspercall, \ 112 | v.maxcn, v.maxn, v.maxc) 113 | #v.clocksperx, v.vectorspercall, v.maxcn, v.maxn, v.maxc) 114 | stdscr.addstr(l, 70, item) 115 | l += 1 116 | if l>60: 117 | break; 118 | 119 | if vector_rate_counters != None: 120 | # Render vector rate header 121 | line += 2 122 | render_header(stdscr, line, header_vector_rates) 123 | # Rendering vector rate output 124 | line += 2 125 | for k, v in vector_rate_counters.items(): 126 | item = "{:^9} | {:^7} | {:^7} | {:^30.02E}".format(k.node_index, v.calls, v.vectors, \ 127 | v.vectors/v.calls if v.calls>0 else 0) 128 | stdscr.addstr(line, 0, item) 129 | line += 1 130 | 131 | if simple_counters != None: 132 | # Header simple counters 133 | line += 2 134 | render_header(stdscr, line, header_simple_counters) 135 | 136 | # Rendering simple counter probes output 137 | line += 2 138 | for k, v in simple_counters.items(): 139 | item = "{:^11} | {:<32} | {:^15}".format(k.counter_index, k.name, v.total) 140 | stdscr.addstr(line, 0, item) 141 | line += 1 142 | 143 | if error_counters != None: 144 | # Header error counters 145 | line += 1 146 | render_header(stdscr, line, header_error_counters) 147 | 148 | # Rendering error counter probes output 149 | line += 2 150 | for k, v in error_counters.items(): 151 | item = "{:^11} | {:<32} | {:^15}".format(k.counter_index, k.name, v.total) 152 | stdscr.addstr(line, 0, item) 153 | line += 1 154 | 155 | if intfs_info != None: 156 | # Header interfaces info 157 | line += 1 158 | render_header(stdscr, line, header_intfs_info) 159 | 160 | # Rendering interface info output 161 | line += 2 162 | for k, v in intfs_info.items(): 163 | item = "{:>3} {:<42} | {:^5} | {:^7}".format(k.if_index,"["+v.if_name+"]", Config["if_s"][v.state], v.thread_index) 164 | stdscr.addstr(line, 0, item) 165 | line += 1 166 | 167 | # Render last Config["log_height"] lines from FILE_LOG 168 | line = height - Config["log_height"] - 2 169 | p = subprocess.Popen(['tail','-n',str(Config["log_height"]),Config["log_file"]], stdout=subprocess.PIPE) 170 | soutput, sinput = p.communicate() 171 | for msg in soutput.split('\n'): 172 | stdscr.addstr(line, 0, msg) 173 | line += 1 174 | 175 | # Set cursor position 176 | stdscr.move(height-1, 0) 177 | # Refresh the screen 178 | stdscr.refresh() 179 | 180 | # Wait for next input 181 | key = ord('a') if auto_refresh else 0 182 | while (key == 0 or key == ord('a')): 183 | rlist, wlist, xlist = select([sys.stdin], [], [], Config["refresh_interval"]) 184 | if rlist: 185 | key = stdscr.getch() 186 | if key == ord('a'): 187 | auto_refresh = True 188 | break 189 | elif key == ord('q'): 190 | break 191 | elif key == ord('r') or key == ord('m'): 192 | auto_refresh = False 193 | break 194 | else: 195 | if auto_refresh: 196 | break 197 | key = 0 198 | 199 | # Callbacks fot performace loggers 200 | 201 | def log_nbh_event(cpu, data, size): 202 | global Config, VppBpfProbes 203 | 204 | nbh_updates = VppBpfProbes["NbhUpdates"] if (VppBpfProbes.get("NbhUpdates") != None) else None 205 | 206 | event = nbh_updates["nbh_events"].event(data) 207 | 208 | ip_bytes = bytearray() 209 | for b in event.ip_address[0:Config["ip_len"][event.is_ipv6]]: ip_bytes.append (b) 210 | 211 | item_fmt = "{:<24} | {:6} | {:3} | {:36} | {:<17} | {:^12}" if event.is_ipv6 else "{:<24} | {:6} | {:3} | {:15} | {:<17} | {:^12}" 212 | item = item_fmt. \ 213 | format("vnet_ip_neighbor_probe", event.sw_if_index, Config["mode_s"][event.is_del], \ 214 | ipaddress.ip_address(bytes(ip_bytes)), \ 215 | ':'.join('%02x' % b for b in event.mac_address), \ 216 | Config["nbh_fl_s"][event.flags]) 217 | 218 | logging.info(item) 219 | 220 | def log_ip_event(cpu, data, size): 221 | global Config, VppBpfProbes 222 | ip_updates = VppBpfProbes["IpUpdates"] if (VppBpfProbes.get("IpUpdates") != None) else None 223 | 224 | event = ip_updates["ip_events"].event(data) 225 | 226 | ip_bytes = bytearray() 227 | for b in event.ip_address[0:Config["ip_len"][event.is_ipv6]]: ip_bytes.append (b) 228 | 229 | item = "{:<24} | {:6} | {:3} | {:3} | {:<128}".\ 230 | format("vnet_ip_address_probe", event.sw_if_index, Config["mode_s"][event.is_del], Config["ip_s"][event.is_ipv6], \ 231 | "{}/{}".format(ipaddress.ip_address(bytes(ip_bytes)), event.address_length)) 232 | 233 | logging.info(item) 234 | 235 | def log_route_event(cpu, data, size): 236 | global Config, VppBpfProbes 237 | route_updates = VppBpfProbes["RouteUpdates"] if (VppBpfProbes.get("RouteUpdates") != None) else None 238 | 239 | event = route_updates["route_events"].event(data) 240 | 241 | path_ip_bytes = bytearray() 242 | route_ip_bytes = bytearray() 243 | for b in event.path[0:Config["ip_len"][event.is_ipv6]]: path_ip_bytes.append (b) 244 | for b in event.route[0:Config["ip_len"][event.is_ipv6]]: route_ip_bytes.append (b) 245 | 246 | item_fmt = "{:<24} | {:6} | {:3} | {:36} | {:32}" if event.is_ipv6 else "{:<24} | {:6} | {:3} | {:20} | {:15}" 247 | item = item_fmt.format("vnet_ip_route_probe", event.fib_index, Config["mode_s"][event.is_del], \ 248 | "{}/{}".format(ipaddress.ip_address(bytes(path_ip_bytes)), event.path_len), \ 249 | ipaddress.ip_address(bytes(route_ip_bytes))) 250 | 251 | logging.info(item) 252 | 253 | def log_nat_event(cpu, data, size): 254 | global Config, VppBpfProbes 255 | nat_updates = VppBpfProbes["NatUpdates"] if (VppBpfProbes.get("NatUpdates") != None) else None 256 | 257 | event = nat_updates["nat_events"].event(data) 258 | item = "{:24} | {:6} | {:3} | {:3} | {:3} | {:>15}:{:<5} | {:>15}:{:<5}".\ 259 | format("vnet_nat_session_update", event.thread_index, \ 260 | Config["nat_op_s"][event.operation], \ 261 | event.fib_index, event.protocol, \ 262 | ipaddress.ip_address(event.in2out_addr), event.in2out_port, \ 263 | ipaddress.ip_address(event.out2in_addr), event.out2in_port) 264 | 265 | logging.info(item) 266 | 267 | ProbesWrapper = { 268 | "InterfaceCounters" : { 269 | "perf": False, 270 | "bcc": "vlib_simple_counters.c", 271 | "probes": ["vlib_increment_simple_counters_probe"], 272 | "probes_fn": ["vpp_simple_counters"]}, 273 | "ErrorCounters" : { 274 | "perf": False, 275 | "bcc": "vlib_error_counters.c", 276 | "probes": ["vlib_error_count_probe"], 277 | "probes_fn": ["vpp_error_counters"]}, 278 | "NodeStatistics" : { 279 | "perf": False, 280 | "bcc": "vlib_stats.c", 281 | "probes": ["vlib_node_runtime_sync_stats_probe", "vlib_vector_rate_probe"], 282 | "probes_fn": ["vpp_stats", "vpp_vector_rate"]}, 283 | "InterfacesInfo" : { 284 | "perf": False, 285 | "bcc": "vnet_interfaces.c", 286 | "probes": ["vnet_sw_interface_state_probe","vnet_set_hw_interface_rx_placement_probe","vnet_hw_interface_set_rx_mode_probe"], 287 | "probes_fn": ["vpp_intfs_state","vpp_intfs_rx_placement","vpp_intfs_rx_mode"]}, 288 | "NbhUpdates": { 289 | "perf": True, 290 | "bcc": "vnet_neighbor_updates.c", 291 | "probes": ["vnet_ip_neighbor_probe"], 292 | "probes_fn": ["vpp_nbh_updates"], 293 | "events": "nbh_events", 294 | "callback": log_nbh_event}, 295 | "IpUpdates": { 296 | "perf": True, 297 | "bcc": "vnet_ip_updates.c", 298 | "probes": ["vnet_ip_address_probe"], 299 | "probes_fn": ["vpp_ip_updates"], 300 | "events": "ip_events", 301 | "callback": log_ip_event}, 302 | "RouteUpdates": { 303 | "perf": True, 304 | "bcc": "vnet_route_updates.c", 305 | "probes": ["vnet_ip_route_probe"], 306 | "probes_fn": ["vpp_route_updates"], 307 | "events": "route_events", 308 | "callback": log_route_event}, 309 | "NatUpdates": { 310 | "perf": True, 311 | "bcc": "vnet_nat_updates.c", 312 | "probes": ["vnet_nat_session_update_probe"], 313 | "probes_fn": ["vpp_nat_session_updates"], 314 | "events": "nat_events", 315 | "callback": log_nat_event}, 316 | } 317 | 318 | # Performance loggers 319 | 320 | def bpf_tracing2log(vpp_bpf_probe, event_table, *args): 321 | global VppBpfProbes 322 | 323 | updates = VppBpfProbes[vpp_bpf_probe] if (VppBpfProbes.get(vpp_bpf_probe) != None) else None 324 | if updates != None: 325 | updates[event_table].open_perf_buffer(*args, page_cnt=64) 326 | while 1: 327 | updates.perf_buffer_poll() 328 | 329 | def create_usdt(probe, ctx): 330 | global Config, ProbesWrapper 331 | 332 | probe_config = ProbesWrapper[probe] 333 | 334 | os_path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) 335 | bpf_code = open("%s/%s" % (os_path, probe_config["bcc"]), 'r').read() 336 | for p, f in zip(probe_config["probes"], probe_config["probes_fn"]): 337 | ctx.enable_probe( p, f) 338 | VppBpfProbes[probe] = BPF(text=bpf_code, usdt_contexts=[ctx], debug=Config["debugLevel"]) 339 | 340 | def create_bpf_tracer(probe): 341 | global ProbesWrapper 342 | 343 | probe_config = ProbesWrapper[probe] 344 | 345 | VppBpfPerfProbes[probe] = Process(target=bpf_tracing2log, 346 | args=(probe, probe_config["events"], probe_config["callback"])) 347 | 348 | def main(): 349 | global Config 350 | 351 | Config["bcc_path"] = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) 352 | Config["refresh_interval"] = 10 353 | Config["debugLevel"] = 0 354 | Config["log_file"] = Config["bcc_path"] + "/vpp_bpf_tracer.log" 355 | Config["log_height"] = 15 356 | 357 | Config["if_s"] = { 0: 'DOWN', 1: 'UP' } 358 | Config["mode_s"] = { 0: 'ADD', 1: 'DEL' } 359 | Config["ip_s"] = { 0: 'IP4', 1: 'IP6'} 360 | Config["nat_op_s"] = { 0: 'CRE', 1: 'UPD', 2: 'DEL' } 361 | Config["nbh_fl_s"] = { 1: 'STATIC', 2: 'DYNAMIC', 4: 'NO_FIB_ENTRY', 8: 'PENDING', 16: 'STALE' } 362 | Config["ip_len"] = { 0: 4, 1: 16 } 363 | 364 | # Parse command line arguments 365 | parser = argparse.ArgumentParser(description="Trace VPP interface's counters.", formatter_class=argparse.RawDescriptionHelpFormatter) 366 | parser.add_argument("-p", "--pid", type=int, help="The id of the VPP process to trace.") 367 | parser.add_argument("-r", "--refresh", dest="refresh_interval", type=int, help="Time interval for auto refresh") 368 | parser.add_argument("-l", "--log_height", dest="log_height", type=int, help="Height, in lines, of log part of window") 369 | parser.add_argument("-v", "--verbose", dest="verbose", action="store_true", help="If true, will output verbose logging information.") 370 | parser.set_defaults(verbose=False) 371 | args = parser.parse_args() 372 | 373 | # Monitored process ID 374 | Config["pid"] = int(args.pid) 375 | # Refresh rate 376 | if args.refresh_interval: 377 | Config["refresh_interval"] = int(args.refresh_interval) 378 | if args.log_height: 379 | Config["log_height"] = int(args.log_height) 380 | # Debug level 381 | if args.verbose: 382 | Config["debugLevel"]=4 383 | 384 | print("Attaching probes to pid %d ..." % Config["pid"]) 385 | 386 | if os.path.exists(Config["log_file"]): 387 | os.remove(Config["log_file"]) 388 | logging.basicConfig(level=logging.DEBUG, filename=Config["log_file"], 389 | filemode="a+", format="%(asctime)-15s %(levelname)-8s %(message)s") 390 | 391 | # Create USDT contexts 392 | usdt_ctx_simple = USDT(pid=Config["pid"]) 393 | usdt_ctx_error = USDT(pid=Config["pid"]) 394 | usdt_ctx_stats = USDT(pid=Config["pid"]) 395 | usdt_ctx_intfs = USDT(pid=Config["pid"]) 396 | usdt_ctx_nbh = USDT(pid=Config["pid"]) 397 | usdt_ctx_ip = USDT(pid=Config["pid"]) 398 | usdt_ctx_route = USDT(pid=Config["pid"]) 399 | usdt_ctx_nat = USDT(pid=Config["pid"]) 400 | 401 | create_usdt("InterfaceCounters", usdt_ctx_simple) 402 | create_usdt("ErrorCounters", usdt_ctx_error) 403 | create_usdt("NodeStatistics", usdt_ctx_stats) 404 | create_usdt("InterfacesInfo", usdt_ctx_intfs) 405 | create_usdt("NbhUpdates", usdt_ctx_nbh) 406 | create_usdt("IpUpdates", usdt_ctx_ip) 407 | create_usdt("RouteUpdates", usdt_ctx_route) 408 | create_usdt("NatUpdates", usdt_ctx_nat) 409 | 410 | for k, v in ProbesWrapper.items(): 411 | if (v["perf"]): 412 | create_bpf_tracer(k) 413 | 414 | # Start tracing 415 | for v in VppBpfPerfProbes.itervalues(): 416 | v.start() 417 | curses.wrapper(bpf_tracing2curses, VppBpfProbes) 418 | 419 | # Stop tracing 420 | for v in VppBpfPerfProbes.itervalues(): 421 | v.terminate() 422 | 423 | print("Closing probes ...") 424 | 425 | if __name__ == "__main__": 426 | main() -------------------------------------------------------------------------------- /vpp-traceability/vpp-traceability.diff: -------------------------------------------------------------------------------- 1 | diff --git a/src/plugins/nat/nat_ha.c b/src/plugins/nat/nat_ha.c 2 | index 8bf07759f..f24f0e01f 100644 3 | --- a/src/plugins/nat/nat_ha.c 4 | +++ b/src/plugins/nat/nat_ha.c 5 | @@ -691,6 +691,16 @@ nat_ha_sadd (ip4_address_t * in_addr, u16 in_port, ip4_address_t * out_addr, 6 | ip4_address_t * ehn_addr, u16 ehn_port, u8 proto, u32 fib_index, 7 | u16 flags, u32 thread_index, u8 is_resync) 8 | { 9 | +#ifdef USE_BPF_TRACE 10 | + DTRACE_PROBE8 (vpp, vnet_nat_session_update_probe, 0 /* create */ , 11 | + thread_index, 12 | + (u32) fib_index, 13 | + (u32) proto, 14 | + htonl (in_addr->as_u32), 15 | + (u32) (htons (in_port)), 16 | + htonl (out_addr->as_u32), (u32) (htons (out_port))); 17 | +#endif 18 | + 19 | nat_ha_event_t event; 20 | 21 | skip_if_disabled (); 22 | diff --git a/src/plugins/nat/nat_inlines.h b/src/plugins/nat/nat_inlines.h 23 | index 7c28919f7..1d4e3a5a8 100644 24 | --- a/src/plugins/nat/nat_inlines.h 25 | +++ b/src/plugins/nat/nat_inlines.h 26 | @@ -22,6 +22,7 @@ 27 | #include 28 | #include 29 | #include 30 | +#include 31 | 32 | static inline uword 33 | nat_pre_node_fn_inline (vlib_main_t * vm, 34 | @@ -281,6 +282,17 @@ nat44_delete_session (snat_main_t * sm, snat_session_t * ses, 35 | 36 | nat44_delete_user_with_no_session (sm, u, thread_index); 37 | } 38 | + 39 | +#ifdef USE_BPF_TRACE 40 | + DTRACE_PROBE8 (vpp, vnet_nat_session_update_probe, 2 /* delete */ , 41 | + thread_index, 42 | + (u32) (ses->in2out.fib_index), 43 | + (u32) (ses->in2out.protocol), 44 | + htonl (ses->in2out.addr.as_u32), 45 | + (u32) (htons (ses->in2out.port)), 46 | + htonl (ses->out2in.addr.as_u32), 47 | + (u32) (htons (ses->out2in.port))); 48 | +#endif 49 | } 50 | 51 | /** \brief Set TCP session state. 52 | @@ -295,6 +307,11 @@ nat44_set_tcp_session_state_i2o (snat_main_t * sm, f64 now, 53 | u8 tcp_flags = vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags; 54 | u32 tcp_ack_number = vnet_buffer (b)->ip.reass.tcp_ack_number; 55 | u32 tcp_seq_number = vnet_buffer (b)->ip.reass.tcp_seq_number; 56 | +#ifdef USE_BPF_TRACE 57 | + u8 old_state = ses->state; 58 | + bool is_add = false; 59 | +#endif 60 | + 61 | if ((ses->state == 0) && (tcp_flags & TCP_FLAG_RST)) 62 | ses->state = NAT44_SES_RST; 63 | if ((ses->state == NAT44_SES_RST) && !(tcp_flags & TCP_FLAG_RST)) 64 | @@ -303,7 +320,12 @@ nat44_set_tcp_session_state_i2o (snat_main_t * sm, f64 now, 65 | (ses->state & NAT44_SES_O2I_SYN)) 66 | ses->state = 0; 67 | if (tcp_flags & TCP_FLAG_SYN) 68 | - ses->state |= NAT44_SES_I2O_SYN; 69 | + { 70 | + ses->state |= NAT44_SES_I2O_SYN; 71 | +#ifdef USE_BPF_TRACE 72 | + is_add = true; 73 | +#endif 74 | + } 75 | if (tcp_flags & TCP_FLAG_FIN) 76 | { 77 | ses->i2o_fin_seq = clib_net_to_host_u32 (tcp_seq_number); 78 | @@ -333,6 +355,21 @@ nat44_set_tcp_session_state_i2o (snat_main_t * sm, f64 now, 79 | } 80 | clib_dlist_remove (tsm->lru_pool, ses->lru_index); 81 | clib_dlist_addtail (tsm->lru_pool, ses->lru_head_index, ses->lru_index); 82 | + 83 | +#ifdef USE_BPF_TRACE 84 | + if (old_state != ses->state) 85 | + { 86 | + DTRACE_PROBE8 (vpp, vnet_nat_session_update_probe, 87 | + (is_add) ? 0 : 1 /* create / update */ , 88 | + thread_index, 89 | + (u32) (ses->in2out.fib_index), 90 | + (u32) (ses->in2out.protocol), 91 | + htonl (ses->in2out.addr.as_u32), 92 | + (u32) (htons (ses->in2out.port)), 93 | + htonl (ses->out2in.addr.as_u32), 94 | + (u32) (htons (ses->out2in.port))); 95 | + } 96 | +#endif 97 | return 0; 98 | } 99 | 100 | diff --git a/src/vlib/CMakeLists.txt b/src/vlib/CMakeLists.txt 101 | index 8a31af687..288fdf85b 100644 102 | --- a/src/vlib/CMakeLists.txt 103 | +++ b/src/vlib/CMakeLists.txt 104 | @@ -97,6 +97,7 @@ add_vpp_library(vlib 105 | unix/util.c 106 | vmbus/vmbus.c 107 | ${VMBUS_SOURCE} 108 | + bpf_tracer.c 109 | 110 | MULTIARCH_SOURCES 111 | drop.c 112 | diff --git a/src/vlib/bpf_tracer.c b/src/vlib/bpf_tracer.c 113 | new file mode 100644 114 | index 000000000..1e0fbe5c8 115 | --- /dev/null 116 | +++ b/src/vlib/bpf_tracer.c 117 | @@ -0,0 +1,130 @@ 118 | +/* 119 | + * Copyright (c) 2020 Pantheon.tech and/or its affiliates. 120 | + * 121 | + * Licensed under the Apache License, Version 2.0 (the "License"); 122 | + * you may not use this file except in compliance with the License. 123 | + * You may obtain a copy of the License at: 124 | + * 125 | + * http://www.apache.org/licenses/LICENSE-2.0 126 | + * 127 | + * Unless required by applicable law or agreed to in writing, software 128 | + * distributed under the License is distributed on an "AS IS" BASIS, 129 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130 | + * See the License for the specific language governing permissions and 131 | + * limitations under the License. 132 | + */ 133 | + 134 | +#include "bpf_tracer.h" 135 | + 136 | +#ifdef USE_BPF_TRACE 137 | + 138 | +bpf_tracer_main_t bpf_tracer_main; 139 | + 140 | +static clib_error_t * 141 | +bpftracer_config (vlib_main_t * vm, unformat_input_t * input) 142 | +{ 143 | + bpf_tracer_main_t *bm = &bpf_tracer_main; 144 | + bm->update_interval = 10.0; 145 | + 146 | + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) 147 | + { 148 | + if (unformat (input, "update-interval %d", &bm->update_interval)) 149 | + ; 150 | + else 151 | + return clib_error_return (0, "unknown input `%U'", 152 | + format_unformat_error, input); 153 | + } 154 | + return 0; 155 | +} 156 | + 157 | +static clib_error_t * 158 | +bpf_tracer_init (vlib_main_t * vm) 159 | +{ 160 | + return 0; 161 | +} 162 | + 163 | +static void 164 | +update_node_runtime (vlib_main_t * vm) 165 | +{ 166 | + vlib_node_main_t *nm = 0; 167 | + vlib_main_t **stat_vms = 0, *stat_vm; 168 | + uword i, j; 169 | + 170 | + for (i = 0; i < vec_len (vlib_mains); i++) 171 | + { 172 | + stat_vm = vlib_mains[i]; 173 | + if (stat_vm) 174 | + { 175 | + vec_add1 (stat_vms, stat_vm); 176 | + } 177 | + } 178 | + 179 | + /* 180 | + * Barrier sync across stats scraping. 181 | + * Otherwise, the counts will be grossly inaccurate. 182 | + */ 183 | + vlib_worker_thread_barrier_sync (vm); 184 | + 185 | + for (j = 0; j < vec_len (stat_vms); j++) 186 | + { 187 | + stat_vm = stat_vms[j]; 188 | + nm = &stat_vm->node_main; 189 | + 190 | + for (i = 0; i < vec_len (nm->nodes); i++) 191 | + { 192 | + vlib_node_sync_stats (stat_vm, nm->nodes[i]); 193 | + } 194 | + 195 | + DTRACE_PROBE3 (vpp, vlib_vector_rate_probe, 196 | + stat_vm->cpu_id, 197 | + stat_vm->internal_node_vectors - 198 | + stat_vm->internal_node_vectors_last_clear, 199 | + stat_vm->internal_node_calls - 200 | + stat_vm->internal_node_calls_last_clear); 201 | + } 202 | + vlib_worker_thread_barrier_release (vm); 203 | + 204 | + vec_free (stat_vms); 205 | +} 206 | + 207 | +static uword 208 | +bpf_tracer_process (vlib_main_t * vm, vlib_node_runtime_t * rt, 209 | + vlib_frame_t * f) 210 | +{ 211 | + bpf_tracer_main_t *bm = &bpf_tracer_main; 212 | + 213 | + while (1) 214 | + { 215 | + /* update BPF counters */ 216 | + update_node_runtime (vm); 217 | + 218 | + /* suspend for required time interval */ 219 | + vlib_process_suspend (vm, (f64) bm->update_interval); 220 | + } 221 | + return 0; 222 | +} 223 | + 224 | +VLIB_EARLY_CONFIG_FUNCTION (bpftracer_config, "bpftracer"); 225 | + 226 | +VLIB_INIT_FUNCTION (bpf_tracer_init) = 227 | +{ 228 | +}; 229 | + 230 | +/* *INDENT-OFF* */ 231 | +VLIB_REGISTER_NODE (bpf_tracer_collector, static) = 232 | +{ 233 | +.function = bpf_tracer_process, 234 | +.name = "bpftracer-process", 235 | +.type = VLIB_NODE_TYPE_PROCESS, 236 | +}; 237 | +/* *INDENT-ON* */ 238 | + 239 | +#endif 240 | + 241 | +/* 242 | + * fd.io coding-style-patch-verification: ON 243 | + * 244 | + * Local Variables: 245 | + * eval: (c-set-style "gnu") 246 | + * End: 247 | + */ 248 | diff --git a/src/vlib/bpf_tracer.h b/src/vlib/bpf_tracer.h 249 | new file mode 100644 250 | index 000000000..50a391379 251 | --- /dev/null 252 | +++ b/src/vlib/bpf_tracer.h 253 | @@ -0,0 +1,42 @@ 254 | +/* 255 | + * Copyright (c) 2020 Pantheon.tech and/or its affiliates. 256 | + * 257 | + * Licensed under the Apache License, Version 2.0 (the "License"); 258 | + * you may not use this file except in compliance with the License. 259 | + * You may obtain a copy of the License at: 260 | + * 261 | + * http://www.apache.org/licenses/LICENSE-2.0 262 | + * 263 | + * Unless required by applicable law or agreed to in writing, software 264 | + * distributed under the License is distributed on an "AS IS" BASIS, 265 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 266 | + * See the License for the specific language governing permissions and 267 | + * limitations under the License. 268 | + */ 269 | + 270 | +#ifndef included_bpf_tracer_h 271 | +#define included_bpf_tracer_h 272 | + 273 | +#define USE_BPF_TRACE 274 | + 275 | +#ifdef USE_BPF_TRACE 276 | +#include 277 | +#include 278 | + 279 | +typedef struct 280 | +{ 281 | + /* Update interval */ 282 | + u32 update_interval; 283 | +} bpf_tracer_main_t; 284 | + 285 | +#endif 286 | + 287 | +#endif /* included_bpf_tracer_h */ 288 | + 289 | +/* 290 | + * fd.io coding-style-patch-verification: ON 291 | + * 292 | + * Local Variables: 293 | + * eval: (c-set-style "gnu") 294 | + * End: 295 | + */ 296 | diff --git a/src/vlib/counter.h b/src/vlib/counter.h 297 | index 8a5aed4c1..c3fb97b9e 100644 298 | --- a/src/vlib/counter.h 299 | +++ b/src/vlib/counter.h 300 | @@ -41,6 +41,7 @@ 301 | #define included_vlib_counter_h 302 | 303 | #include 304 | +#include 305 | 306 | /** \file 307 | 308 | @@ -82,6 +83,10 @@ vlib_increment_simple_counter (vlib_simple_counter_main_t * cm, 309 | 310 | my_counters = cm->counters[thread_index]; 311 | my_counters[index] += increment; 312 | +#ifdef USE_BPF_TRACE 313 | + DTRACE_PROBE3 (vpp, vlib_increment_simple_counters_probe, cm->name, index, 314 | + my_counters[index]); 315 | +#endif 316 | } 317 | 318 | /** Set a simple counter 319 | @@ -228,6 +233,13 @@ vlib_increment_combined_counter (vlib_combined_counter_main_t * cm, 320 | 321 | my_counters[index].packets += n_packets; 322 | my_counters[index].bytes += n_bytes; 323 | + 324 | +#ifdef USE_BPF_TRACE 325 | + DTRACE_PROBE2 (vpp, vlib_increment_combined_counters_packets_probe, index, 326 | + my_counters[index].packets); 327 | + DTRACE_PROBE2 (vpp, vlib_increment_combined_counters_bytes_probe, index, 328 | + my_counters[index].bytes); 329 | +#endif 330 | } 331 | 332 | /** Pre-fetch a per-thread combined counter for the given object index */ 333 | diff --git a/src/vlib/drop.c b/src/vlib/drop.c 334 | index e29195ad1..cfd4f6935 100644 335 | --- a/src/vlib/drop.c 336 | +++ b/src/vlib/drop.c 337 | @@ -222,7 +222,11 @@ process_drop_punt (vlib_main_t * vm, 338 | 339 | c_index = counter_index (vm, error[0]); 340 | em->counters[c_index] += count; 341 | - 342 | +#ifdef USE_BPF_TRACE 343 | + DTRACE_PROBE3 (vpp, vlib_error_count_probe, 344 | + em->error_strings_heap[c_index], c_index, 345 | + em->counters[c_index]); 346 | +#endif 347 | vlib_error_elog_count (vm, c_index, count); 348 | } 349 | 350 | diff --git a/src/vlib/error_funcs.h b/src/vlib/error_funcs.h 351 | index ab281ba2e..f3c95d7f8 100644 352 | --- a/src/vlib/error_funcs.h 353 | +++ b/src/vlib/error_funcs.h 354 | @@ -41,6 +41,7 @@ 355 | #define included_vlib_error_funcs_h 356 | 357 | #include 358 | +#include 359 | 360 | always_inline void 361 | vlib_error_elog_count (vlib_main_t * vm, uword counter, uword increment) 362 | @@ -65,7 +66,10 @@ vlib_error_count (vlib_main_t * vm, uword node_index, 363 | 364 | ASSERT (counter < vec_len (em->counters)); 365 | em->counters[counter] += increment; 366 | - 367 | +#ifdef USE_BPF_TRACE 368 | + DTRACE_PROBE3 (vpp, vlib_error_count_probe, em->error_strings_heap[counter], 369 | + counter, em->counters[counter]); 370 | +#endif 371 | vlib_error_elog_count (vm, counter, increment); 372 | } 373 | 374 | diff --git a/src/vlib/main.c b/src/vlib/main.c 375 | index 2e100b24d..9e250b394 100644 376 | --- a/src/vlib/main.c 377 | +++ b/src/vlib/main.c 378 | @@ -591,6 +591,38 @@ vlib_node_runtime_sync_stats (vlib_main_t * vm, 379 | r->perf_counter0_ticks_since_last_overflow = 0ULL; 380 | r->perf_counter1_ticks_since_last_overflow = 0ULL; 381 | r->perf_counter_vectors_since_last_overflow = 0ULL; 382 | + 383 | +#ifdef USE_BPF_TRACE 384 | + u64 clocks = n->stats_total.clocks - n->stats_last_clear.clocks; 385 | + u64 calls = n->stats_total.calls - n->stats_last_clear.calls; 386 | + u64 vectors = n->stats_total.vectors - n->stats_last_clear.vectors; 387 | + u64 suspends = n->stats_total.suspends - n->stats_last_clear.suspends; 388 | + u64 vectorspercall = (calls > 0) ? ((double) vectors / (double) calls) : 0; 389 | + f64 clocksperx = 0.; 390 | + f64 maxc = (f64) n->stats_total.max_clock; 391 | + u32 maxn = n->stats_total.max_clock_n; 392 | + f64 maxcn = 393 | + (n->stats_total.max_clock_n) ? (f64) n->stats_total.max_clock / 394 | + (f64) maxn : 0.0; 395 | + 396 | + // Clocks per packet, per call or per suspend. 397 | + clocksperx = 0; 398 | + if (vectors > 0) 399 | + clocksperx = (f64) clocks / (f64) vectors; 400 | + else if (calls > 0) 401 | + clocksperx = (f64) clocks / (f64) calls; 402 | + else if (suspends > 0) 403 | + clocksperx = (f64) clocks / (f64) suspends; 404 | + 405 | + DTRACE_PROBE10 (vpp, vlib_node_runtime_sync_stats_probe, n->name, r->node_index, calls, // Calls 406 | + vectors, // Vectors 407 | + suspends, // Suspends 408 | + clocksperx, // Clocks 409 | + vectorspercall, // Vectors/Call 410 | + maxcn, // Max Node Clocks 411 | + maxn, // Vectors at Max 412 | + maxc); // Max Clocks 413 | +#endif 414 | } 415 | 416 | always_inline void __attribute__ ((unused)) 417 | diff --git a/src/vlib/node_funcs.h b/src/vlib/node_funcs.h 418 | index 263017d0e..714add51c 100644 419 | --- a/src/vlib/node_funcs.h 420 | +++ b/src/vlib/node_funcs.h 421 | @@ -47,6 +47,7 @@ 422 | 423 | #include 424 | #include 425 | +#include 426 | 427 | /** \brief Get vlib node by index. 428 | @warning This function will ASSERT if @c i is out of range. 429 | @@ -1176,6 +1177,11 @@ vlib_node_increment_counter (vlib_main_t * vm, u32 node_index, 430 | vlib_error_main_t *em = &vm->error_main; 431 | u32 node_counter_base_index = n->error_heap_index; 432 | em->counters[node_counter_base_index + counter_index] += increment; 433 | +#ifdef USE_BPF_TRACE 434 | + DTRACE_PROBE2 (vpp, vlib_node_counter_probe, 435 | + node_counter_base_index + counter_index, 436 | + em->counters[node_counter_base_index + counter_index]); 437 | +#endif 438 | } 439 | 440 | /** @brief Create a vlib process 441 | diff --git a/src/vnet/devices/devices.c b/src/vnet/devices/devices.c 442 | index e78c5cbe4..4da65bc44 100644 443 | --- a/src/vnet/devices/devices.c 444 | +++ b/src/vnet/devices/devices.c 445 | @@ -303,7 +303,13 @@ vnet_hw_interface_set_rx_mode (vnet_main_t * vnm, u32 hw_if_index, 446 | rt->enabled_node_state = enabled_node_state; 447 | if (vlib_node_get_state (vm, hw->input_node_index) != 448 | VLIB_NODE_STATE_DISABLED) 449 | - vlib_node_set_state (vm, hw->input_node_index, enabled_node_state); 450 | + { 451 | + vlib_node_set_state (vm, hw->input_node_index, enabled_node_state); 452 | +#ifdef USE_BPF_TRACE 453 | + DTRACE_PROBE2 (vpp, vnet_hw_interface_set_rx_mode_probe, 454 | + hw_if_index, (u32) enabled_node_state); 455 | +#endif 456 | + } 457 | } 458 | 459 | return 0; 460 | diff --git a/src/vnet/fib/fib_table.c b/src/vnet/fib/fib_table.c 461 | index ec2acc59c..4498ded33 100644 462 | --- a/src/vnet/fib/fib_table.c 463 | +++ b/src/vnet/fib/fib_table.c 464 | @@ -632,7 +632,23 @@ fib_table_entry_path_add2 (u32 fib_index, 465 | fib_table_source_count_inc(fib_table, source); 466 | } 467 | } 468 | - 469 | +#ifdef USE_BPF_TRACE 470 | + for (ii = 0; ii < vec_len(rpaths); ii++) 471 | + { 472 | + DTRACE_PROBE6(vpp, vnet_ip_route_probe, 473 | + 0 /*is_del*/, 474 | + FIB_PROTOCOL_IP6 == prefix->fp_proto /* is_ip6 */, 475 | + fib_index, 476 | + (FIB_PROTOCOL_IP4 == prefix->fp_proto) ? 477 | + prefix->fp_addr.ip4.as_u8 : 478 | + prefix->fp_addr.ip6.as_u8, 479 | + (u32)prefix->fp_len, 480 | + (FIB_PROTOCOL_IP4 == prefix->fp_proto) ? 481 | + rpaths[ii].frp_addr.ip4.as_u8 : 482 | + rpaths[ii].frp_addr.ip6.as_u8 483 | + ); 484 | + } 485 | +#endif 486 | return (fib_entry_index); 487 | } 488 | 489 | @@ -651,7 +667,6 @@ fib_table_entry_path_remove2 (u32 fib_index, 490 | fib_node_index_t fib_entry_index; 491 | fib_route_path_t *rpath; 492 | fib_table_t *fib_table; 493 | - 494 | fib_table = fib_table_get(fib_index, prefix->fp_proto); 495 | fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix); 496 | 497 | @@ -716,6 +731,24 @@ fib_table_entry_path_remove2 (u32 fib_index, 498 | 499 | fib_entry_unlock(fib_entry_index); 500 | } 501 | +#ifdef USE_BPF_TRACE 502 | + u32 ii; 503 | + for (ii = 0; ii < vec_len(rpaths); ii++) 504 | + { 505 | + DTRACE_PROBE6(vpp, vnet_ip_route_probe, 506 | + 1 /*is_del*/, 507 | + FIB_PROTOCOL_IP6 == prefix->fp_proto /* is_ip6 */, 508 | + fib_index, 509 | + (FIB_PROTOCOL_IP4 == prefix->fp_proto) ? 510 | + prefix->fp_addr.ip4.as_u8 : 511 | + prefix->fp_addr.ip6.as_u8, 512 | + (u32)prefix->fp_len, 513 | + (FIB_PROTOCOL_IP4 == prefix->fp_proto) ? 514 | + rpaths[ii].frp_addr.ip4.as_u8 : 515 | + rpaths[ii].frp_addr.ip6.as_u8 516 | + ); 517 | + } 518 | +#endif 519 | } 520 | 521 | void 522 | diff --git a/src/vnet/interface.c b/src/vnet/interface.c 523 | index dfefdbac9..8a32110c5 100644 524 | --- a/src/vnet/interface.c 525 | +++ b/src/vnet/interface.c 526 | @@ -490,6 +490,17 @@ vnet_sw_interface_set_flags_helper (vnet_main_t * vnm, u32 sw_if_index, 527 | si->flags &= ~mask; 528 | si->flags |= flags; 529 | 530 | +#ifdef USE_BPF_TRACE 531 | + u8 *intf_name = 0; 532 | + intf_name = 533 | + format (intf_name, "%U", format_vnet_sw_interface_name, vnm, si, 534 | + si->sw_if_index); 535 | + DTRACE_PROBE3 (vpp, vnet_sw_interface_state_probe, si->sw_if_index, 536 | + (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? 1 : 0, 537 | + intf_name); 538 | + vec_free (intf_name); 539 | +#endif 540 | + 541 | done: 542 | return error; 543 | } 544 | diff --git a/src/vnet/interface_cli.c b/src/vnet/interface_cli.c 545 | index 2e5714c3c..1c9778a16 100644 546 | --- a/src/vnet/interface_cli.c 547 | +++ b/src/vnet/interface_cli.c 548 | @@ -1763,6 +1763,12 @@ set_hw_interface_rx_placement (u32 hw_if_index, u32 queue_id, 549 | 550 | vnet_hw_interface_assign_rx_thread (vnm, hw_if_index, queue_id, 551 | thread_index); 552 | + 553 | +#ifdef USE_BPF_TRACE 554 | + DTRACE_PROBE3 (vpp, vnet_set_hw_interface_rx_placement_probe, hw_if_index, 555 | + thread_index, queue_id); 556 | +#endif 557 | + 558 | vnet_hw_interface_set_rx_mode (vnm, hw_if_index, queue_id, mode); 559 | 560 | return (error); 561 | diff --git a/src/vnet/ip-neighbor/ip_neighbor.c b/src/vnet/ip-neighbor/ip_neighbor.c 562 | index 09b56058f..df3b59c18 100644 563 | --- a/src/vnet/ip-neighbor/ip_neighbor.c 564 | +++ b/src/vnet/ip-neighbor/ip_neighbor.c 565 | @@ -16,7 +16,10 @@ 566 | */ 567 | 568 | #include 569 | - 570 | +#include 571 | +#ifdef USE_BPF_TRACE 572 | +#include 573 | +#endif 574 | #include 575 | #include 576 | #include 577 | @@ -545,6 +548,13 @@ check_customers: 578 | fib_proto_to_link (fproto), 579 | &ipn->ipn_key->ipnk_ip, 580 | ipn->ipn_key->ipnk_sw_if_index); 581 | +#ifdef USE_BPF_TRACE 582 | + DTRACE_PROBE6 (vpp, vnet_ip_neighbor_probe, 583 | + 0 /* is_del */ , type != IP46_TYPE_IP4 /* is_ipv6 */ , 584 | + sw_if_index, 585 | + (type == IP46_TYPE_IP4) ? ip->ip4.as_u8 : ip->ip6.as_u8, 586 | + mac->bytes, (u32) flags); 587 | +#endif 588 | return 0; 589 | } 590 | 591 | @@ -572,7 +582,13 @@ ip_neighbor_del (const ip46_address_t * ip, ip46_type_t type, u32 sw_if_index) 592 | return (VNET_API_ERROR_NO_SUCH_ENTRY); 593 | 594 | ip_neighbor_free (ipn); 595 | - 596 | +#ifdef USE_BPF_TRACE 597 | + DTRACE_PROBE6 (vpp, vnet_ip_neighbor_probe, 598 | + 1 /* is_del */ , type != IP46_TYPE_IP4 /* is_ipv6 */ , 599 | + sw_if_index, 600 | + (type == IP46_TYPE_IP4) ? ip->ip4.as_u8 : ip->ip6.as_u8, 601 | + ipn->ipn_mac.bytes, ipn->ipn_flags); 602 | +#endif 603 | return (0); 604 | } 605 | 606 | diff --git a/src/vnet/ip/ip_interface.c b/src/vnet/ip/ip_interface.c 607 | index 48c20a6cf..d8e62d1ae 100644 608 | --- a/src/vnet/ip/ip_interface.c 609 | +++ b/src/vnet/ip/ip_interface.c 610 | @@ -86,7 +86,11 @@ ip_interface_address_add (ip_lookup_main_t * lm, 611 | (hi != ~0) ? hi : ai; 612 | 613 | *result_if_address_index = ai; 614 | - 615 | +#ifdef USE_BPF_TRACE 616 | + DTRACE_PROBE5 (vpp, vnet_ip_address_probe, 617 | + 0 /* is_del */ , lm->is_ip6, sw_if_index, (u8 *) addr_fib, 618 | + address_length); 619 | +#endif 620 | return (NULL); 621 | } 622 | 623 | @@ -133,6 +137,11 @@ ip_interface_address_del (ip_lookup_main_t * lm, 624 | mhash_unset (&lm->address_to_if_address_index, addr_fib, 625 | /* old_value */ 0); 626 | pool_put (lm->if_address_pool, a); 627 | +#ifdef USE_BPF_TRACE 628 | + DTRACE_PROBE5 (vpp, vnet_ip_address_probe, 629 | + 1 /* is_del */ , lm->is_ip6, sw_if_index, (u8 *) addr_fib, 630 | + address_length); 631 | +#endif 632 | return NULL; 633 | } 634 | 635 | diff --git a/src/vnet/ip/lookup.c b/src/vnet/ip/lookup.c 636 | index 5d4e137fb..bb8924f91 100644 637 | --- a/src/vnet/ip/lookup.c 638 | +++ b/src/vnet/ip/lookup.c 639 | @@ -284,6 +284,7 @@ vnet_ip_route_cmd (vlib_main_t * vm, 640 | if (is_del && 0 == vec_len (rpaths)) 641 | { 642 | fib_table_entry_delete (fib_index, &prefixs[i], FIB_SOURCE_CLI); 643 | + // TODO ... DTRACE_PROBE for DPO ??? 644 | } 645 | else if (!is_del && 1 == vec_len (dpos)) 646 | { 647 | @@ -293,6 +294,7 @@ vnet_ip_route_cmd (vlib_main_t * vm, 648 | FIB_ENTRY_FLAG_EXCLUSIVE, 649 | &dpos[0]); 650 | dpo_reset (&dpos[0]); 651 | + // TODO ... DTRACE_PROBE for DPO ??? 652 | } 653 | else if (vec_len (dpos) > 0) 654 | { 655 | -------------------------------------------------------------------------------- /ONAP-cdnf-integration/CDS-CNF demo.postman_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "_postman_id": "f99ad65b-3ad5-45f9-ba60-34e9016dc12a", 4 | "name": "CDS-CNF demo", 5 | "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" 6 | }, 7 | "item": [ 8 | { 9 | "name": "Bootstrap", 10 | "protocolProfileBehavior": { 11 | "disabledSystemHeaders": {} 12 | }, 13 | "request": { 14 | "auth": { 15 | "type": "basic", 16 | "basic": [ 17 | { 18 | "key": "password", 19 | "value": "ccsdkapps", 20 | "type": "string" 21 | }, 22 | { 23 | "key": "username", 24 | "value": "ccsdkapps", 25 | "type": "string" 26 | } 27 | ] 28 | }, 29 | "method": "POST", 30 | "header": [ 31 | { 32 | "key": "Content-Type", 33 | "value": "application/json" 34 | }, 35 | { 36 | "key": "", 37 | "type": "text", 38 | "value": "", 39 | "disabled": true 40 | } 41 | ], 42 | "body": { 43 | "mode": "raw", 44 | "raw": "{\r\n\"loadModelType\" : true,\r\n\"loadResourceDictionary\" : true,\r\n\"loadCBA\" : false\r\n}" 45 | }, 46 | "url": { 47 | "raw": "http://{{bp-ip}}:{{bp-port}}/api/v1/blueprint-model/bootstrap", 48 | "protocol": "http", 49 | "host": [ 50 | "{{bp-ip}}" 51 | ], 52 | "port": "{{bp-port}}", 53 | "path": [ 54 | "api", 55 | "v1", 56 | "blueprint-model", 57 | "bootstrap" 58 | ] 59 | } 60 | }, 61 | "response": [ 62 | { 63 | "name": "CDS Bootstrap", 64 | "originalRequest": { 65 | "method": "POST", 66 | "header": [ 67 | { 68 | "key": "Content-Type", 69 | "value": "application/json" 70 | }, 71 | { 72 | "key": "", 73 | "value": "", 74 | "type": "text", 75 | "disabled": true 76 | } 77 | ], 78 | "body": { 79 | "mode": "raw", 80 | "raw": "{\r\n\"loadModelType\" : false,\r\n\"loadResourceDictionary\" : true,\r\n\"loadCBA\" : false\r\n}" 81 | }, 82 | "url": { 83 | "raw": "http://localhost:8081/api/v1/blueprint-model/bootstrap", 84 | "protocol": "http", 85 | "host": [ 86 | "localhost" 87 | ], 88 | "port": "8081", 89 | "path": [ 90 | "api", 91 | "v1", 92 | "blueprint-model", 93 | "bootstrap" 94 | ] 95 | } 96 | }, 97 | "status": "OK", 98 | "code": 200, 99 | "_postman_previewlanguage": "json", 100 | "header": [ 101 | { 102 | "key": "X-ONAP-RequestID", 103 | "value": "b73253b6-d2be-4701-bdb2-31fa66b79a01" 104 | }, 105 | { 106 | "key": "X-ONAP-InvocationID", 107 | "value": "b1a59296-fcf2-4435-b8de-9a2e9b9f4077" 108 | }, 109 | { 110 | "key": "X-ONAP-PartnerName", 111 | "value": "cds-controller" 112 | }, 113 | { 114 | "key": "Vary", 115 | "value": "Origin" 116 | }, 117 | { 118 | "key": "Vary", 119 | "value": "Access-Control-Request-Method" 120 | }, 121 | { 122 | "key": "Vary", 123 | "value": "Access-Control-Request-Headers" 124 | }, 125 | { 126 | "key": "Content-Type", 127 | "value": "application/json" 128 | }, 129 | { 130 | "key": "Content-Length", 131 | "value": "0" 132 | }, 133 | { 134 | "key": "Cache-Control", 135 | "value": "no-cache, no-store, max-age=0, must-revalidate" 136 | }, 137 | { 138 | "key": "Pragma", 139 | "value": "no-cache" 140 | }, 141 | { 142 | "key": "Expires", 143 | "value": "0" 144 | }, 145 | { 146 | "key": "X-Content-Type-Options", 147 | "value": "nosniff" 148 | }, 149 | { 150 | "key": "X-Frame-Options", 151 | "value": "DENY" 152 | }, 153 | { 154 | "key": "X-XSS-Protection", 155 | "value": "1 ; mode=block" 156 | }, 157 | { 158 | "key": "Referrer-Policy", 159 | "value": "no-referrer" 160 | } 161 | ], 162 | "cookie": [], 163 | "body": "" 164 | } 165 | ] 166 | }, 167 | { 168 | "name": "Get Blueprints", 169 | "protocolProfileBehavior": { 170 | "disableBodyPruning": true 171 | }, 172 | "request": { 173 | "auth": { 174 | "type": "basic", 175 | "basic": [ 176 | { 177 | "key": "password", 178 | "value": "ccsdkapps", 179 | "type": "string" 180 | }, 181 | { 182 | "key": "username", 183 | "value": "ccsdkapps", 184 | "type": "string" 185 | } 186 | ] 187 | }, 188 | "method": "GET", 189 | "header": [ 190 | { 191 | "key": "Content-Type", 192 | "value": "application/json" 193 | }, 194 | { 195 | "key": "", 196 | "value": "", 197 | "type": "text", 198 | "disabled": true 199 | } 200 | ], 201 | "body": { 202 | "mode": "raw", 203 | "raw": "{\r\n\"loadModelType\" : true,\r\n\"loadResourceDictionary\" : true,\r\n\"loadCBA\" : false\r\n}" 204 | }, 205 | "url": { 206 | "raw": "http://{{bp-ip}}:{{bp-port}}/api/v1/blueprint-model", 207 | "protocol": "http", 208 | "host": [ 209 | "{{bp-ip}}" 210 | ], 211 | "port": "{{bp-port}}", 212 | "path": [ 213 | "api", 214 | "v1", 215 | "blueprint-model" 216 | ] 217 | } 218 | }, 219 | "response": [ 220 | { 221 | "name": "CDS Bootstrap", 222 | "originalRequest": { 223 | "method": "POST", 224 | "header": [ 225 | { 226 | "key": "Content-Type", 227 | "value": "application/json" 228 | }, 229 | { 230 | "key": "", 231 | "value": "", 232 | "type": "text", 233 | "disabled": true 234 | } 235 | ], 236 | "body": { 237 | "mode": "raw", 238 | "raw": "{\r\n\"loadModelType\" : false,\r\n\"loadResourceDictionary\" : true,\r\n\"loadCBA\" : false\r\n}" 239 | }, 240 | "url": { 241 | "raw": "http://localhost:8081/api/v1/blueprint-model/bootstrap", 242 | "protocol": "http", 243 | "host": [ 244 | "localhost" 245 | ], 246 | "port": "8081", 247 | "path": [ 248 | "api", 249 | "v1", 250 | "blueprint-model", 251 | "bootstrap" 252 | ] 253 | } 254 | }, 255 | "status": "OK", 256 | "code": 200, 257 | "_postman_previewlanguage": "json", 258 | "header": [ 259 | { 260 | "key": "X-ONAP-RequestID", 261 | "value": "b73253b6-d2be-4701-bdb2-31fa66b79a01" 262 | }, 263 | { 264 | "key": "X-ONAP-InvocationID", 265 | "value": "b1a59296-fcf2-4435-b8de-9a2e9b9f4077" 266 | }, 267 | { 268 | "key": "X-ONAP-PartnerName", 269 | "value": "cds-controller" 270 | }, 271 | { 272 | "key": "Vary", 273 | "value": "Origin" 274 | }, 275 | { 276 | "key": "Vary", 277 | "value": "Access-Control-Request-Method" 278 | }, 279 | { 280 | "key": "Vary", 281 | "value": "Access-Control-Request-Headers" 282 | }, 283 | { 284 | "key": "Content-Type", 285 | "value": "application/json" 286 | }, 287 | { 288 | "key": "Content-Length", 289 | "value": "0" 290 | }, 291 | { 292 | "key": "Cache-Control", 293 | "value": "no-cache, no-store, max-age=0, must-revalidate" 294 | }, 295 | { 296 | "key": "Pragma", 297 | "value": "no-cache" 298 | }, 299 | { 300 | "key": "Expires", 301 | "value": "0" 302 | }, 303 | { 304 | "key": "X-Content-Type-Options", 305 | "value": "nosniff" 306 | }, 307 | { 308 | "key": "X-Frame-Options", 309 | "value": "DENY" 310 | }, 311 | { 312 | "key": "X-XSS-Protection", 313 | "value": "1 ; mode=block" 314 | }, 315 | { 316 | "key": "Referrer-Policy", 317 | "value": "no-referrer" 318 | } 319 | ], 320 | "cookie": [], 321 | "body": "" 322 | } 323 | ] 324 | }, 325 | { 326 | "name": "Delete Blueprint Model", 327 | "protocolProfileBehavior": { 328 | "disabledSystemHeaders": {} 329 | }, 330 | "request": { 331 | "auth": { 332 | "type": "basic", 333 | "basic": [ 334 | { 335 | "key": "password", 336 | "value": "ccsdkapps", 337 | "type": "string" 338 | }, 339 | { 340 | "key": "username", 341 | "value": "ccsdkapps", 342 | "type": "string" 343 | } 344 | ] 345 | }, 346 | "method": "DELETE", 347 | "header": [ 348 | { 349 | "key": "Content-Type", 350 | "value": "application/json", 351 | "disabled": true 352 | }, 353 | { 354 | "key": "", 355 | "type": "text", 356 | "value": "", 357 | "disabled": true 358 | } 359 | ], 360 | "url": { 361 | "raw": "http://{{bp-ip}}:{{bp-port}}/api/v1/blueprint-model/name/Firewall-CNF-configuration-example/version/1.0.0", 362 | "protocol": "http", 363 | "host": [ 364 | "{{bp-ip}}" 365 | ], 366 | "port": "{{bp-port}}", 367 | "path": [ 368 | "api", 369 | "v1", 370 | "blueprint-model", 371 | "name", 372 | "Firewall-CNF-configuration-example", 373 | "version", 374 | "1.0.0" 375 | ] 376 | }, 377 | "description": "Delete a blueprint model identified by its name and version from CDS." 378 | }, 379 | "response": [ 380 | { 381 | "name": "CDS Bootstrap", 382 | "originalRequest": { 383 | "method": "POST", 384 | "header": [ 385 | { 386 | "key": "Content-Type", 387 | "value": "application/json" 388 | }, 389 | { 390 | "key": "", 391 | "value": "", 392 | "type": "text", 393 | "disabled": true 394 | } 395 | ], 396 | "body": { 397 | "mode": "raw", 398 | "raw": "{\r\n\"loadModelType\" : false,\r\n\"loadResourceDictionary\" : true,\r\n\"loadCBA\" : false\r\n}" 399 | }, 400 | "url": { 401 | "raw": "http://localhost:8081/api/v1/blueprint-model/bootstrap", 402 | "protocol": "http", 403 | "host": [ 404 | "localhost" 405 | ], 406 | "port": "8081", 407 | "path": [ 408 | "api", 409 | "v1", 410 | "blueprint-model", 411 | "bootstrap" 412 | ] 413 | } 414 | }, 415 | "status": "OK", 416 | "code": 200, 417 | "_postman_previewlanguage": "json", 418 | "header": [ 419 | { 420 | "key": "X-ONAP-RequestID", 421 | "value": "b73253b6-d2be-4701-bdb2-31fa66b79a01" 422 | }, 423 | { 424 | "key": "X-ONAP-InvocationID", 425 | "value": "b1a59296-fcf2-4435-b8de-9a2e9b9f4077" 426 | }, 427 | { 428 | "key": "X-ONAP-PartnerName", 429 | "value": "cds-controller" 430 | }, 431 | { 432 | "key": "Vary", 433 | "value": "Origin" 434 | }, 435 | { 436 | "key": "Vary", 437 | "value": "Access-Control-Request-Method" 438 | }, 439 | { 440 | "key": "Vary", 441 | "value": "Access-Control-Request-Headers" 442 | }, 443 | { 444 | "key": "Content-Type", 445 | "value": "application/json" 446 | }, 447 | { 448 | "key": "Content-Length", 449 | "value": "0" 450 | }, 451 | { 452 | "key": "Cache-Control", 453 | "value": "no-cache, no-store, max-age=0, must-revalidate" 454 | }, 455 | { 456 | "key": "Pragma", 457 | "value": "no-cache" 458 | }, 459 | { 460 | "key": "Expires", 461 | "value": "0" 462 | }, 463 | { 464 | "key": "X-Content-Type-Options", 465 | "value": "nosniff" 466 | }, 467 | { 468 | "key": "X-Frame-Options", 469 | "value": "DENY" 470 | }, 471 | { 472 | "key": "X-XSS-Protection", 473 | "value": "1 ; mode=block" 474 | }, 475 | { 476 | "key": "Referrer-Policy", 477 | "value": "no-referrer" 478 | } 479 | ], 480 | "cookie": [], 481 | "body": "" 482 | } 483 | ] 484 | }, 485 | { 486 | "name": "Enrich Blueprint", 487 | "protocolProfileBehavior": { 488 | "disabledSystemHeaders": {} 489 | }, 490 | "request": { 491 | "auth": { 492 | "type": "basic", 493 | "basic": [ 494 | { 495 | "key": "username", 496 | "value": "ccsdkapps", 497 | "type": "string" 498 | }, 499 | { 500 | "key": "password", 501 | "value": "ccsdkapps", 502 | "type": "string" 503 | }, 504 | { 505 | "key": "showPassword", 506 | "value": false, 507 | "type": "boolean" 508 | } 509 | ] 510 | }, 511 | "method": "POST", 512 | "header": [ 513 | { 514 | "key": "Accept", 515 | "type": "text", 516 | "value": "application/json", 517 | "disabled": true 518 | }, 519 | { 520 | "key": "Accept-Encoding", 521 | "type": "text", 522 | "value": "gzip,deflate", 523 | "disabled": true 524 | }, 525 | { 526 | "key": "Referer", 527 | "type": "text", 528 | "value": "http://84.39.39.116:30497/blueprint", 529 | "disabled": true 530 | }, 531 | { 532 | "key": "Origin", 533 | "type": "text", 534 | "value": "http://84.39.39.116:30497", 535 | "disabled": true 536 | } 537 | ], 538 | "body": { 539 | "mode": "formdata", 540 | "formdata": [ 541 | { 542 | "key": "file", 543 | "contentType": "application/zip", 544 | "type": "file", 545 | "src": "/home/dev/data/projects/onap/cds-cnf-integration/cba.zip" 546 | } 547 | ] 548 | }, 549 | "url": { 550 | "raw": "http://{{bp-ip}}:{{bp-port}}/api/v1/blueprint-model/enrich", 551 | "protocol": "http", 552 | "host": [ 553 | "{{bp-ip}}" 554 | ], 555 | "port": "{{bp-port}}", 556 | "path": [ 557 | "api", 558 | "v1", 559 | "blueprint-model", 560 | "enrich" 561 | ] 562 | } 563 | }, 564 | "response": [] 565 | }, 566 | { 567 | "name": "Save Blueprint", 568 | "request": { 569 | "auth": { 570 | "type": "basic", 571 | "basic": [ 572 | { 573 | "key": "password", 574 | "value": "ccsdkapps", 575 | "type": "string" 576 | }, 577 | { 578 | "key": "username", 579 | "value": "ccsdkapps", 580 | "type": "string" 581 | } 582 | ] 583 | }, 584 | "method": "POST", 585 | "header": [ 586 | { 587 | "key": "Content-Type", 588 | "value": "application/json" 589 | }, 590 | { 591 | "key": "", 592 | "type": "text", 593 | "value": "", 594 | "disabled": true 595 | } 596 | ], 597 | "body": { 598 | "mode": "formdata", 599 | "formdata": [ 600 | { 601 | "key": "file", 602 | "contentType": "application/zip", 603 | "type": "file", 604 | "src": "/home/dev/data/projects/onap/cds-cnf-integration/cba-enriched.zip" 605 | } 606 | ] 607 | }, 608 | "url": { 609 | "raw": "http://{{bp-ip}}:{{bp-port}}/api/v1/blueprint-model", 610 | "protocol": "http", 611 | "host": [ 612 | "{{bp-ip}}" 613 | ], 614 | "port": "{{bp-port}}", 615 | "path": [ 616 | "api", 617 | "v1", 618 | "blueprint-model" 619 | ] 620 | } 621 | }, 622 | "response": [ 623 | { 624 | "name": "CDS Bootstrap", 625 | "originalRequest": { 626 | "method": "POST", 627 | "header": [ 628 | { 629 | "key": "Content-Type", 630 | "value": "application/json" 631 | }, 632 | { 633 | "key": "", 634 | "value": "", 635 | "type": "text", 636 | "disabled": true 637 | } 638 | ], 639 | "body": { 640 | "mode": "raw", 641 | "raw": "{\r\n\"loadModelType\" : false,\r\n\"loadResourceDictionary\" : true,\r\n\"loadCBA\" : false\r\n}" 642 | }, 643 | "url": { 644 | "raw": "http://localhost:8081/api/v1/blueprint-model/bootstrap", 645 | "protocol": "http", 646 | "host": [ 647 | "localhost" 648 | ], 649 | "port": "8081", 650 | "path": [ 651 | "api", 652 | "v1", 653 | "blueprint-model", 654 | "bootstrap" 655 | ] 656 | } 657 | }, 658 | "status": "OK", 659 | "code": 200, 660 | "_postman_previewlanguage": "json", 661 | "header": [ 662 | { 663 | "key": "X-ONAP-RequestID", 664 | "value": "b73253b6-d2be-4701-bdb2-31fa66b79a01" 665 | }, 666 | { 667 | "key": "X-ONAP-InvocationID", 668 | "value": "b1a59296-fcf2-4435-b8de-9a2e9b9f4077" 669 | }, 670 | { 671 | "key": "X-ONAP-PartnerName", 672 | "value": "cds-controller" 673 | }, 674 | { 675 | "key": "Vary", 676 | "value": "Origin" 677 | }, 678 | { 679 | "key": "Vary", 680 | "value": "Access-Control-Request-Method" 681 | }, 682 | { 683 | "key": "Vary", 684 | "value": "Access-Control-Request-Headers" 685 | }, 686 | { 687 | "key": "Content-Type", 688 | "value": "application/json" 689 | }, 690 | { 691 | "key": "Content-Length", 692 | "value": "0" 693 | }, 694 | { 695 | "key": "Cache-Control", 696 | "value": "no-cache, no-store, max-age=0, must-revalidate" 697 | }, 698 | { 699 | "key": "Pragma", 700 | "value": "no-cache" 701 | }, 702 | { 703 | "key": "Expires", 704 | "value": "0" 705 | }, 706 | { 707 | "key": "X-Content-Type-Options", 708 | "value": "nosniff" 709 | }, 710 | { 711 | "key": "X-Frame-Options", 712 | "value": "DENY" 713 | }, 714 | { 715 | "key": "X-XSS-Protection", 716 | "value": "1 ; mode=block" 717 | }, 718 | { 719 | "key": "Referrer-Policy", 720 | "value": "no-referrer" 721 | } 722 | ], 723 | "cookie": [], 724 | "body": "" 725 | } 726 | ] 727 | }, 728 | { 729 | "name": "Workflow(action) apply-firewall-rule (Deny Traffic)", 730 | "request": { 731 | "auth": { 732 | "type": "basic", 733 | "basic": [ 734 | { 735 | "key": "username", 736 | "value": "ccsdkapps", 737 | "type": "string" 738 | }, 739 | { 740 | "key": "password", 741 | "value": "ccsdkapps", 742 | "type": "string" 743 | }, 744 | { 745 | "key": "showPassword", 746 | "value": false, 747 | "type": "boolean" 748 | } 749 | ] 750 | }, 751 | "method": "POST", 752 | "header": [ 753 | { 754 | "key": "Accept", 755 | "type": "text", 756 | "value": "application/json", 757 | "disabled": true 758 | }, 759 | { 760 | "key": "Accept-Encoding", 761 | "type": "text", 762 | "value": "gzip,deflate", 763 | "disabled": true 764 | }, 765 | { 766 | "key": "Referer", 767 | "type": "text", 768 | "value": "http://84.39.39.116:30497/blueprint", 769 | "disabled": true 770 | }, 771 | { 772 | "key": "Origin", 773 | "type": "text", 774 | "value": "http://84.39.39.116:30497", 775 | "disabled": true 776 | } 777 | ], 778 | "body": { 779 | "mode": "raw", 780 | "raw": "{\n\t\"actionIdentifiers\": {\n\t\t\"mode\": \"sync\",\n\t\t\"blueprintName\": \"Firewall-CNF-configuration-example\",\n\t\t\"blueprintVersion\": \"1.0.0\",\n\t\t\"actionName\": \"apply-firewall-rule\"\n\t},\n\t\"payload\": {\n\t\t\"apply-firewall-rule-request\": {\n\t\t\t\"cnf-rest-url\": \"http://vpp-agent:{{vppagent-port}}\",\n\t\t\t\"firewall_action\": \"DENY\",\n \"traffic_destination_network\": \"10.12.0.1/32\"\n\t\t}\n\t},\n\t\"commonHeader\": {\n\t\t\"subRequestId\": \"143748f9-3cd5-4910-81c9-a4601ff2ea58\",\n\t\t\"requestId\": \"e5eb1f1e-3386-435d-b290-d49d8af8db4c\",\n\t\t\"originatorId\": \"SDNC_DG\"\n\t}\n}", 781 | "options": { 782 | "raw": { 783 | "language": "json" 784 | } 785 | } 786 | }, 787 | "url": { 788 | "raw": "http://{{bp-ip}}:{{bp-port}}/api/v1/execution-service/process", 789 | "protocol": "http", 790 | "host": [ 791 | "{{bp-ip}}" 792 | ], 793 | "port": "{{bp-port}}", 794 | "path": [ 795 | "api", 796 | "v1", 797 | "execution-service", 798 | "process" 799 | ] 800 | } 801 | }, 802 | "response": [] 803 | }, 804 | { 805 | "name": "Workflow(action) apply-firewall-rule (Permit Traffic)", 806 | "request": { 807 | "auth": { 808 | "type": "basic", 809 | "basic": [ 810 | { 811 | "key": "username", 812 | "value": "ccsdkapps", 813 | "type": "string" 814 | }, 815 | { 816 | "key": "password", 817 | "value": "ccsdkapps", 818 | "type": "string" 819 | }, 820 | { 821 | "key": "showPassword", 822 | "value": false, 823 | "type": "boolean" 824 | } 825 | ] 826 | }, 827 | "method": "POST", 828 | "header": [ 829 | { 830 | "key": "Accept", 831 | "type": "text", 832 | "value": "application/json", 833 | "disabled": true 834 | }, 835 | { 836 | "key": "Accept-Encoding", 837 | "type": "text", 838 | "value": "gzip,deflate", 839 | "disabled": true 840 | }, 841 | { 842 | "key": "Referer", 843 | "type": "text", 844 | "value": "http://84.39.39.116:30497/blueprint", 845 | "disabled": true 846 | }, 847 | { 848 | "key": "Origin", 849 | "type": "text", 850 | "value": "http://84.39.39.116:30497", 851 | "disabled": true 852 | } 853 | ], 854 | "body": { 855 | "mode": "raw", 856 | "raw": "{\n\t\"actionIdentifiers\": {\n\t\t\"mode\": \"sync\",\n\t\t\"blueprintName\": \"Firewall-CNF-configuration-example\",\n\t\t\"blueprintVersion\": \"1.0.0\",\n\t\t\"actionName\": \"apply-firewall-rule\"\n\t},\n\t\"payload\": {\n\t\t\"apply-firewall-rule-request\": {\n\t\t\t\"cnf-rest-url\": \"http://vpp-agent:{{vppagent-port}}\",\n\t\t\t\"firewall_action\": \"PERMIT\",\n \"traffic_destination_network\": \"10.12.0.1/32\"\n\t\t}\n\t},\n\t\"commonHeader\": {\n\t\t\"subRequestId\": \"143748f9-3cd5-4910-81c9-a4601ff2ea58\",\n\t\t\"requestId\": \"e5eb1f1e-3386-435d-b290-d49d8af8db4c\",\n\t\t\"originatorId\": \"SDNC_DG\"\n\t}\n}", 857 | "options": { 858 | "raw": { 859 | "language": "json" 860 | } 861 | } 862 | }, 863 | "url": { 864 | "raw": "http://{{bp-ip}}:{{bp-port}}/api/v1/execution-service/process", 865 | "protocol": "http", 866 | "host": [ 867 | "{{bp-ip}}" 868 | ], 869 | "port": "{{bp-port}}", 870 | "path": [ 871 | "api", 872 | "v1", 873 | "execution-service", 874 | "process" 875 | ] 876 | } 877 | }, 878 | "response": [] 879 | }, 880 | { 881 | "name": "CNF - VPPAgent - Get configuration", 882 | "protocolProfileBehavior": { 883 | "disableBodyPruning": true 884 | }, 885 | "request": { 886 | "method": "GET", 887 | "header": [], 888 | "body": { 889 | "mode": "raw", 890 | "raw": "" 891 | }, 892 | "url": { 893 | "raw": "http://{{vppagent-ip}}:{{vppagent-port}}/configuration", 894 | "protocol": "http", 895 | "host": [ 896 | "{{vppagent-ip}}" 897 | ], 898 | "port": "{{vppagent-port}}", 899 | "path": [ 900 | "configuration" 901 | ] 902 | } 903 | }, 904 | "response": [] 905 | }, 906 | { 907 | "name": "CNF - VPPAgent - Clean config", 908 | "request": { 909 | "method": "PUT", 910 | "header": [], 911 | "body": { 912 | "mode": "raw", 913 | "raw": "netallocConfig: {}\nlinuxConfig: {}\nvppConfig: {}\n" 914 | }, 915 | "url": { 916 | "raw": "http://{{vppagent-ip}}:{{vppagent-port}}/configuration?replace=true", 917 | "protocol": "http", 918 | "host": [ 919 | "{{vppagent-ip}}" 920 | ], 921 | "port": "{{vppagent-port}}", 922 | "path": [ 923 | "configuration" 924 | ], 925 | "query": [ 926 | { 927 | "key": "replace", 928 | "value": "true" 929 | } 930 | ] 931 | } 932 | }, 933 | "response": [] 934 | } 935 | ], 936 | "event": [ 937 | { 938 | "listen": "prerequest", 939 | "script": { 940 | "type": "text/javascript", 941 | "exec": [ 942 | "" 943 | ] 944 | } 945 | }, 946 | { 947 | "listen": "test", 948 | "script": { 949 | "type": "text/javascript", 950 | "exec": [ 951 | "" 952 | ] 953 | } 954 | } 955 | ], 956 | "variable": [ 957 | { 958 | "key": "bp-ip", 959 | "value": "localhost" 960 | }, 961 | { 962 | "key": "bp-port", 963 | "value": "8000" 964 | }, 965 | { 966 | "key": "vppagent-ip", 967 | "value": "172.28.0.2" 968 | }, 969 | { 970 | "key": "vppagent-port", 971 | "value": "9191" 972 | } 973 | ] 974 | } --------------------------------------------------------------------------------