Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add NSID to network identifiers #6453

Merged
merged 6 commits into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
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
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@ For details about compatibility between different releases, see the **Commitment

### Security

## [3.28.0] - unreleased

### Added

- The Network Server ID (NSID, EUI-64) used in LoRaWAN Backend Interfaces is now included in the application uplink message network metadata as well as in the Backend Interfaces `HomeNSAns` message that Identity Server returns to clients. The NSID is configurable via `is.network.ns-id`.

### Changed

### Deprecated

### Removed

### Fixed

### Security

## [3.27.0] - 2023-07-31

### Added
Expand Down
2 changes: 2 additions & 0 deletions api/ttn/lorawan/v3/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -5231,6 +5231,7 @@ Identifies a Network Server.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `net_id` | [`bytes`](#bytes) | | LoRa Alliance NetID. |
| `ns_id` | [`bytes`](#bytes) | | LoRaWAN NSID (EUI-64) that uniquely identifies the Network Server instance. |
| `tenant_id` | [`string`](#string) | | Optional tenant identifier for multi-tenant deployments. |
| `cluster_id` | [`string`](#string) | | Cluster identifier of the Network Server. |
| `cluster_address` | [`string`](#string) | | Cluster address of the Network Server. |
Expand All @@ -5241,6 +5242,7 @@ Identifies a Network Server.
| Field | Validations |
| ----- | ----------- |
| `net_id` | <p>`bytes.len`: `3`</p> |
| `ns_id` | <p>`bytes.len`: `8`</p> |
| `tenant_id` | <p>`string.max_len`: `36`</p><p>`string.pattern`: `^[a-z0-9](?:[-]?[a-z0-9]){2,}$|^$`</p> |
| `cluster_id` | <p>`string.max_len`: `64`</p> |
| `cluster_address` | <p>`string.max_len`: `256`</p> |
Expand Down
6 changes: 6 additions & 0 deletions api/ttn/lorawan/v3/api.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -23488,6 +23488,12 @@
"example": "000013",
"description": "LoRa Alliance NetID."
},
"ns_id": {
"type": "string",
"format": "string",
"example": "70B3D57ED000ABCD",
"description": "LoRaWAN NSID (EUI-64) that uniquely identifies the Network Server instance."
},
"tenant_id": {
"type": "string",
"description": "Optional tenant identifier for multi-tenant deployments."
Expand Down
20 changes: 20 additions & 0 deletions api/ttn/lorawan/v3/identifiers.proto
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,26 @@ message NetworkIdentifiers {
set_flag_getter_func: "go.thethings.network/lorawan-stack/v3/cmd/ttn-lw-cli/customflags.GetExactBytes"
}
];
// LoRaWAN NSID (EUI-64) that uniquely identifies the Network Server instance.
bytes ns_id = 6 [
(validate.rules).bytes = {
len: 8,
ignore_empty: true
},
(thethings.json.field) = {
marshaler_func: "go.thethings.network/lorawan-stack/v3/pkg/types.MarshalHEXBytes",
unmarshaler_func: "go.thethings.network/lorawan-stack/v3/pkg/types.Unmarshal8Bytes"
},
(thethings.flags.field) = {
set_flag_new_func: "go.thethings.network/lorawan-stack/v3/cmd/ttn-lw-cli/customflags.New8BytesFlag",
set_flag_getter_func: "go.thethings.network/lorawan-stack/v3/cmd/ttn-lw-cli/customflags.GetExactBytes"
},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
type: STRING,
format: "string",
example: "\"70B3D57ED000ABCD\""
}
];
// Optional tenant identifier for multi-tenant deployments.
string tenant_id = 2 [(validate.rules).string = {
pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$|^$",
Expand Down
5 changes: 3 additions & 2 deletions pkg/identityserver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,9 @@ type Config struct {
InitCounter int64 `name:"init-counter" description:"Initial counter value for the addresses to be issued (default 0)"`
} `name:"dev-eui-block" description:"IEEE MAC block used to issue DevEUIs to devices that are not yet programmed"`
Network struct {
NetID ttntypes.NetID `name:"net-id" description:"NetID of this network"`
TenantID string `name:"tenant-id" description:"Tenant ID in the host NetID"`
NetID ttntypes.NetID `name:"net-id" description:"NetID of this network"`
NSID *ttntypes.EUI64 `name:"ns-id" description:"NSID of this network (EUI)"`
TenantID string `name:"tenant-id" description:"Tenant ID"`
} `name:"network"`
TelemetryQueue telemetry.TaskQueue `name:"-"`
}
Expand Down
7 changes: 4 additions & 3 deletions pkg/identityserver/http_interop.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ func (srv *interopServer) HomeNSRequest(ctx context.Context, in *interop.HomeNSR
}

var (
conf = srv.configFromContext(ctx)
hNSID *types.EUI64
conf = srv.configFromContext(ctx)
hNetID = conf.Network.NetID
hNSID = conf.Network.NSID
)

header, err := in.AnswerHeader()
Expand All @@ -73,7 +74,7 @@ func (srv *interopServer) HomeNSRequest(ctx context.Context, in *interop.HomeNSR
Result: interop.Result{
ResultCode: interop.ResultSuccess,
},
HNetID: interop.NetID(conf.Network.NetID),
HNetID: interop.NetID(hNetID),
},
TTIVSExtension: interop.TTIVSExtension{
HNSAddress: dev.NetworkServerAddress,
Expand Down
2 changes: 1 addition & 1 deletion pkg/identityserver/http_interop_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2021 The Things Network Foundation, The Things Industries B.V.

Check warning on line 1 in pkg/identityserver/http_interop_test.go

View workflow job for this annotation

GitHub Actions / Check Mergeability

pkg/identityserver/http_interop_test.go has a conflict when merging TheThingsIndustries/lorawan-stack:v3.28.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -100,7 +100,7 @@
t.FailNow()
}
a.So(ans.HNetID, should.Equal, interop.NetID(test.DefaultNetID))
a.So(ans.HNSID, should.BeNil) // TODO: Return HNSID (https://github.com/TheThingsNetwork/lorawan-stack/issues/4741).
a.So(ans.HNSID, should.Resemble, (*interop.EUI64)(&test.DefaultNSID))

// Test an unknown device
_, err = srv.HomeNSRequest(ctx, &interop.HomeNSReq{
Expand Down
1 change: 1 addition & 0 deletions pkg/identityserver/identityserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ func defaultTestOptions() *testOptions {
testOptions.isConfig.DevEUIBlock.Enabled = true
testOptions.isConfig.DevEUIBlock.ApplicationLimit = 3
testOptions.isConfig.Network.NetID = test.DefaultNetID
testOptions.isConfig.Network.NSID = &test.DefaultNSID
testOptions.isConfig.Network.TenantID = "test"
return testOptions
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/networkserver/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ func (ns *NetworkServer) GetDefaultMACSettings(ctx context.Context, req *ttnpb.G
}

// GetNetID returns the NetID of the Network Server.
func (ns *NetworkServer) GetNetID(_ context.Context, _ *emptypb.Empty) (*ttnpb.GetNetIDResponse, error) {
func (ns *NetworkServer) GetNetID(ctx context.Context, _ *emptypb.Empty) (*ttnpb.GetNetIDResponse, error) {
return &ttnpb.GetNetIDResponse{
NetId: ns.netID[:],
NetId: ns.netID(ctx).Bytes(),
}, nil
}

Expand Down
8 changes: 4 additions & 4 deletions pkg/networkserver/grpc_gsns.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.

Check warning on line 1 in pkg/networkserver/grpc_gsns.go

View workflow job for this annotation

GitHub Actions / Check Mergeability

pkg/networkserver/grpc_gsns.go has a conflict when merging TheThingsIndustries/lorawan-stack:v3.28.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -842,7 +842,7 @@
mds := make([]*ttnpb.RxMetadata, 0, len(up.RxMetadata))
for _, md := range up.RxMetadata {
if pbMD := md.GetPacketBroker(); pbMD != nil {
if types.MustNetID(pbMD.ForwarderNetId).OrZero().Equal(ns.netID) &&
if types.MustNetID(pbMD.ForwarderNetId).OrZero().Equal(ns.netID(ctx)) &&
pbMD.ForwarderClusterId == ns.clusterID {
continue
}
Expand Down Expand Up @@ -1147,7 +1147,7 @@
}
if ns.interopClient != nil {
queuedEvents = append(queuedEvents, evtInteropJoinAttempt.NewWithIdentifiersAndData(ctx, ids, req))
resp, err := ns.interopClient.HandleJoinRequest(ctx, ns.netID, ns.interopNSID, req)
resp, err := ns.interopClient.HandleJoinRequest(ctx, ns.netID(ctx), ns.nsID(ctx), req)
if err == nil {
logger.Debug("Join-request accepted by interop Join Server")
queuedEvents = append(queuedEvents, evtInteropJoinSuccess.NewWithIdentifiersAndData(ctx, ids, joinResponseWithoutKeys(resp)))
Expand Down Expand Up @@ -1288,7 +1288,7 @@
CfList: cfList,
CorrelationIds: events.CorrelationIDsFromContext(ctx),
DevAddr: devAddr.Bytes(),
NetId: ns.netID.Bytes(),
NetId: ns.netID(ctx).Bytes(),
RawPayload: up.RawPayload,
RxDelay: macState.DesiredParameters.Rx1Delay,
SelectedMacVersion: matched.LorawanVersion, // Assume NS version is always higher than the version of the device
Expand Down Expand Up @@ -1327,7 +1327,7 @@
Keys: keys,
Payload: resp.RawPayload,
DevAddr: devAddr.Bytes(),
NetId: ns.netID.Bytes(),
NetId: ns.netID(ctx).Bytes(),
Request: &ttnpb.MACState_JoinRequest{
RxDelay: macState.DesiredParameters.Rx1Delay,
CfList: cfList,
Expand Down
28 changes: 24 additions & 4 deletions pkg/networkserver/networkserver.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.

Check warning on line 1 in pkg/networkserver/networkserver.go

View workflow job for this annotation

GitHub Actions / Check Mergeability

pkg/networkserver/networkserver.go has a conflict when merging TheThingsIndustries/lorawan-stack:v3.28.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -72,6 +72,26 @@
return func(ctx context.Context) time.Duration { return d }
}

// netIDFunc is a function, which is used by the Network Server to determine it's NetID.
johanstokking marked this conversation as resolved.
Show resolved Hide resolved
type netIDFunc func(ctx context.Context) types.NetID

// makeNetIDFunc returns a netIDFunc, which always returns netID.
func makeNetIDFunc(netID types.NetID) netIDFunc {
return func(ctx context.Context) types.NetID {
return netID
}
}

// nsIDFunc is a function, which is used by the Network Server to determine it's NSID.
type nsIDFunc func(ctx context.Context) *types.EUI64

// makeNSIDFunc returns a nsIDFunc, which always returns nsID.
func makeNSIDFunc(nsID *types.EUI64) nsIDFunc {
return func(ctx context.Context) *types.EUI64 {
return nsID
}
}

// newDevAddrFunc is a function, which is used by Network Server to derive new DevAddrs.
type newDevAddrFunc func(ctx context.Context, dev *ttnpb.EndDevice) types.DevAddr

Expand Down Expand Up @@ -129,7 +149,8 @@
devices DeviceRegistry
batchDevices *nsEndDeviceBatchRegistry

netID types.NetID
netID netIDFunc
nsID nsIDFunc
clusterID string
newDevAddr newDevAddrFunc
devAddrPrefixes devAddrPrefixesFunc
Expand All @@ -146,7 +167,6 @@
defaultMACSettings *ttnpb.MACSettings

interopClient InteropClient
interopNSID *types.EUI64

uplinkDeduplicator UplinkDeduplicator

Expand Down Expand Up @@ -245,7 +265,8 @@
ns := &NetworkServer{
Component: c,
ctx: ctx,
netID: conf.NetID,
netID: makeNetIDFunc(conf.NetID),
nsID: makeNSIDFunc(conf.Interop.ID),
clusterID: conf.ClusterID,
newDevAddr: makeNewDevAddrFunc(devAddrPrefixes...),
devAddrPrefixes: makeDevAddrPrefixesFunc(devAddrPrefixes...),
Expand All @@ -258,7 +279,6 @@
downlinkPriorities: downlinkPriorities,
defaultMACSettings: defaultMACSettings,
interopClient: interopCl,
interopNSID: conf.Interop.ID,
uplinkDeduplicator: conf.UplinkDeduplicator,
deviceKEKLabel: conf.DeviceKEKLabel,
downlinkQueueCapacity: conf.DownlinkQueueCapacity,
Expand Down
5 changes: 4 additions & 1 deletion pkg/networkserver/utils.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.

Check warning on line 1 in pkg/networkserver/utils.go

View workflow job for this annotation

GitHub Actions / Check Mergeability

pkg/networkserver/utils.go has a conflict when merging TheThingsIndustries/lorawan-stack:v3.28.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -427,8 +427,11 @@
func (ns *NetworkServer) networkIdentifiers(ctx context.Context) *ttnpb.NetworkIdentifiers {
clusterID := ns.clusterID
networkIDs := &ttnpb.NetworkIdentifiers{
NetId: ns.netID.Bytes(),
NetId: ns.netID(ctx).Bytes(),
ClusterId: clusterID,
}
if nsID := ns.nsID(ctx); nsID != nil {
networkIDs.NsId = nsID.Bytes()
}
return networkIDs
}
2 changes: 2 additions & 0 deletions pkg/ttnpb/applicationserver.pb.paths.fm.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading