Compare commits

...

No commits in common. "c8" and "c9s" have entirely different histories.
c8 ... c9s

25 changed files with 1712 additions and 183 deletions

58
.gitignore vendored
View File

@ -1 +1,57 @@
SOURCES/libteam-1.31.tar.gz
/libteam-20120113git302672e.tar.gz
/libteam-20120125gita1718f8.tar.gz
/libteam-20120130gitb5cf2a8.tar.gz
/libteam-20120221gitfe97f63.tar.gz
/libteam-20120405gita82f8ac.tar.gz
/libteam-20120504git11e234a.tar.gz
/libteam-20120620gita88fabf.tar.gz
/libteam-20120627gitcd6b557.tar.gz
/libteam-20120627git96569f8.tar.gz
/libteam-20120628gitca7b526.tar.gz
/libteam-20120807gitf042120.tar.gz
/libteam-20120807git9fa4a96.tar.gz
/libteam-20120822gitc0d943d.tar.gz
/libteam-20120904gitbdcf72c.tar.gz
/libteam-20120923git8448186.tar.gz
/libteam-20120925gitcc5cddc.tar.gz
/libteam-20121007git6f48751.tar.gz
/libteam-20121019git1a91059.tar.gz
/libteam-20121025git7fe7c72.tar.gz
/libteam-20121105git3b95b34.tar.gz
/libteam-20121115gitffb5267.tar.gz
/libteam-20121122git18b6701.tar.gz
/libteam-20121206git659a848.tar.gz
/libteam-20121212git01fe4bd.tar.gz
/libteam-20130110gitf16805c.tar.gz
/libteam-1.0.tar.gz
/libteam-1.1.tar.gz
/libteam-1.2.tar.gz
/libteam-1.3.tar.gz
/libteam-1.4.tar.gz
/libteam-1.5.tar.gz
/libteam-1.6.tar.gz
/libteam-1.7.tar.gz
/libteam-1.8.tar.gz
/libteam-1.9.tar.gz
/libteam-1.10.tar.gz
/libteam-1.11.tar.gz
/libteam-1.12.tar.gz
/libteam-1.13.tar.gz
/libteam-1.14.tar.gz
/libteam-1.15.tar.gz
/libteam-1.16.tar.gz
/libteam-1.17.tar.gz
/libteam-1.18.tar.gz
/libteam-1.19.tar.gz
/libteam-1.20.tar.gz
/libteam-1.21.tar.gz
/libteam-1.22.tar.gz
/libteam-1.23.tar.gz
/libteam-1.24.tar.gz
/libteam-1.25.tar.gz
/libteam-1.26.tar.gz
/libteam-1.27.tar.gz
/libteam-1.28.tar.gz
/libteam-1.29.tar.gz
/libteam-1.30.tar.gz
/libteam-1.31.tar.gz

View File

@ -1 +1 @@
4e5e0a0d0682f27a0850fac1f9bababdb991f14a SOURCES/libteam-1.31.tar.gz
338f2bae08e143bc3f7a84317ddc3053cff2691d libteam-1.31.tar.gz

View File

@ -0,0 +1,339 @@
From 7a2260a85cb14c58792273753e4f58cca358c548 Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Tue, 30 Mar 2021 17:06:42 +0800
Subject: [PATCH] team: add a tool for team to bonding config migration
Since we will deprecate team on RHEL9 and remove it on RHEL10, add a tool
for team to bonding config migration.
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
man/teamd.8 | 2 +
utils/team2bond | 302 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 304 insertions(+)
create mode 100755 utils/team2bond
diff --git a/man/teamd.8 b/man/teamd.8
index 3d27eae..652111b 100644
--- a/man/teamd.8
+++ b/man/teamd.8
@@ -32,6 +32,8 @@ teamd \(em team network device control daemon
.br
.B teamd
.BR \-h | \-V
+.SH NOTE
+Teaming is deprecated on RHEL9 and will be removed on RHEL10! For replacement please use bonding.
.SH DESCRIPTION
.PP
teamd is a daemon to control a given team network device, during runtime,
diff --git a/utils/team2bond b/utils/team2bond
new file mode 100755
index 0000000..6ac9d52
--- /dev/null
+++ b/utils/team2bond
@@ -0,0 +1,302 @@
+#!/bin/env python3
+# vim: sts=4 ts=4 sw=4 expandtab :
+
+from optparse import OptionParser
+import subprocess
+import json
+import sys
+
+def handle_cmd_line():
+ parser = OptionParser()
+ parser.add_option('--config', dest='config', default = '',
+ help = "convert the team JSON format configuration file " \
+ + "to NetworkManager connection profile, please use " \
+ + "'teamdctl TEAM config dump' to dump the config file." \
+ + " Note the script only convert config file. IP " \
+ + "address configurations still need to be set manually.")
+ parser.add_option('--rename', dest='rename', default = '',
+ help = "rename the default team interface name." \
+ + " Careful: firewall rules, aliases interfaces, etc., " \
+ + "will break after the renaming because the tool " \
+ + "will only change the config file, nothing else.")
+ parser.add_option('--exec-cmd', dest='exec_cmd', action='store_true', default = False,
+ help = "exec nmcli and add the connections directly " \
+ + "instead of printing the nmcli cmd to screen. " \
+ + "This parameter is NOT recommend, it would be good " \
+ + "to double check the cmd before apply.")
+
+ (options, args) = parser.parse_args()
+
+ if subprocess.run(['nmcli', '-v'], stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL).returncode != 0:
+ print("Warn: NetworkManager is needed for this script!");
+ sys.exit(1)
+
+ return options
+
+def convert_runner_opts(runner_opts):
+ bond_opts = ""
+
+ if runner_opts['name'] == 'broadcast':
+ bond_opts = "mode=broadcast"
+ elif runner_opts['name'] == 'roundrobin':
+ bond_opts = "mode=balance-rr"
+ elif runner_opts['name'] == 'activebackup':
+ bond_opts = "mode=active-backup"
+ if 'hwaddr_policy' in runner_opts:
+ if runner_opts['hwaddr_policy'] == 'same_all':
+ bond_opts += ",fail_over_mac=none"
+ elif runner_opts['hwaddr_policy'] == 'by_active':
+ bond_opts += ",fail_over_mac=active"
+ elif runner_opts['hwaddr_policy'] == 'only_active':
+ bond_opts += ",fail_over_mac=follow"
+ else:
+ print("# Warn: invalid runner.hwaddr_policy: " + runner_opts['hwaddr_policy'])
+ elif runner_opts['name'] == 'loadbalance':
+ bond_opts = "mode=balance-tlb"
+ elif runner_opts['name'] == 'lacp':
+ bond_opts = "mode=802.3ad"
+ if 'active' in runner_opts:
+ print("# Warn: option runner.active: %r is not supported by bonding" % runner_opts['active'])
+ if 'fast_rate' in runner_opts:
+ if runner_opts['fast_rate']:
+ bond_opts += ",lacp_rate=1"
+ else:
+ bond_opts += ",lacp_rate=0"
+ if 'sys_prio' in runner_opts:
+ bond_opts += ",ad_actor_sys_prio=" + str(runner_opts['sys_prio'])
+ if 'min_ports' in runner_opts:
+ bond_opts += ",min_links=" + runner_opts['min_ports']
+ if 'agg_select_policy' in runner_opts:
+ if runner_opts['agg_select_policy'] == 'bandwidth':
+ bond_opts += ",ad_select=bandwidth"
+ elif runner_opts['agg_select_policy'] == 'count':
+ bond_opts += ",ad_select=count"
+ else:
+ print("# Warn: Option runner.agg_select_policy: %s is not supported by bonding" %
+ runner_opts['agg_select_policy'])
+ sys.exit(1)
+ else:
+ print("Error: Unsupported runner.name: %s for bonding" % runner_opts['name'])
+ sys.exit(1)
+
+ if 'tx_hash' in runner_opts:
+ print("# Warn: tx_hash ipv4, ipv6, tcp, udp, sctp are not supported by bonding")
+ if 'vlan' in runner_opts['tx_hash']:
+ bond_opts +=",xmit_hash_policy=vlan+srcmac"
+ if 'eth' in runner_opts['tx_hash']:
+ bond_opts +=",xmit_hash_policy=layer2"
+ if 'l3' in runner_opts['tx_hash'] or 'ip' in runner_opts['tx_hash']:
+ bond_opts +="+3"
+ elif ('l3' in runner_opts['tx_hash'] or 'ip' in runner_opts['tx_hash']) \
+ and 'l4' in runner_opts['tx_hash']:
+ bond_opts +=",xmit_hash_policy=layer3+4"
+
+ if 'tx_balancer' in runner_opts:
+ if 'name' in runner_opts['tx_balancer']:
+ if runner_opts['tx_balancer']['name'] == 'basic':
+ bond_opts += ",tlb_dynamic_lb=1"
+ if 'balancing_interval' in runner_opts['tx_balancer']:
+ print("# Warn: option runner.tx_balancer.balancing_interval: %d is not supported by bonding" %
+ runner_opts['tx_balancer']['balancing_interval'])
+
+ return bond_opts
+
+# arp_target is used to store multi targets
+# exist_opts is used to check if there are duplicated arp_intervals
+def convert_link_watch(link_watch_opts, arp_target, exist_opts):
+ bond_opts=""
+ if 'name' not in link_watch_opts:
+ print("Error: no link_watch.name in team config file!")
+ sys.exit(1)
+
+ if link_watch_opts['name'] == 'ethtool':
+ bond_opts += ",miimon=100"
+ if 'delay_up' in link_watch_opts:
+ bond_opts += ",updelay=" + str(link_watch_opts['delay_up'])
+ if 'delay_down' in link_watch_opts:
+ bond_opts += ",downdelay=" + str(link_watch_opts['delay_down'])
+ elif link_watch_opts['name'] == 'arp_ping':
+ if 'interval' in link_watch_opts:
+ if exist_opts.find('arp_interval') > 0:
+ print("# Warn: duplicated arp_interval detected, bonding supports only one.")
+ else:
+ bond_opts += ",arp_interval=" + str(link_watch_opts['interval'])
+ if 'target_host' in link_watch_opts:
+ arp_target.append(link_watch_opts['target_host'])
+
+ if 'validate_active' in link_watch_opts and link_watch_opts['validate_active'] and \
+ 'validate_inactive' in link_watch_opts and link_watch_opts['validate_inactive']:
+ if exist_opts.find('arp_validate') > 0:
+ print("# Warn: duplicated arp_validate detected, bonding supports only one.")
+ else:
+ bond_opts += ",arp_validate=all"
+ elif 'validate_active' in link_watch_opts and link_watch_opts['validate_active']:
+ if exist_opts.find('arp_validate') > 0:
+ print("# Warn: duplicated arp_validate detected, bonding supports only one.")
+ else:
+ bond_opts += ",arp_validate=active"
+ elif 'validate_inactive' in link_watch_opts and link_watch_opts['validate_inactive']:
+ if exist_opts.find('arp_validate') > 0:
+ print("# Warn: duplicated arp_validate detected, bonding supports only one.")
+ else:
+ bond_opts += ",arp_validate=backup"
+
+ if 'init_wait' in link_watch_opts:
+ print("# Warn: option link_watch.init_wait: %d is not supported by bonding" % link_watch_opts['init_wait'])
+ if 'missed_max' in link_watch_opts:
+ print("# Warn: option link_watch.missed_max: %d is not supported by bonding" % link_watch_opts['missed_max'])
+ if 'source_host' in link_watch_opts:
+ print("# Warn: option link_watch.source_host: %s is not supported by bonding" % link_watch_opts['source_host'])
+ if 'vlanid' in link_watch_opts:
+ print("# Warn: option link_watch.vlanid: %d is not supported by bonding" % link_watch_opts['vlanid'])
+ if 'send_always' in link_watch_opts:
+ print("# Warn: option link_watch.send_always: %r is not supported by bonding" % link_watch_opts['send_always'])
+ else:
+ print("# Error: Option link_watch.name: %s is not supported by bonding" %
+ link_watch_opts['name'])
+ sys.exit(1)
+
+ return bond_opts
+
+def convert_opts(bond_name, team_opts, exec_cmd):
+ bond_opts = ""
+
+ # Check runner/mode first
+ if 'runner' in team_opts:
+ bond_opts = convert_runner_opts(team_opts['runner'])
+ else:
+ print("Error: No runner in team config file!")
+ sys.exit(1)
+
+ if 'hwaddr' in team_opts:
+ print("# Warn: option hwaddr: %s is not supported by bonding" % team_opts['hwaddr'])
+
+ if 'notify_peers' in team_opts:
+ if 'count' in team_opts['notify_peers']:
+ bond_opts += ",num_grat_arp=" + str(team_opts['notify_peers']['count'])
+ bond_opts += ",num_unsol_na=" + str(team_opts['notify_peers']['count'])
+ if 'interval' in team_opts['notify_peers']:
+ bond_opts += ",peer_notif_delay=" + str(team_opts['notify_peers']['interval'])
+ if 'mcast_rejoin' in team_opts:
+ if 'count' in team_opts['mcast_rejoin']:
+ bond_opts += ",resend_igmp=" + str(team_opts['mcast_rejoin']['count'])
+ if 'interval' in team_opts['mcast_rejoin']:
+ print("# Warn: option mcast_rejoin.interval: %d is not supported by bonding" % team_opts['mcast_rejoin']['count'])
+
+ # The link_watch maybe a dict or list
+ arp_target = list()
+ if 'link_watch' in team_opts:
+ if isinstance(team_opts['link_watch'], list):
+ for link_watch_opts in team_opts['link_watch']:
+ bond_opts += convert_link_watch(link_watch_opts, arp_target, bond_opts)
+ elif isinstance(team_opts['link_watch'], dict):
+ bond_opts += convert_link_watch(team_opts['link_watch'], arp_target, bond_opts)
+ # Check link watch in team ports if we don't have global link_watch
+ elif 'ports' in team_opts:
+ for iface in team_opts['ports']:
+ if 'link_watch' in team_opts['ports'][iface]:
+ bond_opts += convert_link_watch(team_opts['ports'][iface]['link_watch'], arp_target, bond_opts)
+ else:
+ print("Warn: No link_watch in team config file, use miimon=100 by default")
+ bond_opts += ",miimon=100"
+
+ if arp_target:
+ bond_opts += ",arp_ip_target=" + " ".join(arp_target)
+
+ if exec_cmd:
+ subprocess.run(['nmcli', 'con', 'add', 'type', 'bond', 'ifname',
+ bond_name, 'bond.options', bond_opts])
+ else:
+ print('nmcli con add type bond ifname ' + bond_name \
+ + ' bond.options "' + bond_opts + '"')
+
+def setup_ports(bond_name, team_opts, exec_cmd):
+ primary = {'name': "", 'prio': -2**63, 'sticky': False}
+ bond_ports = []
+ prio = 0
+
+ if 'ports' in team_opts:
+ for iface in team_opts['ports']:
+ bond_ports.append(iface)
+ if 'link_watch' in team_opts['ports'][iface] and \
+ 'link_watch' in team_opts:
+ print("# Warn: Option link_watch in interface %s will be ignored as we have global link_watch set!" % iface)
+ if 'queue_id' in team_opts['ports'][iface]:
+ print("# Warn: Option queue_id: %d on interface %s is not supported by NM yet, please see rhbz:1949127" %
+ (team_opts['ports'][iface]['queue_id'], iface))
+ if 'lacp_prio' in team_opts['ports'][iface]:
+ print("# Warn: Option lacp_prio: %d on interface %s is not supported by bonding" %
+ (team_opts['ports'][iface]['lacp_prio'], iface))
+ if 'prio' in team_opts['ports'][iface]:
+ prio = int(team_opts['ports'][iface]['prio'])
+ if prio > primary['prio'] and primary['sticky'] is False:
+ primary['name'] = iface
+ primary['prio'] = prio
+ if 'sticky' in team_opts['ports'][iface] and \
+ team_opts['ports'][iface]['sticky']:
+ primary['name'] = iface
+ primary['sticky'] = True
+
+ for port in bond_ports:
+ ret = subprocess.run(['nmcli', '-g', 'general.type', 'dev', 'show', port],
+ stderr=subprocess.PIPE, stdout=subprocess.PIPE)
+ if ret.returncode != 0:
+ print("# Warn: Get dev %s type failed, will use type ethernet by default" % port)
+ if_type = 'ethernet'
+ elif ret.stdout.find(b'ethernet') != 0:
+ print("# Warn: %s is not a ethernet device, please make sure the type is correct" % port)
+ if_type = str(ret.stdout, 'utf-8').strip()
+ else:
+ if_type = str(ret.stdout, 'utf-8').strip()
+
+ if exec_cmd:
+ subprocess.run(['nmcli', 'con', 'add', 'type', if_type,
+ 'ifname', port, 'master', bond_name])
+ else:
+ print('nmcli con add type %s ifname %s master %s' % (if_type, port, bond_name))
+
+ if primary['name']:
+ if exec_cmd:
+ subprocess.run(['nmcli', 'con', 'mod', 'bond-' + bond_name,
+ '+bond.options', "primary=" + primary['name']])
+ else:
+ print('nmcli con mod bond-' + bond_name \
+ + ' +bond.options "primary=' + primary['name'] + '"')
+
+def main():
+ options = handle_cmd_line()
+ team_opts = dict()
+
+ if options.config:
+ try:
+ with open(options.config, 'r') as f:
+ team_opts = json.load(f)
+ except OSError as e:
+ print(e)
+ sys.exit(1)
+ else:
+ print("Error: Please supply a team config file")
+ sys.exit(1)
+
+ if not team_opts['device']:
+ print("Error: No team device name in team config file")
+ sys.exit(1)
+
+ if not options.exec_cmd:
+ print("### These are the commands to configure a bond interface " +
+ "similar to this team config:")
+
+ if options.rename:
+ bond_name = options.rename
+ else:
+ bond_name = team_opts['device']
+
+ convert_opts(bond_name, team_opts, options.exec_cmd)
+ setup_ports(bond_name, team_opts, options.exec_cmd)
+
+ if not options.exec_cmd:
+ print("### After this, IP addresses, routes and so need to be reconfigured.")
+
+if __name__ == '__main__':
+ main()
--
2.26.3

View File

@ -0,0 +1,67 @@
From f961dbffb5ca769c2a87a6f1e2548e63d2a0a169 Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Mon, 24 May 2021 12:58:02 +0800
Subject: [PATCH 2/2] team2bond: fix min_ports format and add lacp_key
Should set to str when add min_ports to bond config.
Also add missed lacp_key config.
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
utils/team2bond | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/utils/team2bond b/utils/team2bond
index 6ac9d52..265bc79 100755
--- a/utils/team2bond
+++ b/utils/team2bond
@@ -66,7 +66,7 @@ def convert_runner_opts(runner_opts):
if 'sys_prio' in runner_opts:
bond_opts += ",ad_actor_sys_prio=" + str(runner_opts['sys_prio'])
if 'min_ports' in runner_opts:
- bond_opts += ",min_links=" + runner_opts['min_ports']
+ bond_opts += ",min_links=" + str(runner_opts['min_ports'])
if 'agg_select_policy' in runner_opts:
if runner_opts['agg_select_policy'] == 'bandwidth':
bond_opts += ",ad_select=bandwidth"
@@ -214,6 +214,7 @@ def convert_opts(bond_name, team_opts, exec_cmd):
def setup_ports(bond_name, team_opts, exec_cmd):
primary = {'name': "", 'prio': -2**63, 'sticky': False}
bond_ports = []
+ lacp_key = 0
prio = 0
if 'ports' in team_opts:
@@ -228,6 +229,15 @@ def setup_ports(bond_name, team_opts, exec_cmd):
if 'lacp_prio' in team_opts['ports'][iface]:
print("# Warn: Option lacp_prio: %d on interface %s is not supported by bonding" %
(team_opts['ports'][iface]['lacp_prio'], iface))
+ if 'lacp_key' in team_opts['ports'][iface]:
+ if lacp_key == 0:
+ lacp_key = team_opts['ports'][iface]['lacp_key']
+ if lacp_key < 0 or lacp_key > 1023:
+ lacp_key = 0
+ print("# Warn: Option lacp_key: Invalid value %d for port %s" % (lacp_key, iface))
+ else:
+ print("# Warn: Option lacp_key: already has one key %d, ignore the new one %d" %
+ (lacp_key, team_opts['ports'][iface]['lacp_key']))
if 'prio' in team_opts['ports'][iface]:
prio = int(team_opts['ports'][iface]['prio'])
if prio > primary['prio'] and primary['sticky'] is False:
@@ -256,6 +266,13 @@ def setup_ports(bond_name, team_opts, exec_cmd):
else:
print('nmcli con add type %s ifname %s master %s' % (if_type, port, bond_name))
+ if lacp_key != 0:
+ if exec_cmd:
+ subprocess.run(['nmcli', 'con', 'mod', 'bond-' + bond_name,
+ '+bond.options', "ad_user_port_key=" + str(lacp_key)])
+ else:
+ print('nmcli con mod bond-' + bond_name \
+ + ' +bond.options "ad_user_port_key=' + str(lacp_key) + '"')
if primary['name']:
if exec_cmd:
subprocess.run(['nmcli', 'con', 'mod', 'bond-' + bond_name,
--
2.26.3

View File

@ -0,0 +1,79 @@
From ad9cf008dfed4918e3d1e521647e5f44f46bfc91 Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Wed, 21 Jul 2021 14:23:55 +0800
Subject: [PATCH 3/4] utils/team2bond: add cautions for the script
Split the exec-cmd to Dangerous groups and add cautions to let customer
know they need to remove old team device. Also fix a typo.
Add parameter "actual" when dump team config.
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
utils/team2bond | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/utils/team2bond b/utils/team2bond
index 265bc79..118f38b 100755
--- a/utils/team2bond
+++ b/utils/team2bond
@@ -1,7 +1,7 @@
#!/bin/env python3
# vim: sts=4 ts=4 sw=4 expandtab :
-from optparse import OptionParser
+from optparse import OptionParser, OptionGroup
import subprocess
import json
import sys
@@ -11,7 +11,7 @@ def handle_cmd_line():
parser.add_option('--config', dest='config', default = '',
help = "convert the team JSON format configuration file " \
+ "to NetworkManager connection profile, please use " \
- + "'teamdctl TEAM config dump' to dump the config file." \
+ + "'teamdctl TEAM config dump [actual]' to dump the config file." \
+ " Note the script only convert config file. IP " \
+ "address configurations still need to be set manually.")
parser.add_option('--rename', dest='rename', default = '',
@@ -19,11 +19,17 @@ def handle_cmd_line():
+ " Careful: firewall rules, aliases interfaces, etc., " \
+ "will break after the renaming because the tool " \
+ "will only change the config file, nothing else.")
- parser.add_option('--exec-cmd', dest='exec_cmd', action='store_true', default = False,
+
+ group = OptionGroup(parser, 'Dangerous Options',
+ "Caution: You need to dump the team configuration " \
+ "file first and then delete old team device to avoid " \
+ "device name conflicts.")
+ group.add_option('--exec-cmd', dest='exec_cmd', action='store_true', default = False,
help = "exec nmcli and add the connections directly " \
+ "instead of printing the nmcli cmd to screen. " \
- + "This parameter is NOT recommend, it would be good " \
+ + "This parameter is NOT recommended, it would be good " \
+ "to double check the cmd before apply.")
+ parser.add_option_group(group)
(options, args) = parser.parse_args()
@@ -302,7 +308,8 @@ def main():
if not options.exec_cmd:
print("### These are the commands to configure a bond interface " +
- "similar to this team config:")
+ "similar to this team config (remember to remove the old team " +
+ "device before exec the following cmds):")
if options.rename:
bond_name = options.rename
@@ -313,7 +320,7 @@ def main():
setup_ports(bond_name, team_opts, options.exec_cmd)
if not options.exec_cmd:
- print("### After this, IP addresses, routes and so need to be reconfigured.")
+ print("### After this, IP addresses, routes, and so on, need to be configured.")
if __name__ == '__main__':
main()
--
2.31.1

View File

@ -0,0 +1,99 @@
From ff20b5982cf674e8a0a7267645963a79d2e46729 Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Wed, 21 Jul 2021 17:31:59 +0800
Subject: [PATCH 4/4] man: add team2bond man doc
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
man/Makefile.am | 2 +-
man/team2bond.1 | 69 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 70 insertions(+), 1 deletion(-)
create mode 100644 man/team2bond.1
diff --git a/man/Makefile.am b/man/Makefile.am
index 4c63629..52f0fb9 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -1,3 +1,3 @@
dist_man8_MANS = teamd.8 teamdctl.8 teamnl.8
dist_man5_MANS = teamd.conf.5
-dist_man1_MANS = bond2team.1
+dist_man1_MANS = bond2team.1 team2bond.1
diff --git a/man/team2bond.1 b/man/team2bond.1
new file mode 100644
index 0000000..f47aba4
--- /dev/null
+++ b/man/team2bond.1
@@ -0,0 +1,69 @@
+.TH TEAM2BOND 1 "2021-07-20" "libteam" "Team to Bonding conversion tool"
+.SH NAME
+team2bond \(em Converts a team configuration to a NetworkManager bond configuration
+.SH SYNOPSIS
+.B team2bond
+.RB [options]
+.SH DESCRIPTION
+.PP
+team2bond is a tool to convert team options to bonding options. During the conversion, team2bond tries to create a bond configuration that has the same or similar functionality as the team.
+.PP
+This tool converts a team JSON format configuration file to NetworkManager nmcli commands that you can use to set up a network bonding device. After verifying the commands and deleting the corresponding team device, run the nmcli commands manually or with parameter
+.B \-\-exec
+to create the NetworkManager connection profile.
+.PP
+.B Important:
+Note that deleting the team device makes this connection unavailable until you recreated the bond.
+.SH OPTIONS
+.TP
+.B "\-\-config <team json config file>"
+Specifies the team JSON format configuration file to convert. Use the 'teamdctl <TEAMNAME> config dump [actual]' command to create the JSON file.
+.TP
+.B "\-\-rename <interface>"
+This is a convenient option to replace the original interface name with the specified name. For example, use \-\-rename bond0 to change the interface name to bond0. Note, firewall rules, alias interfaces, and so on, that are tied to the original interface name can break after the renaming an interface because the tool only changes the NetworkManager profile.
+.TP
+.B "\-\-help"
+Print a help text to console and exit.
+.SH DANGEROUS OPTION
+.TP
+.B "\-\-exec"
+Executes the generated nmcli commands and adds the connections directly instead of printing then to the screen. This parameter is NOT recommended. Double-check the generated commands before you apply them.
+.SH EXAMPLE STEPS
+.TP
+1. Save the current 'team0' ip addresses, firewall rules, alias, etc.
+.TP
+2. Dump the current 'team0' configuration to a JSON file. Using the 'actual' option, team2bond dumps the actual config instead of the initial config:
+.TP
+.RS 1
+# teamdctl team0 config dump actual > team0.json
+.RE
+.TP
+3. Run the team2bond utility in dry-run mode to display nmcli commands that set up a network bond with similar settings as the team device:
+.TP
+.RS 1
+# team2bond \%--config team0.json
+.RE
+.TP
+To convert the current 'team0' configuration to bonding connection profile and rename the interface name to 'bond0':
+.TP
+.RS 1
+# team2bond \%--config team0.json \%--rename bond0
+.RE
+.TP
+4. Examine these generated nmcli commands, and make sure all parameters are correct.
+.TP
+5. Delete the team0 device by using the teamd or nmcli utility to avoid a device conflict. Then execute the commands the team2bond utility displayed in the previous step manually or use the \-\-exec option:
+.TP
+.RS 1
+# team2bond \%--config team0.json \%--rename bond0 \%--exec
+.RE
+.SH CAVEATS
+.PP
+The tool will not convert any other configuration which might be tied to the current setup. For instance, IP addresses, firewall rules, alias interfaces, bridges, and so on.
+.SH AUTHOR
+.PP
+Hangbin Liu <haliu@redhat.com>
+.SH SEE ALSO
+.BR nmcli (1),
+.BR teamdctl (8),
+.BR teamd.conf (5).
--
2.31.1

View File

@ -1,5 +1,4 @@
From 61efd6de2fbb8ee077863ee5a355ac3dfd9365b9 Mon Sep 17 00:00:00 2001
Message-Id: <61efd6de2fbb8ee077863ee5a355ac3dfd9365b9.1599144624.git.lucien.xin@gmail.com>
From: Xin Long <lucien.xin@gmail.com>
Date: Tue, 1 Sep 2020 13:59:27 +0800
Subject: [PATCH] Revert "teamd: Disregard current state when considering port
@ -51,5 +50,5 @@ index 166da57..d429753 100644
else
return 0;
--
2.18.1
2.27.0

View File

@ -0,0 +1,27 @@
From 5616af4387302e9e6ec07dd5466f4a0e93c50a59 Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Mon, 7 Mar 2022 14:39:25 +0800
Subject: [PATCH 6/6] utils/team2bond: do not add miimon if already exist
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
utils/team2bond | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/utils/team2bond b/utils/team2bond
index 118f38b..b5555c1 100755
--- a/utils/team2bond
+++ b/utils/team2bond
@@ -117,7 +117,8 @@ def convert_link_watch(link_watch_opts, arp_target, exist_opts):
sys.exit(1)
if link_watch_opts['name'] == 'ethtool':
- bond_opts += ",miimon=100"
+ if exist_opts.find("miimon") == -1:
+ bond_opts += ",miimon=100"
if 'delay_up' in link_watch_opts:
bond_opts += ",updelay=" + str(link_watch_opts['delay_up'])
if 'delay_down' in link_watch_opts:
--
2.31.1

View File

@ -0,0 +1,79 @@
From de84fb3debdf55080bafbf015d76989c17276d01 Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Mon, 16 May 2022 15:40:35 +0800
Subject: [PATCH 7/1] utils/team2bond: do not add updelay/downdelay if already exist
Also check if miimon/arp_interval already set.
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
utils/team2bond | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/utils/team2bond b/utils/team2bond
index b5555c1..111b83b 100755
--- a/utils/team2bond
+++ b/utils/team2bond
@@ -117,34 +117,52 @@ def convert_link_watch(link_watch_opts, arp_target, exist_opts):
sys.exit(1)
if link_watch_opts['name'] == 'ethtool':
- if exist_opts.find("miimon") == -1:
+ if exist_opts.find("arp_interval") >= 0:
+ print("# Warn: detecte miimon(ethtool) setting, but arp_interval(arp_ping) already set, will ignore.")
+ return bond_opts
+
+ if exist_opts.find("miimon") >= 0:
+ print("# Warn: duplicated miimon detected, bonding supports only one.")
+ else:
bond_opts += ",miimon=100"
+
if 'delay_up' in link_watch_opts:
- bond_opts += ",updelay=" + str(link_watch_opts['delay_up'])
+ if exist_opts.find('updelay') >= 0:
+ print("# Warn: duplicated updelay detected, bonding supports only one.")
+ else:
+ bond_opts += ",updelay=" + str(link_watch_opts['delay_up'])
if 'delay_down' in link_watch_opts:
- bond_opts += ",downdelay=" + str(link_watch_opts['delay_down'])
+ if exist_opts.find('downdelay') >= 0:
+ print("# Warn: duplicated downdelay detected, bonding supports only one.")
+ else:
+ bond_opts += ",downdelay=" + str(link_watch_opts['delay_down'])
elif link_watch_opts['name'] == 'arp_ping':
+ if exist_opts.find("miimon") >= 0:
+ print("# Warn: detecte arp_interval(arp_ping) setting, but miimon(ethtool) already set, will ignore.")
+ return bond_opts
+
if 'interval' in link_watch_opts:
- if exist_opts.find('arp_interval') > 0:
+ if exist_opts.find('arp_interval') >= 0:
print("# Warn: duplicated arp_interval detected, bonding supports only one.")
else:
bond_opts += ",arp_interval=" + str(link_watch_opts['interval'])
+
if 'target_host' in link_watch_opts:
arp_target.append(link_watch_opts['target_host'])
if 'validate_active' in link_watch_opts and link_watch_opts['validate_active'] and \
'validate_inactive' in link_watch_opts and link_watch_opts['validate_inactive']:
- if exist_opts.find('arp_validate') > 0:
+ if exist_opts.find('arp_validate') >= 0:
print("# Warn: duplicated arp_validate detected, bonding supports only one.")
else:
bond_opts += ",arp_validate=all"
elif 'validate_active' in link_watch_opts and link_watch_opts['validate_active']:
- if exist_opts.find('arp_validate') > 0:
+ if exist_opts.find('arp_validate') >= 0:
print("# Warn: duplicated arp_validate detected, bonding supports only one.")
else:
bond_opts += ",arp_validate=active"
elif 'validate_inactive' in link_watch_opts and link_watch_opts['validate_inactive']:
- if exist_opts.find('arp_validate') > 0:
+ if exist_opts.find('arp_validate') >= 0:
print("# Warn: duplicated arp_validate detected, bonding supports only one.")
else:
bond_opts += ",arp_validate=backup"
--
2.35.1

View File

@ -0,0 +1,29 @@
From 8e6b8db540299209f28505e7578a6d0ffeba4c38 Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Fri, 24 Mar 2023 10:51:25 +0800
Subject: [PATCH 10/15] utils/team2bond: add lacp_active support
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
utils/team2bond | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/utils/team2bond b/utils/team2bond
index 111b83b..7fc4a48 100755
--- a/utils/team2bond
+++ b/utils/team2bond
@@ -63,7 +63,10 @@ def convert_runner_opts(runner_opts):
elif runner_opts['name'] == 'lacp':
bond_opts = "mode=802.3ad"
if 'active' in runner_opts:
- print("# Warn: option runner.active: %r is not supported by bonding" % runner_opts['active'])
+ if runner_opts['active']:
+ bond_opts += ",lacp_active=1"
+ else:
+ bond_opts += ",lacp_active=0"
if 'fast_rate' in runner_opts:
if runner_opts['fast_rate']:
bond_opts += ",lacp_rate=1"
--
2.38.1

View File

@ -0,0 +1,39 @@
From 6bf7990d35900c033df03cd76c25b7986deb833f Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Fri, 24 Mar 2023 10:59:21 +0800
Subject: [PATCH 11/15] utils/team2bond: support missed_max
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
utils/team2bond | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/utils/team2bond b/utils/team2bond
index 7fc4a48..e6e4f0d 100755
--- a/utils/team2bond
+++ b/utils/team2bond
@@ -153,6 +153,12 @@ def convert_link_watch(link_watch_opts, arp_target, exist_opts):
if 'target_host' in link_watch_opts:
arp_target.append(link_watch_opts['target_host'])
+ if 'missed_max' in link_watch_opts:
+ if exist_opts.find('arp_missed_max') >= 0:
+ print("# Warn: duplicated arp_missed_max detected, bonding supports only one.")
+ else:
+ bond_opts += ",arp_missed_max=" + str(link_watch_opts['missed_max'])
+
if 'validate_active' in link_watch_opts and link_watch_opts['validate_active'] and \
'validate_inactive' in link_watch_opts and link_watch_opts['validate_inactive']:
if exist_opts.find('arp_validate') >= 0:
@@ -172,8 +178,6 @@ def convert_link_watch(link_watch_opts, arp_target, exist_opts):
if 'init_wait' in link_watch_opts:
print("# Warn: option link_watch.init_wait: %d is not supported by bonding" % link_watch_opts['init_wait'])
- if 'missed_max' in link_watch_opts:
- print("# Warn: option link_watch.missed_max: %d is not supported by bonding" % link_watch_opts['missed_max'])
if 'source_host' in link_watch_opts:
print("# Warn: option link_watch.source_host: %s is not supported by bonding" % link_watch_opts['source_host'])
if 'vlanid' in link_watch_opts:
--
2.38.1

View File

@ -0,0 +1,54 @@
From 54255e65e8734635374ee62eb3a8b118f79b568b Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Fri, 24 Mar 2023 11:18:43 +0800
Subject: [PATCH 12/15] utils/team2bond: support link watch in ports
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
utils/team2bond | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/utils/team2bond b/utils/team2bond
index e6e4f0d..ef4210d 100755
--- a/utils/team2bond
+++ b/utils/team2bond
@@ -224,18 +224,20 @@ def convert_opts(bond_name, team_opts, exec_cmd):
bond_opts += convert_link_watch(link_watch_opts, arp_target, bond_opts)
elif isinstance(team_opts['link_watch'], dict):
bond_opts += convert_link_watch(team_opts['link_watch'], arp_target, bond_opts)
- # Check link watch in team ports if we don't have global link_watch
- elif 'ports' in team_opts:
+ # Check link watch in team ports, we asume it's a dict only?
+ if 'ports' in team_opts:
for iface in team_opts['ports']:
- if 'link_watch' in team_opts['ports'][iface]:
+ if ('link_watch' in team_opts['ports'][iface] and
+ isinstance(team_opts['ports'][iface]['link_watch'], dict)):
bond_opts += convert_link_watch(team_opts['ports'][iface]['link_watch'], arp_target, bond_opts)
- else:
- print("Warn: No link_watch in team config file, use miimon=100 by default")
- bond_opts += ",miimon=100"
if arp_target:
bond_opts += ",arp_ip_target=" + " ".join(arp_target)
+ if bond_opts.find("miimon") == -1 and bond_opts.find("_target") == -1:
+ print("Warn: No link_watch in team config file, use miimon=100 by default")
+ bond_opts += ",miimon=100"
+
if exec_cmd:
subprocess.run(['nmcli', 'con', 'add', 'type', 'bond', 'ifname',
bond_name, 'bond.options', bond_opts])
@@ -252,9 +254,6 @@ def setup_ports(bond_name, team_opts, exec_cmd):
if 'ports' in team_opts:
for iface in team_opts['ports']:
bond_ports.append(iface)
- if 'link_watch' in team_opts['ports'][iface] and \
- 'link_watch' in team_opts:
- print("# Warn: Option link_watch in interface %s will be ignored as we have global link_watch set!" % iface)
if 'queue_id' in team_opts['ports'][iface]:
print("# Warn: Option queue_id: %d on interface %s is not supported by NM yet, please see rhbz:1949127" %
(team_opts['ports'][iface]['queue_id'], iface))
--
2.38.1

View File

@ -0,0 +1,98 @@
From 519f8529ac0bc5b19199ec8a2e83a06e88c078b0 Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Fri, 24 Mar 2023 11:33:17 +0800
Subject: [PATCH 13/15] utils/team2bond: add ns_ip6_target support
Rename variable arp_target to target_hosts as we will store both IPv4
and IPv6 address.
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
utils/team2bond | 38 ++++++++++++++++++++++++--------------
1 file changed, 24 insertions(+), 14 deletions(-)
diff --git a/utils/team2bond b/utils/team2bond
index ef4210d..f337906 100755
--- a/utils/team2bond
+++ b/utils/team2bond
@@ -111,9 +111,9 @@ def convert_runner_opts(runner_opts):
return bond_opts
-# arp_target is used to store multi targets
-# exist_opts is used to check if there are duplicated arp_intervals
-def convert_link_watch(link_watch_opts, arp_target, exist_opts):
+# target_hosts is used to store multi targets
+# exist_opts is used to check if there are duplicated options
+def convert_link_watch(link_watch_opts, target_hosts, exist_opts):
bond_opts=""
if 'name' not in link_watch_opts:
print("Error: no link_watch.name in team config file!")
@@ -139,20 +139,20 @@ def convert_link_watch(link_watch_opts, arp_target, exist_opts):
print("# Warn: duplicated downdelay detected, bonding supports only one.")
else:
bond_opts += ",downdelay=" + str(link_watch_opts['delay_down'])
- elif link_watch_opts['name'] == 'arp_ping':
+ elif link_watch_opts['name'] == 'arp_ping' or link_watch_opts['name'] == 'nsna_ping':
if exist_opts.find("miimon") >= 0:
print("# Warn: detecte arp_interval(arp_ping) setting, but miimon(ethtool) already set, will ignore.")
return bond_opts
+ if 'target_host' in link_watch_opts and link_watch_opts['target_host'] not in target_hosts:
+ target_hosts.append(link_watch_opts['target_host'])
+
if 'interval' in link_watch_opts:
if exist_opts.find('arp_interval') >= 0:
print("# Warn: duplicated arp_interval detected, bonding supports only one.")
else:
bond_opts += ",arp_interval=" + str(link_watch_opts['interval'])
- if 'target_host' in link_watch_opts:
- arp_target.append(link_watch_opts['target_host'])
-
if 'missed_max' in link_watch_opts:
if exist_opts.find('arp_missed_max') >= 0:
print("# Warn: duplicated arp_missed_max detected, bonding supports only one.")
@@ -217,22 +217,32 @@ def convert_opts(bond_name, team_opts, exec_cmd):
print("# Warn: option mcast_rejoin.interval: %d is not supported by bonding" % team_opts['mcast_rejoin']['count'])
# The link_watch maybe a dict or list
- arp_target = list()
+ target_hosts = list()
if 'link_watch' in team_opts:
if isinstance(team_opts['link_watch'], list):
for link_watch_opts in team_opts['link_watch']:
- bond_opts += convert_link_watch(link_watch_opts, arp_target, bond_opts)
+ bond_opts += convert_link_watch(link_watch_opts, target_hosts, bond_opts)
elif isinstance(team_opts['link_watch'], dict):
- bond_opts += convert_link_watch(team_opts['link_watch'], arp_target, bond_opts)
+ bond_opts += convert_link_watch(team_opts['link_watch'], target_hosts, bond_opts)
# Check link watch in team ports, we asume it's a dict only?
if 'ports' in team_opts:
for iface in team_opts['ports']:
if ('link_watch' in team_opts['ports'][iface] and
isinstance(team_opts['ports'][iface]['link_watch'], dict)):
- bond_opts += convert_link_watch(team_opts['ports'][iface]['link_watch'], arp_target, bond_opts)
-
- if arp_target:
- bond_opts += ",arp_ip_target=" + " ".join(arp_target)
+ bond_opts += convert_link_watch(team_opts['ports'][iface]['link_watch'], target_hosts, bond_opts)
+
+ if target_hosts:
+ arp_targets = list()
+ ns_targets = list()
+ for target in target_hosts:
+ if target.find(':') == -1:
+ arp_targets.append(target)
+ else:
+ ns_targets.append(target)
+ if arp_targets:
+ bond_opts += ",arp_ip_target=" + " ".join(arp_targets)
+ if ns_targets:
+ bond_opts += ",ns_ip6_target=" + " ".join(ns_targets)
if bond_opts.find("miimon") == -1 and bond_opts.find("_target") == -1:
print("Warn: No link_watch in team config file, use miimon=100 by default")
--
2.38.1

View File

@ -0,0 +1,81 @@
From dea184d3aa8a6038977494ddd4ae6c540317fb72 Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Fri, 24 Mar 2023 14:00:11 +0800
Subject: [PATCH 14/15] utils/team2bond: Add queue_id support
Adding bond ports in the option check logic. There is no need to do it in
another loop, then we can remove the bond_ports variable.
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
utils/team2bond | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/utils/team2bond b/utils/team2bond
index f337906..2f5d868 100755
--- a/utils/team2bond
+++ b/utils/team2bond
@@ -263,10 +263,11 @@ def setup_ports(bond_name, team_opts, exec_cmd):
if 'ports' in team_opts:
for iface in team_opts['ports']:
- bond_ports.append(iface)
+ port_options = ["ifname", iface, "master", bond_name]
+
if 'queue_id' in team_opts['ports'][iface]:
- print("# Warn: Option queue_id: %d on interface %s is not supported by NM yet, please see rhbz:1949127" %
- (team_opts['ports'][iface]['queue_id'], iface))
+ port_options.append("bond-port.queue-id")
+ port_options.append(str(team_opts['ports'][iface]['queue_id']))
if 'lacp_prio' in team_opts['ports'][iface]:
print("# Warn: Option lacp_prio: %d on interface %s is not supported by bonding" %
(team_opts['ports'][iface]['lacp_prio'], iface))
@@ -289,23 +290,21 @@ def setup_ports(bond_name, team_opts, exec_cmd):
primary['name'] = iface
primary['sticky'] = True
- for port in bond_ports:
- ret = subprocess.run(['nmcli', '-g', 'general.type', 'dev', 'show', port],
- stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- if ret.returncode != 0:
- print("# Warn: Get dev %s type failed, will use type ethernet by default" % port)
- if_type = 'ethernet'
- elif ret.stdout.find(b'ethernet') != 0:
- print("# Warn: %s is not a ethernet device, please make sure the type is correct" % port)
- if_type = str(ret.stdout, 'utf-8').strip()
- else:
- if_type = str(ret.stdout, 'utf-8').strip()
+ ret = subprocess.run(['nmcli', '-g', 'general.type', 'dev', 'show', iface],
+ stderr=subprocess.PIPE, stdout=subprocess.PIPE)
+ if ret.returncode != 0:
+ print("# Warn: Get dev %s type failed, will use type ethernet by default" % iface)
+ if_type = 'ethernet'
+ elif ret.stdout.find(b'ethernet') != 0:
+ print("# Warn: %s is not a ethernet device, please make sure the type is correct" % iface)
+ if_type = str(ret.stdout, 'utf-8').strip()
+ else:
+ if_type = str(ret.stdout, 'utf-8').strip()
- if exec_cmd:
- subprocess.run(['nmcli', 'con', 'add', 'type', if_type,
- 'ifname', port, 'master', bond_name])
- else:
- print('nmcli con add type %s ifname %s master %s' % (if_type, port, bond_name))
+ if exec_cmd:
+ subprocess.run(['nmcli', 'con', 'add', 'type', if_type] + port_options)
+ else:
+ print('nmcli con add type %s %s' % (if_type, " ".join(port_options)))
if lacp_key != 0:
if exec_cmd:
@@ -314,6 +313,7 @@ def setup_ports(bond_name, team_opts, exec_cmd):
else:
print('nmcli con mod bond-' + bond_name \
+ ' +bond.options "ad_user_port_key=' + str(lacp_key) + '"')
+
if primary['name']:
if exec_cmd:
subprocess.run(['nmcli', 'con', 'mod', 'bond-' + bond_name,
--
2.38.1

View File

@ -0,0 +1,278 @@
From 8b682b86dfd4ac142724151f4489063dbecc5bda Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Fri, 24 Mar 2023 15:57:36 +0800
Subject: [PATCH 15/15] utils/team2bond: update python code format
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
utils/team2bond | 114 ++++++++++++++++++++++++++----------------------
1 file changed, 62 insertions(+), 52 deletions(-)
diff --git a/utils/team2bond b/utils/team2bond
index 2f5d868..2032c1d 100755
--- a/utils/team2bond
+++ b/utils/team2bond
@@ -6,40 +6,42 @@ import subprocess
import json
import sys
+
def handle_cmd_line():
parser = OptionParser()
- parser.add_option('--config', dest='config', default = '',
- help = "convert the team JSON format configuration file " \
- + "to NetworkManager connection profile, please use " \
- + "'teamdctl TEAM config dump [actual]' to dump the config file." \
- + " Note the script only convert config file. IP " \
+ parser.add_option('--config', dest='config', default='',
+ help="convert the team JSON format configuration file "
+ + "to NetworkManager connection profile, please use "
+ + "'teamdctl TEAM config dump [actual]' to dump the config file."
+ + " Note the script only convert config file. IP "
+ "address configurations still need to be set manually.")
- parser.add_option('--rename', dest='rename', default = '',
- help = "rename the default team interface name." \
- + " Careful: firewall rules, aliases interfaces, etc., " \
- + "will break after the renaming because the tool " \
+ parser.add_option('--rename', dest='rename', default='',
+ help="rename the default team interface name."
+ + " Careful: firewall rules, aliases interfaces, etc., "
+ + "will break after the renaming because the tool "
+ "will only change the config file, nothing else.")
group = OptionGroup(parser, 'Dangerous Options',
- "Caution: You need to dump the team configuration " \
- "file first and then delete old team device to avoid " \
+ "Caution: You need to dump the team configuration "
+ "file first and then delete old team device to avoid "
"device name conflicts.")
- group.add_option('--exec-cmd', dest='exec_cmd', action='store_true', default = False,
- help = "exec nmcli and add the connections directly " \
- + "instead of printing the nmcli cmd to screen. " \
- + "This parameter is NOT recommended, it would be good " \
- + "to double check the cmd before apply.")
+ group.add_option('--exec-cmd', dest='exec_cmd', action='store_true', default=False,
+ help="exec nmcli and add the connections directly "
+ + "instead of printing the nmcli cmd to screen. "
+ + "This parameter is NOT recommended, it would be good "
+ + "to double check the cmd before apply.")
parser.add_option_group(group)
(options, args) = parser.parse_args()
if subprocess.run(['nmcli', '-v'], stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL).returncode != 0:
- print("Warn: NetworkManager is needed for this script!");
+ print("Warn: NetworkManager is needed for this script!")
sys.exit(1)
return options
+
def convert_runner_opts(runner_opts):
bond_opts = ""
@@ -50,14 +52,14 @@ def convert_runner_opts(runner_opts):
elif runner_opts['name'] == 'activebackup':
bond_opts = "mode=active-backup"
if 'hwaddr_policy' in runner_opts:
- if runner_opts['hwaddr_policy'] == 'same_all':
- bond_opts += ",fail_over_mac=none"
- elif runner_opts['hwaddr_policy'] == 'by_active':
- bond_opts += ",fail_over_mac=active"
- elif runner_opts['hwaddr_policy'] == 'only_active':
- bond_opts += ",fail_over_mac=follow"
- else:
- print("# Warn: invalid runner.hwaddr_policy: " + runner_opts['hwaddr_policy'])
+ if runner_opts['hwaddr_policy'] == 'same_all':
+ bond_opts += ",fail_over_mac=none"
+ elif runner_opts['hwaddr_policy'] == 'by_active':
+ bond_opts += ",fail_over_mac=active"
+ elif runner_opts['hwaddr_policy'] == 'only_active':
+ bond_opts += ",fail_over_mac=follow"
+ else:
+ print("# Warn: invalid runner.hwaddr_policy: " + runner_opts['hwaddr_policy'])
elif runner_opts['name'] == 'loadbalance':
bond_opts = "mode=balance-tlb"
elif runner_opts['name'] == 'lacp':
@@ -73,7 +75,7 @@ def convert_runner_opts(runner_opts):
else:
bond_opts += ",lacp_rate=0"
if 'sys_prio' in runner_opts:
- bond_opts += ",ad_actor_sys_prio=" + str(runner_opts['sys_prio'])
+ bond_opts += ",ad_actor_sys_prio=" + str(runner_opts['sys_prio'])
if 'min_ports' in runner_opts:
bond_opts += ",min_links=" + str(runner_opts['min_ports'])
if 'agg_select_policy' in runner_opts:
@@ -83,7 +85,7 @@ def convert_runner_opts(runner_opts):
bond_opts += ",ad_select=count"
else:
print("# Warn: Option runner.agg_select_policy: %s is not supported by bonding" %
- runner_opts['agg_select_policy'])
+ runner_opts['agg_select_policy'])
sys.exit(1)
else:
print("Error: Unsupported runner.name: %s for bonding" % runner_opts['name'])
@@ -92,14 +94,14 @@ def convert_runner_opts(runner_opts):
if 'tx_hash' in runner_opts:
print("# Warn: tx_hash ipv4, ipv6, tcp, udp, sctp are not supported by bonding")
if 'vlan' in runner_opts['tx_hash']:
- bond_opts +=",xmit_hash_policy=vlan+srcmac"
+ bond_opts += ",xmit_hash_policy=vlan+srcmac"
if 'eth' in runner_opts['tx_hash']:
- bond_opts +=",xmit_hash_policy=layer2"
+ bond_opts += ",xmit_hash_policy=layer2"
if 'l3' in runner_opts['tx_hash'] or 'ip' in runner_opts['tx_hash']:
- bond_opts +="+3"
- elif ('l3' in runner_opts['tx_hash'] or 'ip' in runner_opts['tx_hash']) \
- and 'l4' in runner_opts['tx_hash']:
- bond_opts +=",xmit_hash_policy=layer3+4"
+ bond_opts += "+3"
+ elif (('l3' in runner_opts['tx_hash'] or 'ip' in runner_opts['tx_hash'])
+ and 'l4' in runner_opts['tx_hash']):
+ bond_opts += ",xmit_hash_policy=layer3+4"
if 'tx_balancer' in runner_opts:
if 'name' in runner_opts['tx_balancer']:
@@ -107,14 +109,15 @@ def convert_runner_opts(runner_opts):
bond_opts += ",tlb_dynamic_lb=1"
if 'balancing_interval' in runner_opts['tx_balancer']:
print("# Warn: option runner.tx_balancer.balancing_interval: %d is not supported by bonding" %
- runner_opts['tx_balancer']['balancing_interval'])
+ runner_opts['tx_balancer']['balancing_interval'])
return bond_opts
+
# target_hosts is used to store multi targets
# exist_opts is used to check if there are duplicated options
def convert_link_watch(link_watch_opts, target_hosts, exist_opts):
- bond_opts=""
+ bond_opts = ""
if 'name' not in link_watch_opts:
print("Error: no link_watch.name in team config file!")
sys.exit(1)
@@ -159,8 +162,8 @@ def convert_link_watch(link_watch_opts, target_hosts, exist_opts):
else:
bond_opts += ",arp_missed_max=" + str(link_watch_opts['missed_max'])
- if 'validate_active' in link_watch_opts and link_watch_opts['validate_active'] and \
- 'validate_inactive' in link_watch_opts and link_watch_opts['validate_inactive']:
+ if ('validate_active' in link_watch_opts and link_watch_opts['validate_active'] and
+ 'validate_inactive' in link_watch_opts and link_watch_opts['validate_inactive']):
if exist_opts.find('arp_validate') >= 0:
print("# Warn: duplicated arp_validate detected, bonding supports only one.")
else:
@@ -177,20 +180,25 @@ def convert_link_watch(link_watch_opts, target_hosts, exist_opts):
bond_opts += ",arp_validate=backup"
if 'init_wait' in link_watch_opts:
- print("# Warn: option link_watch.init_wait: %d is not supported by bonding" % link_watch_opts['init_wait'])
+ print("# Warn: option link_watch.init_wait: %d is not supported by bonding" %
+ link_watch_opts['init_wait'])
if 'source_host' in link_watch_opts:
- print("# Warn: option link_watch.source_host: %s is not supported by bonding" % link_watch_opts['source_host'])
+ print("# Warn: option link_watch.source_host: %s is not supported by bonding" %
+ link_watch_opts['source_host'])
if 'vlanid' in link_watch_opts:
- print("# Warn: option link_watch.vlanid: %d is not supported by bonding" % link_watch_opts['vlanid'])
+ print("# Warn: option link_watch.vlanid: %d is not supported by bonding" %
+ link_watch_opts['vlanid'])
if 'send_always' in link_watch_opts:
- print("# Warn: option link_watch.send_always: %r is not supported by bonding" % link_watch_opts['send_always'])
+ print("# Warn: option link_watch.send_always: %r is not supported by bonding" %
+ link_watch_opts['send_always'])
else:
print("# Error: Option link_watch.name: %s is not supported by bonding" %
- link_watch_opts['name'])
+ link_watch_opts['name'])
sys.exit(1)
return bond_opts
+
def convert_opts(bond_name, team_opts, exec_cmd):
bond_opts = ""
@@ -214,7 +222,8 @@ def convert_opts(bond_name, team_opts, exec_cmd):
if 'count' in team_opts['mcast_rejoin']:
bond_opts += ",resend_igmp=" + str(team_opts['mcast_rejoin']['count'])
if 'interval' in team_opts['mcast_rejoin']:
- print("# Warn: option mcast_rejoin.interval: %d is not supported by bonding" % team_opts['mcast_rejoin']['count'])
+ print("# Warn: option mcast_rejoin.interval: %d is not supported by bonding" %
+ team_opts['mcast_rejoin']['count'])
# The link_watch maybe a dict or list
target_hosts = list()
@@ -252,12 +261,12 @@ def convert_opts(bond_name, team_opts, exec_cmd):
subprocess.run(['nmcli', 'con', 'add', 'type', 'bond', 'ifname',
bond_name, 'bond.options', bond_opts])
else:
- print('nmcli con add type bond ifname ' + bond_name \
+ print('nmcli con add type bond ifname ' + bond_name
+ ' bond.options "' + bond_opts + '"')
+
def setup_ports(bond_name, team_opts, exec_cmd):
primary = {'name': "", 'prio': -2**63, 'sticky': False}
- bond_ports = []
lacp_key = 0
prio = 0
@@ -270,7 +279,7 @@ def setup_ports(bond_name, team_opts, exec_cmd):
port_options.append(str(team_opts['ports'][iface]['queue_id']))
if 'lacp_prio' in team_opts['ports'][iface]:
print("# Warn: Option lacp_prio: %d on interface %s is not supported by bonding" %
- (team_opts['ports'][iface]['lacp_prio'], iface))
+ (team_opts['ports'][iface]['lacp_prio'], iface))
if 'lacp_key' in team_opts['ports'][iface]:
if lacp_key == 0:
lacp_key = team_opts['ports'][iface]['lacp_key']
@@ -279,14 +288,14 @@ def setup_ports(bond_name, team_opts, exec_cmd):
print("# Warn: Option lacp_key: Invalid value %d for port %s" % (lacp_key, iface))
else:
print("# Warn: Option lacp_key: already has one key %d, ignore the new one %d" %
- (lacp_key, team_opts['ports'][iface]['lacp_key']))
+ (lacp_key, team_opts['ports'][iface]['lacp_key']))
if 'prio' in team_opts['ports'][iface]:
prio = int(team_opts['ports'][iface]['prio'])
if prio > primary['prio'] and primary['sticky'] is False:
primary['name'] = iface
primary['prio'] = prio
- if 'sticky' in team_opts['ports'][iface] and \
- team_opts['ports'][iface]['sticky']:
+ if ('sticky' in team_opts['ports'][iface] and
+ team_opts['ports'][iface]['sticky']):
primary['name'] = iface
primary['sticky'] = True
@@ -311,7 +320,7 @@ def setup_ports(bond_name, team_opts, exec_cmd):
subprocess.run(['nmcli', 'con', 'mod', 'bond-' + bond_name,
'+bond.options', "ad_user_port_key=" + str(lacp_key)])
else:
- print('nmcli con mod bond-' + bond_name \
+ print('nmcli con mod bond-' + bond_name
+ ' +bond.options "ad_user_port_key=' + str(lacp_key) + '"')
if primary['name']:
@@ -319,9 +328,10 @@ def setup_ports(bond_name, team_opts, exec_cmd):
subprocess.run(['nmcli', 'con', 'mod', 'bond-' + bond_name,
'+bond.options', "primary=" + primary['name']])
else:
- print('nmcli con mod bond-' + bond_name \
+ print('nmcli con mod bond-' + bond_name
+ ' +bond.options "primary=' + primary['name'] + '"')
+
def main():
options = handle_cmd_line()
team_opts = dict()
@@ -358,4 +368,4 @@ def main():
print("### After this, IP addresses, routes, and so on, need to be configured.")
if __name__ == '__main__':
- main()
+ main()
--
2.38.1

View File

@ -1,61 +0,0 @@
From 3bbce8a171deab6cd3d7d57d128bc2dbaea451f0 Mon Sep 17 00:00:00 2001
Message-Id: <3bbce8a171deab6cd3d7d57d128bc2dbaea451f0.1664556124.git.lucien.xin@gmail.com>
From: Xin Long <lucien.xin@gmail.com>
Date: Fri, 15 Apr 2022 11:41:39 -0400
Subject: [PATCH] libteamdctl: validate the bus name before using it
Using bus name without validating it will cause core dump generated,
and it can be reproduced by:
# ip link add dummy0.1 type dummy
# teamdctl dummy0.1 state dump
This is normally a bug in some application using the D-Bus library.
D-Bus not built with -rdynamic so unable to print a backtrace
Aborted (core dumped)
Doing this many times can even create too many core files, customers
may complain about it.
This is triggered when calling cli_method_call("ConfigDump") in
cli_init(), so fix it by returning err in cli->init/cli_dbus_init()
if the bus name fails to validate.
Note this is safe, as with dbus, we can't use invalid dbus name to
create the team dev either.
Fixes: d8163e34c25c ("libteamdctl: do test method call instead or Introspect call")
Reported-by: Uday Patel <upatel@redhat.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
libteamdctl/cli_dbus.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/libteamdctl/cli_dbus.c b/libteamdctl/cli_dbus.c
index dfef5c4..242ef86 100644
--- a/libteamdctl/cli_dbus.c
+++ b/libteamdctl/cli_dbus.c
@@ -183,12 +183,17 @@ static int cli_dbus_init(struct teamdctl *tdc, const char *team_name, void *priv
if (ret == -1)
return -errno;
+ err = -EINVAL;
dbus_error_init(&error);
+ if (!dbus_validate_bus_name(cli_dbus->service_name, &error)) {
+ err(tdc, "dbus: Could not validate bus name: %s - %s",
+ error.name, error.message);
+ goto free_service_name;
+ }
cli_dbus->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
if (!cli_dbus->conn) {
err(tdc, "dbus: Could not acquire the system bus: %s - %s",
error.name, error.message);
- err = -EINVAL;
goto free_service_name;
}
err = 0;
--
2.27.0

6
gating.yaml Normal file
View File

@ -0,0 +1,6 @@
--- !Policy
product_versions:
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}

View File

@ -1,24 +1,39 @@
Name: libteam
Version: 1.31
Release: 4%{?dist}
Release: 17%{?dist}
Summary: Library for controlling team network device
Group: System Environment/Libraries
License: LGPLv2+
URL: http://www.libteam.org
Source: http://www.libteam.org/files/libteam-%{version}.tar.gz
Patch1: libteam-Revert-teamd-Disregard-current-state-when-considerin.patch
Patch2: libteamdctl-validate-the-bus-name-before-using-it.patch
Patch3: libteam-teamd-do-no-remove-the-ports-on-shutdown-with-N.patch
Patch4: libteam-teamd-stop-iterating-callbacks-when-a-loop-restart-i.patch
Patch1: 0001-team-add-a-tool-for-team-to-bonding-config-migration.patch
Patch2: 0002-team2bond-fix-min_ports-format-and-add-lacp_key.patch
Patch3: 0003-utils-team2bond-add-cautions-for-the-script.patch
Patch4: 0004-man-add-team2bond-man-doc.patch
Patch5: 0005-Revert-teamd-Disregard-current-state-when-considerin.patch
Patch6: 0006-utils-team2bond-do-not-add-miimon-if-already-exist.patch
Patch7: 0007-utils-team2bond-do-not-add-updelay-downdelay-if-alre.patch
Patch8: 0008-teamd-do-no-remove-the-ports-on-shutdown-with-N.patch
Patch9: 0009-teamd-stop-iterating-callbacks-when-a-loop-restart-i.patch
Patch10: 0010-utils-team2bond-add-lacp_active-support.patch
Patch11: 0011-utils-team2bond-support-missed_max.patch
Patch12: 0012-utils-team2bond-support-link-watch-in-ports.patch
Patch13: 0013-utils-team2bond-add-ns_ip6_target-support.patch
Patch14: 0014-utils-team2bond-Add-queue_id-support.patch
Patch15: 0015-utils-team2bond-update-python-code-format.patch
BuildRequires: gcc
BuildRequires: jansson-devel
BuildRequires: libdaemon-devel
BuildRequires: libnl3-devel
BuildRequires: python3-devel
BuildRequires: dbus-devel
BuildRequires: systemd
BuildRequires: swig
BuildRequires: doxygen
BuildRequires: autoconf automake libtool
BuildRequires: systemd-units
BuildRequires: make
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: libtool
%description
This package contains a library which is a user-space
@ -26,12 +41,10 @@ counterpart for team network driver. It provides an API
to control team network devices.
%package devel
Group: Development/Libraries
Summary: Libraries and header files for libteam development
Requires: libteam = %{version}-%{release}
%package doc
Group: Documentation
Summary: API documentation for libteam and libteamd
Requires: libteam = %{version}-%{release}
@ -39,24 +52,15 @@ Requires: libteam = %{version}-%{release}
This package contains libteam and libteamd API documentation
%package -n teamd
Group: System Environment/Daemons
Summary: Team network device control daemon
Requires: libteam = %{version}-%{release}
%package -n teamd-devel
Group: Development/Libraries
Summary: Libraries and header files for teamd development
Requires: teamd = %{version}-%{release}
%package -n python3-libteam
%{?python_provide:%python_provide python3-libteam}
Group: Development/Libraries
Summary: Team network device library bindings
Requires: libteam = %{version}-%{release}
%package -n network-scripts-team
Group: Development/Libraries
Summary: libteam legacy network service support
%package -n network-scripts-teamd
Summary: teamd legacy network service support
Requires: network-scripts
Supplements: (teamd and network-scripts)
@ -71,17 +75,9 @@ The teamd package contains team network device control daemon.
The teamd-devel package contains the header files and libraries
necessary for developing programs using libteamdctl.
%description -n python3-libteam
The team-python package contains a module that permits applications
written in the Python programming language to use the interface
supplied by team network device library.
This package should be installed if you want to develop Python
programs that will manipulate team network devices.
%description -n network-scripts-team
This provides the ifup and ifdown scripts for libteam use with the legacy
network service.
%description -n network-scripts-teamd
This provides the ifup and ifdown scripts for use with the legacy network
service.
%prep
%autosetup -p1
@ -89,18 +85,13 @@ autoreconf --force --install -I m4
# prepare example dir for -devel
mkdir -p _tmpdoc1/examples
rm examples/python/*.py
cp -p examples/*.c _tmpdoc1/examples
# prepare example dir for team-python
mkdir -p _tmpdoc2/examples
cp -p examples/python/*.py _tmpdoc2/examples
chmod -x _tmpdoc2/examples/*.py
%build
%configure --disable-static
make %{?_smp_mflags}
make html
cd binding/python
%py3_build
%install
make install DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p"
@ -116,114 +107,156 @@ install -p -m 755 teamd/redhat/initscripts_systemd/network-scripts/ifdown-Team $
install -p -m 755 teamd/redhat/initscripts_systemd/network-scripts/ifup-TeamPort $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/network-scripts
install -p -m 755 teamd/redhat/initscripts_systemd/network-scripts/ifdown-TeamPort $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/network-scripts
install -p -m 755 utils/bond2team $RPM_BUILD_ROOT%{_bindir}/bond2team
cd binding/python
%py3_install
install -p -m 755 utils/team2bond $RPM_BUILD_ROOT%{_bindir}/team2bond
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%ldconfig_scriptlets
%files
%doc COPYING
%license COPYING
%{_libdir}/libteam.so.*
%{_bindir}/teamnl
%{_mandir}/man8/teamnl.8*
%files devel
%doc COPYING _tmpdoc1/examples
%doc _tmpdoc1/examples
%{_includedir}/team.h
%{_libdir}/libteam.so
%{_libdir}/pkgconfig/libteam.pc
%files doc
%doc COPYING doc/api
%doc doc/api
%files -n teamd
%doc COPYING teamd/example_configs teamd/redhat/example_ifcfgs/
%doc teamd/example_configs teamd/redhat/example_ifcfgs/
%config(noreplace) %attr(644,root,root) %{_sysconfdir}/dbus-1/system.d/teamd.conf
%config(noreplace) %attr(644,root,root) %{_unitdir}/teamd@.service
%{_libdir}/libteamdctl.so.*
%{_bindir}/teamd
%{_bindir}/teamdctl
%{_bindir}/bond2team
%{_bindir}/team2bond
%{_mandir}/man8/teamd.8*
%{_mandir}/man8/teamdctl.8*
%{_mandir}/man5/teamd.conf.5*
%{_mandir}/man1/bond2team.1*
%{_mandir}/man1/team2bond.1*
%files -n teamd-devel
%doc COPYING
%{_includedir}/teamdctl.h
%{_libdir}/libteamdctl.so
%{_libdir}/pkgconfig/libteamdctl.pc
%files -n python3-libteam
%doc COPYING _tmpdoc2/examples
%{python3_sitearch}/*
%files -n network-scripts-team
%files -n network-scripts-teamd
%{_sysconfdir}/sysconfig/network-scripts/ifup-Team
%{_sysconfdir}/sysconfig/network-scripts/ifdown-Team
%{_sysconfdir}/sysconfig/network-scripts/ifup-TeamPort
%{_sysconfdir}/sysconfig/network-scripts/ifdown-TeamPort
%changelog
* Mon Dec 05 2022 Xin Long <lxin@redhat.com> - 1.31-4
- teamd: do no remove the ports on shutdown with -N [2148856]
- teamd: stop iterating callbacks when a loop restart is requested [2148855]
* Fri Sep 30 2022 Xin Long <lxin@redhat.com> - 1.31-3
- libteamdctl: validate the bus name before using it [2065227]
* Tue Sep 01 2020 Xin Long <lxin@redhat.com> - 1.31-2
- Revert "teamd: Disregard current state when considering port enablement" [1874001]
* Thu Jul 30 2020 Xin Long <lxin@redhat.com> - 1.31-1
- 1.31 release
- utils/bond2team: remove TYPE in ifcfg file [1858518]
- utils/bond2team: keep delivering config to file if stdout not supplied [1858518]
- teamd/lacp: silence ignore none LACP frames
- Send LACP PDU right after the Actor state has been changed
- Skip setting the same hwaddr to a lag port if not needed
- Make all netlink socket RCVBUF sizes configurable
- Don't return an error when timerfd socket return 0
- Fix ifinfo_link_with_port race condition with newlink
- teamd: fix possible race in master ifname callback
* Fri Jul 14 2023 Hangbin Liu <haliu@redhat.com> - 1.31-17
- Update team2bond to latest version (RHEL-783)
* Tue Dec 06 2022 Long Xin <lxin@redhat.com> - 1.31-16
- fix the Requires package name for teamd-devel
- teamd: stop iterating callbacks when a loop restart is requested (rhbz#2148852)
* Mon Dec 05 2022 Long Xin <lxin@redhat.com> - 1.31-15
- teamd: do no remove the ports on shutdown with -N (rhbz#2148854)
* Mon Jun 13 2022 Long Xin <lxin@redhat.com> - 1.31-14
- Rebuilt with a new version to pass the fixed gating test (rhbz#2060445)
* Mon May 16 2022 Hangbin Liu <haliu@redhat.com> - 1.31-13
- utils/team2bond: do not add updelay/downdelay if already exist (rhbz#2060445)
* Mon Mar 7 2022 Hangbin Liu <haliu@redhat.com> - 1.31-12
- utils/team2bond: do not add miimon if already exist (rhbz#2060445)
* Mon Nov 15 2021 Xin Long <lxin@redhat.com> - 1.31-11
- Revert "teamd: Disregard current state when considering port enablement" [1894546]
* Mon Aug 16 2021 Hangbin Liu <haliu@redhat.com> - 1.31-10
- Remove an extra line in spec file
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 1.31-9
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Wed Jul 28 2021 Hangbin Liu <haliu@redhat.com> - 1.31-8
- Build util team2bond in teamd rpm [1986788]
- Add some cautions to util team2bond [1986788]
- Add team2bond man doc [1986788]
* Thu Jun 17 2021 Xin Long <lxin@redhat.com> - 1.31-7
- gating: fix the wrong link of openvswitch for RHEL-9 [1970175]
* Mon May 24 2021 Hangbin Liu <haliu@redhat.com> - 1.31-6
- team2bond: fix min_ports format and add lacp_key [1937155]
* Wed May 12 2021 Hangbin Liu <haliu@redhat.com> - 1.31-5
- team: add a tool for team to bonding config migration [1937155]
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 1.31-4
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.31-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.31-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Sun Jul 26 2020 Jiri Pirko <jiri@resnulli.us> - 1.31-1
1.31 release
utils/bond2team: remove TYPE in ifcfg file
utils/bond2team: keep delivering config to file if stdout not supplied
teamd/lacp: silence ignore none LACP frames
teamd: fix ctx->hwaddr value assignment
Send LACP PDU right after the Actor state has been changed
Skip setting the same hwaddr to a lag port if not needed
Make all netlink socket RCVBUF sizes configurable
Don't return an error when timerfd socket return 0
Fix ifinfo_link_with_port race condition with newlink
teamd: fix possible race in master ifname callback
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.30-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Thu Jan 09 2020 Jiri Pirko <jiri@resnulli.us> - 1.30-1
- 1.30 release
- teamd: Disregard current state when considering port enablement [1851460]
* Sat May 23 2020 Xin Long <lxin@redhat.com> - 1.29-5
- teamd: fix ctx->hwaddr value assignment [1838952]
* Mon May 18 2020 Xin Long <lxin@redhat.com> - 1.29-4
- gating: fix the invalid ovs rpm link with latest version [1782427]
* Mon May 18 2020 Xin Long <lxin@redhat.com> - 1.29-3
- gating: fix the invalid ovs rpm link [1782427]
* Mon May 18 2020 Xin Long <lxin@redhat.com> - 1.29-2
- teamd/lacp: fix segfault due to NULL pointer dereference [1758073]
- teamd: fix build error in expansion of macro teamd_log_dbgx [1758073]
- teamd/lacp: fix segfault due to NULL pointer dereference
- teamd: fix build error in expansion of macro teamd_log_dbgx
- teamd: update ctx->hwaddr after setting team dev to new hwaddr
- libteam: wapper teamd_log_dbg with teamd_log_dbgx [1758073]
* Mon Oct 14 2019 Xin Long <lxin@redhat.com> - 1.29-1
- man teamd.conf: update some parameter default values [1732587]
- libteam: wapper teamd_log_dbg with teamd_log_dbgx
- teamd: Disregard current state when considering port enablement
- man teamd.conf: update some parameter default values
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.29-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Wed Jul 03 2019 Jiri Pirko <jiri@resnulli.us> - 1.29-1
- 1.29 release
- teamd: improve the error output for non-integer port prio
- teamd: return 0 if tdport doesn't exist in teamd_config_port_set
- teamd: add port_master_ifindex_changed for link_watch_port_watch_ops
- initscripts: fix if/fi align
- teamd: fix a json object memleak in get_port_obj() [1767685]
- libteam: set netlink event socket as non-blocking [1684389]
- teamd: fix a json object memleak in get_port_obj()
- libteam: set netlink event socket as non-blocking
- libteam: double NETLINK_RCVBUF to fix -ENOMEM error
- teamd: add a default value 1000 for link_watch.interval
* Mon Jul 15 2019 Xin Long <lxin@redhat.com> - 1.28-4
- gating: run VM with more RAM [1722449]
* Wed Jul 03 2019 Xin Long <lxin@redhat.com> - 1.28-3
- teamd: return 0 if tdport doesn't exist in teamd_config_port_set [1722449]
- teamd: improve the error output for non-integer port prio
* Mon Apr 29 2019 Xin Long <lxin@redhat.com> - 1.28-2
- teamd: use enabled option_changed to sync enabled to link_up for lb runner [1668132]
- teamd: tdport has to exist if item->per_port is set in __find_by_item_path [1687336]
- teamd: remove port if adding fails [1668744]
* Wed Apr 17 2019 Xin Long <lxin@redhat.com> - 1.28-1
- teamd: use enabled option_changed to sync enabled to link_up for lb runner
- teamd: tdport has to exist if item->per_port is set in __find_by_item_path
- teamd: remove port if adding fails
- teamd: lacp: update port state according to partner's sync bit
- man: fix runner.min_ports default value [1679853]
- teamd: lw: nsna_ping: only send ns on enabled port [1671195]
- teamd: lw: arp_ping: only check arp reply message [1663093]
- teamd: config: update local prio to kernel [1657113]
- man: fix runner.min_ports default value
- teamd: lw: nsna_ping: only send ns on enabled port
- teamd: lw: arp_ping: only check arp reply message
- teamd: config: update local prio to kernel
- teamnl: update help message
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.28-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Sun Dec 09 2018 Jiri Pirko <jiri@resnulli.us> - 1.28-1
- 1.28 release
- teamd: lacp: send LACPDU when port state transitions from DEFAULT to CURRENT
- man teamd.conf: Document ARP Ping link_watch.vlanid option
@ -231,29 +264,32 @@ cd binding/python
- libteam/options: fix s32/u32 data storage on big endian
- teamd: add an option to force log output to stdout, stderr or syslog
- teamd: add port_master_ifindex_changed for teamd_event_watch_ops
- utils: check to_stdout return correctly in bond2team
- binding/python: use SWIG_FromCharPtrAndSize for Python3 support
- man: add 'random' to the list of available runners
- libteam: don't crash when trying to print unregistered device name
- configure.ac: Empty LDFLAGS before checking for libnl3
- man: fix runner.sys_prio default
- examples: fix duplex comparison against best port
- teamd: add port_hwaddr_changed for lacp runner
- teamd: add port_hwaddr_changed for lb runner
- teamd: add port_hwaddr_changed for ab runner
- teamd: do not process lacpdu before the port ifinfo is set
* Thu Jan 10 2019 Xin Long <lxin@redhat.com> - 1.27-10
- add new package network-scripts-team [1659846]
* Tue Sep 18 2018 Miro Hrončok <mhroncok@redhat.com> - 1.27-11
- Remove Python 2 subpackage (#1627333)
* Mon Aug 20 2018 Xin Long <lxin@redhat.com> - 1.27-9
- Added patch to fix the issue that no active port is set [1618710]
* Thu Aug 2 2018 Peter Robinson <pbrobinson@fedoraproject.org> 1.27-10
- Properly move network-scripts dep to right package
* Fri Aug 03 2018 Xin Long <lxin@redhat.com> - 1.27-8
- Add fix to only process LACPDU after port ifinfo is set
- Add port_hwaddr_changed for ab, lb and lacp runners
- Add patch to fix runner.sys_prio default in man docs
- Add patch to empty LDFLAGS before checking for libnl3 in configure.ac
- Add patch to not crash when trying to print unregistered device name
- Add patch to use SWIG_FromCharPtrAndSize for Python3 support
- Add patch to check to_stdout return correctly in bond2team in bond2team
- Add 'BuildRequires: systemd-units' in libteam.spec to fix building errors
- Add 'autoreconf --force --install -I m4' in libteam.sepc to regenerate configure
- Remove ifup/ifdown scripts installation in libteam.sepc
* Thu Aug 2 2018 Peter Robinson <pbrobinson@fedoraproject.org> 1.27-9
- Move legacy network scripts into network-scripts-teamd sub package
* Tue Jun 26 2018 Charalampos Stratakis <cstratak@redhat.com> - 1.27-7
- Change the python bindings to Python 3
* Sun Jul 22 2018 Peter Robinson <pbrobinson@fedoraproject.org> 1.27-8
- Cleanup spec, fix deps
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.27-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.27-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild

1
sources Normal file
View File

@ -0,0 +1 @@
SHA512 (libteam-1.31.tar.gz) = f18cbe7316f6ac8ddf019d2e4b52e19fbdbc75d637f8cacda15b29d679508919230e1af3eb656febe7aafdf8a94c4334f2ae95ecd60bc89ac379622b99d3b615

1
tests/.fmf/version Normal file
View File

@ -0,0 +1 @@
1

207
tests/basic/test.sh Normal file
View File

@ -0,0 +1,207 @@
libteam_setup_files()
{
cat <<-EOF > activebackup.json
{
"device":"team0",
"runner":{"name":"activebackup"},
"link_watch": {"name": "ethtool"}
}
EOF
cat <<-EOF >lacp.json
{
"device":"team0",
"runner":{
"name":"lacp",
"active": false,
"fast_rate": true,
"tx_hash": ["eth", "ipv4", "ipv6"]},
"link_watch": {"name": "ethtool"}
}
EOF
cat <<-EOF > roundrobin.json
{
"device":"team0",
"runner":{
"name":"roundrobin",
"fast_rate": true
},
"link_watch": {"name": "ethtool"}
}
EOF
cat <<-EOF > broadcast.json
{
"device":"team0",
"runner":{"name":"broadcast"},
"link_watch": {"name": "ethtool"}
}
EOF
cat <<-EOF > loadbalance.json
{
"device":"team0",
"runner":{
"name":"loadbalance",
"tx_balancer" : { "name" : "basic", "balancing_interval" : 10 },
"tx_hash": ["eth", "ipv4", "ipv6"] },
"link_watch": {"name": "ethtool"}
}
EOF
}
libteam_clean_files()
{
rm -rf *.json
}
libteam_log()
{
echo -e "[libteam gating]: $@"
echo -e "[libteam gating]: $@" >> libteam.log
}
libteam_start_ovs()
{
local url=http://download-node-02.eng.bos.redhat.com/brewroot/packages
ver=`curl -s $url/openvswitch2.15/2.15.0/ | grep -o "[0-9]*.el9fdp" |tail -1`
pver=`curl -s $url/openvswitch-selinux-extra-policy/1.0/ |grep -o "[0-9]*.el9fdp" |tail -1`
yum install -y $url/openvswitch2.15/2.15.0/$ver/x86_64/openvswitch2.15-2.15.0-$ver.x86_64.rpm \
$url/openvswitch-selinux-extra-policy/1.0/$pver/noarch/openvswitch-selinux-extra-policy-1.0-$pver.noarch.rpm
systemctl start openvswitch
}
libteam_stop_ovs()
{
systemctl stop openvswitch
}
libteam_setup_switch()
{
[ $runner = "lacp" ] || return
ovs-vsctl del-port br0 br_ceth1
ovs-vsctl del-port br0 br_ceth2
ovs-vsctl add-bond br0 br_lacp1 br_ceth1 br_ceth2 lacp=active
sleep 3
}
libteam_clean_switch()
{
[ $runner = "lacp" ] || return
ovs-vsctl del-port br0 br_lacp1
ovs-vsctl add-port br0 br_ceth1
ovs-vsctl add-port br0 br_ceth2
}
libteam_setup()
{
# ceth1 --- br_ceth1 \
# br0 - br_seth1 --- seth1 (server)
# ceth2 --- br_ceth2 /
# do topo setup
ip netn add serv1
ip link add ceth1 type veth peer name br_ceth1
ip link add ceth2 type veth peer name br_ceth2
ip link add seth1 type veth peer name br_seth1
ip link set seth1 netns serv1
libteam_start_ovs
ovs-vsctl add-br br0
ovs-vsctl add-port br0 br_ceth1
ovs-vsctl add-port br0 br_ceth2
ovs-vsctl add-port br0 br_seth1
ip link set br0 up
ip link set br_ceth1 up
ip link set br_ceth2 up
ip link set br_seth1 up
ip netns exec serv1 ip link set seth1 up
ip netns exec serv1 ip addr add 192.168.11.1/24 dev seth1
libteam_setup_files
rm -rf libteam.log
libteam_log "testing setup\n\n"
}
libteam_test_nm()
{
local runner=$1
nmcli con add con-name team0 type team ifname team0 ipv4.method manual ipv4.addr 192.168.11.2/24 connection.autoconnect no
nmcli con modify team0 team.config $runner.json
nmcli con add type ethernet con-name ceth1 ifname ceth1 master team0
nmcli con add type ethernet con-name ceth2 ifname ceth2 master team0
nmcli con reload
nmcli con up team0
nmcli con up ceth1
nmcli con up ceth2
timeout 60s bash -c "until ping -c 3 192.168.11.1 >> libteam.log; do sleep 5; done" || \
{ let LIBTEAM_FAIL++; libteam_log "FAIL $LIBTEAM_FAIL: nm $runner testing failed"; }
nmcli con delete ceth1
nmcli con delete ceth2
nmcli con delete team0
nmcli con reload
}
libteam_test_teamd()
{
local runner=$1
ip link set ceth1 down
ip link set ceth2 down
teamd -d -f $runner.json
teamdctl team0 port add ceth1
teamdctl team0 port add ceth2
ip link set team0 up
ip addr add 192.168.11.2/24 dev team0
timeout 60s bash -c "until ping -c 3 192.168.11.1 >> libteam.log; do sleep 5; done" || \
{ let LIBTEAM_FAIL++; libteam_log "FAIL $LIBTEAM_FAIL: teamd $runner testing failed"; }
teamd -k -t team0
}
libteam_tests()
{
local type=$1
libteam_log "testing run $type =>"
for runner in broadcast roundrobin activebackup loadbalance lacp; do
libteam_log "runnner $runner testing start"
libteam_setup_switch $runner
eval "libteam_test_$type $runner"
libteam_clean_switch $runner
libteam_log "runnner $runner testing done\n"
done
}
libteam_clean()
{
ip link del ceth1
ip link del ceth2
ip link del br_seth1
ip netn del serv1
ovs-vsctl del-br br0
libteam_stop_ovs
libteam_clean_files
libteam_log "testing clean\n\n"
}
LIBTEAM_FAIL=0
libteam_setup
libteam_tests nm
libteam_tests teamd
libteam_clean
exit $LIBTEAM_FAIL

5
tests/provision.fmf Normal file
View File

@ -0,0 +1,5 @@
---
standard-inventory-qcow2:
qemu:
m: 2G

10
tests/tests.yml Normal file
View File

@ -0,0 +1,10 @@
# Tests for Libteam
- hosts: localhost
roles:
- role: standard-test-basic
tags:
- classic
tests:
- sanity-tests:
dir: basic
run: sh test.sh