In enterprise device management systems where each client device requires isolated physical networks, administrators often face IP address management complexities. Our case involves a Linux server (kernel 3.14) serving multiple set-top boxes (STBs) through separate physical interfaces, each requiring the server to appear as a different IP address within identical subnet ranges.
Server Interfaces: - eth0: External network - eth1: 172.16.50.1/24 → STB1 LAN - eth2: 172.16.51.1/24 → STB2 LAN - eth3: 172.16.52.1/24 → STB3 LAN
We can implement network namespace isolation combined with policy-based routing to achieve identical IP addressing across physical interfaces while maintaining network separation.
# Create network namespaces sudo ip netns add stb1 sudo ip netns add stb2 sudo ip netns add stb3 # Move interfaces to namespaces sudo ip link set eth1 netns stb1 sudo ip link set eth2 netns stb2 sudo ip link set eth3 netns stb3 # Configure identical IPs in each namespace sudo ip netns exec stb1 ip addr add 172.16.50.1/24 dev eth1 sudo ip netns exec stb2 ip addr add 172.16.50.1/24 dev eth2 sudo ip netns exec stb3 ip addr add 172.16.50.1/24 dev eth3 # Bring up interfaces sudo ip netns exec stb1 ip link set eth1 up sudo ip netns exec stb2 ip link set eth2 up sudo ip netns exec stb3 ip link set eth3 up
For services running in each namespace (TFTP/NFS/HTTP), use systemd units with namespace specification:
[Unit] Description=TFTP Server for STB1 After=network.target [Service] ExecStart=/usr/sbin/in.tftpd --listen --user tftp --address 172.16.50.1:69 /srv/tftp/stb1 Restart=always NetworkNamespacePath=/run/netns/stb1 [Install] WantedBy=multi-user.target
Add specific route tables for each namespace to prevent routing conflicts:
# Create custom routing tables echo "100 stb1" >> /etc/iproute2/rt_tables echo "101 stb2" >> /etc/iproute2/rt_tables echo "102 stb3" >> /etc/iproute2/rt_tables # Configure routing in each namespace sudo ip netns exec stb1 ip route add default via 172.16.50.1 table stb1 sudo ip netns exec stb1 ip rule add from 172.16.50.1 lookup stb1
Test connectivity from within each namespace:
sudo ip netns exec stb1 ping 172.16.50.100 # STB1 device sudo ip netns exec stb2 arping -I eth2 172.16.50.101
For high-throughput scenarios, consider XDP (eXpress Data Path) programs to handle namespace-specific packet processing at the driver level.
// Sample XDP program to filter by physical interface SEC("xdp") int xdp_prog(struct xdp_md *ctx) { void *data_end = (void *)(long)ctx->data_end; void *data = (void *)(long)ctx->data; // Process packets based on ingress interface switch (ctx->ingress_ifindex) { case ETH1_IFINDEX: return process_stb1(data, data_end); case ETH2_IFINDEX: return process_stb2(data, data_end); default: return XDP_PASS; } }
In embedded systems development, particularly when working with multiple consumer devices like set-top boxes, we often encounter unique networking requirements. The scenario involves a Linux server (kernel 3.14) serving as a central TFTP, NFS, and HTTP server for multiple devices, each requiring complete network isolation.
The existing configuration uses separate subnets for each device:
# Current interface configuration auto eth1 iface eth1 inet static address 172.16.50.1 netmask 255.255.255.0 auto eth2 iface eth2 inet static address 172.16.51.1 netmask 255.255.255.0 auto eth3 iface eth3 inet static address 172.16.52.1 netmask 255.255.255.0
This approach creates maintenance overhead as each device must reference the server using different IP addresses in their configuration files.
Using the same IP address (172.16.50.1) on multiple interfaces connected to physically separate networks is technically feasible with proper configuration:
# Modified interface configuration auto eth1 iface eth1 inet static address 172.16.50.1 netmask 255.255.255.0 up ip route add 172.16.50.0/24 dev eth1 table 100 up ip rule add from 172.16.50.1 table 100 auto eth2 iface eth2 inet static address 172.16.50.1 netmask 255.255.255.0 up ip route add 172.16.50.0/24 dev eth2 table 101 up ip rule add from 172.16.50.1 table 101 auto eth3 iface eth3 inet static address 172.16.50.1 netmask 255.255.255.0 up ip route add 172.16.50.0/24 dev eth3 table 102 up ip rule add from 172.16.50.1 table 102
The key components making this work:
- Policy-based routing using multiple routing tables
- Strict ARP filtering to prevent cross-network conflicts
- Interface-specific ARP announcements
Enable ARP filtering and configure interface-specific responses:
# Add to /etc/sysctl.conf net.ipv4.conf.all.arp_filter = 1 net.ipv4.conf.default.arp_filter = 1 net.ipv4.conf.all.arp_announce = 2 net.ipv4.conf.default.arp_announce = 2
After implementation, verify the setup:
# Check routing tables ip route show table 100 ip route show table 101 ip route show table 102 # Test connectivity from each network arping -I eth1 172.16.50.1 arping -I eth2 172.16.50.1 arping -I eth3 172.16.50.1
While this solution works well for our specific use case, consider:
- Broadcast traffic will be limited to each physical network
- Some network monitoring tools might show warnings
- Requires careful firewall configuration
For firewall rules, ensure you specify the outgoing interface:
# Example iptables rules iptables -A INPUT -i eth1 -s 172.16.50.0/24 -d 172.16.50.1 -j ACCEPT iptables -A INPUT -i eth2 -s 172.16.50.0/24 -d 172.16.50.1 -j ACCEPT iptables -A INPUT -i eth3 -s 172.16.50.0/24 -d 172.16.50.1 -j ACCEPT