Why I can send packets through `eth0` but not `eth1` in Docker container? - python-3.x

I created a docker container and connected it to two bridge networks as:
# network 1
docker network create --driver=bridge network1 --subnet=172.56.0.0/24
#network 2
docker network create --driver=bridge network2 --subnet=172.56.1.0/24
docker run \
--name container \
--privileged \
--cap-add=ALL -d \
-v /dev:/dev \
--network network1 \
-v /lib/modules:/lib/modules \
container-image tail -f /dev/null
docker network connect network2 container
Now, if I run ip addr inside container, I have two ethernet network interfaces:
6551: eth0#if6552: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:38:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.56.0.2/24 brd 172.56.0.255 scope global eth0
valid_lft forever preferred_lft forever
6553: eth1#if6554: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:38:01:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.56.1.2/24 brd 172.56.1.255 scope global eth1
valid_lft forever preferred_lft forever
I'm using scapy to send/receive through IP and ICMP protocol, with something like this:
from scapy.all import *
import sys
src = sys.argv[1]
dst = sys.argv[2]
msg = "Hello World!"
packet = IP(src = src, dst = dst)/ICMP()/msg
data = sr1(packet).load.decode('utf-8')
print(f"Received {data!r}")
I'm able to run it when src = 172.56.0.2 and dst = www.google.com or when I'm using eth0 as a source, but if I change it to src = 172.56.1.2, it won't work at all. Is there anything wrong with my eth1 interface here? Any help would be appreciated.

The problem is the routing table. Take a look at conf.route:
>>> from scapy.all import *
>>> conf.route
Network Netmask Gateway Iface Output IP Metric
0.0.0.0 0.0.0.0 172.56.0.1 eth0 172.56.0.2 0
127.0.0.0 255.0.0.0 0.0.0.0 lo 127.0.0.1 1
172.56.0.0 255.255.255.0 0.0.0.0 eth0 172.56.0.2 0
172.56.1.0 255.255.255.0 0.0.0.0 eth1 172.56.1.2 0
In the above route table, the default route is via 172.56.0.1. Any attempt to reach an address that isn't on a directly connected network will be sent via the default gateway, which is only reachable via eth0. If you want your request to go out eth1, you need to modify your routing table. For example, we can replace the default route:
>>> conf.route.delt(net='0.0.0.0/0', gw='172.56.0.1', metric=0)
>>> conf.route.add(net='0.0.0.0/0', gw='172.56.1.1', metric=0)
>>> conf.route
Network Netmask Gateway Iface Output IP Metric
0.0.0.0 0.0.0.0 172.56.1.1 eth1 172.56.1.2 0
127.0.0.0 255.0.0.0 0.0.0.0 lo 127.0.0.1 1
172.56.0.0 255.255.255.0 0.0.0.0 eth0 172.56.0.2 0
172.56.1.0 255.255.255.0 0.0.0.0 eth1 172.56.1.2 0
With this modified routing table, our requests will be sent out eth1.
If we assume that the appropriate gateway will always be the .1 address associated with the source interface, we can rewrite your code like this to automatically apply the correct route:
from scapy.all import *
import sys
import ipaddress
src = ipaddress.ip_interface(sys.argv[1])
dst = sys.argv[2]
gw = src.network[1]
conf.route.routes = [route for route in conf.route.routes if route[1] != 0]
conf.route.add(net='0.0.0.0/0', gw=f'{gw}', metric=0)
msg = "Hello World!"
packet = IP(src = f'{src.ip}', dst=dst)/ICMP()/msg
data = sr1(packet).load.decode('utf-8')
print(f"Received {data!r}")
With the modified code, the first argument (sys.argv[1]) needs to be an address/mask expression. This now works with both interface addresses:
root#bacb8598b801:~# python sendpacket.py 172.56.0.2/24 8.8.8.8
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
Received 'Hello World!'
root#bacb8598b801:~# python sendpacket.py 172.56.1.2/24 8.8.8.8
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
Received 'Hello World!'
Watching tcpdump on the two bridge interfaces, you can see that traffic is being routed via the expected interface for each source address.

Related

Strongswan: packets received and decrypted correctly but not forwarded

I have a Lan-to-Lan vpn tunnel between Cisco CSR router and Strongswan. On Strongswan i see:
[root#ip-172-31-20-224 log]# strongswan status
Security Associations (1 up, 0 connecting):
tenant-13[2]: ESTABLISHED 66 minutes ago, 172.31.20.224[local_public_ip]...remote_public_ip[remote_public_ip]
tenant-13{3}: INSTALLED, TRANSPORT, reqid 1, ESP in UDP SPIs: cdf35340_i cb506e65_o
tenant-13{3}: 172.31.20.224/32 === remote_public_ip/32
tenant-13{147}: INSTALLED, TUNNEL, reqid 3, ESP in UDP SPIs: ca2c0328_i 0295d7bf_o
tenant-13{147}: 0.0.0.0/0 === 0.0.0.0/0
My crypto SA's allow for 0/0 -> 0/0. So all looks good.
I do receive encrypted packet on Strongswan and those are decrypted correctly, example: we can see that on virtual vti interface the udp packets are received (decrypted correctly):
[root#ip-172-31-20-224 log]# tcpdump -i vti13 -n udp port 3000
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on vti13, link-type RAW (Raw IP), capture size 262144 bytes
11:19:57.834374 IP 192.168.1.116.54545 > X.X.X.X.hbci: UDP, length 340
Now X.X.X.X is a public ip address and those packets should be forwarded (out via eth0 using default routing), but i do not see those when looking via tcpdump:
[root#ip-172-31-20-224 log]# tcpdump -i eth0 -n host X.X.X.X
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
^C
0 packets captured
I have only one physical interface (eth0, transport for ipsec and default route) + one virtual (for decrypted traffic). So the traffic after decryption should be sent back out via the same eth0 interface:
[root#ip-172-31-20-224 log]# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
link/ether 02:ab:39:97:b0:7e brd ff:ff:ff:ff:ff:ff
inet 172.31.20.224/20 brd 172.31.31.255 scope global dynamic eth0
valid_lft 2673sec preferred_lft 2673sec
inet6 fe80::ab:39ff:fe97:b07e/64 scope link
valid_lft forever preferred_lft forever
3: ip_vti0#NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
9: vti13#NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1400 qdisc noqueue state UNKNOWN group default qlen 1000
link/ipip 172.31.20.224 peer 89.68.162.135
inet 1.0.0.2/30 scope global vti13
valid_lft forever preferred_lft forever
inet6 fe80::5efe:ac1f:14e0/64 scope link
valid_lft forever preferred_lft forever
I have confirmed that:
routing is enabled
policy checks are disabled (sysctl -w net.ipv4.conf.default.rp_filter=0 and sysctl -w net.ipv4.conf.vti13.disable_policy=1)
iptables INPUT, OUTPUT, FORWARD was empty with ALLOW, but i have added specific rules also and see 0 hits:
[root#ip-172-31-20-224 log]# iptables -I INPUT -i vti13 -j ACCEPT
[root#ip-172-31-20-224 log]# iptables -I FORWARD -i vti13 -j ACCEPT
[root#ip-172-31-20-224 log]# iptables -L -v -n
Chain INPUT (policy ACCEPT 9 packets, 1164 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- vti13 * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- vti13 * 0.0.0.0/0 0.0.0.0/0
Chain OUTPUT (policy ACCEPT 6 packets, 776 bytes)
pkts bytes target prot opt in out source destination
I have added entries to PREROUTING and POSTROUTING, just to check if i see those packets there and can confirm i can see those only in PREROUTING (so indeed the packet is not routed):
[root#ip-172-31-20-224 log]# iptables -L -v -n -t nat
Chain PREROUTING (policy ACCEPT 2 packets, 184 bytes)
pkts bytes target prot opt in out source destination
19192 25M DNAT udp -- vti13 * 0.0.0.0/0 0.0.0.0/0 udp dpt:3000 to:X.X.X.X:3000
I've tried to look via syslog (enabled kernel logging), but did not spot anything interesting.
What is the problem ? why my Linux is not forwarding those packets ?
Thanks,
OK, found the solution, as per https://docs.strongswan.org/docs/5.9/features/routeBasedVpn.html
had to disable charon.install_routes.

How to send/receive raw ethernet packets from `eth0` to `eth1`?

I created a docker container and connected it to two bridge networks as:
# network 1
docker network create --driver=bridge network1 --subnet=172.56.0.0/24
#network 2
docker network create --driver=bridge network2 --subnet=172.56.1.0/24
docker run \
--name container \
--privileged \
--cap-add=ALL -d \
-v /dev:/dev \
--network network1 \
-v /lib/modules:/lib/modules \
container-image tail -f /dev/null
docker network connect network2 container
Then, I add a bridge NIC to connect eth0 to eth1 and add IP address to it:
# creating bridge NIC
brctl addbr br0
brctl addif br0 eth0
brctl addif br0 eth1
ifconfig br0 up
# adding IP address to br0
ip addr add 172.56.0.3/24 brd + dev br0
route add default gw 172.56.0.1 dev br0
Now, If I run ip addr, this is my output:
2: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 02:42:ac:38:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.56.0.3/24 brd 172.56.0.255 scope global br0
valid_lft forever preferred_lft forever
6773: eth0#if6774: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP group default
link/ether 02:42:ac:38:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.56.0.2/24 brd 172.56.0.255 scope global eth0
valid_lft forever preferred_lft forever
6775: eth1#if6776: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP group default
link/ether 02:42:ac:38:01:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.56.1.2/24 brd 172.56.1.255 scope global eth1
valid_lft forever preferred_lft forever
Now, I'm trying to send a raw ethernet packet by using scapy as:
from scapy.all import *
import sys
src_mac_address = sys.argv[1]
dst_mac_address = sys.argv[2]
packet = Ether(src = src_mac_address, dst = dst_mac_address)
answer = srp(packet, iface='eth0')
It sends the packet, but it would not be received by the other side. I checked the traffic by using bmon, So I see the packet coming out of eth0, but it is never going to be received by the eth1. Is something wrong here? I appreciate your help. By the way, I chose src and dst MAC addresses as: src_mac_address = 02:42:ac:38:00:02 for eth0 and dst_mac_address = 02:42:ac:38:00:02 for eth1.

how to copy command output in to a bash variable

I am making a bash script that needs to know the web interface of the Linux server.
I know I can file the interface using the commands IP a or ipconfig
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:3c:20:ec brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute
valid_lft 80057sec preferred_lft 80057sec
inet6 fe80::7888:1c1e:859a:5c75/64 scope link noprefixroute
valid_lft forever preferred_lft forever
in this example, the interface is enp0s3
of course in every server the interface will be different, so what can I do about it?
is there any way that I can copy this data automatically and set it as a variable
on the script?
thanks!
so after a big research, i found a solution
I will use this command to copy the interface
ip a | grep -o -P '(?<=2: ).*(?=:)'
You want to know the "web interface" of the server. By this, I presume you mean the interface on which the Web Server is running. Let's assume that this is a standard web server, using the standard ports for the HTTP and HTTPS protocols. So the first thing you need to know is: Is anything listening on those ports on ANY tcp interfaces? For this you need the netstat command:
netstat -na
You can then filter this output looking for specific patterns using sed or grep. For example:
netstat -na | sed -ne 's/^tcp[6 ]*[0-9]* *[0-9]* *\([0-9.:]*\):\(\(80\|443\)\) .*LISTEN *$/\1 \2/p'
The sed regular expression looks complex, but it's really not too bad (I can provide an explanation if you wish). It should give you output similar to:
0.0.0.0 443
0.0.0.0 80
For IPv4, 0.0.0.0 means ALL interfaces. You then have the IP address(es) of all interfaces that are listening for HTTP or HTTP requests, which you can match to the output of the ip or ifconfig commands.

Odroidh2 Debian - Unable to ping network gateway / no network connectivity

I have an OdroidH2 with docker setup.
It was working fine for a few months and suddenly, out of nowhere it stopped having any internet/intranet connectivity.
It's connectivity is going through an Ethernet cable, not WiFi and the interface that is supposed to have the connection is enp3s0 with an ip address of 192.168.1.100.
I have performed the following troubleshooting steps:
Restart (of course, always the first step)
Checked interface settings via ifconfig and also in /etc/network/interfaces
Checked the routing via route -n
Checked iptables (iptables was populated with the docker configuration, I've flushed the iptables including nat and mangle and set the default policy to ACCEPT for input, forward and output. Restarted the networking service afterwards)
Checked if it was able to ping itself and the default gateway (it is able to ping itself but not the gateway, or any other devices)
Checked if another device was able to ping the OdroidH2 (host unreachable)
Checked dmesg and for some reason, I had 2 firmwares that were not able to be loaded (already installed and rebooted after installation):
rtl_nic/rtl8168g-2.fw (after checking, this is the firmware for the network interfaces)
i915/glk_dmc_ver1_04.bin (didn't research much about this one, something to do with runtime power management??)
After all of these steps, I still am unable to get the network connectivity going.
Below you can find information regarding my current configuration:
dmesg output
Stackoverflow does not allow me to put all the information from my dmesg output so I had to put it on google drive: dmesg_output
/etc/hosts
127.0.0.1 localhost
192.168.1.100 dc1 dc1.samdom.andrewoliverhome.local samdom.andrewoliverhome.local
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
iptables -nvL output (after clearing and reloading the networking service)
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
/etc/resolv.conf
#nameserver 127.0.0.1
#nameserver 8.8.8.8
#nameserver 8.8.4.4
search samdom.andrewoliverhome.local
#domain samdom.andrewoliverhome.local
nameserver 192.168.1.100
nameserver 8.8.8.8
route -n output
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.1.254 0.0.0.0 UG 0 0 0 enp3s0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker_gwbridge
172.19.0.0 0.0.0.0 255.255.0.0 U 0 0 0 br-debc10cb5b21
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 enp3s0
/etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo enp2s0 enp3s0
#auto lo br0
iface lo inet loopback
# The primary network interface
iface enp2s0 inet dhcp
allow-hotplug enp2s0 enp3s0
#iface enp2s0 inet manual
# post-up iptables-restore < /etc/iptables.up.rules
# This is an autoconfigured IPv6 interface
#iface enp2s0 inet dhcp
iface enp3s0 inet static
address 192.168.1.100
netmask 255.255.255.0
# broadcast 169.254.99.255
network 192.168.1.0
gateway 192.168.1.254
#iface enp2s0 inet manual
#iface enp3s0 inet manual
#iface br0 inet static
# bridge_ports enp2s0 enp3s0
# address 192.168.1.100
# broadcast 192.168.1.255
# netmask 255.255.255.0
# gateway 192.168.1.254
#
In /etc/resolv.conf, the reason I have the primary nameserver to be itself is because I am running a docker container that is serving as a samba-ad-dc.
In order for OdroidH2 to find all of my devices in the domain, it needs to make dns queries to the samba dc, if samba is not able to find a dns record, it will autoforward it to 8.8.8.8.
Any help would be greatly appreciated (:
After all the troubleshooting done, the issue is not within the OdroidH2 itself, it was with my router.
The LAN port that I'm using malfunctioned. I switched the Ethernet cable to a different LAN port and it worked.

Bridged Xen domU with gateway in different subnet

I have a Xen dom0 running Debian Wheezy (7.8) and Xen 4.1, set up with bridged networking.
199.XXX.161.64 is the dom0 gateway.
199.XXX.161.65 is the dom0 address.
192.XXX.13.128/28 is the subnet for the domU's.
Configuration dom0:
root#dom0:~# cat /etc/network/interfaces
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet manual
auto xenbr0
iface xenbr0 inet static
address 199.XXX.161.65
netmask 255.255.255.254
network 199.XXX.161.64
broadcast 199.XXX.161.65
gateway 199.XXX.161.64
dns-nameservers 199.XXX.162.41 199.XXX.162.141
bridge_ports eth0
bridge_stp off # disable Spanning Tree Protocol
bridge_fd 0 # no forwarding delay
bridge_maxwait 0 # no delay before a port becomes available
allow-hotplug xenbr0 # start interface on hotplug event
root#dom0:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master xenbr0 state UP qlen 1000
link/ether 00:25:90:d5:06:1a brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 00:25:90:d5:06:1b brd ff:ff:ff:ff:ff:ff
4: xenbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 00:25:90:d5:06:1a brd ff:ff:ff:ff:ff:ff
inet 199.XXX.161.65/31 brd 199.XXX.161.65 scope global xenbr0
inet6 fe80::XXXX:90ff:fed5:61a/64 scope link
valid_lft forever preferred_lft forever
8: vif1.0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master xenbr0 state UP qlen 32
link/ether fe:ff:ff:ff:ff:ff brd ff:ff:ff:ff:ff:ff
inet6 fe80::fcff:ffff:feff:ffff/64 scope link
valid_lft forever preferred_lft forever
root#dom0:~# brctl show
bridge name bridge id STP enabled interfaces
xenbr0 8000.002590d5061a no eth0
vif1.0
root#dom0:~# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 199.XXX.161.64 0.0.0.0 UG 0 0 0 xenbr0
192.XXX.13.128 0.0.0.0 255.255.255.240 U 0 0 0 xenbr0
199.XXX.161.64 0.0.0.0 255.255.255.254 U 0 0 0 xenbr0
root#dom0:~# iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-out vif1.0 --physdev-is-bridged
ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-in vif1.0 --physdev-is-bridged udp spt:68 dpt:67
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-out vif1.0 --physdev-is-bridged
ACCEPT all -- 192.XXX.13.129 0.0.0.0/0 PHYSDEV match --physdev-in vif1.0 --physdev-is-bridged
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
This host can reach its gateway and thus the internet.
root#dom0:~# ping -c 1 199.XXX.161.64
PING 199.XXX.161.64 (199.XXX.161.64) 56(84) bytes of data.
64 bytes from 199.XXX.161.64: icmp_req=1 ttl=64 time=0.459 ms
--- 199.XXX.161.64 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.459/0.459/0.459/0.000 ms
I also have a domU (with the same OS) which needs a primary IP address in a different subnet. There is no gateway on the network in this subnet. I want to keep my network setup bridged (no dom0 routing or NAT) so I added the dom0 gateway as the gateway for the domU as described in this blogpost.
Configuration domU:
root#domU:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:16:3e:b7:7e:cc brd ff:ff:ff:ff:ff:ff
inet 192.XXX.13.129/28 brd 192.XXX.13.143 scope global eth0
inet6 fe80::XXXX:3eff:feb7:7ecc/64 scope link
valid_lft forever preferred_lft forever
root#domU:~# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 199.XXX.161.64 0.0.0.0 UG 0 0 0 eth0
192.XXX.13.128 0.0.0.0 255.255.255.240 U 0 0 0 eth0
199.XXX.161.64 0.0.0.0 255.255.255.255 UH 0 0 0 eth0
With this configuration the domU still has no network access. To test if the bridge was working I manually added a route to dom0.
root#domU:~# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 199.XXX.161.64 0.0.0.0 UG 0 0 0 eth0
192.XXX.13.128 0.0.0.0 255.255.255.240 U 0 0 0 eth0
199.XXX.161.64 0.0.0.0 255.255.255.255 UH 0 0 0 eth0
199.XXX.161.65 0.0.0.0 255.255.255.255 UH 0 0 0 eth0
Now the dom0 and domU can communicate through the bridge.
root#domU:~# ping -c 1 199.XXX.161.65
PING 199.XXX.161.65 (199.XXX.161.65) 56(84) bytes of data.
64 bytes from 199.XXX.161.65: icmp_req=1 ttl=64 time=0.037 ms
--- 199.XXX.161.65 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.037/0.037/0.037/0.000 ms
root#dom0:~# ping -c 1 192.XXX.13.129
PING 192.184.13.129 (192.XXX.13.129) 56(84) bytes of data.
64 bytes from 192.XXX.13.129: icmp_req=1 ttl=64 time=0.100 ms
--- 192.XXX.13.129 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.100/0.100/0.100/0.000 ms
However, the domU still can't reach the gateway.
root#domU:~# ping -c 1 199.XXX.161.64
PING 199.XXX.161.64 (199.XXX.161.64) 56(84) bytes of data.
From 192.XXX.13.129 icmp_seq=1 Destination Host Unreachable
--- 199.XXX.161.64 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
I have attempted to log establish if the traffic is actually being sent through the bridge by inserting a -j LOG rule at the top of the INPUT, OUTPUT and FORWARD iptables chains. When the domU attempts to ping the gateway the dom0 does not log a single packet. I also tried manually adding an entry for the gateway in domU's ARP table but the results were the same. The domU can't reach the gateway and thus has no network access other than being able to communicate with dom0 via static route.
So if I am understanding this correctly, the following is the network configuration for your DomU:
192.XXX.13.129/28 - DomU IP Address
199.XXX.161.64 - DomU GW Address
The problem is that your DomU does not have a route (layer 3) to allow it to talk to the GW address since the GW address is in a different subnet. So even though the router is on the same layer 2 network, the router (if it is processing your packets) does not know about your layer 3 network and is sending it's responses to it's default gateway.
That you are able to ping the Dom0 from the DomU is odd and probably the result of both the Dom0 and the DomU using the same Linux Bridge (which it not a true ethernet switch, more like a dumb hub).
The simple fix is to add an address from your DomU network to the LAN interface on your router.
The better fix would be to use VLANs to segment the different networks via layer 2 and replace Linux Bridges with Open vSwitch. This would completely isolate the Dom0 and DomU traffic so that they would be required to communication via a router and possibly a firewall.

Resources