From 747d5a6607c4986fc386ca2653544f018b0d7eb6 Mon Sep 17 00:00:00 2001 From: Hangbin Liu Date: Fri, 14 Jul 2023 12:09:29 +0800 Subject: [PATCH] 1.31-17 --- .libteam.metadata | 1 + ...ls-team2bond-add-lacp_active-support.patch | 29 ++ 0011-utils-team2bond-support-missed_max.patch | 39 +++ ...eam2bond-support-link-watch-in-ports.patch | 54 ++++ ...-team2bond-add-ns_ip6_target-support.patch | 98 ++++++ ...utils-team2bond-Add-queue_id-support.patch | 81 +++++ ...-team2bond-update-python-code-format.patch | 278 ++++++++++++++++++ libteam.spec | 11 +- 8 files changed, 590 insertions(+), 1 deletion(-) create mode 100644 .libteam.metadata create mode 100644 0010-utils-team2bond-add-lacp_active-support.patch create mode 100644 0011-utils-team2bond-support-missed_max.patch create mode 100644 0012-utils-team2bond-support-link-watch-in-ports.patch create mode 100644 0013-utils-team2bond-add-ns_ip6_target-support.patch create mode 100644 0014-utils-team2bond-Add-queue_id-support.patch create mode 100644 0015-utils-team2bond-update-python-code-format.patch diff --git a/.libteam.metadata b/.libteam.metadata new file mode 100644 index 0000000..cc26da4 --- /dev/null +++ b/.libteam.metadata @@ -0,0 +1 @@ +338f2bae08e143bc3f7a84317ddc3053cff2691d libteam-1.31.tar.gz diff --git a/0010-utils-team2bond-add-lacp_active-support.patch b/0010-utils-team2bond-add-lacp_active-support.patch new file mode 100644 index 0000000..10d847f --- /dev/null +++ b/0010-utils-team2bond-add-lacp_active-support.patch @@ -0,0 +1,29 @@ +From 8e6b8db540299209f28505e7578a6d0ffeba4c38 Mon Sep 17 00:00:00 2001 +From: Hangbin Liu +Date: Fri, 24 Mar 2023 10:51:25 +0800 +Subject: [PATCH 10/15] utils/team2bond: add lacp_active support + +Signed-off-by: Hangbin Liu +--- + 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 + diff --git a/0011-utils-team2bond-support-missed_max.patch b/0011-utils-team2bond-support-missed_max.patch new file mode 100644 index 0000000..9331177 --- /dev/null +++ b/0011-utils-team2bond-support-missed_max.patch @@ -0,0 +1,39 @@ +From 6bf7990d35900c033df03cd76c25b7986deb833f Mon Sep 17 00:00:00 2001 +From: Hangbin Liu +Date: Fri, 24 Mar 2023 10:59:21 +0800 +Subject: [PATCH 11/15] utils/team2bond: support missed_max + +Signed-off-by: Hangbin Liu +--- + 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 + diff --git a/0012-utils-team2bond-support-link-watch-in-ports.patch b/0012-utils-team2bond-support-link-watch-in-ports.patch new file mode 100644 index 0000000..134e8f6 --- /dev/null +++ b/0012-utils-team2bond-support-link-watch-in-ports.patch @@ -0,0 +1,54 @@ +From 54255e65e8734635374ee62eb3a8b118f79b568b Mon Sep 17 00:00:00 2001 +From: Hangbin Liu +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 +--- + 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 + diff --git a/0013-utils-team2bond-add-ns_ip6_target-support.patch b/0013-utils-team2bond-add-ns_ip6_target-support.patch new file mode 100644 index 0000000..115de9d --- /dev/null +++ b/0013-utils-team2bond-add-ns_ip6_target-support.patch @@ -0,0 +1,98 @@ +From 519f8529ac0bc5b19199ec8a2e83a06e88c078b0 Mon Sep 17 00:00:00 2001 +From: Hangbin Liu +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 +--- + 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 + diff --git a/0014-utils-team2bond-Add-queue_id-support.patch b/0014-utils-team2bond-Add-queue_id-support.patch new file mode 100644 index 0000000..c17cc30 --- /dev/null +++ b/0014-utils-team2bond-Add-queue_id-support.patch @@ -0,0 +1,81 @@ +From dea184d3aa8a6038977494ddd4ae6c540317fb72 Mon Sep 17 00:00:00 2001 +From: Hangbin Liu +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 +--- + 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 + diff --git a/0015-utils-team2bond-update-python-code-format.patch b/0015-utils-team2bond-update-python-code-format.patch new file mode 100644 index 0000000..d6a6495 --- /dev/null +++ b/0015-utils-team2bond-update-python-code-format.patch @@ -0,0 +1,278 @@ +From 8b682b86dfd4ac142724151f4489063dbecc5bda Mon Sep 17 00:00:00 2001 +From: Hangbin Liu +Date: Fri, 24 Mar 2023 15:57:36 +0800 +Subject: [PATCH 15/15] utils/team2bond: update python code format + +Signed-off-by: Hangbin Liu +--- + 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 + diff --git a/libteam.spec b/libteam.spec index 17570cc..2926119 100644 --- a/libteam.spec +++ b/libteam.spec @@ -1,6 +1,6 @@ Name: libteam Version: 1.31 -Release: 16%{?dist} +Release: 17%{?dist} Summary: Library for controlling team network device License: LGPLv2+ URL: http://www.libteam.org @@ -15,6 +15,12 @@ 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 @@ -147,6 +153,9 @@ install -p -m 755 utils/team2bond $RPM_BUILD_ROOT%{_bindir}/team2bond %{_sysconfdir}/sysconfig/network-scripts/ifdown-TeamPort %changelog +* Fri Jul 14 2023 Hangbin Liu - 1.31-17 +- Update team2bond to latest version (RHEL-783) + * Tue Dec 06 2022 Long Xin - 1.31-16 - fix the Requires package name for teamd-devel - teamd: stop iterating callbacks when a loop restart is requested (rhbz#2148852)