X-Git-Url: https://git.proxmox.com/?p=pve-common.git;a=blobdiff_plain;f=src%2FPVE%2FNetwork.pm;h=b1564e829613eff9525e17ffc7fa9aa4905a7097;hp=a659a5c4a4f5a31ec66e2ca64ebaa7783aed4d9f;hb=5c1556cd27c93705eef1d02f2d09e0c245212e67;hpb=4ed6974a55ae2615b7e83036b56fcdb718c4cf71 diff --git a/src/PVE/Network.pm b/src/PVE/Network.pm index a659a5c..b1564e8 100644 --- a/src/PVE/Network.pm +++ b/src/PVE/Network.pm @@ -14,6 +14,8 @@ use Net::IP; # host network related utility functions +our $PHYSICAL_NIC_RE = qr/(?:eth\d+|en[^:.]+|ib\d+)/; + our $ipv4_reverse_mask = [ '0.0.0.0', '128.0.0.0', @@ -100,7 +102,7 @@ sub setup_tc_rate_limit { run_command("/sbin/tc filter add dev $iface parent ffff: " . "prio 50 basic " . "police rate ${rate}bps burst ${burst}b mtu 64kb " . - "drop flowid :1"); + "drop"); if ($debug) { print "DEBUG tc settings\n"; @@ -163,12 +165,41 @@ my $compute_fwbr_names = sub { return ($fwbr, $vethfw, $vethfwpeer, $ovsintport); }; +sub iface_delete($) { + my ($iface) = @_; + run_command(['/sbin/ip', 'link', 'delete', 'dev', $iface], noerr => 1) + == 0 or die "failed to delete interface '$iface'\n"; +} + +sub iface_create($$@) { + my ($iface, $type, @args) = @_; + run_command(['/sbin/ip', 'link', 'add', $iface, 'type', $type, @args], noerr => 1) + == 0 or die "failed to create interface '$iface'\n"; +} + +sub iface_set($@) { + my ($iface, @opts) = @_; + run_command(['/sbin/ip', 'link', 'set', $iface, @opts], noerr => 1) + == 0 or die "failed to set interface options for '$iface' (".join(' ', @opts).")\n"; +} + +# helper for nicer error messages: +sub iface_set_master($$) { + my ($iface, $master) = @_; + if (defined($master)) { + eval { iface_set($iface, 'master', $master) }; + die "can't enslave '$iface' to '$master'\n" if $@; + } else { + eval { iface_set($iface, 'nomaster') }; + die "can't unenslave '$iface'\n" if $@; + } +} + my $cond_create_bridge = sub { my ($bridge) = @_; if (! -d "/sys/class/net/$bridge") { - system("/sbin/brctl addbr $bridge") == 0 || - die "can't add bridge '$bridge'\n"; + iface_create($bridge, 'bridge'); disable_ipv6($bridge); } }; @@ -187,8 +218,7 @@ my $bridge_add_interface = sub { # drop link local address (it can't be used when on a bridge anyway) disable_ipv6($iface); - system("/sbin/brctl addif $bridge $iface") == 0 || - die "can't add interface 'iface' to bridge '$bridge'\n"; + iface_set_master($iface, $bridge); my $vlan_aware = PVE::Tools::file_read_firstline("/sys/class/net/$bridge/bridge/vlan_filtering"); @@ -261,7 +291,7 @@ sub veth_create { # create veth pair if (! -d "/sys/class/net/$veth") { - my $cmd = "/sbin/ip link add name $veth type veth peer name $vethpeer mtu $bridgemtu"; + my $cmd = "/sbin/ip link add name $veth mtu $bridgemtu type veth peer name $vethpeer mtu $bridgemtu"; $cmd .= " addr $mac" if $mac; system($cmd) == 0 || die "can't create interface $veth\n"; } @@ -277,7 +307,7 @@ sub veth_delete { my ($veth) = @_; if (-d "/sys/class/net/$veth") { - run_command("/sbin/ip link delete dev $veth", outfunc => sub {}, errfunc => sub {}); + iface_delete($veth); } eval { tap_unplug($veth) }; } @@ -339,8 +369,7 @@ my $cleanup_firewall_bridge = sub { # cleanup fwbr bridge if (-d "/sys/class/net/$fwbr") { - run_command("/sbin/ip link set dev $fwbr down", outfunc => sub {}, errfunc => sub {}); - run_command("/sbin/brctl delbr $fwbr", outfunc => sub {}, errfunc => sub {}); + iface_delete($fwbr); } }; @@ -391,9 +420,7 @@ sub tap_unplug { #avoid insecure dependency; ($bridge) = $bridge =~ /(\S+)/; - system("/sbin/brctl delif $bridge $iface") == 0 || - die "can't del interface '$iface' from bridge '$bridge'\n"; - + iface_set_master($iface, undef); } &$cleanup_firewall_bridge($iface); @@ -477,8 +504,7 @@ sub activate_bridge_vlan { lock_network(sub { # add bridgevlan if it doesn't already exist if (! -d "/sys/class/net/$bridgevlan") { - system("/sbin/brctl addbr $bridgevlan") == 0 || - die "can't add bridge $bridgevlan\n"; + iface_create($bridgevlan, 'bridge'); } # for each physical interface (eth or bridge) bind them to bridge vlan @@ -566,7 +592,7 @@ sub get_local_ip_from_cidr { my $code = sub { my $line = shift; - if ($line =~ m!^\s*inet(?:6)?\s+($PVE::Tools::IPRE)/\d+!) { + if ($line =~ m!^\s*inet(?:6)?\s+($PVE::Tools::IPRE)(?:/\d+|\s+peer\s+)!) { push @$IPs, $1; } };