Skip to content

Commit

Permalink
adding bluefield plugin, to always provide the same IPv6 address
Browse files Browse the repository at this point in the history
  • Loading branch information
MalteJ authored Feb 13, 2024
1 parent 6b2a20a commit 4ebd70a
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 0 deletions.
3 changes: 3 additions & 0 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ server6:
- onmetal: metal-api-system dhcp
- dns: 2001:4860:4860::6464 2001:4860:4860::64
- pxeboot: tftp://[2001:db8::1]/ipxe/x86_64/ipxe http://[2001:db8::1]/ipxe/boot6

# Always provide the same IP address, no matter who's asking:
# - bluefield: 2001:db8::1
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
pl_serverid "github.com/coredhcp/coredhcp/plugins/serverid"
pl_ipam "github.com/onmetal/fedhcp/plugins/ipam"
pl_onmetal "github.com/onmetal/fedhcp/plugins/onmetal"
pl_bluefield "github.com/onmetal/fedhcp/plugins/bluefield"
pl_pxeboot "github.com/onmetal/fedhcp/plugins/pxeboot"

"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -58,6 +59,7 @@ var desiredPlugins = []*plugins.Plugin{
&pl_dns.Plugin,
&pl_mtu.Plugin,
&pl_onmetal.Plugin,
&pl_bluefield.Plugin,
&pl_pxeboot.Plugin,
&pl_searchdomains.Plugin,
&pl_serverid.Plugin,
Expand Down
105 changes: 105 additions & 0 deletions plugins/bluefield/plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package bluefield

import (
"fmt"
"time"
"net"

"github.com/coredhcp/coredhcp/plugins"
"github.com/coredhcp/coredhcp/handler"
"github.com/coredhcp/coredhcp/logger"
"github.com/insomniacslk/dhcp/dhcpv6"
"github.com/insomniacslk/dhcp/iana"

)

var log = logger.GetLogger("plugins/bluefield")

var Plugin = plugins.Plugin {
Name: "bluefield",
Setup6: setupPlugin,
}
var ipaddr net.IP


// setupPlugin initializes the plugin with given arguments.
func setupPlugin(args ...string) (handler.Handler6, error) {
if len(args) < 1 {
return nil, fmt.Errorf("plugin bluefield requires at least one argument (static IPv6 address)")
}
ipaddr = net.ParseIP(args[0])
if ipaddr == nil {
return nil, fmt.Errorf("invalid IPv6 address: %s", args[0])
}
log.Infof("Parsed IP %s", ipaddr)
return handleDHCPv6, nil
}

func handleDHCPv6(req, resp dhcpv6.DHCPv6) (dhcpv6.DHCPv6, bool) {
m, err := req.GetInnerMessage()
if err != nil {
return nil, true
}

hwaddr, err := net.ParseMAC("00:11:22:33:44:55")
if err != nil {
return nil, true
}

v6ServerID := &dhcpv6.DUIDLL {
HWType: iana.HWTypeEthernet,
LinkLayerAddr: hwaddr,
}


switch m.Type() {
case dhcpv6.MessageTypeSolicit:
resp, err := dhcpv6.NewAdvertiseFromSolicit(m)
if err != nil {
log.Errorf("Failed to create DHCPv6 advertise: %v", err)
return nil, true
}

log.Infof("IP: %s", ipaddr)

resp.AddOption(&dhcpv6.OptIANA {
IaId: m.Options.OneIANA().IaId,
T1: 1 * time.Hour,
T2: 2 * time.Hour,
Options: dhcpv6.IdentityOptions{Options: []dhcpv6.Option{
&dhcpv6.OptIAAddress{
IPv6Addr: ipaddr,
PreferredLifetime: 24 * time.Hour,
ValidLifetime: 48 * time.Hour,
},
}},
})

dhcpv6.WithServerID(v6ServerID)(resp)
return resp, false

case dhcpv6.MessageTypeRequest:
resp, err = dhcpv6.NewReplyFromMessage(m)
if err != nil {
log.Errorf("Failed to create DHCPv6 reply: %v", err)
return nil, false
}

resp.AddOption(&dhcpv6.OptIANA {
IaId: m.Options.OneIANA().IaId,
T1: 1 * time.Hour,
T2: 2 * time.Hour,
Options: dhcpv6.IdentityOptions{Options: []dhcpv6.Option{
&dhcpv6.OptIAAddress{
IPv6Addr: ipaddr,
PreferredLifetime: 24 * time.Hour,
ValidLifetime: 48 * time.Hour,
},
}},
})

dhcpv6.WithServerID(v6ServerID)(resp)
return resp, true
}
return nil, false
}

0 comments on commit 4ebd70a

Please sign in to comment.