diff --git a/modules/ansible_generator.py b/modules/ansible_generator.py
index 4bf98b72c4169703a5bb329a66f6c4f8475fdc51..bdef379d6032099926e1830ed2543237ec28945a 100644
--- a/modules/ansible_generator.py
+++ b/modules/ansible_generator.py
@@ -12,6 +12,10 @@ def _create_config_playbooks(input_definitions):
         copy_template_file("hosts",
                            "base_provisioning/roles/hosts/tasks/main.yml")
 
+    if input_definitions["routers"]:
+        copy_template_file("routers",
+                           "base_provisioning/roles/routers/tasks/main.yml")
+
     for device in input_definitions["hosts"] + input_definitions["routers"]:
         copy_template_file("separate_devices", "base_provisioning/roles/" +
                            device["name"] + "/tasks/main.yml")
diff --git a/modules/routing_generator.py b/modules/routing_generator.py
index c1f7dd3763acd15e2ef583c6ea70cde2442a3a2b..0c19a37cc38df8316765ff646633a7d07f563575 100644
--- a/modules/routing_generator.py
+++ b/modules/routing_generator.py
@@ -46,9 +46,26 @@ def _find_iface_ip_in_network(device_name, network, input_definitions):
     raise AttributeError
 
 
+def _find_router_ip_in_br_network(other_network, input_definitions):
+    """Find a router inside of a network and returns its ip in br network."""
+    router = None
+
+    for router_mapping in input_definitions["router_mappings"]:
+        if router_mapping["network"] == other_network:
+            router = router_mapping["router"]
+
+    if not router:
+        return None
+
+    for router_mapping in input_definitions["router_mappings"]:
+        if router_mapping["router"] == router and\
+           router_mapping["network"] == BORDER_ROUTER_NETWORK_NAME:
+            return router_mapping["ip"]
+
 def _create_host_routing(target_host_name, input_definitions, flags):
     """Generate routings for the given host."""
-    routings = []
+    simple_routings = []
+    default_routings = []
 
     for host_mapping in input_definitions["net_mappings"]:
         if host_mapping["host"] == target_host_name:
@@ -57,18 +74,16 @@ def _create_host_routing(target_host_name, input_definitions, flags):
 
     if flags["border_router"]:
         routing_to_router = dict()
-        routing_to_router["default"] = True
         routing_to_router["interface_ip"] = mapping["ip"]
         gateway = _find_router_in_network(mapping["network"],
                                           input_definitions)
         routing_to_router["gateway"] = gateway
-        routings.append(routing_to_router)
+        default_routings.append(routing_to_router)
     else:
         for network in input_definitions["networks"]:
             if network["name"] == mapping["network"]:
                 continue
             routing_to_other_hosts = dict()
-            routing_to_other_hosts["default"] = False
             routing_to_other_hosts["interface_ip"] = mapping["ip"]
             gateway = _find_router_in_network(mapping["network"],
                                               input_definitions)
@@ -76,84 +91,77 @@ def _create_host_routing(target_host_name, input_definitions, flags):
             net_ip, mask = network["cidr"].split('/')
             routing_to_other_hosts["network"] = net_ip
             routing_to_other_hosts["netmask"] = mask
-            routings.append(routing_to_other_hosts)
+            simple_routings.append(routing_to_other_hosts)
 
-    return routings
+    return simple_routings, default_routings
 
 
 def _create_router_routing(router_name, input_definitions, flags):
     """Generate routings for the given router."""
-    routings = []
+    simple_routings = []
+    default_routings = []
 
     if flags["border_router"]:
         routing_to_br = dict()
-        routing_to_br["default"] = True
         interface_ip = _find_iface_ip_in_network(router_name,
                                                  BORDER_ROUTER_NETWORK_NAME,
                                                  input_definitions)
         routing_to_br["interface_ip"] = interface_ip
         routing_to_br["gateway"] = BORDER_ROUTER_IP
-        routings.append(routing_to_br)
-    else:
-        for network in input_definitions["networks"]:
-            if network["name"] in _find_networks_of_device(router_name,
-                                                           input_definitions):
-                continue
-            routing_to_other_router = dict()
-            routing_to_other_router["default"] = False
-            interface_ip = _find_iface_ip_in_network(router_name,
-                                                     network["name"],
-                                                     input_definitions)
-            routing_to_br["interface_ip"] = interface_ip
-            gateway = _find_router_in_network(network["name"],
-                                              input_definitions)
-            routing_to_other_router["gateway"] = gateway
-            net_ip, mask = network["cidr"].split('/')
-            routing_to_other_router["network"] = net_ip
-            routing_to_other_router["netmask"] = mask
-            routings.append(routing_to_other_router)
+        default_routings.append(routing_to_br)
 
-    return routings
+    return simple_routings, default_routings
 
 
 def _create_border_router_routing(input_definitions, flags):
     """Generate routings for the border router."""
-    routings = []
+    simple_routings = []
+    default_routings = []
 
     for network in input_definitions["networks"]:
         if network["name"] == BORDER_ROUTER_NETWORK_NAME:
             continue
         routing_to_hosts = dict()
-        routing_to_hosts["default"] = False
         routing_to_hosts["interface_ip"] = BORDER_ROUTER_IP
         net_ip, mask = network["cidr"].split('/')
         routing_to_hosts["network"] = net_ip
         routing_to_hosts["netmask"] = mask
-        gateway = _find_router_in_network(network["name"], input_definitions)
+        gateway = _find_router_ip_in_br_network(network["name"],
+                                                input_definitions)
         routing_to_hosts["gateway"] = gateway
-        routings.append(routing_to_hosts)
+        simple_routings.append(routing_to_hosts)
 
-    return routings
+    return simple_routings, default_routings
 
 
 def add_routings(device_name, device_type, input_definitions, flags):
-    """Generate routings for the given device.
+    """Generate simple and default routings for the given device.
 
     Returns a list of dicts with the syntax:
-    - default: True/False
-      gateway: ip of the target device
+    - gateway: ip of the target device
       interface_ip: ip of the device on the given interface
       network: ip of the network (if default is False)
       netmask: mask of the network (if default is False)
     """
     if not input_definitions["routers"]:
-        return []
+        return dict()
+
+    routings = {"simple": [], "default": []}
 
     if device_type == "host":
-        return _create_host_routing(device_name, input_definitions, flags)
+        simple, default = _create_host_routing(device_name, input_definitions,
+                                               flags)
+        routings["simple"].extend(simple)
+        routings["default"].extend(default)
     elif device_type == "router":
         if device_name != BORDER_ROUTER_NAME:
-            return _create_router_routing(device_name, input_definitions,
-                                          flags)
-        return _create_border_router_routing(input_definitions, flags)
-    return []
+            simple, default =  _create_router_routing(device_name,
+                                                      input_definitions, flags)
+            routings["simple"].extend(simple)
+            routings["default"].extend(default)
+        else:
+            simple, default = _create_border_router_routing(input_definitions,
+                                                        flags)
+            routings["simple"].extend(simple)
+            routings["default"].extend(default)
+    return routings
diff --git a/sandbox.yml b/sandbox.yml
index c53b54d0e2ac286fe728197f90e4f7f631fb0322..9a686249ec1a37139ff783e9c770d39836233e66 100644
--- a/sandbox.yml
+++ b/sandbox.yml
@@ -16,24 +16,24 @@ routers:
 
 networks:
   - name: server-switch
-    cidr: 10.10.20.0/24
+    cidr: 192.168.20.0/24
 
   - name: home-switch
-    cidr: 10.10.30.0/24
+    cidr: 192.168.30.0/24
 
 net_mappings:
     - host: server
       network: server-switch
-      ip: 10.10.20.5
+      ip: 192.168.20.5
     - host: home
       network: home-switch
-      ip: 10.10.30.5
+      ip: 192.168.30.5
 
 router_mappings:
     - router: router
       network: server-switch
-      ip: 10.10.20.1
+      ip: 192.168.20.1
     - router: router
       network: home-switch
-      ip: 10.10.30.1
+      ip: 192.168.30.1
 
diff --git a/templates/common/meta/main.yml b/templates/common/meta/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..edff08cf19051df266730d50704938dbf642e748
--- /dev/null
+++ b/templates/common/meta/main.yml
@@ -0,0 +1,15 @@
+
+galaxy_info:
+    role_name: common
+    author: Kamil Andoniadis
+    description: This role provide common macros, templates or files
+    licence: MIT
+    min_ansible_version: 2.3.3
+    platforms:
+        - name: Debian
+          versions:
+              - all
+        - name: Ubuntu
+          versions:
+              - all
+
diff --git a/templates/common/templates/config.j2 b/templates/common/templates/config.j2
new file mode 100644
index 0000000000000000000000000000000000000000..929abb78e17c01dca63d9b607556121a5283fa02
--- /dev/null
+++ b/templates/common/templates/config.j2
@@ -0,0 +1,3 @@
+{%- macro yaml_config_key_regexp(key) -%}
+    ^(#.*)?{{ key }}:.*
+{%- endmacro -%}
diff --git a/templates/common/templates/network.j2 b/templates/common/templates/network.j2
new file mode 100644
index 0000000000000000000000000000000000000000..f409e1ca0c933d39d1f5db773aa7b5ae52ca68d2
--- /dev/null
+++ b/templates/common/templates/network.j2
@@ -0,0 +1,30 @@
+{%- set common_network = namespace(
+    interfaces=[]
+) -%} 
+{%- for ansible_interface in ansible_interfaces -%} 
+    {%- set common_network.interfaces = common_network.interfaces + [hostvars[inventory_hostname]['ansible_' + ansible_interface]] -%} 
+{%- endfor -%}
+
+{%- macro mac_to_interface(mac) -%}
+    {{  
+        (   
+            common_network.interfaces | selectattr('macaddress', 'defined') |
+            selectattr('macaddress', 'equalto', mac) | map(attribute='device') | list
+        ) [0] | default('')
+    }}
+{%- endmacro -%}
+
+{%- macro ip_to_interface(ip) -%}
+    {{
+        (
+            common_network.interfaces | selectattr('ipv4', 'defined') | selectattr('ipv4.address', 'defined') |
+            selectattr('ipv4.address', 'equalto', ip) | map(attribute='device') | list
+        ) [0] | default('')
+    }}
+{%- endmacro -%}
+
+{%- macro get_inactive_interfaces() -%}
+    {{
+        common_network.interfaces | selectattr("active", "equalto", False) | list
+    }}
+{%- endmacro -%}
diff --git a/templates/config b/templates/config
index 0280902ffb67b4405908ffeb9692a19c30d4b37f..9c73ad703a3a50a2c1d5fbd1ed2a8c6e1b0f53a5 100644
--- a/templates/config
+++ b/templates/config
@@ -1,3 +1,4 @@
+{% if hosts %}
 hosts:
   {% for host in hosts %}
   - name: {{ host.name }}
@@ -8,7 +9,11 @@ hosts:
     {{ network }}: {{ ip }}
   {% endfor %}
   {% endfor %}
+{% else %}
+hosts: []
+{% endif %}
 
+{% if routers %}
 routers:
   {% for router in routers %}
   - name: {{ router.name }}
@@ -19,3 +24,6 @@ routers:
     {{ network }}: {{ ip }}
   {% endfor %}
   {% endfor %}
+{% else %}
+routers: []
+{% endif %}
diff --git a/templates/device_configuration b/templates/device_configuration
index d6951767bd0b148d236ca2e467411a70a4e9ef3f..90697be2a11c70a7579980c5badacf792197c143 100644
--- a/templates/device_configuration
+++ b/templates/device_configuration
@@ -12,39 +12,21 @@
 
 - name: Configuring hosts
   hosts: hosts
+  become: yes
   roles:
     - hosts
 
-#- name: Configuring routers
-#  hosts: routers
-#  roles:
-#    - routers
+- name: Configuring routers
+  hosts: routers
+  become: yes
+  roles:
+    - routers
 
 - name: Configuring devices separately
   hosts: all
+  become: yes
   tasks:
-    
   - name: include role
     include_role:
       name: "{{ inventory_hostname }}"
 ...
-
-
-
-
-#- name: Configuring host {{ host.host_name }}
-#  hosts: hosts
-#  become: yes
-#  tasks:
-#{% for network_ip in network_ips %}
-#  - name: Add gateway for {{ network_ip }}
-#    command: route add -net {{ network_ip }} gw {{ host.router_ip }} {{ host.interface }}
-#{% endfor %}
-
-
-#- name: Configuring border router
-#  hosts: {{ border_router_name }}
-#  become: yes
-#  roles:
-#    - br
-#...
diff --git a/templates/hosts b/templates/hosts
index 05ebab4386403488d89ef30804683cc47a0625e3..34e8296b1bf6323068655bdd749d110801b52869 100644
--- a/templates/hosts
+++ b/templates/hosts
@@ -3,8 +3,5 @@
 
 - name: Install net-tools
   apt:
-    name: net-tools
-
-# name: Delete default gateway
-#  command: route del default
+    name: "net-tools"
 ...
diff --git a/templates/interface/defaults/main.yml b/templates/interface/defaults/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..0910da5b26381303fbc25deb652f190995339756
--- /dev/null
+++ b/templates/interface/defaults/main.yml
@@ -0,0 +1,40 @@
+
+interface_default_file: /etc/network/interfaces
+interface_directory: '{{ interface_default_file }}.d'
+interface_file_name:
+interface_file: '
+    {%- if interface_file_name is defined and interface_file_name -%}
+        {{ interface_directory }}/{{ interface_file_name }}
+    {%- else -%}
+        {{ interface_default_file }}
+    {%- endif %}'
+
+interface_clean: True
+interface_mtu: 1442
+
+interface_ip:
+interface_mac:
+interface_name:
+interface_default_gateway:
+interface_routes: []
+# - gateway:
+#   network:
+#   mask:
+
+interface_device: '
+    {%- import "roles/common/templates/network.j2" as network with context -%}
+    {%- if interface_ip is defined and interface_ip -%}
+        {{ network.ip_to_interface(interface_ip) | default("") }}
+    {%- endif -%}
+    {%- if interface_mac is defined and interface_mac -%}
+        {{ network.mac_to_interface(interface_mac) | default("") }}
+    {%- endif -%}
+    {%- if interface_name is defined and interface_name -%}
+        {{ interface_name }}
+    {%- endif -%}'
+interface_identifiers:
+    interface_ip: '{{ interface_ip }}'
+    interface_mac: '{{ interface_mac }}'
+    interface_name: '{{ interface_name }}'
+interface_condition_single_interface_identifier: '{{ interface_identifiers | dict2items | map(attribute="value") | select("string") | select("ne", "") | list | length != 1 }}'
+
diff --git a/templates/interface/handlers/main.yml b/templates/interface/handlers/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..34553f66237ce5bfa2b75cff663b452a2402eae4
--- /dev/null
+++ b/templates/interface/handlers/main.yml
@@ -0,0 +1,6 @@
+
+- name: interface_networking_restart
+  service:
+      name: networking
+      state: restarted
+
diff --git a/templates/interface/meta/main.yml b/templates/interface/meta/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..58ecda581c150aac8a05d5d99e63955a1cae7073
--- /dev/null
+++ b/templates/interface/meta/main.yml
@@ -0,0 +1,19 @@
+
+dependencies:
+    - src: git@gitlab.ics.muni.cz:CSIRT-MU-public/ansible-roles/common.git
+      scm: git
+
+galaxy_info:
+    role_name: interface
+    author: Kamil Andoniadis
+    description: Basic network interface configuration
+    licence: MIT
+    min_ansible_version: 2.3.3
+    platforms:
+        - name: Debian
+          versions:
+              - all
+        - name: Ubuntu
+          versions:
+              - all
+
diff --git a/templates/interface/tasks/clean.yml b/templates/interface/tasks/clean.yml
new file mode 100644
index 0000000000000000000000000000000000000000..36a651b9e5b6bff74029196dc471219b519fcc64
--- /dev/null
+++ b/templates/interface/tasks/clean.yml
@@ -0,0 +1,31 @@
+
+- name: find all interfaces configuration files
+  find:
+      paths:
+          - '{{ interface_directory }}'
+  register: interface_extra_files
+
+- set_fact:
+      interface_config_files: '{{ (interface_extra_files.files | map(attribute="path") | list) + [interface_default_file] }}'
+
+- name: remove old iface settings for retrieved interface name
+  replace:
+      path: '{{ item }}'
+      regexp: ^iface[ \t]{{ interface_device }}[ \t].*(\n[ \t]+.*)*
+  notify: interface_networking_restart
+  with_items: '{{ interface_config_files }}'
+
+- name: remove the rest of old settings for retrieved interface name
+  replace:
+      path: '{{ item }}'
+      regexp: '^.*(?<=\s){{ interface_device }}(?=\s).*$'
+  notify: interface_networking_restart
+  with_items: '{{ interface_config_files }}'
+
+- name: remove multiple consecutive new line characters
+  replace:
+      path: '{{ item }}'
+      regexp: '(\n)+'
+      replace: '\n'
+  with_items: '{{ interface_config_files }}'
+
diff --git a/templates/interface/tasks/interface.yml b/templates/interface/tasks/interface.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9946165d81cbeb53dc6a885e4a90ba78ff099e59
--- /dev/null
+++ b/templates/interface/tasks/interface.yml
@@ -0,0 +1,25 @@
+
+- name: configure interface
+  blockinfile:
+      path: '{{ interface_file }}'
+      create: yes
+      marker: '# {mark} {{ interface_device }}'
+      block: |
+          allow-hotplug {{ interface_device }}
+          auto {{ interface_device }}
+          iface {{ interface_device }} inet static
+              address {{ interface_ip }}
+              netmask {{ interface_routes[0]['mask'] }}
+              mtu {{ interface_mtu }}
+              {% if interface_default_gateway -%}
+              gateway {{ interface_default_gateway }}
+              up route add default gw {{ interface_default_gateway }}
+              {% endif -%}
+              {% if interface_routes -%}
+              {% for route in interface_routes -%}
+              post-up ip route add {{ route['network'] }}/{{ route['mask'] }} via {{ route['gateway'] }}
+              pre-down ip route del {{ route['network'] }}/{{ route['mask'] }} via {{ route['gateway'] }}
+              {% endfor %}
+              {% endif %}
+  notify: interface_networking_restart
+
diff --git a/templates/interface/tasks/main.yml b/templates/interface/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..7e69f74724ae2ed1bf954c99f929b0a53dceccf5
--- /dev/null
+++ b/templates/interface/tasks/main.yml
@@ -0,0 +1,11 @@
+
+- name: check existence of single interface identifier
+  fail:
+      msg: there must be set exactly one of [interface_ip|interface_mac|interface_name] variables, got {{ interface_identifiers }}
+  when: interface_condition_single_interface_identifier
+
+- include: clean.yml
+  when: interface_clean is defined and interface_clean
+
+- include: interface.yml
+
diff --git a/templates/routers b/templates/routers
index 52a027509342ae79caa656470c3bf155c1233c26..2e1724cbf267a7eb1af1ecacd07ac08d3087782b 100644
--- a/templates/routers
+++ b/templates/routers
@@ -2,16 +2,9 @@
 # Configuration of all router devices
 
 - name: Enable IP forwarding
-  copy:
-    dest: "/etc/sysctl.conf"
-    content: "net.ipv4.ip_forward=1"
-
-- name: Restarting procps service
-  command: /etc/init.d/procps restart
-
-- name: Delete default gateway
-  command: route del default
-
-- name: Add default path to border router
-  command: route add default gw {{ border_router_ip }} eth3
+  sysctl:
+    name: net.ipv4.ip_forward
+    value: '1'
+    sysctl_set: yes
+    reload: yes
 ...
diff --git a/templates/separate_devices b/templates/separate_devices
index 212d1244e737062d61067f425b29d8001773aa30..83f5b705907ad11cc9df3eb4152c740346d46865 100644
--- a/templates/separate_devices
+++ b/templates/separate_devices
@@ -1,5 +1,28 @@
-- name: Add aliases
-  loop: "{{ aliases|dict2items }}"
+- name: Adding aliases
+  loop: "{{ aliases | dict2items }}"
   lineinfile:
     path: /etc/hosts
-    line: {{ item.value }} "{{ item.key }}"
+    line: "{{ item.value }} {{ item.key }}"
+
+- name: Configuring nondefault routes
+  include_role:
+    name: interface
+  vars:
+    interface_ip: "{{ route.interface_ip }}"
+    interface_routes:
+      - gateway: "{{ route.gateway }}"
+        network: "{{ route.network }}"
+        mask: "{{ route.netmask }}"
+  loop: "{{ routings.simple }}"
+  loop_control:
+    loop_var: route
+
+- name: Configuring default routes
+  include_role:
+    name: interface
+  vars:
+    interface_ip: "{{ route.interface_ip }}"
+    interface_default_gateway: "{{ route.gateway }}"
+  loop: "{{ routings.default }}"
+  loop_control:
+    loop_var: route
diff --git a/templates/vagrantfile b/templates/vagrantfile
index ae000d70a14bf288c015ff8eb92b763d593503af..664f569a5b63a022d605442c9e515a138fd51485 100644
--- a/templates/vagrantfile
+++ b/templates/vagrantfile
@@ -49,10 +49,32 @@
   {{ namespace }}.{{ item.command }} = {{ item.value }}
 {% endmacro -%}
 
+{# Macro for general items (not str int or bool) #}
+{% macro other(item, namespace) %}
+{% if item.separator %}
+  {{ namespace }}.{{ item.command }} {{ item.separator }} {{ item.value }}
+{% else %}
+  {{ namespace }}.{{ item.command }} {{ item.value }}
+{% endif %}
+{% endmacro -%}
+
 {# Macro for dictionaries #}
 {% macro dictionary(item, namespace) %}
   {{ namespace }}.{{ item.command }} = {
   {% for key, value in item.dictionary.items() %}
+    {% if loop.last %}
+      {{ key }}: {{ value }}
+    {% else %}
+      {{ key }}: {{ value }},
+    {% endif %}
+  {% endfor %}
+    }
+{% endmacro -%}
+
+{# Macro for dictionaries #}
+{% macro groups(item, namespace) %}
+  {{ namespace }}.groups = {
+  {% for key, value in item.groups.items() %}
     {% if loop.last %}
       "{{ key }}" => {{ value }}
     {% else %}
@@ -96,12 +118,16 @@ end
   {{ boolean(item, namespace) -}}
 {% elif item.type == "integer" %}
   {{ integer(item, namespace) -}}
+{% elif item.type == "other" %}
+  {{ other(item, namespace) -}}
 {% elif item.type == "provider" %}
   {{ provider(item, namespace) -}}
 {% elif item.type == "network" %}
   {{ network(item, namespace) -}}
 {% elif item.type == "dictionary" %}
   {{ dictionary(item, namespace) -}}
+{% elif item.type == "groups" %}
+  {{ groups(item, namespace) -}}
 {% endif %}
 {% endfor %}
   end