blob: 432c27697305f200f45662034fdd3e1e71756c9d [file] [log] [blame]
Matthew Giassa4a0dd382021-11-19 17:06:11 +00001#!/bin/bash
2################################################################################
3# @brief: Launcher/entrypoint script plus helper functions for "client
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-client.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 client container once it's up and
41# running.
42function context_create()
43{
44 set -x
45 echo "Running client. 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 "${CLIENT_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 "${CLIENT_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 slave
81 sleep 1
82 ${VPPCTL} set int state memif0/0 up
83 ${VPPCTL} set int ip address memif0/0 "${CLIENT_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 "${CLIENT_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 client container.
96function context_destroy()
97{
98 # OS will reclaim interfaces and resources when container is terminated.
99 :
100}
101
102#------------------------------------------------------------------------------#
103# @brief: Client 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: Main/default entry point.
124function main()
125{
126 # Make sure we always cleanup.
127 trap context_destroy EXIT
128
129 # Bring up interfaces.
130 context_create
131
132 # Enable health check responder.
133 health_check_init &
134
135 # Enter our worker loop.
136 context_loop
137}
138
139#------------------------------------------------------------------------------#
140# Script is generally intended to be sourced and individual functions called.
141# If just run as a standalone script, assume it's being used as the entrypoint
142# for a Docker container.
143if [ "${BASH_SOURCE[0]}" -ef "$0" ]; then
144 # Being run. Launch main.
145 main "${@}"
146else
147 # Being sourced. Do nothing.
148 :
149fi
150