> For the complete documentation index, see [llms.txt](https://jncia-workbook.gitbook.io/workbook/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jncia-workbook.gitbook.io/workbook/junos-firewall-filters/2-adding-filter-terms.md).

# 2) Adding Filter Terms

### Pre-Work

Load the config called **filter.configured.cfg** using the **load\_config\_on\_nodes.py** script.

```
python3 load_config_on_nodes.py --lab_dir three-routers --config_filename filter.configured.cfg
```

### Lab

The filter from the previous lab is already configured on R2.

We now want to permit ICMP traffic to R2's addresses. Add a term to both of the existing filters that permits all ICMP messages, but continues to drop all other traffic to R2's local addresses.

### Answer

<details>

<summary>Expand to reveal</summary>

```
edit firewall family inet filter ge-0/0/0_filter_in_v4
set term allow_icmp from protocol icmp
set term allow_icmp then accept
insert term allow_icmp before term block_local_address

top edit firewall family inet6 filter ge-0/0/0_filter_in_v6
set term allow_icmp from next-header icmp6
set term allow_icmp then accept
insert term allow_icmp before term block_local_address
```

</details>

### Explanation

<details>

<summary>Expand to reveal</summary>

This lab tests your understanding how firewall filter terms are processed, and how to move terms around. Firewall filter terms are processed from the top down. When you add a new term to a filter, it will be placed at the very bottom. This can end up creating rule shadowing, where the new rule never gets hit because another rule higher up is more general, or "overshadowing" it.

\
For example, let's see what happens if we do not move the new term:

```
edit firewall family inet filter ge-0/0/0_filter_in_v4
set term allow_icmp from protocol icmp
set term allow_icmp then accept

top edit firewall family inet6 filter ge-0/0/0_filter_in_v6
set term allow_icmp from next-header icmp6
set term allow_icmp then accept
```

```
admin@R2> show configuration firewall 
family inet {
    filter ge-0/0/0_filter_in_v4 {
        term allow_ospf {
            from {
                protocol ospf;
            }
            then accept;
        }
        term block_local_address {
            from {
                destination-address {
                    10.1.2.2/32;
                }
            }
            then {
                discard;
            }
        }
        term allow_all {
            then accept;
        }
        term allow_icmp {   <--------------
            from {
                protocol icmp;
            }
            then accept;
        }
    }
}
family inet6 {
    filter ge-0/0/0_filter_in_v6 {
        term allow_ospf {
            from {
                next-header ospf;
            }
            then accept;
        }
        term block_local_address {
            from {
                destination-address {
                    2001:db8:1:2::2/128;
                }
            }
            then discard;
        }
        term allow_all {
            then accept;
        }
        term allow_icmp {   <-------------
            from {
                next-header icmp6;
            }
            then accept;
        }
    }
}
```

\
The `block_local_address` term is now shadowing the new term we've added, and ICMP will not be accepted to `10.1.2.2` or `2001:db8:1:2::2`:

```
admin@R1> ping 10.1.2.2           
PING 10.1.2.2 (10.1.2.2): 56 data bytes
^C
--- 10.1.2.2 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

admin@R1> ping 2001:db8:1:2::2    
PING6(56=40+8+8 bytes) 2001:db8:1:2::1 --> 2001:db8:1:2::2
^C
--- 2001:db8:1:2::2 ping6 statistics ---
2 packets transmitted, 0 packets received, 100% packet loss
```

\
We must fix this by moving the terms around, using the `insert` command.&#x20;

```
edit firewall family inet filter ge-0/0/0_filter_in_v4
insert term allow_icmp before term block_local_address

top edit firewall family inet6 filter ge-0/0/0_filter_in_v6
insert term allow_icmp before term block_local_address
```

\
The `show | compare` output is slightly hard to understand, but the `allow_icmp` term is now being moved directly under the `allow_ospf` term:

```
[edit]
admin@R2# show | compare 
[edit firewall family inet filter ge-0/0/0_filter_in_v4]
      term allow_ospf { ... }
!      term allow_icmp { ... }
[edit firewall family inet6 filter ge-0/0/0_filter_in_v6]
      term allow_ospf { ... }
!      term allow_icmp { ... }
```

\
Although `insert before` is used above, we could also `insert after` the `allow_ospf` term as well.

\
After committing the above changes, the term is moved and pings are now working:

```
admin@R1> ping 10.1.2.2           
PING 10.1.2.2 (10.1.2.2): 56 data bytes
64 bytes from 10.1.2.2: icmp_seq=0 ttl=64 time=1.781 ms

admin@R1> ping 2001:db8:1:2::2    
PING6(56=40+8+8 bytes) 2001:db8:1:2::1 --> 2001:db8:1:2::2
16 bytes from 2001:db8:1:2::2, icmp_seq=0 hlim=64 time=5.904 ms
```

</details>

### Further Reading

<https://www.reddit.com/r/networking/comments/g6bsgq/editing_juniper_firewall_filters/>

<https://community.juniper.net/discussion/edit-policy-statement-insert-or-re-order-terms>
