Nftables vs dockerd

Hi,

Not sure if dockerd package should support nftables (via iptables-legacy) or not even with wrapper. Also fw4 may have possible bugs which manifested while i am using docker but may not necessarily due to docker. (this is a long post, sorry)

Any insight is welcomed.

The environment
I am using openwrt 22.03-rc5 x86 with overlay filesystem (in VMware, probably that's not relevant though).

after installing dockerd, docker and docker-compose packages, and enable/start dockerd service everything looks ok. using package default dockerd config file, only enabling extra args in firewall section as below:

/etc/config/dockerd
config firewall 'firewall'
        option device 'docker0'
        list blocked_interfaces 'wan'
        option extra_iptables_args '--match conntrack ! --ctstate RELATED,ESTABLISHED' # allow outbound connections

dockerd creates basic config including network and firewall related as below:

Summary
$ uci show | grep docker
dockerd.globals=globals
dockerd.globals.data_root='/opt/docker/'
dockerd.globals.log_level='info'
dockerd.globals.iptables='1'
dockerd.firewall=firewall
dockerd.firewall.device='docker0'
dockerd.firewall.blocked_interfaces='wan'
dockerd.firewall.extra_iptables_args='--match conntrack ! --ctstate RELATED,ESTABLISHED'
firewall.docker=zone
firewall.docker.input='ACCEPT'
firewall.docker.output='ACCEPT'
firewall.docker.forward='ACCEPT'
firewall.docker.name='docker'
firewall.docker.network='docker'
firewall.@forwarding[1].src='docker'
firewall.@forwarding[2].dest='docker'
network.docker=interface
network.docker.device='docker0'
network.docker.proto='none'
network.docker.auto='0'
network.@device[2].name='docker0'

$ uci show firewall | grep forwarding | grep '1\|2'
firewall.@forwarding[1]=forwarding
firewall.@forwarding[1].src='docker'
firewall.@forwarding[1].dest='wan'
firewall.@forwarding[2]=forwarding
firewall.@forwarding[2].src='lan'
firewall.@forwarding[2].dest='docker'

as docker using iptables as a dependency iptables-zz-legacy is intalled too:

Summary
$ opkg depends dockerd
dockerd depends on:
        libc
        ca-certificates
        containerd
        iptables
        iptables-mod-extra
        ip6tables
        kmod-ipt-nat6
        libseccomp
        kmod-ipt-nat
        kmod-ipt-physdev
        kmod-nf-ipvs
        kmod-veth
        libnetwork
        tini
        uci-firewall

$ opkg list-installed | grep iptables
iptables-mod-extra - 1.8.7-7
iptables-zz-legacy - 1.8.7-7

I want to use adguard home docker container so it requires:

  • to be available for lan clients as DNS resolver
  • to access wan to reach upstream DNS servers

Now, the findings/problems/questions.

dockerd automatically creates via iptables docker related firewall rules:

Summary
$ iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N DOCKER
-N DOCKER-ISOLATION-STAGE-1
-N DOCKER-ISOLATION-STAGE-2
-N DOCKER-USER
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
-A DOCKER-USER -i eth0 -o docker0 -m conntrack ! --ctstate RELATED,ESTABLISHED -j REJECT --reject-with icmp-port-unreachable
-A DOCKER-USER -j RETURN

using the approach am used to, on top of these rules, i allow docker -> wan forwarding in firewall zone config, but with the extra args in dockerd config it is limitied to related, established traffic. so I'd hope am good to go in a reasonable secure way.

But this is not working "out-of-box" as expected.

the problems:

  1. some rule are missing from fw4/nftables still, somehow there is a disconnect on the dcokerd-iptables-nftables path.

the system generated fw4 rules are:

$  nft list ruleset
table inet fw4 {
        chain input {
                type filter hook input priority filter; policy accept;
                iifname "lo" accept comment "!fw4: Accept traffic from loopback"
                ct state established,related accept comment "!fw4: Allow inbound established and related flows"
                tcp flags syn / fin,syn,rst,ack jump syn_flood comment "!fw4: Rate limit TCP syn packets"
                iifname "br-lan" jump input_lan comment "!fw4: Handle lan IPv4/IPv6 input traffic"
                iifname "eth0" jump input_wan comment "!fw4: Handle wan IPv4/IPv6 input traffic"
                iifname "eth4" jump input_console comment "!fw4: Handle console IPv4/IPv6 input traffic"
                iifname "br-guest" jump input_guest comment "!fw4: Handle guest IPv4/IPv6 input traffic"
        }

        chain forward {
                type filter hook forward priority filter; policy drop;
                ct state established,related accept comment "!fw4: Allow forwarded established and related flows"
                iifname "br-lan" jump forward_lan comment "!fw4: Handle lan IPv4/IPv6 forward traffic"
                iifname "eth0" jump forward_wan comment "!fw4: Handle wan IPv4/IPv6 forward traffic"
                iifname "eth4" jump forward_console comment "!fw4: Handle console IPv4/IPv6 forward traffic"
                iifname "br-guest" jump forward_guest comment "!fw4: Handle guest IPv4/IPv6 forward traffic"
                iifname "docker0" jump forward_docker comment "fix: handle docker forward traffic" # (1) <--- this rule is missing by default
                jump handle_reject
        }

        chain output {
                type filter hook output priority filter; policy accept;
                oifname "lo" accept comment "!fw4: Accept traffic towards loopback"
                ct state established,related accept comment "!fw4: Allow outbound established and related flows"
                oifname "br-lan" jump output_lan comment "!fw4: Handle lan IPv4/IPv6 output traffic"
                oifname "eth0" jump output_wan comment "!fw4: Handle wan IPv4/IPv6 output traffic"
                oifname "eth4" jump output_console comment "!fw4: Handle console IPv4/IPv6 output traffic"
                oifname "br-guest" jump output_guest comment "!fw4: Handle guest IPv4/IPv6 output traffic"
        }

        chain prerouting {
                type filter hook prerouting priority filter; policy accept;
                iifname "br-lan" jump helper_lan comment "!fw4: Handle lan IPv4/IPv6 helper assignment"
                iifname "eth4" jump helper_console comment "!fw4: Handle console IPv4/IPv6 helper assignment"
                iifname "br-guest" jump helper_guest comment "!fw4: Handle guest IPv4/IPv6 helper assignment"
        }

        chain handle_reject {
                meta l4proto tcp reject with tcp reset comment "!fw4: Reject TCP traffic"
                reject comment "!fw4: Reject any other traffic"
        }

        chain syn_flood {
                limit rate 25/second burst 50 packets return comment "!fw4: Accept SYN packets below rate-limit"
                drop comment "!fw4: Drop excess packets"
        }

        chain input_lan {
                jump accept_from_lan
        }

        chain output_lan {
                jump accept_to_lan
        }

        chain forward_lan {
                jump accept_to_wan comment "!fw4: Accept lan to wan forwarding"
                jump accept_to_docker comment "!fw4: Accept lan to docker forwarding"
                jump accept_to_lan
        }

        chain helper_lan {
        }

        chain accept_from_lan {
                iifname "br-lan" counter packets 1 bytes 48 accept comment "!fw4: accept lan IPv4/IPv6 traffic"
        }

        chain accept_to_lan {
                oifname "br-lan" counter packets 0 bytes 0 accept comment "!fw4: accept lan IPv4/IPv6 traffic"
        }

        chain input_wan {
                meta nfproto ipv4 udp dport 68 counter packets 0 bytes 0 accept comment "!fw4: Allow-DHCP-Renew"
                icmp type echo-request counter packets 0 bytes 0 accept comment "!fw4: Allow-Ping"
                meta nfproto ipv4 meta l4proto igmp counter packets 0 bytes 0 accept comment "!fw4: Allow-IGMP"
                meta nfproto ipv6 udp dport 546 counter packets 0 bytes 0 accept comment "!fw4: Allow-DHCPv6"
                ip6 saddr fe80::/10 icmpv6 type . icmpv6 code { mld-listener-query . no-route, mld-listener-report . no-route, mld-listener-done . no-route, mld2-listener-report . no-route } counter packets 0 bytes 0 accept comment "!fw4: Allow-MLD"
                icmpv6 type { destination-unreachable, time-exceeded, echo-request, echo-reply, nd-router-solicit, nd-router-advert } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Input"
                icmpv6 type . icmpv6 code { packet-too-big . no-route, parameter-problem . no-route, nd-neighbor-solicit . no-route, nd-neighbor-advert . no-route, parameter-problem . admin-prohibited } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Input"
                jump reject_from_wan
        }

        chain output_wan {
                jump accept_to_wan
        }

        chain forward_wan {
                icmpv6 type { destination-unreachable, time-exceeded, echo-request, echo-reply } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Forward"
                icmpv6 type . icmpv6 code { packet-too-big . no-route, parameter-problem . no-route, parameter-problem . admin-prohibited } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Forward"
                meta l4proto esp counter packets 0 bytes 0 jump accept_to_lan comment "!fw4: Allow-IPSec-ESP"
                udp dport 500 counter packets 0 bytes 0 jump accept_to_lan comment "!fw4: Allow-ISAKMP"
                jump reject_to_wan
        }

        chain accept_to_wan {
                oifname "eth0" counter packets 211 bytes 16020 accept comment "!fw4: accept wan IPv4/IPv6 traffic"
        }

        chain reject_from_wan {
                iifname "eth0" counter packets 2732 bytes 748966 jump handle_reject comment "!fw4: reject wan IPv4/IPv6 traffic"
        }

        chain reject_to_wan {
                oifname "eth0" counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject wan IPv4/IPv6 traffic"
        }

        chain input_console {
                ct status dnat accept comment "!fw4: Accept port redirections"
                jump accept_from_console
        }

        chain output_console {
                jump accept_to_console
        }

        chain forward_console {
                ct status dnat accept comment "!fw4: Accept port forwards"
                jump reject_to_console
        }

        chain helper_console {
        }

        chain accept_from_console {
                iifname "eth4" counter packets 2735 bytes 749118 accept comment "!fw4: accept console IPv4/IPv6 traffic"
        }

        chain accept_to_console {
                oifname "eth4" counter packets 6 bytes 1080 accept comment "!fw4: accept console IPv4/IPv6 traffic"
        }

        chain reject_to_console {
                oifname "eth4" counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject console IPv4/IPv6 traffic"
        }

        chain input_docker {
                jump accept_from_docker
        }

        chain output_docker {
                jump accept_to_docker
        }

        chain forward_docker {
                jump accept_to_wan comment "!fw4: Accept docker to wan forwarding"
                jump accept_to_docker
        }

        chain helper_docker {
        }

        chain accept_from_docker {
        }

        chain accept_to_docker { # (2) <--- this section is empty by default
               oifname "docker0" accept comment "fix: accept traffic to docker"
        }

        chain dstnat {
                type nat hook prerouting priority dstnat; policy accept;
                iifname "eth4" jump dstnat_console comment "!fw4: Handle console IPv4/IPv6 dstnat traffic"
                iifname "br-guest" jump dstnat_guest comment "!fw4: Handle guest IPv4/IPv6 dstnat traffic"
        }

        chain srcnat {
                type nat hook postrouting priority srcnat; policy accept;
                oifname "eth0" jump srcnat_wan comment "!fw4: Handle wan IPv4/IPv6 srcnat traffic"
        }

        chain srcnat_wan {
                meta nfproto ipv4 masquerade comment "!fw4: Masquerade IPv4 wan traffic"
        }

        chain dstnat_console {
               [ reduced ]
        }

        chain raw_prerouting {
                type filter hook prerouting priority raw; policy accept;
        }

        chain raw_output {
                type filter hook output priority raw; policy accept;
        }

        chain mangle_prerouting {
                type filter hook prerouting priority mangle; policy accept;
        }

        chain mangle_postrouting {
                type filter hook postrouting priority mangle; policy accept;
        }

        chain mangle_input {
                type filter hook input priority mangle; policy accept;
        }

        chain mangle_output {
                type route hook output priority mangle; policy accept;
        }

        chain mangle_forward {
                type filter hook forward priority mangle; policy accept;
                iifname "eth0" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 ingress MTU fixing"
                oifname "eth0" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 egress MTU fixing"
        }

        chain dstnat_lan {
        }

        chain input_guest {
                ct status dnat accept comment "!fw4: Accept port redirections"
                jump accept_from_guest
        }

        chain output_guest {
                jump accept_to_guest
        }

        chain forward_guest {
                jump accept_to_wan comment "!fw4: Accept guest to wan forwarding"
                ct status dnat accept comment "!fw4: Accept port forwards"
                jump reject_to_guest
        }

        chain helper_guest {
        }

        chain accept_from_guest {
                iifname "br-guest" counter packets 0 bytes 0 accept comment "!fw4: accept guest IPv4/IPv6 traffic"
        }

        chain accept_to_guest {
                oifname "br-guest" counter packets 0 bytes 0 accept comment "!fw4: accept guest IPv4/IPv6 traffic"
        }

        chain reject_to_guest {
                oifname "br-guest" counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject guest IPv4/IPv6 traffic"
        }

        chain dstnat_guest {
                [ reduced ]
        }
}

the two missing rules are required to allow container to send traffic to wan and receive reply traffic.

  1. using config include in firewall works partially.

config include
        option type 'nftables'
        option path '/etc/forward.nft'
        option position 'chain-append'
        option chain 'forward'

config include
        option type 'nftables'
        option path '/etc/accept_to_docker.nft'
        option position 'chain-prepend'
        option chain 'accept_to_docker'

$ cat /etc/forward.nft
iifname docker0 jump forward_docker comment "fix: handle docker forward traffic"

$ cat /etc/accept_to_docker.nft
oifname docker0  accept comment "fix: accept traffic to docker"

while the first include works and append the missing rule (1), the second for some reason does not although service firewall restart completes without error. i have to add manually the missing rule (2). is this a (known) bug or i miss something? setting position either direction (append or prepend) has no effect by the way.

  1. a strange fw4 thing: usually if i add comments to an /etc/config/<service> file it remains even if reboot server and or restart service. this is not the case with firewall service: if i comment out a section and restart the service the whole commented section disappear from the file.

any thoughts please?

thanks

There's no include hooks for the {accept,reject,drop}_to_* chains yet, that's why an include at this position does not work. What you try to achieve with extra includes does look like a normal zone declaration + associated rules though, how is the docker zone defined?

Something like this should do the trick:

config zone
  option name docker
  list device docker0
  option input reject
  option forward reject
  option output accept

config forwarding
  option src docker
  option dest wan

oh, i see. that explains the why.

dockerd service takes care for zone setup:

        if ! uci_quiet get firewall.${zone}; then
                logger -t "dockerd-init" -p notice "Adding firewall zone '${zone}' to firewall config"
                uci_quiet add firewall zone
                uci_quiet rename firewall.@zone[-1]="${zone}"
                uci_quiet set firewall.@zone[-1].input="ACCEPT"
                uci_quiet set firewall.@zone[-1].output="ACCEPT"
                uci_quiet set firewall.@zone[-1].forward="ACCEPT"
                uci_quiet set firewall.@zone[-1].name="${zone}"
                uci_quiet commit firewall

But in spite of the all three accept rule, i think there is a disconnect because, unlike lan zone, all the necessary chains / rules are missing or blank. I tried to do the same as you suggest but that's not working: the accept_to_wan jump rule is missing from the forward_docker chain in spite of below config

i hope am doing something wrong and there is an obvious fix, but it feels somehow that automatic chain logic which works nicely for lan zone might not work with on the fly generated zones together with legacy iptables logic. that's my guess, but hope really am doing just something stupid.

yikes - that's awful and the reason why your comments are lost btw, it automatically scribbles into the firewall uci configuration and commits the changes without any user consent/interaction. And worse, it does it on every docker service restart.

Furthermore it appears to not actually add the docker0 device to the zone, essentially creating an empty chain structure not matching any device.

I'd consider that a packaging bug that should be fixed, there's more appropriate mechanisms available.

Which happens when a zone declaration can not resolve to any actual network device or subnet. Did you ensure that
a) that broken dockerd init script logic is not interfering
b) your manual docker zone declaration includes list device docker0
?

Edit:
I took a look at the script myself and see that it adds the docker bridge as logical network later. It seems however that it does not set option bridge_empty 1 to the bridge device declaration, so the docker bridge netdev is not actually spawned until something is attached to it, means the firewall will initially come up empty since there will be no docker bridge netdev to emit rules for. It might be the reason for your issue. Is the firewall populating those empty chains once a container attaches to the docker bridge? If not does it do after a manual fw4 restart?

what happens is the following:

service dockerd starts, creates the docker0 bridge and all the other stuff (e.g. zone config) etc, and also starts the containers, meaning the respective veth devices are also added to docker0 bridge - but the relevant nft rules are still missing. the iptables rules are created too (e.g. the NAT rules required for docker-proxy) but the docker part is not chained into inet fw4 table, so e.g. this rule in chain forward "iifname "docker0" jump forward_docker" is missing hence no forwarded traffic reaching docker0 and so on. it looks as there is openwrt and docker world separately, which normally would be ok (=very secure) but my expectation is after setting

config forwarding
  option src docker
  option dest wan

would the two worlds meet.

i'll play with option bridge_empty 1 and report back.

@jow, thank your for looking into this.

i added the empty bridge option to init script but it does not help.

  1. reset to default settings, no additional zone config whatsoever, only the service created 3xACCEPT docker zone.
    it ends up having these docker related chains / rules:
 chain input_docker {
                 jump accept_from_docker
         }
 
         chain output_docker {
                 jump accept_to_docker
         }
 
         chain forward_docker {
                 jump accept_to_docker
         }
 
         chain helper_docker {
         }
 
         chain accept_from_docker {
         }
 
         chain accept_to_docker {
         }

no other docker related config: neither in input, output or forward chain in spite docker zone config all 3 ACCEPT.

with this setup container starts, my lan interface is 10.0.0.1 and docker container is bind to 10.0.0.2 which is an alias for lan. container is adguard home DNS resolver.

$ docker ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED        STATUS         PORTS                                                                                                                                                                                                                                                                                                                                NAMES
c28128f7dab5   adguard/adguardhome   "/opt/adguardhome/Ad…"   27 hours ago   Up 7 minutes   10.0.0.2:53->53/tcp, 10.0.0.2:80->80/tcp, 10.0.0.2:53->53/udp, 10.0.0.2:443->443/udp, 10.0.0.2:443->443/tcp, 10.0.0.2:784->784/udp, 67-68/udp, 10.0.0.2:853->853/tcp, 10.0.0.2:3000->3000/tcp, 10.0.0.2:853->853/udp, 3001/tcp, 10.0.0.2:5443->5443/udp, 10.0.0.2:5443->5443/tcp, 10.0.0.2:8853->8853/udp, 3000-3001/udp, 6060/tcp   adguard

running DNS request against adguard fails:

 $ nslookup google.com 10.0.0.2
 Server:         10.0.0.2
 Address:        10.0.0.2:53
 
 ;; connection timed out; no servers could be reached

  1. set forwarding docker -> wan in docker zone config:
 firewall.@forwarding[2]=forwarding
 firewall.@forwarding[2].src='docker'
 firewall.@forwarding[2].dest='wan'

now, as should, there is a new rule in forward_docker chain but still nothing in forward chain:

 chain forward {
                 type filter hook forward priority filter; policy drop;
                 ct state established,related accept comment "!fw4: Allow forwarded established and related flows"
                 iifname "br-lan" jump forward_lan comment "!fw4: Handle lan IPv4/IPv6 forward traffic"
                 iifname "eth0" jump forward_wan comment "!fw4: Handle wan IPv4/IPv6 forward traffic"
                 iifname "eth4" jump forward_console comment "!fw4: Handle console IPv4/IPv6 forward traffic"
                 iifname "br-guest" jump forward_guest comment "!fw4: Handle guest IPv4/IPv6 forward traffic"
 				jump handle_reject
         }
 		
 chain input_docker {
 		jump accept_from_docker
 }
 
 chain output_docker {
 		jump accept_to_docker
 }
 
 chain forward_docker {
 		jump accept_to_wan comment "!fw4: Accept docker to wan forwarding"
 		jump accept_to_docker
 }
 
 chain helper_docker {
 }
 
 chain accept_from_docker {
 }
 
 chain accept_to_docker {
 }

DNS request still fails:

$ nslookup google.com 10.0.0.2
Server:         10.0.0.2
Address:        10.0.0.2:53

;; connection timed out; no servers could be reached

  1. adding missing rules by hand to forward and to accept_to_docker chain:
nft list chain inet fw4 forward; nft list chain inet fw4 forward_docker; nft list chain inet fw4 accept_to_d
ocker
table inet fw4 {
        chain forward {
                type filter hook forward priority filter; policy drop;
                ct state established,related accept comment "!fw4: Allow forwarded established and related flows"
                iifname "br-lan" jump forward_lan comment "!fw4: Handle lan IPv4/IPv6 forward traffic"
                iifname "eth0" jump forward_wan comment "!fw4: Handle wan IPv4/IPv6 forward traffic"
                iifname "eth4" jump forward_console comment "!fw4: Handle console IPv4/IPv6 forward traffic"
                iifname "br-guest" jump forward_guest comment "!fw4: Handle guest IPv4/IPv6 forward traffic"
                iifname "docker0" jump forward_docker comment "added by me"
                jump handle_reject
        }
}
table inet fw4 {
        chain forward_docker {
                jump accept_to_wan comment "!fw4: Accept docker to wan forwarding"
                jump accept_to_docker
        }
}
table inet fw4 {
        chain accept_to_docker {
                oifname "docker0" accept comment "added by me"
        }
}

and finally DNS is working:

$ nslookup google.com 10.0.0.2
Server:         10.0.0.2
Address:        10.0.0.2:53

Non-authoritative answer:
Name:   google.com
Address: 216.58.212.206

Non-authoritative answer:
Name:   google.com
Address: 2a00:1450:4009:823::200e

note: all this with the same docker config as in first post, i.e. list blocked_interfaces wan with the extra iptables args, which adds this legacy firewall rule too but this works as expected:

-A DOCKER-USER -i eth0 -o docker0 -m conntrack ! --ctstate RELATED,ESTABLISHED -j REJECT --reject-with icmp-port-unreachable

Problem remains, the firewall is not able to resolve the actual device tied to the "docker" zone. What's reported by ifstatus docker when all chains are empty? I think somewhere along that entire setup path there's some ubus call network reload or ifup docker missing.

I see that the dockerd init script calls reload_config but it registers the logical docker interface with option auto 0, which means it will not get brought up until the user manually invokes ifup docker (or (re)start in the gui).

changing /etc/init.d/dockerd like this

 uciadd() {
...
        if [ "$(find_network_device "$device")" = "" ]; then
                logger -t "dockerd-init" -p notice "Adding bridge device '${device}' to network config"
                uci_quiet add network device
                uci_quiet set network.@device[-1].type="bridge"
                uci_quiet set network.@device[-1].name="${device}"
                uci_quiet set network.@device[-1].bridge_empty='1' # <-- add this new bridge option
                uci_quiet commit network
[...]

       reload_config
       ifup docker

seems to solve the issue. i can even set docker zone forward=REJECT.

@jow, thanks for the guidance!

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.