Skip to content

Commit c01cd8f

Browse files
Steve Ramageclaude
andcommitted
feat: grammar validators for MAC / hardware-address directives (#501)
Nine networkd/.link/.netdev directives took a MAC or hardware address but had no value validator (key recognized, value accepted unconditionally). Add grammar-based validators faithful to how systemd actually parses each, verified against src/basic/ether-addr-util.c. Two shared combinators: MAC_ADDRESS — a 6-byte Ethernet MAC (parse_ether_addr): colon, hyphen, or dot separators. HARDWARE_ADDRESS — parse_hw_addr_full(expected_len=0): 4/6/16/20-byte hardware addresses in colon/hyphen (1-byte) or dot (2-byte) fields, AND — since the parser tries in_addr_from_string first — IPv4/IPv6 literals. Wired up (parser, ltype) -> validator: hw_addrs Match.MACAddress / PermanentMACAddress (list, hw addr) hw_addr Link.MACAddress (single hw addr) neighbor_section Neighbor.LinkLayerAddress (+dep MACAddress) (hw addr) sr_iov_mac SR-IOV.MACAddress (6-byte MAC) fdb_hwaddr BridgeFDB.MACAddress (6-byte MAC) dhcp_static_lease DHCPServerStaticLease.MACAddress (6-byte MAC) netdev_hw_addr NetDev/Peer.MACAddress (6-byte MAC) macsec_hw_address MACsec*.MACAddress (6-byte MAC) ether_addrs MACVLAN/MACVTAP.SourceMACAddress (list, 6-byte MAC) Longest group-count alternatives come first so the classic first-full-match matcher never stops on a shorter prefix. Purely additive: these previously resolved to NullOptionValue. Covered by a new-engine grammar test and a classic-engine inspection wiring test; whole suite green under both engines. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 946d80c commit c01cd8f

13 files changed

Lines changed: 324 additions & 0 deletions

src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/AiGenerated.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,17 @@ fun getAllAIGeneratedValidators(): Map<Validator, OptionValueInformation> {
273273
Validator("config_parse_fdname", "0") to ConfigParseFdnameOptionValue() as OptionValueInformation,
274274
Validator("config_parse_udev_property_name", "0") to ConfigParseUdevPropertyNameOptionValue() as OptionValueInformation,
275275

276+
// MAC / hardware address directives (#501).
277+
Validator("config_parse_hw_addrs", "0") to ConfigParseHwAddrsOptionValue() as OptionValueInformation,
278+
Validator("config_parse_hw_addr", "0") to ConfigParseHwAddrOptionValue() as OptionValueInformation,
279+
Validator("config_parse_neighbor_section", "NEIGHBOR_LINK_LAYER_ADDRESS") to ConfigParseNeighborLinkLayerAddressOptionValue() as OptionValueInformation,
280+
Validator("config_parse_sr_iov_mac", "0") to ConfigParseSrIovMacOptionValue() as OptionValueInformation,
281+
Validator("config_parse_fdb_hwaddr", "0") to ConfigParseFdbHwaddrOptionValue() as OptionValueInformation,
282+
Validator("config_parse_dhcp_static_lease_hwaddr", "0") to ConfigParseDhcpStaticLeaseHwaddrOptionValue() as OptionValueInformation,
283+
Validator("config_parse_netdev_hw_addr", "ETH_ALEN") to ConfigParseNetdevHwAddrOptionValue() as OptionValueInformation,
284+
Validator("config_parse_macsec_hw_address", "0") to ConfigParseMacsecHwAddressOptionValue() as OptionValueInformation,
285+
Validator("config_parse_ether_addrs", "0") to ConfigParseEtherAddrsOptionValue() as OptionValueInformation,
286+
276287
)
277288

278289
return allValidators
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for [DHCPServerStaticLease] MACAddress= (.network).
8+
* C Function: config_parse_dhcp_static_lease_hwaddr -> parse_ether_addr (a single 6-byte Ethernet MAC).
9+
*/
10+
class ConfigParseDhcpStaticLeaseHwaddrOptionValue : SimpleGrammarOptionValues(
11+
"config_parse_dhcp_static_lease_hwaddr",
12+
SequenceCombinator(MAC_ADDRESS, EOF())
13+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for [MACVLAN] SourceMACAddress= and [MACVTAP] SourceMACAddress= (.netdev).
8+
* C Function: config_parse_ether_addrs -> a whitespace-separated list of 6-byte Ethernet MACs.
9+
*/
10+
class ConfigParseEtherAddrsOptionValue : SimpleGrammarOptionValues(
11+
"config_parse_ether_addrs",
12+
SequenceCombinator(MAC_ADDRESS, ZeroOrMore(SequenceCombinator(WhitespaceTerminal(), MAC_ADDRESS)), EOF())
13+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for [BridgeFDB] MACAddress= (.network).
8+
* C Function: config_parse_fdb_hwaddr -> parse_ether_addr (a single 6-byte Ethernet MAC).
9+
*/
10+
class ConfigParseFdbHwaddrOptionValue : SimpleGrammarOptionValues(
11+
"config_parse_fdb_hwaddr",
12+
SequenceCombinator(MAC_ADDRESS, EOF())
13+
)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for [Link] MACAddress= (.network, .link).
8+
* C Function: config_parse_hw_addr (ltype 0) -> parse_hw_addr_full(expected_len = 0): a single 4/6/16/20-byte
9+
* hardware address in colon/hyphen/dot notation, or an IPv4/IPv6 address literal.
10+
*/
11+
class ConfigParseHwAddrOptionValue : SimpleGrammarOptionValues(
12+
"config_parse_hw_addr",
13+
SequenceCombinator(HARDWARE_ADDRESS, EOF())
14+
)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for [Match] MACAddress= and [Match] PermanentMACAddress= (.network, .link).
8+
* C Function: config_parse_hw_addrs (ltype 0) -> a whitespace-separated list of hardware addresses, each
9+
* a 4/6/16/20-byte address in colon/hyphen/dot notation, or an IPv4/IPv6 address literal.
10+
*/
11+
class ConfigParseHwAddrsOptionValue : SimpleGrammarOptionValues(
12+
"config_parse_hw_addrs",
13+
SequenceCombinator(HARDWARE_ADDRESS, ZeroOrMore(SequenceCombinator(WhitespaceTerminal(), HARDWARE_ADDRESS)), EOF())
14+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for [MACsecReceiveChannel] MACAddress= and [MACsecReceiveAssociation] MACAddress= (.netdev).
8+
* C Function: config_parse_macsec_hw_address -> parse_ether_addr (a single 6-byte Ethernet MAC).
9+
*/
10+
class ConfigParseMacsecHwAddressOptionValue : SimpleGrammarOptionValues(
11+
"config_parse_macsec_hw_address",
12+
SequenceCombinator(MAC_ADDRESS, EOF())
13+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for [Neighbor] LinkLayerAddress= (and the deprecated [Neighbor] MACAddress= alias) (.network).
8+
* C Function: config_parse_neighbor_section (ltype NEIGHBOR_LINK_LAYER_ADDRESS) -> config_parse_hw_addr with
9+
* expected_len = 0: a single 4/6/16/20-byte hardware address, or an IPv4/IPv6 address literal.
10+
*/
11+
class ConfigParseNeighborLinkLayerAddressOptionValue : SimpleGrammarOptionValues(
12+
"config_parse_neighbor_section",
13+
SequenceCombinator(HARDWARE_ADDRESS, EOF())
14+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for [NetDev] MACAddress= and [Peer] MACAddress= (.netdev).
8+
* C Function: config_parse_netdev_hw_addr (ltype ETH_ALEN) -> a single 6-byte Ethernet MAC.
9+
*/
10+
class ConfigParseNetdevHwAddrOptionValue : SimpleGrammarOptionValues(
11+
"config_parse_netdev_hw_addr",
12+
SequenceCombinator(MAC_ADDRESS, EOF())
13+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for [SR-IOV] MACAddress= (.network, .link).
8+
* C Function: config_parse_sr_iov_mac -> parse_ether_addr (a single 6-byte Ethernet MAC).
9+
*/
10+
class ConfigParseSrIovMacOptionValue : SimpleGrammarOptionValues(
11+
"config_parse_sr_iov_mac",
12+
SequenceCombinator(MAC_ADDRESS, EOF())
13+
)

0 commit comments

Comments
 (0)