Kea issueshttps://gitlab.isc.org/isc-projects/kea/-/issues2024-03-14T14:49:00Zhttps://gitlab.isc.org/isc-projects/kea/-/issues/3282Support option-data based on client class AND subnet2024-03-14T14:49:00ZDarren AnkneySupport option-data based on client class AND subnetScenario: A class of clients (ACME Phones) need to receive option 225 "foo" with string content. This string needs to vary depending on the subnet selected. The option-data must not be offered to clients that are NOT ACME Phones.
<det...Scenario: A class of clients (ACME Phones) need to receive option 225 "foo" with string content. This string needs to vary depending on the subnet selected. The option-data must not be offered to clients that are NOT ACME Phones.
<details><summary>Current solution:</summary>
```
{
"Dhcp4": {
"option-def": [
{
"name": "foo",
"code": 225,
"type": "string",
}
],
"client-classes": [
{
"name": "ACMEphone",
"test": "option[60].hex == 'ACME IP Phone'",
"option-data": [
{
"name": "foo",
"data": "'some string 1'"
}
],
"only-if-required": true
},
{
"name": "ACMEphone2",
"test": "option[60].hex == 'ACME IP Phone'",
"option-data": [
{
"name": "foo",
"data": "'some string 2'"
}
],
"only-if-required": true
}
],
"subnet4": [
{
"id": 1,
"subnet": "192.0.2.0/24",
"require-client-classes": [
"ACMEphone"
],
"pools": [
{
"pool": "192.0.2.2 - 192.0.2.254"
}
]
},
{
"id": 2,
"subnet": "192.0.3.0/24",
"require-client-classes": [
"ACMEphone2"
],
"pools": [
{
"pool": "192.0.3.2 - 192.0.3.254"
}
]
}
]
}
}
```
</details>
This solution works but requires adding one client-class per subnet that will need to provide differing parameters to the class of clients in question on a per subnet basis.
This scenario is quite common and was handled previously in ISC DHCP with "if" statements where an "if" statement would be dropped into a subnet as necessary for the clients that might appear there that needed some option content provided with values specific to the subnet selected.
[SF1773](https://isc.lightning.force.com/lightning/r/Case/500S6000006NkOVIA0/view)next-stable-3.0https://gitlab.isc.org/isc-projects/kea/-/issues/3170Feature request: Add regex classification expression2023-11-30T14:29:47ZottoreiFeature request: Add regex classification expressionIt would be a huge improvement for client classification to have the possibility of using regular expressions. That way even more complex inputs could be handled with ease.It would be a huge improvement for client classification to have the possibility of using regular expressions. That way even more complex inputs could be handled with ease.next-stable-2.6https://gitlab.isc.org/isc-projects/kea/-/issues/2917VENDOR_CLASS_ not assigned if kea-dhcp4 receives two or more options of code 602023-06-22T13:38:46ZAndrei Pavelandrei@isc.orgVENDOR_CLASS_ not assigned if kea-dhcp4 receives two or more options of code 60If kea-dhcp4 receives two or more options of code 60, it concatenates them under a single option which is then parsed as a byte-array rather than a string. Not a confirmed use case by any stretch, but potential clients sending two option...If kea-dhcp4 receives two or more options of code 60, it concatenates them under a single option which is then parsed as a byte-array rather than a string. Not a confirmed use case by any stretch, but potential clients sending two options might theoretically expect to be treated as two vendors simultaneously rather than as a single vendor with a kludgy ID. `VENDOR_CLASS_` is not assigned at all to the packet as it usually is when a single option is received. Arguably, it would be better if all vendor classes were assigned or at least one of them.
- Here is how Kea logs a 4-length option 60: `type=060, len=004: "1234" (string)` followed by `DHCP4_CLASS_ASSIGNED [...] client packet has been assigned to the following class(es): ALL, VENDOR_CLASS_1234, UNKNOWN`
- Here is how Kea logs two 4-length options with values `1234` and `5678`: `type=060, len=008: 31:32:33:34:35:36:37:38` followed by `DHCP4_CLASS_ASSIGNED [...] client packet has been assigned to the following class(es): ALL, UNKNOWN`
Tested on current master f390f5ac984b815c67d1af14882a83cfc38d69ab, but happens on 2.2.0 as well.
Capture, config, and log, that help in observing the issue:
- [capture.pcap](/uploads/9091b90e7c58f27228514dbc372ad6c2/capture.pcap)
- [kea-dhcp4.conf](/uploads/c87797a78fc1efb7d8a71c2c4c25e887/kea-dhcp4.conf)
- [kea.log](/uploads/f25867508f64c40acac633d99caa4885/kea.log)next-stable-2.6https://gitlab.isc.org/isc-projects/kea/-/issues/2911New classification expressions "contains"2023-06-15T14:01:23ZCarsten StrotmannNew classification expressions "contains"---
name: Feature request
about: New classification expressions "contains"
---
Sometimes I find the need to classify a DHCP client based on a string of byte-sequence in the DHCP request, but the string or byte-sequence might vary in po...---
name: Feature request
about: New classification expressions "contains"
---
Sometimes I find the need to classify a DHCP client based on a string of byte-sequence in the DHCP request, but the string or byte-sequence might vary in position inside the packet (option) data (based on version of the client product).
A new classification expression that will search a sub-string or byte-sequence inside packet data and reporting the boolean value based on the existence of this sub-string or byte-sequence would be helpful.
Proposed example:
```
"client-classes": [
{ "name": "foo",
"test": "contains(substring(option[60].hex,0,3),'bar','i')",
"option-data": [{
"name": "domain-name", "data": "bar.example.com" }]
},
{ "name": "baz",
"test": "contains(hexstring(option[55].hex),'01:79:03','')",
"option-data": [{
"name": "domain-name", "data": "quux.example.com" }]
},
```
Proposed syntax format
contains('base-string','search-string','options')
where 'options' modify the search, e.g. using 'i' for case-insensitive searchnext-stable-2.6https://gitlab.isc.org/isc-projects/kea/-/issues/2800Client classes are case insensitive in the leaseX_stat_by_client_class MySQL ...2023-04-20T13:29:20ZAndrei Pavelandrei@isc.orgClient classes are case insensitive in the leaseX_stat_by_client_class MySQL tableReplication steps:
1. Start `kea-dhcp4` with two classes having the same name, but with different capitalization, with limits hook library loaded, and a MySQL lease backend, like in the following example. Add to the configuration whatev...Replication steps:
1. Start `kea-dhcp4` with two classes having the same name, but with different capitalization, with limits hook library loaded, and a MySQL lease backend, like in the following example. Add to the configuration whatever else is needed for dealing with DHCP traffic like `interfaces-config` and `subnet4`.
```json
{
"Dhcp4": {
"client-classes": [
{
"name": "myclass",
"test": "member('ALL')"
},
{
"name": "MYCLASS",
"test": "member('ALL')"
}
],
"hooks-libraries": [
{
"library": "/opt/kea/lib/kea/hooks/libdhcp_limits.so"
}
],
"lease-database": {
"host": "127.0.0.1",
"name": "keatest",
"password": "keatest",
"type": "mysql",
"user": "keatest"
}
}
}
```
2. Send any number of DORAs. Each of the two client classes has to be assigned at least to one DORA.
3. Get all rows from `lease4_stat_by_client_class`. Notice that one of the classes is missing, and the other one is present with more leases than `ALL` which should not be possible. The problem is that both classes are registered under only one of them.
```sh
$ mysql --user=root --password=keatest --database=keatest --execute='SELECT * FROM lease4_stat_by_client_class;'
+--------------+--------+
| client_class | leases |
+--------------+--------+
| ALL | 29 |
| myclass | 58 |
| UNKNOWN | 29 |
+--------------+--------+
```
4. Get the user context from `lease4`. See that both classes are properly added to the user context.
```sh
$ mysql --user=root --password=keatest --database=keatest -e 'SELECT DISTINCT user_context FROM lease4;'
+-----------------------------------------------------------------------------+
| user_context |
+-----------------------------------------------------------------------------+
| { "ISC": { "client-classes": [ "ALL", "myclass", "MYCLASS", "UNKNOWN" ] } } |
+-----------------------------------------------------------------------------+
```
Replicates for `kea-dhcp6` too.
Does not replicate on a PostgreSQL lease backend, meaning there are separate entries for each class e.g. `myclass` and `MYCLASS`. This is the expected behavior.
Used this version to replicate: `Server version: 10.11.2-MariaDB-1:10.11.2+maria~ubu2204 mariadb.org binary distribution`outstandinghttps://gitlab.isc.org/isc-projects/kea/-/issues/2736valid-lifetime and required client classes2023-01-26T14:25:43ZPeter Daviesvalid-lifetime and required client classesvalid-lifetime and required client classes:
When defining "valid-lifetime" in a client class the value takes precedence over
the global and subnet values. This does not happen when the class is defined as
"only-if-required" and...valid-lifetime and required client classes:
When defining "valid-lifetime" in a client class the value takes precedence over
the global and subnet values. This does not happen when the class is defined as
"only-if-required" and the subnet is defined with "required-client-classes"
The Kea Arm suggests that "option-data" in required classes take precedence but
no mention is made of "valid-lifetime"
Quote: Required evaluation can be used to express complex dependencies like subnet membership. It can also be used to reverse
the precedence; if option-data is set in a subnet, it takes precedence over option-data in a class. If option-data
is moved to a required class and required in the subnet, a class evaluated earlier may take precedence.
The following offers a lease time with the default value of "7200" and not "123"
for clients classifed as "Class-1"
```
{
"Dhcp4": {
"interfaces-config": { "interfaces": [ "vethserver" ] },
"control-socket": { "socket-type": "unix", "socket-name": "../sockets/kea4_command" },
"lease-database": { "type": "memfile", "name": "./kea-lease4.csv", "lfc-interval": 0, "persist": true },
"client-classes": [ {
"name": "Class-1", "test": "(pkt4.mac == 0x1e503193e1a6)", "only-if-required": true, "valid-lifetime": 123 }],
"subnet4": [ {
"subnet": "10.0.1.0/24", "id": 1,
"pools": [ { "pool": "10.0.1.5 - 10.0.1.254",
"require-client-classes": [ "Class-1" ] } ] }],
"dhcp-ddns": { "enable-updates": false },
"option-data": [ {
"name": "domain-name-servers", "code": 6, "data": "1.1.1.1" }, {
"name": "routers", "code": 3, "data": "10.0.1.1" } ],
"loggers": [ {
"name": "kea-dhcp4", "output_options": [ { "output": "./kea-dhcp4.log" } ],
"severity": "DEBUG", "debuglevel": 99 } ] }
}
```
[RT #21738](https://support.isc.org/Ticket/Display.html?id=21738)backloghttps://gitlab.isc.org/isc-projects/kea/-/issues/2716reversing the priority of allocated resources in client classes would allow t...2023-05-31T19:56:05ZAndrei Pavelandrei@isc.orgreversing the priority of allocated resources in client classes would allow template-spawned inheritanceThe current behavior for client classes is that any resource (lease times, option data, v4 option definitions, v4 fields) defined in a client class is taken from the first matching class. In the following example (don't worry about its u...The current behavior for client classes is that any resource (lease times, option data, v4 option definitions, v4 fields) defined in a client class is taken from the first matching class. In the following example (don't worry about its uselessness, it's only there to prove a point), the valid lifetime of 100 is always given to clients.
```json
{
"Dhcp6": {
"client-classes": [
{
"name": "foo",
"test": "0 == 0",
"valid-lifetime": 100
},
{
"name": "bar",
"test": "0 == 0",
"valid-lifetime": 200
}
]
}
}
```
Since template classes always need to be defined first relative to their spawned class, that means that template classes always have priority over spawned classes. If a user wanted to have a value overwritten in the spawned class, they cannot do it. Having values overwritten for a more specific set of clients is a legitimate reason. Furthermore, it matches the inheritance priority in other parts of the configuration, see the `global - shared network - subnet` relationship. To exemplify, in the following configuration, nobody would ever get valid lifetime 200.
```json
{
"Dhcp6": {
"client-classes": [
{
"name": "oui-vendor",
"template-test": "hexstring(substring(option[1].hex, 4, 3), ':')",
"valid-lifetime": 100
},
{
"name": "SPAWN_oui-vendor_01:02:03",
"valid-lifetime": 200
}
]
}
}
```outstandinghttps://gitlab.isc.org/isc-projects/kea/-/issues/2676[ kea-dhcp4.options] EVAL_RESULT Expression unreserved_class evaluated to 12023-07-31T14:10:04ZPPEQ[ kea-dhcp4.options] EVAL_RESULT Expression unreserved_class evaluated to 1I am testing the matching class function in kea dhcp version 2.2.0. The configuration is as follows:
____________________________________________________________________________________________________
//设置终端匹配类,授权控制策略
"client-classe...I am testing the matching class function in kea dhcp version 2.2.0. The configuration is as follows:
____________________________________________________________________________________________________
//设置终端匹配类,授权控制策略
"client-classes": [
{
"name": "reserved_class"
},
{
"name": "unreserved_class",
"test": "not member('reserved_class')"
}
],
//地址保留分配
"reservation-mode": "global", //设置全局预留
"reservations": [ //预留的地址
{
"hostname": "host-one",
"hw-address": "01:bb:cc:dd:ee:ff"
},
{
"hostname": "host-two",
"hw-address": "02:bb:cc:dd:ee:ff"
},
{
"hw-address": "aa:bb:cc:dd:ee:fe",
"client-classes": [ "reserved_class" ]
},
{
"hostname": "test-one",
"hw-address": "00:0c:29:e9:00:07",
//"client-classes": [ "reserved_class" ]
}
//{
// "hw-address": "00:0c:29:e9:00:07",
// "client-classes": [ "reserved_class" ]
//}
],
"shared-networks": [{
"name": "mytest111",
"subnet4": [
{
"reservations-global": true, //全局预留生效
"reservations-in-subnet": true, //子网预留生效
"reservations-out-of-pool": false, //地址池域名不生效
"subnet": "192.168.100.0/24",
"pools": [
{
"pool": "192.168.100.10-192.168.100.200",
"client-class": "reserved_class"
}
],
"option-data": [
{
"name": "routers",
"data": "192.168.100.1"
},
{
"name": "domain-name-servers",
"data": "223.5.5.5, 223.6.6.6"
}
]
},
{
"subnet": "192.168.101.0/24",
"valid-lifetime": 40, //默认租期
"min-valid-lifetime":40, //最小租期
"max-valid-lifetime":40, //最大租期
"pools": [
{
"pool": "192.168.101.10-192.168.101.200",
"client-class": "unreserved_class"
}
],
"option-data": [
{
"name": "routers",
"data": "192.168.101.1"
},
{
"name": "domain-name-servers",
"data": "192.168.100.183"
}
]
}
]
}],
___________________________________________________________________________________________________
![image](/uploads/f50b39a0f4b8a509dcd3f3c1ca56a625/image.png)
But I found a fatal error. The DHCP service was deployed and the configuration check passed normally. However, the log output found that there would be an error about the option, and it would follow every log requesting an IP address. If there were thousands of terminal devices in the network, the log storage would be impossible to estimate.
So, please help me to deal with this matter and see if it is the reason for my configuration or if it is true.
thank you!next-stable-2.6https://gitlab.isc.org/isc-projects/kea/-/issues/2670renew-timer and rebind-timer in client classes2023-03-03T11:49:51ZPeter Daviesrenew-timer and rebind-timer in client classesFor some users, it may be useful to be able to define "renew-timer" and "rebind-timer"
within client class definitions.
[RT #21543](https://support.isc.org/Ticket/Display.html?id=21543)For some users, it may be useful to be able to define "renew-timer" and "rebind-timer"
within client class definitions.
[RT #21543](https://support.isc.org/Ticket/Display.html?id=21543)backloghttps://gitlab.isc.org/isc-projects/kea/-/issues/2603add support for template-classes in CB2023-07-31T12:45:46ZRazvan Becheriuadd support for template-classes in CBNow that template classes are implemented, it would be good to extend the Config Backend support to cover them.Now that template classes are implemented, it would be good to extend the Config Backend support to cover them.backlogRazvan BecheriuRazvan Becheriuhttps://gitlab.isc.org/isc-projects/kea/-/issues/2553EVAL_RESULT INFO or DEBUG to provide client ID2022-09-08T13:34:12ZVeroniqueEVAL_RESULT INFO or DEBUG to provide client IDHello,
It would be helpful if the line INFO or DEBUG which is printed with the EVAL_RESULT information, would provide the client identifier (in my case I am interested to have the hardware address of the client, but it could be something...Hello,
It would be helpful if the line INFO or DEBUG which is printed with the EVAL_RESULT information, would provide the client identifier (in my case I am interested to have the hardware address of the client, but it could be something else).
It would help while grepping on the log file.
Many thanks.outstandinghttps://gitlab.isc.org/isc-projects/kea/-/issues/2480Documentation - Update KB Article Understanding Client Classification2023-07-31T13:34:54ZPeter DaviesDocumentation - Update KB Article Understanding Client Classification**Update KB Article Understanding Client Classification**
The early-global-reservations-lookup for classed was implemented in release 2.1.4 see #2249
This optionally changes the phases of subnet selection and host reservation.
It need...**Update KB Article Understanding Client Classification**
The early-global-reservations-lookup for classed was implemented in release 2.1.4 see #2249
This optionally changes the phases of subnet selection and host reservation.
It needs to be explained in the KB article:
https://kb.isc.org/docs/understanding-client-classificationnext-stable-2.6https://gitlab.isc.org/isc-projects/kea/-/issues/1942Refactor ClientClassDictionary to provide indexing2022-11-02T15:10:41ZMarcin SiodelskiRefactor ClientClassDictionary to provide indexingI would like to propose refactoring the `ClientClassDictionary` internals to support indexing classes by various parameters. Right now we index by class names and we have an ordered index. In #1836 we are adding a change which matches cl...I would like to propose refactoring the `ClientClassDictionary` internals to support indexing classes by various parameters. Right now we index by class names and we have an ordered index. In #1836 we are adding a change which matches classes with configured server identifiers. Without indexing, such matching is sub-optimal. Perhaps, if we migrate the class collection to multi index container we could easily add additional indexing if necessary.backloghttps://gitlab.isc.org/isc-projects/kea/-/issues/1588EVAL_RESULT displays boolean status as an integer2023-07-05T10:39:18ZFrancis DupontEVAL_RESULT displays boolean status as an integerFor instance ```EVAL_RESULT Expression 53148-RU evaluated to 1``` should be ```EVAL_RESULT Expression 53148-RU evaluated to true``` so all uses of EVAL_RESULT should set std::boolalpha or convert the boolean into false and true directly.For instance ```EVAL_RESULT Expression 53148-RU evaluated to 1``` should be ```EVAL_RESULT Expression 53148-RU evaluated to true``` so all uses of EVAL_RESULT should set std::boolalpha or convert the boolean into false and true directly.next-stable-2.6https://gitlab.isc.org/isc-projects/kea/-/issues/1544user-class filtering per reservation (Microsoft DHCP)2020-12-21T13:11:08ZTomek Mrugalskiuser-class filtering per reservation (Microsoft DHCP)Some time ago there was [a discussion on kea-users](https://lists.isc.org/pipermail/kea-users/2019-April/002333.html) (note: the discussion continued in May). Here's what the user was trying to do:
> What mkangelo and I are trying to do...Some time ago there was [a discussion on kea-users](https://lists.isc.org/pipermail/kea-users/2019-April/002333.html) (note: the discussion continued in May). Here's what the user was trying to do:
> What mkangelo and I are trying to do is to replace Microsoft DHCP server which has a feature to create host reservations with
two option 67 values which are served to the client based on the class (type) of the client - for example return undionly.kpxe when client is pxe return https://api.example.com/customurl/ when client is gpxe
Here's an expression they're trying to achieve:
```
Client class is extracted from DHCP Discover packets:
IF Option [77] == gPXE
then second value is being returned
ELSEIF Option [60] == "PXEClient:Arch:00000:UNDI:002001"
then first value is returned
```
This seems like a useful feature that's provided by some other implementations.outstandinghttps://gitlab.isc.org/isc-projects/kea/-/issues/1168client class erase concern2023-07-31T13:04:35ZFrancis Dupontclient class erase concern#1139 introduced a new client class method erase. I have some concerns about its use:
- first it supposes built-in or added by hook classes are never defined: this is in general true **but** nothing prevents someone to define a class ad...#1139 introduced a new client class method erase. I have some concerns about its use:
- first it supposes built-in or added by hook classes are never defined: this is in general true **but** nothing prevents someone to define a class added by a hook or a built-in class
- second performance can be very bad: complexity is <number of definitions> x <number of classes in the query>
I found some ways to improve the performance and in some cases to fix the first concern too:
- move to a boost multi-index: the problem is with the list part (linear), in a multi-index the interesting node can be found using the unordered set index (logarithm). Note this can be applied to the ClientClasses or the ClientClassDictionary or both.
- if I understand well the code the problem is with member predicates: we can add a flag in definitions when the test expression uses a member predicate. Note we do this in test expression parsing to check if the member predicate refers to an already defined or built-in class so this is a small change: keep the condition in a new field.
- swap the query classes and the definition dictionary in the iteration.backloghttps://gitlab.isc.org/isc-projects/kea/-/issues/1153Rewrite the client classification documentation in Kea ARM2022-11-02T15:10:17ZMarcin SiodelskiRewrite the client classification documentation in Kea ARMClient classification is a complex topic. We started simple but over the years we have added more and more feature to client classification. While reviewing the most recent addition to client classification in #1139 we found that certain...Client classification is a complex topic. We started simple but over the years we have added more and more feature to client classification. While reviewing the most recent addition to client classification in #1139 we found that certain paragraphs are unclear. For example, see this thread: https://gitlab.isc.org/isc-projects/kea/-/merge_requests/686#note_115873. We think it may be now good time to rewrite the documentation about the client classification and perhaps add some diagrams explaining how it all works together.backloghttps://gitlab.isc.org/isc-projects/kea/-/issues/1030client class added by hooks and expressions2020-01-16T16:36:32ZFrancis Dupontclient class added by hooks and expressionsA client class added by a hook in pkt4_receive can't be used in an expression because the main classification is done before the callout. This means it can be used only directly for subnet selection, e.g. if the hook adds the class "foo"...A client class added by a hook in pkt4_receive can't be used in an expression because the main classification is done before the callout. This means it can be used only directly for subnet selection, e.g. if the hook adds the class "foo" you can guard a subnet by "foo" but not by a class "not-foo" defined by the expression "not member('foo')".
The case of pool guard is more complex because it is possible to move to the host identifier classification point using "KNOWN" or "UNKNOWN" in the expression. Of course it is simpler for required classes which are evaluated late.
This is not beyond repair but if we want to change this IMHO it is better to reconsider the whole classification design as explained in #1028.outstandinghttps://gitlab.isc.org/isc-projects/kea/-/issues/1029New built-in client class for incomplete unpacking2020-01-09T16:56:32ZFrancis DupontNew built-in client class for incomplete unpackingCurrent Kea accepts packets which have a not fatal error during unpacking. I believe it was added by @tmark: in such case the SkipRemainingOptionsError exception is thrown and processing continue.
I'd like to put such packets in a new b...Current Kea accepts packets which have a not fatal error during unpacking. I believe it was added by @tmark: in such case the SkipRemainingOptionsError exception is thrown and processing continue.
I'd like to put such packets in a new built-in class so a "not option[xxx].exist" can't be mislead: it will be enough to add "add not member("<new-class-name>')".
This allows too to classify such packets in the DROP class so by configuration accept or drop them.outstandinghttps://gitlab.isc.org/isc-projects/kea/-/issues/1028New classification design.2023-07-31T11:54:22ZFrancis DupontNew classification design.Some proposals for a new classification design:
- replace the list+set by a multi-index
- replace the required-xxx by a more direct add-client-classes.
- add this new add-client-classes to host reservations as an alias of the existing...Some proposals for a new classification design:
- replace the list+set by a multi-index
- replace the required-xxx by a more direct add-client-classes.
- add this new add-client-classes to host reservations as an alias of the existing client-classes (same entry with the same behavior for all objects which add a class to the query)
- complete the list of class evaluation points:
* new points after the deferred unpack, pkt*_receive hook, etc
* make clear in the doc that which a classification point is for:
+ dependency on a packet procession phase (e.g. KNOWN/UNKNOWN)
+ usage for the next packet processing step (e.g. subnet selection, pool guard, output option)
* add an enum (vs a few flags) for the point where a class must be evaluated
* add a meta-data with the value of its enum and make it visible to users
- same rules on dependency (use of member in expression):
* no forward reference (the user class in a member clause must be already defined)
* get the last classification point
* perhaps a new built-in class for instance for the pkt*_receive hook
- document the way to switch from expired-* to this new stuff (but do not develop a tool to translate configurations)
- (next steps?) new uses of classes (e.g. lifetime), new expressions (e.g. in the response vs the query): in almost all cases this means new classification pointsnext-stable-3.0