Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f9de11a1 authored by Wang Weidong's avatar Wang Weidong Committed by David S. Miller
Browse files

bonding: add ip checks when store ip target



I met a Bug when I add ip target with the wrong ip address:

echo +500.500.500.500 > /sys/class/net/bond0/bonding/arp_ip_target

the wrong ip address will transfor to 245.245.245.244 and add
to the ip target success, it is uncorrect, so I add checks to avoid
adding wrong address.

The in4_pton() will set wrong ip address to 0.0.0.0, it will return by
the next check and will not add to ip target.

v2
According Veaceslav's opinion, simplify the code.

v3
According Veaceslav's opinion, add broadcast check and make a micro
definition to package it.

v4
Solve the problem of the format which David point out.

Suggested-by: default avatarVeaceslav Falico <vfalico@redhat.com>
Suggested-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarDing Tianhong <dingtianhong@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1188f054
Loading
Loading
Loading
Loading
+6 −13
Original line number Original line Diff line number Diff line
@@ -604,15 +604,14 @@ static ssize_t bonding_store_arp_targets(struct device *d,
		return restart_syscall();
		return restart_syscall();


	targets = bond->params.arp_targets;
	targets = bond->params.arp_targets;
	newtarget = in_aton(buf + 1);
	if (!in4_pton(buf + 1, -1, (u8 *)&newtarget, -1, NULL) ||
	/* look for adds */
	    IS_IP_TARGET_UNUSABLE_ADDRESS(newtarget)) {
	if (buf[0] == '+') {
		if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
		pr_err("%s: invalid ARP target %pI4 specified for addition\n",
		pr_err("%s: invalid ARP target %pI4 specified for addition\n",
		       bond->dev->name, &newtarget);
		       bond->dev->name, &newtarget);
		goto out;
		goto out;
	}
	}

	/* look for adds */
	if (buf[0] == '+') {
		if (bond_get_targets_ip(targets, newtarget) != -1) { /* dup */
		if (bond_get_targets_ip(targets, newtarget) != -1) { /* dup */
			pr_err("%s: ARP target %pI4 is already present\n",
			pr_err("%s: ARP target %pI4 is already present\n",
			       bond->dev->name, &newtarget);
			       bond->dev->name, &newtarget);
@@ -635,12 +634,6 @@ static ssize_t bonding_store_arp_targets(struct device *d,
		targets[ind] = newtarget;
		targets[ind] = newtarget;
		write_unlock_bh(&bond->lock);
		write_unlock_bh(&bond->lock);
	} else if (buf[0] == '-')	{
	} else if (buf[0] == '-')	{
		if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
			pr_err("%s: invalid ARP target %pI4 specified for removal\n",
			       bond->dev->name, &newtarget);
			goto out;
		}

		ind = bond_get_targets_ip(targets, newtarget);
		ind = bond_get_targets_ip(targets, newtarget);
		if (ind == -1) {
		if (ind == -1) {
			pr_err("%s: unable to remove nonexistent ARP target %pI4.\n",
			pr_err("%s: unable to remove nonexistent ARP target %pI4.\n",
+3 −0
Original line number Original line Diff line number Diff line
@@ -63,6 +63,9 @@
		(((mode) == BOND_MODE_TLB) ||	\
		(((mode) == BOND_MODE_TLB) ||	\
		 ((mode) == BOND_MODE_ALB))
		 ((mode) == BOND_MODE_ALB))


#define IS_IP_TARGET_UNUSABLE_ADDRESS(a)	\
	((htonl(INADDR_BROADCAST) == a) ||	\
	 ipv4_is_zeronet(a))
/*
/*
 * Less bad way to call ioctl from within the kernel; this needs to be
 * Less bad way to call ioctl from within the kernel; this needs to be
 * done some other way to get the call out of interrupt context.
 * done some other way to get the call out of interrupt context.