Skip to content

Commit

Permalink
ms8.1 - further improvements for single-binary operation
Browse files Browse the repository at this point in the history
Embed web-based and BPF C file templates so that nethadone
can run entirely from a pre-built binary and not require
a checkout of the source code

External JS libraries will still be pulled from CDNs when accessing
the web interface, tbd whether it's worth the trouble to embed those
  • Loading branch information
atomic77 committed Aug 9, 2024
1 parent 0709c95 commit 784c0c5
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 18 deletions.
6 changes: 4 additions & 2 deletions cmd/nethadone.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package main
import (
"flag"
"log"
"net/http"

"github.com/alecthomas/repr"
"github.com/atomic77/nethadone/config"
"github.com/atomic77/nethadone/database"
"github.com/atomic77/nethadone/handlers"
"github.com/atomic77/nethadone/policy"
"github.com/atomic77/nethadone/views"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/adaptor"
"github.com/gofiber/fiber/v2/middleware/logger"
Expand All @@ -32,8 +34,8 @@ func main() {
database.Connect()
handlers.Initialize()

// Pass the engine to the Views
engine := html.New("./views", ".tpl")
// Use embedded templates
engine := html.NewFileSystem(http.FS(views.EmbedTemplates), ".tpl")
app := fiber.New(fiber.Config{
Views: engine,
})
Expand Down
41 changes: 27 additions & 14 deletions handlers/bpf.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,28 +88,41 @@ func Initialize() {
}

func ApplyPolicies(ipPolicies *[]models.IpPolicy) {
rebuildBpf("ebpf/throttle.bpf.c.tpl", "ebpf/throttle.bpf.c", ipPolicies)
reattachThrottler(config.Cfg.LanInterface, tc.HandleMinEgress)
targFile, err := os.CreateTemp("", "throttle-*.bpf.c")
if err != nil {
log.Fatal("could not create throttler file: ", err)
}
objFile, err := os.CreateTemp("", "throttle-*.o")
if err != nil {
log.Fatal("could not create throttler object file: ", err)
}

rebuildBpf("throttle.bpf.c.tpl", targFile, objFile, ipPolicies)
reattachThrottler(objFile, config.Cfg.LanInterface, tc.HandleMinEgress)
os.Remove(targFile.Name())
os.Remove(objFile.Name())
}

func rebuildBpf(tplfile string, target string, ipPolicies *[]models.IpPolicy) {
func rebuildBpf(tplfile string, target *os.File, objFile *os.File, ipPolicies *[]models.IpPolicy) {
log.Println("Rebuilding with ", len(*ipPolicies), " throttle targets from policy database")

f, err := os.Create(target)
if err != nil {
log.Fatal("failed to create rendered file ", err)
}
tpl := template.Must(template.ParseFiles(tplfile))
tpl := template.Must(template.ParseFS(EmbedThrottlerCode, tplfile))
type fdata struct {
IpPolicies *[]models.IpPolicy
}
err = tpl.Execute(f, fdata{IpPolicies: ipPolicies})

log.Println("Temporary file ", target.Name())
err := tpl.Execute(target, fdata{IpPolicies: ipPolicies})
if err != nil {
log.Fatal("failed to render file ", err)
}
// FIXME There surely must be a better way of doing this dynamically
cmd := exec.Command("make", "build-throttler")
cmd.Dir = "ebpf/"
cmd := exec.Command(
"clang", "-g", "-O2",
// Include both armv7 and aarch64 include folders
"-I/usr/include/aarch64-linux-gnu", "-I/usr/arm-linux-gnueabi/include",
"-Wall", "-target", "bpf", "-c", target.Name(), "-o", objFile.Name(),
)
cmd.Dir = os.TempDir()
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatal("failed to rebuild throttler eBPF, out: ", string(out), " err: ", err)
Expand Down Expand Up @@ -144,7 +157,7 @@ func cleanupThrottler(iface *net.Interface) {

}

func reattachThrottler(ifname string, direction uint32) {
func reattachThrottler(objFile *os.File, ifname string, direction uint32) {

log.Println("(Re)attaching throttler BPF to if ", ifname, " direction ", direction)

Expand All @@ -157,7 +170,7 @@ func reattachThrottler(ifname string, direction uint32) {
cleanupThrottler(iface)

BpfCtx.ThrottleObjs = &throttleObjects{}
spec, err := ebpf.LoadCollectionSpec("ebpf/throttle.o")
spec, err := ebpf.LoadCollectionSpec(objFile.Name())
if err != nil {
log.Fatal("failed to load spec ", err)
}
Expand Down
10 changes: 10 additions & 0 deletions handlers/embed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package handlers

import "embed"

// Currently we are handling the management of the throttler
// ebpf outside of bpf2go due to challenges figuring out how to allow
// live recompiling

//go:embed throttle.bpf.c.tpl
var EmbedThrottlerCode embed.FS
2 changes: 0 additions & 2 deletions handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import (
"net"
)

// var config Config

func Index(c *fiber.Ctx) error {
// Render index
return c.Render("index", fiber.Map{
Expand Down
File renamed without changes.
7 changes: 7 additions & 0 deletions views/embed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package views

import "embed"

//go:embed *.tpl
//go:embed **/*.tpl
var EmbedTemplates embed.FS

0 comments on commit 784c0c5

Please sign in to comment.