.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * drivers/net/bond/bond_options.c - bonding options |
---|
3 | 4 | * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us> |
---|
4 | 5 | * Copyright (c) 2013 Scott Feldman <sfeldma@cumulusnetworks.com> |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify |
---|
7 | | - * it under the terms of the GNU General Public License as published by |
---|
8 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
9 | | - * (at your option) any later version. |
---|
10 | 6 | */ |
---|
11 | 7 | |
---|
12 | 8 | #include <linux/errno.h> |
---|
.. | .. |
---|
28 | 24 | const struct bond_opt_value *newval); |
---|
29 | 25 | static int bond_option_downdelay_set(struct bonding *bond, |
---|
30 | 26 | const struct bond_opt_value *newval); |
---|
| 27 | +static int bond_option_peer_notif_delay_set(struct bonding *bond, |
---|
| 28 | + const struct bond_opt_value *newval); |
---|
31 | 29 | static int bond_option_use_carrier_set(struct bonding *bond, |
---|
32 | 30 | const struct bond_opt_value *newval); |
---|
33 | 31 | static int bond_option_arp_interval_set(struct bonding *bond, |
---|
.. | .. |
---|
428 | 426 | .desc = "Number of peer notifications to send on failover event", |
---|
429 | 427 | .values = bond_num_peer_notif_tbl, |
---|
430 | 428 | .set = bond_option_num_peer_notif_set |
---|
| 429 | + }, |
---|
| 430 | + [BOND_OPT_PEER_NOTIF_DELAY] = { |
---|
| 431 | + .id = BOND_OPT_PEER_NOTIF_DELAY, |
---|
| 432 | + .name = "peer_notif_delay", |
---|
| 433 | + .desc = "Delay between each peer notification on failover event, in milliseconds", |
---|
| 434 | + .values = bond_intmax_tbl, |
---|
| 435 | + .set = bond_option_peer_notif_delay_set |
---|
431 | 436 | } |
---|
432 | 437 | }; |
---|
433 | 438 | |
---|
.. | .. |
---|
740 | 745 | return &bond_opts[option]; |
---|
741 | 746 | } |
---|
742 | 747 | |
---|
| 748 | +static void bond_set_xfrm_features(struct net_device *bond_dev, u64 mode) |
---|
| 749 | +{ |
---|
| 750 | + if (!IS_ENABLED(CONFIG_XFRM_OFFLOAD)) |
---|
| 751 | + return; |
---|
| 752 | + |
---|
| 753 | + if (mode == BOND_MODE_ACTIVEBACKUP) |
---|
| 754 | + bond_dev->wanted_features |= BOND_XFRM_FEATURES; |
---|
| 755 | + else |
---|
| 756 | + bond_dev->wanted_features &= ~BOND_XFRM_FEATURES; |
---|
| 757 | + |
---|
| 758 | + netdev_update_features(bond_dev); |
---|
| 759 | +} |
---|
| 760 | + |
---|
743 | 761 | static int bond_option_mode_set(struct bonding *bond, |
---|
744 | 762 | const struct bond_opt_value *newval) |
---|
745 | 763 | { |
---|
.. | .. |
---|
761 | 779 | |
---|
762 | 780 | if (newval->value == BOND_MODE_ALB) |
---|
763 | 781 | bond->params.tlb_dynamic_lb = 1; |
---|
| 782 | + |
---|
| 783 | + if (bond->dev->reg_state == NETREG_REGISTERED) |
---|
| 784 | + bond_set_xfrm_features(bond->dev, newval->value); |
---|
764 | 785 | |
---|
765 | 786 | /* don't cache arp_validate between modes */ |
---|
766 | 787 | bond->params.arp_validate = BOND_ARP_VALIDATE_NONE; |
---|
.. | .. |
---|
787 | 808 | |
---|
788 | 809 | if (slave_dev) { |
---|
789 | 810 | if (!netif_is_bond_slave(slave_dev)) { |
---|
790 | | - netdev_err(bond->dev, "Device %s is not bonding slave\n", |
---|
791 | | - slave_dev->name); |
---|
| 811 | + slave_err(bond->dev, slave_dev, "Device is not bonding slave\n"); |
---|
792 | 812 | return -EINVAL; |
---|
793 | 813 | } |
---|
794 | 814 | |
---|
795 | 815 | if (bond->dev != netdev_master_upper_dev_get(slave_dev)) { |
---|
796 | | - netdev_err(bond->dev, "Device %s is not our slave\n", |
---|
797 | | - slave_dev->name); |
---|
| 816 | + slave_err(bond->dev, slave_dev, "Device is not our slave\n"); |
---|
798 | 817 | return -EINVAL; |
---|
799 | 818 | } |
---|
800 | 819 | } |
---|
.. | .. |
---|
813 | 832 | |
---|
814 | 833 | if (new_active == old_active) { |
---|
815 | 834 | /* do nothing */ |
---|
816 | | - netdev_dbg(bond->dev, "%s is already the current active slave\n", |
---|
817 | | - new_active->dev->name); |
---|
| 835 | + slave_dbg(bond->dev, new_active->dev, "is already the current active slave\n"); |
---|
818 | 836 | } else { |
---|
819 | 837 | if (old_active && (new_active->link == BOND_LINK_UP) && |
---|
820 | 838 | bond_slave_is_up(new_active)) { |
---|
821 | | - netdev_dbg(bond->dev, "Setting %s as active slave\n", |
---|
822 | | - new_active->dev->name); |
---|
| 839 | + slave_dbg(bond->dev, new_active->dev, "Setting as active slave\n"); |
---|
823 | 840 | bond_change_active_slave(bond, new_active); |
---|
824 | 841 | } else { |
---|
825 | | - netdev_err(bond->dev, "Could not set %s as active slave; either %s is down or the link is down\n", |
---|
826 | | - new_active->dev->name, |
---|
827 | | - new_active->dev->name); |
---|
| 842 | + slave_err(bond->dev, new_active->dev, "Could not set as active slave; either %s is down or the link is down\n", |
---|
| 843 | + new_active->dev->name); |
---|
828 | 844 | ret = -EINVAL; |
---|
829 | 845 | } |
---|
830 | 846 | } |
---|
.. | .. |
---|
850 | 866 | if (bond->params.downdelay) |
---|
851 | 867 | netdev_dbg(bond->dev, "Note: Updating downdelay (to %d) since it is a multiple of the miimon value\n", |
---|
852 | 868 | bond->params.downdelay * bond->params.miimon); |
---|
| 869 | + if (bond->params.peer_notif_delay) |
---|
| 870 | + netdev_dbg(bond->dev, "Note: Updating peer_notif_delay (to %d) since it is a multiple of the miimon value\n", |
---|
| 871 | + bond->params.peer_notif_delay * bond->params.miimon); |
---|
853 | 872 | if (newval->value && bond->params.arp_interval) { |
---|
854 | 873 | netdev_dbg(bond->dev, "MII monitoring cannot be used with ARP monitoring - disabling ARP monitoring...\n"); |
---|
855 | 874 | bond->params.arp_interval = 0; |
---|
.. | .. |
---|
873 | 892 | return 0; |
---|
874 | 893 | } |
---|
875 | 894 | |
---|
876 | | -/* Set up and down delays. These must be multiples of the |
---|
877 | | - * MII monitoring value, and are stored internally as the multiplier. |
---|
878 | | - * Thus, we must translate to MS for the real world. |
---|
| 895 | +/* Set up, down and peer notification delays. These must be multiples |
---|
| 896 | + * of the MII monitoring value, and are stored internally as the |
---|
| 897 | + * multiplier. Thus, we must translate to MS for the real world. |
---|
879 | 898 | */ |
---|
880 | | -static int bond_option_updelay_set(struct bonding *bond, |
---|
881 | | - const struct bond_opt_value *newval) |
---|
| 899 | +static int _bond_option_delay_set(struct bonding *bond, |
---|
| 900 | + const struct bond_opt_value *newval, |
---|
| 901 | + const char *name, |
---|
| 902 | + int *target) |
---|
882 | 903 | { |
---|
883 | 904 | int value = newval->value; |
---|
884 | 905 | |
---|
885 | 906 | if (!bond->params.miimon) { |
---|
886 | | - netdev_err(bond->dev, "Unable to set up delay as MII monitoring is disabled\n"); |
---|
| 907 | + netdev_err(bond->dev, "Unable to set %s as MII monitoring is disabled\n", |
---|
| 908 | + name); |
---|
887 | 909 | return -EPERM; |
---|
888 | 910 | } |
---|
889 | 911 | if ((value % bond->params.miimon) != 0) { |
---|
890 | | - netdev_warn(bond->dev, "up delay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n", |
---|
| 912 | + netdev_warn(bond->dev, |
---|
| 913 | + "%s (%d) is not a multiple of miimon (%d), value rounded to %d ms\n", |
---|
| 914 | + name, |
---|
891 | 915 | value, bond->params.miimon, |
---|
892 | 916 | (value / bond->params.miimon) * |
---|
893 | 917 | bond->params.miimon); |
---|
894 | 918 | } |
---|
895 | | - bond->params.updelay = value / bond->params.miimon; |
---|
896 | | - netdev_dbg(bond->dev, "Setting up delay to %d\n", |
---|
897 | | - bond->params.updelay * bond->params.miimon); |
---|
| 919 | + *target = value / bond->params.miimon; |
---|
| 920 | + netdev_dbg(bond->dev, "Setting %s to %d\n", |
---|
| 921 | + name, |
---|
| 922 | + *target * bond->params.miimon); |
---|
898 | 923 | |
---|
899 | 924 | return 0; |
---|
| 925 | +} |
---|
| 926 | + |
---|
| 927 | +static int bond_option_updelay_set(struct bonding *bond, |
---|
| 928 | + const struct bond_opt_value *newval) |
---|
| 929 | +{ |
---|
| 930 | + return _bond_option_delay_set(bond, newval, "up delay", |
---|
| 931 | + &bond->params.updelay); |
---|
900 | 932 | } |
---|
901 | 933 | |
---|
902 | 934 | static int bond_option_downdelay_set(struct bonding *bond, |
---|
903 | 935 | const struct bond_opt_value *newval) |
---|
904 | 936 | { |
---|
905 | | - int value = newval->value; |
---|
| 937 | + return _bond_option_delay_set(bond, newval, "down delay", |
---|
| 938 | + &bond->params.downdelay); |
---|
| 939 | +} |
---|
906 | 940 | |
---|
907 | | - if (!bond->params.miimon) { |
---|
908 | | - netdev_err(bond->dev, "Unable to set down delay as MII monitoring is disabled\n"); |
---|
909 | | - return -EPERM; |
---|
910 | | - } |
---|
911 | | - if ((value % bond->params.miimon) != 0) { |
---|
912 | | - netdev_warn(bond->dev, "down delay (%d) is not a multiple of miimon (%d), delay rounded to %d ms\n", |
---|
913 | | - value, bond->params.miimon, |
---|
914 | | - (value / bond->params.miimon) * |
---|
915 | | - bond->params.miimon); |
---|
916 | | - } |
---|
917 | | - bond->params.downdelay = value / bond->params.miimon; |
---|
918 | | - netdev_dbg(bond->dev, "Setting down delay to %d\n", |
---|
919 | | - bond->params.downdelay * bond->params.miimon); |
---|
920 | | - |
---|
921 | | - return 0; |
---|
| 941 | +static int bond_option_peer_notif_delay_set(struct bonding *bond, |
---|
| 942 | + const struct bond_opt_value *newval) |
---|
| 943 | +{ |
---|
| 944 | + int ret = _bond_option_delay_set(bond, newval, |
---|
| 945 | + "peer notification delay", |
---|
| 946 | + &bond->params.peer_notif_delay); |
---|
| 947 | + return ret; |
---|
922 | 948 | } |
---|
923 | 949 | |
---|
924 | 950 | static int bond_option_use_carrier_set(struct bonding *bond, |
---|
.. | .. |
---|
1136 | 1162 | |
---|
1137 | 1163 | bond_for_each_slave(bond, slave, iter) { |
---|
1138 | 1164 | if (strncmp(slave->dev->name, primary, IFNAMSIZ) == 0) { |
---|
1139 | | - netdev_dbg(bond->dev, "Setting %s as primary slave\n", |
---|
1140 | | - slave->dev->name); |
---|
| 1165 | + slave_dbg(bond->dev, slave->dev, "Setting as primary slave\n"); |
---|
1141 | 1166 | rcu_assign_pointer(bond->primary_slave, slave); |
---|
1142 | 1167 | strcpy(bond->params.primary, slave->dev->name); |
---|
1143 | 1168 | bond->force_primary = true; |
---|
.. | .. |
---|
1154 | 1179 | strncpy(bond->params.primary, primary, IFNAMSIZ); |
---|
1155 | 1180 | bond->params.primary[IFNAMSIZ - 1] = 0; |
---|
1156 | 1181 | |
---|
1157 | | - netdev_dbg(bond->dev, "Recording %s as primary, but it has not been enslaved to %s yet\n", |
---|
1158 | | - primary, bond->dev->name); |
---|
| 1182 | + netdev_dbg(bond->dev, "Recording %s as primary, but it has not been enslaved yet\n", |
---|
| 1183 | + primary); |
---|
1159 | 1184 | |
---|
1160 | 1185 | out: |
---|
1161 | 1186 | unblock_netpoll_tx(); |
---|
.. | .. |
---|
1368 | 1393 | sscanf(newval->string, "%16s", command); /* IFNAMSIZ*/ |
---|
1369 | 1394 | ifname = command + 1; |
---|
1370 | 1395 | if ((strlen(command) <= 1) || |
---|
| 1396 | + (command[0] != '+' && command[0] != '-') || |
---|
1371 | 1397 | !dev_valid_name(ifname)) |
---|
1372 | 1398 | goto err_no_cmd; |
---|
1373 | 1399 | |
---|
.. | .. |
---|
1381 | 1407 | |
---|
1382 | 1408 | switch (command[0]) { |
---|
1383 | 1409 | case '+': |
---|
1384 | | - netdev_dbg(bond->dev, "Adding slave %s\n", dev->name); |
---|
| 1410 | + slave_dbg(bond->dev, dev, "Enslaving interface\n"); |
---|
1385 | 1411 | ret = bond_enslave(bond->dev, dev, NULL); |
---|
1386 | 1412 | break; |
---|
1387 | 1413 | |
---|
1388 | 1414 | case '-': |
---|
1389 | | - netdev_dbg(bond->dev, "Removing slave %s\n", dev->name); |
---|
| 1415 | + slave_dbg(bond->dev, dev, "Releasing interface\n"); |
---|
1390 | 1416 | ret = bond_release(bond->dev, dev); |
---|
1391 | 1417 | break; |
---|
1392 | 1418 | |
---|
1393 | 1419 | default: |
---|
| 1420 | + /* should not run here. */ |
---|
1394 | 1421 | goto err_no_cmd; |
---|
1395 | 1422 | } |
---|
1396 | 1423 | |
---|
.. | .. |
---|
1449 | 1476 | return 0; |
---|
1450 | 1477 | |
---|
1451 | 1478 | err: |
---|
1452 | | - netdev_err(bond->dev, "Invalid MAC address.\n"); |
---|
| 1479 | + netdev_err(bond->dev, "Invalid ad_actor_system MAC address.\n"); |
---|
1453 | 1480 | return -EINVAL; |
---|
1454 | 1481 | } |
---|
1455 | 1482 | |
---|