From 2b8f2fb518561119567512499f3952d158eb0111 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 25 Nov 2014 21:53:38 -0800 Subject: [PATCH 01/25] Change names and s/br/bridge/ Ticket: CM-3346 Reviewed By: Testing Done: Tested ifupdown2 sanity with all example files --- .../vlan_aware_bridges/interfaces.basic | 25 +++++ .../interfaces.vlan_prune_and_access_ports | 55 +++++++++++ .../vlan_aware_bridges/interfaces.with_bonds | 92 +++++++++++++++++++ .../vlan_aware_bridges/interfaces.with_clag | 83 +++++++++++++++++ 4 files changed, 255 insertions(+) create mode 100644 docs/examples/vlan_aware_bridges/interfaces.basic create mode 100644 docs/examples/vlan_aware_bridges/interfaces.vlan_prune_and_access_ports create mode 100644 docs/examples/vlan_aware_bridges/interfaces.with_bonds create mode 100644 docs/examples/vlan_aware_bridges/interfaces.with_clag diff --git a/docs/examples/vlan_aware_bridges/interfaces.basic b/docs/examples/vlan_aware_bridges/interfaces.basic new file mode 100644 index 0000000..0c64835 --- /dev/null +++ b/docs/examples/vlan_aware_bridges/interfaces.basic @@ -0,0 +1,25 @@ +# +# vlan-aware bridge simple example +# +# 'bridge' is a vlan aware bridge with all ports (swp1-52). +# native vlan is by default 1 +# +# 'bridge-vids' attribute is used to declare vlans. +# 'bridge-pvid' attribute is used to specify native vlans if other than 1 +# 'bridge-access' attribute is used to declare access port +# + +# +# ports swp1-swp52 are trunk ports which inherit vlans from the bridge br +# ie vlans 310 700 707 712 850 910 + +# +# the following is a vlan aware bridge with ports swp1-swp52 +# It has stp on +# +auto bridge +iface bridge + bridge-vlan-aware yes + bridge-ports glob swp1-52 + bridge-stp on + bridge-vids 310 700 707 712 850 910 diff --git a/docs/examples/vlan_aware_bridges/interfaces.vlan_prune_and_access_ports b/docs/examples/vlan_aware_bridges/interfaces.vlan_prune_and_access_ports new file mode 100644 index 0000000..95b6400 --- /dev/null +++ b/docs/examples/vlan_aware_bridges/interfaces.vlan_prune_and_access_ports @@ -0,0 +1,55 @@ +# +# vlan-aware bridge access ports and pruned vlan example +# +# 'bridge' is a vlan aware bridge with all ports (swp1-52). +# native vlan is by default 1 +# +# 'bridge-vids' attribute is used to declare vlans. +# 'bridge-pvid' attribute is used to specify native vlans if other than 1 +# 'bridge-access' attribute is used to declare access port +# +# + +# The following is an access port to vlan 310, no trunking +auto swp1 +iface swp1 + bridge-access 310 + mstpctl-portautoedge yes + mstpctl-bpduguard yes + +# The following is a truk port that is "pruned". +# native vlan is 1, but only .1q tags of 707, 712, 850 are +# sent and received +# +auto swp2 +iface swp2 + bridge-vids 707 712 850 + mstpctl-portautoedge yes + mstpctl-bpduguard yes + +# The following port is the trunk uplink and inherits all vlans +# from bridge br +auto swp49 +iface swp49 + mstpctl-portpathcost 10 + +# The following port is the trunk uplink and inherits all vlans +# from bridge br +auto swp50 +iface swp50 + mstpctl-portpathcost 0 + +# +# ports swp3-swp48 are trunk ports which inherit vlans from the bridge br +# ie vlans 310,700,707,712,850,910 + +# +# the following is a vlan aware bridge with ports swp1-swp52 +# It has stp on +# +auto bridge +iface bridge + bridge-vlan-aware yes + bridge-ports glob swp1-52 + bridge-stp on + bridge-vids 310 700 707 712 850 910 diff --git a/docs/examples/vlan_aware_bridges/interfaces.with_bonds b/docs/examples/vlan_aware_bridges/interfaces.with_bonds new file mode 100644 index 0000000..7a1781a --- /dev/null +++ b/docs/examples/vlan_aware_bridges/interfaces.with_bonds @@ -0,0 +1,92 @@ +# +# vlan-aware bridge with bonds example +# +# uplink1, peerlink and downlink are bond interfaces. +# 'bridge' is a vlan aware bridge with ports uplink1, peerlink +# and downlink (swp2-20). +# +# native vlan is by default 1 +# +# 'bridge-vids' attribute is used to declare vlans. +# 'bridge-pvid' attribute is used to specify native vlans if other than 1 +# 'bridge-access' attribute is used to declare access port +# +auto lo +iface lo + +auto eth0 +iface eth0 inet dhcp + +# bond interface +auto uplink1 +iface uplink1 + bond-slaves swp32 + bond-mode 802.3ad + bond-miimon 100 + bond-use-carrier 1 + bond-lacp-rate 1 + bond-min-links 1 + bond-xmit-hash-policy layer2 + bridge-vids 2000-2079 + +# bond interface +auto peerlink +iface peerlink + bond-slaves swp30 swp31 + bond-mode 802.3ad + bond-miimon 100 + bond-use-carrier 1 + bond-lacp-rate 1 + bond-min-links 1 + bond-xmit-hash-policy layer3+4 + bridge-vids 2000-2079 4094 + +# bond interface +auto downlink +iface downlink + bond-slaves swp1 + bond-mode 802.3ad + bond-miimon 100 + bond-use-carrier 1 + bond-lacp-rate 1 + bond-min-links 1 + bond-xmit-hash-policy layer3+4 + bridge-vids 2000-2079 + +# +# Declare vlans for all swp ports +# swp2-20 get vlans from 2004 to 2022. +# The below uses mako templates to generate iface sections +# with vlans for swp ports +# +%for port, vlanid in zip(range(2, 20), range(2004, 2022)) : + auto swp${port} + iface swp${port} + bridge-vids ${vlanid} + +%endfor + +# svi vlan 4094 +auto bridge.4094 +iface bridge.4094 + address 11.100.1.252/24 + +# l2 attributes for vlan 4094 +auto bridge.4094 +vlan bridge.4094 + bridge-igmp-querier-src 172.16.101.1 + +# +# vlan aware bridge br +# +auto bridge +iface bridge + bridge-vlan-aware yes + bridge-ports uplink1 peerlink downlink glob swp2-20 + bridge-stp on + +# svi peerlink vlan +auto peerlink.4094 +iface peerlink.4094 + address 192.168.10.1/30 + broadcast 192.168.10.3 diff --git a/docs/examples/vlan_aware_bridges/interfaces.with_clag b/docs/examples/vlan_aware_bridges/interfaces.with_clag new file mode 100644 index 0000000..e57b734 --- /dev/null +++ b/docs/examples/vlan_aware_bridges/interfaces.with_clag @@ -0,0 +1,83 @@ +# +# vlan-aware bridge with clag example +# +# +# 'bridge' is a vlan aware bridge with ports: +# 'peer-bond spine-bond glob host-bond-0[1-2]' +# +# All ports inherit 'vlans 10 20-23' from the 'bridge-vids' attribute +# under the bridge +# +# native vlan is by default 1 +# +# 'bridge-vids' attribute is used to declare vlans. +# 'bridge-pvid' attribute is used to specify native vlans if other than 1 +# 'bridge-access' attribute is used to declare access port +# +# + +# spine bond +# +auto spine-bond +iface spine-bond + bond-slaves glob swp19-22 + bond-mode 802.3ad + bond-miimon 100 + bond-use-carrier 1 + bond-lacp-rate 1 + bond-min-links 1 + bond-xmit-hash-policy layer3+4 + +# mlag bond and peer interface +# +auto peer-bond +iface peer-bond + bond-slaves glob swp23-24 + bond-mode 802.3ad + bond-miimon 100 + bond-use-carrier 1 + bond-lacp-rate 1 + bond-min-links 1 + bond-xmit-hash-policy layer3+4 + +# sub-interface for clagd communication +# +auto peer-bond.4094 +iface peer-bond.4094 + address 169.254.0.1/30 + clagd-peer-ip 169.254.0.2 + clagd-sys-mac 44:38:39:ff:00:01 + #clagd-priority 4096 + # Please see man clagd for more options + # clagd-args --peerTimeout 30 + +# host ports +# +auto host-bond-01 +iface host-bond-01 + bond-slaves swp1 + bond-mode 802.3ad + bond-miimon 100 + bond-use-carrier 1 + bond-lacp-rate 1 + bond-min-links 1 + bond-xmit-hash-policy layer3+4 + +auto host-bond-02 +iface host-bond-02 + bond-slaves swp2 + bond-mode 802.3ad + bond-miimon 100 + bond-use-carrier 1 + bond-lacp-rate 1 + bond-min-links 1 + bond-xmit-hash-policy layer3+4 + +# the bridge +# +auto bridge +iface bridge + bridge-vlan-aware yes + bridge-ports peer-bond spine-bond glob host-bond-0[1-2] + bridge-stp on + bridge-vids 10 20-23 From 46416d7443a4680db290c41be5779c4c137ded60 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 25 Nov 2014 22:05:02 -0800 Subject: [PATCH 02/25] Fix setup.py to include new example file names Ticket: CM-3346 Reviewed By: Testing Done:checked build --- setup.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 130d127..c51da37 100755 --- a/setup.py +++ b/setup.py @@ -28,10 +28,10 @@ setup(name='ifupdown2', 'docs/examples/interfaces_with_template', 'docs/examples/interfaces_bridge_igmp_mstp']), ('/usr/share/doc/python-ifupdown2/examples/vlan_aware_bridges', - ['docs/examples/vlan_aware_bridges/interfaces.1', - 'docs/examples/vlan_aware_bridges/interfaces.2', - 'docs/examples/vlan_aware_bridges/interfaces.3', - 'docs/examples/vlan_aware_bridges/interfaces.4']), + ['docs/examples/vlan_aware_bridges/interfaces.basic', + 'docs/examples/vlan_aware_bridges/interfaces.vlan_prune_and_access_ports', + 'docs/examples/vlan_aware_bridges/interfaces.with_bonds', + 'docs/examples/vlan_aware_bridges/interfaces.with_clag']), ('/etc/bash_completion.d/', ['completion/ifup']), ('/usr/share/ifupdownaddons/', ['addons/bridge.py', 'addons/ifenslave.py', 'addons/vlan.py', From 007c9f0f187e7a64c1e573b351a1eca0f0a1a16f Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 25 Nov 2014 22:25:33 -0800 Subject: [PATCH 03/25] add a helper switchd ifupdown script that returns reserved vlan range Ticket: Reviewed By: CCR-2279 Testing Done: tested ifupdown2 reserved vlan checks THis patch adds a switchd ifupdown script to return the reserved vlan. Ifupdown will use this to warn the user when he uses a reserved vlan (THis patch is a result of wilsons request to have a reserved vlan check if ifupdown) --- ifupdownaddons/modulebase.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ifupdownaddons/modulebase.py b/ifupdownaddons/modulebase.py index 50a1e7c..f8cf7c0 100644 --- a/ifupdownaddons/modulebase.py +++ b/ifupdownaddons/modulebase.py @@ -4,6 +4,7 @@ # Author: Roopa Prabhu, roopa@cumulusnetworks.com # +import os import re import io import logging @@ -324,11 +325,14 @@ class moduleBase(object): def _get_reserved_vlan_range(self): start = end = 0 get_resvvlan = '/usr/share/python-ifupdown2/get_reserved_vlan_range.sh' + if not os.path.exists(get_resvvlan): + return (start, end) try: (s, e) = self.exec_command(get_resvvlan).strip('\n').split('-') start = int(s) end = int(e) - except: + except Exception, e: + self.logger.debug('%s failed (%s)' %(get_resvvlan, str(e))) # ignore errors pass return (start, end) From 5b49d0cd7f5c2e6e5b9b9d5e27e27826d5fe60af Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Wed, 26 Nov 2014 10:59:58 -0800 Subject: [PATCH 04/25] Delete stale example files Ticket: CM-3346 Reviewed By: Testing Done: sanity tests --- docs/examples/vlan_aware_bridges/interfaces.1 | 25 ----- docs/examples/vlan_aware_bridges/interfaces.2 | 55 ----------- docs/examples/vlan_aware_bridges/interfaces.3 | 92 ------------------- docs/examples/vlan_aware_bridges/interfaces.4 | 80 ---------------- 4 files changed, 252 deletions(-) delete mode 100644 docs/examples/vlan_aware_bridges/interfaces.1 delete mode 100644 docs/examples/vlan_aware_bridges/interfaces.2 delete mode 100644 docs/examples/vlan_aware_bridges/interfaces.3 delete mode 100644 docs/examples/vlan_aware_bridges/interfaces.4 diff --git a/docs/examples/vlan_aware_bridges/interfaces.1 b/docs/examples/vlan_aware_bridges/interfaces.1 deleted file mode 100644 index 74e4d73..0000000 --- a/docs/examples/vlan_aware_bridges/interfaces.1 +++ /dev/null @@ -1,25 +0,0 @@ -# -# vlan-aware bridge simple example -# -# bridge br is a vlan aware bridge with all ports (swp1-52). -# native vlan is by default 1 -# -# 'bridge-vids' attribute is used to declare vlans. -# 'bridge-pvid' attribute is used to specify native vlans if other than 1 -# 'bridge-access' attribute is used to declare access port -# - -# -# ports swp1-swp52 are trunk ports which inherit vlans from the bridge br -# ie vlans 310 700 707 712 850 910 - -# -# the following is a vlan aware bridge with ports swp1-swp52 -# It has stp on -# -auto br -iface br - bridge-vlan-aware yes - bridge-ports glob swp1-52 - bridge-stp on - bridge-vids 310 700 707 712 850 910 diff --git a/docs/examples/vlan_aware_bridges/interfaces.2 b/docs/examples/vlan_aware_bridges/interfaces.2 deleted file mode 100644 index 5a032ec..0000000 --- a/docs/examples/vlan_aware_bridges/interfaces.2 +++ /dev/null @@ -1,55 +0,0 @@ -# -# vlan-aware bridge access ports and pruned vlan example -# -# bridge br is a vlan aware bridge with all ports (swp1-52). -# native vlan is by default 1 -# -# 'bridge-vids' attribute is used to declare vlans. -# 'bridge-pvid' attribute is used to specify native vlans if other than 1 -# 'bridge-access' attribute is used to declare access port -# -# - -# The following is an access port to vlan 310, no trunking -auto swp1 -iface swp1 - bridge-access 310 - mstpctl-portautoedge yes - mstpctl-bpduguard yes - -# The following is a truk port that is "pruned". -# native vlan is 1, but only .1q tags of 707, 712, 850 are -# sent and received -# -auto swp2 -iface swp2 - bridge-vids 707 712 850 - mstpctl-portautoedge yes - mstpctl-bpduguard yes - -# The following port is the trunk uplink and inherits all vlans -# from bridge br -auto swp49 -iface swp49 - mstpctl-portpathcost 10 - -# The following port is the trunk uplink and inherits all vlans -# from bridge br -auto swp50 -iface swp50 - mstpctl-portpathcost 0 - -# -# ports swp3-swp48 are trunk ports which inherit vlans from the bridge br -# ie vlans 310,700,707,712,850,910 - -# -# the following is a vlan aware bridge with ports swp1-swp52 -# It has stp on -# -auto br -iface br - bridge-vlan-aware yes - bridge-ports glob swp1-52 - bridge-stp on - bridge-vids 310 700 707 712 850 910 diff --git a/docs/examples/vlan_aware_bridges/interfaces.3 b/docs/examples/vlan_aware_bridges/interfaces.3 deleted file mode 100644 index 0064a6a..0000000 --- a/docs/examples/vlan_aware_bridges/interfaces.3 +++ /dev/null @@ -1,92 +0,0 @@ -# -# vlan-aware bridge with bonds example -# -# uplink1, peerlink and downlink are bond interfaces. -# bridge br is a vlan aware bridge with ports uplink1, peerlink -# and downlink (swp2-20). -# -# native vlan is by default 1 -# -# 'bridge-vids' attribute is used to declare vlans. -# 'bridge-pvid' attribute is used to specify native vlans if other than 1 -# 'bridge-access' attribute is used to declare access port -# -auto lo -iface lo - -auto eth0 -iface eth0 inet dhcp - -# bond interface -auto uplink1 -iface uplink1 - bond-slaves swp32 - bond-mode 802.3ad - bond-miimon 100 - bond-use-carrier 1 - bond-lacp-rate 1 - bond-min-links 1 - bond-xmit-hash-policy layer2 - bridge-vids 2000-2079 - -# bond interface -auto peerlink -iface peerlink - bond-slaves swp30 swp31 - bond-mode 802.3ad - bond-miimon 100 - bond-use-carrier 1 - bond-lacp-rate 1 - bond-min-links 1 - bond-xmit-hash-policy layer3+4 - bridge-vids 2000-2079 4094 - -# bond interface -auto downlink -iface downlink - bond-slaves swp1 - bond-mode 802.3ad - bond-miimon 100 - bond-use-carrier 1 - bond-lacp-rate 1 - bond-min-links 1 - bond-xmit-hash-policy layer3+4 - bridge-vids 2000-2079 - -# -# Declare vlans for all swp ports -# swp2-20 get vlans from 2004 to 2022. -# The below uses mako templates to generate iface sections -# with vlans for swp ports -# -%for port, vlanid in zip(range(2, 20), range(2004, 2022)) : - auto swp${port} - iface swp${port} - bridge-vids ${vlanid} - -%endfor - -# svi vlan 4094 -auto br.4094 -iface br.4094 - address 11.100.1.252/24 - -# l2 attributes for vlan 4094 -auto br.4094 -vlan br.4094 - bridge-igmp-querier-src 172.16.101.1 - -# -# vlan aware bridge br -# -auto br -iface br - bridge-vlan-aware yes - bridge-ports uplink1 peerlink downlink glob swp2-20 - bridge-stp on - -# svi peerlink vlan -auto peerlink.4094 -iface peerlink.4094 - address 192.168.10.1/30 - broadcast 192.168.10.3 diff --git a/docs/examples/vlan_aware_bridges/interfaces.4 b/docs/examples/vlan_aware_bridges/interfaces.4 deleted file mode 100644 index 2bb3a5a..0000000 --- a/docs/examples/vlan_aware_bridges/interfaces.4 +++ /dev/null @@ -1,80 +0,0 @@ -# -# vlan-aware bridge with clag example -# -# -# bridge 'br' is a vlan aware bridge with ports: -# 'peer-bond spine-bond glob host-bond-0[1-2]' -# -# All ports inherit 'vlans 10 20-23' from the 'bridge-vids' attribute -# under the bridge -# -# native vlan is by default 1 -# -# 'bridge-vids' attribute is used to declare vlans. -# 'bridge-pvid' attribute is used to specify native vlans if other than 1 -# 'bridge-access' attribute is used to declare access port -# -# - -# spine bond -# -auto spine-bond -iface spine-bond - bond-slaves glob swp19-22 - bond-mode 802.3ad - bond-miimon 100 - bond-use-carrier 1 - bond-lacp-rate 1 - bond-min-links 1 - bond-xmit-hash-policy layer3+4 - -# mlag bond and peer interface -# -auto peer-bond -iface peer-bond - bond-slaves glob swp23-24 - bond-mode 802.3ad - bond-miimon 100 - bond-use-carrier 1 - bond-lacp-rate 1 - bond-min-links 1 - bond-xmit-hash-policy layer3+4 - -# sub-interface for clagd communication -# -auto peer-bond.4094 -iface peer-bond.4094 - address 169.254.0.1/30 - clagd-peer-ip 169.254.0.2 - clagd-sys-mac 44:38:39:ff:00:01 - -# host ports -# -auto host-bond-01 -iface host-bond-01 - bond-slaves swp1 - bond-mode 802.3ad - bond-miimon 100 - bond-use-carrier 1 - bond-lacp-rate 1 - bond-min-links 1 - bond-xmit-hash-policy layer3+4 - -auto host-bond-02 -iface host-bond-02 - bond-slaves swp2 - bond-mode 802.3ad - bond-miimon 100 - bond-use-carrier 1 - bond-lacp-rate 1 - bond-min-links 1 - bond-xmit-hash-policy layer3+4 - -# the bridge -# -auto br -iface br - bridge-vlan-aware yes - bridge-ports peer-bond spine-bond glob host-bond-0[1-2] - bridge-stp on - bridge-vids 10 20-23 From 44d3bb5b9dffa387c403a905ee794cd450c89e98 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Wed, 26 Nov 2014 11:09:50 -0800 Subject: [PATCH 05/25] Fix a few more s/br/bridge/g Ticket: CM-3346 Reviewed By: Testing Done: --- docs/examples/vlan_aware_bridges/interfaces.basic | 2 +- .../interfaces.vlan_prune_and_access_ports | 6 +++--- docs/examples/vlan_aware_bridges/interfaces.with_bonds | 2 +- docs/examples/vlan_aware_bridges/interfaces.with_clag | 1 - 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/examples/vlan_aware_bridges/interfaces.basic b/docs/examples/vlan_aware_bridges/interfaces.basic index 0c64835..7506175 100644 --- a/docs/examples/vlan_aware_bridges/interfaces.basic +++ b/docs/examples/vlan_aware_bridges/interfaces.basic @@ -10,7 +10,7 @@ # # -# ports swp1-swp52 are trunk ports which inherit vlans from the bridge br +# ports swp1-swp52 are trunk ports which inherit vlans from 'bridge' # ie vlans 310 700 707 712 850 910 # diff --git a/docs/examples/vlan_aware_bridges/interfaces.vlan_prune_and_access_ports b/docs/examples/vlan_aware_bridges/interfaces.vlan_prune_and_access_ports index 95b6400..71549a6 100644 --- a/docs/examples/vlan_aware_bridges/interfaces.vlan_prune_and_access_ports +++ b/docs/examples/vlan_aware_bridges/interfaces.vlan_prune_and_access_ports @@ -28,19 +28,19 @@ iface swp2 mstpctl-bpduguard yes # The following port is the trunk uplink and inherits all vlans -# from bridge br +# from 'bridge' auto swp49 iface swp49 mstpctl-portpathcost 10 # The following port is the trunk uplink and inherits all vlans -# from bridge br +# from 'bridge' auto swp50 iface swp50 mstpctl-portpathcost 0 # -# ports swp3-swp48 are trunk ports which inherit vlans from the bridge br +# ports swp3-swp48 are trunk ports which inherit vlans from the 'bridge' # ie vlans 310,700,707,712,850,910 # diff --git a/docs/examples/vlan_aware_bridges/interfaces.with_bonds b/docs/examples/vlan_aware_bridges/interfaces.with_bonds index 7a1781a..f3425dd 100644 --- a/docs/examples/vlan_aware_bridges/interfaces.with_bonds +++ b/docs/examples/vlan_aware_bridges/interfaces.with_bonds @@ -77,7 +77,7 @@ vlan bridge.4094 bridge-igmp-querier-src 172.16.101.1 # -# vlan aware bridge br +# vlan aware bridge # auto bridge iface bridge diff --git a/docs/examples/vlan_aware_bridges/interfaces.with_clag b/docs/examples/vlan_aware_bridges/interfaces.with_clag index e57b734..ae729b6 100644 --- a/docs/examples/vlan_aware_bridges/interfaces.with_clag +++ b/docs/examples/vlan_aware_bridges/interfaces.with_clag @@ -74,7 +74,6 @@ iface host-bond-02 bond-xmit-hash-policy layer3+4 # the bridge -# auto bridge iface bridge bridge-vlan-aware yes From a3b9ac1e996aadd56d07ffca03d23bf12a30565c Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Fri, 28 Nov 2014 12:48:01 -0800 Subject: [PATCH 06/25] Change case of check strings Ticket: CM-3346 Reviewed By: cosmetic Testing Done: ifquery check sanity --- addons/bridge.py | 9 --------- addons/vlan.py | 2 ++ config/ifupdown2.conf | 4 ++-- ifupdownaddons/modulebase.py | 11 +++++++++++ 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/addons/bridge.py b/addons/bridge.py index 696adb1..7cfdd5a 100644 --- a/addons/bridge.py +++ b/addons/bridge.py @@ -336,15 +336,6 @@ class bridge(moduleBase): b = list(b) yield b[0][1], b[-1][1] - def _handle_reserved_vlan(self, vlanid): - if vlanid in range(self._resv_vlan_range[0], - self._resv_vlan_range[1]): - self.logger.warn('skipping reserved vlan %d' %vlanid + - ' (reserved vlan range %d-%d)' %(self._resv_vlan_range[0], - self._resv_vlan_range[1])) - return True - return False - def _ranges_to_ints(self, rangelist): """ returns expanded list of integers given set of string ranges example: ['1', '2-4', '6'] returns [1, 2, 3, 4, 6] diff --git a/addons/vlan.py b/addons/vlan.py index b4e3000..b3bde91 100644 --- a/addons/vlan.py +++ b/addons/vlan.py @@ -124,6 +124,8 @@ class vlan(moduleBase): vlanid = self._get_vlan_id(ifaceobj) if vlanid == -1: raise Exception('could not determine vlanid') + if self._handle_reserved_vlan(vlanid): + return vlanrawdevice = self._get_vlan_raw_device(ifaceobj) if not vlanrawdevice: raise Exception('could not determine vlan raw device') diff --git a/config/ifupdown2.conf b/config/ifupdown2.conf index 79f11a5..d7680ce 100644 --- a/config/ifupdown2.conf +++ b/config/ifupdown2.conf @@ -23,8 +23,8 @@ multiple_vlan_aware_bridge_support=0 # cross marks against interface attributes. # Use the below strings to modify the default behaviour. # -ifquery_check_success_str=(OK) -ifquery_check_error_str=(FAIL) +ifquery_check_success_str=(ok) +ifquery_check_error_str=(fail) ifquery_check_unknown_str= # diff --git a/ifupdownaddons/modulebase.py b/ifupdownaddons/modulebase.py index f8cf7c0..a602eb5 100644 --- a/ifupdownaddons/modulebase.py +++ b/ifupdownaddons/modulebase.py @@ -336,3 +336,14 @@ class moduleBase(object): # ignore errors pass return (start, end) + + def _handle_reserved_vlan(self, vlanid): + """ Helper function to check and warn if the vlanid falls in the + reserved vlan range """ + if vlanid in range(self._resv_vlan_range[0], + self._resv_vlan_range[1]): + self.logger.warn('skipping reserved vlan %d' %vlanid + + ' (reserved vlan range %d-%d)' %(self._resv_vlan_range[0], + self._resv_vlan_range[1])) + return True + return False From a3c7ba7a09fb83602ab6b4b4635ed68f3a3dc528 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Sun, 30 Nov 2014 21:15:10 -0800 Subject: [PATCH 07/25] Change to square brackets (hopefully last change on this before it goes out) Ticket: CM-3346 Reviewed By: Testing Done: Tested ifquery check (cherry picked from commit d8b03e1d50e2936d87a419f16564b79b908e6ef7) --- config/ifupdown2.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/ifupdown2.conf b/config/ifupdown2.conf index d7680ce..96ea793 100644 --- a/config/ifupdown2.conf +++ b/config/ifupdown2.conf @@ -23,8 +23,8 @@ multiple_vlan_aware_bridge_support=0 # cross marks against interface attributes. # Use the below strings to modify the default behaviour. # -ifquery_check_success_str=(ok) -ifquery_check_error_str=(fail) +ifquery_check_success_str=[ok] +ifquery_check_error_str=[fail] ifquery_check_unknown_str= # From ef892cccd96ec22a2f9c95ed1d6f08dd4aa07270 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Sun, 30 Nov 2014 21:44:46 -0800 Subject: [PATCH 08/25] Check for unexpected characters (specifically the ones which look like variable names) + also fix a condition that looks incorrect Ticket: Reviewed By: wkok Testing Done: Tested with the failing This was seen in a case where mako is unable to render the template or incorrectly renders it due to user template errors, leaving interface names with mako variables in them. There is no easy way to recognize and warn about these. This patch tries to warn the user of such cases by looking for variable patterns ('$') in interface names. (cherry picked from commit fc0d45a794a61f7e6a3fd2c2ebce3d621bf0c7b2) --- ifupdown/networkinterfaces.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/ifupdown/networkinterfaces.py b/ifupdown/networkinterfaces.py index 00ab548..5650470 100644 --- a/ifupdown/networkinterfaces.py +++ b/ifupdown/networkinterfaces.py @@ -219,8 +219,18 @@ class networkInterfaces(): iface_attrs = re.split(self._ws_split_regex, iface_line) ifacename = iface_attrs[1] + # in cases where mako is unable to render the template + # or incorrectly renders it due to user template + # errors, we maybe left with interface names with + # mako variables in them. There is no easy way to + # recognize and warn about these. In the below check + # we try to warn the user of such cases by looking for + # variable patterns ('$') in interface names. + if '$' in ifacename: + self._parse_warn(self._currentfile, lineno, + '%s: unexpected characters in interface name' %ifacename) + ifaceobj.raw_config.append(iface_line) - iface_config = collections.OrderedDict() for line_idx in range(cur_idx + 1, len(lines)): l = lines[line_idx].strip(whitespaces) @@ -365,9 +375,9 @@ class networkInterfaces(): try: rendered_filedata = self._template_engine.render(filedata) if rendered_filedata is filedata: - self._currentfile_has_template = True - else: self._currentfile_has_template = False + else: + self._currentfile_has_template = True except Exception, e: self._parse_error(self._currentfile, -1, 'failed to render template (%s). ' %str(e) + From 3e6ea735cc904fe2eaf500c71f9df506360f5ecc Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Mon, 1 Dec 2014 14:54:12 -0800 Subject: [PATCH 09/25] continue passing the object to other modules if one of the modules fails Ticket: CM-4336 Reviewed By: Testing Done: Tested with the missing port testcase from CM-4336 --- addons/mstpctl.py | 27 +++++++-------------------- ifupdown/scheduler.py | 21 ++++++++++++++------- 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/addons/mstpctl.py b/addons/mstpctl.py index a36e962..14745cf 100644 --- a/addons/mstpctl.py +++ b/addons/mstpctl.py @@ -245,25 +245,6 @@ class mstpctl(moduleBase): def _apply_bridge_settings(self, ifaceobj): check = False if self.PERFMODE else True try: - bridgeattrs = {k:v for k,v in - {'treeprio' : - ifaceobj.get_attr_value_first('mstpctl-treeprio'), - 'ageing' : - ifaceobj.get_attr_value_first('mstpctl-ageing'), - 'maxage' : - ifaceobj.get_attr_value_first('mstpctl-maxage'), - 'fdelay' : - ifaceobj.get_attr_value_first('mstpctl-fdelay'), - 'maxhops' : - ifaceobj.get_attr_value_first('mstpctl-maxhops'), - 'txholdcount' : - ifaceobj.get_attr_value_first('mstpctl-txholdcount'), - 'forcevers' : - ifaceobj.get_attr_value_first('mstpctl-forcevers'), - 'hello' : - ifaceobj.get_attr_value_first('mstpctl-hello') - }.items() if v} - # set bridge attributes for attrname, dstattrname in self._attrs_map.items(): try: @@ -346,6 +327,10 @@ class mstpctl(moduleBase): for bport in bridgeports: self.logger.info('%s: processing mstp config for port %s' %(ifaceobj.name, bport)) + if not self.ipcmd.link_exists(bport): + self.logger.warn('%s: port %s does not exist' %(ifaceobj.name, + bport)) + continue bportifaceobjlist = ifaceobj_getfunc(bport) if not bportifaceobjlist: continue @@ -604,7 +589,7 @@ class mstpctl(moduleBase): def _query_check_bridge_port(self, ifaceobj, ifaceobjcurr): if not self.ipcmd.link_exists(ifaceobj.name): - self.logger.debug('bridge port %s does not exist' %ifaceobj.name) + #self.logger.debug('bridge port %s does not exist' %ifaceobj.name) ifaceobjcurr.status = ifaceStatus.NOTFOUND return # Check if this is a bridge port @@ -764,6 +749,8 @@ class mstpctl(moduleBase): of interfaces. status is success if the running state is same as user required state in ifaceobj. error otherwise. """ + if ifaceobj.type == ifaceType.BRIDGE_VLAN: + return op_handler = self._run_ops.get(operation) if not op_handler: return diff --git a/ifupdown/scheduler.py b/ifupdown/scheduler.py index 448b332..247bb76 100644 --- a/ifupdown/scheduler.py +++ b/ifupdown/scheduler.py @@ -43,7 +43,7 @@ class ifaceScheduler(): """ Runs sub operation on an interface """ ifacename = ifaceobj.name - if ifupdownobj.type and ifupdownobj.type != ifaceobj.Type: + if ifupdownobj.type and ifupdownobj.type != ifaceobj.type: return if (cls._STATE_CHECK and @@ -76,12 +76,14 @@ class ifaceScheduler(): ifaceobj_getfunc=ifupdownobj.get_ifaceobjs) else: ifupdownobj.logger.debug(msg) - m.run(ifaceobj, op, ifaceobj_getfunc=ifupdownobj.get_ifaceobjs) + m.run(ifaceobj, op, + ifaceobj_getfunc=ifupdownobj.get_ifaceobjs) except Exception, e: - err = 1 - ifupdownobj.log_error(str(e)) - err = 0 # error can be ignored by log_error, in which case - # reset err flag + if not ifupdownobj.ignore_error(str(e)): + err = 1 + ifupdownobj.logger.warn(str(e)) + # Continue with rest of the modules + pass finally: if err or ifaceobj.status == ifaceStatus.ERROR: ifaceobj.set_state_n_status(ifaceState.from_str(op), @@ -89,8 +91,13 @@ class ifaceScheduler(): if 'up' in op or 'down' in op: cls._SCHED_RETVAL = False else: + # Mark success only if the interface was not already + # marked with error + status = (ifaceobj.status + if ifaceobj.status == ifaceStatus.ERROR + else ifaceStatus.SUCCESS) ifaceobj.set_state_n_status(ifaceState.from_str(op), - ifaceStatus.SUCCESS) + status) if ifupdownobj.config.get('addon_scripts_support', '0') == '1': # execute /etc/network/ scripts From 5b4d304406d53d4230d11f3d0cf6bde5459d698e Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Mon, 1 Dec 2014 23:19:48 -0800 Subject: [PATCH 10/25] Fix formatting for ifquery check (cosmetic. only fixes prints) Ticket: CM-3346 Reviewed By: Testing Done: ifupdown2 sanity + ifquery check tests (cherry picked from commit ba81bde56d04a8f90a6f5d548518605fd1e5ae5f) --- config/ifupdown2.conf | 2 +- ifupdown/iface.py | 34 ++++++++++++++++++++-------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/config/ifupdown2.conf b/config/ifupdown2.conf index 96ea793..012b536 100644 --- a/config/ifupdown2.conf +++ b/config/ifupdown2.conf @@ -23,7 +23,7 @@ multiple_vlan_aware_bridge_support=0 # cross marks against interface attributes. # Use the below strings to modify the default behaviour. # -ifquery_check_success_str=[ok] +ifquery_check_success_str=[pass] ifquery_check_error_str=[fail] ifquery_check_unknown_str= # diff --git a/ifupdown/iface.py b/ifupdown/iface.py index e596bde..5365eca 100644 --- a/ifupdown/iface.py +++ b/ifupdown/iface.py @@ -458,28 +458,35 @@ class iface(): name = self.name if self.auto: outbuf += 'auto %s\n' %name + ifaceline = '' if self.type == ifaceType.BRIDGE_VLAN: - outbuf += 'vlan %s' %name + ifaceline += 'vlan %s' %name else: - outbuf += 'iface %s' %name + ifaceline += 'iface %s' %name if self.addr_family: - outbuf += ' %s' %self.addr_family + ifaceline += ' %s' %self.addr_family if self.addr_method: - outbuf += ' %s' %self.addr_method + ifaceline += ' %s' %self.addr_method if with_status: + status_str = None if (self.status == ifaceStatus.ERROR or self.status == ifaceStatus.NOTFOUND): if self.status_str: - outbuf += ' [%s]' %self.status_str - outbuf += ' %s' %errorstr + ifaceline += ' (%s)' %self.status_str + status_str = errorstr elif self.status == ifaceStatus.SUCCESS: - outbuf += ' %s' %successstr + status_str = successstr + if status_str: + outbuf += '{0:65} {1:>8}'.format(ifaceline, status_str) + '\n' + else: + outbuf += ifaceline + '\n' if self.status == ifaceStatus.NOTFOUND: outbuf = (outbuf.encode('utf8') if isinstance(outbuf, unicode) else outbuf) print outbuf + '\n' return - outbuf += '\n' + else: + outbuf += ifaceline + '\n' config = self.config if config: for cname, cvaluelist in config.items(): @@ -488,14 +495,13 @@ class iface(): if with_status: s = self.get_config_attr_status(cname, idx) if s == -1: - outbuf += (indent + '%s %s %s\n' - %(cname, cv, unknownstr)) + status_str = unknownstr elif s == 1: - outbuf += (indent + '%s %s %s\n' - %(cname, cv, errorstr)) + status_str = errorstr elif s == 0: - outbuf += (indent + '%s %s %s\n' - %(cname, cv, successstr)) + status_str = successstr + outbuf += (indent + '{0:55} {1:>10}'.format( + '%s %s' %(cname, cv), status_str)) + '\n' else: outbuf += indent + '%s %s\n' %(cname, cv) idx += 1 From 4b08367ba3d3d5ce9d7cdd9e58514d09ec46eefe Mon Sep 17 00:00:00 2001 From: Andy Gospodarek Date: Tue, 2 Dec 2014 19:55:30 -0800 Subject: [PATCH 11/25] ifupdown2: remove up op in config file Ticket: CM-3525 Reviewed By: CCR-2035 Testing Done: ifup/ifdown, service networking restart, reboot Need for this change noticed in review. --- config/addons.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/config/addons.conf b/config/addons.conf index 7982fd1..7b90365 100644 --- a/config/addons.conf +++ b/config/addons.conf @@ -10,7 +10,6 @@ up,dhcp up,address up,addressvirtual up,usercmds -up,loopback post-up,ethtool post-up,usercmds post-up,vrrpd From f59b5c656b3af88de62bcba3f01350ae01229356 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Wed, 3 Dec 2014 14:03:34 -0800 Subject: [PATCH 12/25] Fix reserved vlan check + change switchd ifupdown reserved vlan script to return reserved vlan range from /etc/cumulus/switchd.conf Ticket: CM-4367 Reviewed By: wkok Testing Done: Tested using reserved vlans in old and new bridge (cherry picked from commit 8626feb08703392b29e234b2f81f4df536ad7f7b) --- addons/bridge.py | 22 +++++++++++++++++----- addons/vlan.py | 2 +- ifupdownaddons/modulebase.py | 8 ++++---- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/addons/bridge.py b/addons/bridge.py index 7cfdd5a..0f42585 100644 --- a/addons/bridge.py +++ b/addons/bridge.py @@ -345,14 +345,9 @@ class bridge(moduleBase): if '-' in part: a, b = part.split('-') a, b = int(a), int(b) - if (self._handle_reserved_vlan(a) or - self._handle_reserved_vlan(b)): - continue result.extend(range(a, b + 1)) else: a = int(part) - if self._handle_reserved_vlan(a): - continue result.append(a) return result @@ -594,8 +589,25 @@ class bridge(moduleBase): except Exception, e: self.log_warn(str(e)) + def _check_vids(self, ifaceobj, vids): + ret = True + for v in vids: + if '-' in v: + va, vb = v.split('-') + va, vb = int(va), int(vb) + if (self._handle_reserved_vlan(va, ifaceobj.name) or + self._handle_reserved_vlan(vb, ifaceobj.name)): + ret = False + else: + va = int(v) + if self._handle_reserved_vlan(va, ifaceobj.name): + ret = False + return ret + def _apply_bridge_vids(self, bportifaceobj, vids, running_vids, isbridge): try: + if not self._check_vids(bportifaceobj, vids): + return if running_vids: (vids_to_del, vids_to_add) = \ self._diff_vids(vids, running_vids) diff --git a/addons/vlan.py b/addons/vlan.py index b3bde91..3ae9852 100644 --- a/addons/vlan.py +++ b/addons/vlan.py @@ -124,7 +124,7 @@ class vlan(moduleBase): vlanid = self._get_vlan_id(ifaceobj) if vlanid == -1: raise Exception('could not determine vlanid') - if self._handle_reserved_vlan(vlanid): + if self._handle_reserved_vlan(vlanid, ifaceobj.name): return vlanrawdevice = self._get_vlan_raw_device(ifaceobj) if not vlanrawdevice: diff --git a/ifupdownaddons/modulebase.py b/ifupdownaddons/modulebase.py index a602eb5..1ea3311 100644 --- a/ifupdownaddons/modulebase.py +++ b/ifupdownaddons/modulebase.py @@ -337,13 +337,13 @@ class moduleBase(object): pass return (start, end) - def _handle_reserved_vlan(self, vlanid): + def _handle_reserved_vlan(self, vlanid, logprefix=''): """ Helper function to check and warn if the vlanid falls in the reserved vlan range """ if vlanid in range(self._resv_vlan_range[0], self._resv_vlan_range[1]): - self.logger.warn('skipping reserved vlan %d' %vlanid + - ' (reserved vlan range %d-%d)' %(self._resv_vlan_range[0], - self._resv_vlan_range[1])) + self.logger.error('%s: reserved vlan %d being used' + %(logprefix, vlanid) + ' (reserved vlan range %d-%d)' + %(self._resv_vlan_range[0], self._resv_vlan_range[1])) return True return False From 971c9b35c025285a3a7174413b0fbce19eede5ba Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Thu, 4 Dec 2014 08:09:05 -0800 Subject: [PATCH 13/25] Disable vrrpd until it is fully supported Ticket: CM-3791 Reviewed By: Testing Done: compile tested --- config/addons.conf | 2 -- 1 file changed, 2 deletions(-) diff --git a/config/addons.conf b/config/addons.conf index 7b90365..7eb006e 100644 --- a/config/addons.conf +++ b/config/addons.conf @@ -12,8 +12,6 @@ up,addressvirtual up,usercmds post-up,ethtool post-up,usercmds -post-up,vrrpd -pre-down,vrrpd pre-down,usercmds down,dhcp down,addressvirtual From b48ff1a9838a7edcf024ff0ec73f2f404f2fe404 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Mon, 8 Dec 2014 17:15:57 -0800 Subject: [PATCH 14/25] This patch moves bond slave link ownership to the bond module and makes sure that slaves can never be brought admin up on their own when they are not in the bond Ticket: CM-4408 Reviewed By: CCR-2323 Testing Done: Tested ifup/ifdown of bond slaves and bond interface This patch introduces: - introduces 2 interface flags, LINK_MASTER and LINK_SLAVE. - The bond module will set LINK_MASTER on the bond iface object indicating that the bond module owns the link. - Which means that all lower devices /slaves of the bond get their link when the bond (aka LINK_MASTER) is processed in the bond module - The module that queries dependencies propagates the LINK_SLAVE flags on the dependents of LINK_MASTER. - The scheduler now acts on the LINK_SLAVE flag. If LINK_SLAVE is set, it skips setting admin 'up' on that interface. It also makes sure the interface is not already in the bond. ie if an interface is a LINK_SLAVE (bond slave in this case), admin up will not be executed when the interface is not inside the bond. (cherry picked from commit 84b5a07a4f7685c7ae2eac5892889d6c0e08b2eb) --- addons/ifenslave.py | 6 ++-- ifupdown/iface.py | 8 +++-- ifupdown/ifupdownmain.py | 69 +++++++++++++++++++--------------------- 3 files changed, 40 insertions(+), 43 deletions(-) diff --git a/addons/ifenslave.py b/addons/ifenslave.py index a4dbf0d..7189cd4 100644 --- a/addons/ifenslave.py +++ b/addons/ifenslave.py @@ -105,6 +105,7 @@ class ifenslave(moduleBase): # Also save a copy for future use ifaceobj.priv_data = list(slave_list) + ifaceobj.flags |= iface.LINK_MASTER return slave_list def get_dependent_ifacenames_running(self, ifaceobj): @@ -200,9 +201,8 @@ class ifenslave(moduleBase): self.log_warn('%s: skipping slave %s, does not exist' %(ifaceobj.name, slave)) continue - self.ifenslavecmd.enslave_slave(ifaceobj.name, slave, - prehook=self.ipcmd.link_down, - posthook=self.ipcmd.link_up) + self.ipcmd.link_set(slave, 'master', ifaceobj.name) + rtnetlink_api.rtnl_api.link_set(slave, "up") def _apply_slaves_lacp_fallback_prio(self, ifaceobj): slaves = self.ifenslavecmd.get_slaves(ifaceobj.name) diff --git a/ifupdown/iface.py b/ifupdown/iface.py index 5365eca..3e9d81a 100644 --- a/ifupdown/iface.py +++ b/ifupdown/iface.py @@ -181,6 +181,8 @@ class iface(): HAS_SIBLINGS = 0x2 IFACERANGE_ENTRY = 0x3 IFACERANGE_START = 0x4 + LINK_MASTER = 0x5 + LINK_SLAVE = 0x6 version = '0.1' @@ -452,10 +454,10 @@ class iface(): unknownstr='unknown', use_realname=False): indent = '\t' outbuf = '' - if use_realname: - name = self.realname + if use_realname and self.realname: + name = '%s' %self.realname else: - name = self.name + name = '%s' %self.name if self.auto: outbuf += 'auto %s\n' %name ifaceline = '' diff --git a/ifupdown/ifupdownmain.py b/ifupdown/ifupdownmain.py index e807267..5443b20 100644 --- a/ifupdown/ifupdownmain.py +++ b/ifupdown/ifupdownmain.py @@ -108,14 +108,26 @@ class ifupdownMain(ifupdownBase): # Handlers for ops that ifupdown2 owns def run_up(self, ifaceobj): - ifacename = ifaceobj.name - if self.link_exists(ifacename): - self.link_up(ifacename) + # If this object is a link slave, ie its link is controlled + # by its link master interface, then dont set the link state. + # But do allow user to change state of the link if the interface + # is already with its link master (hence the master check). + if ((ifaceobj.flags & iface.LINK_SLAVE) and + not os.path.exists('/sys/class/net/%s/master' %ifaceobj.name)): + return + if self.link_exists(ifaceobj.name): + self.link_up(ifaceobj.name) def run_down(self, ifaceobj): - ifacename = ifaceobj.name - if self.link_exists(ifacename): - self.link_down(ifacename) + # If this object is a link slave, ie its link is controlled + # by its link master interface, then dont set the link state. + # But do allow user to change state of the link if the interface + # is already with its link master (hence the master check). + if ((ifaceobj.flags & iface.LINK_SLAVE) and + not os.path.exists('/sys/class/net/%s/master' %ifaceobj.name)): + return + if self.link_exists(ifaceobj.name): + self.link_down(ifaceobj.name) # ifupdown object interface operation handlers ops_handlers = OrderedDict([('up', run_up), @@ -314,7 +326,7 @@ class ifupdownMain(ifupdownBase): if not ifaceobj: return True return self.is_ifaceobj_noconfig(ifaceobj) - def preprocess_dependency_list(self, upperifacename, dlist, ops): + def preprocess_dependency_list(self, upperifaceobj, dlist, ops): """ We go through the dependency list and delete or add interfaces from the interfaces dict by applying the following rules: @@ -334,18 +346,25 @@ class ifupdownMain(ifupdownBase): for d in dlist: dilist = self.get_ifaceobjs(d) if not dilist: + ni = None if self.is_iface_builtin_byname(d): - self.create_n_save_ifaceobj(d, self.BUILTIN | self.NOCONFIG, - True).add_to_upperifaces(upperifacename) + ni = self.create_n_save_ifaceobj(d, self.BUILTIN | self.NOCONFIG, + True) elif not self._DELETE_DEPENDENT_IFACES_WITH_NOCONFIG: - self.create_n_save_ifaceobj(d, self.NOCONFIG, - True).add_to_upperifaces(upperifacename) + ni = self.create_n_save_ifaceobj(d, self.NOCONFIG, + True) else: del_list.append(d) + if ni: + ni.add_to_upperifaces(upperifaceobj.name) + if (upperifaceobj.flags & iface.LINK_MASTER): + ni.flags |= iface.LINK_SLAVE else: for di in dilist: di.inc_refcnt() - di.add_to_upperifaces(upperifacename) + di.add_to_upperifaces(upperifaceobj.name) + if (upperifaceobj.flags & iface.LINK_MASTER): + di.flags |= iface.LINK_SLAVE for d in del_list: dlist.remove(d) @@ -375,30 +394,6 @@ class ifupdownMain(ifupdownBase): if dlist: ret_dlist.extend(dlist) return list(set(ret_dlist)) - def populate_dependency_info_old(self, ops, ifacenames=None): - """ recursive function to generate iface dependency info """ - - if not ifacenames: - ifacenames = self.ifaceobjdict.keys() - - iqueue = deque(ifacenames) - while iqueue: - i = iqueue.popleft() - # Go through all modules and find dependent ifaces - dlist = None - ifaceobj = self.get_ifaceobj_first(i) - if not ifaceobj: - continue - dlist = self.query_dependents(ifaceobj, ops, ifacenames) - if dlist and dlist != ifaceobj.lowerifaces: - self.preprocess_dependency_list(ifaceobj.name, - dlist, ops) - [iqueue.append(d) for d in dlist] - self.dependency_graph.setdefault(i, []).extend(dlist) - ifaceobj.lowerifaces = self.dependency_graph.get(i) - else: - self.dependency_graph[i] = dlist - def populate_dependency_info(self, ops, ifacenames=None): """ recursive function to generate iface dependency info """ @@ -419,7 +414,7 @@ class ifupdownMain(ifupdownBase): else: continue if dlist: - self.preprocess_dependency_list(ifaceobj.name, + self.preprocess_dependency_list(ifaceobj, dlist, ops) ifaceobj.lowerifaces = dlist [iqueue.append(d) for d in dlist] From c416da6adc8f1ac0869dec7f161083b9f4d6f806 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Mon, 8 Dec 2014 22:59:41 -0800 Subject: [PATCH 15/25] Move LINK_MASTER/LINK_SLAVE to a new field link_type (purna hit some issues with having it in flags) + add check for bond slave being already up Ticket: CM-4408 Reviewed By: Testing Done: some bond sanity test (cherry picked from commit 346b62a41fbf4521008cd8a9b0fa227e75a5d994) --- addons/ifenslave.py | 14 +++++++------- debian/python-ifupdown2.postinst | 8 ++++---- ifupdown/iface.py | 10 ++++++++-- ifupdown/ifupdownmain.py | 12 ++++++------ ifupdownaddons/iproute2.py | 12 ++++++++++++ 5 files changed, 37 insertions(+), 19 deletions(-) diff --git a/addons/ifenslave.py b/addons/ifenslave.py index 7189cd4..e854b3b 100644 --- a/addons/ifenslave.py +++ b/addons/ifenslave.py @@ -105,7 +105,7 @@ class ifenslave(moduleBase): # Also save a copy for future use ifaceobj.priv_data = list(slave_list) - ifaceobj.flags |= iface.LINK_MASTER + ifaceobj.link_type = ifaceLinkType.LINK_MASTER return slave_list def get_dependent_ifacenames_running(self, ifaceobj): @@ -145,6 +145,7 @@ class ifenslave(moduleBase): def _apply_master_settings(self, ifaceobj): have_attrs_to_set = 0 + linkup = False ifenslavecmd_attrmap = OrderedDict([('bond-mode' , 'mode'), ('bond-miimon' , 'miimon'), ('bond-use-carrier', 'use_carrier'), @@ -157,10 +158,7 @@ class ifenslave(moduleBase): ('bond-ad-sys-priority' , 'ad_sys_priority'), ('bond-lacp-fallback-allow', 'lacp_fallback_allow'), ('bond-lacp-fallback-period', 'lacp_fallback_period')]) - linkstatus = self.ipcmd.link_get_status(ifaceobj.name) - if not linkstatus: - # assume link status is 'UP' - linkstatus = 'UP' + linkup = self.ipcmd.is_link_up(ifaceobj.name) try: # order of attributes set matters for bond, so # construct the list sequentially @@ -173,11 +171,11 @@ class ifenslave(moduleBase): return have_attrs_to_set = 1 self.ifenslavecmd.set_attrs(ifaceobj.name, attrstoset, - self.ipcmd.link_down if linkstatus == 'UP' else None) + self.ipcmd.link_down if linkup else None) except: raise finally: - if have_attrs_to_set and linkstatus == 'UP': + if have_attrs_to_set and linkup: self.ipcmd.link_up(ifaceobj.name) def _add_slaves(self, ifaceobj): @@ -201,6 +199,8 @@ class ifenslave(moduleBase): self.log_warn('%s: skipping slave %s, does not exist' %(ifaceobj.name, slave)) continue + if self.ipcmd.is_link_up(slave): + rtnetlink_api.rtnl_api.link_set(slave, "down") self.ipcmd.link_set(slave, 'master', ifaceobj.name) rtnetlink_api.rtnl_api.link_set(slave, "up") diff --git a/debian/python-ifupdown2.postinst b/debian/python-ifupdown2.postinst index 9247975..10ca49a 100644 --- a/debian/python-ifupdown2.postinst +++ b/debian/python-ifupdown2.postinst @@ -50,10 +50,10 @@ case "$1" in fi fi - [ -e /sbin/ifup ] || ln -s /sbin/ifupdown /sbin/ifup - [ -e /sbin/ifdown ] || ln -s /sbin/ifupdown /sbin/ifdown - [ -e /sbin/ifquery ] || ln -s /sbin/ifupdown /sbin/ifquery - [ -e /sbin/ifreload ] || ln -s /sbin/ifupdown /sbin/ifreload + [ -e /sbin/ifup ] || ln -sf /sbin/ifupdown /sbin/ifup + [ -e /sbin/ifdown ] || ln -sf /sbin/ifupdown /sbin/ifdown + [ -e /sbin/ifquery ] || ln -sf /sbin/ifupdown /sbin/ifquery + [ -e /sbin/ifreload ] || ln -sf /sbin/ifupdown /sbin/ifreload (cd /usr/share/man/man8/ && ln -sf /usr/share/man/man8/ifup.8.gz ifdown.8.gz) diff --git a/ifupdown/iface.py b/ifupdown/iface.py index 3e9d81a..22ebf82 100644 --- a/ifupdown/iface.py +++ b/ifupdown/iface.py @@ -22,6 +22,11 @@ class ifaceType(): IFACE = 0x1 BRIDGE_VLAN = 0x2 +class ifaceLinkType(): + UNKNOWN = 0x0 + LINK_SLAVE = 0x1 + LINK_MASTER = 0x2 + class ifaceStatus(): """Enumerates iface status """ @@ -181,8 +186,6 @@ class iface(): HAS_SIBLINGS = 0x2 IFACERANGE_ENTRY = 0x3 IFACERANGE_START = 0x4 - LINK_MASTER = 0x5 - LINK_SLAVE = 0x6 version = '0.1' @@ -218,6 +221,7 @@ class iface(): """interface type""" self.priv_data = None self.realname = None + self.link_type = ifaceLinkType.UNKNOWN def _set_attrs_from_dict(self, attrdict): self.auto = attrdict.get('auto', False) @@ -401,6 +405,7 @@ class iface(): del odict['raw_config'] del odict['linkstate'] del odict['env'] + del odict['link_type'] return odict def __setstate__(self, dict): @@ -417,6 +422,7 @@ class iface(): self.priv_flags = 0 self.raw_config = [] self.flags |= self._PICKLED + self.link_type = ifaceLinkType.UNKNOWN def dump_raw(self, logger): indent = ' ' diff --git a/ifupdown/ifupdownmain.py b/ifupdown/ifupdownmain.py index 5443b20..d24b0ab 100644 --- a/ifupdown/ifupdownmain.py +++ b/ifupdown/ifupdownmain.py @@ -112,7 +112,7 @@ class ifupdownMain(ifupdownBase): # by its link master interface, then dont set the link state. # But do allow user to change state of the link if the interface # is already with its link master (hence the master check). - if ((ifaceobj.flags & iface.LINK_SLAVE) and + if ((ifaceobj.link_type == ifaceLinkType.LINK_SLAVE) and not os.path.exists('/sys/class/net/%s/master' %ifaceobj.name)): return if self.link_exists(ifaceobj.name): @@ -123,7 +123,7 @@ class ifupdownMain(ifupdownBase): # by its link master interface, then dont set the link state. # But do allow user to change state of the link if the interface # is already with its link master (hence the master check). - if ((ifaceobj.flags & iface.LINK_SLAVE) and + if ((ifaceobj.link_type == ifaceLinkType.LINK_SLAVE) and not os.path.exists('/sys/class/net/%s/master' %ifaceobj.name)): return if self.link_exists(ifaceobj.name): @@ -357,14 +357,14 @@ class ifupdownMain(ifupdownBase): del_list.append(d) if ni: ni.add_to_upperifaces(upperifaceobj.name) - if (upperifaceobj.flags & iface.LINK_MASTER): - ni.flags |= iface.LINK_SLAVE + if upperifaceobj.link_type == ifaceLinkType.LINK_MASTER: + ni.link_type = ifaceLinkType.LINK_SLAVE else: for di in dilist: di.inc_refcnt() di.add_to_upperifaces(upperifaceobj.name) - if (upperifaceobj.flags & iface.LINK_MASTER): - di.flags |= iface.LINK_SLAVE + if upperifaceobj.flags == ifaceLinkType.LINK_MASTER: + di.link_type = ifaceLinkType.LINK_SLAVE for d in del_list: dlist.remove(d) diff --git a/ifupdownaddons/iproute2.py b/ifupdownaddons/iproute2.py index 51feac4..b2111a1 100644 --- a/ifupdownaddons/iproute2.py +++ b/ifupdownaddons/iproute2.py @@ -673,3 +673,15 @@ class iproute2(utilsBase): def is_bridge(self, bridge): return os.path.exists('/sys/class/net/%s/bridge' %bridge) + + def is_link_up(self, ifacename): + ret = False + try: + flags = self.read_file_oneline('/sys/class/net/%s/flags' %ifacename) + iflags = int(flags, 16) + if (iflags & 0x0001): + ret = True + except: + ret = False + pass + return ret From 5be7399dc962a3f194c5f6c2e63f87ab3324a17c Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 9 Dec 2014 12:56:45 -0800 Subject: [PATCH 16/25] Fix if condition when propagating link_type (old flags check left over from my previous commit) Ticket: CM-4408 Reviewed By: Testing Done: Tested with old bridge driver config (bug reported by satish) (cherry picked from commit 11e6ae96aae85591e8d32e1062d979e51de9e424) --- ifupdown/ifupdownmain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ifupdown/ifupdownmain.py b/ifupdown/ifupdownmain.py index d24b0ab..3c65322 100644 --- a/ifupdown/ifupdownmain.py +++ b/ifupdown/ifupdownmain.py @@ -363,7 +363,7 @@ class ifupdownMain(ifupdownBase): for di in dilist: di.inc_refcnt() di.add_to_upperifaces(upperifaceobj.name) - if upperifaceobj.flags == ifaceLinkType.LINK_MASTER: + if upperifaceobj.link_type == ifaceLinkType.LINK_MASTER: di.link_type = ifaceLinkType.LINK_SLAVE for d in del_list: From 6c3425307c2df25daa1828ef4e9bd7c8251c7a15 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 9 Dec 2014 13:49:23 -0800 Subject: [PATCH 17/25] Add clagd in the default shipped addons.conf and remove the editing of addons file Ticket: CM-4423 Reviewed By: Testing Done: tested ifupdown2 in the presence and absence of clagd This is a hack to get around an ifupdown2 limitation. The real fix should come as part of CM-3782 (cherry picked from commit 6fb63d6cdcb660063cf5d07ff28f49c34a306371) --- config/addons.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/config/addons.conf b/config/addons.conf index 7eb006e..4228b19 100644 --- a/config/addons.conf +++ b/config/addons.conf @@ -12,6 +12,7 @@ up,addressvirtual up,usercmds post-up,ethtool post-up,usercmds +post-up,clagd pre-down,usercmds down,dhcp down,addressvirtual From 853d3b146ac042b64b4082a10e68998ec74b2f68 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 9 Dec 2014 14:26:11 -0800 Subject: [PATCH 18/25] Remove stale debug Ticket: Reviewed By: Testing Done: (cherry picked from commit 3ccb3873a995ee7d47134dbbae88ebb424da6d8e) --- addons/vrrpd.py | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/vrrpd.py b/addons/vrrpd.py index 13bb93e..9791141 100644 --- a/addons/vrrpd.py +++ b/addons/vrrpd.py @@ -64,7 +64,6 @@ class vrrpd(moduleBase): targetpids.append(pid) except: pass - self.logger.debug("Roopa: targetpids = %s" %str(targetpids)) return targetpids def _up(self, ifaceobj): From 40ed8c4d30eb4f8bf9cd1d21af279770e8531d73 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Wed, 10 Dec 2014 21:30:39 -0800 Subject: [PATCH 19/25] Add a few more trt/except blocks to warn and proceed Ticket: Reviewed By: Testing Done: (cherry picked from commit da446f09f0c723852f20ba1c666abcc80b5fe764) --- ifupdown/scheduler.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/ifupdown/scheduler.py b/ifupdown/scheduler.py index 247bb76..f50f99f 100644 --- a/ifupdown/scheduler.py +++ b/ifupdown/scheduler.py @@ -138,7 +138,11 @@ class ifaceScheduler(): if (not ifaceobjs[0].addr_method or (ifaceobjs[0].addr_method and ifaceobjs[0].addr_method != 'manual')): - handler(ifupdownobj, ifaceobjs[0]) + try: + handler(ifupdownobj, ifaceobjs[0]) + except Exception, e: + ifupdownobj.logger.warn('%s' %str(e)) + pass for ifaceobj in ifaceobjs: cls.run_iface_op(ifupdownobj, ifaceobj, op, cenv=ifupdownobj.generate_running_env(ifaceobj, op) @@ -146,8 +150,12 @@ class ifaceScheduler(): '0') == '1' else None) posthookfunc = ifupdownobj.sched_hooks.get('posthook') if posthookfunc: - [posthookfunc(ifupdownobj, ifaceobj, ops[0]) - for ifaceobj in ifaceobjs] + try: + [posthookfunc(ifupdownobj, ifaceobj, ops[0]) + for ifaceobj in ifaceobjs] + except Exception, e: + ifupdownobj.logger.warn('%s' %str(e)) + pass @classmethod def _check_upperifaces(cls, ifupdownobj, ifaceobj, ops, parent, From 73c275920ac301b1aa2a27705f4380199a010a7f Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Thu, 11 Dec 2014 16:13:25 -0800 Subject: [PATCH 20/25] Fix hex flags representation (this was causing wrong evaluation of & and | on flags) Ticket: Reviewed By: Testing Done: Problem seen with ifquery skipping some interfaces because of wrong evaluation of iface flags --- ifupdown/iface.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ifupdown/iface.py b/ifupdown/iface.py index 22ebf82..7cbad6d 100644 --- a/ifupdown/iface.py +++ b/ifupdown/iface.py @@ -182,10 +182,10 @@ class iface(): """ # flag to indicate that the object was created from pickled state - _PICKLED = 0x1 - HAS_SIBLINGS = 0x2 - IFACERANGE_ENTRY = 0x3 - IFACERANGE_START = 0x4 + _PICKLED = 0x00000001 + HAS_SIBLINGS = 0x00000010 + IFACERANGE_ENTRY = 0x00000100 + IFACERANGE_START = 0x00001000 version = '0.1' From 1be3f95b01266d314a30aa6f13324d36f8714136 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Fri, 12 Dec 2014 22:56:29 -0800 Subject: [PATCH 21/25] s/fallback/bypass/ Ticket: CM-4452 Reviewed By: Testing Done: Tested with old and new format --- addons/ifenslave.py | 55 ++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/addons/ifenslave.py b/addons/ifenslave.py index e854b3b..1d08632 100644 --- a/addons/ifenslave.py +++ b/addons/ifenslave.py @@ -67,17 +67,33 @@ class ifenslave(moduleBase): 'example' : ['bond-ad-sys-mac-addr 00:00:00:00:00:00']}, 'bond-lacp-fallback-allow': {'help' : 'allow lacp fall back', + 'compat' : True, 'validvals' : ['0', '1'], 'default' : '0', 'example' : ['bond-lacp-fallback-allow 0']}, 'bond-lacp-fallback-period': {'help' : 'grace period (seconds) for lacp fall back', + 'compat' : True, 'validrange' : ['0', '100'], 'default' : '90', 'example' : ['bond-lacp-fallback-period 100']}, 'bond-lacp-fallback-priority': {'help' : 'slave priority for lacp fall back', + 'compat' : True, 'example' : ['bond-lacp-fallback-priority swp1=1 swp2=1 swp3=2']}, + 'bond-lacp-bypass-allow': + {'help' : 'allow lacp bypass', + 'validvals' : ['0', '1'], + 'default' : '0', + 'example' : ['bond-lacp-bypass-allow 0']}, + 'bond-lacp-bypass-period': + {'help' : 'grace period (seconds) for lacp bypass', + 'validrange' : ['0', '100'], + 'default' : '90', + 'example' : ['bond-lacp-bypass-period 100']}, + 'bond-lacp-bypass-priority': + {'help' : 'slave priority for lacp bypass', + 'example' : ['bond-lacp-bypass-priority swp1=1 swp2=1 swp3=2']}, 'bond-slaves' : {'help' : 'bond slaves', 'required' : True, @@ -157,7 +173,9 @@ class ifenslave(moduleBase): ('bond-ad-sys-mac-addr' , 'ad_sys_mac_addr'), ('bond-ad-sys-priority' , 'ad_sys_priority'), ('bond-lacp-fallback-allow', 'lacp_fallback_allow'), - ('bond-lacp-fallback-period', 'lacp_fallback_period')]) + ('bond-lacp-fallback-period', 'lacp_fallback_period'), + ('bond-lacp-bypass-allow', 'lacp_fallback_allow'), + ('bond-lacp-bypass-period', 'lacp_fallback_period')]) linkup = self.ipcmd.is_link_up(ifaceobj.name) try: # order of attributes set matters for bond, so @@ -204,16 +222,16 @@ class ifenslave(moduleBase): self.ipcmd.link_set(slave, 'master', ifaceobj.name) rtnetlink_api.rtnl_api.link_set(slave, "up") - def _apply_slaves_lacp_fallback_prio(self, ifaceobj): + def _apply_slaves_lacp_bypass_prio(self, ifaceobj): slaves = self.ifenslavecmd.get_slaves(ifaceobj.name) - attrval = ifaceobj.get_attr_value_first('bond-lacp-fallback-priority') + attrval = ifaceobj.get_attrs_value_first(['bond-lacp-bypass-priority', + 'bond-lacp-fallback-priority']) if attrval: portlist = self.parse_port_list(attrval) if not portlist: self.log_warn('%s: could not parse \'%s %s\'' %(ifaceobj.name, attrname, attrval)) return - for p in portlist: try: (port, val) = p.split('=') @@ -222,7 +240,8 @@ class ifenslave(moduleBase): %(ifaceobj.name, port)) continue slaves.remove(port) - self.ifenslavecmd.set_lacp_fallback_priority(ifaceobj.name, port, val) + self.ifenslavecmd.set_lacp_fallback_priority( + ifaceobj.name, port, val) except Exception, e: self.log_warn('%s: failed to set lacp_fallback_priority %s (%s)' %(ifaceobj.name, port, str(e))) @@ -231,7 +250,7 @@ class ifenslave(moduleBase): try: self.ifenslavecmd.set_lacp_fallback_priority(ifaceobj.name, p, '0') except Exception, e: - self.log_warn('%s: failed to clear lacp_fallback_priority %s (%s)' + self.log_warn('%s: failed to clear lacp_bypass_priority %s (%s)' %(ifaceobj.name, p, str(e))) @@ -241,7 +260,7 @@ class ifenslave(moduleBase): self.ifenslavecmd.create_bond(ifaceobj.name) self._apply_master_settings(ifaceobj) self._add_slaves(ifaceobj) - self._apply_slaves_lacp_fallback_prio(ifaceobj) + self._apply_slaves_lacp_bypass_prio(ifaceobj) if ifaceobj.addr_method == 'manual': rtnetlink_api.rtnl_api.link_set(ifaceobj.name, "up") except Exception, e: @@ -265,26 +284,33 @@ class ifenslave(moduleBase): self.get_mod_attrs()) if not ifaceattrs: return runningattrs = self._query_running_attrs(ifaceobj.name) + + # backward compat change + runningattrs.update({'bond-lacp-fallback-allow': runningattrs.get( + 'bond-lacp-bypass-allow'), + 'bond-lacp-fallback-period': runningattrs.get( + 'bond-lacp-bypass-period'), + 'bond-lacp-fallback-priority': runningattrs.get( + 'bond-lacp-bypass-priority')}) for k in ifaceattrs: v = ifaceobj.get_attr_value_first(k) if not v: continue if k == 'bond-slaves': slaves = self._get_slave_list(ifaceobj) - #slaves = v.split() continue rv = runningattrs.get(k) if not rv: ifaceobjcurr.update_config_with_status(k, 'None', 1) else: - if k == 'bond-lacp-fallback-priority': + if (k == 'bond-lacp-bypass-priority' or + k == 'bond-lacp-fallback-priority'): prios = v.split() prios.sort() prio_str = ' '.join(prios) ifaceobjcurr.update_config_with_status(k, rv, - 1 if prio_str != rv else 0) + 1 if prio_str != rv else 0) continue - ifaceobjcurr.update_config_with_status(k, rv, 1 if v != rv else 0) runningslaves = runningattrs.get('bond-slaves') @@ -317,13 +343,12 @@ class ifenslave(moduleBase): self.ifenslavecmd.get_ad_sys_priority(bondname), 'bond-xmit-hash-policy' : self.ifenslavecmd.get_xmit_hash_policy(bondname), - 'bond-lacp-fallback-allow' : + 'bond-lacp-bypass-allow' : self.ifenslavecmd.get_lacp_fallback_allow(bondname), - 'bond-lacp-fallback-period' : + 'bond-lacp-bypass-period' : self.ifenslavecmd.get_lacp_fallback_period(bondname), - 'bond-lacp-fallback-priority' : + 'bond-lacp-bypass-priority' : self.ifenslavecmd.get_lacp_fallback_priority(bondname)} - slaves = self.ifenslavecmd.get_slaves(bondname) if slaves: bondattrs['bond-slaves'] = slaves From ff3bdefff7f42b0e6e2fc8f56a6dd18e55420dc1 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Fri, 12 Dec 2014 23:45:31 -0800 Subject: [PATCH 22/25] bring up bridge ports only after vlan config is done Ticket: Reviewed By: wkok Testing Done: unit testing + testing by wkok/purna (cherry picked from commit 5af90b2893cd54bb21fedaf27ec6dd22de3f2802) Conflicts: packages/ifupdown2/addons/bridge.py --- addons/bridge.py | 18 +++++++++++------- ifupdownaddons/bridgeutils.py | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/addons/bridge.py b/addons/bridge.py index 0f42585..426d3df 100644 --- a/addons/bridge.py +++ b/addons/bridge.py @@ -278,16 +278,19 @@ class bridge(moduleBase): runningbridgeports = [] self._process_bridge_waitport(ifaceobj, bridgeports) + self.ipcmd.batch_start() # Delete active ports not in the new port list if not self.PERFMODE: runningbridgeports = self.brctlcmd.get_bridge_ports(ifaceobj.name) if runningbridgeports: - [self.ipcmd.link_set(bport, 'nomaster') - for bport in runningbridgeports - if not bridgeports or bport not in bridgeports] + for bport in runningbridgeports: + if not bridgeports or bport not in bridgeports: + self.ipcmd.link_set(bport, 'nomaster') + self.ipcmd.link_set(bport, 'down') else: runningbridgeports = [] if not bridgeports: + self.ipcmd.batch_commit() return err = 0 for bridgeport in Set(bridgeports).difference(Set(runningbridgeports)): @@ -302,7 +305,9 @@ class bridge(moduleBase): '/disable_ipv6', '1') self.ipcmd.addr_flush(bridgeport) except Exception, e: - self.log_error(str(e)) + self.logger.error(str(e)) + pass + self.ipcmd.batch_commit() if err: self.log_error('bridge configuration failed (missing ports)') @@ -784,7 +789,6 @@ class bridge(moduleBase): link_exists = False porterr = False porterrstr = '' - self.ipcmd.batch_start() if not self.PERFMODE: if not self.ipcmd.link_exists(ifaceobj.name): self.ipcmd.link_create(ifaceobj.name, 'bridge') @@ -797,8 +801,6 @@ class bridge(moduleBase): porterr = True porterrstr = str(e) pass - finally: - self.ipcmd.batch_commit() self._apply_bridge_settings(ifaceobj) self._apply_bridge_port_settings_all(ifaceobj, ifaceobj_getfunc=ifaceobj_getfunc) @@ -806,6 +808,8 @@ class bridge(moduleBase): except Exception, e: self.log_error(str(e)) finally: + running_ports = self.brctlcmd.get_bridge_ports(ifaceobj.name) + [rtnetlink_api.rtnl_api.link_set(p, "up") for p in running_ports] if link_exists and ifaceobj.addr_method == 'manual': rtnetlink_api.rtnl_api.link_set(ifaceobj.name, "up") if porterr: diff --git a/ifupdownaddons/bridgeutils.py b/ifupdownaddons/bridgeutils.py index f38a3ff..73f28b1 100644 --- a/ifupdownaddons/bridgeutils.py +++ b/ifupdownaddons/bridgeutils.py @@ -498,4 +498,4 @@ class brctl(utilsBase): try: return os.listdir('/sys/class/net/%s/brif/' %bridgename) except: - return {} + return [] From caac3e369d72eb582eb359141cfcb2a25e3791af Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Mon, 15 Dec 2014 17:45:49 -0800 Subject: [PATCH 23/25] fix kernel lacp_fallback_* sysfs file references to use lacp_bypass_* Ticket: Reviewed By: Testing Done: Build and sanity test --- addons/ifenslave.py | 8 ++++---- ifupdownaddons/ifenslaveutil.py | 26 +++++++++++++------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/addons/ifenslave.py b/addons/ifenslave.py index 1d08632..74c5001 100644 --- a/addons/ifenslave.py +++ b/addons/ifenslave.py @@ -172,10 +172,10 @@ class ifenslave(moduleBase): ('bond-num-unsol-na' , 'num_unsol_na'), ('bond-ad-sys-mac-addr' , 'ad_sys_mac_addr'), ('bond-ad-sys-priority' , 'ad_sys_priority'), - ('bond-lacp-fallback-allow', 'lacp_fallback_allow'), - ('bond-lacp-fallback-period', 'lacp_fallback_period'), - ('bond-lacp-bypass-allow', 'lacp_fallback_allow'), - ('bond-lacp-bypass-period', 'lacp_fallback_period')]) + ('bond-lacp-fallback-allow', 'lacp_bypass_allow'), + ('bond-lacp-fallback-period', 'lacp_bypass_period'), + ('bond-lacp-bypass-allow', 'lacp_bypass_allow'), + ('bond-lacp-bypass-period', 'lacp_bypass_period')]) linkup = self.ipcmd.is_link_up(ifaceobj.name) try: # order of attributes set matters for bond, so diff --git a/ifupdownaddons/ifenslaveutil.py b/ifupdownaddons/ifenslaveutil.py index 8a23ca5..ab21f21 100644 --- a/ifupdownaddons/ifenslaveutil.py +++ b/ifupdownaddons/ifenslaveutil.py @@ -52,7 +52,7 @@ class ifenslaveutil(utilsBase): self.read_file_oneline('/sys/class/net/%s/bonding/%s' %(bondname, x))), ['use_carrier', 'miimon', 'min_links', 'num_unsol_na', - 'num_grat_arp', 'lacp_fallback_allow', 'lacp_fallback_period']) + 'num_grat_arp', 'lacp_bypass_allow', 'lacp_bypass_period']) except Exception, e: pass @@ -231,44 +231,44 @@ class ifenslaveutil(utilsBase): return self._cache_get([bondname, 'linkinfo', 'lacp_rate']) def set_lacp_fallback_allow(self, bondname, allow, prehook=None, posthook=None): - if (self._cache_check([bondname, 'linkinfo', 'lacp_fallback_allow'], - lacp_fallback_allow)): + if (self._cache_check([bondname, 'linkinfo', 'lacp_bypass_allow'], + lacp_bypass_allow)): return if prehook: prehook(bondname) try: self.write_file('/sys/class/net/%s' %bondname + - '/bonding/lacp_fallback_allow', allow) + '/bonding/lacp_bypass_allow', allow) except: raise finally: if posthook: posthook(bondname) self._cache_update([bondname, 'linkinfo', - 'lacp_fallback_allow'], allow) + 'lacp_bypass_allow'], allow) def get_lacp_fallback_allow(self, bondname): - return self._cache_get([bondname, 'linkinfo', 'lacp_fallback_allow']) + return self._cache_get([bondname, 'linkinfo', 'lacp_bypass_allow']) def set_lacp_fallback_period(self, bondname, period, prehook=None, posthook=None): - if (self._cache_check([bondname, 'linkinfo', 'lacp_fallback_period'], - lacp_fallback_period)): + if (self._cache_check([bondname, 'linkinfo', 'lacp_bypass_period'], + lacp_bypass_period)): return if prehook: prehook(bondname) try: self.write_file('/sys/class/net/%s' %bondname + - '/bonding/lacp_fallback_period', period) + '/bonding/lacp_bypass_period', period) except: raise finally: if posthook: posthook(bondname) self._cache_update([bondname, 'linkinfo', - 'lacp_fallback_period'], period) + 'lacp_bypass_period'], period) def get_lacp_fallback_period(self, bondname): - return self._cache_get([bondname, 'linkinfo', 'lacp_fallback_period']) + return self._cache_get([bondname, 'linkinfo', 'lacp_bypass_period']) def set_min_links(self, bondname, min_links, prehook=None): if (self._cache_check([bondname, 'linkinfo', 'min_links'], @@ -284,7 +284,7 @@ class ifenslaveutil(utilsBase): return self._cache_get([bondname, 'linkinfo', 'min_links']) def set_lacp_fallback_priority(self, bondname, port, val): - slavefile = '/sys/class/net/%s/bonding_slave/lacp_fallback_priority' %port + slavefile = '/sys/class/net/%s/bonding_slave/lacp_bypass_priority' %port if os.path.exists(slavefile): self.write_file(slavefile, val) @@ -294,7 +294,7 @@ class ifenslaveutil(utilsBase): return slaves prios = [] for slave in slaves: - priofile = '/sys/class/net/%s/bonding_slave/lacp_fallback_priority' %slave + priofile = '/sys/class/net/%s/bonding_slave/lacp_bypass_priority' %slave if os.path.exists(priofile): val = self.read_file_oneline(priofile) if val and val != '0': From a070c90ec3c3342d349e54aed45f2500cd8403e5 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Wed, 17 Dec 2014 12:39:38 -0800 Subject: [PATCH 24/25] Multiple fixes and cleanup Ticket: CM-3346 Reviewed By: Testing Done: Tested ifupdown2 sanity - moved 'admin up' delays that we introduced recently to be configurable via two ifupdown2.conf attributes # Let link master (bridges, bonds) own the link state of slaves link_master_slave=1 # Delay admin state change till the end delay_admin_state_change=0 - reduced some redundant traversal of dependency trees - fixed a few bugs in query check --- addons/bridge.py | 16 ++++--- addons/ifenslave.py | 8 +++- addons/mstpctl.py | 2 +- addons/vxlan.py | 2 +- config/ifupdown2.conf | 6 +++ ifupdown/iface.py | 13 +++--- ifupdown/ifupdownmain.py | 80 +++++++++++++++++++++++++++++------ ifupdown/networkinterfaces.py | 12 +++--- ifupdown/rtnetlink_api.py | 4 +- ifupdown/scheduler.py | 32 ++++++++------ 10 files changed, 126 insertions(+), 49 deletions(-) diff --git a/addons/bridge.py b/addons/bridge.py index 426d3df..ae15fd7 100644 --- a/addons/bridge.py +++ b/addons/bridge.py @@ -218,6 +218,8 @@ class bridge(moduleBase): def get_dependent_ifacenames(self, ifaceobj, ifacenames_all=None): if not self._is_bridge(ifaceobj): return None + if ifaceobj.link_type != ifaceLinkType.LINK_NA: + ifaceobj.link_type = ifaceLinkType.LINK_MASTER return self.parse_port_list(ifaceobj.get_attr_value_first( 'bridge-ports'), ifacenames_all) @@ -808,8 +810,10 @@ class bridge(moduleBase): except Exception, e: self.log_error(str(e)) finally: - running_ports = self.brctlcmd.get_bridge_ports(ifaceobj.name) - [rtnetlink_api.rtnl_api.link_set(p, "up") for p in running_ports] + if ifaceobj.link_type != ifaceLinkType.LINK_NA: + running_ports = self.brctlcmd.get_bridge_ports(ifaceobj.name) + [rtnetlink_api.rtnl_api.link_set(p, "up") + for p in running_ports] if link_exists and ifaceobj.addr_method == 'manual': rtnetlink_api.rtnl_api.link_set(ifaceobj.name, "up") if porterr: @@ -819,12 +823,14 @@ class bridge(moduleBase): try: if ifaceobj.get_attr_value_first('bridge-ports'): ports = self.brctlcmd.get_bridge_ports(ifaceobj.name) + self.brctlcmd.delete_bridge(ifaceobj.name) if ports: for p in ports: proc_file = ('/proc/sys/net/ipv6/conf/%s' %p + '/disable_ipv6') self.write_file(proc_file, '0') - self.brctlcmd.delete_bridge(ifaceobj.name) + if ifaceobj.link_type == ifaceLinkType.LINK_MASTER: + rtnetlink_api.rtnl_api.link_set(p, "down") except Exception, e: self.log_error(str(e)) @@ -1284,11 +1290,11 @@ class bridge(moduleBase): ifaceobj_getfunc): if not self._is_bridge_port(ifaceobj): # Mark all bridge attributes as failed - ifaceobj.check_n_update_config_with_status_many( + ifaceobjcurr.check_n_update_config_with_status_many(ifaceobj, ['bridge-vids', 'bridge-pvid', 'bridge-access', 'bridge-pathcosts', 'bridge-portprios', 'bridge-portmcrouter', - 'bridge-portmcfl'], 0) + 'bridge-portmcfl'], 1) return bridgename = self._get_bridge_name(ifaceobj) if not bridgename: diff --git a/addons/ifenslave.py b/addons/ifenslave.py index 74c5001..8cb51ba 100644 --- a/addons/ifenslave.py +++ b/addons/ifenslave.py @@ -121,7 +121,8 @@ class ifenslave(moduleBase): # Also save a copy for future use ifaceobj.priv_data = list(slave_list) - ifaceobj.link_type = ifaceLinkType.LINK_MASTER + if ifaceobj.link_type != ifaceLinkType.LINK_NA: + ifaceobj.link_type = ifaceLinkType.LINK_MASTER return slave_list def get_dependent_ifacenames_running(self, ifaceobj): @@ -217,10 +218,13 @@ class ifenslave(moduleBase): self.log_warn('%s: skipping slave %s, does not exist' %(ifaceobj.name, slave)) continue + link_up = False if self.ipcmd.is_link_up(slave): rtnetlink_api.rtnl_api.link_set(slave, "down") + link_up = True self.ipcmd.link_set(slave, 'master', ifaceobj.name) - rtnetlink_api.rtnl_api.link_set(slave, "up") + if link_up or ifaceobj.link_type != ifaceLinkType.LINK_NA: + rtnetlink_api.rtnl_api.link_set(slave, "up") def _apply_slaves_lacp_bypass_prio(self, ifaceobj): slaves = self.ifenslavecmd.get_slaves(ifaceobj.name) diff --git a/addons/mstpctl.py b/addons/mstpctl.py index 14745cf..4ace15a 100644 --- a/addons/mstpctl.py +++ b/addons/mstpctl.py @@ -595,7 +595,7 @@ class mstpctl(moduleBase): # Check if this is a bridge port if not self._is_bridge_port(ifaceobj): # mark all the bridge attributes as error - ifaceobj.check_n_update_config_with_status_many( + ifaceobjcurr.check_n_update_config_with_status_many(ifaceobj, self._port_attrs_map.keys(), 0) return bridgename = self.ipcmd.bridge_port_get_bridge_name(ifaceobj.name) diff --git a/addons/vxlan.py b/addons/vxlan.py index e4b16c6..8d87b2f 100644 --- a/addons/vxlan.py +++ b/addons/vxlan.py @@ -80,7 +80,7 @@ class vxlan(moduleBase): # Update vxlan object vxlanattrs = self.ipcmd.get_vxlandev_attrs(ifaceobj.name) if not vxlanattrs: - ifaceobjcurr.check_n_update_config_with_status_many( + ifaceobjcurr.check_n_update_config_with_status_many(ifaceobj, self.get_mod_attrs(), -1) return self._query_check_n_update(ifaceobjcurr, 'vxlan-id', diff --git a/config/ifupdown2.conf b/config/ifupdown2.conf index 012b536..2c23ac9 100644 --- a/config/ifupdown2.conf +++ b/config/ifupdown2.conf @@ -32,3 +32,9 @@ ifquery_check_unknown_str= # in ifquery default output. ifquery_ifacename_expand_range=0 +# Let link master (bridges, bonds) own the link state of slaves +link_master_slave=1 + +# Delay admin state change till the end +delay_admin_state_change=0 + diff --git a/ifupdown/iface.py b/ifupdown/iface.py index 7cbad6d..a1cabe5 100644 --- a/ifupdown/iface.py +++ b/ifupdown/iface.py @@ -23,9 +23,10 @@ class ifaceType(): BRIDGE_VLAN = 0x2 class ifaceLinkType(): - UNKNOWN = 0x0 + LINK_UNKNOWN = 0x0 LINK_SLAVE = 0x1 LINK_MASTER = 0x2 + LINK_NA = 0x3 class ifaceStatus(): """Enumerates iface status """ @@ -221,7 +222,7 @@ class iface(): """interface type""" self.priv_data = None self.realname = None - self.link_type = ifaceLinkType.UNKNOWN + self.link_type = ifaceLinkType.LINK_UNKNOWN def _set_attrs_from_dict(self, attrdict): self.auto = attrdict.get('auto', False) @@ -358,13 +359,13 @@ class iface(): # Not already error, mark success self.status = ifaceStatus.SUCCESS - def check_n_update_config_with_status_many(self, attr_names, + def check_n_update_config_with_status_many(self, ifaceobjorig, attr_names, attr_status=0): # set multiple attribute status to zero # also updates status only if the attribute is present for attr_name in attr_names: - if not self.get_attr_value_first(attr_name): - return + if not ifaceobjorig.get_attr_value_first(attr_name): + continue self.config.setdefault(attr_name, []).append('') self._config_status.setdefault(attr_name, []).append(attr_status) @@ -422,7 +423,7 @@ class iface(): self.priv_flags = 0 self.raw_config = [] self.flags |= self._PICKLED - self.link_type = ifaceLinkType.UNKNOWN + self.link_type = ifaceLinkType.LINK_UNKNOWN def dump_raw(self, logger): indent = ' ' diff --git a/ifupdown/ifupdownmain.py b/ifupdown/ifupdownmain.py index 3c65322..a1e8d4c 100644 --- a/ifupdown/ifupdownmain.py +++ b/ifupdown/ifupdownmain.py @@ -60,8 +60,8 @@ class ifupdownMain(ifupdownBase): ADDONS_ENABLE = False # priv flags to mark iface objects - BUILTIN = 0x1 - NOCONFIG = 0x2 + BUILTIN = 0x0001 + NOCONFIG = 0x0010 scripts_dir='/etc/network' addon_modules_dir='/usr/share/ifupdownaddons' @@ -108,6 +108,12 @@ class ifupdownMain(ifupdownBase): # Handlers for ops that ifupdown2 owns def run_up(self, ifaceobj): + if (ifaceobj.addr_method and + ifaceobj.addr_method == 'manual'): + return + if self._delay_admin_state: + self._delay_admin_state_iface_queue.append(ifaceobj.name) + return # If this object is a link slave, ie its link is controlled # by its link master interface, then dont set the link state. # But do allow user to change state of the link if the interface @@ -115,19 +121,27 @@ class ifupdownMain(ifupdownBase): if ((ifaceobj.link_type == ifaceLinkType.LINK_SLAVE) and not os.path.exists('/sys/class/net/%s/master' %ifaceobj.name)): return - if self.link_exists(ifaceobj.name): - self.link_up(ifaceobj.name) + if not self.link_exists(ifaceobj.name): + return + self.link_up(ifaceobj.name) def run_down(self, ifaceobj): + if (ifaceobj.addr_method and + ifaceobj.addr_method == 'manual'): + return + if self._delay_admin_state: + self._delay_admin_state_iface_queue.append(ifaceobj.name) + return # If this object is a link slave, ie its link is controlled # by its link master interface, then dont set the link state. # But do allow user to change state of the link if the interface # is already with its link master (hence the master check). - if ((ifaceobj.link_type == ifaceLinkType.LINK_SLAVE) and - not os.path.exists('/sys/class/net/%s/master' %ifaceobj.name)): + if ((ifaceobj.link_type == ifaceLinkType.LINK_SLAVE) and + not os.path.exists('/sys/class/net/%s/master' %ifaceobj.name)): return - if self.link_exists(ifaceobj.name): - self.link_down(ifaceobj.name) + if not self.link_exists(ifaceobj.name): + return + self.link_down(ifaceobj.name) # ifupdown object interface operation handlers ops_handlers = OrderedDict([('up', run_up), @@ -215,6 +229,14 @@ class ifupdownMain(ifupdownBase): raise else: self.STATEMANAGER_UPDATE = False + self._delay_admin_state = True if self.config.get( + 'delay_admin_state_change', '0') == '1' else False + self._delay_admin_state_iface_queue = [] + if not self._delay_admin_state: + self._link_master_slave = True if self.config.get( + 'link_master_slave', '0') == '1' else False + else: + self._link_master_slave = False def get_ifaceobjs(self, ifacename): return self.ifaceobjdict.get(ifacename) @@ -348,8 +370,8 @@ class ifupdownMain(ifupdownBase): if not dilist: ni = None if self.is_iface_builtin_byname(d): - ni = self.create_n_save_ifaceobj(d, self.BUILTIN | self.NOCONFIG, - True) + ni = self.create_n_save_ifaceobj(d, + self.BUILTIN | self.NOCONFIG, True) elif not self._DELETE_DEPENDENT_IFACES_WITH_NOCONFIG: ni = self.create_n_save_ifaceobj(d, self.NOCONFIG, True) @@ -365,7 +387,6 @@ class ifupdownMain(ifupdownBase): di.add_to_upperifaces(upperifaceobj.name) if upperifaceobj.link_type == ifaceLinkType.LINK_MASTER: di.link_type = ifaceLinkType.LINK_SLAVE - for d in del_list: dlist.remove(d) @@ -448,6 +469,8 @@ class ifupdownMain(ifupdownBase): if ifaceobj.compare(currentifaceobjlist[0]): self.logger.warn('duplicate interface %s found' %ifaceobj.name) return + if not self._link_master_slave: + ifaceobj.link_type = ifaceLinkType.LINK_NA if currentifaceobjlist[0].type == ifaceobj.type: currentifaceobjlist[0].flags |= iface.HAS_SIBLINGS ifaceobj.flags |= iface.HAS_SIBLINGS @@ -747,6 +770,23 @@ class ifupdownMain(ifupdownBase): else: self.type = ifaceType.UNKNOWN + def _process_delay_admin_state_queue(self, op): + if not self._delay_admin_state_iface_queue: + return + if op == 'up': + func = self.link_up + elif op == 'down': + func = self.link_down + else: + return + for i in self._delay_admin_state_iface_queue: + try: + if self.link_exists(i): + func(i) + except Exception, e: + self.logger.warn(str(e)) + pass + def up(self, ops, auto=False, allow_classes=None, ifacenames=None, excludepats=None, printdependency=None, syntaxcheck=False, type=None, skipupperifaces=False): @@ -805,6 +845,7 @@ class ifupdownMain(ifupdownBase): self._sched_ifaces(filtered_ifacenames, ops, skipupperifaces=skipupperifaces) finally: + self._process_delay_admin_state_queue('up') if not self.DRYRUN and self.ADDONS_ENABLE: self._save_state() @@ -865,6 +906,7 @@ class ifupdownMain(ifupdownBase): try: self._sched_ifaces(filtered_ifacenames, ops) finally: + self._process_delay_admin_state_queue('down') if not self.DRYRUN and self.ADDONS_ENABLE: self._save_state() @@ -1090,7 +1132,13 @@ class ifupdownMain(ifupdownBase): self.dependency_graph = OrderedDict({}) # Generate dependency info for old config self.populate_dependency_info(downops, ifacedownlist) - self._sched_ifaces(ifacedownlist, downops) + try: + self._sched_ifaces(ifacedownlist, downops) + except Exception, e: + self.logger.error(str(e)) + pass + finally: + self._process_delay_admin_state_queue('down') else: self.logger.debug('no interfaces to down ..') @@ -1107,7 +1155,13 @@ class ifupdownMain(ifupdownBase): self.logger.info('reload: scheduling up on interfaces: %s' %str(filtered_ifacenames)) - self._sched_ifaces(filtered_ifacenames, upops) + try: + self._sched_ifaces(filtered_ifacenames, upops) + except Exception, e: + self.logger.error(str(e)) + pass + finally: + self._process_delay_admin_state_queue('up') if self.DRYRUN: return self._save_state() diff --git a/ifupdown/networkinterfaces.py b/ifupdown/networkinterfaces.py index 5650470..66db91b 100644 --- a/ifupdown/networkinterfaces.py +++ b/ifupdown/networkinterfaces.py @@ -287,9 +287,9 @@ class networkInterfaces(): if range_val: for v in range(range_val[1], range_val[2]): ifaceobj_new = copy.deepcopy(ifaceobj) - ifaceobj_new.realname = ifaceobj.name - ifaceobj_new.name = "%s%d" %(range_val[0], v) - ifaceobj_new.flags |= iface.IFACERANGE_ENTRY + ifaceobj_new.realname = '%s' %ifaceobj.name + ifaceobj_new.name = '%s%d' %(range_val[0], v) + ifaceobj_new.flags = iface.IFACERANGE_ENTRY if v == range_val[1]: ifaceobj_new.flags |= iface.IFACERANGE_START self.callbacks.get('iface_found')(ifaceobj_new) @@ -306,10 +306,10 @@ class networkInterfaces(): if range_val: for v in range(range_val[1], range_val[2]): ifaceobj_new = copy.deepcopy(ifaceobj) - ifaceobj_new.realname = ifaceobj.name - ifaceobj_new.name = "%s%d" %(range_val[0], v) + ifaceobj_new.realname = '%s' %ifaceobj.name + ifaceobj_new.name = '%s%d' %(range_val[0], v) ifaceobj_new.type = ifaceType.BRIDGE_VLAN - ifaceobj_new.flags |= iface.IFACERANGE_ENTRY + ifaceobj_new.flags = iface.IFACERANGE_ENTRY if v == range_val[1]: ifaceobj_new.flags |= iface.IFACERANGE_START self.callbacks.get('iface_found')(ifaceobj_new) diff --git a/ifupdown/rtnetlink_api.py b/ifupdown/rtnetlink_api.py index ab3fe0e..3993ce8 100644 --- a/ifupdown/rtnetlink_api.py +++ b/ifupdown/rtnetlink_api.py @@ -40,7 +40,7 @@ class rtnetlinkApi(RtNetlink): return ifindex def create_vlan(self, link, ifname, vlanid): - self.logger.info('rtnetlink: creating vlan %s' %ifname) + self.logger.info('rtnetlink: creating vlan interface %s' %ifname) if ifupdownmain.ifupdownFlags.DRYRUN: return try: @@ -64,7 +64,7 @@ class rtnetlinkApi(RtNetlink): self.process_wait([token]) def create_macvlan(self, ifname, link, mode='private'): - self.logger.info('rtnetlink: creating macvlan %s' %ifname) + self.logger.info('rtnetlink: creating macvlan interface %s' %ifname) if ifupdownmain.ifupdownFlags.DRYRUN: return try: diff --git a/ifupdown/scheduler.py b/ifupdown/scheduler.py index f50f99f..a634586 100644 --- a/ifupdown/scheduler.py +++ b/ifupdown/scheduler.py @@ -46,10 +46,6 @@ class ifaceScheduler(): if ifupdownobj.type and ifupdownobj.type != ifaceobj.type: return - if (cls._STATE_CHECK and - (ifaceobj.state >= ifaceState.from_str(op))): - ifupdownobj.logger.debug('%s: already in state %s' %(ifacename, op)) - return if not ifupdownobj.ADDONS_ENABLE: return if op == 'query-checkcurr': query_ifaceobj=ifupdownobj.create_n_save_ifaceobjcurr(ifaceobj) @@ -114,6 +110,7 @@ class ifaceScheduler(): """ Runs all operations on a list of interface configurations for the same interface """ + # minor optimization. If operation is 'down', proceed only # if interface exists in the system ifacename = ifaceobjs[0].name @@ -135,14 +132,12 @@ class ifaceScheduler(): # for the first object in the list handler = ifupdownobj.ops_handlers.get(op) if handler: - if (not ifaceobjs[0].addr_method or - (ifaceobjs[0].addr_method and - ifaceobjs[0].addr_method != 'manual')): - try: - handler(ifupdownobj, ifaceobjs[0]) - except Exception, e: - ifupdownobj.logger.warn('%s' %str(e)) - pass + try: + handler(ifupdownobj, ifaceobjs[0]) + except Exception, e: + ifupdownobj.logger.warn('%s: %s' + %(ifaceobjs[0].name, str(e))) + pass for ifaceobj in ifaceobjs: cls.run_iface_op(ifupdownobj, ifaceobj, op, cenv=ifupdownobj.generate_running_env(ifaceobj, op) @@ -212,10 +207,16 @@ class ifaceScheduler(): if not ifaceobjs: raise Exception('%s: not found' %ifacename) + # Check state of the dependent. If it is already brought up, return + if (cls._STATE_CHECK and + (ifaceobjs[0].state == ifaceState.from_str(ops[-1]))): + ifupdownobj.logger.debug('%s: already processed' %ifacename) + return + for ifaceobj in ifaceobjs: if not cls._check_upperifaces(ifupdownobj, ifaceobj, ops, parent, followdependents): - return + return # If inorder, run the iface first and then its dependents if order == ifaceSchedulerFlags.INORDER: @@ -288,6 +289,11 @@ class ifaceScheduler(): if not ifaceobjs: raise Exception('%s: not found' %ifacename) + if (cls._STATE_CHECK and + (ifaceobjs[0].state == ifaceState.from_str(ops[-1]))): + ifupdownobj.logger.debug('%s: already processed' %ifacename) + return + if not skip_root: # run the iface first and then its upperifaces cls.run_iface_list_ops(ifupdownobj, ifaceobjs, ops) From 8c2c9f2661bc52a04cb29f880320d2f427bdb72f Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Wed, 17 Dec 2014 15:09:52 -0800 Subject: [PATCH 25/25] Add check for vlan aware bridge when setting arp_accept to 1 Ticket: CM-4373 Reviewed By: Testing Done: Tested with address on vlan aware bridge as described in the bug --- addons/address.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/address.py b/addons/address.py index 9843d23..627837e 100644 --- a/addons/address.py +++ b/addons/address.py @@ -82,7 +82,8 @@ class address(moduleBase): if '.' in ifaceobj.name: (bridgename, vlan) = ifaceobj.name.split('.') is_vlan_dev_on_vlan_aware_bridge = self.ipcmd.bridge_is_vlan_aware(bridgename) - if is_bridge or is_vlan_dev_on_vlan_aware_bridge: + if ((is_bridge and not self.ipcmd.bridge_is_vlan_aware(ifaceobj.name)) + or is_vlan_dev_on_vlan_aware_bridge): if self._address_valid(addrs): if up: self.write_file('/proc/sys/net/ipv4/conf/%s' %ifaceobj.name +