blob: 755472a72bff4e7a07f96f414e4f14f645dbbb59 [file] [log] [blame]
Matthew Giassa4a0dd382021-11-19 17:06:11 +00001#!/bin/bash
2################################################################################
3# @brief: Launcher/entrypoint script plus helper functions for "server
4# side" container in the VPP testbench.
5# @author: Matthew Giassa <mgiassa@cisco.com>
6# @copyright: (C) Cisco 2021.
7################################################################################
8
9################################################################################
10# Dependencies.
11################################################################################
12# Import common settings for server and client. This is supplied via the
13# Dockerfile build.
14# shellcheck disable=SC1091
15. vpp_testbench_helpers.sh
16
17################################################################################
18# Globals.
19################################################################################
20# VPP instance socket.
21export VPP_SOCK=/run/vpp/vpp.testbench-server.sock
22# Alias for vppctl that uses the correct socket name.
23export VPPCTL="vppctl -s ${VPP_SOCK}"
24# Our "Docker bridge network". Don't change this value.
25export NET_IF_DOCKER="eth0"
26# Name of link associated with our VXLAN.
27export LINK_VXLAN_LINUX="vxlan-vid-${VXLAN_ID_LINUX}"
28
29################################################################################
30# Function definitions.
31################################################################################
32#------------------------------------------------------------------------------#
33# @brief: Alias for vppctl (knowing which API socket to use).
34function vc()
35{
36 vppctl -s "${VPP_SOCK}" "${@}"
37}
38
39#------------------------------------------------------------------------------#
40# @brief: Used to initialize/configure the server container once it's up and
41# running.
42function context_create()
43{
44 set -x
45 echo "Running server. Host: $(hostname)"
46 local mtu
47
48 # Setup VXLAN overlay.
49 ip link add "${LINK_VXLAN_LINUX}" \
50 type vxlan \
51 id "${VXLAN_ID_LINUX}" \
52 dstport "${VXLAN_PORT}" \
53 local "${SERVER_BRIDGE_IP_DOCKER}" \
54 group "${MC_VXLAN_ADDR_LINUX}" \
55 dev "${NET_IF_DOCKER}" \
56 ttl 1
57 ip link set "${LINK_VXLAN_LINUX}" up
58 ip addr add "${SERVER_VXLAN_IP_LINUX}/${MASK_VXLAN_LINUX}" dev "${LINK_VXLAN_LINUX}"
59
60 # Get MTU of interface. VXLAN must use a smaller value due to overhead.
61 mtu="$(cat /sys/class/net/${NET_IF_DOCKER}/mtu)"
62
63 # Decrease VXLAN MTU. This should already be handled for us by iproute2, but
64 # just being cautious.
65 ip link set dev "${LINK_VXLAN_LINUX}" mtu "$((mtu - 50))"
66
67 # Bring-up VPP and create tap interfaces and VXLAN tunnel.
68 vpp \
69 unix '{' log /tmp/vpp1.log full-coredump cli-listen ${VPP_SOCK} '}' \
70 api-segment '{' prefix vpp1 '}' \
71 api-trace '{' on '}' \
72 dpdk '{' uio-driver uio_pci_generic no-pci '}'
73
74 # Wait for VPP to come up.
75 while ! ${VPPCTL} show log; do
76 sleep 1
77 done
78
79 # Bring up the memif interface and assign an IP to it.
80 ${VPPCTL} create interface memif id 0 master
81 sleep 1
82 ${VPPCTL} set int state memif0/0 up
83 ${VPPCTL} set int ip address memif0/0 "${SERVER_VPP_MEMIF_IP}/${VPP_MEMIF_NM}"
84
85 # Create VPP-controlled tap interface bridged to the memif.
86 ${VPPCTL} create tap id 0 host-if-name vpp-tap-0
87 sleep 1
88 ${VPPCTL} set interface state tap0 up
89 ip addr add "${SERVER_VPP_TAP_IP_MEMIF}/${VPP_TAP_NM}" dev vpp-tap-0
90 ${VPPCTL} set interface l2 bridge tap0 "${VPP_BRIDGE_DOMAIN_TAP}"
91 ${VPPCTL} set interface l2 bridge memif0/0 "${VPP_BRIDGE_DOMAIN_TAP}"
92}
93
94#------------------------------------------------------------------------------#
95# @brief: Used to shutdown/cleanup the server container.
96function context_destroy()
97{
98 # OS will reclaim interfaces and resources when container is terminated.
99 :
100}
101
102#------------------------------------------------------------------------------#
103# @brief: Server worker loop to keep the container alive. Just idles.
104function context_loop()
105{
106 # Sleep indefinitely (to keep container alive for testing).
107 tail -f /dev/null
108}
109
110#------------------------------------------------------------------------------#
111# @brief: Launches a minimalistic web server via netcat. The Dockerfile
112# associated with this project is configured to treat the web server
113# replying with "200 OK" as a sort of simple health probe.
114function health_check_init()
115{
116 while true; do
117 echo -e "HTTP/1.1 200 OK\n\nHOST:$(hostname)\nDATE:$(date)" \
118 | nc -l -p "${DOCKER_HEALTH_PROBE_PORT}" -q 1
119 done
120}
121
122#------------------------------------------------------------------------------#
123# @brief: Launches a minimalistic web server via netcat. This instance is
124# meant to bind to the Linux VXLAN tunnel we create.
125function web_server_vxlan_linux()
126{
127 while true; do
128 echo -e "HTTP/1.1 200 OK\n\nHOST:$(hostname)\nDATE:$(date)\nHello from the Linux interface." \
129 | nc -l -s "${SERVER_VXLAN_IP_LINUX}" -p 8000 -q 1
130 done
131}
132
133#------------------------------------------------------------------------------#
134# @brief: Launches a minimalistic web server via netcat. This instance is
135# meant to bind to the VPP VXLAN tunnel we create.
136function web_server_vpp_tap()
137{
138 while true; do
139 echo -e "HTTP/1.1 200 OK\n\nHOST:$(hostname)\nDATE:$(date)\nHello from the VPP interface." \
140 | nc -l -s "${SERVER_VPP_TAP_IP_MEMIF}" -p 8000 -q 1
141 done
142}
143
144#------------------------------------------------------------------------------#
145# @brief: Main/default entry point.
146function main()
147{
148 # Make sure we always cleanup.
149 trap context_destroy EXIT
150
151 # Bring up interfaces.
152 context_create
153
154 # Enable health check responder.
155 health_check_init &
156
157 # Bring up test web servers.
158 web_server_vxlan_linux &
159 web_server_vpp_tap &
160
161 # Enter our worker loop.
162 context_loop
163}
164
165#------------------------------------------------------------------------------#
166# Script is generally intended to be sourced and individual functions called.
167# If just run as a standalone script, assume it's being used as the entrypoint
168# for a Docker container.
169if [ "${BASH_SOURCE[0]}" -ef "$0" ]; then
170 # Being run. Launch main.
171 main "${@}"
172else
173 # Being sourced. Do nothing.
174 :
175fi
176