Skip to content

Commit

Permalink
Merge pull request #93 from named-data/nfdc
Browse files Browse the repository at this point in the history
nfdc / dvc + URI refactor + client conf
  • Loading branch information
pulsejet authored Jan 3, 2025
2 parents e6a1870 + 8ee8188 commit 6a31c07
Show file tree
Hide file tree
Showing 76 changed files with 1,873 additions and 470 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ ndnd fw run yanfd.config.yml
A full configuration example can be found in [fw/yanfd.sample.yml](fw/yanfd.sample.yml).
Note that the default configuration may require root privileges to bind to multicast interfaces.

Once started, you can use the [Forwarder Control](tools/nfdc/README.md) tool to manage faces and routes.

## 📡 Distance Vector Router

The `ndnd/dv` package implements `ndn-dv`, an NDN Distance Vector routing daemon.
Expand All @@ -76,6 +78,8 @@ ndnd dv run dv.config.yml
A full configuration example can be found in [dv/dv.sample.yml](dv/dv.sample.yml).
Make sure the network and router name are correctly configured and the forwarder is running.

Once started, you can use the [DV Control](tools/dvc/README.md) tool to create and destroy neighbor links.

## 📚 Standard Library

The `ndnd/std` package implements `go-ndn`, a standard library for NDN applications.
Expand Down
26 changes: 20 additions & 6 deletions cmd/ndnd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,46 @@ package main
import (
"os"

"github.com/named-data/ndnd/cmd"
dv "github.com/named-data/ndnd/dv/executor"
fw "github.com/named-data/ndnd/fw/executor"
"github.com/named-data/ndnd/std/utils"
tools "github.com/named-data/ndnd/tools"
dvc "github.com/named-data/ndnd/tools/dvc"
nfdc "github.com/named-data/ndnd/tools/nfdc"
)

func main() {
// subtrees from other packages
nfdcTree := nfdc.GetNfdcCmdTree()

// create a command tree
tree := cmd.CmdTree{
tree := utils.CmdTree{
Name: "ndnd",
Help: "Named Data Networking Daemon",
Sub: []*cmd.CmdTree{{
Sub: []*utils.CmdTree{{
Name: "fw",
Help: "NDN Forwarding Daemon",
Sub: []*cmd.CmdTree{{
Sub: append([]*utils.CmdTree{{
Name: "run",
Help: "Start the NDN Forwarding Daemon",
Fun: fw.Main,
}},
}, {},
}, nfdcTree.Sub...),
}, {
Name: "dv",
Help: "NDN Distance Vector Routing Daemon",
Sub: []*cmd.CmdTree{{
Sub: []*utils.CmdTree{{
Name: "run",
Help: "Start the NDN Distance Vector Routing Daemon",
Fun: dv.Main,
}, {}, {
Name: "link create",
Help: "Create a new active neighbor link",
Fun: dvc.RunDvLinkCreate(&nfdcTree),
}, {
Name: "link destroy",
Help: "Destroy an active neighbor link",
Fun: dvc.RunDvLinkDestroy(&nfdcTree),
}},
}, {
// tools separator
Expand Down
18 changes: 15 additions & 3 deletions dv/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type Config struct {
// Prefix Table Data Prefix
pfxDataPfxN enc.Name
// NLSR readvertise prefix
readvertisePfxN enc.Name
localPfxN enc.Name
}

func DefaultConfig() *Config {
Expand Down Expand Up @@ -103,7 +103,7 @@ func (c *Config) Parse() (err error) {
enc.NewStringComponent(enc.TypeKeywordNameComponent, "DV"),
enc.NewStringComponent(enc.TypeKeywordNameComponent, "PFX"),
)
c.readvertisePfxN = append(Localhost,
c.localPfxN = append(Localhost,
enc.NewStringComponent(enc.TypeGenericNameComponent, "nlsr"),
)

Expand Down Expand Up @@ -142,8 +142,20 @@ func (c *Config) PrefixTableDataPrefix() enc.Name {
return c.pfxDataPfxN
}

func (c *Config) LocalPrefix() enc.Name {
return c.localPfxN
}

func (c *Config) ReadvertisePrefix() enc.Name {
return c.readvertisePfxN
return append(c.localPfxN,
enc.NewStringComponent(enc.TypeGenericNameComponent, "rib"),
)
}

func (c *Config) StatusPrefix() enc.Name {
return append(c.localPfxN,
enc.NewStringComponent(enc.TypeGenericNameComponent, "status"),
)
}

func (c *Config) AdvertisementSyncInterval() time.Duration {
Expand Down
6 changes: 1 addition & 5 deletions dv/dv.sample.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
nfd:
# [optional] Unix socket used to connect to the local forwarder
unix: /var/run/nfd/nfd.sock

config:
dv:
# [required] Global prefix for all DV routers in the network
network: /ndn
# [required] Unique name for each router in the network
Expand Down
11 changes: 10 additions & 1 deletion dv/dv/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,22 @@ func (dv *Router) register() (err error) {
return err
}

// Router status
err = dv.engine.AttachHandler(dv.config.StatusPrefix(),
func(args ndn.InterestHandlerArgs) {
go dv.statusOnInterest(args)
})
if err != nil {
return err
}

// Register routes to forwarder
pfxs := []enc.Name{
dv.config.AdvertisementSyncPrefix(),
dv.config.AdvertisementDataPrefix(),
dv.config.PrefixTableSyncPrefix(),
dv.config.PrefixTableDataPrefix(),
dv.config.ReadvertisePrefix(),
dv.config.LocalPrefix(),
}
for _, prefix := range pfxs {
dv.nfdc.Exec(nfdc.NfdMgmtCmd{
Expand Down
34 changes: 34 additions & 0 deletions dv/dv/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package dv

import (
"time"

"github.com/named-data/ndnd/dv/tlv"
"github.com/named-data/ndnd/std/log"
"github.com/named-data/ndnd/std/ndn"
"github.com/named-data/ndnd/std/security"
"github.com/named-data/ndnd/std/utils"
)

// Received advertisement Interest
func (dv *Router) statusOnInterest(args ndn.InterestHandlerArgs) {
status := tlv.Status{
NetworkName: &tlv.Destination{Name: dv.config.NetworkName()},
RouterName: &tlv.Destination{Name: dv.config.RouterName()},
}

name := args.Interest.Name()
cfg := &ndn.DataConfig{
ContentType: utils.IdPtr(ndn.ContentTypeBlob),
Freshness: utils.IdPtr(time.Second),
}
signer := security.NewSha256Signer()

data, err := dv.engine.Spec().MakeData(name, cfg, status.Encode(), signer)
if err != nil {
log.Warnf("readvertise: failed to make response Data: %+v", err)
return
}

args.Reply(data.Wire)
}
17 changes: 5 additions & 12 deletions dv/executor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,13 @@ import (
)

type DvConfig struct {
// NFD related options
Nfd struct {
Unix string `json:"unix"`
} `json:"nfd"`

// Underlying configuration
Config *config.Config `json:"config"`
Config *config.Config `json:"dv"`
}

func DefaultConfig() DvConfig {
dc := DvConfig{}
dc.Nfd.Unix = "/var/run/nfd/nfd.sock"
dc.Config = config.DefaultConfig()
return dc
return DvConfig{
Config: config.DefaultConfig(),
}
}

func (dc DvConfig) Parse() error {
Expand All @@ -45,7 +38,7 @@ func NewDvExecutor(dc DvConfig) (*DvExecutor, error) {
}

// Start NDN engine
dve.engine = engine.NewBasicEngine(engine.NewUnixFace(dc.Nfd.Unix))
dve.engine = engine.NewBasicEngine(engine.NewDefaultFace())

// Create the DV router
dve.router, err = dv.NewRouter(dc.Config, dve.engine)
Expand Down
2 changes: 1 addition & 1 deletion dv/nfdc/nfdc.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (m *NfdMgmtThread) Start() {
select {
case cmd := <-m.channel:
for i := 0; i < cmd.Retries || cmd.Retries < 0; i++ {
err := m.engine.ExecMgmtCmd(cmd.Module, cmd.Cmd, cmd.Args)
_, err := m.engine.ExecMgmtCmd(cmd.Module, cmd.Cmd, cmd.Args)
if err != nil {
log.Errorf("nfdc %s %s failed: %s %+v [%d]", cmd.Module, cmd.Cmd, cmd.Args.Name, err, i)
time.Sleep(100 * time.Millisecond)
Expand Down
12 changes: 7 additions & 5 deletions dv/table/neighbor_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,18 @@ func (ns *NeighborState) IsDead() bool {
// and update the last seen time for the neighbor.
// Return => true if the face ID has changed
func (ns *NeighborState) RecvPing(faceId uint64, active bool) (error, bool) {
if ns.isFaceActive && !active {
// This ping is passive, but we already have an active ping.
return nil, false // ignore this ping.
}

// Update last seen time for neighbor
// Note that we skip this when the face is active and the ping is passive.
// This is because we want to detect if the active face is removed.
ns.lastSeen = time.Now()

// If face ID has changed, re-register face.
if ns.faceId != faceId {
if ns.isFaceActive && !active {
// This ping is passive, but we already have an active ping.
return nil, false // ignore this ping.
}

ns.isFaceActive = active
log.Infof("neighbor: %s face ID changed from %d to %d", ns.Name, ns.faceId, faceId)
ns.routeUnregister()
Expand Down
7 changes: 7 additions & 0 deletions dv/tlv/tlv.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,10 @@ type PrefixOpRemove struct {
//+field:name
Name enc.Name `tlv:"0x07"`
}

type Status struct {
//+field:struct:Destination
NetworkName *Destination `tlv:"0x191"`
//+field:struct:Destination
RouterName *Destination `tlv:"0x193"`
}
Loading

0 comments on commit 6a31c07

Please sign in to comment.