containers / netavark

Container network stack
Apache License 2.0
516 stars 83 forks source link

macvlan: dhcp proxy not reaching server running on host #1008

Open sarming opened 3 months ago

sarming commented 3 months ago

I get the following error when starting a container on a macvlan network with the dhcp ipam driver: netavark: unable to obtain lease: dhcp proxy error: status: Aborted, message: "Timeout: Timeout" The server is running on the host and is reachable from a container using a macvlan network with the host-local driver.

Steps to reproduce

$ ip a
...
2: enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0e:2e:2c:c6:77 brd ff:ff:ff:ff:ff:ff
...
7: mvlan@enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 56:a1:e4:16:c2:b9 brd ff:ff:ff:ff:ff:ff
    inet 192.168.4.1/24 brd 192.168.4.255 scope global mvlan
       valid_lft forever preferred_lft forever
$ podman network create dhcp -d macvlan -o parent=enp4s0  --ipam-driver=dhcp
dhcp
$ podman network create host-local -d macvlan -o parent=enp4s0 --ipam-driver=host-local --ip-range 192.168.4.10-192.168.4.20 --subnet 192.168.4.0/24
host-local
$ podman run --network dhcp --privileged alpine:latest udhcpc
Error: netavark: unable to obtain lease: dhcp proxy error: status: Aborted, message: "Timeout: Timeout", details: [], metadata: MetadataMap { headers: {"content-type": "application/grpc", "date": "Tue, 18 Jun 2024 11:43:09 GMT", "content-length": "0"} }
$ podman run --network host-local --privileged alpine:latest udhcpc
udhcpc: started, v1.36.1
udhcpc: broadcasting discover
udhcpc: broadcasting select for 192.168.4.109, server 192.168.4.1
udhcpc: lease of 192.168.4.109 obtained from 192.168.4.1, lease time 3600

Here are package dumps of the above run for both the macvlan and the underlying device. The request of the dhcp proxy only shows up on the underlying device.

enp4s0.pcap mvlan.pcap

Configuration

$ podman info
host:
  arch: amd64
  buildahVersion: 1.36.0
  cgroupControllers:
  - cpuset
  - cpu
  - io
  - memory
  - hugetlb
  - pids
  - rdma
  - misc
  cgroupManager: systemd
  cgroupVersion: v2
  conmon:
    package: /usr/bin/conmon is owned by conmon 1:2.1.12-1
    path: /usr/bin/conmon
    version: 'conmon version 2.1.12, commit: e8896631295ccb0bfdda4284f1751be19b483264'
  cpuUtilization:
    idlePercent: 98.73
    systemPercent: 0.39
    userPercent: 0.88
  cpus: 4
  databaseBackend: sqlite
  distribution:
    distribution: arch
    version: unknown
  eventLogger: journald
  freeLocks: 2020
  hostname: chef
  idMappings:
    gidmap: null
    uidmap: null
  kernel: 6.9.2-arch1-1
  linkmode: dynamic
  logDriver: journald
  memFree: 542154752
  memTotal: 8190984192
  networkBackend: netavark
  networkBackendInfo:
    backend: netavark
    dns:
      package: /usr/lib/podman/aardvark-dns is owned by aardvark-dns 1.11.0-1
      path: /usr/lib/podman/aardvark-dns
      version: aardvark-dns 1.11.0
    package: /usr/lib/podman/netavark is owned by netavark 1.11.0-2
    path: /usr/lib/podman/netavark
    version: netavark 1.11.0
  ociRuntime:
    name: crun
    package: /usr/bin/crun is owned by crun 1.15-1
    path: /usr/bin/crun
    version: |-
      crun version 1.15
      commit: e6eacaf4034e84185fd8780ac9262bbf57082278
      rundir: /run/crun
      spec: 1.0.0
      +SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +CRIU +YAJL
  os: linux
  pasta:
    executable: /usr/bin/pasta
    package: /usr/bin/pasta is owned by passt 2024_06_07.8a83b53-1
    version: |
      pasta 2024_06_07.8a83b53
      Copyright Red Hat
      GNU General Public License, version 2 or later
        <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
      This is free software: you are free to change and redistribute it.
      There is NO WARRANTY, to the extent permitted by law.
  remoteSocket:
    exists: true
    path: /run/podman/podman.sock
  rootlessNetworkCmd: pasta
  security:
    apparmorEnabled: false
    capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
    rootless: false
    seccompEnabled: true
    seccompProfilePath: /etc/containers/seccomp.json
    selinuxEnabled: false
  serviceIsRemote: false
  slirp4netns:
    executable: ""
    package: ""
    version: ""
  swapFree: 8589144064
  swapTotal: 8589930496
  uptime: 23h 48m 41.00s (Approximately 0.96 days)
  variant: ""
plugins:
  authorization: null
  log:
  - k8s-file
  - none
  - passthrough
  - journald
  network:
  - bridge
  - macvlan
  - ipvlan
  volume:
  - local
registries: {}
store:
  configFile: /etc/containers/storage.conf
  containerStore:
    number: 3
    paused: 0
    running: 0
    stopped: 3
  graphDriverName: overlay
  graphOptions:
    overlay.mountopt: nodev
  graphRoot: /var/lib/containers/storage
  graphRootAllocated: 493409042432
  graphRootUsed: 183902281728
  graphStatus:
    Backing Filesystem: extfs
    Native Overlay Diff: "false"
    Supports d_type: "true"
    Supports shifting: "true"
    Supports volatile: "true"
    Using metacopy: "true"
  imageCopyTmpDir: /var/tmp
  imageStore:
    number: 13
  runRoot: /run/containers/storage
  transientStore: false
  volumePath: /var/lib/containers/storage/volumes
version:
  APIVersion: 5.1.1
  Built: 1717539130
  BuiltTime: Wed Jun  5 00:12:10 2024
  GitCommit: bda6eb03dcbcf12a5b7ae004c1240e38dd056d24-dirty
  GoVersion: go1.22.3
  Os: linux
  OsArch: linux/amd64
  Version: 5.1.1

systemd-networkd configuration:

mvlan.netdev

[NetDev]
Name=mvlan
Kind=macvlan

[MACVLAN]
Mode=bridge

mvlan.network

[Match]
Name=mvlan

[Network]
Address=192.168.4.1/24
DHCPServer=true

[DHCPServer]
PoolOffset=100
PoolSize=20
EmitDNS=yes
DNS=9.9.9.9

enp4s0.network

[Match]
Name=enp4s0
[Network]
MACVLAN=mvlan
DHCP=no
IPv6AcceptRA=false
LinkLocalAddressing=no
MulticastDNS=false
LLMNR=false
Luap99 commented 3 months ago

Ok I think I understand setup now. I am not sure if this can work correctly though, I guess in such case we want the enp4s0 as parent device for macvlan the the dhcp proxy should use the mvlan device on the host. But I have no time to test if this would work like that.