From f8ead12a3d4d41e5f6daf4c9684b82e95f91271e Mon Sep 17 00:00:00 2001 From: Dan Halperin Date: Fri, 7 Nov 2025 13:34:05 -0800 Subject: [PATCH 1/3] Junos: add parsing support for switch-options interface-mac-limit (#9580) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add parsing support for Juniper switch-options interface-mac-limit configuration, including the limit value and packet-action options (drop, drop-and-log, log, none, shutdown). This change adds grammar rules to parse both hierarchical and set-style configurations: - set switch-options interface interface-mac-limit - set switch-options interface interface-mac-limit packet-action Parsing is implemented using _null suffix rules as this configuration does not affect the Batfish data model (MAC learning is not modeled). --- Prompt: ``` Add Juniper parsing support for interface ge-0/0/0.0 { interface-mac-limit { 5; packet-action shutdown; } } set switch-options interface ge-0/0/24.0 interface-mac-limit 5 set switch-options interface ge-0/0/24.0 interface-mac-limit packet-action shutdown The docs for this are https://www.juniper.net/documentation/us/en/software/junos/cli-reference/topics/ref/statement/interface-mac-limit-edit-bridge-domains-edit-switch-options.html Read the general parsing and specific juniper docs/, and add a parsing "don't crash" test. ``` commit-id:24734f36 --- **Stack**: - #9582 - #9581 - #9580 ⬅ ⚠️ *Part of a stack created by [spr](https://github.com/ejoffe/spr). Do not merge manually using the UI - doing so may have unexpected results.* --- .../grammar/flatjuniper/FlatJuniperLexer.g4 | 6 ++- .../flatjuniper/FlatJuniper_switch_options.g4 | 37 ++++++++++++++++++- .../flatjuniper/FlatJuniperGrammarTest.java | 5 +++ .../juniper/testconfigs/interface-mac-limit | 21 +++++++++++ 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 projects/batfish/src/test/resources/org/batfish/grammar/juniper/testconfigs/interface-mac-limit diff --git a/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniperLexer.g4 b/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniperLexer.g4 index a599028109a..26d49cc2a9c 100644 --- a/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniperLexer.g4 +++ b/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniperLexer.g4 @@ -601,6 +601,8 @@ DOMAIN_NAME: 'domain-name' -> pushMode(M_Name); DOMAIN_SEARCH: 'domain-search'; DOMAIN_TYPE: 'domain-type'; +DROP: 'drop'; +DROP_AND_LOG: 'drop-and-log'; DROP_PATH_ATTRIBUTES: 'drop-path-attributes'; DROP_PROFILES: 'drop-profiles' -> pushMode(M_Name); @@ -1087,6 +1089,7 @@ INTERFACE 'interface' -> pushMode ( M_Interface ) ; +INTERFACE_MAC_LIMIT: 'interface-mac-limit'; INTERFACE_MODE: 'interface-mode'; INTERFACE_RANGE: 'interface-range' -> pushMode(M_Name); @@ -2087,6 +2090,7 @@ OVERRIDES: 'overrides'; P2MP: 'p2mp'; P2MP_OVER_LAN: 'p2mp-over-lan'; P2P: 'p2p'; +PACKET_ACTION: 'packet-action'; PACKET_LENGTH: 'packet-length' -> pushMode(M_SubRange); PACKET_LENGTH_EXCEPT: 'packet-length-except' -> pushMode(M_SubRange); @@ -2643,7 +2647,7 @@ SHARED_IKE_ID: 'shared-ike-id'; SHIM6_HEADER: 'shim6-header'; SHORTCUTS: 'shortcuts'; - +SHUTDOWN: 'shutdown'; SIGNALING: 'signaling'; SIMPLE: 'simple'; diff --git a/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniper_switch_options.g4 b/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniper_switch_options.g4 index 6816d96c47b..0b33cd0fc64 100644 --- a/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniper_switch_options.g4 +++ b/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniper_switch_options.g4 @@ -10,7 +10,8 @@ s_switch_options : SWITCH_OPTIONS ( - so_vtep_source_interface + so_interface + | so_vtep_source_interface | so_route_distinguisher | so_vrf_target | so_vrf_export @@ -42,3 +43,37 @@ so_vrf_import : VRF_IMPORT null_filler ; + +so_interface +: + INTERFACE interface_id + ( + soi_interface_mac_limit + ) +; + +soi_interface_mac_limit +: + INTERFACE_MAC_LIMIT + ( + soiiml_limit_null + | soiiml_packet_action_null + ) +; + +soiiml_limit_null +: + uint16 +; + +soiiml_packet_action_null +: + PACKET_ACTION + ( + DROP + | DROP_AND_LOG + | LOG + | NONE + | SHUTDOWN + ) +; diff --git a/projects/batfish/src/test/java/org/batfish/grammar/flatjuniper/FlatJuniperGrammarTest.java b/projects/batfish/src/test/java/org/batfish/grammar/flatjuniper/FlatJuniperGrammarTest.java index 63b592aa710..ad6fb71c90e 100644 --- a/projects/batfish/src/test/java/org/batfish/grammar/flatjuniper/FlatJuniperGrammarTest.java +++ b/projects/batfish/src/test/java/org/batfish/grammar/flatjuniper/FlatJuniperGrammarTest.java @@ -1011,6 +1011,11 @@ public void testClassOfServiceParsing() { parseJuniperConfig("juniper-class-of-service"); } + @Test + public void testInterfaceMacLimitParsing() { + parseJuniperConfig("interface-mac-limit"); + } + @Test public void testL2Topology() throws IOException { /* diff --git a/projects/batfish/src/test/resources/org/batfish/grammar/juniper/testconfigs/interface-mac-limit b/projects/batfish/src/test/resources/org/batfish/grammar/juniper/testconfigs/interface-mac-limit new file mode 100644 index 00000000000..858750fe194 --- /dev/null +++ b/projects/batfish/src/test/resources/org/batfish/grammar/juniper/testconfigs/interface-mac-limit @@ -0,0 +1,21 @@ +# RANCID-CONTENT-TYPE: juniper +set system host-name interface-mac-limit +# +# Test interface-mac-limit with limit value +set switch-options interface ge-0/0/24.0 interface-mac-limit 5 +# +# Test interface-mac-limit with packet-action shutdown +set switch-options interface ge-0/0/24.0 interface-mac-limit packet-action shutdown +# +# Test interface-mac-limit with all packet-action values +set switch-options interface ge-0/0/25.0 interface-mac-limit 10 +set switch-options interface ge-0/0/25.0 interface-mac-limit packet-action drop +# +set switch-options interface ge-0/0/26.0 interface-mac-limit 15 +set switch-options interface ge-0/0/26.0 interface-mac-limit packet-action drop-and-log +# +set switch-options interface ge-0/0/27.0 interface-mac-limit 20 +set switch-options interface ge-0/0/27.0 interface-mac-limit packet-action log +# +set switch-options interface ge-0/0/28.0 interface-mac-limit 25 +set switch-options interface ge-0/0/28.0 interface-mac-limit packet-action none From 11273bc2b7eb1139526bc8b5060eafc2740900c6 Mon Sep 17 00:00:00 2001 From: Dan Halperin Date: Fri, 7 Nov 2025 13:40:50 -0800 Subject: [PATCH 2/3] Junos: refactor system services grammar to separate SSH/FTP/TELNET (#9581) Refactor the generic `sy_services_linetype` rule into service-specific rules to enable service-specific configuration parsing. This change: 1. Replaced generic `sy_services_linetype` + `line_type` with: - `syserv_ftp` for FTP service - `syserv_ssh` for SSH service - `syserv_telnet` for TELNET service 2. Renamed `sy_services_null` to `syserv_null` for naming consistency 3. Created SSH-specific `syservs_null` rule (currently identical to `sysl_null` but will diverge when SSH-specific options are added) 4. Kept `sysl_null` for legacy use by FTP/TELNET with TODO comments for future service-specific refactoring This separation enables service-specific parsing while maintaining backward compatibility. Reference tests updated to reflect new parse tree structure. --- Prompt: ``` so, I don't like that we have a generic sysl where we mix different line types. Let's do a minimal refactoring to extract ssh. I think we get rid of system_line_type and replace it with 3 rules for the three line types. The non-SSH ones can stay sysl_null as their body with a comment to improve this later with line-type-specific code. Then let's move all the stuff we just added into system_ssh-specific rules and not in sysl_null ``` --- .../grammar/flatjuniper/FlatJuniper_system.g4 | 62 ++++++++++++++++--- .../flatjuniper/ConfigurationBuilder.java | 40 +++++++++--- tests/parsing-tests/srx-testbed.ref | 21 +++---- tests/parsing-tests/unit-tests.ref | 15 +++-- 4 files changed, 98 insertions(+), 40 deletions(-) diff --git a/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniper_system.g4 b/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniper_system.g4 index 5c1dd0331e9..6af146cfad2 100644 --- a/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniper_system.g4 +++ b/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniper_system.g4 @@ -254,29 +254,44 @@ sy_services : SERVICES ( - sy_services_linetype - | sy_services_null + syserv_ftp + | syserv_ssh + | syserv_telnet + | syserv_null ) ; -sy_services_linetype +syserv_ftp : - linetype = line_type + FTP ( apply_groups | sy_authentication_order - | sysl_null + | sysl_null // TODO: refactor to FTP-specific rules )? ; -line_type +syserv_ssh : - FTP - | SSH - | TELNET + SSH + ( + apply_groups + | sy_authentication_order + | syservs_null + )? +; + +syserv_telnet +: + TELNET + ( + apply_groups + | sy_authentication_order + | sysl_null // TODO: refactor to TELNET-specific rules + )? ; -sy_services_null +syserv_null : ( DATABASE_REPLICATION @@ -345,6 +360,33 @@ syr_encrypted_password sysl_null : + // Generic line_type options (used by FTP/TELNET pending refactoring) + ( + AUTHORIZED_KEYS_COMMAND + | AUTHORIZED_KEYS_COMMAND_USER + | CIPHERS + | CLIENT_ALIVE_COUNT_MAX + | CLIENT_ALIVE_INTERVAL + | CONNECTION_LIMIT + | FINGERPRINT_HASH + | HOSTKEY_ALGORITHM + | KEY_EXCHANGE + | MACS + | MAX_PRE_AUTHENTICATION_PACKETS + | MAX_SESSIONS_PER_CONNECTION + | NO_PASSWORDS + | NO_TCP_FORWARDING + | PROTOCOL_VERSION + | RATE_LIMIT + | REKEY + | ROOT_LOGIN + | TCP_FORWARDING + ) null_filler +; + +syservs_null +: + // SSH-specific options ( AUTHORIZED_KEYS_COMMAND | AUTHORIZED_KEYS_COMMAND_USER diff --git a/projects/batfish/src/main/java/org/batfish/grammar/flatjuniper/ConfigurationBuilder.java b/projects/batfish/src/main/java/org/batfish/grammar/flatjuniper/ConfigurationBuilder.java index c9f8210d098..49f9ac7af3c 100644 --- a/projects/batfish/src/main/java/org/batfish/grammar/flatjuniper/ConfigurationBuilder.java +++ b/projects/batfish/src/main/java/org/batfish/grammar/flatjuniper/ConfigurationBuilder.java @@ -458,7 +458,6 @@ import org.batfish.grammar.flatjuniper.FlatJuniperParser.Junos_applicationContext; import org.batfish.grammar.flatjuniper.FlatJuniperParser.Junos_application_setContext; import org.batfish.grammar.flatjuniper.FlatJuniperParser.Junos_nameContext; -import org.batfish.grammar.flatjuniper.FlatJuniperParser.Line_typeContext; import org.batfish.grammar.flatjuniper.FlatJuniperParser.Mpls_admin_groupsContext; import org.batfish.grammar.flatjuniper.FlatJuniperParser.Mpls_pathContext; import org.batfish.grammar.flatjuniper.FlatJuniperParser.Mpls_rib_nameContext; @@ -806,7 +805,6 @@ import org.batfish.grammar.flatjuniper.FlatJuniperParser.Sy_portsContext; import org.batfish.grammar.flatjuniper.FlatJuniperParser.Sy_porttypeContext; import org.batfish.grammar.flatjuniper.FlatJuniperParser.Sy_security_profileContext; -import org.batfish.grammar.flatjuniper.FlatJuniperParser.Sy_services_linetypeContext; import org.batfish.grammar.flatjuniper.FlatJuniperParser.Sy_tacplus_serverContext; import org.batfish.grammar.flatjuniper.FlatJuniperParser.Syn_serverContext; import org.batfish.grammar.flatjuniper.FlatJuniperParser.Syn_server_routing_instanceContext; @@ -814,6 +812,9 @@ import org.batfish.grammar.flatjuniper.FlatJuniperParser.Syp_disableContext; import org.batfish.grammar.flatjuniper.FlatJuniperParser.Syr_encrypted_passwordContext; import org.batfish.grammar.flatjuniper.FlatJuniperParser.Sys_hostContext; +import org.batfish.grammar.flatjuniper.FlatJuniperParser.Syserv_ftpContext; +import org.batfish.grammar.flatjuniper.FlatJuniperParser.Syserv_sshContext; +import org.batfish.grammar.flatjuniper.FlatJuniperParser.Syserv_telnetContext; import org.batfish.grammar.flatjuniper.FlatJuniperParser.Sysh_routing_instanceContext; import org.batfish.grammar.flatjuniper.FlatJuniperParser.Sysp_logical_systemContext; import org.batfish.grammar.flatjuniper.FlatJuniperParser.Syt_routing_instanceContext; @@ -4200,9 +4201,7 @@ public void enterSy_security_profile(Sy_security_profileContext ctx) { _configuration.defineFlattenedStructure(SECURITY_PROFILE, toString(ctx.name), ctx, _parser); } - @Override - public void enterSy_services_linetype(Sy_services_linetypeContext ctx) { - String name = toString(ctx.linetype); + private void enterServiceLine(String name) { _currentLogicalSystem.getJf().getLines().computeIfAbsent(name, Line::new); _currentLine = _currentLogicalSystem.getJf().getLines().get(name); @@ -4216,6 +4215,21 @@ public void enterSy_services_linetype(Sy_services_linetypeContext ctx) { } } + @Override + public void enterSyserv_ftp(Syserv_ftpContext ctx) { + enterServiceLine("ftp"); + } + + @Override + public void enterSyserv_ssh(Syserv_sshContext ctx) { + enterServiceLine("ssh"); + } + + @Override + public void enterSyserv_telnet(Syserv_telnetContext ctx) { + enterServiceLine("telnet"); + } + @Override public void enterSy_tacplus_server(Sy_tacplus_serverContext ctx) { String hostname = toString(ctx.tacplus_server_host()); @@ -7534,7 +7548,17 @@ public void exitSy_ports(Sy_portsContext ctx) { } @Override - public void exitSy_services_linetype(Sy_services_linetypeContext ctx) { + public void exitSyserv_ftp(Syserv_ftpContext ctx) { + _currentLine = null; + } + + @Override + public void exitSyserv_ssh(Syserv_sshContext ctx) { + _currentLine = null; + } + + @Override + public void exitSyserv_telnet(Syserv_telnetContext ctx) { _currentLine = null; } @@ -8250,10 +8274,6 @@ private AsPath toAsPath(As_path_exprContext path) { return unquote(ctx.getText(), ctx); } - private static @Nonnull String toString(Line_typeContext ctx) { - return ctx.getText(); - } - private @Nonnull Optional toString(Bgp_description_textContext ctx) { String description = unquote(ctx.getText(), ctx.getParent()); // Juniper requires BGP descriptions to be between 1 and 255 characters diff --git a/tests/parsing-tests/srx-testbed.ref b/tests/parsing-tests/srx-testbed.ref index 3a563644867..8cada3c7fb9 100644 --- a/tests/parsing-tests/srx-testbed.ref +++ b/tests/parsing-tests/srx-testbed.ref @@ -255,9 +255,8 @@ " SYSTEM:'system'", " (sy_services*", " SERVICES:'services'", - " (sy_services_linetype", - " linetype = (line_type*", - " SSH:'ssh')))))))", + " (syserv_ssh", + " SSH:'ssh'))))))", " NEWLINE:'\\n')", " (set_line*", " SET:'set'", @@ -268,7 +267,7 @@ " SYSTEM:'system'", " (sy_services*", " SERVICES:'services'", - " (sy_services_null*", + " (syserv_null*", " WEB_MANAGEMENT:'web-management'", " (null_filler*", " HTTP:'http'", @@ -2683,9 +2682,8 @@ " SYSTEM:'system'", " (sy_services*", " SERVICES:'services'", - " (sy_services_linetype", - " linetype = (line_type*", - " SSH:'ssh')))))))", + " (syserv_ssh", + " SSH:'ssh'))))))", " NEWLINE:'\\n')", " (set_line*", " SET:'set'", @@ -2696,7 +2694,7 @@ " SYSTEM:'system'", " (sy_services*", " SERVICES:'services'", - " (sy_services_null*", + " (syserv_null*", " WEB_MANAGEMENT:'web-management'", " (null_filler*", " HTTP:'http'", @@ -4621,9 +4619,8 @@ " SYSTEM:'system'", " (sy_services*", " SERVICES:'services'", - " (sy_services_linetype", - " linetype = (line_type*", - " SSH:'ssh')))))))", + " (syserv_ssh", + " SSH:'ssh'))))))", " NEWLINE:'\\n')", " (set_line*", " SET:'set'", @@ -4634,7 +4631,7 @@ " SYSTEM:'system'", " (sy_services*", " SERVICES:'services'", - " (sy_services_null*", + " (syserv_null*", " WEB_MANAGEMENT:'web-management'", " (null_filler*", " HTTP:'http'", diff --git a/tests/parsing-tests/unit-tests.ref b/tests/parsing-tests/unit-tests.ref index e27c6275d75..04695c41234 100644 --- a/tests/parsing-tests/unit-tests.ref +++ b/tests/parsing-tests/unit-tests.ref @@ -40274,9 +40274,8 @@ " SYSTEM:'system'", " (sy_services*", " SERVICES:'services'", - " (sy_services_linetype", - " linetype = (line_type*", - " SSH:'ssh')))))))", + " (syserv_ssh", + " SSH:'ssh'))))))", " NEWLINE:'\\n')", " (set_line*", " SET:'set'", @@ -40287,7 +40286,7 @@ " SYSTEM:'system'", " (sy_services*", " SERVICES:'services'", - " (sy_services_null*", + " (syserv_null*", " NETCONF:'netconf'", " (null_filler*", " SSH:'ssh')))))))", @@ -61586,7 +61585,7 @@ " SYSTEM:'system'", " (sy_services*", " SERVICES:'services'", - " (sy_services_null*", + " (syserv_null*", " DHCP:'dhcp'", " (null_filler*", " TRACEOPTIONS:'traceoptions'", @@ -61602,7 +61601,7 @@ " SYSTEM:'system'", " (sy_services*", " SERVICES:'services'", - " (sy_services_null*", + " (syserv_null*", " DHCP:'dhcp'", " (null_filler*", " POOL:'pool'", @@ -61622,7 +61621,7 @@ " SYSTEM:'system'", " (sy_services*", " SERVICES:'services'", - " (sy_services_null*", + " (syserv_null*", " DHCP:'dhcp'", " (null_filler*", " POOL:'pool'", @@ -61639,7 +61638,7 @@ " SYSTEM:'system'", " (sy_services*", " SERVICES:'services'", - " (sy_services_null*", + " (syserv_null*", " DHCP:'dhcp'", " (null_filler*", " POOL:'pool'", From 5c051dc269169c9e0f8c0c45338f12f9d3c68cf3 Mon Sep 17 00:00:00 2001 From: Dan Halperin Date: Fri, 7 Nov 2025 13:43:06 -0800 Subject: [PATCH 3/3] Junos: add parsing support for system services ssh options (#9582) Add parsing support for SSH boolean configuration options: - access-disable-external - allow-tcp-forwarding (replacement for deprecated tcp-forwarding) - no-challenge-response - no-password-authentication - no-passwords (already existed in sysl_null) - no-public-keys - no-tcp-forwarding (deprecated, kept for compatibility) - root-login (with null_filler to consume the login mode parameter) - tcp-forwarding (deprecated, kept for compatibility) Each option is parsed as a distinct grammar rule with _null suffix rather than being grouped in a generic _null rule. This provides grammatical precision while still indicating the options are not extracted into the Batfish data model. The `syservs_null` rule is simplified to contain only the remaining SSH options that don't yet have individual rules. --- Prompt: ``` In exactly the same style as last commit, add support for `set system services ssh allow-tcp-forwarding`: https://www.juniper.net/documentation/us/en/software/junos/cli-reference/topics/ref/statement/ssh-edit-system.html . This is a large grammar, so implement only the things that are easy and obvious. Maybe just the booleans with no parameters, like no-passwords? ``` --- .../grammar/flatjuniper/FlatJuniperLexer.g4 | 9 ++ .../grammar/flatjuniper/FlatJuniper_system.g4 | 90 +++++++++++++------ .../flatjuniper/FlatJuniperGrammarTest.java | 5 ++ .../juniper/testconfigs/system-services-ssh | 10 +++ 4 files changed, 85 insertions(+), 29 deletions(-) create mode 100644 projects/batfish/src/test/resources/org/batfish/grammar/juniper/testconfigs/system-services-ssh diff --git a/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniperLexer.g4 b/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniperLexer.g4 index 26d49cc2a9c..2b7cb78e5cb 100644 --- a/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniperLexer.g4 +++ b/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniperLexer.g4 @@ -54,6 +54,8 @@ ACCEPTED_PREFIX_LIMIT: 'accepted-prefix-limit'; ACCESS: 'access'; +ACCESS_DISABLE_EXTERNAL: 'access-disable-external'; + ACCESS_INTERNAL: 'access-internal'; ACCESS_PROFILE: 'access-profile' -> pushMode(M_Name); @@ -186,6 +188,8 @@ ALLOW_DUPLICATES: 'allow-duplicates'; ALLOW_SNOOPED_CLIENTS: 'allow-snooped-clients'; +ALLOW_TCP_FORWARDING: 'allow-tcp-forwarding'; + ALLOW_V4MAPPED_PACKETS: 'allow-v4mapped-packets'; ALWAYS_COMPARE_MED: 'always-compare-med'; @@ -1994,6 +1998,7 @@ NO_ANTI_REPLAY: 'no-anti-replay'; NO_ARP: 'no-arp'; NO_AUTO_NEGOTIATION: 'no-auto-negotiation'; +NO_CHALLENGE_RESPONSE: 'no-challenge-response'; NO_CLIENT_REFLECT: 'no-client-reflect'; NO_DECREMENT_TTL: 'no-decrement-ttl'; NO_ECMP_FAST_REROUTE: 'no-ecmp-fast-reroute'; @@ -2013,6 +2018,8 @@ NO_NEXT_HEADER: 'no-next-header'; NO_NEXTHOP_CHANGE: 'no-nexthop-change'; +NO_PASSWORD_AUTHENTICATION: 'no-password-authentication'; + NO_PASSWORDS: 'no-passwords'; NO_PEER_LOOP_CHECK: 'no-peer-loop-check'; @@ -2025,6 +2032,8 @@ NO_PREEMPT: 'no-preempt'; NO_PREPEND_GLOBAL_AS: 'no-prepend-global-as'; +NO_PUBLIC_KEYS: 'no-public-keys'; + NO_READVERTISE: 'no-readvertise'; NO_REDIRECTS: 'no-redirects'; diff --git a/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniper_system.g4 b/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniper_system.g4 index 6af146cfad2..99e818c51f4 100644 --- a/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniper_system.g4 +++ b/projects/batfish/src/main/antlr4/org/batfish/grammar/flatjuniper/FlatJuniper_system.g4 @@ -267,7 +267,7 @@ syserv_ftp ( apply_groups | sy_authentication_order - | sysl_null // TODO: refactor to FTP-specific rules + | syserv_common_null )? ; @@ -277,6 +277,16 @@ syserv_ssh ( apply_groups | sy_authentication_order + | syserv_common_null + | syservs_access_disable_external_null + | syservs_allow_tcp_forwarding_null + | syservs_no_challenge_response_null + | syservs_no_password_authentication_null + | syservs_no_passwords_null + | syservs_no_public_keys_null + | syservs_no_tcp_forwarding_null + | syservs_root_login_null + | syservs_tcp_forwarding_null | syservs_null )? ; @@ -287,7 +297,7 @@ syserv_telnet ( apply_groups | sy_authentication_order - | sysl_null // TODO: refactor to TELNET-specific rules + | syserv_common_null )? ; @@ -358,58 +368,80 @@ syr_encrypted_password ENCRYPTED_PASSWORD password = secret_string ; -sysl_null +syserv_common_null : - // Generic line_type options (used by FTP/TELNET pending refactoring) + // Options shared by SSH, FTP, and TELNET ( - AUTHORIZED_KEYS_COMMAND - | AUTHORIZED_KEYS_COMMAND_USER - | CIPHERS - | CLIENT_ALIVE_COUNT_MAX - | CLIENT_ALIVE_INTERVAL - | CONNECTION_LIMIT - | FINGERPRINT_HASH - | HOSTKEY_ALGORITHM - | KEY_EXCHANGE - | MACS - | MAX_PRE_AUTHENTICATION_PACKETS - | MAX_SESSIONS_PER_CONNECTION - | NO_PASSWORDS - | NO_TCP_FORWARDING - | PROTOCOL_VERSION + CONNECTION_LIMIT | RATE_LIMIT - | REKEY - | ROOT_LOGIN - | TCP_FORWARDING ) null_filler ; +syservs_access_disable_external_null +: + ACCESS_DISABLE_EXTERNAL +; + +syservs_allow_tcp_forwarding_null +: + ALLOW_TCP_FORWARDING +; + +syservs_no_challenge_response_null +: + NO_CHALLENGE_RESPONSE +; + +syservs_no_password_authentication_null +: + NO_PASSWORD_AUTHENTICATION +; + +syservs_no_public_keys_null +: + NO_PUBLIC_KEYS +; + syservs_null : - // SSH-specific options + // Other SSH-only options (not yet extracted) ( AUTHORIZED_KEYS_COMMAND | AUTHORIZED_KEYS_COMMAND_USER | CIPHERS | CLIENT_ALIVE_COUNT_MAX | CLIENT_ALIVE_INTERVAL - | CONNECTION_LIMIT | FINGERPRINT_HASH | HOSTKEY_ALGORITHM | KEY_EXCHANGE | MACS | MAX_PRE_AUTHENTICATION_PACKETS | MAX_SESSIONS_PER_CONNECTION - | NO_PASSWORDS - | NO_TCP_FORWARDING | PROTOCOL_VERSION - | RATE_LIMIT | REKEY - | ROOT_LOGIN - | TCP_FORWARDING ) null_filler ; +syservs_no_passwords_null +: + NO_PASSWORDS +; + +syservs_no_tcp_forwarding_null +: + NO_TCP_FORWARDING +; + +syservs_root_login_null +: + ROOT_LOGIN null_filler +; + +syservs_tcp_forwarding_null +: + TCP_FORWARDING +; + sysp_logical_system : LOGICAL_SYSTEM name = junos_name diff --git a/projects/batfish/src/test/java/org/batfish/grammar/flatjuniper/FlatJuniperGrammarTest.java b/projects/batfish/src/test/java/org/batfish/grammar/flatjuniper/FlatJuniperGrammarTest.java index ad6fb71c90e..daea950792c 100644 --- a/projects/batfish/src/test/java/org/batfish/grammar/flatjuniper/FlatJuniperGrammarTest.java +++ b/projects/batfish/src/test/java/org/batfish/grammar/flatjuniper/FlatJuniperGrammarTest.java @@ -1016,6 +1016,11 @@ public void testInterfaceMacLimitParsing() { parseJuniperConfig("interface-mac-limit"); } + @Test + public void testSystemServicesSshParsing() { + parseJuniperConfig("system-services-ssh"); + } + @Test public void testL2Topology() throws IOException { /* diff --git a/projects/batfish/src/test/resources/org/batfish/grammar/juniper/testconfigs/system-services-ssh b/projects/batfish/src/test/resources/org/batfish/grammar/juniper/testconfigs/system-services-ssh new file mode 100644 index 00000000000..faae7317cc4 --- /dev/null +++ b/projects/batfish/src/test/resources/org/batfish/grammar/juniper/testconfigs/system-services-ssh @@ -0,0 +1,10 @@ +# RANCID-CONTENT-TYPE: juniper +set system host-name system-services-ssh +# +# Test simple SSH boolean options +set system services ssh access-disable-external +set system services ssh allow-tcp-forwarding +set system services ssh no-challenge-response +set system services ssh no-password-authentication +set system services ssh no-passwords +set system services ssh no-public-keys