Skip to content

Commit

Permalink
network: Refactor network setup to avoid code duplication
Browse files Browse the repository at this point in the history
Signed-off-by: Georgios Ntoutsos <[email protected]>
Reviewed-by: Charalampos Mainas <[email protected]>
Approved-by: Charalampos Mainas <[email protected]>
PR: #30
  • Loading branch information
gntouts authored and cmainas committed Jun 20, 2024
1 parent 05f5650 commit 073824b
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 93 deletions.
1 change: 0 additions & 1 deletion cmd/urunc/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ var createCommand = cli.Command{
if err != nil {
return err
}

return createUnikontainer(context)
}
err := handleNonBimaContainer(context)
Expand Down
5 changes: 5 additions & 0 deletions cmd/urunc/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ func handleNonBimaContainer(context *cli.Context) error {
return nil
}
logrus.Info("This is a normal container. Calling runc...")
return runcExec()
}

func runcExec() error {
args := os.Args
binPath, err := exec.LookPath("runc")
if err != nil {
Expand Down Expand Up @@ -172,6 +176,7 @@ func handleQueueProxy(context *cli.Context) error {
if err != nil {
return fmt.Errorf("error writing to file: %v", err)
}
return runcExec()
}
return nil
}
Expand Down
5 changes: 3 additions & 2 deletions internal/constants/network_constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package constants
const (
StaticNetworkTapIP = "172.16.1.1"
StaticNetworkUnikernelIP = "172.16.1.2"
DynamicNetworkTapIP = "172.16.X.2"
QueueProxyRedirectIP = "172.16.1.2"
// TODO: Experiment with DynamicNetworkTapIP starting from 172.16.X.1
DynamicNetworkTapIP = "172.16.X.2"
QueueProxyRedirectIP = "172.16.1.2"
)
1 change: 0 additions & 1 deletion internal/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ func NewZerologMetrics(target string) Writer {
if err != nil {
return nil
}
defer file.Close()
logger := zerolog.New(file).Level(zerolog.InfoLevel).With().Timestamp().Logger()
zerolog.TimeFieldFormat = zerolog.TimeFormatUnixNano
return &zerologMetrics{
Expand Down
62 changes: 62 additions & 0 deletions pkg/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"errors"
"fmt"
"net"
"os/user"
"strconv"
"strings"

"github.com/jackpal/gateway"
Expand Down Expand Up @@ -72,6 +74,9 @@ func getTapIndex() (int, error) {
tapCount++
}
}
if tapCount > 255 {
return tapCount, fmt.Errorf("TAP interfaces count higher than 255")
}
return tapCount, nil
}

Expand Down Expand Up @@ -212,3 +217,60 @@ func addRedirectFilter(source netlink.Link, target netlink.Link) error {
},
})
}

func networkSetup(tapName string, ipAdrress string, redirectLink netlink.Link, addTCRules bool) (netlink.Link, error) {
err := ensureEth0Exists()
// if eth0 does not exist in the namespace, the unikernel was spawned using ctr, so we skip the network setup
if err != nil {
netlog.Info("eth0 interface not found, assuming unikernel was spawned using ctr")
return nil, nil
}
currentUser, err := user.Current()
if err != nil {
return nil, err
}
uid, err := strconv.Atoi(currentUser.Uid)
if err != nil {
return nil, err
}
gid, err := strconv.Atoi(currentUser.Gid)
if err != nil {
return nil, err
}
newTapDevice, err := createTapDevice(tapName, redirectLink.Attrs().MTU, uid, gid)
if err != nil {
return nil, err
}
if addTCRules {
err = addIngressQdisc(newTapDevice)
if err != nil {
return nil, err
}
err = addIngressQdisc(redirectLink)
if err != nil {
return nil, err
}
err = addRedirectFilter(newTapDevice, redirectLink)
if err != nil {
return nil, err
}
err = addRedirectFilter(redirectLink, newTapDevice)
if err != nil {
return nil, err
}
}
ipn, err := netlink.ParseAddr(ipAdrress)
if err != nil {
return nil, err
}
err = netlink.AddrReplace(newTapDevice, ipn)
if err != nil {
return nil, err
}

err = netlink.LinkSetUp(newTapDevice)
if err != nil {
return nil, err
}
return newTapDevice, nil
}
60 changes: 7 additions & 53 deletions pkg/network/network_dynamic.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ package network

import (
"fmt"
"os/user"
"strconv"
"strings"

Expand All @@ -37,72 +36,27 @@ type DynamicNetwork struct {
// for multiple unikernels in the same pod/network namespace
// See: https://github.com/nubificus/urunc/issues/13
func (n DynamicNetwork) NetworkSetup() (*UnikernelNetworkInfo, error) {
err := ensureEth0Exists()
// if eth0 does not exist in the namespace, the unikernel was spawned using ctr, so we skip the network setup
if err != nil {
netlog.Info("eth0 interface not found, assuming unikernel was spawned using ctr")
return nil, nil
}
redirectLink, err := netlink.LinkByName(DefaultInterface)
if err != nil {
netlog.Errorf("failed to find %s interface", DefaultInterface)
return nil, err
}
ifInfo, err := getInterfaceInfo(DefaultInterface)
if err != nil {
return nil, err
}
currentUser, err := user.Current()
if err != nil {
return nil, err
}
uid, err := strconv.Atoi(currentUser.Uid)
if err != nil {
return nil, err
}
gid, err := strconv.Atoi(currentUser.Gid)
if err != nil {
return nil, err
}
tapIndex, err := getTapIndex()
if err != nil {
return nil, err
}
newTapName := strings.ReplaceAll(DefaultTap, "X", strconv.Itoa(tapIndex))
newTapDevice, err := createTapDevice(newTapName, redirectLink.Attrs().MTU, uid, gid)
redirectLink, err := netlink.LinkByName(DefaultInterface)
if err != nil {
netlog.Errorf("failed to find %s interface", DefaultInterface)
return nil, err
}
newTapName := strings.ReplaceAll(DefaultTap, "X", strconv.Itoa(tapIndex))
addTCRules := false
if tapIndex == 0 {
err = addIngressQdisc(newTapDevice)
if err != nil {
return nil, err
}
err = addIngressQdisc(redirectLink)
if err != nil {
return nil, err
}
err = addRedirectFilter(newTapDevice, redirectLink)
if err != nil {
return nil, err
}
err = addRedirectFilter(redirectLink, newTapDevice)
if err != nil {
return nil, err
}
addTCRules = true
}
ipTemplate := fmt.Sprintf("%s/24", constants.DynamicNetworkTapIP)
newIPAddr := strings.ReplaceAll(ipTemplate, "X", strconv.Itoa(tapIndex+1))
ipn, err := netlink.ParseAddr(newIPAddr)
if err != nil {
return nil, err
}
err = netlink.AddrReplace(newTapDevice, ipn)
newTapDevice, err := networkSetup(newTapName, newIPAddr, redirectLink, addTCRules)
if err != nil {
return nil, err
}

err = netlink.LinkSetUp(newTapDevice)
ifInfo, err := getInterfaceInfo(DefaultInterface)
if err != nil {
return nil, err
}
Expand Down
40 changes: 5 additions & 35 deletions pkg/network/network_static.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ package network

import (
"fmt"
"os/user"
"strconv"
"strings"

"github.com/nubificus/urunc/internal/constants"
Expand All @@ -30,42 +28,14 @@ type StaticNetwork struct {
}

func (n StaticNetwork) NetworkSetup() (*UnikernelNetworkInfo, error) {
err := ensureEth0Exists()
if err != nil {
netlog.Error("failed to find eth0 interface in current netns")
return nil, err
}
redirectLink, err := netlink.LinkByName(DefaultInterface)
if err != nil {
netlog.Errorf("failed to find %s interface", DefaultInterface)
return nil, err
}
currentUser, err := user.Current()
if err != nil {
return nil, err
}
uid, err := strconv.Atoi(currentUser.Uid)
if err != nil {
return nil, err
}
gid, err := strconv.Atoi(currentUser.Gid)
if err != nil {
return nil, err
}
newTapName := strings.ReplaceAll(DefaultTap, "X", "0")
newTapDevice, err := createTapDevice(newTapName, redirectLink.Attrs().MTU, uid, gid)
if err != nil {
return nil, err
}
ipn, err := netlink.ParseAddr(StaticIPAddr)
if err != nil {
return nil, err
}
err = netlink.AddrReplace(newTapDevice, ipn)
addTCRules := false
redirectLink, err := netlink.LinkByName(DefaultInterface)
if err != nil {
netlog.Errorf("failed to find %s interface", DefaultInterface)
return nil, err
}
err = netlink.LinkSetUp(newTapDevice)
newTapDevice, err := networkSetup(newTapName, StaticIPAddr, redirectLink, addTCRules)
if err != nil {
return nil, err
}
Expand All @@ -75,7 +45,7 @@ func (n StaticNetwork) NetworkSetup() (*UnikernelNetworkInfo, error) {
IP: constants.StaticNetworkUnikernelIP,
DefaultGateway: constants.StaticNetworkTapIP,
Mask: "255.255.255.0",
Interface: "eth0", // or tap0_urunc?
Interface: DefaultInterface, // or tap0_urunc?
MAC: redirectLink.Attrs().HardwareAddr.String(),
},
}, nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/unikontainers/unikontainers.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func (u *Unikontainer) Exec() error {
}
networkInfo, err := netManager.NetworkSetup()
if err != nil {
return err
Log.Errorf("Failed to setup network :%v. Possibly due to ctr", err)
}
metrics.Capture(u.State.ID, "TS17")

Expand Down

0 comments on commit 073824b

Please sign in to comment.