1 Using VPP as a Home Gateway
2 ===========================
4 Vpp running on a small system (with appropriate NICs) makes a fine
5 home gateway. The resulting system performs far in excess of
6 requirements: a debug image runs at a vector size of \~1.2 terminating
7 a 150-mbit down / 10-mbit up cable modem connection.
9 At a minimum, install sshd and the isc-dhcp-server. If you prefer, you
12 System configuration files
13 --------------------------
15 /etc/vpp/startup.conf:
19 log /var/log/vpp/vpp.log
21 cli-listen /run/vpp/cli.sock
22 startup-config /setup.gate
36 ## Disable all plugins, selectively enable specific plugins
37 ## YMMV, you may wish to enable other plugins (acl, etc.)
38 plugin default { disable }
39 plugin dpdk_plugin.so { enable }
40 plugin nat_plugin.so { enable }
41 ## if you plan to use the time-based MAC filter
42 plugin mactime_plugin.so { enable }
47 subnet 192.168.1.0 netmask 255.255.255.0 {
48 range 192.168.1.10 192.168.1.99;
49 option routers 192.168.1.1;
50 option domain-name-servers 8.8.8.8;
53 If you decide to enable the vpp dns name resolver, substitute
54 192.168.1.2 for 8.8.8.8 in the dhcp server configuration.
56 /etc/default/isc-dhcp-server:
58 # On which interfaces should the DHCP server (dhcpd) serve DHCP requests?
59 # Separate multiple interfaces with spaces, e.g. "eth0 eth1".
63 /etc/ssh/sshd\_config:
65 # What ports, IPs and protocols we listen for
66 Port <REDACTED-high-number-port>
67 # Change to no to disable tunnelled clear text passwords
68 PasswordAuthentication no
70 For your own comfort and safety, do NOT allow password authentication
71 and do not answer ssh requests on port 22. Experience shows several hack
72 attempts per hour on port 22, but none (ever) on random high-number
78 In a typical home-gateway use-case, vpp owns the one-and-only WAN link
79 with a prayer of reaching the public internet. Simple things like
80 updating distro software requires use of the \"lstack\" interface
81 created above, and configuring a plausible upstream DNS name resolver.
83 Configure /etc/systemd/resolved.conf as follows.
85 /etc/systemd/resolved.conf:
100 If you want to configure a static IP address on one of your home-gateway
101 Ethernet ports on Ubuntu 18.04, you\'ll need to configure netplan.
102 Netplan is relatively new. It and the network manager GUI and can be
103 cranky. In the configuration shown below,
104 s/enp4s0/\<your-interface\>/\...
106 /etc/netplan-01-netcfg.yaml:
108 # This file describes the network interfaces available on your system
109 # For more information, see netplan(5).
116 addresses: [192.168.2.254/24]
117 gateway4: 192.168.2.100
122 /etc/systemd/network-10.enp4s0.network:
131 ConfigureWithoutCarrier=true
132 Address=192.168.2.254/24
134 Note that we\'ve picked an IP address for the home gateway which is on
135 an independent unrouteable subnet. This is handy for installing (and
136 possibly reverting) new vpp software.
138 VPP Configuration Files
139 -----------------------
141 Here we see a nice use-case for the vpp debug CLI macro expander:
146 define TRUNK GigabitEthernet3/0/0
148 comment { Specific MAC address yields a constant IP address }
149 define TRUNK_MACADDR 48:f8:b3:00:01:01
150 define BVI_MACADDR 48:f8:b3:01:01:02
152 comment { inside subnet 192.168.<inside_subnet>.0/24 }
153 define INSIDE_SUBNET 1
155 define INSIDE_PORT1 GigabitEthernet6/0/0
156 define INSIDE_PORT2 GigabitEthernet6/0/1
157 define INSIDE_PORT3 GigabitEthernet8/0/0
158 define INSIDE_PORT4 GigabitEthernet8/0/1
160 comment { feature selections }
161 define FEATURE_NAT44 comment
162 define FEATURE_CNAT uncomment
163 define FEATURE_DNS comment
164 define FEATURE_IP6 comment
165 define FEATURE_MACTIME uncomment
173 set int mac address $(TRUNK) $(TRUNK_MACADDR)
174 set dhcp client intfc $(TRUNK) hostname $(HOSTNAME)
175 set int state $(TRUNK) up
177 bvi create instance 0
178 set int mac address bvi0 $(BVI_MACADDR)
179 set int l2 bridge bvi0 1 bvi
180 set int ip address bvi0 192.168.$(INSIDE_SUBNET).1/24
181 set int state bvi0 up
183 set int l2 bridge $(INSIDE_PORT1) 1
184 set int state $(INSIDE_PORT1) up
185 set int l2 bridge $(INSIDE_PORT2) 1
186 set int state $(INSIDE_PORT2) up
187 set int l2 bridge $(INSIDE_PORT3) 1
188 set int state $(INSIDE_PORT3) up
189 set int l2 bridge $(INSIDE_PORT4) 1
190 set int state $(INSIDE_PORT4) up
192 comment { dhcp server and host-stack access }
193 create tap host-if-name lstack host-ip4-addr 192.168.$(INSIDE_SUBNET).2/24 host-ip4-gw 192.168.$(INSIDE_SUBNET).1
194 set int l2 bridge tap0 1
195 set int state tap0 up
197 service restart isc-dhcp-server
199 $(FEATURE_NAT44) { nat44 enable users 50 user-sessions 750 sessions 63000 }
200 $(FEATURE_NAT44) { nat44 add interface address $(TRUNK) }
201 $(FEATURE_NAT44) { set interface nat44 in bvi0 out $(TRUNK) }
203 $(FEATURE_NAT44) { nat44 add static mapping local 192.168.$(INSIDE_SUBNET).2 22432 external $(TRUNK) 22432 tcp }
205 $(FEATURE_CNAT) { cnat snat with $(TRUNK) }
206 $(FEATURE_CNAT) { set interface feature bvi0 ip4-cnat-snat arc ip4-unicast }
207 $(FEATURE_CNAT) { cnat translation add proto tcp real $(TRUNK) 22432 to -> 192.168.$(INSIDE_SUBNET).2 22432 }
208 $(FEATURE_CNAT) { $(FEATURE_DNS) { cnat translation add proto udp real $(TRUNK) 53053 to -> 192.168.$(INSIDE_SUBNET).1 53053 } }
210 $(FEATURE_DNS) { $(FEATURE_NAT44) { nat44 add identity mapping external $(TRUNK) udp 53053 } }
211 $(FEATURE_DNS) { bin dns_name_server_add_del 8.8.8.8 }
212 $(FEATURE_DNS) { bin dns_enable_disable }
214 comment { set ct6 inside $(TRUNK) }
215 comment { set ct6 outside $(TRUNK) }
217 $(FEATURE_IP6) { set int ip6 table $(TRUNK) 0 }
218 $(FEATURE_IP6) { ip6 nd address autoconfig $(TRUNK) default-route }
219 $(FEATURE_IP6) { dhcp6 client $(TRUNK) }
220 $(FEATURE_IP6) { dhcp6 pd client $(TRUNK) prefix group hgw }
221 $(FEATURE_IP6) { set ip6 address bvi0 prefix group hgw ::1/64 }
222 $(FEATURE_IP6) { ip6 nd address autoconfig bvi0 default-route }
223 comment { iPhones seem to need lots of RA messages... }
224 $(FEATURE_IP6) { ip6 nd bvi0 ra-managed-config-flag ra-other-config-flag ra-interval 5 3 ra-lifetime 180 }
225 comment { ip6 nd bvi0 prefix 0::0/0 ra-lifetime 100000 }
228 $(FEATURE_MACTIME) { bin mactime_add_del_range name cisco-vpn mac a8:b4:56:e1:b8:3e allow-static }
229 $(FEATURE_MACTIME) { bin mactime_add_del_range name old-mac mac <redacted> allow-static }
230 $(FEATURE_MACTIME) { bin mactime_add_del_range name roku mac <redacted> allow-static }
231 $(FEATURE_MACTIME) { bin mactime_enable_disable $(INSIDE_PORT1) }
232 $(FEATURE_MACTIME) { bin mactime_enable_disable $(INSIDE_PORT2) }
233 $(FEATURE_MACTIME) { bin mactime_enable_disable $(INSIDE_PORT3) }
234 $(FEATURE_MACTIME) { bin mactime_enable_disable $(INSIDE_PORT4) }
236 Installing new vpp software
237 ---------------------------
239 If you\'re **sure** that a given set of vpp Debian packages will install
240 and work properly, you can install them while logged into the gateway
241 via the lstack / nat path. This procedure is a bit like standing on a
242 rug and yanking it. If all goes well, a perfect back-flip occurs. If
243 not, you may wish that you\'d configured a static IP address on a
244 reserved Ethernet interface as described above.
246 Installing a new vpp image via ssh to 192.168.1.2:
248 # nohup dpkg -i *.deb >/dev/null 2>&1 &
250 Within a few seconds, the inbound ssh connection SHOULD begin to respond
251 again. If it does not, you\'ll have to debug the issue(s).
253 Reasonably Robust Remote Software Installation
254 ----------------------------------------------
256 Here are a couple of scripts which yield a reasonably robust software
259 ### Build-host script
263 buildroot=/scratch/vpp-workspace/build-root
264 if [ $1x = "testx" ] ; then
266 ipaddr="192.168.2.48"
267 elif [ $1x = "foox" ] ; then
269 ipaddr="foo.some.net"
270 elif [ $1x = "barx" ] ; then
272 ipaddr="bar.some.net"
275 ipaddr="192.168.2.48"
278 echo Save current software...
279 ssh -p 22432 $ipaddr "rm -rf /gate_debians.prev"
280 ssh -p 22432 $ipaddr "mv /gate_debians /gate_debians.prev"
281 ssh -p 22432 $ipaddr "mkdir /gate_debians"
282 echo Copy new software to the gateway...
283 scp -P 22432 $buildroot/*.deb $ipaddr:/gate_debians
284 echo Install new software...
285 ssh -p 22432 $ipaddr "nohup /usr/local/bin/vpp-swupdate > /dev/null 2>&1 &"
287 for i in 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
289 echo Wait for $i seconds...
293 echo Try to access the device...
295 ssh -p 22432 -o ConnectTimeout=10 $ipaddr "tail -20 /var/log/syslog | grep Ping"
296 if [ $? == 0 ] ; then
297 echo Access test OK...
299 echo Access failed, wait for configuration restoration...
300 for i in 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
302 echo Wait for $i seconds...
305 echo Retry access test
306 ssh -p 22432 -o ConnectTimeout=10 $ipaddr "tail -20 /var/log/syslog | grep Ping"
307 if [ $? == 0 ] ; then
308 echo Access test OK, check syslog on the device
311 echo Access test still fails, manual intervention required.
322 logger "About to update vpp software..."
325 sudo dpkg -i *.deb >/dev/null 2>&1 &
327 logger "Ping connectivity test..."
328 for i in 1 2 3 4 5 6 7 8 9 10
330 ping -4 -c 1 yahoo.com
331 if [ $? == 0 ] ; then
332 logger "Ping test OK..."
337 logger "Ping test NOT OK, restore old software..."
339 mv /gate_debians.prev /gate_debians
341 nohup sudo dpkg -i *.deb >/dev/null 2>&1 &
343 logger "Repeat connectivity test..."
344 for i in 1 2 3 4 5 6 7 8 9 10
346 ping -4 -c 1 yahoo.com
347 if [ $? == 0 ] ; then
348 logger "Ping test OK after restoring old software..."
353 logger "Ping test FAIL after restoring software, manual intervention required"
356 Note that the target script **requires** that the userid which invokes
357 it will manage to "sudo dpkg ..." without further authentication. If
358 you're uncomfortable with the security implications of that
359 requirement, you'll need to solve the problem a different
360 way. Strongly suggest configuring sshd as described above to minimize
367 If you frequently test new home gateway software, it may be handy to set
368 up a test gateway behind your production gateway. This testing
369 methodology reduces complaints from family members, to name one benefit.
371 Change the inside network (dhcp) subnet from 192.168.1.0/24 to
372 192.168.3.0/24, change the (dhcp) advertised router to 192.168.3.1,
373 reconfigure the vpp tap interface addresses onto the 192.168.3.0/24
374 subnet, and you should be all set.
376 This scenario nats traffic twice: first, from the 192.168.3.0/24 network
377 onto the 192.168.1.0/24 network. Next, from the 192.168.1.0/24 network
378 onto the public internet.
383 You\'ll want this addition to src/vpp/vnet/main.c to add the \"service
384 restart isc-dhcp-server" and \"service restart vpp\" commands:
386 #include <sys/types.h>
387 #include <sys/wait.h>
397 execl("/bin/sh", "sh", "-c", cmd);
400 clib_unix_warning ("('%s') child process returned %d", cmd, rv);
404 static clib_error_t *
405 restart_isc_dhcp_server_command_fn (vlib_main_t * vm,
406 unformat_input_t * input,
407 vlib_cli_command_t * cmd)
411 /* Wait a while... */
412 vlib_process_suspend (vm, 2.0);
414 rv = mysystem("/usr/sbin/service isc-dhcp-server restart");
416 vlib_cli_output (vm, "Restarted the isc-dhcp-server, status %d...", rv);
421 VLIB_CLI_COMMAND (restart_isc_dhcp_server_command, static) =
423 .path = "service restart isc-dhcp-server",
424 .short_help = "restarts the isc-dhcp-server",
425 .function = restart_isc_dhcp_server_command_fn,
429 static clib_error_t *
430 restart_dora_tunnels_command_fn (vlib_main_t * vm,
431 unformat_input_t * input,
432 vlib_cli_command_t * cmd)
436 /* Wait three seconds... */
437 vlib_process_suspend (vm, 3.0);
439 rv = mysystem ("/usr/sbin/service dora restart");
441 vlib_cli_output (vm, "Restarted the dora tunnel service, status %d...", rv);
446 VLIB_CLI_COMMAND (restart_dora_tunnels_command, static) =
448 .path = "service restart dora",
449 .short_help = "restarts the dora tunnel service",
450 .function = restart_dora_tunnels_command_fn,
454 static clib_error_t *
455 restart_vpp_service_command_fn (vlib_main_t * vm,
456 unformat_input_t * input,
457 vlib_cli_command_t * cmd)
459 (void) mysystem ("/usr/sbin/service vpp restart");
464 VLIB_CLI_COMMAND (restart_vpp_service_command, static) =
466 .path = "service restart vpp",
467 .short_help = "restarts the vpp service, be careful what you wish for",
468 .function = restart_vpp_service_command_fn,
472 Using the time-based mac filter plugin
473 --------------------------------------
475 If you need to restrict network access for certain devices to specific
476 daily time ranges, configure the \"mactime\" plugin. Add it to the list
477 of enabled plugins in /etc/vpp/startup.conf, then enable the feature on
478 the NAT \"inside\" interfaces:
480 bin mactime_enable_disable GigabitEthernet0/14/0
481 bin mactime_enable_disable GigabitEthernet0/14/1
484 Create the required src-mac-address rule database. There are 4 rule
487 - allow-static - pass traffic from this mac address
488 - drop-static - drop traffic from this mac address
489 - allow-range - pass traffic from this mac address at specific times
490 - drop-range - drop traffic from this mac address at specific times
492 Here are some examples:
494 bin mactime_add_del_range name alarm-system mac 00:de:ad:be:ef:00 allow-static
495 bin mactime_add_del_range name unwelcome mac 00:de:ad:be:ef:01 drop-static
496 bin mactime_add_del_range name not-during-business-hours mac <mac> drop-range Mon - Fri 7:59 - 18:01
497 bin mactime_add_del_range name monday-busines-hours mac <mac> allow-range Mon 7:59 - 18:01