Skip to content
  •  
  •  
  •  

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai

import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.EOF
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.FlexibleLiteralChoiceTerminal
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.SequenceCombinator

/*
* [Link] ActivationPolicy= (.network).
*
* man https://www.freedesktop.org/software/systemd/man/latest/systemd.network.html#ActivationPolicy=
* parser https://github.com/systemd/systemd/blob/0f0682b773/src/network/networkd-network.c#L1201 config_parse_activation_policy (0), DEFINE_CONFIG_PARSE_ENUM
* leaf https://github.com/systemd/systemd/blob/0f0682b773/src/network/networkd-network.c#L1191-L1198 activation_policy_table
* tests https://github.com/systemd/systemd/blob/0f0682b773/test/test-network/conf/25-activation-policy.network.d/always-down.conf#L2
*/

/**
* Validator for `[Link] ActivationPolicy=`: exactly one of `up`, `always-up`, `manual`, `always-down`,
* `down`, `bound` (plain DEFINE_STRING_TABLE_LOOKUP — case-sensitive, no boolean).
*/
class ConfigParseActivationPolicyOptionValue : SimpleGrammarOptionValues(
"config_parse_activation_policy",
SequenceCombinator(
FlexibleLiteralChoiceTerminal("up", "always-up", "manual", "always-down", "down", "bound"),
EOF(),
)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai

import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.EOF
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.RegexTerminal
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.SequenceCombinator

/*
* [Address] Label= (.network).
*
* man https://www.freedesktop.org/software/systemd/man/latest/systemd.network.html#Label=
* parser https://github.com/systemd/systemd/blob/0f0682b773/src/network/networkd-address.c#L2298-L2363 config_parse_address_section (ADDRESS_LABEL)
* https://github.com/systemd/systemd/blob/0f0682b773/src/network/networkd-address.c#L2174-L2200 config_parse_address_label
* leaf https://github.com/systemd/systemd/blob/0f0682b773/src/basic/socket-util.c#L832-L852 address_label_valid
*/

/**
* Validator for `[Address] Label=` (.network) — the ADDRESS_LABEL slot, whose table entry is
* config_parse_address_label → address_label_valid().
*
* One to 15 characters (shorter than IFNAMSIZ), each a byte in 32…126 — printable ASCII, space
* included. A longer or non-ASCII label is ignored with "Interface label is too long or invalid".
*/
class ConfigParseAddressLabelOptionValue : SimpleGrammarOptionValues(
"config_parse_address_section",
SequenceCombinator(RegexTerminal("""[\s\S]+""", """[\x20-\x7E]{1,15}"""), EOF())
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai

import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.EOF
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.FlexibleLiteralChoiceTerminal
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.SequenceCombinator
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.WhitespaceTerminal
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.ZeroOrMore

/*
* [Link] Advertise= and [EnergyEfficientEthernet] LinkMode= in a .link file.
*
* man https://www.freedesktop.org/software/systemd/man/latest/systemd.link.html#Advertise=
* parser https://github.com/systemd/systemd/blob/0f0682b773/src/shared/ethtool-util.c#L1125-L1177 config_parse_advertise (0)
* leaf https://github.com/systemd/systemd/blob/0f0682b773/src/shared/ethtool-util.c#L162-L168 ethtool_link_mode_bit_table (DEFINE_STRING_TABLE_LOOKUP)
* leaf https://github.com/systemd/systemd/blob/0f0682b773/src/shared/ethtool-link-mode.py (generates the table from enum ethtool_link_mode_bit_indices)
* leaf https://github.com/systemd/systemd/blob/0f0682b773/src/include/uapi/linux/ethtool.h#L1966-L2109 enum ethtool_link_mode_bit_indices
* linux https://man7.org/linux/man-pages/man8/ethtool.8.html
*/

/**
* The link-mode names ethtool-link-mode.py derives from the vendored kernel header: each
* `ETHTOOL_LINK_MODE_<name>_BIT` lower-cased with `_` turned into `-`, and `autoneg` renamed
* `autonegotiation`. 125 names at 0f0682b773.
*/
private val LINK_MODE = FlexibleLiteralChoiceTerminal(
"10baset-half", "10baset-full", "100baset-half", "100baset-full", "1000baset-half",
"1000baset-full", "autonegotiation", "tp", "aui", "mii", "fibre", "bnc", "10000baset-full",
"pause", "asym-pause", "2500basex-full", "backplane", "1000basekx-full", "10000basekx4-full",
"10000basekr-full", "10000baser-fec", "20000basemld2-full", "20000basekr2-full",
"40000basekr4-full", "40000basecr4-full", "40000basesr4-full", "40000baselr4-full",
"56000basekr4-full", "56000basecr4-full", "56000basesr4-full", "56000baselr4-full",
"25000basecr-full", "25000basekr-full", "25000basesr-full", "50000basecr2-full",
"50000basekr2-full", "100000basekr4-full", "100000basesr4-full", "100000basecr4-full",
"100000baselr4-er4-full", "50000basesr2-full", "1000basex-full", "10000basecr-full",
"10000basesr-full", "10000baselr-full", "10000baselrm-full", "10000baseer-full",
"2500baset-full", "5000baset-full", "fec-none", "fec-rs", "fec-baser", "50000basekr-full",
"50000basesr-full", "50000basecr-full", "50000baselr-er-fr-full", "50000basedr-full",
"100000basekr2-full", "100000basesr2-full", "100000basecr2-full", "100000baselr2-er2-fr2-full",
"100000basedr2-full", "200000basekr4-full", "200000basesr4-full", "200000baselr4-er4-fr4-full",
"200000basedr4-full", "200000basecr4-full", "100baset1-full", "1000baset1-full",
"400000basekr8-full", "400000basesr8-full", "400000baselr8-er8-fr8-full", "400000basedr8-full",
"400000basecr8-full", "fec-llrs", "100000basekr-full", "100000basesr-full",
"100000baselr-er-fr-full", "100000basecr-full", "100000basedr-full", "200000basekr2-full",
"200000basesr2-full", "200000baselr2-er2-fr2-full", "200000basedr2-full", "200000basecr2-full",
"400000basekr4-full", "400000basesr4-full", "400000baselr4-er4-fr4-full", "400000basedr4-full",
"400000basecr4-full", "100basefx-half", "100basefx-full", "10baset1l-full", "800000basecr8-full",
"800000basekr8-full", "800000basedr8-full", "800000basedr8-2-full", "800000basesr8-full",
"800000basevr8-full", "10baset1s-full", "10baset1s-half", "10baset1s-p2mp-half",
"10baset1brr-full", "200000basecr-full", "200000basekr-full", "200000basedr-full",
"200000basedr-2-full", "200000basesr-full", "200000basevr-full", "400000basecr2-full",
"400000basekr2-full", "400000basedr2-full", "400000basedr2-2-full", "400000basesr2-full",
"400000basevr2-full", "800000basecr4-full", "800000basekr4-full", "800000basedr4-full",
"800000basedr4-2-full", "800000basesr4-full", "800000basevr4-full", "1600000basecr8-full",
"1600000basekr8-full", "1600000basedr8-full", "1600000basedr8-2-full"
)

/**
* Validator for `[Link] Advertise=` and `[EnergyEfficientEthernet] LinkMode=` (.link).
*
* C function: config_parse_advertise. A whitespace-separated list (extract_first_word, no unquoting) of
* ethtool link-mode names, each looked up exactly (case-sensitive) in ethtool_link_mode_bit_table —
* speed/duplex modes like `1000baset-full` as well as the non-speed bits (`autonegotiation`, `pause`,
* `asym-pause`, `tp`, `fibre`, `fec-rs`, …).
*
* The table is generated at build time from the kernel's enum ethtool_link_mode_bit_indices in
* systemd's vendored copy of linux/ethtool.h (src/include/uapi, which meson puts first on the include
* path). That is wider than the ethtool-link-mode.xml table in the plugin's generated man data, which
* lists 102 names; this follows the header the C is built against. An unknown name is logged and
* skipped by udev; an empty assignment clears the list.
*/
class ConfigParseAdvertiseOptionValue : SimpleGrammarOptionValues(
"config_parse_advertise",
SequenceCombinator(LINK_MODE, ZeroOrMore(SequenceCombinator(WhitespaceTerminal(), LINK_MODE)), EOF())
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai

import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.EOF
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.NetdevLinkCheckedSpan
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.SequenceCombinator
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.netdevLinkParseSizeSi
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.siSize
import java.math.BigInteger

/*
* [BatmanAdvanced] GatewayBandwidthDown= / GatewayBandwidthUp= in a .netdev file.
*
* man https://www.freedesktop.org/software/systemd/man/latest/systemd.netdev.html#GatewayBandwidthDown=
* parser https://github.com/systemd/systemd/blob/0f0682b773/src/network/netdev/batadv.c#L53-L89 config_parse_badadv_bandwidth (0)
* leaf https://github.com/systemd/systemd/blob/0f0682b773/src/network/netdev/batadv.c#L81-L84 (the 100 kbit uint32_t range warning)
* leaf https://github.com/systemd/systemd/blob/0f0682b773/src/basic/parse-util.c#L157-L283 parse_size (base 1000)
* tests https://github.com/systemd/systemd/blob/0f0682b773/src/test/test-parse-util.c#L178 TEST(parse_size_si)
* tests https://github.com/systemd/systemd/blob/0f0682b773/test/test-network/conf/25-batadv.netdev#L14-L15
*/

/**
* Validator for `[BatmanAdvanced] GatewayBandwidthDown=` and `GatewayBandwidthUp=` (.netdev), plus the
* misspelled `GatewayBandwithDown=` / `GatewayBandwithUp=` that systemd still accepts as aliases.
*
* C function: config_parse_badadv_bandwidth, which hands the whole value to parse_size(rvalue, 1000, …):
* a number with an optional case-sensitive SI suffix (`K`, `M`, `G`, `T`, `P`, `E`, `B`), a
* fraction allowed, and several elements with strictly descending suffixes (`1G 500M`) summed. See
* [siSize].
*
* The total is stored in units of 100 kbit in a uint32_t, so a total of 4294967296 × 100000
* (429496729600000, e.g. `12P` or `3E 2P`) or more is flagged. systemd logs that case ("is outside of
* 0...429496729500000 range") and then stores the total truncated to 32 bits, which is never what was
* meant, so it is treated as invalid here. Totals that overflow parse_size itself (`20E`) are refused
* outright. Confirmed against systemd's parser built at 0f0682b773: `429496729599999` is silent,
* `429496729600000` warns. Any other invalid value is logged and ignored by systemd.
*
* There is no isempty() branch, so an empty `GatewayBandwidthDown=` or `GatewayBandwidthUp=` is a parse error in systemd (logged and ignored), not
* a reset. The plugin never runs a grammar on an empty value, so it is not flagged here.
*/
class ConfigParseBadadvBandwidthOptionValue : SimpleGrammarOptionValues(
"config_parse_badadv_bandwidth",
SequenceCombinator(
NetdevLinkCheckedSpan(siSize(), "total < 429496729600000") { text ->
netdevLinkParseSizeSi(text)?.let { it < BATADV_BANDWIDTH_LIMIT } == true
},
EOF()
)
)

/** `k/1000/100 > UINT32_MAX` (batadv.c#L81) first holds at this total. */
private val BATADV_BANDWIDTH_LIMIT: BigInteger = BigInteger.valueOf(4_294_967_296L) * BigInteger.valueOf(100_000L)
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai

import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*

/*
* [BFIFO] LimitBytes= (.network)
*
* man https://www.freedesktop.org/software/systemd/man/latest/systemd.network.html#LimitBytes=
* parser https://github.com/systemd/systemd/blob/0f0682b773/src/network/tc/fifo.c#L103-L160 config_parse_bfifo_size (QDISC_KIND_BFIFO)
* leaf https://github.com/systemd/systemd/blob/0f0682b773/src/basic/parse-util.c#L157-L283 parse_size
* tests https://github.com/systemd/systemd/blob/0f0682b773/src/test/test-parse-util.c#L108-L176 TEST(parse_size_iec)
* tests https://github.com/systemd/systemd/blob/0f0682b773/src/test/test-parse-util.c#L178-L246 TEST(parse_size_si)
* tests https://github.com/systemd/systemd/blob/0f0682b773/test/test-network/conf/25-qdisc-htb-fifo.network#L42 LimitBytes=1000000
*/

/**
* Validator for [BFIFO] LimitBytes=.
*
* C function: config_parse_bfifo_size (QDISC_KIND_BFIFO). An empty assignment resets the setting and is
* handled before this grammar runs.
*
* A byte size as parse_size(rvalue, 1024) reads it (see [parseSize]) that must not exceed UINT32_MAX:
* above it the parser logs "Invalid 'LimitBytes=', ignoring assignment". So `4G` is rejected.
*/
class ConfigParseBfifoSizeOptionValue : SimpleGrammarOptionValues(
"config_parse_bfifo_size",
SequenceCombinator(parseSize(1024, maxInclusive = SIZE_UINT32_MAX), EOF()),
)
Loading
Loading