Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
dd39ff5
fw: bier works now with merged code
r2dev2 Mar 19, 2026
61f60d4
fw: initial refactor into pipeline structure
r2dev2 Mar 23, 2026
bfd0dac
fw: use PET multicast flag on sync / advertisement rather than strategy
r2dev2 Mar 24, 2026
cc00471
fw: get rid of isDvSvs and isDvAdvLocalhop overrides
r2dev2 Mar 24, 2026
70dc41c
fw: add string reprs for the pipeline
r2dev2 Mar 24, 2026
6732a82
dv: add retry to execMgmt to properly add egress routes for adv svs
r2dev2 Mar 24, 2026
9e1d9be
fw: remove isLocalHop && !petFound impossible branch
r2dev2 Mar 24, 2026
681158b
fw: remove unused twoPhaseLookup fn
r2dev2 Mar 24, 2026
42eae17
fw: distinguish fwMulticastEgress from fwMulticastTransit if there is…
r2dev2 Mar 24, 2026
7847c86
fw: fix localhop check
r2dev2 Mar 24, 2026
046407b
fw: revert a check that was breaking multicast
r2dev2 Mar 31, 2026
cc287f0
fw: some comments
r2dev2 Mar 31, 2026
0302bc4
fw: implement table to identify multicast forwarding strategy
r2dev2 Mar 31, 2026
da41f16
fw: refactor multicast into a strategy dispatch table
r2dev2 Mar 31, 2026
08d4d0e
fw: extract local delivery logic for multicast out of mcast strategy
r2dev2 Mar 31, 2026
685f287
fw: delete replicast (doesnt work with 3-pipeline forwarding) + remov…
r2dev2 Mar 31, 2026
a7b8496
fw: remove fallback which was not originally present
r2dev2 Mar 31, 2026
667d517
fw: remove early fibstrategy lookup present for AfterContentStoreHit
r2dev2 Mar 31, 2026
1503b52
e2e: pet prefix ready deadline of 180 for ci
r2dev2 Mar 31, 2026
87fec4d
fw: filter out forwarding to incoming faceid
r2dev2 Mar 31, 2026
f60356c
ci: collect minindn e2e logs on failure
r2dev2 Apr 1, 2026
723c4cd
fw: broadcast send to all faces in fib instead of by pet er lookup
r2dev2 Apr 3, 2026
68b2c38
fw: refactor out duplicated multicast-strategy-choice into strategy-c…
r2dev2 Apr 3, 2026
4541b7a
dv: get rid of retries param in helper fn
r2dev2 Apr 3, 2026
8bdae7e
dv: explicit multicast flag in pet mgmt cmd
r2dev2 Apr 3, 2026
7e8a30d
std: use new multicast arg in client announce
r2dev2 Apr 6, 2026
8ecfdab
fw: remove bier empty sanity check
r2dev2 Apr 6, 2026
3786b71
fw: name broadcast file
r2dev2 Apr 6, 2026
2d9774a
dv: simplify retry loop
r2dev2 Apr 6, 2026
11ed32f
fw: switch on strategy choice kind
r2dev2 Apr 6, 2026
8f60368
fw: incorporate strategy verification logic for multicast
r2dev2 Apr 6, 2026
f90c2f4
fw: switch in strategy choice String
r2dev2 Apr 6, 2026
7d15225
fw: move bier into contained package
r2dev2 Apr 6, 2026
ecf7169
fw: standardize bier strategy name in fw/fw
r2dev2 Apr 6, 2026
4439d76
ci: upload log artifact in zip form for granular unzipping
r2dev2 Apr 13, 2026
a429eca
dv: use execMgmtRetry for adding fib nexthop for registering neighbor…
r2dev2 Apr 13, 2026
df243eb
e2e: use info loglevel to not exhaust ci compute/storage
r2dev2 Apr 13, 2026
799fcca
fw: do not send to same faceid twice in broadcast
r2dev2 Apr 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,10 @@ jobs:

- name: Run e2e tests
run: make e2e

- name: Upload minindn logs on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: minindn-logs
path: /tmp/minindn
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ ndnd: clean
CGO_ENABLED=0 go build -o ndnd \
-ldflags "-X '${STD_PACKAGE}/utils.NDNdVersion=${VERSION}'" \
cmd/ndnd/main.go
mkdir -p .bin/
cp ndnd .bin/

examples: .bin/alo-latest

Expand Down
5 changes: 0 additions & 5 deletions dv/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,6 @@ var BroadcastStrategy = enc.LOCALHOST.
Append(enc.NewGenericComponent("strategy")).
Append(enc.NewGenericComponent("broadcast"))

var ReplicastStrategy = enc.LOCALHOST.
Append(enc.NewGenericComponent("nfd")).
Append(enc.NewGenericComponent("strategy")).
Append(enc.NewGenericComponent("replicast"))

//go:embed schema.tlv
var SchemaBytes []byte

Expand Down
2 changes: 1 addition & 1 deletion dv/dv/mgmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ func (dv *Router) mgmtOnPrefix(args ndn.InterestHandlerArgs) {
responseParams.ExpirationPeriod = optional.Some(expires)
}

multicast := params.Val.Flags.GetOr(0)&1 != 0
multicast := params.Val.Multicast
dv.mutex.Lock()
dv.pfx.Announce(name, faceID, cost, multicast, validity)
dv.mutex.Unlock()
Expand Down
3 changes: 1 addition & 2 deletions dv/dv/prefix.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,9 +425,8 @@ func (pfx *PrefixModule) applyPetOps(ops []petEgressOp) {
}
if op.add {
cmd = "add-egress"
// Signal the Sync group (multicast) flag to the forwarder's PET via Flags bit 0.
if op.multicast {
args.Flags = optional.Some(uint64(1))
args.Multicast = true
}
}

Expand Down
95 changes: 39 additions & 56 deletions dv/dv/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/named-data/ndnd/dv/config"
"github.com/named-data/ndnd/dv/nfdc"
"github.com/named-data/ndnd/dv/table"
"github.com/named-data/ndnd/fw/defn"
enc "github.com/named-data/ndnd/std/encoding"
"github.com/named-data/ndnd/std/log"
"github.com/named-data/ndnd/std/ndn"
Expand Down Expand Up @@ -285,64 +286,51 @@ func (dv *Router) register() (err error) {
}

for _, prefix := range pfxs {
dv.nfdc.Exec(nfdc.NfdMgmtCmd{
Module: "pet",
Cmd: "add-nexthop",
Args: &mgmt.ControlArgs{
Name: prefix,
},
Retries: -1,
dv.execMgmtRetry("pet", "add-nexthop", &mgmt.ControlArgs{
Name: prefix,
})
}
// Allow outgoing local-prefix-sync Interests to use two-phase forwarding.
// Incoming Interests still terminate locally on the same prefix.
dv.nfdc.Exec(nfdc.NfdMgmtCmd{
Module: "pet",
Cmd: "add-egress",
Args: &mgmt.ControlArgs{
Name: dv.pfx.SyncPrefix(),
Egress: &mgmt.EgressRecord{Name: neighborsPrefix.Clone()},
},
Retries: -1,
dv.execMgmtRetry("pet", "add-egress", &mgmt.ControlArgs{
Name: dv.pfx.SyncPrefix(),
Egress: &mgmt.EgressRecord{Name: neighborsPrefix.Clone()},
Multicast: true,
})
// Set Advertisement Sync to localhop neighbors
dv.nfdc.Exec(nfdc.NfdMgmtCmd{
Module: "pet",
Cmd: "add-egress",
Args: &mgmt.ControlArgs{
Name: dv.config.AdvertisementSyncPrefix(),
Egress: &mgmt.EgressRecord{Name: neighborsPrefix.Clone()},
},
Retries: -1,
})
// Set strategy to broadcast for advertisement sync Interests, so
// /localhop/.../DV/ADS traffic fan-outs to all neighbor nexthops.
dv.nfdc.Exec(nfdc.NfdMgmtCmd{
Module: "strategy-choice",
Cmd: "set",
Args: &mgmt.ControlArgs{
Name: dv.config.AdvertisementSyncPrefix(),
Strategy: &mgmt.Strategy{
Name: config.BroadcastStrategy,
},
},
Retries: -1,
})
dv.nfdc.Exec(nfdc.NfdMgmtCmd{
Module: "strategy-choice",
Cmd: "set",
Args: &mgmt.ControlArgs{
Name: dv.pfx.SyncPrefix(),
Strategy: &mgmt.Strategy{
Name: config.BroadcastStrategy,
},
},
Retries: -1,
dv.execMgmtRetry("pet", "add-egress", &mgmt.ControlArgs{
Name: dv.config.AdvertisementSyncPrefix(),
Egress: &mgmt.EgressRecord{Name: neighborsPrefix.Clone()},
Multicast: true,
})

// Force multicast strategy for sync prefixes to broadcast.
broadcastPrefixes := []enc.Name{
dv.pfx.SyncPrefix(),
dv.config.AdvertisementSyncPrefix(),
}
for _, prefix := range broadcastPrefixes {
dv.execMgmtRetry("multicast-strategy-choice", "set", &mgmt.ControlArgs{
Name: prefix,
Strategy: &mgmt.Strategy{Name: defn.BROADCAST_STRATEGY},
})
}

return nil
}

func (dv *Router) execMgmtRetry(module, cmd string, args *mgmt.ControlArgs) {
var err error
for i := 0; ; i++ {
if _, err = dv.engine.ExecMgmtCmd(module, cmd, args); err == nil {
break
}
log.Error(dv, "Forwarder command failed", "err", err, "attempt", i,
"module", module, "cmd", cmd, "args", args)
time.Sleep(100 * time.Millisecond)
}
}

// createFaces creates faces to all neighbors.
func (dv *Router) createFaces() {
neighborsPrefix := enc.LOCALHOP.Append(enc.NewGenericComponent("neighbors"))
Expand Down Expand Up @@ -370,15 +358,10 @@ func (dv *Router) createFaces() {
dv.mutex.Unlock()

// Add neighbor to localhop neighbors
dv.nfdc.Exec(nfdc.NfdMgmtCmd{
Module: "fib",
Cmd: "add-nexthop",
Args: &mgmt.ControlArgs{
Name: neighborsPrefix.Clone(),
Cost: optional.Some(uint64(1)),
FaceId: optional.Some(faceId),
},
Retries: 3,
dv.execMgmtRetry("fib", "add-nexthop", &mgmt.ControlArgs{
Name: neighborsPrefix.Clone(),
Cost: optional.Some(uint64(1)),
FaceId: optional.Some(faceId),
})
}
}
Expand Down
6 changes: 3 additions & 3 deletions dv/dv/table_algo.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package dv
import (
"github.com/named-data/ndnd/dv/config"
"github.com/named-data/ndnd/dv/table"
fw "github.com/named-data/ndnd/fw/fw"
"github.com/named-data/ndnd/fw/bier"
enc "github.com/named-data/ndnd/std/encoding"
"github.com/named-data/ndnd/std/log"
)
Expand Down Expand Up @@ -138,7 +138,7 @@ func (dv *Router) updateFib() {

// Rebuild the BIFT whenever the FIB changes so BIER forwarding paths
// are always consistent with the routing table.
if fw.IsBierEnabled() {
fw.Bift.BuildFromFib()
if bier.IsBierEnabled() {
bier.Bift.BuildFromFib()
}
}
2 changes: 1 addition & 1 deletion e2e/dv_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def is_converged(nodes: list[Node], network=DEFAULT_NETWORK, use_nfdc=False) ->
# We don't support that.
routes = node.cmd('nfdc route list')
else:
routes = node.cmd('ndnd fw route-list')
routes = node.cmd('ndnd fw route-list 2>&1')
for other in nodes:
if other == node:
continue
Expand Down
10 changes: 0 additions & 10 deletions e2e/test_001.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,6 @@ def scenario(ndn: Minindn, network='/minindn'):
strategy = node.cmd('ndnd fw strategy-list')
if "multicast" in strategy:
raise Exception(f'Multicast is to be retired, unexpectedly present in strategy on {node.name}')
expected_strategies = [
# Localhop SVS sync interests should use broadcast (#174)
"prefix=/minindn/32=DV/32=PES/32=svs strategy=/localhost/nfd/strategy/broadcast/v=1",

# Localhop advertisement sync interests should use broadcast strategy (#174)
"prefix=/localhop/minindn/32=DV/32=ADS strategy=/localhost/nfd/strategy/broadcast/v=1",
]
for expected_strat in expected_strategies:
if expected_strat not in strategy:
raise Exception(f'Strategy {expected_strat!r} not in strategy on {node.name}')

for node, put_node in cat_requests:
cmd = f'ndnd cat "{network}/{put_node.name}/test" > recv.test.bin 2> cat.log'
Expand Down
2 changes: 2 additions & 0 deletions e2e/test_007.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def scenario(ndn: Minindn, network='/minindn'):
producer_prefixes = {sync_prefix, f'{network}/svs/{producer.name}'}
dv_util.wait_prefix_pet_ready({node: producer_prefixes for node in consumers}, deadline=60)

beg = time.time()
# Step 5: Wait for publish → BIER sync interest propagation → unicast data fetch.
# 20s delay + 30s SVS sync cycle + 20s fetch buffer = 70s total.
info(f'Waiting for message propagation from {producer.name} (70s)...\n')
Expand All @@ -90,6 +91,7 @@ def scenario(ndn: Minindn, network='/minindn'):
for node in chat_nodes:
node.cmd("pkill -f 'ndnd svs-chat' 2>/dev/null; true")
time.sleep(1) # let log buffers flush
print(time.time() - beg, "seconds elapsed")

failures = []
for consumer in consumers:
Expand Down
Loading
Loading