diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/AiGenerated.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/AiGenerated.kt index acf10cd..39c2b6c 100644 --- a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/AiGenerated.kt +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/AiGenerated.kt @@ -189,6 +189,8 @@ fun getAllAIGeneratedValidators(): Map { Validator("config_parse_restrict_network_interfaces", "0") to ConfigParseRestrictNetworkInterfacesOptionValue() as OptionValueInformation, Validator("config_parse_ring_buffer_or_channel", "0") to ConfigParseRingBufferOrChannelOptionValue() as OptionValueInformation, Validator("config_parse_route_prefix_preference", "0") to ConfigParseRoutePrefixPreferenceOptionValue() as OptionValueInformation, + Validator("config_parse_route_section", "ROUTE_GATEWAY") to ConfigParseRouteSectionGatewayOptionValue() as OptionValueInformation, + Validator("config_parse_route_section", "ROUTE_GATEWAY_NETWORK") to ConfigParseRouteSectionGatewayNetworkOptionValue() as OptionValueInformation, Validator("config_parse_route_section", "ROUTE_METRIC_FASTOPEN_NO_COOKIE") to ConfigParseRouteSectionOptionValue() as OptionValueInformation, Validator("config_parse_route_section", "ROUTE_METRIC_HOPLIMIT") to ConfigParseRouteSectionOptionValue() as OptionValueInformation, Validator("config_parse_route_section", "ROUTE_METRIC_INITRWND") to ConfigParseRouteSectionOptionValue() as OptionValueInformation, diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseRouteSectionGatewayNetworkOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseRouteSectionGatewayNetworkOptionValue.kt new file mode 100644 index 0000000..0e4e150 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseRouteSectionGatewayNetworkOptionValue.kt @@ -0,0 +1,21 @@ +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.* + +/** + * Validator for [Network] Gateway= (config_parse_route_section, ltype ROUTE_GATEWAY_NETWORK). + * + * systemd.network(5): "The gateway address, which must be in the format described in inet_pton(3). + * This is a short-hand for a [Route] section only containing a Gateway= key." + * + * So it accepts an IPv4 or IPv6 address only — unlike [Route] Gateway=, the special "_dhcp4" / + * "_ipv6ra" tokens are NOT accepted in the [Network] short-hand. + */ +class ConfigParseRouteSectionGatewayNetworkOptionValue : SimpleGrammarOptionValues( + "config_parse_route_section", + SequenceCombinator( + AlternativeCombinator(IPV4_ADDR, IPV6_ADDR), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseRouteSectionGatewayOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseRouteSectionGatewayOptionValue.kt new file mode 100644 index 0000000..d707664 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseRouteSectionGatewayOptionValue.kt @@ -0,0 +1,23 @@ +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.* + +/** + * Validator for [Route] Gateway= (config_parse_route_section, ltype ROUTE_GATEWAY). + * + * systemd.network(5): "Takes the gateway address or the special values "_dhcp4" and "_ipv6ra". If + * "_dhcp4" or "_ipv6ra" is set, then the gateway address provided by DHCPv4 or IPv6 RA is used." + */ +class ConfigParseRouteSectionGatewayOptionValue : SimpleGrammarOptionValues( + "config_parse_route_section", + SequenceCombinator( + AlternativeCombinator( + IPV4_ADDR, + IPV6_ADDR, + LiteralChoiceTerminal("_dhcp4"), + LiteralChoiceTerminal("_ipv6ra") + ), + EOF() + ) +) diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseRouteSectionGatewayOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseRouteSectionGatewayOptionValueTest.kt new file mode 100644 index 0000000..2a549d2 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseRouteSectionGatewayOptionValueTest.kt @@ -0,0 +1,54 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +/** + * Gateway= coverage for systemd .network files (config_parse_route_section, ltypes ROUTE_GATEWAY + * and ROUTE_GATEWAY_NETWORK). Previously unregistered, so Gateway values were not validated at all. + * + * [Network] Gateway= is an IPv4/IPv6 address only; [Route] Gateway= also accepts "_dhcp4"/"_ipv6ra". + */ +class ConfigParseRouteSectionGatewayOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidGateways() { + // language="unit file (systemd)" + val file = """ + [Network] + Gateway=192.168.1.1 + Gateway=2001:db8::1 + [Route] + Gateway=10.0.0.1 + Gateway=fe80::1 + Gateway=_dhcp4 + Gateway=_ipv6ra + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testInvalidGateways() { + // [Network] does not accept the special tokens; bad addresses are rejected in both sections; + // [Route] only accepts _dhcp4 / _ipv6ra (not _dhcp6). One highlight per line. + // language="unit file (systemd)" + val file = """ + [Network] + Gateway=_dhcp4 + Gateway=notanip + [Route] + Gateway=_dhcp6 + Gateway=300.1.2.3 + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + + assertSize(4, myFixture.doHighlighting()) + } +}