From 8dc93c66c44c808b1bab2aa163731d17d671ef8e Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Tue, 8 Mar 2022 09:32:09 +0100 Subject: [PATCH 1/7] netconfig: enable NAT hairpinning for port forwardings fixes https://github.com/rtr7/router7/issues/53 --- integration/netconfig/netconfig_test.go | 9 +- internal/netconfig/netconfig.go | 133 +++++++++++++++++++++--- 2 files changed, 126 insertions(+), 16 deletions(-) diff --git a/integration/netconfig/netconfig_test.go b/integration/netconfig/netconfig_test.go index d8ab0ed..9237360 100644 --- a/integration/netconfig/netconfig_test.go +++ b/integration/netconfig/netconfig_test.go @@ -137,19 +137,20 @@ func goldenNftablesRules(additionalForwarding bool) string { add := "" if additionalForwarding { add = ` - iifname "uplink0" tcp dport 8045 dnat to 192.168.42.22:8045` + ip daddr != 127.0.0.0/8 ip daddr != 10.0.0.0/24 fib daddr type 2 tcp dport 8045 dnat to 192.168.42.22:8045` } return `table ip nat { chain prerouting { type nat hook prerouting priority 0; policy accept; - iifname "uplink0" tcp dport 8080 dnat to 192.168.42.23:9999` + add + ` - iifname "uplink0" tcp dport 8040-8060 dnat to 192.168.42.99:8040-8060 - iifname "uplink0" udp dport 53 dnat to 192.168.42.99:53 + ip daddr != 127.0.0.0/8 ip daddr != 10.0.0.0/24 fib daddr type 2 tcp dport 8080 dnat to 192.168.42.23:9999` + add + ` + ip daddr != 127.0.0.0/8 ip daddr != 10.0.0.0/24 fib daddr type 2 tcp dport 8040-8060 dnat to 192.168.42.99:8040-8060 + ip daddr != 127.0.0.0/8 ip daddr != 10.0.0.0/24 fib daddr type 2 udp dport 53 dnat to 192.168.42.99:53 } chain postrouting { type nat hook postrouting priority 100; policy accept; oifname "uplink0" masquerade + iifname "lan0" oifname "lan0" ct status 0x20 masquerade } } table ip filter { diff --git a/internal/netconfig/netconfig.go b/internal/netconfig/netconfig.go index 5e8b779..f13fd01 100644 --- a/internal/netconfig/netconfig.go +++ b/internal/netconfig/netconfig.go @@ -409,6 +409,73 @@ func nfifname(n string) []byte { return b } +// matchUplinkIP is conceptually equivalent to "ip daddr ", but +// without actually using the IP address of the uplink0 interface (which would +// mean that rules need to change when the IP address changes). +// +// Instead, it uses “fib daddr type local” to match all locally-configured IP +// addresses and then excludes the loopback and LAN IP addresses. +func matchUplinkIP() []expr.Any { + return []expr.Any{ + // [ payload load 4b @ network header + 16 => reg 1 ] + &expr.Payload{ + DestRegister: 1, + Base: expr.PayloadBaseNetworkHeader, + Offset: 16, // TODO + Len: 4, // TODO + }, + // [ bitwise reg 1 = (reg=1 & 0x000000ff ) ^ 0x00000000 ] + &expr.Bitwise{ + DestRegister: 1, + SourceRegister: 1, + Len: 4, + Mask: []byte{0xff, 0x00, 0x00, 0x00}, // 255.0.0.0, i.e. /8 + Xor: []byte{0x00, 0x00, 0x00, 0x00}, + }, + // [ cmp neq reg 1 0x0000007f ] + &expr.Cmp{ + Op: expr.CmpOpNeq, + Register: 1, + Data: []byte{0x7f, 0x00, 0x00, 0x00}, + }, + + // [ payload load 4b @ network header + 16 => reg 1 ] + &expr.Payload{ + DestRegister: 1, + Base: expr.PayloadBaseNetworkHeader, + Offset: 16, // TODO + Len: 4, // TODO + }, + // [ bitwise reg 1 = (reg=1 & 0x00ffffff ) ^ 0x00000000 ] + &expr.Bitwise{ + DestRegister: 1, + SourceRegister: 1, + Len: 4, + Mask: []byte{0xff, 0xff, 0xff, 0x00}, // 255.255.255.0, i.e. /24 + Xor: []byte{0x00, 0x00, 0x00, 0x00}, + }, + // [ cmp neq reg 1 0x0000000a ] + &expr.Cmp{ + Op: expr.CmpOpNeq, + Register: 1, + Data: []byte{0x0a, 0x00, 0x00, 0x00}, + }, + + // [ fib daddr type => reg 1 ] + &expr.Fib{ + Register: 1, + FlagDADDR: true, + ResultADDRTYPE: true, + }, + // [ cmp eq reg 1 0x00000002 ] + &expr.Cmp{ + Op: expr.CmpOpEq, + Register: 1, + Data: []byte{0x02, 0x00, 0x00, 0x00}, + }, + } +} + func portForwardExpr(ifname string, proto uint8, portMin, portMax uint16, dest net.IP, dportMin, dportMax uint16) []expr.Any { var cmp []expr.Any if portMin == portMax { @@ -436,16 +503,7 @@ func portForwardExpr(ifname string, proto uint8, portMin, portMax uint16, dest n }, } } - ex := []expr.Any{ - // [ meta load iifname => reg 1 ] - &expr.Meta{Key: expr.MetaKeyIIFNAME, Register: 1}, - // [ cmp eq reg 1 0x696c7075 0x00306b6e 0x00000000 0x00000000 ] - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: nfifname(ifname), - }, - + ex := append(matchUplinkIP(), // [ meta load l4proto => reg 1 ] &expr.Meta{Key: expr.MetaKeyL4PROTO, Register: 1}, // [ cmp eq reg 1 0x00000006 ] @@ -461,8 +519,7 @@ func portForwardExpr(ifname string, proto uint8, portMin, portMax uint16, dest n Base: expr.PayloadBaseTransportHeader, Offset: 2, // TODO Len: 2, // TODO - }, - } + }) ex = append(ex, cmp...) ex = append(ex, // [ immediate reg 1 0x0217a8c0 ] @@ -627,6 +684,52 @@ func getCounterObj(c *nftables.Conn, o *nftables.CounterObj) *nftables.CounterOb return o } +func hairpinDNAT() []expr.Any { + return []expr.Any{ + // [ meta load oifname => reg 1 ] + &expr.Meta{Key: expr.MetaKeyIIFNAME, Register: 1}, + // [ cmp eq reg 1 0x306e616c 0x00000000 0x00000000 0x00000000 ] + &expr.Cmp{ + Op: expr.CmpOpEq, + Register: 1, + Data: nfifname("lan0"), + }, + + // [ meta load oifname => reg 1 ] + &expr.Meta{Key: expr.MetaKeyOIFNAME, Register: 1}, + // [ cmp eq reg 1 0x306e616c 0x00000000 0x00000000 0x00000000 ] + &expr.Cmp{ + Op: expr.CmpOpEq, + Register: 1, + Data: nfifname("lan0"), + }, + + // [ ct load status => reg 1 ] + &expr.Ct{ + Register: 1, + SourceRegister: false, + Key: expr.CtKeySTATUS, + }, + // [ bitwise reg 1 = (reg=1 & 0x00000020 ) ^ 0x00000000 ] + &expr.Bitwise{ + DestRegister: 1, + SourceRegister: 1, + Len: 4, + Mask: []byte{0x20, 0x00, 0x00, 0x00}, + Xor: []byte{0x00, 0x00, 0x00, 0x00}, + }, + + // [ cmp neq reg 1 0x00000000 ] + &expr.Cmp{ + Op: expr.CmpOpNeq, + Register: 1, + Data: []byte{0x00, 0x00, 0x00, 0x00}, + }, + // [ masq ] + &expr.Masq{}, + } +} + func applyFirewall(dir, ifname string) error { c := &nftables.Conn{} @@ -670,6 +773,12 @@ func applyFirewall(dir, ifname string) error { }, }) + c.AddRule(&nftables.Rule{ + Table: nat, + Chain: postrouting, + Exprs: hairpinDNAT(), + }) + if err := applyPortForwardings(dir, ifname, c, nat, prerouting); err != nil { return err } From 593cd8c12defe185725a1a7bbe8689f93faddc87 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Tue, 8 Mar 2022 22:47:18 +0100 Subject: [PATCH 2/7] export input/output nftables counters as well as forwarded Thus far, we have only had forwarded bytes metrics. Notably, forwarded bytes does not include bytes that were sent by the router itself, e.g. by the webserver or rsync server running on the machine. fixes https://github.com/rtr7/router7/issues/71 --- cmd/netconfigd/netconfigd.go | 41 +++++++++---- integration/netconfig/netconfig_test.go | 50 +++++++++++++--- internal/netconfig/netconfig.go | 76 +++++++++++++++++-------- 3 files changed, 124 insertions(+), 43 deletions(-) diff --git a/cmd/netconfigd/netconfigd.go b/cmd/netconfigd/netconfigd.go index fbffd31..d9f9fbd 100644 --- a/cmd/netconfigd/netconfigd.go +++ b/cmd/netconfigd/netconfigd.go @@ -44,6 +44,8 @@ var ( func init() { var c nftables.Conn + filter4 := &nftables.Table{Family: nftables.TableFamilyIPv4, Name: "filter"} + filter6 := &nftables.Table{Family: nftables.TableFamilyIPv6, Name: "filter"} for _, metric := range []struct { name string labels prometheus.Labels @@ -53,18 +55,34 @@ func init() { { name: "filter_forward", labels: prometheus.Labels{"family": "ipv4"}, - obj: &nftables.CounterObj{ - Table: &nftables.Table{Family: nftables.TableFamilyIPv4, Name: "filter"}, - Name: "fwded", - }, + obj: &nftables.CounterObj{Table: filter4, Name: "fwded"}, }, { name: "filter_forward", labels: prometheus.Labels{"family": "ipv6"}, - obj: &nftables.CounterObj{ - Table: &nftables.Table{Family: nftables.TableFamilyIPv6, Name: "filter"}, - Name: "fwded", - }, + obj: &nftables.CounterObj{Table: filter6, Name: "fwded"}, + }, + + { + name: "filter_input", + labels: prometheus.Labels{"family": "ipv4"}, + obj: &nftables.CounterObj{Table: filter4, Name: "inputc"}, + }, + { + name: "filter_input", + labels: prometheus.Labels{"family": "ipv6"}, + obj: &nftables.CounterObj{Table: filter6, Name: "inputc"}, + }, + + { + name: "filter_output", + labels: prometheus.Labels{"family": "ipv4"}, + obj: &nftables.CounterObj{Table: filter4, Name: "outputc"}, + }, + { + name: "filter_output", + labels: prometheus.Labels{"family": "ipv6"}, + obj: &nftables.CounterObj{Table: filter6, Name: "outputc"}, }, } { metric := metric // copy @@ -72,12 +90,11 @@ func init() { updateCounter := func() { mu.Lock() defer mu.Unlock() - objs, err := c.GetObjReset(metric.obj) - if err != nil || - len(objs) != 1 { + obj, err := c.ResetObject(metric.obj) + if err != nil { return } - if co, ok := objs[0].(*nftables.CounterObj); ok { + if co, ok := obj.(*nftables.CounterObj); ok { metric.packets += co.Packets metric.bytes += co.Bytes } diff --git a/integration/netconfig/netconfig_test.go b/integration/netconfig/netconfig_test.go index 9237360..7e8ac40 100644 --- a/integration/netconfig/netconfig_test.go +++ b/integration/netconfig/netconfig_test.go @@ -158,14 +158,11 @@ table ip filter { packets 23 bytes 42 } - chain forward { - type filter hook forward priority 0; policy accept; - oifname "uplink0" tcp flags 0x2 tcp option maxseg size set rt mtu - counter name "fwded" + counter inputc { + packets 23 bytes 42 } -} -table ip6 filter { - counter fwded { + + counter outputc { packets 23 bytes 42 } @@ -174,6 +171,45 @@ table ip6 filter { oifname "uplink0" tcp flags 0x2 tcp option maxseg size set rt mtu counter name "fwded" } + + chain input { + type filter hook input priority 0; policy accept; + counter name "inputc" + } + + chain output { + type filter hook output priority 0; policy accept; + counter name "outputc" + } +} +table ip6 filter { + counter fwded { + packets 23 bytes 42 + } + + counter inputc { + packets 23 bytes 42 + } + + counter outputc { + packets 23 bytes 42 + } + + chain forward { + type filter hook forward priority 0; policy accept; + oifname "uplink0" tcp flags 0x2 tcp option maxseg size set rt mtu + counter name "fwded" + } + + chain input { + type filter hook input priority 0; policy accept; + counter name "inputc" + } + + chain output { + type filter hook output priority 0; policy accept; + counter name "outputc" + } }` } diff --git a/internal/netconfig/netconfig.go b/internal/netconfig/netconfig.go index f13fd01..0b250f1 100644 --- a/internal/netconfig/netconfig.go +++ b/internal/netconfig/netconfig.go @@ -648,35 +648,13 @@ func applyPortForwardings(dir, ifname string, c *nftables.Conn, nat *nftables.Ta var DefaultCounterObj = &nftables.CounterObj{} func getCounterObj(c *nftables.Conn, o *nftables.CounterObj) *nftables.CounterObj { - objs, err := c.GetObj(o) + obj, err := c.GetObject(o) if err != nil { o.Bytes = DefaultCounterObj.Bytes o.Packets = DefaultCounterObj.Packets return o } - { - // TODO: remove this workaround once travis has workers with a newer kernel - // than its current Ubuntu trusty kernel (Linux 4.4.0): - var filtered []nftables.Obj - for _, obj := range objs { - co, ok := obj.(*nftables.CounterObj) - if !ok { - continue - } - if co.Table.Name != o.Table.Name { - continue - } - filtered = append(filtered, obj) - } - objs = filtered - } - if got, want := len(objs), 1; got != want { - log.Printf("could not carry counter values: unexpected number of objects in table %v: got %d, want %d", o.Table.Name, got, want) - o.Bytes = DefaultCounterObj.Bytes - o.Packets = DefaultCounterObj.Packets - return o - } - if co, ok := objs[0].(*nftables.CounterObj); ok { + if co, ok := obj.(*nftables.CounterObj); ok { return co } o.Bytes = DefaultCounterObj.Bytes @@ -888,6 +866,56 @@ func applyFirewall(dir, ifname string) error { }, }, }) + + input := c.AddChain(&nftables.Chain{ + Name: "input", + Hooknum: nftables.ChainHookInput, + Priority: nftables.ChainPriorityFilter, + Table: filter, + Type: nftables.ChainTypeFilter, + }) + + counterObj = getCounterObj(c, &nftables.CounterObj{ + Table: filter, + Name: "inputc", + }) + counter = c.AddObj(counterObj).(*nftables.CounterObj) + c.AddRule(&nftables.Rule{ + Table: filter, + Chain: input, + Exprs: []expr.Any{ + // [ counter name input ] + &expr.Objref{ + Type: NFT_OBJECT_COUNTER, + Name: counter.Name, + }, + }, + }) + + output := c.AddChain(&nftables.Chain{ + Name: "output", + Hooknum: nftables.ChainHookOutput, + Priority: nftables.ChainPriorityFilter, + Table: filter, + Type: nftables.ChainTypeFilter, + }) + + counterObj = getCounterObj(c, &nftables.CounterObj{ + Table: filter, + Name: "outputc", + }) + counter = c.AddObj(counterObj).(*nftables.CounterObj) + c.AddRule(&nftables.Rule{ + Table: filter, + Chain: output, + Exprs: []expr.Any{ + // [ counter name output ] + &expr.Objref{ + Type: NFT_OBJECT_COUNTER, + Name: counter.Name, + }, + }, + }) } return c.Flush() From 2014da4ca32e3b83281357ac5a13ae336f0ffca6 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 12 Mar 2022 17:38:16 +0100 Subject: [PATCH 3/7] dhcp4d: display active devices based on LastACK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This has the advantage that it also works for static DHCP leases, provided the device obtains a DHCP lease at all (and isn’t configured with a static IP address, like the shelly motion sensors for example). --- cmd/dhcp4d/dhcp4d.go | 32 +++++++++++++++++++++----------- internal/dhcp4d/dhcp4d.go | 35 +++++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/cmd/dhcp4d/dhcp4d.go b/cmd/dhcp4d/dhcp4d.go index ae705a4..f78b19b 100644 --- a/cmd/dhcp4d/dhcp4d.go +++ b/cmd/dhcp4d/dhcp4d.go @@ -92,6 +92,9 @@ var ( } return dur.Truncate(1 * time.Second).String() }, + "zero": func(t time.Time) bool { + return t.IsZero() + }, }).Parse(` @@ -150,7 +153,7 @@ form { Hostname MAC address Vendor -Expiry +Last ACK {{ range $idx, $l := . }} @@ -166,27 +169,31 @@ form { {{$l.HardwareAddr}} {{$l.Vendor}} - -{{ if $l.Expired }} -{{ since $l.Expiry }} -expired -{{ else }} -{{ if $l.Static }} -static -{{ else }} -{{ timefmt $l.Expiry }} + +{{ if (not (zero $l.LastACK)) }} +{{ timefmt $l.LastACK }} +{{ if $l.Active }} active {{ end }} +{{ if $l.Expired }} +expired +{{ end }} {{ end }} {{ end }} {{ end }} +

Static Leases

{{ template "table" .StaticLeases }} +
+ +

Dynamic Leases

+ {{ template "table" .DynamicLeases }}
+ `)) @@ -341,17 +348,20 @@ func newSrv(permDir string) (*srv, error) { Vendor string Expired bool Static bool + Active bool } leasesMu.Lock() defer leasesMu.Unlock() static := make([]tmplLease, 0, len(leases)) dynamic := make([]tmplLease, 0, len(leases)) + now := time.Now() tl := func(l *dhcp4d.Lease) tmplLease { return tmplLease{ Lease: *l, Vendor: ouiDB.Lookup(l.HardwareAddr[:8]), - Expired: l.Expired(time.Now()), + Expired: l.Expired(now), + Active: l.Active(now), Static: l.Expiry.IsZero(), } } diff --git a/internal/dhcp4d/dhcp4d.go b/internal/dhcp4d/dhcp4d.go index fec3496..4eaf1de 100644 --- a/internal/dhcp4d/dhcp4d.go +++ b/internal/dhcp4d/dhcp4d.go @@ -43,12 +43,17 @@ type Lease struct { Hostname string `json:"hostname"` HostnameOverride string `json:"hostname_override"` Expiry time.Time `json:"expiry"` + LastACK time.Time `json:"last_ack"` } func (l *Lease) Expired(at time.Time) bool { return !l.Expiry.IsZero() && at.After(l.Expiry) } +func (l *Lease) Active(at time.Time) bool { + return !l.LastACK.IsZero() && at.Before(l.LastACK.Add(leasePeriod)) +} + type Handler struct { serverIP net.IP start net.IP // first IP address to hand out @@ -90,18 +95,14 @@ func NewHandler(dir string, iface *net.Interface, ifaceName string, conn net.Pac copy(start, serverIP) start[len(start)-1] += 1 return &Handler{ - rawConn: conn, - iface: iface, - leasesHW: make(map[string]int), - leasesIP: make(map[int]*Lease), - serverIP: serverIP, - start: start, - leaseRange: 230, - // Apple recommends a DHCP lease time of 1 hour in - // https://support.apple.com/de-ch/HT202068, - // so if 20 minutes ever causes any trouble, - // we should try increasing it to 1 hour. - LeasePeriod: 20 * time.Minute, + rawConn: conn, + iface: iface, + leasesHW: make(map[string]int), + leasesIP: make(map[int]*Lease), + serverIP: serverIP, + start: start, + leaseRange: 230, + LeasePeriod: leasePeriod, options: dhcp4.Options{ dhcp4.OptionSubnetMask: []byte{255, 255, 255, 0}, dhcp4.OptionRouter: []byte(serverIP), @@ -113,6 +114,12 @@ func NewHandler(dir string, iface *net.Interface, ifaceName string, conn net.Pac }, nil } +// Apple recommends a DHCP lease time of 1 hour in +// https://support.apple.com/de-ch/HT202068, +// so if 20 minutes ever causes any trouble, +// we should try increasing it to 1 hour. +const leasePeriod = 20 * time.Minute + // SetLeases overwrites the leases database with the specified leases, typically // loaded from persistent storage. There is no locking, so SetLeases must be // called before Serve. @@ -122,6 +129,9 @@ func (h *Handler) SetLeases(leases []*Lease) { h.leasesHW = make(map[string]int) h.leasesIP = make(map[int]*Lease) for _, l := range leases { + if l.LastACK.IsZero() { + l.LastACK = l.Expiry + } h.leasesHW[l.HardwareAddr] = l.Num h.leasesIP[l.Num] = l } @@ -334,6 +344,7 @@ func (h *Handler) serveDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, options d HardwareAddr: hwAddr, Expiry: h.timeNow().Add(h.leasePeriodForDevice(hwAddr)), Hostname: string(options[dhcp4.OptionHostName]), + LastACK: h.timeNow(), } copy(lease.Addr, reqIP.To4()) From ef7089dc61a751dc99c8be5178e4dd3d99a31501 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Fri, 25 Mar 2022 09:09:26 +0100 Subject: [PATCH 4/7] radvd: switch to netip package for mdlayher/ndp --- go.mod | 2 +- go.sum | 12 ++++++++++-- internal/radvd/radvd.go | 12 +++++++----- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index b61c795..0f6a2f9 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/krolaw/dhcp4 v0.0.0-20190909130307-a50d88189771 github.com/libdns/cloudflare v0.1.0 github.com/libdns/libdns v0.2.0 - github.com/mdlayher/ndp v0.0.0-20200602162440-17ab9e3e5567 + github.com/mdlayher/ndp v0.10.0 github.com/mdlayher/netlink v1.6.0 // indirect github.com/mdlayher/packet v1.0.0 github.com/miekg/dns v1.1.42 diff --git a/go.sum b/go.sum index 5448d66..61484f2 100644 --- a/go.sum +++ b/go.sum @@ -224,8 +224,16 @@ github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQob github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43/go.mod h1:+t7E0lkKfbBsebllff1xdTmyJt8lH37niI6kwFk9OTo= 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-20200602162440-17ab9e3e5567 h1:x+xs91ZJ+lr0C6sedWeREvck4uGCt+AA1kKXwsHB6jI= -github.com/mdlayher/ndp v0.0.0-20200602162440-17ab9e3e5567/go.mod h1:32w/5dDZWVSEOxyniAgKK4d7dHTuO6TCxWmUznQe3f8= +github.com/mdlayher/ndp v0.0.0-20210831201139-f982b8766fb5 h1:w1Lne6x7QKrrkAviNvSd0M3NYblM1n76Pv2FsGkNzzI= +github.com/mdlayher/ndp v0.0.0-20210831201139-f982b8766fb5/go.mod h1:32w/5dDZWVSEOxyniAgKK4d7dHTuO6TCxWmUznQe3f8= +github.com/mdlayher/ndp v0.0.0-20220213140253-2a2b53cd2045 h1:cLcATbaiT+9tZwgtOqN1Duhp5bBkHLBxKlrXCf6srtI= +github.com/mdlayher/ndp v0.0.0-20220213140253-2a2b53cd2045/go.mod h1:32w/5dDZWVSEOxyniAgKK4d7dHTuO6TCxWmUznQe3f8= +github.com/mdlayher/ndp v0.0.0-20220304194648-de594d7bc183 h1:s+zRraldOwsr9RR1N6Q37xjIkEBO64Wk+mniHNimXxE= +github.com/mdlayher/ndp v0.0.0-20220304194648-de594d7bc183/go.mod h1:32w/5dDZWVSEOxyniAgKK4d7dHTuO6TCxWmUznQe3f8= +github.com/mdlayher/ndp v0.9.0 h1:2ARcMhqzN+CloJYcW/yeKRm4JCwf7lc1cgYpUSFJYFQ= +github.com/mdlayher/ndp v0.9.0/go.mod h1:Uv6IWvgvqirNUu2N3ZXJEB86xu6foyUsG0NrClSSfek= +github.com/mdlayher/ndp v0.10.0 h1:Zdwol2bq1EHY8xSnejIYkq6LEj7dLjLymJX0o/2tjGw= +github.com/mdlayher/ndp v0.10.0/go.mod h1:Uv6IWvgvqirNUu2N3ZXJEB86xu6foyUsG0NrClSSfek= 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= diff --git a/internal/radvd/radvd.go b/internal/radvd/radvd.go index 45818e3..df3257d 100644 --- a/internal/radvd/radvd.go +++ b/internal/radvd/radvd.go @@ -18,6 +18,7 @@ package radvd import ( "log" "net" + "net/netip" "sync" "time" @@ -144,21 +145,21 @@ func (s *Server) sendAdvertisement(addr net.Addr) error { if err != nil { return err } - var linkLocal net.IP + var linkLocal netip.Addr for _, addr := range addrs { ipnet, ok := addr.(*net.IPNet) if !ok { continue } if ipv6LinkLocal.Contains(ipnet.IP) { - linkLocal = ipnet.IP + linkLocal, _ = netip.AddrFromSlice(ipnet.IP) break } } - if !linkLocal.Equal(net.IPv6zero) { + if linkLocal.IsValid() && !linkLocal.IsUnspecified() { options = append(options, &ndp.RecursiveDNSServer{ Lifetime: 30 * time.Minute, - Servers: []net.IP{linkLocal}, + Servers: []netip.Addr{linkLocal}, }) } } @@ -170,13 +171,14 @@ func (s *Server) sendAdvertisement(addr net.Addr) error { ones = 64 } + addr, _ := netip.AddrFromSlice(prefix.IP) options = append(options, &ndp.PrefixInformation{ PrefixLength: uint8(ones), OnLink: true, AutonomousAddressConfiguration: true, ValidLifetime: 2 * time.Hour, PreferredLifetime: 30 * time.Minute, - Prefix: prefix.IP, + Prefix: addr, }) } From d747f1db5fc53ee6928fe9d2d2372fb2abde2138 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Fri, 25 Mar 2022 09:11:08 +0100 Subject: [PATCH 5/7] go mod tidy --- go.mod | 4 ++-- go.sum | 18 ++++-------------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/go.mod b/go.mod index 0f6a2f9..e16abb1 100644 --- a/go.mod +++ b/go.mod @@ -30,9 +30,9 @@ require ( github.com/vishvananda/netlink v1.1.1-0.20200221165523-c79a4b7b4066 github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a - golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd + golang.org/x/net v0.0.0-20220225172249-27dd8689420f golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20220209214540-3681064d5158 + golang.org/x/sys v0.0.0-20220317061510-51cd9980dadf golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba golang.zx2c4.com/wireguard v0.0.20201118 // indirect golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210506160403-92e472f520a5 diff --git a/go.sum b/go.sum index 61484f2..3d9af06 100644 --- a/go.sum +++ b/go.sum @@ -110,7 +110,6 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a 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/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -224,14 +223,6 @@ github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQob github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43/go.mod h1:+t7E0lkKfbBsebllff1xdTmyJt8lH37niI6kwFk9OTo= 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-20210831201139-f982b8766fb5 h1:w1Lne6x7QKrrkAviNvSd0M3NYblM1n76Pv2FsGkNzzI= -github.com/mdlayher/ndp v0.0.0-20210831201139-f982b8766fb5/go.mod h1:32w/5dDZWVSEOxyniAgKK4d7dHTuO6TCxWmUznQe3f8= -github.com/mdlayher/ndp v0.0.0-20220213140253-2a2b53cd2045 h1:cLcATbaiT+9tZwgtOqN1Duhp5bBkHLBxKlrXCf6srtI= -github.com/mdlayher/ndp v0.0.0-20220213140253-2a2b53cd2045/go.mod h1:32w/5dDZWVSEOxyniAgKK4d7dHTuO6TCxWmUznQe3f8= -github.com/mdlayher/ndp v0.0.0-20220304194648-de594d7bc183 h1:s+zRraldOwsr9RR1N6Q37xjIkEBO64Wk+mniHNimXxE= -github.com/mdlayher/ndp v0.0.0-20220304194648-de594d7bc183/go.mod h1:32w/5dDZWVSEOxyniAgKK4d7dHTuO6TCxWmUznQe3f8= -github.com/mdlayher/ndp v0.9.0 h1:2ARcMhqzN+CloJYcW/yeKRm4JCwf7lc1cgYpUSFJYFQ= -github.com/mdlayher/ndp v0.9.0/go.mod h1:Uv6IWvgvqirNUu2N3ZXJEB86xu6foyUsG0NrClSSfek= github.com/mdlayher/ndp v0.10.0 h1:Zdwol2bq1EHY8xSnejIYkq6LEj7dLjLymJX0o/2tjGw= github.com/mdlayher/ndp v0.10.0/go.mod h1:Uv6IWvgvqirNUu2N3ZXJEB86xu6foyUsG0NrClSSfek= github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA= @@ -446,7 +437,6 @@ golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLL 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/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/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/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -458,8 +448,9 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210504132125-bbd867fde50d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 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= @@ -468,7 +459,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ 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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -502,7 +492,6 @@ golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -529,8 +518,9 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220317061510-51cd9980dadf h1:Fm4IcnUL803i92qDlmB0obyHmosDrxZWxJL3gIeNqOw= +golang.org/x/sys v0.0.0-20220317061510-51cd9980dadf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= From e8a78c2eaaab46f8f06b303377e8710b9b0f2f90 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Fri, 25 Mar 2022 09:12:16 +0100 Subject: [PATCH 6/7] GitHub Actions: switch to Go 1.18 --- .github/workflows/go.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 1522dee..07c8261 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -16,8 +16,8 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v2 with: - # Run on the latest minor release of Go 1.14: - go-version: ^1.14 + # Run on the latest minor release of Go 1.18: + go-version: ^1.18 id: go - name: Check out code into the Go module directory @@ -51,8 +51,8 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v2 with: - # Run on the latest minor release of Go 1.14: - go-version: ^1.14 + # Run on the latest minor release of Go 1.18: + go-version: ^1.18 id: go - name: Check out code into the Go module directory @@ -78,8 +78,8 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v2 with: - # Run on the latest minor release of Go 1.14: - go-version: ^1.14 + # Run on the latest minor release of Go 1.18: + go-version: ^1.18 id: go - name: Check out code into the Go module directory From 2ee2a943a7f3ba6a83aab7cb872b464018ff7813 Mon Sep 17 00:00:00 2001 From: insanitywholesale <45580420+insanitywholesale@users.noreply.github.com> Date: Fri, 22 Apr 2022 18:04:28 +0300 Subject: [PATCH 7/7] remove line about hairpinning not being supported (#72) --- website/content/installation.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/website/content/installation.md b/website/content/installation.md index 3597735..68f8430 100644 --- a/website/content/installation.md +++ b/website/content/installation.md @@ -107,8 +107,6 @@ Example: 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: