O script para criar a ponte macvlan no host não funciona a menos que seja executado duas vezes

1

Eu tenho um script que deve criar uma ponte macvlan no host quando ele for iniciado. O host é um Arch Linux atualizado. Isso destina-se a permitir que o host e o convidado compartilhem a mesma rede. Eu encontrei instruções dadas em:

link

(Sobre a execução na inicialização, eu também consultei Como escrever script de inicialização para systemd e link ).

O problema, no entanto, é que o script não é eficaz na primeira tentativa. Ele cria o dispositivo macvlan e a tabela de roteamento, mas não permite que o host faça o ping do convidado e vice-versa.

Mas, quando executado uma segunda vez, funciona - ou seja, apesar de uma mensagem de erro que diz "create_macvlan_bridge.sh [4489]: RTNETLINK responde: Arquivo existe" . O host agora pode efetuar ping como esperado.

É suposto que funcione na primeira tentativa , e não consigo entender por que não é. Alguém pode ajudar?

[Update] Percebi que o resultado de ip a mostra uma segunda entrada inet para macvlan0 @ enp10s0 depois da segunda execução:

macvlan0@enp10s0: mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether da:a2:21:d1:95:24 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.3/24 scope global macvlan0
        valid_lft forever preferred_lft forever
    inet 192.168.1.22/24 brd 192.168.1.255 scope global secondary macvlan0
        valid_lft forever preferred_lft forever

Observe como esse segundo endereço IP foi fornecido pelo dhcp do roteador e possui secondary attribute.

O mais estranho é que, após a segunda execução, o convidado pode fazer ping no host em 192.168.1.3 e no endereço "secundário".

O código está abaixo.

Script: /usr/local/bin/create_macvlan_bridge.sh

#!/bin/sh

# Evert Mouw, 2013
# Modified by Marc Ranolfi, 2017-07-24

# ------------
# wait for network availability
# ------------
TESTHOST=kernel.org
while ! ping -q -c 1 $TESTHOST > /dev/null
do
    echo "$0: Cannot ping $TESTHOST, waiting another 5 secs..."
    sleep 5
done

# ------------
# network config
# ------------
HWLINK=enp10s0
MACVLN=macvlan0

IP=192.168.1.3/24
NETWORK=192.168.1.0/24
GATEWAY=192.168.1.1

# ------------
# setting up $MACVLN interface
# ------------
ip link add link $HWLINK $MACVLN type macvlan mode bridge
ip address add $IP dev $MACVLN
ip link set dev $MACVLN up

# ------------
# routing table
# ------------
# empty routes
ip route flush dev $HWLINK
ip route flush dev $MACVLN

# add routes
ip route add $NETWORK dev $MACVLN metric 0

# add the default gateway
ip route add default via $GATEWAY

Arquivo de unidade do Systemd: /etc/systemd/system/create_macvlan_bridge.service

[Unit]
Description=Create_macvlan_bridge
Wants=network-online.target
After=network.target network-online.target dhcpcd.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/create_macvlan_bridge.sh

[Install]
WantedBy=multi-user.target
    
por Marc.2377 25.07.2017 / 04:20

2 respostas

0

As informações detalhadas na última atualização da pergunta deram-me uma ideia de onde o problema residia.

Eu tinha dhcpcd.service ativado para todas as interfaces. Eu tentei desativá-lo e ativar apenas para enp10s0 e funcionou.

Então:

systemctl disable dhcpcd
systemctl enable dhcpcd@enp10s0

e voila.

    
por 26.07.2017 / 06:49
0

Eu também tive problemas com o script. Eu não tive que fazer isso duas vezes. As coisas começaram a funcionar novamente depois de um minuto ou mais. Mas isso ainda era chato. Eu decidi que faz mudanças de roteamento desnecessárias. Não há motivos para o tráfego normal do host não usar a interface física. Você só precisa usar o macvlan para acessar suas VMs. Por essa razão, as únicas mudanças de roteamento que você realmente precisa são

ip route flush dev $ MACVLN

ip route adiciona métrica $ VMHOST dev $ MACVLN 0

Nesse momento, não tive mais problemas.

Também não vale nada que pelo menos no Centos 7, o / sbin / ifup-local seja executado pela rede de reinício do systemctl no final da criação de uma interface. Então você pode colocar o script lá, embora deva começar com algo assim, já que você não quer executá-lo quando outras interfaces são ativadas.

se! teste "$ 1"="em1"; então   sair 0 fi

Você provavelmente também não precisa do loop de ping quando é / sbin / ifup-local. Na verdade, é perigoso, já que é um loop infinito, então, se houver algum problema de rede, o sistema pode não apresentar isso como parte da inicialização.

    
por 19.04.2018 / 19:52