Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
1789f1e94c | |||
55ac682d36 | |||
5f01503df6 | |||
ce29a6f436 | |||
04ee69ce02 | |||
7923e58428 | |||
2dc11ce1e3 | |||
e421cff225 | |||
fbd2facfa1 | |||
fbbfa568a8 | |||
169bc5c3e7 | |||
3c451f06ca | |||
ee17db29b6 | |||
5573c4dde7 | |||
cf1e1dd480 | |||
30b160ee55 | |||
f86e20be53 | |||
ae8cfee616 | |||
281f876834 | |||
8c1b3676ab | |||
dff392e558 | |||
876a3308d2 | |||
cb95bb6df8 |
2
.github/workflows/go.yml
vendored
2
.github/workflows/go.yml
vendored
@ -33,7 +33,7 @@ jobs:
|
||||
|
||||
- name: Ensure all files were formatted as per gofmt
|
||||
run: |
|
||||
gofmt -l $(find . -name '*.go') >/dev/null
|
||||
[ "$(gofmt -l $(find . -name '*.go') 2>&1)" = "" ]
|
||||
|
||||
- name: Go Vet
|
||||
run: |
|
||||
|
3
Makefile
3
Makefile
@ -25,6 +25,7 @@ endif
|
||||
-gokrazy_pkgs=github.com/gokrazy/gokrazy/cmd/ntp,github.com/gokrazy/gokrazy/cmd/randomd \
|
||||
-kernel_package=github.com/rtr7/kernel \
|
||||
-firmware_package=github.com/rtr7/kernel \
|
||||
-eeprom_package= \
|
||||
-overwrite_boot=${DIR}/boot.img \
|
||||
-overwrite_root=${DIR}/root.img \
|
||||
-overwrite_mbr=${DIR}/mbr.img \
|
||||
@ -40,6 +41,7 @@ recover: #test
|
||||
-gokrazy_pkgs=github.com/gokrazy/gokrazy/cmd/ntp,github.com/gokrazy/gokrazy/cmd/randomd \
|
||||
-kernel_package=github.com/rtr7/kernel \
|
||||
-firmware_package=github.com/rtr7/kernel \
|
||||
-eeprom_package= \
|
||||
-overwrite_boot=/tmp/recovery/boot.img \
|
||||
-overwrite_root=/tmp/recovery/root.img \
|
||||
-serial_console=ttyS0,115200n8 \
|
||||
@ -82,6 +84,7 @@ qemu:
|
||||
-hostname=qemu-router7 \
|
||||
-kernel_package=github.com/rtr7/kernel \
|
||||
-firmware_package=github.com/rtr7/kernel \
|
||||
-eeprom_package= \
|
||||
-overwrite=/tmp/router7-qemu/disk.img \
|
||||
-target_storage_bytes=$$((2*1024*1024*1024)) \
|
||||
-serial_console=ttyS0,115200 \
|
||||
|
161
README.md
161
README.md
@ -8,163 +8,4 @@ router7 is a pure-Go implementation of a small home internet router. It comes wi
|
||||
|
||||
Note that this project should be considered a (working!) tech demo. Feature requests will likely not be implemented, and see [CONTRIBUTING.md](CONTRIBUTING.md) for details about which contributions are welcome.
|
||||
|
||||
## Motivation
|
||||
|
||||
Before starting router7, I was using the [Turris Omnia](https://omnia.turris.cz/en/) router running OpenWrt. That worked fine up until May 2018, when an automated update pulled in a new version of [odhcp6c](https://git.openwrt.org/?p=project/odhcp6c.git;a=shortlog), OpenWrt’s DHCPv6 client. That version is incompatible with fiber7’s DHCP server setup (I think there are shortcomings on both sides).
|
||||
|
||||
It was not only quicker to develop my own router than to wait for either side to resolve the issue, but it was also a lot of fun and allowed me to really tailor my router to my needs, experimenting with a bunch of interesting ideas I had.
|
||||
|
||||
## Project goals
|
||||
|
||||
* Maximize internet connectivity: retain the most recent DHCP configuration across reboots and even after its expiration (chances are the DHCP server will be back before the configuration stops working).
|
||||
* Unit/integration tests use fiber7 packet capture files to minimize the chance of software changes breaking my connectivity.
|
||||
* Safe and quick updates
|
||||
* Auto-rollback of updates which result in loss of connectivity: the diagnostics daemon assesses connectivity state, the update tool reads it and rolls back faulty updates.
|
||||
* Thanks to kexec, updates translate into merely 13s of internet connectivity loss.
|
||||
* Easy debugging
|
||||
* Configuration-related network packets (e.g. DHCP, IPv6 neighbor/router advertisements) are stored in a ring buffer which can be streamed into [Wireshark](https://www.wireshark.org/), allowing for live and retro-active debugging.
|
||||
* The diagnostics daemon performs common diagnostic steps (ping, traceroute, …) for you.
|
||||
* All state in the system is stored as human-readable JSON within the `/perm` partition and can be modified.
|
||||
|
||||
## Hardware
|
||||
|
||||
The reference hardware platform is the [PC Engines™ apu2c4](https://pcengines.ch/apu2c4.htm) system board. It features a 1 GHz quad core amd64 CPU, 4 GB of RAM, 3 Ethernet ports and a DB9 serial port. It conveniently supports PXE boot, the schematics and bootloader sources are available. I recommend the [msata16g](https://pcengines.ch/msata16g.htm) SSD module for reliable persistent storage and the [usbcom1a](https://pcengines.ch/usbcom1a.htm) serial adapter if you don’t have one already.
|
||||
|
||||
Other hardware might work, too, but is not tested.
|
||||
|
||||
### Teensy rebootor
|
||||
|
||||
The cheap and widely-available [Teensy++ USB development board](https://www.pjrc.com/store/teensypp.html) comes with a firmware called rebootor, which is used by the [`teensy_loader_cli`](https://www.pjrc.com/teensy/loader_cli.html) program to perform hard resets.
|
||||
|
||||
This setup can be used to programmatically reset the apu2c4 (from `rtr7-recover`) by connecting the Teensy++ to the [apu2c4’s reset pins](http://pcengines.ch/pdf/apu2.pdf):
|
||||
* connect the Teensy++’s `GND` pin to the apu2c4 J2’s pin 4 (`GND`)
|
||||
* connect the Teensy++’s `B7` pin to the apu2c4 J2’s pin 5 (`3.3V`, resets when pulled to `GND`)
|
||||
|
||||
You can find a working rebootor firmware .hex file at https://github.com/PaulStoffregen/teensy_loader_cli/issues/38
|
||||
|
||||
## Architecture
|
||||
|
||||
router7 is based on [gokrazy](https://gokrazy.org/): it is an appliance which gets packed into a hard disk image, containing a FAT partition with the kernel, a read-only SquashFS partition for the root file system and an ext4 partition for permanent data.
|
||||
|
||||
The individual services can be found in [github.com/rtr7/router7/cmd](https://godoc.org/github.com/rtr7/router7/cmd).
|
||||
|
||||
* Each service runs in a separate process.
|
||||
* Services communicate with each other by persisting state files. E.g., `cmd/dhcp4` writes `/perm/dhcp4/wire/lease.json`.
|
||||
* A service notifies other services about state changes by sending them signal `SIGUSR1`.
|
||||
|
||||
### Configuration files
|
||||
|
||||
| File | Consumer(s) | Purpose |
|
||||
|---|---|---|
|
||||
| `/perm/interfaces.json` | `netconfigd` | Set IP/MAC addresses of `uplink0` and `lan0` |
|
||||
| `/perm/portforwardings.json` | `netconfigd` | Configure nftables port forwarding rules |
|
||||
| `/perm/dhcp6/duid` | `dhcp6` | Set DHCP Unique Identifier (DUID) for obtaining static leases |
|
||||
|
||||
### State files
|
||||
|
||||
| File | Producer | Consumer(s) | Purpose |
|
||||
|---|---|---|---|
|
||||
| `/perm/dhcp4/wire/ack` | `dhcp4` | `dhcp4` | last DHCPACK packet for renewals across restarts |
|
||||
| `/perm/dhcp4/wire/lease.json` | `dhcp4` | `netconfigd` | Obtained DHCPv4 lease |
|
||||
| `/perm/dhcp6/wire/lease.json` | `dhcp6` | `netconfigd`, `radvd` | Obtained DHCPv6 lease |
|
||||
| `/perm/dhcp4d/leases.json` | `dhcp4d` | `dhcp4d`, `dnsd` | DHCPv4 leases handed out (including hostnames) |
|
||||
|
||||
### Available ports
|
||||
|
||||
| Port | Purpose |
|
||||
|---|---|
|
||||
| `<public>:8053` | `dnsd` metrics (forwarded requests)
|
||||
| `<public>:8066` | `netconfigd` metrics (nftables counters)
|
||||
| `<private>:80` | gokrazy web interface
|
||||
| `<private>:67` | `dhcp4d`
|
||||
| `<private>:58` | `radvd`
|
||||
| `<private>:53` | `dnsd`
|
||||
| `<private>:8077` | `backupd` (serve backup.tar.gz)
|
||||
| `<private>:7733` | `diagd` (perform diagnostics)
|
||||
| `<private>:5022` | `captured` (serve captured packets)
|
||||
|
||||
Here’s an example of the diagd output:
|
||||
|
||||
<img src="https://github.com/rtr7/router7/raw/master/2018-07-14-diagd.png"
|
||||
width="800" alt="diagd output">
|
||||
|
||||
Here’s an example of the metrics when scraped with [Prometheus](https://prometheus.io/) and displayed in [Grafana](https://grafana.com/):
|
||||
|
||||
<img src="https://github.com/rtr7/router7/raw/master/2018-07-14-grafana.png"
|
||||
width="800" alt="metrics in grafana">
|
||||
|
||||
## Installation
|
||||
|
||||
Connect your serial adapter ([usbcom1a](https://pcengines.ch/usbcom1a.htm) works well if you don’t have one already) to the apu2c4 and start a program to use it, e.g. `screen /dev/ttyUSB0 115200`. Then, power on the apu2c4 and configure it to do PXE boot:
|
||||
|
||||
* Press `F10` to enter the boot menu
|
||||
* Press `3` to enter setup
|
||||
* Press `n` to enable network boot
|
||||
* Press `c` to move mSATA to the top of the boot order
|
||||
* Press `e` to move iPXE to the top of the boot order
|
||||
* Press `s` to save configuration and exit
|
||||
|
||||
Connect a network cable on `net0`, the port closest to the serial console port:
|
||||
|
||||
<img src="https://github.com/rtr7/router7/raw/master/devsetup.jpg"
|
||||
width="800" alt="router7 development setup">
|
||||
|
||||
Next, build a router7 image:
|
||||
|
||||
```
|
||||
go get -u github.com/gokrazy/tools/cmd/gokr-packer github.com/rtr7/tools/cmd/...
|
||||
go get -u -d github.com/rtr7/router7
|
||||
mkdir /tmp/recovery
|
||||
GOARCH=amd64 gokr-packer \
|
||||
-hostname=router7 \
|
||||
-overwrite_boot=/tmp/recovery/boot.img \
|
||||
-overwrite_mbr=/tmp/recovery/mbr.img \
|
||||
-overwrite_root=/tmp/recovery/root.img \
|
||||
-kernel_package=github.com/rtr7/kernel \
|
||||
-firmware_package=github.com/rtr7/kernel \
|
||||
-gokrazy_pkgs=github.com/gokrazy/gokrazy/cmd/ntp \
|
||||
-serial_console=ttyS0,115200n8 \
|
||||
github.com/rtr7/router7/cmd/...
|
||||
```
|
||||
|
||||
Run `rtr7-recover -boot=/tmp/recovery/boot.img -mbr=/tmp/recovery/mbr.img -root=/tmp/recovery/root.img` to:
|
||||
|
||||
* trigger a reset if a Teensy with the rebootor firmware is attached
|
||||
* serve a DHCP lease to all clients which request PXE boot (i.e., your apu2c4)
|
||||
* serve via TFTP:
|
||||
* the PXELINUX bootloader
|
||||
* the router7 kernel
|
||||
* an initrd archive containing the rtr7-recovery-init program and mke2fs
|
||||
* serve via HTTP the boot and root images
|
||||
* optionally serve via HTTP a backup.tar.gz image containing files for /perm (e.g. for moving to new hardware, rolling back corrupted state, or recovering from a disk failure)
|
||||
* exit once the router successfully wrote the images to disk
|
||||
|
||||
### Updates
|
||||
|
||||
Run e.g. `rtr7-safe-update -updates_dir=$HOME/router7/updates` to:
|
||||
|
||||
* verify the router currently has connectivity, abort the update otherwise
|
||||
* download a backup archive of `/perm`
|
||||
* build a new image
|
||||
* update the router
|
||||
* wait until the router restored connectivity, roll back the update using `rtr7-recover` otherwise
|
||||
|
||||
The update step uses kexec to reduce the downtime to approximately 15 seconds.
|
||||
|
||||
### Manual Recovery
|
||||
|
||||
Given `rtr7-safe-update`’s safeguards, manual recovery should rarely be required.
|
||||
|
||||
To manually roll back to an older image, invoke `rtr7-safe-update` via the
|
||||
`recover.bash` script in the image directory underneath `-updates_dir`, e.g.:
|
||||
|
||||
```
|
||||
% cd ~/router7/updates/2018-07-03T17:33:52+02:00
|
||||
% ./recover.bash
|
||||
```
|
||||
|
||||
### Prometheus
|
||||
|
||||
See https://github.com/rtr7/router7/tree/master/contrib/prometheus for example
|
||||
configuration files, and install the [router7 Grafana
|
||||
Dashboard](https://grafana.com/dashboards/8288).
|
||||
**For more details, please see [router7.org](https://router7.org/)**
|
||||
|
@ -68,6 +68,7 @@ func logic() error {
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if err := logic(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ import (
|
||||
|
||||
"github.com/rtr7/router7/internal/dhcp4d"
|
||||
"github.com/rtr7/router7/internal/multilisten"
|
||||
"github.com/rtr7/router7/internal/netconfig"
|
||||
"github.com/rtr7/router7/internal/notify"
|
||||
"github.com/rtr7/router7/internal/oui"
|
||||
"github.com/rtr7/router7/internal/teelogger"
|
||||
@ -58,8 +59,9 @@ var (
|
||||
Help: "Number of non-expired DHCP leases",
|
||||
})
|
||||
|
||||
iface = flag.String("interface", "lan0", "ethernet interface to listen for DHCPv4 requests on")
|
||||
perm = flag.String("perm", "/perm", "path to replace /perm")
|
||||
iface = flag.String("interface", "lan0", "ethernet interface to listen for DHCPv4 requests on")
|
||||
perm = flag.String("perm", "/perm", "path to replace /perm")
|
||||
domain = flag.String("domain", "lan", "domain name for your network")
|
||||
)
|
||||
|
||||
func updateNonExpired(leases []*dhcp4d.Lease) {
|
||||
@ -259,7 +261,27 @@ func newSrv(permDir string) (*srv, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
handler, err := dhcp4d.NewHandler(permDir, ifc, *iface, nil)
|
||||
|
||||
serverIP, err := netconfig.LinkAddress(permDir, *iface)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
serverIP = serverIP.To4()
|
||||
var domainSearch []byte
|
||||
domainSearch, err = dhcp4d.CompressNames("lan.", *domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
options := dhcp4.Options{
|
||||
dhcp4.OptionSubnetMask: []byte{255, 255, 255, 0},
|
||||
dhcp4.OptionRouter: []byte(serverIP),
|
||||
dhcp4.OptionDomainNameServer: []byte(serverIP),
|
||||
dhcp4.OptionNetworkTimeProtocolServers: []byte(serverIP),
|
||||
dhcp4.OptionDomainName: []byte(*domain),
|
||||
dhcp4.OptionDomainSearch: domainSearch,
|
||||
}
|
||||
|
||||
handler, err := dhcp4d.NewHandler(permDir, ifc, *iface, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/renameio"
|
||||
"github.com/jpillora/backoff"
|
||||
"github.com/rtr7/router7/internal/dhcp6"
|
||||
"github.com/rtr7/router7/internal/notify"
|
||||
"github.com/rtr7/router7/internal/teelogger"
|
||||
@ -57,12 +58,21 @@ func logic() error {
|
||||
}
|
||||
usr2 := make(chan os.Signal, 1)
|
||||
signal.Notify(usr2, syscall.SIGUSR2)
|
||||
backoff := backoff.Backoff{
|
||||
Factor: 2,
|
||||
Jitter: true,
|
||||
Min: 10 * time.Second,
|
||||
Max: 1 * time.Minute,
|
||||
}
|
||||
|
||||
for c.ObtainOrRenew() {
|
||||
if err := c.Err(); err != nil {
|
||||
log.Printf("Temporary error: %v", err)
|
||||
time.Sleep(10 * time.Second)
|
||||
dur := backoff.Duration()
|
||||
log.Printf("Temporary error: %v (waiting %v)", err, dur)
|
||||
time.Sleep(dur)
|
||||
continue
|
||||
}
|
||||
backoff.Reset()
|
||||
log.Printf("lease: %+v", c.Config())
|
||||
b, err := json.Marshal(c.Config())
|
||||
if err != nil {
|
||||
|
1
docs/CNAME
Normal file
1
docs/CNAME
Normal file
@ -0,0 +1 @@
|
||||
router7.org
|
221
docs/architecture/index.html
Normal file
221
docs/architecture/index.html
Normal file
@ -0,0 +1,221 @@
|
||||
<!DOCTYPE html>
|
||||
<html> <head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
|
||||
<link rel="stylesheet" href="/bootstrap-4.4.1.min.css" crossorigin="anonymous">
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="https://router7.org/sass/sidebar.css">
|
||||
|
||||
<title>router7: architecture</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-10"><nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<a class="navbar-brand" href="#">router7</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
|
||||
<div class="navbar-nav ml-auto">
|
||||
|
||||
|
||||
|
||||
<a class="nav-item nav-link " href="/">Home </a>
|
||||
|
||||
|
||||
<a class="nav-item nav-link active" href="/architecture/">Architecture <span class="sr-only">(current)</span></a>
|
||||
|
||||
|
||||
<a class="nav-item nav-link " href="/installation/">Installation </a>
|
||||
|
||||
|
||||
<a class="nav-item nav-link " href="https://github.com/rtr7/router7">GitHub </a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<h1 id="architecture">Architecture</h1>
|
||||
<p>router7 is based on <a href="https://gokrazy.org/">gokrazy</a>: it is an appliance which gets packed into a hard disk image, containing a FAT partition with the kernel, a read-only SquashFS partition for the root file system and an ext4 partition for permanent data.</p>
|
||||
<p>The individual services can be found in <a href="https://pkg.go.dev/github.com/rtr7/router7/cmd">github.com/rtr7/router7/cmd</a></p>
|
||||
<ul>
|
||||
<li>Each service runs in a separate process.</li>
|
||||
<li>Services communicate with each other by persisting state files. E.g., <code>cmd/dhcp4</code> writes <code>/perm/dhcp4/wire/lease.json</code>.</li>
|
||||
<li>A service notifies other services about state changes by sending them signal <code>SIGUSR1</code>.</li>
|
||||
</ul>
|
||||
<h2 id="configuration-files">Configuration files</h2>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>File</th>
|
||||
<th>Consumer(s)</th>
|
||||
<th>Purpose</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>/perm/interfaces.json</code></td>
|
||||
<td><code>netconfigd</code></td>
|
||||
<td>Set IP/MAC addresses of <code>uplink0</code> and <code>lan0</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>/perm/portforwardings.json</code></td>
|
||||
<td><code>netconfigd</code></td>
|
||||
<td>Configure nftables port forwarding rules</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>/perm/dhcp6/duid</code></td>
|
||||
<td><code>dhcp6</code></td>
|
||||
<td>Set DHCP Unique Identifier (DUID) for obtaining static leases</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<h2 id="state-files">State files</h2>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>File</th>
|
||||
<th>Producer</th>
|
||||
<th>Consumer(s)</th>
|
||||
<th>Purpose</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>/perm/dhcp4/wire/ack</code></td>
|
||||
<td><code>dhcp4</code></td>
|
||||
<td><code>dhcp4</code></td>
|
||||
<td>last DHCPACK packet for renewals across restarts</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>/perm/dhcp4/wire/lease.json</code></td>
|
||||
<td><code>dhcp4</code></td>
|
||||
<td><code>netconfigd</code></td>
|
||||
<td>Obtained DHCPv4 lease</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>/perm/dhcp6/wire/lease.json</code></td>
|
||||
<td><code>dhcp6</code></td>
|
||||
<td><code>netconfigd</code>, <code>radvd</code></td>
|
||||
<td>Obtained DHCPv6 lease</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>/perm/dhcp4d/leases.json</code></td>
|
||||
<td><code>dhcp4d</code></td>
|
||||
<td><code>dhcp4d</code>, <code>dnsd</code></td>
|
||||
<td>DHCPv4 leases handed out (including hostnames)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<h2 id="available-ports">Available ports</h2>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Port</th>
|
||||
<th>Purpose</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code><public>:8053</code></td>
|
||||
<td><code>dnsd</code> metrics (forwarded requests)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><public>:8066</code></td>
|
||||
<td><code>netconfigd</code> metrics (nftables counters)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><private>:80</code></td>
|
||||
<td>gokrazy web interface</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><private>:67</code></td>
|
||||
<td><code>dhcp4d</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><private>:58</code></td>
|
||||
<td><code>radvd</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><private>:53</code></td>
|
||||
<td><code>dnsd</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><private>:8077</code></td>
|
||||
<td><code>backupd</code> (serve backup.tar.gz)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><private>:7733</code></td>
|
||||
<td><code>diagd</code> (perform diagnostics)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><private>:5022</code></td>
|
||||
<td><code>captured</code> (serve captured packets)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<p>Here’s an example of <code>cmd/diagd</code> output:</p>
|
||||
<p><img src="https://github.com/rtr7/router7/raw/master/2018-07-14-diagd.png"
|
||||
width="800" alt="diagd output"></p>
|
||||
<p>Here’s an example of <code>cmd/netconfigd</code> metrics when scraped with <a href="https://prometheus.io/">Prometheus</a> and displayed in <a href="https://grafana.com/">Grafana</a>:</p>
|
||||
<p><img src="https://github.com/rtr7/router7/raw/master/2018-07-14-grafana.png"
|
||||
width="800" alt="metrics in grafana"></p>
|
||||
|
||||
|
||||
<hr>
|
||||
|
||||
<p class="small">
|
||||
© 2018 Michael Stapelberg and contributors
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<aside class="bd-toc">
|
||||
<nav id="TableOfContents">
|
||||
<ul>
|
||||
<li><a href="#configuration-files">Configuration files</a></li>
|
||||
<li><a href="#state-files">State files</a></li>
|
||||
<li><a href="#available-ports">Available ports</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
|
||||
<script src="/popper-1.16.0.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
|
||||
<script src="/bootstrap-4.4.1.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
|
||||
</body>
|
||||
</html>
|
||||
</body>
|
||||
</html>
|
7
docs/bootstrap-4.4.1.min.css
vendored
Normal file
7
docs/bootstrap-4.4.1.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
7
docs/bootstrap-4.4.1.min.js
vendored
Normal file
7
docs/bootstrap-4.4.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
94
docs/index.html
Normal file
94
docs/index.html
Normal file
@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html>
|
||||
<html> <head>
|
||||
<meta name="generator" content="Hugo 0.71.0-DEV" />
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
|
||||
<link rel="stylesheet" href="/bootstrap-4.4.1.min.css" crossorigin="anonymous">
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="https://router7.org/sass/sidebar.css">
|
||||
|
||||
<title>router7: a small home internet router completely written in Go</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-10"><nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<a class="navbar-brand" href="#">router7</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
|
||||
<div class="navbar-nav ml-auto">
|
||||
|
||||
|
||||
|
||||
<a class="nav-item nav-link active" href="/">Home <span class="sr-only">(current)</span></a>
|
||||
|
||||
|
||||
<a class="nav-item nav-link " href="/architecture/">Architecture </a>
|
||||
|
||||
|
||||
<a class="nav-item nav-link " href="/installation/">Installation </a>
|
||||
|
||||
|
||||
<a class="nav-item nav-link " href="https://github.com/rtr7/router7">GitHub </a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<h1 id="router7">router7</h1>
|
||||
<p>router7 is a pure-Go implementation of a small home internet router. It comes with all the services required to make a <a href="https://www.init7.net/en/internet/fiber7/">fiber7 internet connection</a> work (DHCPv4, DHCPv6, DNS, etc.).</p>
|
||||
<p>Note that this project should be considered a (working!) tech demo. Feature requests will likely not be implemented, and see <a href="CONTRIBUTING.md">CONTRIBUTING.md</a> for details about which contributions are welcome.</p>
|
||||
<h2 id="motivation">Motivation</h2>
|
||||
<p>Before starting router7, I was using the <a href="https://omnia.turris.cz/en/">Turris Omnia</a> router running OpenWrt. That worked fine up until May 2018, when an automated update pulled in a new version of <a href="https://git.openwrt.org/?p=project/odhcp6c.git;a=shortlog">odhcp6c</a>, OpenWrt’s DHCPv6 client. That version is incompatible with fiber7’s DHCP server setup (I think there are shortcomings on both sides).</p>
|
||||
<p>It was not only quicker to develop my own router than to wait for either side to resolve the issue, but it was also a lot of fun and allowed me to really tailor my router to my needs, experimenting with a bunch of interesting ideas I had.</p>
|
||||
<h2 id="project-goals">Project goals</h2>
|
||||
<ul>
|
||||
<li>Maximize internet connectivity: retain the most recent DHCP configuration across reboots and even after its expiration (chances are the DHCP server will be back before the configuration stops working).</li>
|
||||
<li>Unit/integration tests use fiber7 packet capture files to minimize the chance of software changes breaking my connectivity.</li>
|
||||
<li>Safe and quick updates
|
||||
<ul>
|
||||
<li>Auto-rollback of updates which result in loss of connectivity: the diagnostics daemon assesses connectivity state, the update tool reads it and rolls back faulty updates.</li>
|
||||
<li>Thanks to kexec, updates translate into merely 13s of internet connectivity loss.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Easy debugging
|
||||
<ul>
|
||||
<li>Configuration-related network packets (e.g. DHCP, IPv6 neighbor/router advertisements) are stored in a ring buffer which can be streamed into <a href="https://www.wireshark.org/">Wireshark</a>, allowing for live and retro-active debugging.</li>
|
||||
<li>The diagnostics daemon performs common diagnostic steps (ping, traceroute, …) for you.</li>
|
||||
<li>All state in the system is stored as human-readable JSON within the <code>/perm</code> partition and can be modified.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="hardware">Hardware</h2>
|
||||
<p>The reference hardware platform is the <a href="https://pcengines.ch/apu2c4.htm">PC Engines™ apu2c4</a> system board. It features a 1 GHz quad core amd64 CPU, 4 GB of RAM, 3 Ethernet ports and a DB9 serial port. It conveniently supports PXE boot, the schematics and bootloader sources are available. I recommend the <a href="https://pcengines.ch/msata16g.htm">msata16g</a> SSD module for reliable persistent storage and the <a href="https://pcengines.ch/usbcom1a.htm">usbcom1a</a> serial adapter if you don’t have one already.</p>
|
||||
<p>Other hardware might work, too, but is not tested.</p>
|
||||
|
||||
|
||||
<hr>
|
||||
|
||||
<p class="small">
|
||||
© 2018 Michael Stapelberg and contributors
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
|
||||
<script src="/popper-1.16.0.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
|
||||
<script src="/bootstrap-4.4.1.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
|
||||
</body>
|
||||
</html>
|
||||
</body>
|
||||
</html>
|
192
docs/installation/index.html
Normal file
192
docs/installation/index.html
Normal file
@ -0,0 +1,192 @@
|
||||
<!DOCTYPE html>
|
||||
<html> <head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
|
||||
<link rel="stylesheet" href="/bootstrap-4.4.1.min.css" crossorigin="anonymous">
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="https://router7.org/sass/sidebar.css">
|
||||
|
||||
<title>router7: installation</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-10"><nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<a class="navbar-brand" href="#">router7</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
|
||||
<div class="navbar-nav ml-auto">
|
||||
|
||||
|
||||
|
||||
<a class="nav-item nav-link " href="/">Home </a>
|
||||
|
||||
|
||||
<a class="nav-item nav-link " href="/architecture/">Architecture </a>
|
||||
|
||||
|
||||
<a class="nav-item nav-link active" href="/installation/">Installation <span class="sr-only">(current)</span></a>
|
||||
|
||||
|
||||
<a class="nav-item nav-link " href="https://github.com/rtr7/router7">GitHub </a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<h1 id="installation">Installation</h1>
|
||||
<p>Connect your serial adapter (<a href="https://pcengines.ch/usbcom1a.htm">usbcom1a</a> works well if you don’t have one already) to the apu2c4 and start a program to use it, e.g. <code>screen /dev/ttyUSB0 115200</code>. Then, power on the apu2c4 and configure it to do PXE boot:</p>
|
||||
<ul>
|
||||
<li>Press <code>F10</code> to enter the boot menu</li>
|
||||
<li>Press <code>3</code> to enter setup</li>
|
||||
<li>Press <code>n</code> to enable network boot</li>
|
||||
<li>Press <code>c</code> to move mSATA to the top of the boot order</li>
|
||||
<li>Press <code>e</code> to move iPXE to the top of the boot order</li>
|
||||
<li>Press <code>s</code> to save configuration and exit</li>
|
||||
</ul>
|
||||
<p>Connect a network cable on <code>net0</code>, the port closest to the serial console port:</p>
|
||||
<p><img src="https://github.com/rtr7/router7/raw/master/devsetup.jpg"
|
||||
width="800" alt="router7 development setup"></p>
|
||||
<p>Next, build a router7 image:</p>
|
||||
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">go get -u github.com/gokrazy/tools/cmd/gokr-packer github.com/rtr7/tools/cmd/...
|
||||
go get -u -d github.com/rtr7/router7
|
||||
mkdir /tmp/recovery
|
||||
GOARCH<span style="color:#f92672">=</span>amd64 gokr-packer <span style="color:#ae81ff">\
|
||||
</span><span style="color:#ae81ff"></span> -hostname<span style="color:#f92672">=</span>router7 <span style="color:#ae81ff">\
|
||||
</span><span style="color:#ae81ff"></span> -overwrite_boot<span style="color:#f92672">=</span>/tmp/recovery/boot.img <span style="color:#ae81ff">\
|
||||
</span><span style="color:#ae81ff"></span> -overwrite_mbr<span style="color:#f92672">=</span>/tmp/recovery/mbr.img <span style="color:#ae81ff">\
|
||||
</span><span style="color:#ae81ff"></span> -overwrite_root<span style="color:#f92672">=</span>/tmp/recovery/root.img <span style="color:#ae81ff">\
|
||||
</span><span style="color:#ae81ff"></span> -eeprom_package<span style="color:#f92672">=</span> <span style="color:#ae81ff">\
|
||||
</span><span style="color:#ae81ff"></span> -kernel_package<span style="color:#f92672">=</span>github.com/rtr7/kernel <span style="color:#ae81ff">\
|
||||
</span><span style="color:#ae81ff"></span> -firmware_package<span style="color:#f92672">=</span>github.com/rtr7/kernel <span style="color:#ae81ff">\
|
||||
</span><span style="color:#ae81ff"></span> -gokrazy_pkgs<span style="color:#f92672">=</span>github.com/gokrazy/gokrazy/cmd/ntp <span style="color:#ae81ff">\
|
||||
</span><span style="color:#ae81ff"></span> -serial_console<span style="color:#f92672">=</span>ttyS0,115200n8 <span style="color:#ae81ff">\
|
||||
</span><span style="color:#ae81ff"></span> github.com/rtr7/router7/cmd/...
|
||||
</code></pre></div><p>Run <code>rtr7-recover -boot=/tmp/recovery/boot.img -mbr=/tmp/recovery/mbr.img -root=/tmp/recovery/root.img</code> to:</p>
|
||||
<ul>
|
||||
<li>trigger a reset <a href="#rebootor">if a Teensy with the rebootor firmware is attached</a></li>
|
||||
<li>serve a DHCP lease to all clients which request PXE boot (i.e., your apu2c4)</li>
|
||||
<li>serve via TFTP:
|
||||
<ul>
|
||||
<li>the PXELINUX bootloader</li>
|
||||
<li>the router7 kernel</li>
|
||||
<li>an initrd archive containing the rtr7-recovery-init program and mke2fs</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>serve via HTTP the boot and root images</li>
|
||||
<li>optionally serve via HTTP a backup.tar.gz image containing files for <code>/perm</code> (e.g. for moving to new hardware, rolling back corrupted state, or recovering from a disk failure)</li>
|
||||
<li>exit once the router successfully wrote the images to disk</li>
|
||||
</ul>
|
||||
<h2 id="configuration">Configuration</h2>
|
||||
<h3 id="interfaces">Interfaces</h3>
|
||||
<p>The <code>/perm/interfaces.json</code> configuration file will be <a href="https://github.com/rtr7/tools/blob/57c2cdc3b629d2fbd13564ae37f6282f6ee8427f/cmd/rtr7-recovery-init/recoveryinit.go#L320">automatically created</a> if it is not present when you run the first recovery.</p>
|
||||
<p>Example:</p>
|
||||
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-json" data-lang="json">{
|
||||
<span style="color:#f92672">"interfaces"</span>: [
|
||||
{
|
||||
<span style="color:#f92672">"hardware_addr"</span>: <span style="color:#e6db74">"12:34:56:78:9a:b0"</span>,
|
||||
<span style="color:#f92672">"name"</span>: <span style="color:#e6db74">"lan0"</span>,
|
||||
<span style="color:#f92672">"addr"</span>: <span style="color:#e6db74">"192.168.0.1/24"</span>
|
||||
},
|
||||
{
|
||||
<span style="color:#f92672">"hardware_addr"</span>: <span style="color:#e6db74">"12:34:56:78:9a:b2"</span>,
|
||||
<span style="color:#f92672">"name"</span>: <span style="color:#e6db74">"uplink0"</span>
|
||||
}
|
||||
]
|
||||
}
|
||||
</code></pre></div><p>Schema: see <a href="https://github.com/rtr7/router7/blob/f86e20be5305fc0e7e77421e0f2abde98a84f2a7/internal/netconfig/netconfig.go#L183"><code>InterfaceConfig</code></a></p>
|
||||
<h3 id="port-forwarding">Port Forwarding</h3>
|
||||
<p>The <code>/perm/portforwardings.json</code> configuration file can be created to define port forwarding rules.</p>
|
||||
<p>Example:</p>
|
||||
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-json" data-lang="json">{
|
||||
<span style="color:#f92672">"forwardings"</span>: [
|
||||
{
|
||||
<span style="color:#f92672">"proto"</span>: <span style="color:#e6db74">"tcp"</span>,
|
||||
<span style="color:#f92672">"port"</span>: <span style="color:#e6db74">"22"</span>,
|
||||
<span style="color:#f92672">"dest_addr"</span>: <span style="color:#e6db74">"10.0.0.10"</span>,
|
||||
<span style="color:#f92672">"dest_port"</span>: <span style="color:#e6db74">"22"</span>
|
||||
},
|
||||
{
|
||||
<span style="color:#f92672">"proto"</span>: <span style="color:#e6db74">"tcp"</span>,
|
||||
<span style="color:#f92672">"port"</span>: <span style="color:#e6db74">"80"</span>,
|
||||
<span style="color:#f92672">"dest_addr"</span>: <span style="color:#e6db74">"10.0.0.10"</span>,
|
||||
<span style="color:#f92672">"dest_port"</span>: <span style="color:#e6db74">"80"</span>
|
||||
}
|
||||
]
|
||||
}
|
||||
</code></pre></div><p>Schema: see <a href="https://github.com/rtr7/router7/blob/f86e20be5305fc0e7e77421e0f2abde98a84f2a7/internal/netconfig/netconfig.go#L431"><code>portForwardings</code></a></p>
|
||||
<p>Please be aware that Hairpinning is currently not supported (see issue <a href="https://github.com/rtr7/router7/issues/53%5D">#53 Support for Hairpinning</a>)</p>
|
||||
<h2 id="updates">Updates</h2>
|
||||
<p>Run e.g. <code>rtr7-safe-update -updates_dir=$HOME/router7/updates</code> to:</p>
|
||||
<ul>
|
||||
<li>verify the router currently has connectivity, abort the update otherwise</li>
|
||||
<li>download a backup archive of <code>/perm</code></li>
|
||||
<li>build a new image</li>
|
||||
<li>update the router</li>
|
||||
<li>wait until the router restored connectivity, roll back the update using <code>rtr7-recover</code> otherwise</li>
|
||||
</ul>
|
||||
<p>The update step uses kexec to reduce the downtime to approximately 15 seconds.</p>
|
||||
<h2 id="manual-recovery">Manual Recovery</h2>
|
||||
<p>Given <code>rtr7-safe-update</code>’s safeguards, manual recovery should rarely be required.</p>
|
||||
<p>To manually roll back to an older image, invoke <code>rtr7-safe-update</code> via the
|
||||
<code>recover.bash</code> script in the image directory underneath <code>-updates_dir</code>, e.g.:</p>
|
||||
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">% cd ~/router7/updates/2018-07-03T17:33:52+02:00
|
||||
% ./recover.bash
|
||||
</code></pre></div><h2 id="rebootor">Teensy rebootor</h2>
|
||||
<p>The cheap and widely-available <a href="https://www.pjrc.com/store/teensypp.html">Teensy++ USB development board</a> comes with a firmware called rebootor, which is used by the <a href="https://www.pjrc.com/teensy/loader_cli.html"><code>teensy_loader_cli</code></a> program to perform hard resets.</p>
|
||||
<p>This setup can be used to programmatically reset the apu2c4 (from <code>rtr7-recover</code>) by connecting the Teensy++ to the <a href="http://pcengines.ch/pdf/apu2.pdf">apu2c4’s reset pins</a>:</p>
|
||||
<ul>
|
||||
<li>connect the Teensy++’s <code>GND</code> pin to the apu2c4 J2’s pin 4 (<code>GND</code>)</li>
|
||||
<li>connect the Teensy++’s <code>B7</code> pin to the apu2c4 J2’s pin 5 (<code>3.3V</code>, resets when pulled to <code>GND</code>)</li>
|
||||
</ul>
|
||||
<p>You can find a working rebootor firmware .hex file at <a href="https://github.com/PaulStoffregen/teensy_loader_cli/issues/38">https://github.com/PaulStoffregen/teensy_loader_cli/issues/38</a></p>
|
||||
<h2 id="prometheus">Prometheus</h2>
|
||||
<p>See <a href="https://github.com/rtr7/router7/tree/master/contrib/prometheus">https://github.com/rtr7/router7/tree/master/contrib/prometheus</a> for example
|
||||
configuration files, and install the <a href="https://grafana.com/dashboards/8288">router7 Grafana
|
||||
Dashboard</a>.</p>
|
||||
|
||||
|
||||
<hr>
|
||||
|
||||
<p class="small">
|
||||
© 2018 Michael Stapelberg and contributors
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<aside class="bd-toc">
|
||||
<nav id="TableOfContents">
|
||||
<ul>
|
||||
<li><a href="#configuration">Configuration</a>
|
||||
<ul>
|
||||
<li><a href="#interfaces">Interfaces</a></li>
|
||||
<li><a href="#port-forwarding">Port Forwarding</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#updates">Updates</a></li>
|
||||
<li><a href="#manual-recovery">Manual Recovery</a></li>
|
||||
<li><a href="#rebootor">Teensy rebootor</a></li>
|
||||
<li><a href="#prometheus">Prometheus</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
|
||||
<script src="/popper-1.16.0.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
|
||||
<script src="/bootstrap-4.4.1.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
|
||||
</body>
|
||||
</html>
|
||||
</body>
|
||||
</html>
|
2
docs/jquery-3.4.1.slim.min.js
vendored
Normal file
2
docs/jquery-3.4.1.slim.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
5
docs/popper-1.16.0.min.js
vendored
Normal file
5
docs/popper-1.16.0.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
docs/robots.txt
Normal file
2
docs/robots.txt
Normal file
@ -0,0 +1,2 @@
|
||||
User-Agent: *
|
||||
sitemap: https://router7.org/sitemap.xml
|
19
docs/sass/sidebar.css
Normal file
19
docs/sass/sidebar.css
Normal file
@ -0,0 +1,19 @@
|
||||
.bd-toc {
|
||||
position: sticky;
|
||||
top: 4rem;
|
||||
height: calc(100vh - 4rem);
|
||||
overflow-y: auto; }
|
||||
|
||||
.bd-toc ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
border-left: 1px solid #eee; }
|
||||
|
||||
.bd-toc li {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em; }
|
||||
|
||||
/* TODO: move this to a separate style sheet */
|
||||
.bigbutton {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em; }
|
17
docs/sitemap.xml
Normal file
17
docs/sitemap.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
||||
xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<url>
|
||||
<loc>https://router7.org/</loc>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://router7.org/architecture/</loc>
|
||||
</url>
|
||||
|
||||
<url>
|
||||
<loc>https://router7.org/installation/</loc>
|
||||
</url>
|
||||
|
||||
</urlset>
|
37
go.mod
37
go.mod
@ -2,38 +2,41 @@ module github.com/rtr7/router7
|
||||
|
||||
go 1.13
|
||||
|
||||
replace github.com/gokrazy/gokrazy => bombur.narnian.us/git/lordwelch/gokrazy v0.0.0-20200822174213-684b7f10bbcc
|
||||
|
||||
require (
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883
|
||||
github.com/digineo/go-ping v1.0.0
|
||||
github.com/gokrazy/gokrazy v0.0.0-20200501080617-f3445e01a904
|
||||
github.com/gokrazy/internal v0.0.0-20200407080221-9da902858268 // indirect
|
||||
github.com/golang/protobuf v1.4.1 // indirect
|
||||
github.com/google/go-cmp v0.4.0
|
||||
github.com/google/gopacket v1.1.17
|
||||
github.com/google/nftables v0.0.0-20200316075819-7127d9d22474
|
||||
github.com/gokrazy/gokrazy v0.0.0-20200801074800-f7c3cb7e0e6a
|
||||
github.com/gokrazy/internal v0.0.0-20200713084155-ab6fc6e02a03 // indirect
|
||||
github.com/google/go-cmp v0.5.0
|
||||
github.com/google/gopacket v1.1.18
|
||||
github.com/google/nftables v0.0.0-20200802175506-c25e4f69b425
|
||||
github.com/google/renameio v0.1.0
|
||||
github.com/insomniacslk/dhcp v0.0.0-20200420235442-ed3125c2efe7
|
||||
github.com/insomniacslk/dhcp v0.0.0-20200806210722-3f14f7f8bd9c
|
||||
github.com/jpillora/backoff v1.0.0
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/krolaw/dhcp4 v0.0.0-20190909130307-a50d88189771
|
||||
github.com/libdns/cloudflare v0.0.0-20200528144945-97886e7873b1
|
||||
github.com/libdns/libdns v0.0.0-20200501023120-186724ffc821
|
||||
github.com/mdlayher/ndp v0.0.0-20200509194142-8a50b5ef8b52
|
||||
github.com/mdlayher/ndp v0.0.0-20200602162440-17ab9e3e5567
|
||||
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065
|
||||
github.com/miekg/dns v1.1.29
|
||||
github.com/miekg/dns v1.1.31
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/prometheus/client_golang v1.6.0
|
||||
github.com/prometheus/client_golang v1.7.1
|
||||
github.com/prometheus/common v0.11.1 // indirect
|
||||
github.com/rtr7/dhcp4 v0.0.0-20181120124042-778e8c2e24a5
|
||||
github.com/sergi/go-diff v1.1.0 // indirect
|
||||
github.com/u-root/u-root v6.0.0+incompatible // indirect
|
||||
github.com/vishvananda/netlink v1.1.0
|
||||
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a
|
||||
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1
|
||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae // indirect
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208
|
||||
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e
|
||||
golang.zx2c4.com/wireguard v0.0.20200320 // indirect
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200324154536-ceff61240acf
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200609130330-bd2cb7843e1b
|
||||
google.golang.org/protobuf v1.25.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
gopkg.in/yaml.v2 v2.2.8 // indirect
|
||||
)
|
||||
|
393
go.sum
393
go.sum
@ -1,86 +1,180 @@
|
||||
bombur.narnian.us/git/lordwelch/gokrazy v0.0.0-20200822174213-684b7f10bbcc h1:8dSoG9r/UydbDre0bV/oWef5zkPZVTf2CuEITPgWXqU=
|
||||
bombur.narnian.us/git/lordwelch/gokrazy v0.0.0-20200822174213-684b7f10bbcc/go.mod h1:gg6WuqKqQT5Ty8vivqW/UUwyinbpjNpiaQJyAHDUquY=
|
||||
cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/beevik/ntp v0.2.0 h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/digineo/go-logwrap v0.0.0-20181106161722-a178c58ea3f0 h1:OT/LKmj81wMymnWXaKaKBR9n1vPlu+GC0VVKaZP6kzs=
|
||||
github.com/digineo/go-logwrap v0.0.0-20181106161722-a178c58ea3f0/go.mod h1:DmqdumeAKGQNU5E8MN0ruT5ZGx8l/WbAsMbXCXcSEts=
|
||||
github.com/digineo/go-ping v1.0.0 h1:gOuD3YzkIcW/0Y2IAe27bsMKtpfNZdoX1Rnc1RGYOSI=
|
||||
github.com/digineo/go-ping v1.0.0/go.mod h1:YLDBnHoAygacawa2aubI4vXhZ4do5f62oJSvRiJVEjw=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
|
||||
github.com/gdamore/tcell v1.1.1/go.mod h1:K1udHkiR3cOtlpKG5tZPD5XxrF7v2y7lDq7Whcj+xkQ=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gokrazy/gokrazy v0.0.0-20200501080617-f3445e01a904 h1:eqfH4A/LLgxv5RvqEXwVoFvfmpRa8+TokRjB5g6xBkk=
|
||||
github.com/gokrazy/gokrazy v0.0.0-20200501080617-f3445e01a904/go.mod h1:pq6rGHqxMRPSaTXaCMzIZy0wLDusAJyoVNyNo05RLs0=
|
||||
github.com/gokrazy/internal v0.0.0-20200407075822-660ad467b7c9/go.mod h1:LA5TQy7LcvYGQOy75tkrYkFUhbV2nl5qEBP47PSi2JA=
|
||||
github.com/gokrazy/internal v0.0.0-20200407080221-9da902858268 h1:Q0Z5vi1HjXMlwiIaC6nn04y0PwRjyG9h9S4hZVzFjTw=
|
||||
github.com/gokrazy/internal v0.0.0-20200407080221-9da902858268/go.mod h1:LA5TQy7LcvYGQOy75tkrYkFUhbV2nl5qEBP47PSi2JA=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gokrazy/internal v0.0.0-20200531194636-d96421c60091/go.mod h1:LA5TQy7LcvYGQOy75tkrYkFUhbV2nl5qEBP47PSi2JA=
|
||||
github.com/gokrazy/internal v0.0.0-20200713084155-ab6fc6e02a03 h1:H2GO8vfBaFo6msfPXPoY6KSqO1HmfDe0eiAc0LYKXOI=
|
||||
github.com/gokrazy/internal v0.0.0-20200713084155-ab6fc6e02a03/go.mod h1:LA5TQy7LcvYGQOy75tkrYkFUhbV2nl5qEBP47PSi2JA=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gopacket v1.1.16/go.mod h1:UCLx9mCmAwsVbn6qQl1WIEt2SO7Nd2fD0th1TBAsqBw=
|
||||
github.com/google/gopacket v1.1.17 h1:rMrlX2ZY2UbvT+sdz3+6J+pp2z+msCq9MxTU6ymxbBY=
|
||||
github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
|
||||
github.com/google/nftables v0.0.0-20200316075819-7127d9d22474 h1:D6bN82zzK92ywYsE+Zjca7EHZCRZbcNTU3At7WdxQ+c=
|
||||
github.com/google/nftables v0.0.0-20200316075819-7127d9d22474/go.mod h1:cfspEyr/Ap+JDIITA+N9a0ernqG0qZ4W1aqMRgDZa1g=
|
||||
github.com/google/gopacket v1.1.18 h1:lum7VRA9kdlvBi7/v2p7/zcbkduHaCH/SVVyurs7OpY=
|
||||
github.com/google/gopacket v1.1.18/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
|
||||
github.com/google/nftables v0.0.0-20200802175506-c25e4f69b425 h1:Ob7HrdEgedxSwCofNfvAYCNiuXbcuELBXP+Y2loxpXM=
|
||||
github.com/google/nftables v0.0.0-20200802175506-c25e4f69b425/go.mod h1:cfspEyr/Ap+JDIITA+N9a0ernqG0qZ4W1aqMRgDZa1g=
|
||||
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20200420235442-ed3125c2efe7 h1:iaCm+9nZdYb8XCSU2TfIb0qYTcAlIv2XzyKR2d2xZ38=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20200420235442-ed3125c2efe7/go.mod h1:CfMdguCK66I5DAUJgGKyNz8aB6vO5dZzkm9Xep6WGvw=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20200806210722-3f14f7f8bd9c h1:sGjF7j2eY9V0tCvP2s2tZVoM/9f/I9RYdEtv3qLrtMk=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20200806210722-3f14f7f8bd9c/go.mod h1:CfMdguCK66I5DAUJgGKyNz8aB6vO5dZzkm9Xep6WGvw=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4 h1:nwOc1YaOrYJ37sEBrtWZrdqzK22hiJs3GpDmP3sR2Yw=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/koneu/natend v0.0.0-20150829182554-ec0926ea948d h1:MFX8DxRnKMY/2M3H61iSsVbo/n3h0MWGmWNN1UViOU0=
|
||||
github.com/koneu/natend v0.0.0-20150829182554-ec0926ea948d/go.mod h1:QHb4k4cr1fQikUahfcRVPcEXiUgFsdIstGqlurL0XL4=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
@ -91,16 +185,21 @@ github.com/libdns/cloudflare v0.0.0-20200528144945-97886e7873b1/go.mod h1:A9MqNm
|
||||
github.com/libdns/libdns v0.0.0-20200430163404-ee2c42449104/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
|
||||
github.com/libdns/libdns v0.0.0-20200501023120-186724ffc821 h1:663opx/RKxiISi1ozf0WbvweQpYBgf34dx8hKSIau3w=
|
||||
github.com/libdns/libdns v0.0.0-20200501023120-186724ffc821/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||
github.com/lucasb-eyer/go-colorful v0.0.0-20181028223441-12d3b2882a08/go.mod h1:NXg0ArsFk0Y01623LgUqoqcouGDB+PwCCQlrwrG6xJ4=
|
||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mdlayher/genetlink v1.0.0 h1:OoHN1OdyEIkScEmRgxLEe2M9U8ClMytqA5niynLtfj0=
|
||||
github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc=
|
||||
github.com/mdlayher/ndp v0.0.0-20200509194142-8a50b5ef8b52 h1:qWqNvHaKhGECNieU1gGusKRuoPeoR+rhlkaWdO1gyT8=
|
||||
github.com/mdlayher/ndp v0.0.0-20200509194142-8a50b5ef8b52/go.mod h1:AXE3T2f7eg/MV02LS+DGHgH0c+ehknWViE4pgbHtZf8=
|
||||
github.com/mdlayher/ndp v0.0.0-20200602162440-17ab9e3e5567 h1:x+xs91ZJ+lr0C6sedWeREvck4uGCt+AA1kKXwsHB6jI=
|
||||
github.com/mdlayher/ndp v0.0.0-20200602162440-17ab9e3e5567/go.mod h1:32w/5dDZWVSEOxyniAgKK4d7dHTuO6TCxWmUznQe3f8=
|
||||
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
|
||||
github.com/mdlayher/netlink v0.0.0-20191009155606-de872b0d824b/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
|
||||
github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
|
||||
@ -109,96 +208,214 @@ github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcK
|
||||
github.com/mdlayher/raw v0.0.0-20190303161257-764d452d77af/go.mod h1:rC/yE65s/DoHB6BzVOUBNYBGTg772JVytyAytffIZkY=
|
||||
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065 h1:aFkJ6lx4FPip+S+Uw4aTegFMct9shDvP+79PsSxpm3w=
|
||||
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
|
||||
github.com/miekg/dns v1.1.29 h1:xHBEhR+t5RzcFJjBLJlax2daXOrTYtr9z4WdKEfWFzg=
|
||||
github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo=
|
||||
github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws=
|
||||
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
|
||||
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
|
||||
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
|
||||
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.6.0 h1:YVPodQOcK15POxhgARIvnDRVpLcuK8mglnMrWfyrw6A=
|
||||
github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4=
|
||||
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
||||
github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||
github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.11.1 h1:0ZISXCMRuCZcxF77aT1BXY5m74mX2vrGYl1dSwBI0Jo=
|
||||
github.com/prometheus/common v0.11.1/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI=
|
||||
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rivo/tview v0.0.0-20181226202439-36893a669792/go.mod h1:J4W+hErFfITUbyFAEXizpmkuxX7ZN56dopxHB4XQhMw=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rtr7/dhcp4 v0.0.0-20181120124042-778e8c2e24a5 h1:/kzTBQ20DbbhSNaBXiFEk2gPrGhY26kajwC1ro/Vlh8=
|
||||
github.com/rtr7/dhcp4 v0.0.0-20181120124042-778e8c2e24a5/go.mod h1:FwstIpm6vX98QgtR8KEwZcVjiRn2WP76LjXAHj84fK0=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/u-root/u-root v6.0.0+incompatible h1:YqPGmRoRyYmeg17KIWFRSyVq6LX5T6GSzawyA6wG6EE=
|
||||
github.com/u-root/u-root v6.0.0+incompatible/go.mod h1:RYkpo8pTHrNjW08opNd/U6p/RJE7K0D8fXO0d47+3YY=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae h1:4hwBBUfQCFe3Cym0ZtKyq7L16eZUtYKs+BaHDN6mAns=
|
||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
gitlab.com/golang-commonmark/puny v0.0.0-20191124015043-9f83538fa04f h1:Wku8eEdeJqIOFHtrfkYUByc4bCaTeA6fL0UJgfEiFMI=
|
||||
gitlab.com/golang-commonmark/puny v0.0.0-20191124015043-9f83538fa04f/go.mod h1:Tiuhl+njh/JIg0uS/sOJVYi0x2HEa5rc1OAaVsb5tAs=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 h1:IaQbIIB2X/Mp/DKctl6ROxz1KyMlKp4uyvL6+kQ7C88=
|
||||
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig=
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190419010253-1f3472d942ba/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f h1:QBjCr1Fz5kw158VqdE9JfI9cJnl/ymnJWAdMuinqL7Y=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -207,59 +424,113 @@ golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191029155521-f43be2a4598c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200406155108-e3b113bbe6a4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=
|
||||
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f h1:mOhmO9WsBaJCNmaZHPtHs9wOcdqdKCjF6OPJlmDM3KI=
|
||||
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/sys v0.0.0-20200602100848-8d3cce7afc34/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed h1:WBkVNH1zd9jg/dK4HCM4lNANnmd12EHC9z+LmcCG4ns=
|
||||
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI=
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s=
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.zx2c4.com/wireguard v0.0.20200121 h1:vcswa5Q6f+sylDfjqyrVNNrjsFUUbPsgAQTBCAg/Qf8=
|
||||
golang.zx2c4.com/wireguard v0.0.20200121/go.mod h1:P2HsVp8SKwZEufsnezXZA4GRX/T49/HlU7DGuelXsU4=
|
||||
golang.zx2c4.com/wireguard v0.0.20200320 h1:1vE6zVeO7fix9cJX1Z9ZQ+ikPIIx7vIyU0o0tLDD88g=
|
||||
golang.zx2c4.com/wireguard v0.0.20200320/go.mod h1:lDian4Sw4poJ04SgHh35nzMVwGSYlPumkdnHcucAQoY=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200324154536-ceff61240acf h1:rWUZHukj3poXegPQMZOXgxjTGIBe3mLNHNVvL5DsHus=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200324154536-ceff61240acf/go.mod h1:UdS9frhv65KTfwxME1xE8+rHYoFpbm36gOud1GhBe9c=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200609130330-bd2cb7843e1b h1:l4mBVCYinjzZuR5DtxHuBD6wyd4348TGiavJ5vLrhEc=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200609130330-bd2cb7843e1b/go.mod h1:UdS9frhv65KTfwxME1xE8+rHYoFpbm36gOud1GhBe9c=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0 h1:cJv5/xdbk1NnMPR1VP9+HU6gupuG9MLBoH1r6RHZ2MY=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
rsc.io/goversion v1.2.0 h1:SPn+NLTiAG7w30IRK/DKp1BjvpWabYgxlLp/+kx5J8w=
|
||||
rsc.io/goversion v1.2.0/go.mod h1:Eih9y/uIBS3ulggl7KNJ09xGSLcuNaLgmvvqa07sgfo=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
||||
|
@ -36,7 +36,7 @@ func main() {
|
||||
exec.Command(path.Join(cmdRoot, "backupd"), "-perm="+perm),
|
||||
exec.Command(path.Join(cmdRoot, "captured"), "-perm="+perm),
|
||||
exec.Command(path.Join(cmdRoot, "dhcp4"), "-perm="+perm),
|
||||
exec.Command(path.Join(cmdRoot, "dhcp4d"), "-perm="+perm),
|
||||
exec.Command(path.Join(cmdRoot, "dhcp4d"), fmt.Sprintf("-domain=%s", domain), "-perm="+perm),
|
||||
exec.Command(path.Join(cmdRoot, "dhcp6"), "-perm="+perm),
|
||||
exec.Command(path.Join(cmdRoot, "diagd"), "-perm="+perm),
|
||||
exec.Command(path.Join(cmdRoot, "dnsd"), fmt.Sprintf("-domain=%s", domain), "-perm="+perm),
|
||||
|
@ -213,6 +213,11 @@ func (w *wgLink) Attrs() *netlink.LinkAttrs {
|
||||
}
|
||||
|
||||
var wireGuardAvailable = func() bool {
|
||||
// The wg tool must also be available for our test to succeed:
|
||||
if _, err := exec.LookPath("wg"); err == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// ns must not collide with any namespace used in the test functions: this
|
||||
// function will be called by the helper process, too.
|
||||
const ns = "ns4"
|
||||
@ -265,7 +270,7 @@ func TestNetconfig(t *testing.T) {
|
||||
}
|
||||
|
||||
netconfig.DefaultCounterObj = &nftables.CounterObj{Packets: 23, Bytes: 42}
|
||||
if err := netconfig.Apply(tmp, filepath.Join(tmp, "root")); err != nil {
|
||||
if err := netconfig.Apply(tmp, filepath.Join(tmp, "root"), true); err != nil {
|
||||
t.Fatalf("netconfig.Apply: %v", err)
|
||||
}
|
||||
|
||||
@ -273,7 +278,7 @@ func TestNetconfig(t *testing.T) {
|
||||
// already-configured interfaces, addresses, routes, … (and ensure
|
||||
// nftables rules are replaced, not appendend to).
|
||||
netconfig.DefaultCounterObj = &nftables.CounterObj{Packets: 0, Bytes: 0}
|
||||
if err := netconfig.Apply(tmp, filepath.Join(tmp, "root")); err != nil {
|
||||
if err := netconfig.Apply(tmp, filepath.Join(tmp, "root"), true); err != nil {
|
||||
t.Fatalf("netconfig.Apply: %v", err)
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ package dhcp4d
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
@ -36,8 +37,8 @@ import (
|
||||
)
|
||||
|
||||
type Lease struct {
|
||||
Num int `json:"num"` // relative to Handler.start
|
||||
Addr net.IP `json:"addr"`
|
||||
Num int `json:"num"` // relative to Handler.start
|
||||
Addr net.IP `json:"addr"` // subnet.start+Num
|
||||
HardwareAddr string `json:"hardware_addr"`
|
||||
Hostname string `json:"hostname"`
|
||||
HostnameOverride string `json:"hostname_override"`
|
||||
@ -67,7 +68,7 @@ type Handler struct {
|
||||
leasesIP map[int]*Lease
|
||||
}
|
||||
|
||||
func NewHandler(dir string, iface *net.Interface, ifaceName string, conn net.PacketConn) (*Handler, error) {
|
||||
func NewHandler(dir string, iface *net.Interface, ifaceName string, conn net.PacketConn, options dhcp4.Options) (*Handler, error) {
|
||||
serverIP, err := netconfig.LinkAddress(dir, ifaceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -84,10 +85,24 @@ func NewHandler(dir string, iface *net.Interface, ifaceName string, conn net.Pac
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if options == nil {
|
||||
var domainSearch []byte
|
||||
domainSearch, err = CompressNames("lan.")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
options = dhcp4.Options{
|
||||
dhcp4.OptionSubnetMask: []byte{255, 255, 255, 0},
|
||||
dhcp4.OptionRouter: []byte(serverIP),
|
||||
dhcp4.OptionDomainNameServer: []byte(serverIP),
|
||||
dhcp4.OptionDomainName: []byte("lan"),
|
||||
dhcp4.OptionDomainSearch: domainSearch,
|
||||
}
|
||||
}
|
||||
serverIP = serverIP.To4()
|
||||
start := make(net.IP, len(serverIP))
|
||||
copy(start, serverIP)
|
||||
start[len(start)-1] += 1
|
||||
start[len(start)-1]++
|
||||
return &Handler{
|
||||
rawConn: conn,
|
||||
iface: iface,
|
||||
@ -97,14 +112,8 @@ func NewHandler(dir string, iface *net.Interface, ifaceName string, conn net.Pac
|
||||
start: start,
|
||||
leaseRange: 230,
|
||||
LeasePeriod: 20 * time.Minute,
|
||||
options: dhcp4.Options{
|
||||
dhcp4.OptionSubnetMask: []byte{255, 255, 255, 0},
|
||||
dhcp4.OptionRouter: []byte(serverIP),
|
||||
dhcp4.OptionDomainNameServer: []byte(serverIP),
|
||||
dhcp4.OptionDomainName: []byte("lan"),
|
||||
dhcp4.OptionDomainSearch: []byte{0x03, 'l', 'a', 'n', 0x00},
|
||||
},
|
||||
timeNow: time.Now,
|
||||
options: options,
|
||||
timeNow: time.Now,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -389,3 +398,78 @@ func (h *Handler) expireLease(hwAddr string) bool {
|
||||
l.Expiry = time.Now()
|
||||
return true
|
||||
}
|
||||
|
||||
func CompressNames(names ...string) ([]byte, error) {
|
||||
b := make([]byte, 0, 255)
|
||||
m := make(map[string]int)
|
||||
var err error
|
||||
for _, name := range names {
|
||||
if name[len(name)-1] != '.' {
|
||||
name += "."
|
||||
}
|
||||
b, err = pack([]byte(name), b, m)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func pack(name []byte, msg []byte, compression map[string]int) ([]byte, error) {
|
||||
oldMsg := msg
|
||||
|
||||
// Add a trailing dot to canonicalize name.
|
||||
if len(name) == 0 || name[len(name)-1] != '.' {
|
||||
return oldMsg, fmt.Errorf("%s", "errNonCanonicalName")
|
||||
}
|
||||
|
||||
// Allow root domain.
|
||||
if name[0] == '.' && len(name) == 1 {
|
||||
return append(msg, 0), nil
|
||||
}
|
||||
|
||||
// Emit sequence of counted strings, chopping at dots.
|
||||
for i, begin := 0, 0; i < len(name); i++ {
|
||||
// Check for the end of the segment.
|
||||
if name[i] == '.' {
|
||||
// The two most significant bits have special meaning.
|
||||
// It isn't allowed for segments to be long enough to
|
||||
// need them.
|
||||
if i-begin >= 1<<6 {
|
||||
return oldMsg, fmt.Errorf("%s", "errSegTooLong")
|
||||
}
|
||||
|
||||
// Segments must have a non-zero length.
|
||||
if i-begin == 0 {
|
||||
return oldMsg, fmt.Errorf("%s", "errZeroSegLen")
|
||||
}
|
||||
|
||||
msg = append(msg, byte(i-begin))
|
||||
|
||||
for j := begin; j < i; j++ {
|
||||
msg = append(msg, name[j])
|
||||
}
|
||||
|
||||
begin = i + 1
|
||||
continue
|
||||
}
|
||||
|
||||
// We can only compress domain suffixes starting with a new
|
||||
// segment. A pointer is two bytes with the two most significant
|
||||
// bits set to 1 to indicate that it is a pointer.
|
||||
if (i == 0 || name[i-1] == '.') && compression != nil {
|
||||
if ptr, ok := compression[string(name[i:])]; ok {
|
||||
// Hit. Emit a pointer instead of the rest of
|
||||
// the domain.
|
||||
return append(msg, byte(ptr>>8|0xC0), byte(ptr)), nil
|
||||
}
|
||||
|
||||
// Miss. Add the suffix to the compression table if the
|
||||
// offset can be stored in the available 14 bytes.
|
||||
if len(msg) <= int(^uint16(0)>>2) {
|
||||
compression[string(name[i:])] = len(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
return append(msg, 0), nil
|
||||
}
|
||||
|
@ -95,6 +95,7 @@ func testHandler(t *testing.T) (_ *Handler, cleanup func()) {
|
||||
},
|
||||
"lan0",
|
||||
&noopSink{},
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -266,6 +266,14 @@ func (c *Client) ObtainOrRenew() bool {
|
||||
}
|
||||
|
||||
c.advertise = advertise
|
||||
|
||||
if iapd := advertise.Options.OneIAPD(); iapd != nil {
|
||||
if status := iapd.Options.Status(); status != nil && status.StatusCode != iana.StatusSuccess {
|
||||
c.err = fmt.Errorf("IAPD error: %v (%v)", status.StatusCode, status.StatusMessage)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
_, reply, err := c.request(advertise)
|
||||
if err != nil {
|
||||
c.err = err
|
||||
|
@ -143,6 +143,11 @@ func NewServer(addr, domain string) *Server {
|
||||
}
|
||||
|
||||
func (s *Server) initHostsLocked() {
|
||||
for k := range s.subnames {
|
||||
if k != s.domain {
|
||||
s.Mux.HandleRemove(string(k))
|
||||
}
|
||||
}
|
||||
s.hostsByName = make(map[lcHostname]string)
|
||||
s.hostsByIP = make(map[string]string)
|
||||
s.subnames[s.domain] = make(map[lcHostname]IP)
|
||||
@ -341,6 +346,15 @@ func (s *Server) SetDNSEntries(dnsEntries []IP) {
|
||||
entry.Host = lcHostname(strings.TrimSuffix(dn, "lan")) + s.domain
|
||||
}
|
||||
s.setSubname(entry)
|
||||
hdnSlice := strings.SplitN(string(entry.Host), ".", 2)
|
||||
domain := lcHostname("")
|
||||
if len(hdnSlice) == 2 {
|
||||
domain = lcHostname(hdnSlice[1])
|
||||
}
|
||||
if domain == "" || domain == s.domain {
|
||||
continue
|
||||
}
|
||||
s.Mux.HandleFunc(string(domain), s.subnameHandler(domain))
|
||||
}
|
||||
}
|
||||
|
||||
@ -548,6 +562,7 @@ func (s *Server) resolveSubname(domain string, q dns.Question) (dns.RR, error) {
|
||||
}
|
||||
if q.Qtype == dns.TypeA || q.Qtype == dns.TypeAAAA /*|| q.Qtype == dns.TypeMX*/ {
|
||||
name := strings.TrimSuffix(q.Name, ".")
|
||||
name = strings.TrimSuffix(name, ".lan") // trim lan domain
|
||||
name = strings.TrimSuffix(name, "."+string(s.domain)) // trim server domain
|
||||
name = strings.TrimSuffix(name, "."+strings.TrimSuffix(domain, "."+string(s.domain))) // trim function domain
|
||||
if ip, ok := s.subname(domain, name); ok {
|
||||
|
@ -158,6 +158,28 @@ func TestResolveLatencySteering(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDHCPDomain(t *testing.T) {
|
||||
s := NewServer("localhost:0", "example.org")
|
||||
s.SetLeases([]dhcp4d.Lease{
|
||||
{
|
||||
Hostname: "testtarget",
|
||||
Addr: net.IP{192, 168, 42, 23},
|
||||
},
|
||||
})
|
||||
|
||||
t.Run("testtarget.lan.", func(t *testing.T) {
|
||||
if err := resolveTestTarget(s, "testtarget.lan.", net.ParseIP("192.168.42.23")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("testtarget.example.org.", func(t *testing.T) {
|
||||
if err := resolveTestTarget(s, "testtarget.lan.", net.ParseIP("192.168.42.23")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestDHCP(t *testing.T) {
|
||||
r := &recorder{}
|
||||
s := NewServer("localhost:0", "lan")
|
||||
@ -620,3 +642,93 @@ func TestSubname(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestDNSEntries(t *testing.T) {
|
||||
r := &recorder{}
|
||||
s := NewServer("127.0.0.2:0", "lan")
|
||||
s.SetLeases([]dhcp4d.Lease{
|
||||
{
|
||||
Hostname: "testtarget",
|
||||
Addr: net.IP{192, 168, 42, 23},
|
||||
},
|
||||
{
|
||||
Hostname: "testtarget-ipv6",
|
||||
Addr: net.ParseIP("fe80:3::"),
|
||||
},
|
||||
})
|
||||
s.SetDNSEntries([]IP{
|
||||
IP{
|
||||
Host: "testtarget",
|
||||
IPv4: net.IP{7, 7, 7, 7},
|
||||
IPv6: net.ParseIP("fe80:1::"),
|
||||
},
|
||||
IP{
|
||||
Host: "testtarget.example.org",
|
||||
IPv4: net.IP{8, 8, 8, 8},
|
||||
IPv6: net.ParseIP("fe80:2::"),
|
||||
},
|
||||
{
|
||||
Host: "testtarget-ipv6",
|
||||
IPv4: net.IP{9, 9, 9, 9},
|
||||
IPv6: net.ParseIP("fe80:9::"),
|
||||
},
|
||||
})
|
||||
|
||||
t.Run("testtarget.", func(t *testing.T) {
|
||||
if err := resolveTestTarget(s, "testtarget.", net.IP{192, 168, 42, 23}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("testtarget.lan.", func(t *testing.T) {
|
||||
if err := resolveTestTarget(s, "testtarget.lan.", net.IP{192, 168, 42, 23}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("testtarget-ipv6.lan. (IPv6)", func(t *testing.T) {
|
||||
if err := resolveTestTarget(s, "testtarget-ipv6.lan.", net.ParseIP("fe80:3::")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("testtarget-ipv6.lan. (no override???)", func(t *testing.T) {
|
||||
if err := resolveTestTarget(s, "testtarget-ipv6.lan.", net.IP{9, 9, 9, 9}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("testtarget.lan. (IPv6) (no override???)", func(t *testing.T) {
|
||||
if err := resolveTestTarget(s, "testtarget.lan.", net.ParseIP("fe80:1::")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("testtarget.example.org.", func(t *testing.T) {
|
||||
if err := resolveTestTarget(s, "testtarget.example.org.", net.IP{8, 8, 8, 8}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("testtarget.example.org. (IPv6)", func(t *testing.T) {
|
||||
if err := resolveTestTarget(s, "testtarget.example.org.", net.ParseIP("fe80:2::")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
s.SetLeases([]dhcp4d.Lease{
|
||||
{
|
||||
Hostname: "testtarget",
|
||||
Addr: net.IP{192, 168, 42, 23},
|
||||
},
|
||||
})
|
||||
|
||||
t.Run("testtarget.example.org. (deleted)", func(t *testing.T) {
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion("testtarget.example.org.", dns.TypeA)
|
||||
s.Mux.ServeDNS(r, m)
|
||||
if got, want := r.response.Rcode, dns.RcodeNameError; got != want {
|
||||
t.Fatalf("unexpected rcode: got %v, want %v", got, want)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ func Process(name string, sig os.Signal) error {
|
||||
}
|
||||
return err
|
||||
}
|
||||
if !strings.HasPrefix(string(b), name) {
|
||||
if !strings.Contains(string(b), name) {
|
||||
continue
|
||||
}
|
||||
pid, _ := strconv.Atoi(fi.Name()) // already verified to be numeric
|
||||
|
@ -12,7 +12,7 @@ RUN echo 'APT::Acquire::Retries "5";' > /etc/apt/apt.conf.d/80retry
|
||||
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
dnsmasq ndisc6 nftables dnsutils strace && \
|
||||
dnsmasq ndisc6 nftables dnsutils strace wireguard && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /usr/src
|
||||
|
6
website/archetypes/default.md
Normal file
6
website/archetypes/default.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
title: "{{ replace .Name "-" " " | title }}"
|
||||
date: {{ .Date }}
|
||||
draft: true
|
||||
---
|
||||
|
19
website/config.toml
Normal file
19
website/config.toml
Normal file
@ -0,0 +1,19 @@
|
||||
baseURL = "https://router7.org/"
|
||||
languageCode = "en-us"
|
||||
title = "router7"
|
||||
theme = "router7"
|
||||
disableKinds = ["RSS", "taxonomyTerm"]
|
||||
publishDir = "../docs/"
|
||||
enableRobotsTXT = true
|
||||
|
||||
[markup.goldmark.renderer]
|
||||
# Required for e.g. <img> tags in markdown articles.
|
||||
unsafe = true
|
||||
|
||||
[menu]
|
||||
|
||||
[[menu.main]]
|
||||
name = "github"
|
||||
title = "GitHub"
|
||||
url = "https://github.com/rtr7/router7"
|
||||
weight = 60
|
37
website/content/_index.md
Normal file
37
website/content/_index.md
Normal file
@ -0,0 +1,37 @@
|
||||
---
|
||||
title: "router7: a small home internet router completely written in Go"
|
||||
menu:
|
||||
main:
|
||||
title: "Home"
|
||||
weight: 10
|
||||
---
|
||||
|
||||
# router7
|
||||
|
||||
router7 is a pure-Go implementation of a small home internet router. It comes with all the services required to make a [fiber7 internet connection](https://www.init7.net/en/internet/fiber7/) work (DHCPv4, DHCPv6, DNS, etc.).
|
||||
|
||||
Note that this project should be considered a (working!) tech demo. Feature requests will likely not be implemented, and see [CONTRIBUTING.md](CONTRIBUTING.md) for details about which contributions are welcome.
|
||||
|
||||
## Motivation
|
||||
|
||||
Before starting router7, I was using the [Turris Omnia](https://omnia.turris.cz/en/) router running OpenWrt. That worked fine up until May 2018, when an automated update pulled in a new version of [odhcp6c](https://git.openwrt.org/?p=project/odhcp6c.git;a=shortlog), OpenWrt’s DHCPv6 client. That version is incompatible with fiber7’s DHCP server setup (I think there are shortcomings on both sides).
|
||||
|
||||
It was not only quicker to develop my own router than to wait for either side to resolve the issue, but it was also a lot of fun and allowed me to really tailor my router to my needs, experimenting with a bunch of interesting ideas I had.
|
||||
|
||||
## Project goals
|
||||
|
||||
* Maximize internet connectivity: retain the most recent DHCP configuration across reboots and even after its expiration (chances are the DHCP server will be back before the configuration stops working).
|
||||
* Unit/integration tests use fiber7 packet capture files to minimize the chance of software changes breaking my connectivity.
|
||||
* Safe and quick updates
|
||||
* Auto-rollback of updates which result in loss of connectivity: the diagnostics daemon assesses connectivity state, the update tool reads it and rolls back faulty updates.
|
||||
* Thanks to kexec, updates translate into merely 13s of internet connectivity loss.
|
||||
* Easy debugging
|
||||
* Configuration-related network packets (e.g. DHCP, IPv6 neighbor/router advertisements) are stored in a ring buffer which can be streamed into [Wireshark](https://www.wireshark.org/), allowing for live and retro-active debugging.
|
||||
* The diagnostics daemon performs common diagnostic steps (ping, traceroute, …) for you.
|
||||
* All state in the system is stored as human-readable JSON within the `/perm` partition and can be modified.
|
||||
|
||||
## Hardware
|
||||
|
||||
The reference hardware platform is the [PC Engines™ apu2c4](https://pcengines.ch/apu2c4.htm) system board. It features a 1 GHz quad core amd64 CPU, 4 GB of RAM, 3 Ethernet ports and a DB9 serial port. It conveniently supports PXE boot, the schematics and bootloader sources are available. I recommend the [msata16g](https://pcengines.ch/msata16g.htm) SSD module for reliable persistent storage and the [usbcom1a](https://pcengines.ch/usbcom1a.htm) serial adapter if you don’t have one already.
|
||||
|
||||
Other hardware might work, too, but is not tested.
|
64
website/content/architecture.md
Normal file
64
website/content/architecture.md
Normal file
@ -0,0 +1,64 @@
|
||||
---
|
||||
title: "router7: architecture"
|
||||
menu:
|
||||
main:
|
||||
title: "Architecture"
|
||||
weight: 20
|
||||
---
|
||||
|
||||
# Architecture
|
||||
|
||||
router7 is based on [gokrazy](https://gokrazy.org/): it is an appliance which gets packed into a hard disk image, containing a FAT partition with the kernel, a read-only SquashFS partition for the root file system and an ext4 partition for permanent data.
|
||||
|
||||
The individual services can be found in [github.com/rtr7/router7/cmd](https://pkg.go.dev/github.com/rtr7/router7/cmd)
|
||||
|
||||
* Each service runs in a separate process.
|
||||
* Services communicate with each other by persisting state files. E.g., `cmd/dhcp4` writes `/perm/dhcp4/wire/lease.json`.
|
||||
* A service notifies other services about state changes by sending them signal `SIGUSR1`.
|
||||
|
||||
## Configuration files
|
||||
|
||||
{{<table "table table-striped table-bordered">}}
|
||||
| File | Consumer(s) | Purpose |
|
||||
|---|---|---|
|
||||
| `/perm/interfaces.json` | `netconfigd` | Set IP/MAC addresses of `uplink0` and `lan0` |
|
||||
| `/perm/portforwardings.json` | `netconfigd` | Configure nftables port forwarding rules |
|
||||
| `/perm/dhcp6/duid` | `dhcp6` | Set DHCP Unique Identifier (DUID) for obtaining static leases |
|
||||
{{</table>}}
|
||||
|
||||
## State files
|
||||
|
||||
{{<table "table table-striped table-bordered">}}
|
||||
| File | Producer | Consumer(s) | Purpose |
|
||||
|---|---|---|---|
|
||||
| `/perm/dhcp4/wire/ack` | `dhcp4` | `dhcp4` | last DHCPACK packet for renewals across restarts |
|
||||
| `/perm/dhcp4/wire/lease.json` | `dhcp4` | `netconfigd` | Obtained DHCPv4 lease |
|
||||
| `/perm/dhcp6/wire/lease.json` | `dhcp6` | `netconfigd`, `radvd` | Obtained DHCPv6 lease |
|
||||
| `/perm/dhcp4d/leases.json` | `dhcp4d` | `dhcp4d`, `dnsd` | DHCPv4 leases handed out (including hostnames) |
|
||||
{{</table>}}
|
||||
|
||||
## Available ports
|
||||
|
||||
{{<table "table table-striped table-bordered">}}
|
||||
| Port | Purpose |
|
||||
|---|---|
|
||||
| `<public>:8053` | `dnsd` metrics (forwarded requests)
|
||||
| `<public>:8066` | `netconfigd` metrics (nftables counters)
|
||||
| `<private>:80` | gokrazy web interface
|
||||
| `<private>:67` | `dhcp4d`
|
||||
| `<private>:58` | `radvd`
|
||||
| `<private>:53` | `dnsd`
|
||||
| `<private>:8077` | `backupd` (serve backup.tar.gz)
|
||||
| `<private>:7733` | `diagd` (perform diagnostics)
|
||||
| `<private>:5022` | `captured` (serve captured packets)
|
||||
{{</table>}}
|
||||
|
||||
Here’s an example of `cmd/diagd` output:
|
||||
|
||||
<img src="https://github.com/rtr7/router7/raw/master/2018-07-14-diagd.png"
|
||||
width="800" alt="diagd output">
|
||||
|
||||
Here’s an example of `cmd/netconfigd` metrics when scraped with [Prometheus](https://prometheus.io/) and displayed in [Grafana](https://grafana.com/):
|
||||
|
||||
<img src="https://github.com/rtr7/router7/raw/master/2018-07-14-grafana.png"
|
||||
width="800" alt="metrics in grafana">
|
150
website/content/installation.md
Normal file
150
website/content/installation.md
Normal file
@ -0,0 +1,150 @@
|
||||
---
|
||||
title: "router7: installation"
|
||||
menu:
|
||||
main:
|
||||
title: "Installation"
|
||||
weight: 30
|
||||
---
|
||||
|
||||
# Installation
|
||||
|
||||
Connect your serial adapter ([usbcom1a](https://pcengines.ch/usbcom1a.htm) works well if you don’t have one already) to the apu2c4 and start a program to use it, e.g. `screen /dev/ttyUSB0 115200`. Then, power on the apu2c4 and configure it to do PXE boot:
|
||||
|
||||
* Press `F10` to enter the boot menu
|
||||
* Press `3` to enter setup
|
||||
* Press `n` to enable network boot
|
||||
* Press `c` to move mSATA to the top of the boot order
|
||||
* Press `e` to move iPXE to the top of the boot order
|
||||
* Press `s` to save configuration and exit
|
||||
|
||||
Connect a network cable on `net0`, the port closest to the serial console port:
|
||||
|
||||
<img src="https://github.com/rtr7/router7/raw/master/devsetup.jpg"
|
||||
width="800" alt="router7 development setup">
|
||||
|
||||
Next, build a router7 image:
|
||||
|
||||
```shell
|
||||
go get -u github.com/gokrazy/tools/cmd/gokr-packer github.com/rtr7/tools/cmd/...
|
||||
go get -u -d github.com/rtr7/router7
|
||||
mkdir /tmp/recovery
|
||||
GOARCH=amd64 gokr-packer \
|
||||
-hostname=router7 \
|
||||
-overwrite_boot=/tmp/recovery/boot.img \
|
||||
-overwrite_mbr=/tmp/recovery/mbr.img \
|
||||
-overwrite_root=/tmp/recovery/root.img \
|
||||
-eeprom_package= \
|
||||
-kernel_package=github.com/rtr7/kernel \
|
||||
-firmware_package=github.com/rtr7/kernel \
|
||||
-gokrazy_pkgs=github.com/gokrazy/gokrazy/cmd/ntp \
|
||||
-serial_console=ttyS0,115200n8 \
|
||||
github.com/rtr7/router7/cmd/...
|
||||
```
|
||||
|
||||
Run `rtr7-recover -boot=/tmp/recovery/boot.img -mbr=/tmp/recovery/mbr.img -root=/tmp/recovery/root.img` to:
|
||||
|
||||
* trigger a reset [if a Teensy with the rebootor firmware is attached](#rebootor)
|
||||
* serve a DHCP lease to all clients which request PXE boot (i.e., your apu2c4)
|
||||
* serve via TFTP:
|
||||
* the PXELINUX bootloader
|
||||
* the router7 kernel
|
||||
* an initrd archive containing the rtr7-recovery-init program and mke2fs
|
||||
* serve via HTTP the boot and root images
|
||||
* optionally serve via HTTP a backup.tar.gz image containing files for `/perm` (e.g. for moving to new hardware, rolling back corrupted state, or recovering from a disk failure)
|
||||
* exit once the router successfully wrote the images to disk
|
||||
|
||||
## Configuration
|
||||
|
||||
### Interfaces
|
||||
|
||||
The `/perm/interfaces.json` configuration file will be [automatically created](https://github.com/rtr7/tools/blob/57c2cdc3b629d2fbd13564ae37f6282f6ee8427f/cmd/rtr7-recovery-init/recoveryinit.go#L320) if it is not present when you run the first recovery.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"interfaces": [
|
||||
{
|
||||
"hardware_addr": "12:34:56:78:9a:b0",
|
||||
"name": "lan0",
|
||||
"addr": "192.168.0.1/24"
|
||||
},
|
||||
{
|
||||
"hardware_addr": "12:34:56:78:9a:b2",
|
||||
"name": "uplink0"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Schema: see [`InterfaceConfig`](https://github.com/rtr7/router7/blob/f86e20be5305fc0e7e77421e0f2abde98a84f2a7/internal/netconfig/netconfig.go#L183)
|
||||
|
||||
### Port Forwarding
|
||||
|
||||
The `/perm/portforwardings.json` configuration file can be created to define port forwarding rules.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"forwardings": [
|
||||
{
|
||||
"proto": "tcp",
|
||||
"port": "22",
|
||||
"dest_addr": "10.0.0.10",
|
||||
"dest_port": "22"
|
||||
},
|
||||
{
|
||||
"proto": "tcp",
|
||||
"port": "80",
|
||||
"dest_addr": "10.0.0.10",
|
||||
"dest_port": "80"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Schema: see [`portForwardings`](
|
||||
https://github.com/rtr7/router7/blob/f86e20be5305fc0e7e77421e0f2abde98a84f2a7/internal/netconfig/netconfig.go#L431)
|
||||
|
||||
Please be aware that Hairpinning is currently not supported (see issue [#53 Support for Hairpinning](https://github.com/rtr7/router7/issues/53]))
|
||||
|
||||
## Updates
|
||||
|
||||
Run e.g. `rtr7-safe-update -updates_dir=$HOME/router7/updates` to:
|
||||
|
||||
* verify the router currently has connectivity, abort the update otherwise
|
||||
* download a backup archive of `/perm`
|
||||
* build a new image
|
||||
* update the router
|
||||
* wait until the router restored connectivity, roll back the update using `rtr7-recover` otherwise
|
||||
|
||||
The update step uses kexec to reduce the downtime to approximately 15 seconds.
|
||||
|
||||
## Manual Recovery
|
||||
|
||||
Given `rtr7-safe-update`’s safeguards, manual recovery should rarely be required.
|
||||
|
||||
To manually roll back to an older image, invoke `rtr7-safe-update` via the
|
||||
`recover.bash` script in the image directory underneath `-updates_dir`, e.g.:
|
||||
|
||||
```shell
|
||||
% cd ~/router7/updates/2018-07-03T17:33:52+02:00
|
||||
% ./recover.bash
|
||||
```
|
||||
|
||||
## Teensy rebootor {#rebootor}
|
||||
|
||||
The cheap and widely-available [Teensy++ USB development board](https://www.pjrc.com/store/teensypp.html) comes with a firmware called rebootor, which is used by the [`teensy_loader_cli`](https://www.pjrc.com/teensy/loader_cli.html) program to perform hard resets.
|
||||
|
||||
This setup can be used to programmatically reset the apu2c4 (from `rtr7-recover`) by connecting the Teensy++ to the [apu2c4’s reset pins](http://pcengines.ch/pdf/apu2.pdf):
|
||||
* connect the Teensy++’s `GND` pin to the apu2c4 J2’s pin 4 (`GND`)
|
||||
* connect the Teensy++’s `B7` pin to the apu2c4 J2’s pin 5 (`3.3V`, resets when pulled to `GND`)
|
||||
|
||||
You can find a working rebootor firmware .hex file at https://github.com/PaulStoffregen/teensy_loader_cli/issues/38
|
||||
|
||||
## Prometheus
|
||||
|
||||
See https://github.com/rtr7/router7/tree/master/contrib/prometheus for example
|
||||
configuration files, and install the [router7 Grafana
|
||||
Dashboard](https://grafana.com/dashboards/8288).
|
2
website/layouts/robots.txt
Normal file
2
website/layouts/robots.txt
Normal file
@ -0,0 +1,2 @@
|
||||
User-Agent: *
|
||||
sitemap: https://router7.org/sitemap.xml
|
6
website/layouts/shortcodes/table.html
Normal file
6
website/layouts/shortcodes/table.html
Normal file
@ -0,0 +1,6 @@
|
||||
{{ $htmlTable := .Inner | markdownify }}
|
||||
{{ $class := .Get 0 }}
|
||||
{{ $old := "<table>" }}
|
||||
{{ $new := printf "<table class=\"%s\">" $class }}
|
||||
{{ $htmlTable := replace $htmlTable $old $new }}
|
||||
{{ $htmlTable | safeHTML }}
|
@ -0,0 +1,19 @@
|
||||
.bd-toc {
|
||||
position: sticky;
|
||||
top: 4rem;
|
||||
height: calc(100vh - 4rem);
|
||||
overflow-y: auto; }
|
||||
|
||||
.bd-toc ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
border-left: 1px solid #eee; }
|
||||
|
||||
.bd-toc li {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em; }
|
||||
|
||||
/* TODO: move this to a separate style sheet */
|
||||
.bigbutton {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em; }
|
@ -0,0 +1 @@
|
||||
{"Target":"sass/sidebar.css","MediaType":"text/css","Data":{}}
|
1
website/static/CNAME
Normal file
1
website/static/CNAME
Normal file
@ -0,0 +1 @@
|
||||
router7.org
|
7
website/static/bootstrap-4.4.1.min.css
vendored
Normal file
7
website/static/bootstrap-4.4.1.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
7
website/static/bootstrap-4.4.1.min.js
vendored
Normal file
7
website/static/bootstrap-4.4.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
website/static/jquery-3.4.1.slim.min.js
vendored
Normal file
2
website/static/jquery-3.4.1.slim.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
5
website/static/popper-1.16.0.min.js
vendored
Normal file
5
website/static/popper-1.16.0.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
20
website/themes/router7/LICENSE
Normal file
20
website/themes/router7/LICENSE
Normal file
@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2020 YOUR_NAME_HERE
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
2
website/themes/router7/archetypes/default.md
Normal file
2
website/themes/router7/archetypes/default.md
Normal file
@ -0,0 +1,2 @@
|
||||
+++
|
||||
+++
|
23
website/themes/router7/assets/sass/sidebar.scss
Normal file
23
website/themes/router7/assets/sass/sidebar.scss
Normal file
@ -0,0 +1,23 @@
|
||||
.bd-toc {
|
||||
position: sticky;
|
||||
top: 4rem;
|
||||
height: calc(100vh - 4rem);
|
||||
overflow-y: auto
|
||||
}
|
||||
|
||||
.bd-toc ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
border-left: 1px solid #eee;
|
||||
}
|
||||
|
||||
.bd-toc li {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
/* TODO: move this to a separate style sheet */
|
||||
.bigbutton {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
}
|
0
website/themes/router7/layouts/404.html
Normal file
0
website/themes/router7/layouts/404.html
Normal file
17
website/themes/router7/layouts/_default/baseof.html
Normal file
17
website/themes/router7/layouts/_default/baseof.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
{{- partial "head.html" . -}}
|
||||
<body>
|
||||
<div id="content">
|
||||
<div class="container">
|
||||
|
||||
{{- partial "header.html" . -}}
|
||||
|
||||
{{ block "main" . }}
|
||||
{{ end }}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{{- partial "footer.html" . -}}
|
||||
</body>
|
||||
</html>
|
31
website/themes/router7/layouts/_default/list.html
Normal file
31
website/themes/router7/layouts/_default/list.html
Normal file
@ -0,0 +1,31 @@
|
||||
{{ define "main" }}
|
||||
<div class="row">
|
||||
<div class="col-md-10">
|
||||
|
||||
{{- partial "nav.html" . -}}
|
||||
{{ .Content }}
|
||||
|
||||
<h1>list template</h1>
|
||||
|
||||
<ul>
|
||||
{{ range .Pages }}
|
||||
<li>
|
||||
<a href="{{ .Permalink }}">{{ .Title }}</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<p class="small">
|
||||
© 2018 Michael Stapelberg and contributors
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<aside class="bd-toc">
|
||||
{{ .TableOfContents }}
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
20
website/themes/router7/layouts/_default/single.html
Normal file
20
website/themes/router7/layouts/_default/single.html
Normal file
@ -0,0 +1,20 @@
|
||||
{{ define "main" }}
|
||||
<div class="row">
|
||||
<div class="col-md-10">
|
||||
|
||||
{{- partial "nav.html" . -}}
|
||||
{{ .Content }}
|
||||
|
||||
<hr>
|
||||
|
||||
<p class="small">
|
||||
© 2018 Michael Stapelberg and contributors
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<aside class="bd-toc">
|
||||
{{ .TableOfContents }}
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
17
website/themes/router7/layouts/index.html
Normal file
17
website/themes/router7/layouts/index.html
Normal file
@ -0,0 +1,17 @@
|
||||
{{ define "main" }}
|
||||
<div class="row">
|
||||
<div class="col-md-10">
|
||||
|
||||
{{- partial "nav.html" . -}}
|
||||
{{ .Content }}
|
||||
|
||||
<hr>
|
||||
|
||||
<p class="small">
|
||||
© 2018 Michael Stapelberg and contributors
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
7
website/themes/router7/layouts/partials/footer.html
Normal file
7
website/themes/router7/layouts/partials/footer.html
Normal file
@ -0,0 +1,7 @@
|
||||
<!-- Optional JavaScript -->
|
||||
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
|
||||
<script src="/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
|
||||
<script src="/popper-1.16.0.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
|
||||
<script src="/bootstrap-4.4.1.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
|
||||
</body>
|
||||
</html>
|
14
website/themes/router7/layouts/partials/head.html
Normal file
14
website/themes/router7/layouts/partials/head.html
Normal file
@ -0,0 +1,14 @@
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<!-- Bootstrap CSS -->
|
||||
<link rel="stylesheet" href="/bootstrap-4.4.1.min.css" crossorigin="anonymous">
|
||||
|
||||
{{ $sass := resources.Get "sass/sidebar.scss" }}
|
||||
{{ $style := $sass | resources.ToCSS }}
|
||||
<link rel="stylesheet" href="{{ $style.Permalink }}">
|
||||
|
||||
<title>{{ .Title }}</title>
|
||||
</head>
|
0
website/themes/router7/layouts/partials/header.html
Normal file
0
website/themes/router7/layouts/partials/header.html
Normal file
15
website/themes/router7/layouts/partials/nav.html
Normal file
15
website/themes/router7/layouts/partials/nav.html
Normal file
@ -0,0 +1,15 @@
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<a class="navbar-brand" href="#">router7</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
|
||||
<div class="navbar-nav ml-auto">
|
||||
{{ $current := . }}
|
||||
{{ range .Site.Menus.main }}
|
||||
{{ $active := $current.IsMenuCurrent "main" . }}
|
||||
<a class="nav-item nav-link {{ if $active }}active{{ end }}" href="{{ .URL }}">{{ .Title }} {{ if $active }}<span class="sr-only">(current)</span>{{ end }}</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
21
website/themes/router7/theme.toml
Normal file
21
website/themes/router7/theme.toml
Normal file
@ -0,0 +1,21 @@
|
||||
# theme.toml template for a Hugo theme
|
||||
# See https://github.com/gohugoio/hugoThemes#themetoml for an example
|
||||
|
||||
name = "Distri"
|
||||
license = "MIT"
|
||||
licenselink = "https://github.com/yourname/yourtheme/blob/master/LICENSE"
|
||||
description = ""
|
||||
homepage = "http://example.com/"
|
||||
tags = []
|
||||
features = []
|
||||
min_version = "0.41.0"
|
||||
|
||||
[author]
|
||||
name = ""
|
||||
homepage = ""
|
||||
|
||||
# If porting an existing theme
|
||||
[original]
|
||||
name = ""
|
||||
homepage = ""
|
||||
repo = ""
|
Reference in New Issue
Block a user