Skip to content

Commit 7f17d5c

Browse files
authored
Merge branch 'dv2' into dv2
2 parents ff70f8c + 7ac25fb commit 7f17d5c

14 files changed

Lines changed: 301 additions & 47 deletions

File tree

.github/workflows/test.yml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ jobs:
1818
go-version-file: go.mod
1919

2020
- name: Build
21-
run: make
21+
run: |
22+
make
23+
make examples
2224
2325
- name: Test
2426
run: make test
@@ -28,6 +30,11 @@ jobs:
2830
name: ndnd
2931
path: ndnd
3032

33+
- uses: actions/upload-artifact@v4
34+
with:
35+
name: alo-latest
36+
path: .bin/alo-latest
37+
3138
lint:
3239
runs-on: ubuntu-latest
3340

@@ -49,6 +56,7 @@ jobs:
4956
e2e:
5057
needs: test
5158
runs-on: ubuntu-latest
59+
timeout-minutes: 30
5260

5361
container:
5462
image: ghcr.io/named-data/mini-ndn:master
@@ -63,13 +71,21 @@ jobs:
6371
name: ndnd
6472
path: /usr/bin/
6573

74+
- uses: actions/download-artifact@v4
75+
with:
76+
name: alo-latest
77+
path: /usr/bin/
78+
6679
- name: Mark ndnd as executable
67-
run: chmod +x /usr/bin/ndnd
80+
run: |
81+
chmod +x /usr/bin/ndnd
82+
chmod +x /usr/bin/alo-latest
6883
6984
- name: Copy ndnd to e2e's bin folder
7085
run: |
7186
mkdir .bin/
7287
cp /usr/bin/ndnd .bin/
88+
cp /usr/bin/alo-latest .bin/
7389
7490
- name: Run e2e tests
7591
run: make e2e

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
VERSION= $(shell git describe --tags --always --dirty)
22
STD_PACKAGE = github.com/named-data/ndnd/std
33

4-
.PHONY: all install clean test coverage e2e
4+
.PHONY: all install clean test coverage e2e examples
55

66
all: ndnd
77

@@ -10,6 +10,12 @@ ndnd: clean
1010
-ldflags "-X '${STD_PACKAGE}/utils.NDNdVersion=${VERSION}'" \
1111
cmd/ndnd/main.go
1212

13+
examples: .bin/alo-latest
14+
15+
.bin/alo-latest: std/examples/svs/alo-latest/main.go
16+
mkdir -p .bin/
17+
go build -o .bin/alo-latest std/examples/svs/alo-latest/main.go
18+
1319
generate:
1420
go generate ./...
1521

dv/config/config.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@ var MulticastStrategy = enc.LOCALHOST.
2727
Append(enc.NewGenericComponent("strategy")).
2828
Append(enc.NewGenericComponent("multicast"))
2929

30+
var BroadcastStrategy = enc.LOCALHOST.
31+
Append(enc.NewGenericComponent("nfd")).
32+
Append(enc.NewGenericComponent("strategy")).
33+
Append(enc.NewGenericComponent("broadcast"))
34+
35+
var ReplicastStrategy = enc.LOCALHOST.
36+
Append(enc.NewGenericComponent("nfd")).
37+
Append(enc.NewGenericComponent("strategy")).
38+
Append(enc.NewGenericComponent("replicast"))
39+
3040
//go:embed schema.tlv
3141
var SchemaBytes []byte
3242

dv/dv/router.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -315,15 +315,15 @@ func (dv *Router) register() (err error) {
315315
},
316316
Retries: -1,
317317
})
318-
// Set strategy to multicast for advertisement sync Interests, so
318+
// Set strategy to broadcast for advertisement sync Interests, so
319319
// /localhop/.../DV/ADS traffic fan-outs to all neighbor nexthops.
320320
dv.nfdc.Exec(nfdc.NfdMgmtCmd{
321321
Module: "strategy-choice",
322322
Cmd: "set",
323323
Args: &mgmt.ControlArgs{
324324
Name: dv.config.AdvertisementSyncPrefix(),
325325
Strategy: &mgmt.Strategy{
326-
Name: config.MulticastStrategy,
326+
Name: config.BroadcastStrategy,
327327
},
328328
},
329329
Retries: -1,
@@ -334,7 +334,7 @@ func (dv *Router) register() (err error) {
334334
Args: &mgmt.ControlArgs{
335335
Name: dv.pfx.SyncPrefix(),
336336
Strategy: &mgmt.Strategy{
337-
Name: config.MulticastStrategy,
337+
Name: config.BroadcastStrategy,
338338
},
339339
},
340340
Retries: -1,

e2e/run_scenario.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ def ensure_local_ndnd(repo_root: Path) -> None:
1616
local_bin = repo_root / ".bin"
1717
local_ndnd = local_bin / "ndnd"
1818
local_bin.mkdir(parents=True, exist_ok=True)
19-
info("Building local ndnd binary for E2E scenario\n")
20-
subprocess.check_call(
21-
["go", "build", "-o", str(local_ndnd), "./cmd/ndnd"],
22-
cwd=repo_root,
23-
)
19+
if not local_ndnd.exists():
20+
info("Building local ndnd binary for E2E scenario\n")
21+
subprocess.check_call(
22+
["go", "build", "-o", str(local_ndnd), "./cmd/ndnd"],
23+
cwd=repo_root,
24+
)
2425
os.environ["PATH"] = f"{local_bin}:{os.environ.get('PATH', '')}"
2526

2627

@@ -37,7 +38,6 @@ def main():
3738
ensure_local_ndnd(repo_root)
3839

3940
setLogLevel("info")
40-
random.seed(0)
4141

4242
Minindn.cleanUp()
4343
Minindn.verifyDependencies()
@@ -49,6 +49,8 @@ def main():
4949
scenario = getattr(mod, "scenario")
5050
sig = inspect.signature(scenario)
5151

52+
random.seed(0)
53+
5254
info("===================================================\n")
5355
start = time.time()
5456
if "network" in sig.parameters:

e2e/test_001.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,22 @@ def scenario(ndn: Minindn, network='/minindn'):
5858
if f'/localhop{network}/' in fib and '/32=DV' in fib:
5959
raise Exception(f'Router-specific localhop DV entries unexpectedly present in FIB on {node.name}')
6060

61+
# Validate the deprecation of multicast in DV code (#174)
62+
for node in ndn.net.hosts:
63+
strategy = node.cmd('ndnd fw strategy-list')
64+
if "multicast" in strategy:
65+
raise Exception(f'Multicast is to be retired, unexpectedly present in strategy on {node.name}')
66+
expected_strategies = [
67+
# Localhop SVS sync interests should use broadcast (#174)
68+
"prefix=/minindn/32=DV/32=PES/32=svs strategy=/localhost/nfd/strategy/broadcast/v=1",
69+
70+
# Localhop advertisement sync interests should use broadcast strategy (#174)
71+
"prefix=/localhop/minindn/32=DV/32=ADS strategy=/localhost/nfd/strategy/broadcast/v=1",
72+
]
73+
for expected_strat in expected_strategies:
74+
if expected_strat not in strategy:
75+
raise Exception(f'Strategy {expected_strat!r} not in strategy on {node.name}')
76+
6177
for node, put_node in cat_requests:
6278
cmd = f'ndnd cat "{network}/{put_node.name}/test" > recv.test.bin 2> cat.log'
6379
info(f'{node.name} {cmd}\n')

fw/defn/name.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ var NON_LOCAL_PREFIX = enc.Name{enc.LOCALHOP, enc.NewGenericComponent("nfd")}
1111
// Prefix for all stratgies
1212
var STRATEGY_PREFIX = LOCAL_PREFIX.Append(enc.NewGenericComponent("strategy"))
1313

14-
// Default forwarding strategy name
15-
var DEFAULT_STRATEGY = STRATEGY_PREFIX.
14+
var BEST_ROUTE_STRATEGY = STRATEGY_PREFIX.
1615
Append(enc.NewGenericComponent("best-route")).
1716
Append(enc.NewVersionComponent(1))
17+
18+
// Default forwarding strategy name
19+
var DEFAULT_STRATEGY = BEST_ROUTE_STRATEGY

fw/fw/bestroute.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
"github.com/named-data/ndnd/fw/core"
1515
"github.com/named-data/ndnd/fw/defn"
1616
"github.com/named-data/ndnd/fw/table"
17-
enc "github.com/named-data/ndnd/std/encoding"
1817
)
1918

2019
// BestRouteSuppressionTime is the time to suppress retransmissions of the same Interest.
@@ -65,23 +64,24 @@ func (s *BestRoute) AfterReceiveInterest(
6564
packet *defn.Pkt,
6665
pitEntry table.PitEntry,
6766
inFace uint64,
68-
nexthops []*table.FibNextHopEntry,
69-
nextER []enc.Name,
67+
nexthops []StrategyCandidateHop,
7068
) {
7169
if len(nexthops) == 0 {
7270
core.Log.Debug(s, "No nexthop found - DROP", "name", packet.Name)
7371
return
7472
}
7573

76-
// Sort nexthops by cost and send to best-possible nexthop
77-
sort.Slice(nexthops, func(i, j int) bool { return nexthops[i].Cost < nexthops[j].Cost })
74+
// sort nexthops by cost and send to best-possible hop for each unique ER
75+
sort.Slice(nexthops, func(i, j int) bool {
76+
return nexthops[i].HopEntry.Cost < nexthops[j].HopEntry.Cost
77+
})
7878

7979
now := time.Now()
8080
for pass := range 2 {
81-
for i, nh := range nexthops {
81+
for _, nh := range nexthops {
8282
// In the first pass, skip hops that already have a out record
8383
if pass == 0 {
84-
if oR := pitEntry.OutRecords()[nh.Nexthop]; oR != nil {
84+
if oR := pitEntry.OutRecords()[nh.HopEntry.Nexthop]; oR != nil {
8585
// Suppress retransmissions of the same Interest within suppression time
8686
if oR.LatestTimestamp.Add(BestRouteSuppressionTime).After(now) {
8787
core.Log.Debug(s, "Suppressed Interest - DROP", "name", packet.Name)
@@ -97,19 +97,17 @@ func (s *BestRoute) AfterReceiveInterest(
9797
// But then we need to resort the list - this is just faster for now.
9898
// In densely connected networks, this is not a big deal.
9999

100-
core.Log.Trace(s, "Forwarding Interest", "name", packet.Name, "faceid", nh.Nexthop)
100+
core.Log.Trace(s, "Forwarding Interest", "name", packet.Name, "faceid", nh.HopEntry.Nexthop)
101101

102102
// if there is an associated EgressRouter tag with this new route, then set packet.EgressRouter to the tag
103-
if i < len(nextER) {
104-
oldEgress := packet.EgressRouter
105-
packet.EgressRouter = nextER[i]
106-
if sent := s.SendInterest(packet, pitEntry, nh.Nexthop, inFace); sent {
103+
if nh.EgressRouter != nil {
104+
packet.EgressRouter = nh.EgressRouter
105+
if sent := s.SendInterest(packet, pitEntry, nh.HopEntry.Nexthop, inFace); sent {
107106
return
108107
}
109-
packet.EgressRouter = oldEgress
110108
// otherwise, normal forwarding
111109
} else {
112-
if sent := s.SendInterest(packet, pitEntry, nh.Nexthop, inFace); sent {
110+
if sent := s.SendInterest(packet, pitEntry, nh.HopEntry.Nexthop, inFace); sent {
113111
return
114112
}
115113
}

fw/fw/broadcast.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/**
2+
* Broadcast forwarding strategy.
3+
*
4+
* Using this strategy, the interest packet will be forwarded to all nexthops.
5+
*/
6+
7+
package fw
8+
9+
import (
10+
"github.com/named-data/ndnd/fw/core"
11+
"github.com/named-data/ndnd/fw/defn"
12+
"github.com/named-data/ndnd/fw/table"
13+
)
14+
15+
// The strategy to forward interests to all nexthops.
16+
type Broadcast struct {
17+
StrategyBase
18+
}
19+
20+
// (AI GENERATED DESCRIPTION): Registers the Broadcast strategy with version 1 in the strategy registry by appending its constructor to the init list.
21+
func init() {
22+
strategyInit = append(strategyInit, func() Strategy { return &Broadcast{} })
23+
StrategyVersions["broadcast"] = []uint64{1}
24+
}
25+
26+
// (AI GENERATED DESCRIPTION): Initializes the *Broadcast strategy by setting up its base with the name “broadcast” and priority 1 on the provided forwarding thread.
27+
func (s *Broadcast) Instantiate(fwThread *Thread) {
28+
s.NewStrategyBase(fwThread, "broadcast", 1)
29+
}
30+
31+
// (AI GENERATED DESCRIPTION): Sends a cached Data packet (retrieved from the Content Store) back to the requester via the specified PIT entry, using the requesting face and indicating the Content Store as the data source.
32+
func (s *Broadcast) AfterContentStoreHit(
33+
packet *defn.Pkt,
34+
pitEntry table.PitEntry,
35+
inFace uint64,
36+
) {
37+
core.Log.Trace(s, "AfterContentStoreHit", "name", packet.Name, "faceid", inFace)
38+
s.SendData(packet, pitEntry, inFace, 0) // 0 indicates ContentStore is source
39+
}
40+
41+
// (AI GENERATED DESCRIPTION): Forwards a received Data packet to every face recorded in the PIT entry, logging each forwarding step and invoking SendData for each destination.
42+
func (s *Broadcast) AfterReceiveData(
43+
packet *defn.Pkt,
44+
pitEntry table.PitEntry,
45+
inFace uint64,
46+
) {
47+
core.Log.Trace(s, "AfterReceiveData", "name", packet.Name, "inrecords", len(pitEntry.InRecords()))
48+
for faceID := range pitEntry.InRecords() {
49+
core.Log.Trace(s, "Forwarding Data", "name", packet.Name, "faceid", faceID)
50+
s.SendData(packet, pitEntry, faceID, inFace)
51+
}
52+
}
53+
54+
// Forwards an incoming Interest to all next-hops
55+
func (s *Broadcast) AfterReceiveInterest(
56+
packet *defn.Pkt,
57+
pitEntry table.PitEntry,
58+
inFace uint64,
59+
nexthops []StrategyCandidateHop,
60+
) {
61+
if len(nexthops) == 0 {
62+
core.Log.Debug(s, "No nexthop found - DROP", "name", packet.Name)
63+
return
64+
}
65+
66+
successfulForward := false
67+
68+
for _, nh := range nexthops {
69+
if sent := s.SendInterest(packet, pitEntry, nh.HopEntry.Nexthop, inFace); sent {
70+
core.Log.Trace(s, "Forwarded Interest", "name", packet.Name, "faceid", nh.HopEntry.Nexthop)
71+
successfulForward = true
72+
} else {
73+
core.Log.Trace(s, "Error forwarding interest", "name", packet.Name, "faceid", nh.HopEntry.Nexthop)
74+
}
75+
}
76+
77+
if !successfulForward {
78+
core.Log.Debug(s, "No usable nexthop for Interest - DROP", "name", packet.Name)
79+
}
80+
}
81+
82+
// (AI GENERATED DESCRIPTION): No‑op hook invoked before satisfying an Interest in the Broadcast strategy – it performs no action.
83+
func (s *Broadcast) BeforeSatisfyInterest(pitEntry table.PitEntry, inFace uint64) {
84+
// This does nothing in Broadcast
85+
}

fw/fw/multicast.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"github.com/named-data/ndnd/fw/core"
1414
"github.com/named-data/ndnd/fw/defn"
1515
"github.com/named-data/ndnd/fw/table"
16-
enc "github.com/named-data/ndnd/std/encoding"
1716
)
1817

1918
// MulticastSuppressionTime is the time to suppress retransmissions of the same Interest.
@@ -64,8 +63,7 @@ func (s *Multicast) AfterReceiveInterest(
6463
packet *defn.Pkt,
6564
pitEntry table.PitEntry,
6665
inFace uint64,
67-
nexthops []*table.FibNextHopEntry,
68-
nextER []enc.Name,
66+
nexthops []StrategyCandidateHop,
6967
) {
7068
if len(packet.Bier) > 0 {
7169
bierReplicate(s, packet, pitEntry, inFace, s.SendInterest)
@@ -87,8 +85,8 @@ func (s *Multicast) AfterReceiveInterest(
8785
}
8886

8987
for _, nexthop := range nexthops {
90-
core.Log.Trace(s, "Forwarding Interest", "name", packet.Name, "faceid", nexthop.Nexthop)
91-
s.SendInterest(packet, pitEntry, nexthop.Nexthop, inFace)
88+
core.Log.Trace(s, "Forwarding Interest", "name", packet.Name, "faceid", nexthop.HopEntry.Nexthop)
89+
s.SendInterest(packet, pitEntry, nexthop.HopEntry.Nexthop, inFace)
9290
}
9391
}
9492

0 commit comments

Comments
 (0)