This commit implements part of the OTBR firewall. This implementation
focuses on the ingress filtering part. We may also introduce egress
filtering part when necessary.
For security purpose, there are some packet forwarding rules to
follow, which were originally introduced in the spec.
- Inbound packets initiated with On-Link addresses source (OMR and
mesh local prefix based addresses) should be blocked.
- Inbound unicast packets whose destination address is not OMR address
or DUA should be blocked.
- Inbound unicast packets whose source address or destination address
is link-local should be blocked. Note that we don’t need to
explicitly add rules for link-local addresses since this should
already be handled by the kernel.
These rules can be easily implemented by iptables and ipset.
- Before otbr-agent starts, there is a script creating the iptables
rules. The rules themselves are constant so we don't need to change
them dynamically.
- During the runtime of otbr-agent, otbr-agent updates ipsets
accordingly whenever there's a change of on-link prefixes.
This commit uses a longer duration (10s) to make the test more
reliable.
The root cause why LEADER does not become Leader within 4s is still
unknown and to be investigated.
Some enhancements for cert test run:
- Use a different log name for every test run. With the help of this
we can get all logs & pcaps after running a test case when MULTIPLY
> MAX_JOBS.
- While running test cases, print a line showing the test case being
run.
Add steps which verify the bug fix contributed to OTBR:
https://github.com/openthread/ot-br-posix/pull/1020
That is, verify that SRP updates which modify both a host
and a service can be successfully completed.
Current implement will start evaluating on-link prefix before
successfully sending kMaxRtrSolicitations=3 RS messages. This commit
fixes this issue by retrying sending failed RS messages in
kRtrSolicitationRetryFailDelay=60 seconds.
This commit adds a new class `AnycastLocator` which can be used to
locate the closest destination of an anycast IPv6 address (i.e., find
the related mesh local EID and RLOC16). The closest destination is
determined based on the the current routing table and path costs
within the Thread mesh.
The implementation uses a CoAP confirmable post request to a newly
added URI path ("a/yl"). The destination IPv6 address of such as
request message is set to the anycast address to be located. The
receiver of the request message sends a CoAP response which includes
the "Mesh Local EID" and "Thread RLOC16" TLVs.
This commit also adds support this new feature in CLI (adding a new
`locate <anycast-addr>` command).
Finally this commit adds `test_anycast_locator.py` to test behavior of
the new feature.
This commit disallows concurrent commands.
With this commit, the CLI only execute a new command after it complete
the previous command. CLI can also prompt properly after the command
execution is done.
Other fixes and enhancements:
- Fixes premature command prompt
- Add ping async command for ping in async mode: output Done
immediately but print ping responses later on.
- Fixes networkdiagnostic get outputs multiple Done by always waiting
for 5 seconds.
This commit updates `Srp::Server` to add support for selecting its
address mode (unicast or anycast). The address mode specifies how the
SRP server determines its address and port number and how this info
is published in Thread Network Data.
In anycast address mode, the SRP server will use port number 53 which
is also used by DNS resolver/server. So if both `Srp::Server` and
`Dns::ServiceDiscovery::Server` are enabled on a device, they both
need to listen on the same port number and share the same UDP socket
instance. This commit adds the mechanism in the code to realize this.
The `Srp::Server` will monitor when/if DNS-SD is active and checks
whether the port numbers match and if so it will close its own socket
and re-use the one from DNS-SD. In this case, an incoming UDP message
is first given to `Srp::Server` to process and if it fails to process
it then the message is given to DNS-SD.
This commit also adds CLI commands under `srp server` to get/set the
address mode (and update the `README_SRP_SERVER.md` documentation).
It also adds a new test `test_srp_server_anycast_mode` which covers
the SRP server address mode and the newly added behaviors.
This commit fixes the test by removing the unnecessary argument
in the call to `srp_client_remove_host()`. Removing the host on
SRP client also removed all previously registered service so
we can remove the call to `client.srp_client_remove_service(...)`.
This commit adds a new parameter `aSendUnregToServer` to SRP client's
`RemoveHostAndServices()` API. This parameter determines the behavior
when the host info is not yet registered with the server. If it is
set to `false` (which is the default/expected value) then the SRP
client will immediately remove the host info and services without
sending an update message to server (no need to update the server if
nothing is yet registered with it). If it is set to `true` then the
SRP client will send an update message to the server. Note that if
the host info is registered then the value of `aSendUnregToServer`
does not matter and the SRP client will always send an update message
to the server requesting removal of all info.
One situation where this parameter can be useful is on a device
reset/reboot where the caller may want to remove any previously
registered services with the server. In this case, caller can
`SetHostName()` and then request `RemoveHostAndServices()` with
`aSendUnregToServer` as `true`.
This commit also adds `test_srp_client_remove_host.py` which
verifies the behavior the newly added mechanism between client and
server.
This commit updates the `test_netdata_publisher` to add extra wait
time between adds (where the same on-mesh prefix is published on all
routers). This should help make the test robust and avoid the
situation where publishing the same prefix on all routers all
together could cause the number of entries in the Network Data to
temporarily go above the desired number. This can happen (though not
often) due to the randomness in how/when nodes using `Publisher` add
their entry in the Network Data.
This commit updates `Mle::DiscoverScanner` to check that IPv6
interface is enabled from `Discover()` (returns `kErrorInvalidState`
if netif is not up).
This commit adds History Tracker feature and its CLI support. This
feature records history of different events as the Thread network
operates (e.g., history of RX and TX IPv6 messages or network info
changes).
Recorded entries are timestamped. When the history list is read, the
timestamps are given as the entry age relative to the time the list
is being read. For example in CLI a timestamp can be shown as
`02:31:50.628 ago` indicating the entry was recorded 2 hours, 31 min,
50 sec, and 628 msec ago. Number of days is added for events that are
older than 24 hours, e.g., `31 days 03:00:23.931 ago`. Timestamps use
millisecond accuracy and are tacked up to 49 days. If an event is
older than 49 days, the entry is still tracked in the list but the
timestamp is shown as old or `more than 49 days ago`.
The `HistoryTracker` currently maintains 3 lists. The Network Info
history tracks changes to Device Role, Mode, RLOC16 and Partition ID.
The RX/TX history list records information about the received/sent
IPv6 messages:
- Message type (UDP, TCP, ICMP6 (and its subtype), etc.)
- Source and destination IPv6 addresses and port numbers
- IPv6 payload length
- The message checksum (for UDP, TCP, or ICMP6).
- Whether or not the link-layer security was used
- Message priority: low, norm, high, net (for control messages)
- Short address (RLOC16) of neighbor who send/received the msg
- Received Signal Strength (in dBm) for RX only
- Radio link info (15.4/TREL) on which msg was sent/received
(useful when `OPENTHREAD_CONFIG_MULTI_RADIO` is enabled)
Config `HISTORY_TRACKER_EXCLUDE_THREAD_CONTROL_MESSAGES` can be used
to configure `HistoryTracker` to exclude Thread Control message
(e.g., MLE, TMF) from TX and RX history.
The number of entries recorded for each history list is configurable
through a set of OpenThread config options, e.g., number of entries
in Network Info history list is specified by OpenThread config option
`OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_INFO_LIST_SIZE`. The
`HistoryTracker` will keep the most recent entries overwriting oldest
ones when the list gets full.
This commit also adds support for `HistoryTracker` in CLI. The CLI
commands provide two style for printing the history information: A
table format (more human-readable) and list style (better suited for
parsing by machine/code). `README_HISTORY.md` is added to document
the commands and the info provided by each history list entry.
This commit also adds `test_history_tracker.py` test-case which
covers the behavior of `HistoryTracker`.
Per RFC 4862 section 5.5.3, the SLAAC address of a on-link prefix
will not immediately be invalidated even if the on-link prefix is
sent with zero PIO valid lifetime but we currently removes the
external route for the on-link prefix when we see zero valid lifetime.
This results in an error case that a Thread device can not reach
a valid SLAAC address of a Wi-Fi host on the same infra link because
there is no routes for this address.
This commit fixes this issue by delay removing the external route
for the discovered on-link prefix untill its valid lifetime expires.
Meanwhile, the Border Router now considers a deprecated (zero preferred
lifetime) on-link prefix not usable. Thus, the Border Router will
start advertising its own on-link prefix when current on-link prefix
is deprecated.
This commit implements a new feature "Network Data Publisher" which
provides mechanisms to limit the number of similar entries (service
and/or prefix) in the Thread Network Data by monitoring the Network
Data and managing if or when to add or remove entries. This feature is
enabled using `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE` config, or
`NETDATA_PUBLISHER` in autoconf, or `OT_NETDATA_PUBLISHER` cmake
option.
This commit adds support for publishing DNS/SRP anycast/unicast
service, on-mesh prefix, and external route prefix entries.
When there is a request to publish an entry, the `Publisher` monitors
the Network Data and counts the number of similar entries. If there
are fewer entries than a desired target number, the entry is added
after a short random delay.
If there are too many similar entries, `Publisher` starts the process
of removing its own entry (again after some random wait time). When
removing entries, certain entries are preferred over others (e.g., an
entry from a router over one from an end-device or if they are from
the same type of node, the one with smaller RLOC16). If `Publisher`
determines that its own entry is a preferred one, it adds an extra
wait time before removing its entry. This gives higher chance for a
non-preferred entry from another device to be removed before removing
a preferred entry which helps towards quicker convergence of the
process to the desired number of entries.
On-mesh prefix and external route entries have a "preference" field.
When publishing such an entry, a matching entry in the network data is
counted only if its preference is same or higher than the entry's
preference. This ensures that a device with a higher preference entry
publishes its entry even when there are many lower preference similar
entries in the network data (potentially causing a lower preference
entry to be removed).
This commit also adds `test_netdata_publisher.py` to verify the
behavior of the `Publisher`.
This commit includes a test case to verify that multiple border
routers can publish their meshcop services successfully without
instance name conflicts.
When a new service with subtypes is added to an existing
host, the SRP server incorrectly merges the subtype service
copies so that the TXT information is lost, i.e. 0-length
TXT record is created.
Moreover, the OT DNS client cannot parse services with
0-length TXT record (instead of ignoring the TXT record
itself) causing that such a service cannot be examined
at all.
The problem is caused by incorrect merging of the service
description structure which is shared across all services
with the same instance name (i.e. among the base type
service and its subtypes).
Signed-off-by: Damian Krolik <damian.krolik@nordicsemi.no>
This commit aims to update the meshcop service instance name in
test_publish_meshcop_service.py to make it consistent with the change
on ot-br-posix side.
This commit fixes reporting expect failures by adding fail on error
flag to the ot_exec_expect_script function in script/test script.
This commit also fixes failing expect tests and removes expect tests
on macOS for unstable issues.
This commits updates `thread-cert/Makefile.am` adding some existing
tests that were not included in the Makefile when the tests were
added. It also sorts the entries to be in alphabetical order.
This commit also updates the access control mode for all script files
to be executable by all (`chmod 755` or "-rwxr-xr-x").
This commit allows a zero-len prefix `::/0` to be added as an external
route in Network Data. Such a prefix can act as a default route. This
commit also adds `test_zero_len_external_route.py` testcase to verify
the network's behavior using a zero-len external route.
This commit adds a new feature in DNS client to automatically set and
update the server's IPv6 address in the default config. This is done
only when user does not explicitly set or specify the server address.
This behavior requires SRP client and its auto-start feature to be
enabled. SRP client will then monitor the Thread Network Data for
DNS/SRP Service entries to select an SRP server. The selected SRP
server address is also set as the DNS server address in the default
config.
This commit also adds `test_dns_client_config_auto_start.py` which
verifies the behavior of the new feature. In particular, that the DNS
client's default config gets changed and mirrors the SRP client
selected server address (when not set by user) and that it remains
unchanged if user explicitly sets the address in the default config.
This commit updates `Dns::ServiceDiscovery::Server` to add support for
browsing a service subtype. In particular, it updates the code which
breaks a DNS name into its components such that it can correctly
parse and accept a service subtype name. It also updates how the
service name compression is done to handle the subtype names.
This commit also updates `Dns::Client` to remove the extra check of
service name (which is already verified) when trying to find a PTR
record for a given service instance name. This change enables browse
for service subtype (parsing the browse response).
This commit also updates and enhances the `test_dnssd.py` script
adding test-cases for browsing for service subtype.
This commit adds support for service subtypes in SRP server. It
updates the internal data model to store services in `Srp::Server`.
Every `Host` now has a list of `Service` entries along with a list of
`Service::Description` entries. These types mirror the SRP update
message format and the set of instructions that form the SRP message.
The `Service` entries represent the "Service Discovery Instructions",
i.e., the PTR records mapping a service name or a subtype name to a
service instance. A `Service::Description` entry represents the the
SRV and TXT records. A `Service` entry is always associated with a
`Service::Description` and the subtypes of the same service instance
all share the same `Service::Description` entry.
This commit also adds a new method `Host::FindNextService()` and the
public API `otSrpServerHostFindNextService()` which is very flexible
and can be used in different ways. It can be used to iterate over the
full list of services, or over a specific subset of services matching
certain conditions, e.g., iterate over all base services excluding
subtypes, or over all subtypes of an instance, or over all deleted
services, etc. It can also be used to find a specific service with a
given instance and service names.
This commit also simplifies and enhances the logging in `Srp::Server`.
In particular, when a new host is added, we now also log the list of
services being added along with it. Also a change to a `Service` is
only logged if the `Service` is marked as committed. This ensures
that temporary `Service` entries associated with a newly received SRP
update message are not logged (e.g., when an associated temporary
`Host` object is being freed after its content is merged with an
existing `Host` entry).
Finally, this commit adds a test `test_srp_sub_type.py` to cover the
subtype service registration on SRP client and server.
This commit updates `test_srp_server_reboot_port` to restart the SRP
sever instead of performing a full device reset. The SRP restart will
trigger the port number change by the server which is the behavior
this test is intended to verify. This change should help address
intermittent failures on this test.