Thank you, unfortunately is the Switch/Mirror-thing to stupid to do this correctly...
You can mirror frames, but only on one port and I use LAGs with at least 2 ports. LAGs are not under the switch menu visible. Worked not good/predictable for me :/
I have 2 VLANs:
LAN = VLAN101 (main MGMT for MT devices)
WLAN = VLAN102 (WLAN with Winbox)
IPs for the reflector are:
10.88.101.2/24 (VLAN101)
10.88.102.2/24 (VLAN102)
I wrote a smol docker/phyton-contianer+script which does what I want.
I share with you guys, if someone seeks such a solution too:
Dockerfile:
# Use Python 3.11 slim as the base image
FROM python:3.11-slim
# Set the working directory in the container
WORKDIR /app
# Install required system dependencies
RUN apt-get update && apt-get install -y libpcap-dev tcpdump && apt-get clean
# Copy the Python script to the container
COPY udp_forwarder_bidirectional.py /app/
# Install Python dependencies (Scapy)
RUN pip install scapy
# Define the entry point
CMD ["python", "udp_forwarder_bidirectional.py"]
docker-compose.yml
version: "3.9" # Define the compose file version
services:
mndp-reflector:
build:
context: . # Current directory containing Dockerfile and scripts
dockerfile: Dockerfile
container_name: vlan101-vlan102-mndp-reflector
restart: always
cap_add:
- NET_ADMIN # Allow the container to manage network interfaces
- NET_RAW # Allow raw network packet manipulation
command: python3 /app/udp_forwarder_bidirectional.py # Start the Python script
networks:
vlan101:
ipv4_address: 10.88.101.2 # Specific IP for VLAN101
vlan102:
ipv4_address: 10.88.102.2 # Specific IP for VLAN102
networks:
vlan101:
external: true # Use the existing vlan101 network
vlan102:
external: true # Use the existing vlan102 network
udp_forwarder_bidirectional.py
from scapy.all import Ether, IP, UDP, sendp, Raw
import socket
import threading
# Configuration from environment variables
import os
SOURCE_INTERFACE_VLAN101 = os.getenv("SOURCE_INTERFACE_VLAN101", "eth0")
TARGET_INTERFACE_VLAN102 = os.getenv("TARGET_INTERFACE_VLAN102", "eth1")
SOURCE_INTERFACE_VLAN102 = os.getenv("SOURCE_INTERFACE_VLAN102", "eth1")
TARGET_INTERFACE_VLAN101 = os.getenv("TARGET_INTERFACE_VLAN101", "eth0")
SOURCE_PORT = int(os.getenv("SOURCE_PORT", 5678))
TARGET_PORT = int(os.getenv("TARGET_PORT", 5678))
BROADCAST_MAC = "ff:ff:ff:ff:ff:ff"
# Function to forward traffic from VLAN101 to VLAN102
def forward_vlan101_to_vlan102():
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("", SOURCE_PORT))
print(f"Listening on {SOURCE_INTERFACE_VLAN101}, forwarding to {TARGET_INTERFACE_VLAN102}...")
while True:
try:
data, addr = sock.recvfrom(2048)
print(f"[VLAN101 -> VLAN102] Received from {addr}: {data}")
# Check if source port matches
if addr[1] != SOURCE_PORT:
print(f"[VLAN101 -> VLAN102] Ignored packet from port {addr[1]}")
continue
ether = Ether(dst=BROADCAST_MAC)
ip = IP(src=addr[0], dst="255.255.255.255") # Keep source IP, set destination as broadcast
udp = UDP(sport=SOURCE_PORT, dport=TARGET_PORT)
payload = Raw(load=data)
sendp(ether / ip / udp / payload, iface=TARGET_INTERFACE_VLAN102, verbose=False)
print(f"[VLAN101 -> VLAN102] Sent to broadcast on {TARGET_INTERFACE_VLAN102}")
except Exception as e:
print(f"[VLAN101 -> VLAN102] Error: {e}")
# Function to forward traffic from VLAN102 to VLAN101
def forward_vlan102_to_vlan101_raw():
sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(3))
sock.bind((SOURCE_INTERFACE_VLAN102, 0))
print(f"Listening on {SOURCE_INTERFACE_VLAN102}, forwarding to {TARGET_INTERFACE_VLAN101}...")
while True:
try:
packet = sock.recv(2048)
ether = Ether(packet)
# Filter only UDP packets with the desired ports
if UDP in ether and ether[UDP].sport == SOURCE_PORT and ether[UDP].dport == TARGET_PORT:
sendp(ether, iface=TARGET_INTERFACE_VLAN101, verbose=False)
print(f"[VLAN102 -> VLAN101] Forwarded UDP packet: {ether.summary()}")
else:
print(f"[VLAN102 -> VLAN101] Ignored non-matching packet")
except Exception as e:
print(f"[VLAN102 -> VLAN101] Error: {e}")
# Start forwarding threads
thread_vlan101_to_vlan102 = threading.Thread(target=forward_vlan101_to_vlan102, daemon=True)
thread_vlan102_to_vlan101 = threading.Thread(target=forward_vlan102_to_vlan101_raw, daemon=True)
thread_vlan101_to_vlan102.start()
thread_vlan102_to_vlan101.start()
thread_vlan101_to_vlan102.join()
thread_vlan102_to_vlan101.join()
Finally I have my MNDP-frames from VLAN101 in VLAN102.
edit from 14.12.2024, 22:48: Updated .py (old one matched on more than UDP/5678-traffic)
You do not have the required permissions to view the files attached to this post.