PCC exemptions

From MikroTik Wiki
Revision as of 04:46, 20 July 2011 by Fewi (talk | contribs) (Solution)
Jump to: navigation, search

Introduction

When using PCC as per the [Manual:PCC | official manual] PCC policy applies routing marks to all packets originated by the local network. These routing marks override all other routing decisions the router would normally make, including routing decisions between directly connected networks. This leads to devices on one local network being unable to reach devices on another directly connected network - something that would work out of the box without PCC. Without PCC the router would simply consult the routing table and send the packet out the appropriate port, with PCC the packet gets marked for distribution via one of the WAN links and gets sent out that way.

Solution

To restore connectivity between directly connected networks traffic between the networks must be exempted from PCC. A simple and extendable approach is to first create an address list that contains all local networks, including the WAN link networks, and to then accept all traffic between networks on the address list. The official PCC manual actually kind of does this: the first two rules in the [Manual:PCC#Policy_routing | policy routing section example] exempts traffic from the LAN to the directly connected WAN segments:

/ip firewall mangle
add chain=prerouting dst-address=10.111.0.0/24 \
   action=accept in-interface=LAN
add chain=prerouting dst-address=10.112.0.0/24 \
   action=accept in-interface=LAN

The same principle can be extended to enable multiple local networks to talk to one another. Building on the example from the manual - where the LAN addressing is 192.168.0.0/24 - let's assume there is also a DMZ addressed as 172.16.0.0/24.

First, build an address list with all the networks that are exempted from PCC amongst each other:

/ip firewall address-list
add list=local-networks address=10.111.0.0/24
add list=local-networks address=10.112.0.0/24
add list=local-networks address=192.168.0.0/24
add list=local-networks address=172.16.0.0/24

Then replace the accept rules from the original PCC example with this: </pre> /ip firewall mangle add chain=prerouting src-address-list=local-networks dst-address-list=local-networks action=accept</pre> Now traffic between all networks on the address list is exempted from PCC, and is routed as per the normal routing table.

Complete extended example

For completion's sake, here the entire rewritten PCC example taken from the [Manual:PCC | official manual], with 172.16.0.0/24 added as a DMZ:

/ip address
add address=192.168.0.1/24 interface=LAN
add address=172.16.0.1/24 interface=DMZ
add address=10.111.0.2/24 interface=ISP1
add address=10.112.0.2/24 interface=ISP2

/ip firewall address-list
add list=local-networks address=10.111.0.0/24
add list=local-networks address=10.112.0.0/24
add list=local-networks address=192.168.0.0/24
add list=local-networks address=172.16.0.0/24

/ip firewall mangle
add chain=prerouting src-address-list=local-networks \
    dst-address-list=local-networks action=accept
add chain=prerouting in-interface=ISP1 connection-mark=no-mark \ 
    action=mark-connection new-connection-mark=ISP1_conn
add chain=prerouting in-interface=ISP2 connection-mark=no-mark \
    action=mark-connection new-connection-mark=ISP2_conn
add chain=prerouting  in-interface=LAN connection-mark=no-mark \
    dst-address-type=!local per-connection-classifier=both-addresses:2/0 \
    action=mark-connection new-connection-mark=ISP1_conn 
add chain=prerouting  in-interface=LAN connection-mark=no-mark \
    dst-address-type=!local per-connection-classifier=both-addresses:2/1\
    action=mark-connection new-connection-mark=ISP2_conn 
add chain=prerouting  in-interface=DMZ connection-mark=no-mark \
    dst-address-type=!local per-connection-classifier=both-addresses:2/0 \
    action=mark-connection new-connection-mark=ISP1_conn 
add chain=prerouting  in-interface=DMZ connection-mark=no-mark \
    dst-address-type=!local per-connection-classifier=both-addresses:2/1\
    action=mark-connection new-connection-mark=ISP2_conn 
add chain=prerouting connection-mark=ISP1_conn in-interface=LAN \
    action=mark-routing new-routing-mark=to_ISP1
add chain=prerouting connection-mark=ISP2_conn in-interface=LAN \
    action=mark-routing new-routing-mark=to_ISP2
add chain=prerouting connection-mark=ISP1_conn in-interface=DMZ \
    action=mark-routing new-routing-mark=to_ISP1
add chain=prerouting connection-mark=ISP2_conn in-interface=DMZ \
    action=mark-routing new-routing-mark=to_ISP2
add chain=output connection-mark=ISP1_conn action=mark-routing \
     new-routing-mark=to_ISP1     
add chain=output connection-mark=ISP2_conn action=mark-routing \
     new-routing-mark=to_ISP2

/ip route
add dst-address=0.0.0.0/0 gateway=10.111.0.1 routing-mark=to_ISP1 \
    check-gateway=ping
add dst-address=0.0.0.0/0 gateway=10.112.0.1 routing-mark=to_ISP2 \
    check-gateway=ping
add dst-address=0.0.0.0/0 gateway=10.111.0.1 distance=1 check-gateway=ping
add dst-address=0.0.0.0/0 gateway=10.112.0.1 distance=2 check-gateway=ping

/ip firewall nat 
add chain=srcnat out-interface=ISP1 action=masquerade
add chain=srcnat out-interface=ISP2 action=masquerade