diff --git a/Makefile b/Makefile
index dd3d2d00f..e4b230622 100644
--- a/Makefile
+++ b/Makefile
@@ -1,58 +1,59 @@
 TMPL_DIR := templates-cfg
 OP_TMPL_DIR := templates-op
 
 .PHONY: interface_definitions
 .ONESHELL:
 interface_definitions:
 	mkdir -p $(TMPL_DIR)
 
 	find $(CURDIR)/interface-definitions/ -type f -name "*.xml" | xargs -I {} $(CURDIR)/scripts/build-command-templates {} $(CURDIR)/schema/interface_definition.rng $(TMPL_DIR) || exit 1
 
 	# XXX: delete top level node.def's that now live in other packages
+	rm -f $(TMPL_DIR)/firewall/node.def
 	rm -f $(TMPL_DIR)/interfaces/node.def
 	rm -f $(TMPL_DIR)/protocols/node.def
 	rm -f $(TMPL_DIR)/system/node.def
 	rm -f $(TMPL_DIR)/system/options/node.def
 	rm -f $(TMPL_DIR)/vpn/node.def
 	rm -f $(TMPL_DIR)/vpn/ipsec/node.def
 
 .PHONY: op_mode_definitions
 .ONESHELL:
 op_mode_definitions:
 	mkdir -p $(OP_TMPL_DIR)
 
 	find $(CURDIR)/op-mode-definitions/ -type f -name "*.xml" | xargs -I {} $(CURDIR)/scripts/build-command-op-templates {} $(CURDIR)/schema/op-mode-definition.rng $(OP_TMPL_DIR) || exit 1
 
 	# XXX: delete top level op mode node.def's that now live in other packages
 	rm -f $(OP_TMPL_DIR)/clear/node.def
 	rm -f $(OP_TMPL_DIR)/set/node.def
 	rm -f $(OP_TMPL_DIR)/show/node.def
 	rm -f $(OP_TMPL_DIR)/show/interfaces/node.def
 	rm -f $(OP_TMPL_DIR)/show/ip/node.def
 	rm -f $(OP_TMPL_DIR)/reset/node.def
 	rm -f $(OP_TMPL_DIR)/restart/node.def
 	rm -f $(OP_TMPL_DIR)/monitor/node.def
 	rm -f $(OP_TMPL_DIR)/generate/node.def
 
 .PHONY: all
 all: clean interface_definitions op_mode_definitions
 
 .PHONY: clean
 clean:
 	rm -rf $(TMPL_DIR)/*
 	rm -rf $(OP_TMPL_DIR)/*
 
 .PHONY: test
 test:
 	PYTHONPATH=python/ python3 -m "nose" --with-xunit src --with-coverage --cover-erase --cover-xml --cover-package src/conf_mode,src/op_mode,src/completion,src/helpers,src/validators,src/tests --verbose
 
 .PHONY: sonar
 sonar:
 	sonar-scanner -X -Dsonar.login=${SONAR_TOKEN}
 
 .PHONY: docs
 .ONESHELL:
 docs:
 	sphinx-apidoc -o sphinx/source/  python/
 	cd sphinx/
 	PYTHONPATH=../python make html
diff --git a/interface-definitions/firewall-options.xml b/interface-definitions/firewall-options.xml
new file mode 100644
index 000000000..2936cc703
--- /dev/null
+++ b/interface-definitions/firewall-options.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+  <node name="firewall">
+    <children>
+      <node name="options">
+        <properties>
+          <help>Firewall options/Packet manipulation</help>
+          <priority>990</priority>
+        </properties>
+        <children>
+          <tagNode name="interface" owner="sudo ${vyos_conf_scripts_dir}/firewall_options.py">
+            <properties>
+              <help>Interface clamping options</help>
+              <completionHelp>
+                <script>${vyos_completion_dir}/list_interfaces.py</script>
+              </completionHelp>
+            </properties>
+            <children>
+              <leafNode name="disable">
+                <properties>
+                  <help>Disable this rule</help>
+                  <valueless/>
+                </properties>
+              </leafNode>
+              <leafNode name="adjust-mss">
+                <properties>
+                  <help>Adjust MSS for IPv4 transit packets</help>
+                  <valueHelp>
+                    <format>500-1460</format>
+                    <description>TCP Maximum segment size in bytes</description>
+                  </valueHelp>
+                  <constraint>
+                    <validator name="numeric" argument="--range 500-1460"/>
+                  </constraint>
+                </properties>
+              </leafNode>
+              <leafNode name="adjust-mss6">
+                <properties>
+                  <help>Adjust MSS for IPv6 transit packets</help>
+                  <valueHelp>
+                    <format>1280-1492</format>
+                    <description>TCP Maximum segment size in bytes</description>
+                  </valueHelp>
+                  <constraint>
+                    <validator name="numeric" argument="--range 1280-1492"/>
+                  </constraint>
+                </properties>
+              </leafNode>
+            </children>
+          </tagNode>
+        </children>
+      </node>
+    </children>
+  </node>
+</interfaceDefinition>
diff --git a/src/conf_mode/firewall_options.py b/src/conf_mode/firewall_options.py
new file mode 100755
index 000000000..e2c306904
--- /dev/null
+++ b/src/conf_mode/firewall_options.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2018 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+import sys
+import os
+import copy
+
+from vyos.config import Config
+from vyos import ConfigError
+
+default_config_data = {
+    'intf_opts': [],
+    'new_chain4': False,
+    'new_chain6': False
+}
+
+def get_config():
+    opts = copy.deepcopy(default_config_data)
+    conf = Config()
+    if not conf.exists('firewall options'):
+        return None
+    else:
+        conf.set_level('firewall options')
+
+        # Parse configuration of each individual instance
+        if conf.exists('interface'):
+            for intf in conf.list_nodes('interface'):
+                conf.set_level('firewall options interface {0}'.format(intf))
+                config = {
+                    'intf': intf,
+                    'disabled': False,
+                    'mss4': '',
+                    'mss6': ''
+                }
+
+                # Check if individual option is disabled
+                if conf.exists('disable'):
+                    config['disabled'] = True
+
+                #
+                # Get MSS value IPv4
+                #
+                if conf.exists('adjust-mss'):
+                    config['mss4'] = conf.return_value('adjust-mss')
+
+                    # We need a marker that a new iptables chain needs to be generated
+                    if not opts['new_chain4']:
+                        opts['new_chain4'] = True
+
+                #
+                # Get MSS value IPv6
+                #
+                if conf.exists('adjust-mss6'):
+                    config['mss6'] = conf.return_value('adjust-mss6')
+
+                    # We need a marker that a new ip6tables chain needs to be generated
+                    if not opts['new_chain6']:
+                        opts['new_chain6'] = True
+
+                # Append interface options to global list
+                opts['intf_opts'].append(config)
+
+    return opts
+
+def verify(tcp):
+    # syntax verification is done via cli
+    return None
+
+def apply(tcp):
+    target = 'VYOS_FW_OPTIONS'
+
+    # always cleanup iptables
+    os.system('iptables --table mangle --delete FORWARD --jump {} >&/dev/null'.format(target))
+    os.system('iptables --table mangle --flush {} >&/dev/null'.format(target))
+    os.system('iptables --table mangle --delete-chain {} >&/dev/null'.format(target))
+
+    # always cleanup ip6tables
+    os.system('ip6tables --table mangle --delete FORWARD --jump {} >&/dev/null'.format(target))
+    os.system('ip6tables --table mangle --flush {} >&/dev/null'.format(target))
+    os.system('ip6tables --table mangle --delete-chain {} >&/dev/null'.format(target))
+
+    # Setup new iptables rules
+    if tcp['new_chain4']:
+        os.system('iptables --table mangle --new-chain {} >&/dev/null'.format(target))
+        os.system('iptables --table mangle --append FORWARD --jump {} >&/dev/null'.format(target))
+
+        for opts in tcp['intf_opts']:
+            intf = opts['intf']
+            mss = opts['mss4']
+
+            # Check if this rule iis disabled
+            if opts['disabled']:
+                continue
+
+            # adjust TCP MSS per interface
+            if mss:
+                os.system('iptables --table mangle --append {} --out-interface {} --protocol tcp ' \
+                          '--tcp-flags SYN,RST SYN --jump TCPMSS --set-mss {} >&/dev/null'.format(target, intf, mss))
+
+    # Setup new ip6tables rules
+    if tcp['new_chain6']:
+        os.system('ip6tables --table mangle --new-chain {} >&/dev/null'.format(target))
+        os.system('ip6tables --table mangle --append FORWARD --jump {} >&/dev/null'.format(target))
+
+        for opts in tcp['intf_opts']:
+            intf = opts['intf']
+            mss = opts['mss6']
+
+            # Check if this rule iis disabled
+            if opts['disabled']:
+                continue
+
+            # adjust TCP MSS per interface
+            if mss:
+                os.system('ip6tables --table mangle --append {} --out-interface {} --protocol tcp ' \
+                          '--tcp-flags SYN,RST SYN --jump TCPMSS --set-mss {} >&/dev/null'.format(target, intf, mss))
+
+    return None
+
+if __name__ == '__main__':
+
+    try:
+        c = get_config()
+        verify(c)
+        apply(c)
+    except ConfigError as e:
+        print(e)
+        sys.exit(1)